Skip to content

Commit

Permalink
Mark tasks assigned to user as in progress when viewing appeal (#14277)
Browse files Browse the repository at this point in the history
Resolves #14023

### Description
Also adds back the bolding of case details links that have not yet been viewed.

### Acceptance Criteria
- [ ] Ama tasks assigned to user get updated to "in_progress" when a user veiws an appeal
- [ ] Cases that have not yet been viewed show up as bolded in the users queue
    - [ ] AMA tasks
    - [ ] Legacy tasks
- [ ] Cases that have been viewed show up as not bolded in the users queue
    - [ ] AMA tasks
    - [ ] Legacy tasks

### Testing Plan
1. Sign in as an attorney (BVASCASPER1) and go to your queue
2. All cases should be bolded
3. Pick a bolded ama appeal and check the tasks and appeal views
```ruby
uuid = ""
appeal = Appeal.find_by_uuid(uuid)
appeal.tasks.where(assigned_to: User.first).pluck(:status)
=> ["assigned"]
appeal.appeal_views.find_by(user: User.first)
=> nil
```
4. Click into the ama appeal's case details
5. Ensure this task is updated to in progress and an appeal view is created
```ruby
appeal.reload.tasks.where(assigned_to: User.first).pluck(:status)
=> ["in_progress"]
appeal.appeal_views.find_by(user: User.first)
=> => #<AppealView:0x00007fc5e7b3a330 ... >
```
7. Go back to your queue and make sure the link is no longer bolded

1. Pick a bolded legacy appeal and check the appeal views
```ruby
vacols_id = ""
appeal = LegacyAppeal.find_by_vacols_id(vacols_id)
appeal.appeal_views.find_by(user: User.first)
=> nil
```
2. Click into an legacy appeal's case details
3. Check the appeal views again
```ruby
appeal.reload.appeal_views.find_by(user: User.first)
=> #<AppealView:0x00007fc5f0670e90 ... >
```
4. Go back to your queue and make sure the link is no longer bolded

1. Pick a bolded legacy appeal and check the appeal views
```ruby
vacols_id = ""
appeal = LegacyAppeal.find_by_vacols_id(vacols_id)
appeal.appeal_views.find_by(user: User.first)
=> nil
```
2. Click into an legacy appeal's documents
3. Check the appeal views again
```ruby
appeal.appeal_views.find_by(user: User.first)
=> #<AppealView:0x00007fc5eeae3628 ... >
```
4. Go back to your queue and make sure the link is no longer bolded

### User Facing Changes
 - [x] Unviewed appeals are bolded in queue
 - [x] Viewed appeals are not bolded in queue

![ezgif-3-9d944c5d31f3](https://user-images.githubusercontent.com/45575454/81850269-c0d90c80-9525-11ea-9ad2-10316cb99cf6.gif)
  • Loading branch information
hschallhorn authored May 15, 2020
1 parent f15e162 commit ba8b8ad
Show file tree
Hide file tree
Showing 16 changed files with 69 additions and 112 deletions.
1 change: 0 additions & 1 deletion .reek.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ detectors:
- TaskTimerJob
- UpdateCachedAppealsAttributesJob
- UserReporter#report_user_related_records
- User#current_case_assignments_with_views
- User#appeal_has_task_assigned_to_user?
- VeteranAttributeCacher
- WarmBgsCachesJob
Expand Down
1 change: 1 addition & 0 deletions app/controllers/appeals_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def show
MetricsService.record("Get appeal information for ID #{id}",
service: :queue,
name: "AppealsController.show") do
appeal.appeal_views.find_or_create_by(user: current_user).update!(last_viewed_at: Time.zone.now)
render json: { appeal: json_appeals(appeal)[:data] }
end
else
Expand Down
7 changes: 1 addition & 6 deletions app/controllers/reader/documents_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@ def index
respond_to do |format|
format.html { return render "reader/appeal/index" }
format.json do
AppealView.find_or_create_by(
appeal: appeal,
user_id: current_user.id
).tap do |t|
t.update!(last_viewed_at: Time.zone.now)
end
AppealView.find_or_create_by(appeal: appeal, user: current_user).update!(last_viewed_at: Time.zone.now)
MetricsService.record "Get appeal #{appeal_id} document data" do
render json: {
appealDocuments: documents,
Expand Down
5 changes: 3 additions & 2 deletions app/models/legacy_tasks/legacy_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class LegacyTask
include ActiveModel::Serialization

ATTRS = [:id, :appeal_id, :assigned_to, :assigned_at, :docket_name, :previous_task,
:docket_date, :added_by, :task_id, :action, :document_id, :assigned_by, :work_product].freeze
:docket_date, :added_by, :task_id, :action, :document_id, :assigned_by, :work_product, :started_at].freeze

attr_accessor(*ATTRS)
attr_writer :appeal
Expand Down Expand Up @@ -86,7 +86,8 @@ def self.from_vacols(record, appeal, user)
task_id: record.created_at ? record.vacols_id + "-" + record.created_at.strftime("%Y-%m-%d") : nil,
document_id: record.document_id,
assigned_by: record.assigned_by,
appeal: appeal
appeal: appeal,
started_at: appeal.appeal_views.find_by(user: user)&.created_at
)
end

Expand Down
2 changes: 2 additions & 0 deletions app/models/serializers/work_queue/legacy_task_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class WorkQueue::LegacyTaskSerializer
attribute :work_product
attribute :appeal_type
attribute :timeline_title
attribute :started_at

attribute :previous_task do |object|
{
assigned_on: object.previous_task.try(:assigned_at)
Expand Down
12 changes: 8 additions & 4 deletions app/models/serializers/work_queue/task_column_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ def self.serialize_attribute?(params, columns)
end
end

attribute :started_at do |object, params|
columns = [Constants.QUEUE_CONFIG.COLUMNS.CASE_DETAILS_LINK.name]

if serialize_attribute?(params, columns)
object.started_at
end
end

attribute :issue_count do |object, params|
columns = [Constants.QUEUE_CONFIG.COLUMNS.ISSUE_COUNT.name]

Expand Down Expand Up @@ -204,10 +212,6 @@ def self.serialize_attribute?(params, columns)
nil
end

attribute :started_at do
nil
end

attribute :created_at do
nil
end
Expand Down
22 changes: 0 additions & 22 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -257,22 +257,6 @@ def station_offices
RegionalOffice::STATIONS[station_id]
end

def current_case_assignments_with_views
appeals = current_case_assignments
opened_appeals = viewed_appeals(appeals.map(&:id))

appeal_streams = LegacyAppeal.fetch_appeal_streams(appeals)
appeal_stream_hearings = get_appeal_stream_hearings(appeal_streams)

appeals.map do |appeal|
appeal.to_hash(
viewed: opened_appeals[appeal.id],
issues: appeal.issues,
hearings: appeal_stream_hearings[appeal.id]
)
end
end

def current_case_assignments
self.class.appeal_repository.load_user_case_assignments_from_vacols(css_id)
end
Expand Down Expand Up @@ -415,12 +399,6 @@ def get_appeal_stream_hearings(appeal_streams)
end
end

def viewed_appeals(appeal_ids)
appeal_views.where(appeal_id: appeal_ids).each_with_object({}) do |appeal_view, object|
object[appeal_view.appeal_id] = true
end
end

def appeal_hearings(appeal_ids)
LegacyHearing.where(appeal_id: appeal_ids)
end
Expand Down
9 changes: 9 additions & 0 deletions app/workflows/tasks_for_appeal.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# frozen_string_literal: true

# Returns all tasks relevant to an appeal based on the user's role
# We only query vacols for legacy tasks if the user is a judge, attroney, or a users that can act on behalf of judges
# We also only return tasks assigned to a VSO or a vso employee is the user is a vso employee
# Because this is currently only called from the case details view of an appeal, we mark any tasks assigned to the
# requesting user as "in progress", indicating they have looked at the case and have presumably started their task
class TasksForAppeal
def initialize(appeal:, user:, user_role:)
@appeal = appeal
Expand All @@ -18,6 +23,10 @@ def call
# This change filters them out from the Queue page
tasks = all_tasks_except_for_decision_review_tasks

# Mark ama tasks in progress if any are assigned to the requesting user, indicating that they have started work on
# this task if they have gone to the case details page of this appeal
tasks.assigned.where(assigned_to: user).each(&:in_progress!)

return (legacy_appeal_tasks + tasks).uniq if appeal.is_a?(LegacyAppeal)

tasks
Expand Down
26 changes: 3 additions & 23 deletions client/app/queue/CaseDetailsLink.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,25 @@ import { bindActionCreators } from 'redux';
import { css } from 'glamor';

import { onReceiveAmaTasks } from './QueueActions';
import ApiUtil from '../util/ApiUtil';
import COPY from '../../COPY';
import USER_ROLE_TYPES from '../../constants/USER_ROLE_TYPES';
import { subHeadTextStyle } from './constants';
import Link from '@department-of-veterans-affairs/caseflow-frontend-toolkit/components/Link';

class CaseDetailsLink extends React.PureComponent {
onClick = (...args) => {
const { task, userRole } = this.props;

// when searching for a case, we only load appeal info, no tasks
if (task && task.status && task.status === 'assigned' && userRole === USER_ROLE_TYPES.colocated) {
const payload = {
data: {
task: {
status: 'in_progress'
}
}
};

ApiUtil.patch(`/tasks/${task.taskId}`, payload);
}

return this.props.onClick ? this.props.onClick(args) : true;
}
onClick = (...args) => this.props.onClick ? this.props.onClick(args) : true;

getLinkText = () => {
const {
task,
appeal,
userRole
appeal
} = this.props;

if (this.props.getLinkText) {
return this.props.getLinkText(appeal, task);
}

const linkStyling = css({
fontWeight: (task.status === 'assigned' && userRole === USER_ROLE_TYPES.colocated) ? 'bold' : null
fontWeight: task.startedAt ? null : 'bold'
});

return <span {...linkStyling} id={`veteran-name-for-task-${task.taskId}`}>
Expand Down
2 changes: 2 additions & 0 deletions client/app/queue/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ const taskAttributesFromRawTask = (task) => {
closestRegionalOffice: task.attributes.closest_regional_office,
createdAt: task.attributes.created_at,
closedAt: task.attributes.closed_at,
startedAt: task.attributes.started_at,
assigneeName: task.attributes.assignee_name,
assignedTo: {
cssId: task.attributes.assigned_to.css_id,
Expand Down Expand Up @@ -179,6 +180,7 @@ export const prepareLegacyTasksForStore = (tasks) => {
externalAppealId: task.attributes.external_appeal_id,
assignedOn: task.attributes.assigned_on,
closedAt: null,
startedAt: task.attributes.started_at,
assigneeName: task.attributes.assignee_name,
assignedTo: {
cssId: task.attributes.assigned_to.css_id,
Expand Down
2 changes: 2 additions & 0 deletions client/test/karma/queue/QueueLoadingScreen-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const serverData = {
previous_task: {
assigned_on: '2018-08-02T17:37:03.000Z'
},
started_at: '2018-08-02T17:37:03.000Z',
task_id: '3625593-2018-07-11',
label: 'Review',
user_id: 'BVANKUVALIS',
Expand Down Expand Up @@ -96,6 +97,7 @@ describe('QueueLoadingScreen', () => {
},
workProduct: 'OTD',
previousTaskAssignedOn: '2018-08-02T17:37:03.000Z',
startedAt: '2018-08-02T17:37:03.000Z',
status: 'Assigned',
decisionPreparedBy: null,
type: 'LegacyJudgeTask',
Expand Down
17 changes: 13 additions & 4 deletions spec/controllers/appeals_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -537,18 +537,27 @@
end

describe "GET appeals/:id.json" do
it "should succeed" do
appeal = create_legacy_appeal_with_hearings
let(:appeal) { create_legacy_appeal_with_hearings }
let!(:user) { User.authenticate!(roles: ["System Admin"]) }

User.authenticate!(roles: ["System Admin"])
get :show, params: { appeal_id: appeal.vacols_id }, as: :json
subject { get :show, params: { appeal_id: appeal.vacols_id }, as: :json }

it "should succeed" do
subject
appeal_json = JSON.parse(response.body)["appeal"]["attributes"]

assert_response :success
expect(appeal_json["available_hearing_locations"][0]["city"]).to eq "Holdrege"
expect(appeal_json["hearings"][0]["type"]).to eq "Video"
end

it "should create an appeal view for the user if it does not exist" do
expect(appeal.appeal_views.where(user: user).count).to eq 0
subject
expect(appeal.appeal_views.where(user: user).count).to eq 1
subject
expect(appeal.appeal_views.where(user: user).count).to eq 1
end
end

describe "GET veteran/:appeal_id" do
Expand Down
1 change: 1 addition & 0 deletions spec/controllers/tasks_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,7 @@
expect(colocated_task).to_not be_nil
expect(colocated_task["attributes"]["assigned_to"]["css_id"]).to eq colocated_user.css_id
expect(colocated_task["attributes"]["appeal_id"]).to eq appeal.id
expect(colocated_task["attributes"]["status"]).to eq Task.statuses[:in_progress]
end
end

Expand Down
3 changes: 1 addition & 2 deletions spec/feature/queue/case_details_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -722,8 +722,7 @@
)
end

scenario "displays task bold in queue",
skip: "https://circleci.com/gh/department-of-veterans-affairs/caseflow/65218, bat team investigated" do
scenario "displays task bold in queue" do
visit "/queue"
vet_name = assigned_task.appeal.veteran_full_name
fontweight_new = get_computed_styles("#veteran-name-for-task-#{assigned_task.id}", "font-weight")
Expand Down
41 changes: 23 additions & 18 deletions spec/models/legacy_tasks/attorney_legacy_task_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,36 @@
end

context "#from_vacols" do
subject do
AttorneyLegacyTask.from_vacols(
case_assignment,
LegacyAppeal.create(vacols_id: "1111"),
User.new(css_id: "USER_ID")
subject { AttorneyLegacyTask.from_vacols(case_assignment, appeal, user) }

let(:vacols_id) { "1111" }
let(:appeal) { LegacyAppeal.create(vacols_id: vacols_id) }
let(:user) { create(:user) }
let(:case_assignment) do
OpenStruct.new(
vacols_id: vacols_id,
date_due: 1.day.ago,
assigned_to_location_date: 5.days.ago,
created_at: 6.days.ago,
docket_date: nil
)
end

context "when there is information about the case assignment" do
let(:case_assignment) do
vacols_id = "1111"
OpenStruct.new(
vacols_id: vacols_id,
date_due: 1.day.ago,
assigned_to_location_date: 5.days.ago,
created_at: 6.days.ago,
docket_date: nil
)
end

it "sets all the fields correctly" do
expect(subject.user_id).to eq("USER_ID")
expect(subject.id).to eq("1111")
expect(subject.user_id).to eq(user.css_id)
expect(subject.id).to eq(vacols_id)
expect(subject.assigned_on).to eq 5.days.ago.to_date
expect(subject.task_id).to eq "1111-2015-01-24"
expect(subject.started_at).to eq nil
end

context "when the user has viewed the appeal before" do
before { AppealView.create(appeal: appeal, user: user, created_at: 5.days.ago) }

it "sets the started_at timetamp" do
expect(subject.started_at).to eq 5.days.ago
end
end
end
end
Expand Down
30 changes: 0 additions & 30 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -483,36 +483,6 @@
end
end

context "#current_case_assignments_with_views" do
subject { user.current_case_assignments_with_views[0] }

let!(:appeal) { create(:legacy_appeal, vacols_case: create(:case, :assigned, user: user)) }

it "returns nil when no cases have been viewed" do
is_expected.to include(
"vbms_id" => appeal.vbms_id,
"vacols_id" => appeal.vacols_id,
"veteran_full_name" => appeal.veteran_full_name,
"viewed" => nil
)
end

context "has hash with view" do
before do
AppealView.create(user_id: user.id, appeal: appeal)
end

it do
is_expected.to include(
"vbms_id" => appeal.vbms_id,
"vacols_id" => appeal.vacols_id,
"veteran_full_name" => appeal.veteran_full_name,
"viewed" => true
)
end
end
end

context ".from_session" do
subject { User.from_session(session) }
context "gets a user object from a session" do
Expand Down

0 comments on commit ba8b8ad

Please sign in to comment.