Skip to content

Commit

Permalink
MHV-65340 Handled API failure; Added a spinner (#33686)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmoyer-va authored Jan 6, 2025
1 parent 0361c19 commit c3d2a08
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 38 deletions.
12 changes: 12 additions & 0 deletions src/applications/mhv-medical-records/actions/images.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,20 @@ import {
getImageRequestStatus,
getImageList,
getBbmiNotificationStatus,
requestImagingStudy,
} from '../api/MrApi';

export const requestImages = studyId => async dispatch => {
try {
dispatch({ type: Actions.Images.SET_REQUEST_API_FAILED, payload: false });
const response = await requestImagingStudy(studyId);
dispatch({ type: Actions.Images.REQUEST_IMAGE_STUDY, response });
} catch (error) {
dispatch({ type: Actions.Images.SET_REQUEST_API_FAILED, payload: true });
throw error;
}
};

export const fetchImageRequestStatus = () => async dispatch => {
try {
const response = await getImageRequestStatus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ import DownloadSuccessAlert from '../shared/DownloadSuccessAlert';
import {
fetchImageRequestStatus,
fetchBbmiNotificationStatus,
requestImages,
} from '../../actions/images';
import { requestImagingStudy } from '../../api/MrApi';
import useAlerts from '../../hooks/use-alerts';

const RadiologyDetails = props => {
Expand Down Expand Up @@ -67,13 +67,16 @@ const RadiologyDetails = props => {
// State to manage the dynamic backoff polling interval
const [pollInterval, setPollInterval] = useState(2000);

const [processingRequest, setProcessingRequest] = useState(false);

const radiologyDetails = useSelector(
state => state.mr.labsAndTests.labsAndTestsDetails,
);
const studyJobs = useSelector(state => state.mr.images.imageStatus);
const notificationStatus = useSelector(
state => state.mr.images.notificationStatus,
);
const {
imageStatus: studyJobs,
notificationStatus,
imageRequestApiFailed,
} = useSelector(state => state.mr.images);

const activeAlert = useAlerts(dispatch);

Expand Down Expand Up @@ -115,13 +118,24 @@ const RadiologyDetails = props => {
[studyJobs, radiologyDetails.studyId],
);

useEffect(
() => {
if (imageRequestApiFailed) {
setProcessingRequest(false);
}
},
[imageRequestApiFailed],
);

useEffect(
() => {
let timeoutId;
if (
studyJob?.status === studyJobStatus.NEW ||
studyJob?.status === studyJobStatus.PROCESSING
) {
setProcessingRequest(false);

timeoutId = setTimeout(() => {
dispatch(fetchImageRequestStatus());
// Increase the polling interval by 5% on each iteration, capped at 30 seconds
Expand Down Expand Up @@ -179,9 +193,8 @@ ${record.results}`;
};

const makeImageRequest = async () => {
await requestImagingStudy(radiologyDetails.studyId);
// After requesting the study, update the status.
dispatch(fetchImageRequestStatus());
setProcessingRequest(true);
dispatch(requestImages(radiologyDetails.studyId));
setIsImageRequested(true);
};

Expand Down Expand Up @@ -232,35 +245,35 @@ ${record.results}`;
</>
);

const imageAlertProcessing = imageRequest => (
<>
{requestNote()}
<va-alert
status="info"
visible
aria-live="polite"
data-testid="image-request-progress-alert"
>
<h3
aria-describedby="in-progress-description"
ref={processingAlertHeadingRef}
const imageAlertProcessing = imageRequest => {
const percent =
imageRequest.status === studyJobStatus.NEW
? 0
: imageRequest.percentComplete;
return (
<>
{requestNote()}
<va-alert
status="info"
visible
aria-live="polite"
data-testid="image-request-progress-alert"
>
Image request
</h3>
<p id="in-progress-description" className="sr-only">
in progress{' '}
</p>
<p>{imageRequest.percentComplete}% complete</p>
<va-progress-bar
percent={
imageRequest.status === studyJobStatus.NEW
? 0
: imageRequest.percentComplete
}
/>
</va-alert>
</>
);
<h3
aria-describedby="in-progress-description"
ref={processingAlertHeadingRef}
>
Image request
</h3>
<p id="in-progress-description" className="sr-only">
in progress{' '}
</p>
<p>{percent}% complete</p>
<va-progress-bar percent={percent} />
</va-alert>
</>
);
};

const imageAlertComplete = () => {
const endDateParts = formatDateAndTime(
Expand Down Expand Up @@ -324,6 +337,16 @@ ${record.results}`;

const imageStatusContent = () => {
if (radiologyDetails.studyId) {
if (processingRequest) {
return (
<va-loading-indicator
message="Loading..."
setFocus
data-testid="loading-indicator"
/>
);
}

if (activeAlert && activeAlert.type === ALERT_TYPE_IMAGE_STATUS_ERROR) {
return imageAlert(ERROR_TRY_LATER);
}
Expand All @@ -336,7 +359,8 @@ ${record.results}`;
studyJob?.status === studyJobStatus.PROCESSING) &&
imageAlertProcessing(studyJob)}
{studyJob?.status === studyJobStatus.COMPLETE && imageAlertComplete()}
{studyJob?.status === studyJobStatus.ERROR &&
{(imageRequestApiFailed ||
studyJob?.status === studyJobStatus.ERROR) &&
imageAlertError(studyJob)}
{notificationContent()}
</>
Expand Down
15 changes: 14 additions & 1 deletion src/applications/mhv-medical-records/reducers/images.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,18 @@ const initialState = {
imageList: [],

notificationStatus: undefined,

imageRequestApiFailed: false,
};

export const imagesReducer = (state = initialState, action) => {
switch (action.type) {
case Actions.Images.REQUEST_IMAGE_STUDY: {
return {
...state,
imageStatus: [action.response],
};
}
case Actions.Images.GET_IMAGE_REQUEST_STATUS: {
return {
...state,
Expand All @@ -29,7 +37,12 @@ export const imagesReducer = (state = initialState, action) => {
notificationStatus: action?.payload?.flag ?? null,
};
}

case Actions.Images.SET_REQUEST_API_FAILED: {
return {
...state,
imageRequestApiFailed: action?.payload ?? false,
};
}
default:
return state;
}
Expand Down
1 change: 1 addition & 0 deletions src/applications/mhv-medical-records/util/actionTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export const Actions = {
REQUEST_IMAGE_STUDY: 'MR_IMAGES_REQUEST_IMAGE_STUDY',
GET_IMAGE_STUDIES: 'MR_IMAGES_GET_IMAGE_STUDIES',
GET_NOTIFICATION_STATUS: 'MR_IMAGES_GET_NOTIFICATION_STATUS',
SET_REQUEST_API_FAILED: 'MR_IMAGES_SET_REQUEST_API_FAILED',
},
SelfEntered: {
GET_ACTIVITY_JOURNAL: 'MR_SELF_ENTERED_GET_ACTIVITY_JOURNAL',
Expand Down

0 comments on commit c3d2a08

Please sign in to comment.