Skip to content

Commit

Permalink
Merge branch 'master' into feature/appeals-45972
Browse files Browse the repository at this point in the history
  • Loading branch information
mikefinneran committed Jun 26, 2024
2 parents 44651cf + b75d2f0 commit 1a49d3c
Show file tree
Hide file tree
Showing 59 changed files with 2,186 additions and 2,392 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
- name: install node version
uses: actions/setup-node@v4
with:
node-version: '14.20.0'
node-version: '16.16.0'

# If we don't explicitly set this, the runner doesn't find the path when trying to save the cache
- name: Set yarn cache directory
Expand Down Expand Up @@ -286,7 +286,7 @@ jobs:
- name: install node version
uses: actions/setup-node@v4
with:
node-version: '14.20.0'
node-version: '16.16.0'

- name: validate node version
run: ./ci-bin/capture-log "node -v"
Expand Down Expand Up @@ -339,7 +339,7 @@ jobs:
- name: install node version
uses: actions/setup-node@v4
with:
node-version: '14.20.0'
node-version: '16.16.0'

- name: Install Node Dependencies
run: ./ci-bin/capture-log "cd client && yarn install --frozen-lockfile"
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
14.20.0
16.16.0
1 change: 1 addition & 0 deletions .reek.yml
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ detectors:
- UpdateCachedAppealsAttributesJob
- Veteran
- LegacyDocket
- Test::UsersController
TooManyConstants:
exclude:
- Fakes::BGSServicePOA
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ RUN apt -y update && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt -y update

#install node
# Install node
RUN mkdir /usr/local/nvm
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION 14.20.0
ENV NODE_VERSION 16.16.0
ENV NVM_INSTALL_PATH $NVM_DIR/versions/node/v$NODE_VERSION
RUN curl --silent -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
RUN source $NVM_DIR/nvm.sh \
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/metrics/v2/logs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def create
private

def metrics_not_saved
render json: { error_code: "Metrics not saved for user" }, status: :unprocessable_entity
render json: { error_code: "Metrics not saved for user" }, status: :accepted
end

def allowed_params
Expand Down
9 changes: 8 additions & 1 deletion app/controllers/test/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
CaseflowCertification::Application.load_tasks

class Test::UsersController < ApplicationController
before_action :require_demo, only: [:set_user, :set_end_products, :reseed, :toggle_feature]
before_action :require_demo, only: [:set_user, :set_end_products, :reseed, :optional_seed, :toggle_feature]
before_action :require_global_admin, only: :log_in_as_user
skip_before_action :deny_vso_access, only: [:index, :set_user, :show]

Expand Down Expand Up @@ -110,6 +110,13 @@ def reseed
head :ok
end

def optional_seed
return unless Rails.deploy_env?(:demo)

system "bundle exec rake db:seed:optional"
head :ok
end

def toggle_feature
params[:enable]&.each do |f|
FeatureToggle.enable!(f[:value])
Expand Down
5 changes: 4 additions & 1 deletion app/models/appeal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,6 @@ def clone_task_tree(parent_appeal, user_css_id)
parent_ordered_tasks = parent_appeal.tasks.order(:created_at)
# define hash to store parent/child relationship values
task_parent_to_child_hash = {}

while parent_appeal.tasks.count != tasks.count && !parent_appeal.tasks.nil?
# cycle each task in the parent
parent_ordered_tasks.each do |task|
Expand Down Expand Up @@ -698,6 +697,10 @@ def cavc
court_remand?
end

def predocketed?
tasks.select { |task| task.class.name == "PreDocketTask" && task.open? }
end

def vha_predocket_needed?
request_issues.active.any?(&:vha_predocket?)
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/bgs_power_of_attorney.rb
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def save_with_updated_bgs_record!

def update_ihp_task
related_appeals.each do |appeal|
InformalHearingPresentationTask.update_to_new_poa(appeal) if appeal.active?
InformalHearingPresentationTask.update_to_new_poa(appeal) if appeal.active? && !appeal.predocketed?
end
end

Expand Down
2 changes: 0 additions & 2 deletions app/models/task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -957,8 +957,6 @@ def status_is_valid_on_create
if status != Constants.TASK_STATUSES.assigned
fail Caseflow::Error::InvalidStatusOnTaskCreate, task_type: type
end

true
end

def assignee_status_is_valid_on_create
Expand Down
10 changes: 9 additions & 1 deletion app/models/tasks/schedule_hearing_colocated_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,18 @@ def just_completed_ama_organization_task?
assigned_to.is_a?(Organization)
end

# Selects all judge tasks that are NOT QualityReviewJudgeTasks
def handle_judge_tasks!
judge_tasks = JudgeTask.open.where(appeal: appeal)
non_quality_review_judge_tasks = judge_tasks.to_a.reject { |task| task.type == "JudgeQualityReviewTask" }
# Converts array to active record association and runs cancel_task_and_child_subtasks
JudgeTask.where(id: non_quality_review_judge_tasks.map(&:id)).find_each(&:cancel_task_and_child_subtasks)
end

