Skip to content

Commit

Permalink
Hotfix/appeals 46639 prodtest (#22389)
Browse files Browse the repository at this point in the history
* Initial commit and turning off queue tab variables used for the frontend pagination for the bulk assign tab for the specialty case team.

* Altered the queue actions to work with the new task selection action and a new redux action to remove tasks from a cached queue state. Also updated queue table to work with the redux caching instead of local state caching.

* Added in task selection function changes to TaskTable to work
with the altered task selection redux action. Also added the ability to pass down the redux cache property to queue table. Refactored the UnassignedCasesPage to allow for backend pagination of queue table instead of only working via frontend loaded data from the redux store.

* Added the queueTableCache reducer slice. Added a :advanced_on_docket trait to the task factory for specialty_case_team_assign_tasks. Added the caching combined reducer to the queue table reducers.

* Moved columnsFromConfig and createColumnObject functions out of QueueTableBuilder.jsx into a utils file so it can be used in multiple components around the app.

* Updated the setSelectionOfTaskOfUser to work with the new action and data that it should be expecting.

* Updated the selectedTasksSelector to work with the new task selection reducer and action.

* Added a parameter for useReduxCache for TaskTable to send down to queue table instead of always setting it to true. Removed some comments from the queueTableCacheSlice removeTaskIdsFromCache reducer method/action. Passed in the new useReduxCache property to TaskTable in the UnassignedCasesPage component for the sct bulk assign queue.

* Removed code out of QueueTableBuilder that is now in queueTableUtils.js.

* Fixed a bug if queueConfig was an empty hash in the UnassignedCasesPage component.

* Serializer optimizations for contested issues and issue categories. Also included request issues in the includes for the sct queue to take advantage of these optimizations.

* Fixed a bug where clear filters was not properly updating the get parameters anymore for queue table.

* Added cavc_type trait to the sct assign task factory.

* Fix code climate issues.

---------

Co-authored-by: = <tyler.broyles@va.gov>
  • Loading branch information
brandondorner and TylerBroyles authored Aug 2, 2024
1 parent 365948e commit 3eb4db5
Show file tree
Hide file tree
Showing 16 changed files with 450 additions and 179 deletions.
10 changes: 7 additions & 3 deletions app/models/appeal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,15 @@ def contested_claim?

category_substrings = %w[Contested Apportionment]

request_issues.active.any? do |request_issue|
category_substrings.any? do |substring|
request_issues.active.include?(request_issue) && request_issue.nonrating_issue_category&.include?(substring)
request_issues.each do |request_issue|
category_substrings.each do |substring|
if request_issue.active? && request_issue.nonrating_issue_category&.include?(substring)
return true
end
end
end

false
end

# :reek:RepeatedConditionals
Expand Down
6 changes: 5 additions & 1 deletion app/models/decision_review.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,11 @@ def veteran_full_name
end

def number_of_issues
request_issues.active.count
request_issues.count(&:active?)
end

def issue_categories
request_issues.select(&:active?).map(&:nonrating_issue_category)
end

def external_id
Expand Down
24 changes: 19 additions & 5 deletions app/models/queue_tabs/specialty_case_team_unassigned_tasks_tab.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,31 @@ def tasks
assigned_tasks
end

# Override task_includes to optimize the queue a bit
def task_includes
[
{ appeal: [
:request_issues,
:available_hearing_locations,
:claimants,
:work_mode,
:latest_informal_hearing_presentation_task
] },
:assigned_by,
:assigned_to,
:children,
:parent,
:attorney_case_reviews
]
end

def column_names
SpecialtyCaseTeam::COLUMN_NAMES
end

# This only affects bulk assign on the standard queue tab view
def allow_bulk_assign?
true
false
end

def hide_from_queue_table_view
Expand All @@ -37,8 +55,4 @@ def hide_from_queue_table_view
def no_task_limit
false
end

def custom_task_limit
60
end
end
6 changes: 1 addition & 5 deletions app/models/serializers/work_queue/task_column_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,7 @@ def self.serialize_attribute?(params, columns)
columns = [Constants.QUEUE_CONFIG.COLUMNS.ISSUE_TYPES.name]

if serialize_attribute?(params, columns)
if object.appeal.is_a?(LegacyAppeal)
object.appeal.issue_categories
else
object.appeal.request_issues.active.map(&:nonrating_issue_category)
end.join(",")
object.appeal.issue_categories.join(",")
end
end

Expand Down
6 changes: 1 addition & 5 deletions app/models/serializers/work_queue/task_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,7 @@ class WorkQueue::TaskSerializer
end

attribute :issue_types do |object|
if object.appeal.is_a?(LegacyAppeal)
object.appeal.issue_categories
else
object.appeal.request_issues.active.map(&:nonrating_issue_category)
end.join(",")
object.appeal.issue_categories.join(",")
end

attribute :external_hearing_id do |object|
Expand Down
9 changes: 7 additions & 2 deletions client/app/queue/QueueActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import ApiUtil from '../util/ApiUtil';
import { getMinutesToMilliseconds } from '../util/DateUtil';
import pluralize from 'pluralize';
import { keyBy, pick } from 'lodash';
import { removeTaskIdsFromCache } from './caching/queueTableCache.slice';

export const onReceiveQueue = (
{ tasks, amaTasks, appeals }
Expand Down Expand Up @@ -419,12 +420,13 @@ export const fetchTasksAndAppealsOfAttorney = (attorneyId, params) => (dispatch)
};

export const setSelectionOfTaskOfUser =
({ userId, taskId, selected }) => ({
({ userId, taskId, selected, task }) => ({
type: ACTIONS.SET_SELECTION_OF_TASK_OF_USER,
payload: {
userId,
taskId,
selected
selected,
task
}
});

Expand Down Expand Up @@ -507,6 +509,9 @@ export const initialSpecialtyCaseTeamAssignTasksToUser = ({
then((resp) => {
const receievedTasks = prepareAllTasksForStore(resp.tasks.data);

// Removes tasks from queue table cache if using redux caching instead of local component state
dispatch(removeTaskIdsFromCache({ taskIds }));

dispatch(onReceiveTasks(pick(receievedTasks, ['tasks', 'amaTasks'])));

dispatch(incrementTaskCountForAttorney({
Expand Down
59 changes: 53 additions & 6 deletions client/app/queue/QueueTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -353,10 +353,21 @@ export default class QueueTable extends React.PureComponent {

if (this.props.rowObjects.length) {
this.setState({ cachedResponses: { ...this.state.cachedResponses, [this.requestUrl()]: firstResponse } });

if (this.props.useReduxCache) {
this.props.updateReduxCache({ key: this.requestUrl(), value: firstResponse });
}

}
};

componentDidUpdate = (previousProps, previousState) => {
if (this.props.useReduxCache &&
(this.props.reduxCache[this.requestUrl()]?.tasks?.length !==
previousProps.reduxCache[this.requestUrl()]?.tasks?.length)) {
this.setState({ tasksFromApi: this.props.reduxCache[this.requestUrl()].tasks });
}

// Only refetch if the search query text changes
if (this.props.tabPaginationOptions &&
previousState.querySearchText !== this.props.tabPaginationOptions[QUEUE_CONFIG.SEARCH_QUERY_REQUEST_PARAM]) {
Expand Down Expand Up @@ -556,9 +567,29 @@ export default class QueueTable extends React.PureComponent {

deepLink = () => {
const base = `${window.location.origin}${window.location.pathname}`;
const tab = this.props.taskPagesApiEndpoint.split('?')[1];
const currentParams = new URLSearchParams(window.location.search);
const tableParams = new URLSearchParams(this.requestQueryString());
const tabParams = new URLSearchParams(this.props.taskPagesApiEndpoint.split('?')[1]);

// List of parameters that should be cleared if not present in tableParams
const paramsToClear = [
QUEUE_CONFIG.SEARCH_QUERY_REQUEST_PARAM,
`${QUEUE_CONFIG.FILTER_COLUMN_REQUEST_PARAM}[]`,
];

// Remove paramsToClear from currentParams if they are not in tableParams
paramsToClear.forEach((param) => {
if (!tableParams.has(param)) {
currentParams.delete(param);
}
});

// Merge tableParams and tabParams into currentParams, overwriting any duplicate keys
for (const [key, value] of [...tabParams.entries(), ...tableParams.entries()]) {
currentParams.set(key, value);
}

return `${base}?${tab}${this.requestQueryString()}`;
return `${base}?${currentParams.toString()}`;
};

// /organizations/vlj-support-staff/tasks?tab=on_hold
Expand Down Expand Up @@ -622,7 +653,8 @@ export default class QueueTable extends React.PureComponent {
const endpointUrl = this.requestUrl();

// If we already have the tasks cached then we set the state and return early.
const responseFromCache = this.state.cachedResponses[endpointUrl];
const responseFromCache = this.props.useReduxCache ? this.props.reduxCache[endpointUrl] :
this.state.cachedResponses[endpointUrl];

if (responseFromCache) {
this.setState({ tasksFromApi: responseFromCache.tasks });
Expand All @@ -643,11 +675,21 @@ export default class QueueTable extends React.PureComponent {
const preparedResponse = Object.assign(response.body, { tasks: preparedTasks });

this.setState({
cachedResponses: { ...this.state.cachedResponses, [endpointUrl]: preparedResponse },
// cachedResponses: { ...this.state.cachedResponses, [endpointUrl]: preparedResponse },
...(!this.props.useReduxCache && {
cachedResponses: {
...this.state.cachedResponses,
[endpointUrl]: preparedResponse
}
}),
tasksFromApi: preparedTasks,
loadingComponent: null
});

if (this.props.useReduxCache) {
this.props.updateReduxCache({ key: endpointUrl, value: preparedResponse });
}

this.updateAddressBar();
}).
catch(() => this.setState({ loadingComponent: null }));
Expand All @@ -669,7 +711,9 @@ export default class QueueTable extends React.PureComponent {
styling,
bodyStyling,
enablePagination,
useTaskPagesApi
useTaskPagesApi,
reduxCache,
useReduxCache
} = this.props;

let { totalTaskCount, numberOfPages, rowObjects, casesPerPage } = this.props;
Expand All @@ -682,7 +726,7 @@ export default class QueueTable extends React.PureComponent {

// If we already have the response cached then use the attributes of the response to set the pagination vars.
const endpointUrl = this.requestUrl();
const responseFromCache = this.state.cachedResponses[endpointUrl];
const responseFromCache = useReduxCache ? reduxCache[endpointUrl] : this.state.cachedResponses[endpointUrl];

if (responseFromCache) {
numberOfPages = responseFromCache.task_page_count;
Expand Down Expand Up @@ -843,6 +887,9 @@ HeaderRow.propTypes = FooterRow.propTypes = Row.propTypes = BodyRows.propTypes =
}),
onHistoryUpdate: PropTypes.func,
preserveFilter: PropTypes.bool,
useReduxCache: PropTypes.bool,
reduxCache: PropTypes.object,
updateReduxCache: PropTypes.func
};

Row.propTypes.rowObjects = PropTypes.arrayOf(PropTypes.object);
Expand Down
116 changes: 1 addition & 115 deletions client/app/queue/QueueTableBuilder.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,12 @@ import QueueTable from './QueueTable';
import TabWindow from '../components/TabWindow';
import Link from '@department-of-veterans-affairs/caseflow-frontend-toolkit/components/Link';
import QueueOrganizationDropdown from './components/QueueOrganizationDropdown';
import {
assignedToColumn,
assignedByColumn,
badgesColumn,
boardIntakeColumn,
completedToNameColumn,
daysOnHoldColumn,
daysSinceLastActionColumn,
daysSinceIntakeColumn,
receiptDateColumn,
daysWaitingColumn,
detailsColumn,
docketNumberColumn,
documentIdColumn,
lastActionColumn,
issueCountColumn,
issueTypesColumn,
readerLinkColumn,
readerLinkColumnWithNewDocsIcon,
regionalOfficeColumn,
taskColumn,
taskOwnerColumn,
taskCompletedDateColumn,
typeColumn,
vamcOwnerColumn
} from './components/TaskTableColumns';
import { tasksWithAppealsFromRawTasks } from './utils';

import COPY from '../../COPY';
import QUEUE_CONFIG from '../../constants/QUEUE_CONFIG';
import { css } from 'glamor';
import { isActiveOrganizationVHA } from '../queue/selectors';
import { columnsFromConfig } from './queueTableUtils';

const rootStyles = css({
'.usa-alert + &': {
Expand Down Expand Up @@ -86,94 +60,6 @@ const QueueTableBuilder = (props) => {
return config;
};

const filterValuesForColumn = (column) =>
column && column.filterable && column.filter_options;

const createColumnObject = (column, config, tasks) => {

const { requireDasRecord } = props;
const filterOptions = filterValuesForColumn(column);
const functionForColumn = {
[QUEUE_CONFIG.COLUMNS.APPEAL_TYPE.name]: typeColumn(
tasks,
filterOptions,
requireDasRecord
),
[QUEUE_CONFIG.COLUMNS.BADGES.name]: badgesColumn(tasks),
[QUEUE_CONFIG.COLUMNS.CASE_DETAILS_LINK.name]: detailsColumn(
tasks,
requireDasRecord,
config.userRole
),
[QUEUE_CONFIG.COLUMNS.DAYS_ON_HOLD.name]: daysOnHoldColumn(
requireDasRecord
),
[QUEUE_CONFIG.COLUMNS.DAYS_SINCE_LAST_ACTION.name]: daysSinceLastActionColumn(
requireDasRecord
),
[QUEUE_CONFIG.COLUMNS.DAYS_WAITING.name]: daysWaitingColumn(
requireDasRecord
),
[QUEUE_CONFIG.COLUMNS.DOCKET_NUMBER.name]: docketNumberColumn(
tasks,
filterOptions,
requireDasRecord
),
[QUEUE_CONFIG.COLUMNS.DOCUMENT_COUNT_READER_LINK.name]: readerLinkColumn(
requireDasRecord,
true
),
[QUEUE_CONFIG.COLUMNS.DOCUMENT_ID.name]: documentIdColumn(),
[QUEUE_CONFIG.COLUMNS.ISSUE_COUNT.name]: issueCountColumn(
tasks,
filterOptions,
requireDasRecord
),
[QUEUE_CONFIG.COLUMNS.ISSUE_TYPES.name]: issueTypesColumn(
tasks,
filterOptions,
requireDasRecord
),
[QUEUE_CONFIG.COLUMNS.READER_LINK_WITH_NEW_DOCS_ICON.
name]: readerLinkColumnWithNewDocsIcon(requireDasRecord),
[QUEUE_CONFIG.COLUMNS.REGIONAL_OFFICE.name]: regionalOfficeColumn(
tasks,
filterOptions
),
[QUEUE_CONFIG.COLUMNS.TASK_ASSIGNEE.name]: assignedToColumn(
tasks,
filterOptions
),
[QUEUE_CONFIG.COLUMNS.BOARD_INTAKE.name]: boardIntakeColumn(
filterOptions
),
[QUEUE_CONFIG.COLUMNS.LAST_ACTION.name]: lastActionColumn(
tasks,
filterOptions
),
[QUEUE_CONFIG.COLUMNS.TASK_OWNER.name]: taskOwnerColumn(
filterOptions
),
[QUEUE_CONFIG.COLUMNS.VAMC_OWNER.name]: vamcOwnerColumn(
tasks,
filterOptions
),
[QUEUE_CONFIG.COLUMNS.TASK_ASSIGNER.name]: completedToNameColumn(),
[QUEUE_CONFIG.COLUMNS.TASK_ASSIGNED_BY.name]: assignedByColumn(),
[QUEUE_CONFIG.COLUMNS.TASK_CLOSED_DATE.name]: taskCompletedDateColumn(),
[QUEUE_CONFIG.COLUMNS.TASK_TYPE.name]: taskColumn(tasks, filterOptions),
[QUEUE_CONFIG.COLUMNS.DAYS_SINCE_INTAKE.name]: daysSinceIntakeColumn(requireDasRecord),
[QUEUE_CONFIG.COLUMNS.RECEIPT_DATE_INTAKE.name]: receiptDateColumn(),
};

return functionForColumn[column.name];
};

const columnsFromConfig = (config, tabConfig, tasks) =>
(tabConfig.columns || []).map((column) =>
createColumnObject(column, config, tasks)
);

const taskTableTabFactory = (tabConfig, config) => {
const savedPaginationOptions = storedPaginationOptions;
const tasks = tasksWithAppealsFromRawTasks(tabConfig.tasks);
Expand Down
Loading

0 comments on commit 3eb4db5

Please sign in to comment.