def send_to_hearings_branch
parent = DistributionTask.create!(appeal: appeal, parent: appeal.root_task)
ScheduleHearingTask.create!(appeal: appeal, parent: parent)
JudgeTask.open.where(appeal: appeal).find_each(&:cancel_task_and_child_subtasks)
handle_judge_tasks!
DistributedCase.find_by(case_id: appeal.uuid)&.rename_for_redistribution!
end
end
4 changes: 4 additions & 0 deletions app/models/tasks/schedule_hearing_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ def default_instructions
end

def create_parent_hearing_task
return true unless parent

if parent.type != HearingTask.name
self.parent = HearingTask.create(appeal: appeal, parent: parent)
end

true
end

def verify_vso_can_change_hearing_to_virtual!(params)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ def cancel_tasks_blocking_distribution

def verify_appeal_distributable
if DistributionTask.open.where(appeal: appeal).empty?
return true if appeal.appeal_split_process == true

fail(Caseflow::Error::IneligibleForBlockedSpecialCaseMovement, appeal_id: appeal.id)
end
end
Expand Down
27 changes: 15 additions & 12 deletions app/models/tasks/special_case_movement_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,25 @@ def self.label
private

def distribute_to_judge
Task.transaction do
JudgeAssignTask.create!(appeal: appeal,
parent: appeal.root_task,
assigned_to: assigned_to,
assigned_by: assigned_by,
instructions: instructions)
# We don't want the judge to have to worry about the SpecialCaseMovementTask,
# so we assign it to the SCM user that assigned this.
update!(status: Constants.TASK_STATUSES.completed, assigned_to: assigned_by)
# For now, we expect the parent to always be the distribution task
# so we don't worry about distribution task explicitly
parent.update!(status: Constants.TASK_STATUSES.completed)
unless appeal.appeal_split_process
Task.transaction do
JudgeAssignTask.create!(appeal: appeal,
parent: appeal.root_task,
assigned_to: assigned_to,
assigned_by: assigned_by,
instructions: instructions)
# We don't want the judge to have to worry about the SpecialCaseMovementTask,
# so we assign it to the SCM user that assigned this.
update!(status: Constants.TASK_STATUSES.completed, assigned_to: assigned_by)
# For now, we expect the parent to always be the distribution task
# so we don't worry about distribution task explicitly
parent.update!(status: Constants.TASK_STATUSES.completed)
end
end
end

def verify_appeal_distributable
return true if appeal.appeal_split_process
if !appeal.ready_for_distribution?
fail(Caseflow::Error::IneligibleForSpecialCaseMovement, appeal_id: appeal.id)
end
Expand Down
2 changes: 1 addition & 1 deletion app/services/external_api/va_dot_gov_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ def send_facilities_requests(ids:, query:)
response = nil

until remaining_ids.empty? || response.try(:next?) == false || response.try(:success?) == false
response = send_facilities_request(query: query.merge(page: page, perPage: 200)).merge(response)
response = send_facilities_request(query: query.merge(page: page, per_page: 200)).merge(response)

remaining_ids -= response.data.pluck(:facility_id)

Expand Down
18 changes: 18 additions & 0 deletions app/workflows/ihp_tasks_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ def initialize(parent)

def create_ihp_tasks!
appeal = @parent.appeal

if appeal.status.send(:open_pre_docket_task?)
cancel_any_existing_ihp_tasks(appeal)
return []
end

appeal.representatives.select { |org| org.should_write_ihp?(appeal) }.map do |vso_organization|
# For some RAMP appeals, this method may run twice.
existing_task = InformalHearingPresentationTask.find_by(
Expand All @@ -22,4 +28,16 @@ def create_ihp_tasks!
)
end
end

private

def cancel_any_existing_ihp_tasks(appeal)
appeal.representatives.select { |org| org.should_write_ihp?(appeal) }.each do |vso_organization|
existing_task = InformalHearingPresentationTask.find_by(
appeal: appeal,
assigned_to: vso_organization
)
existing_task&.update!(status: Constants.TASK_STATUSES.cancelled)
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def create_send_final_notification_letter_tasks
appeal: @task.appeal,
parent: @task.parent,
assigned_to: Organization.find_by_url("clerk-of-the-board"),
assigned_by: current_user
assigned_by: @task.assigned_by
)
# sfnlt.instructions.push(instructions)
sfnlt.update!(status: Constants.TASK_STATUSES.assigned)
Expand Down
26 changes: 24 additions & 2 deletions client/app/components/LoadingDataDisplay.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,38 @@ import LoadingScreen from './LoadingScreen';
import StatusMessage from './StatusMessage';
import COPY from '../../COPY';
import { recordAsyncMetrics } from '../util/Metrics';
import { ExternalLinkIcon } from './icons';
import { css } from 'glamor';
import Link from './Link';

const ICON_POSITION_FIX = css({ position: 'relative', top: 3 });

const PROMISE_RESULTS = {
SUCCESS: 'SUCCESS',
FAILURE: 'FAILURE'
};

const ESCALATION_FORM_URL = 'https://leaf.va.gov/VBA/335/sensitive_level_access_request/';

const accessDeniedTitle = { title: COPY.ACCESS_DENIED_TITLE };
const accessDeniedMsg = <div>
It looks like you do not have the necessary level of access to view this information.<br />
Please check with your application administrator before trying again.</div>;
VBA employs a sensitive access system and to access records at any designated level requires approval for the same or
higher-level access.<br />
You are receiving this message because you do not have an authorized access level required to view this page.<br />
<br />
To request access, please click the button below
<div>
<Link href={ESCALATION_FORM_URL}>
<button className="btn btn-default">Request Access &nbsp;
<span {...ICON_POSITION_FIX}><ExternalLinkIcon /></span>
</button>
</Link>
</div>
<br />
If you have any questions or need assistance with the request form linked above,
please contact the Restricted Portfolio Management team at
<a href="mailto:VBA.RPM@va.gov">VBA.RPM@va.gov</a>.
</div>;

const duplicateNumberTitle = { title: COPY.DUPLICATE_PHONE_NUMBER_TITLE };
const duplicateNumberMsg = <div>
Expand Down
2 changes: 1 addition & 1 deletion client/app/queue/cavc/AddCavcDatesModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ const mapStateToProps = (state, ownProps) => ({
highlightInvalid: state.ui.highlightFormItems,
error: state.ui.messages.error,
// eslint-disable-next-line camelcase
decisionType: state.queue.appealDetails[ownProps.appealId].cavcRemand?.cavc_decision_type
decisionType: state.queue.appealDetails[ownProps.appealId]?.cavcRemand?.cavc_decision_type
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
Expand Down
32 changes: 14 additions & 18 deletions client/app/reader/PdfFile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ export class PdfFile extends React.PureComponent {
file: this.props.file,
documentType: this.props.documentType,
prefetchDisabled: this.props.featureToggles.prefetchDisabled,
overscan: this.props.windowingOverscan
overscan: this.props.windowingOverscan,
isPageVisible: this.props.isVisible,
name: null
};
}

Expand Down Expand Up @@ -467,32 +469,26 @@ export class PdfFile extends React.PureComponent {
clearTimeout(this.scrollTimer);
}

this.scrollTimer = setTimeout(() => {
const scrollStart = performance.now();
const scrollStart = performance.now();

const data = {
overscan: this.props.windowingOverscan,
documentType: this.props.documentType,
pageCount: this.props.pdfDocument.numPages,
pageIndex: this.pageIndex,
prefetchDisabled: this.props.featureToggles.prefetchDisabled,
start: scrollStart,
end: performance.now()
};
this.scrollTimer = setTimeout(() => {
const scrollEnd = performance.now();
const scrollMessage = `Scroll to page ${this.currentPage + 1}
(${(Math.round(this.scrollLeft * 100) / 100).toFixed(2)},
${(Math.round(this.scrollTop * 100) / 100).toFixed(2)})`;

const posx = (Math.round(this.scrollLeft * 100) / 100).toFixed(2);
const posy = (Math.round(this.scrollTop * 100) / 100).toFixed(2);
this.metricsAttributes.name = scrollMessage;

storeMetrics(
this.props.documentId,
this.metricsAttributes,
{
message: `Scroll to position ${posx}, ${posy}`,
message: scrollMessage,
type: 'performance',
product: 'reader',
start: new Date(performance.timeOrigin + data.start),
end: new Date(performance.timeOrigin + data.end),
duration: data.start ? data.end - data.start : 0
start: new Date(performance.timeOrigin + scrollStart),
end: new Date(performance.timeOrigin + scrollEnd),
duration: scrollStart ? scrollEnd - scrollStart : 0
},
this.metricsIdentifier,
);
Expand Down
12 changes: 12 additions & 0 deletions client/app/reader/PdfPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ export class PdfPage extends React.PureComponent {
this.isDrawing = false;
this.renderTask = null;
this.marks = [];

this.metricsAttributes = {
documentId: this.props.documentId,
numPagesInDoc: null,
pageIndex: this.props.pageIndex,
file: this.props.file,
documentType: this.props.documentType,
prefetchDisabled: this.props.featureToggles.prefetchDisabled,
overscan: this.props.windowingOverscan,
isPageVisible: this.props.isVisible,
name: null
};
}

getPageContainerRef = (pageContainer) => (this.pageContainer = pageContainer);
Expand Down
3 changes: 1 addition & 2 deletions client/app/reader/ReaderLoadingScreen.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ export class ReaderLoadingScreen extends React.Component {
this.props.onReceiveAnnotations(annotations);
}).
catch((err) => {
// allow HTTP errors to fall on the floor via the console.
console.error(new Error(`Problem with GET /reader/appeal/${this.props.vacolsId}/documents?json ${err}`));
throw err;
});
}

Expand Down
Loading

0 comments on commit 1a49d3c

Please sign in to comment.