Skip to content

Commit

Permalink
Phase 8 - Refactor shared actions and selectors to shared directory (#…
Browse files Browse the repository at this point in the history
…34021)

* refactor shared actions and selectors to shared directory

* refactor shared actions and selectors to shared directory

---------

Co-authored-by: Tony Williams <[email protected]>
  • Loading branch information
vbahinwillit and Tony Williams authored Jan 13, 2025
1 parent f71f74b commit 75b6da7
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 195 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ import InfoAlert from '../../components/InfoAlert';
import RequestAppointmentLayout from '../../components/RequestAppointmentLayout';
import { FETCH_STATUS, GA_PREFIX } from '../../utils/constants';
import { scrollAndFocus } from '../../utils/scrollAndFocus';
import {
fetchPendingAppointments,
startNewAppointmentFlow,
} from '../redux/actions';
import { getRequestedAppointmentListInfo } from '../redux/selectors';
import { startNewAppointmentFlow } from '../redux/actions';
import { fetchPendingAppointments } from '../../redux/actions';
import { getRequestedAppointmentListInfo } from '../../redux/selectors';
import NoAppointments from './NoAppointments';

export default function RequestedAppointmentsList({ hasTypeChanged }) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import { useDispatch, useSelector } from 'react-redux';
import { Route, Switch, useHistory, useLocation } from 'react-router-dom';
import CernerAlert from '../../../components/CernerAlert';
import WarningNotification from '../../../components/WarningNotification';
import { selectFeatureBreadcrumbUrlUpdate } from '../../../redux/selectors';
import {
selectFeatureBreadcrumbUrlUpdate,
selectPendingAppointments,
} from '../../../redux/selectors';
import { APPOINTMENT_STATUS } from '../../../utils/constants';
import { scrollAndFocus } from '../../../utils/scrollAndFocus';
import { selectPendingAppointments } from '../../redux/selectors';
import RequestedAppointmentsPage from '../RequestedAppointmentsPage/RequestedAppointmentsPage';
// import CernerTransitionAlert from '../../../components/CernerTransitionAlert';
// import { selectPatientFacilities } from '~/platform/user/cerner-dsot/selectors';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,18 @@ import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { recordEvent } from '@department-of-veterans-affairs/platform-monitoring/exports';
import classNames from 'classnames';
import InfoAlert from '../../../components/InfoAlert';
import RequestAppointmentLayout from '../../../components/RequestAppointmentLayout';
import { fetchPendingAppointments } from '../../../redux/actions';
import { getRequestedAppointmentListInfo } from '../../../redux/selectors';
import {
APPOINTMENT_STATUS,
FETCH_STATUS,
GA_PREFIX,
} from '../../../utils/constants';
import { scrollAndFocus } from '../../../utils/scrollAndFocus';
import RequestAppointmentLayout from '../../../components/RequestAppointmentLayout';
import BackendAppointmentServiceAlert from '../../components/BackendAppointmentServiceAlert';
import NoAppointments from '../../components/NoAppointments';
import {
fetchPendingAppointments,
startNewAppointmentFlow,
} from '../../redux/actions';
import { getRequestedAppointmentListInfo } from '../../redux/selectors';
import { startNewAppointmentFlow } from '../../redux/actions';

export default function RequestedAppointmentsPage({ hasTypeChanged }) {
const {
Expand Down
165 changes: 22 additions & 143 deletions src/applications/vaos/appointment-list/redux/actions.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,48 @@
/* eslint-disable no-prototype-builtins */
import moment from 'moment';
import * as Sentry from '@sentry/browser';
import { recordEvent } from '@department-of-veterans-affairs/platform-monitoring/exports';
import * as Sentry from '@sentry/browser';
import moment from 'moment';
import {
selectFeatureVAOSServiceCCAppointments,
selectFeatureVAOSServiceRequests,
selectFeatureVAOSServiceVAAppointments,
selectSystemIds,
} from '../../redux/selectors';
import {
GA_PREFIX,
APPOINTMENT_TYPES,
GA_PREFIX,
VIDEO_TYPES,
} from '../../utils/constants';
import { recordItemsRetrieved } from '../../utils/events';
import {
selectSystemIds,
selectFeatureVAOSServiceRequests,
selectFeatureVAOSServiceCCAppointments,
selectFeatureVAOSServiceVAAppointments,
} from '../../redux/selectors';

import {
getLocation,
getLocations,
getLocationSettings,
} from '../../services/location';
import { getLocation, getLocationSettings } from '../../services/location';

import {
cancelAppointment,
fetchAppointments,
fetchBookedAppointment,
fetchRequestById,
getAppointmentRequests,
getVAAppointmentLocationId,
isVideoHome,
fetchRequestById,
fetchBookedAppointment,
cancelAppointment,
} from '../../services/appointment';

import { captureError, has400LevelError } from '../../utils/error';
import {
FETCH_FACILITY_LIST_DATA_SUCCEEDED,
FETCH_PENDING_APPOINTMENTS_FAILED,
FETCH_PENDING_APPOINTMENTS_SUCCEEDED,
getAdditionalFacilityInfo,
getAdditionalFacilityInfoV2,
} from '../../redux/actions';
import {
STARTED_NEW_APPOINTMENT_FLOW,
STARTED_NEW_VACCINE_FLOW,
} from '../../redux/sitewide';
import { selectAppointmentById } from './selectors';
import { fetchHealthcareServiceById } from '../../services/healthcare-service';
import { captureError, has400LevelError } from '../../utils/error';
import { selectAppointmentById } from './selectors';

export const FETCH_FUTURE_APPOINTMENTS = 'vaos/FETCH_FUTURE_APPOINTMENTS';
export const FETCH_PENDING_APPOINTMENTS = 'vaos/FETCH_PENDING_APPOINTMENTS';
export const FETCH_PENDING_APPOINTMENTS_FAILED =
'vaos/FETCH_PENDING_APPOINTMENTS_FAILED';
export const FETCH_PENDING_APPOINTMENTS_SUCCEEDED =
'vaos/FETCH_PENDING_APPOINTMENTS_SUCCEEDED';
export const FETCH_FUTURE_APPOINTMENTS_FAILED =
'vaos/FETCH_FUTURE_APPOINTMENTS_FAILED';
export const FETCH_FUTURE_APPOINTMENTS_SUCCEEDED =
Expand Down Expand Up @@ -77,63 +75,12 @@ export const CANCEL_APPOINTMENT_CONFIRMED_FAILED =
'vaos/CANCEL_APPOINTMENT_CONFIRMED_FAILED';
export const CANCEL_APPOINTMENT_CLOSED = 'vaos/CANCEL_APPOINTMENT_CLOSED';

export const FETCH_FACILITY_LIST_DATA_SUCCEEDED =
'vaos/FETCH_FACILITY_LIST_DATA_SUCCEEDED';

export const FETCH_FACILITY_SETTINGS = 'vaos/FETCH_FACILITY_SETTINGS';
export const FETCH_FACILITY_SETTINGS_FAILED =
'vaos/FETCH_FACILITY_SETTINGS_FAILED';
export const FETCH_FACILITY_SETTINGS_SUCCEEDED =
'vaos/FETCH_FACILITY_SETTINGS_SUCCEEDED';

/*
* The facility data we get back from the various endpoints for
* requests and appointments does not have basics like address or phone.
*
* We want to show that basic info on the list page, so this goes and fetches
* it separately, but doesn't block the list page from displaying
*/
async function getAdditionalFacilityInfo(futureAppointments) {
// Get facility ids from non-VA appts or requests
const nonVaFacilityAppointmentIds = futureAppointments
.filter(
appt => !appt.vaos?.isVideo && (appt.vaos?.isCommunityCare || !appt.vaos),
)
.map(appt => appt.facilityId || appt.facility?.facilityCode);

// Get facility ids from VA appointments
const vaFacilityAppointmentIds = futureAppointments
.filter(appt => appt.vaos && !appt.vaos.isCommunityCare)
.map(getVAAppointmentLocationId);

const uniqueFacilityIds = new Set(
[...nonVaFacilityAppointmentIds, ...vaFacilityAppointmentIds].filter(
id => !!id,
),
);
let facilityData = null;
if (uniqueFacilityIds.size > 0) {
facilityData = await getLocations({
facilityIds: Array.from(uniqueFacilityIds),
});
}

return facilityData;
}

/**
* Function to retrieve facility information from the appointment
* record when using the v2 api.
*
* @param {*} appointments
*/
function getAdditionalFacilityInfoV2(appointments) {
// Facility information included with v2 appointment api call.
return appointments
?.map(appt => appt?.vaos?.facilityData ?? null)
.filter(n => n);
}

export function fetchFutureAppointments({ includeRequests = true } = {}) {
return async (dispatch, getState) => {
const featureVAOSServiceRequests = selectFeatureVAOSServiceRequests(
Expand Down Expand Up @@ -288,74 +235,6 @@ export function fetchFutureAppointments({ includeRequests = true } = {}) {
};
}

export function fetchPendingAppointments() {
return async (dispatch, getState) => {
try {
dispatch({
type: FETCH_PENDING_APPOINTMENTS,
});

const state = getState();
const featureVAOSServiceRequests = selectFeatureVAOSServiceRequests(
state,
);

const pendingAppointments = await getAppointmentRequests({
startDate: moment()
.subtract(120, 'days')
.format('YYYY-MM-DD'),
endDate: moment()
.add(featureVAOSServiceRequests ? 2 : 0, 'days')
.format('YYYY-MM-DD'),
});

const data = pendingAppointments?.filter(
appt => !appt.hasOwnProperty('meta'),
);
const backendServiceFailures = pendingAppointments.find(
appt => appt.hasOwnProperty('meta') || null,
);

dispatch({
type: FETCH_PENDING_APPOINTMENTS_SUCCEEDED,
data,
backendServiceFailures,
});

recordEvent({
event: `${GA_PREFIX}-get-pending-appointments-retrieved`,
});

try {
let facilityData;
if (featureVAOSServiceRequests) {
facilityData = getAdditionalFacilityInfoV2(data);
} else {
facilityData = await getAdditionalFacilityInfo(data);
}
if (facilityData) {
dispatch({
type: FETCH_FACILITY_LIST_DATA_SUCCEEDED,
facilityData,
});
}
} catch (error) {
captureError(error);
}

return data;
} catch (error) {
recordEvent({
event: `${GA_PREFIX}-get-pending-appointments-failed`,
});
dispatch({
type: FETCH_PENDING_APPOINTMENTS_FAILED,
});
return captureError(error);
}
};
}

export function fetchPastAppointments(startDate, endDate, selectedIndex) {
return async (dispatch, getState) => {
const featureVAOSServiceVAAppointments = selectFeatureVAOSServiceVAAppointments(
Expand Down
36 changes: 19 additions & 17 deletions src/applications/vaos/appointment-list/redux/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,41 @@ import moment from 'moment';
import set from 'platform/utilities/data/set';

import {
FETCH_FUTURE_APPOINTMENTS,
FETCH_FUTURE_APPOINTMENTS_SUCCEEDED,
FETCH_FUTURE_APPOINTMENTS_FAILED,
FETCH_PENDING_APPOINTMENTS,
FETCH_PENDING_APPOINTMENTS_SUCCEEDED,
FETCH_PENDING_APPOINTMENTS_FAILED,
FETCH_PAST_APPOINTMENTS,
FETCH_PAST_APPOINTMENTS_SUCCEEDED,
FETCH_PAST_APPOINTMENTS_FAILED,
FETCH_REQUEST_DETAILS,
FETCH_REQUEST_DETAILS_SUCCEEDED,
CANCEL_APPOINTMENT,
CANCEL_APPOINTMENT_CLOSED,
CANCEL_APPOINTMENT_CONFIRMED,
CANCEL_APPOINTMENT_CONFIRMED_FAILED,
CANCEL_APPOINTMENT_CONFIRMED_SUCCEEDED,
CANCEL_APPOINTMENT_CLOSED,
FETCH_FACILITY_LIST_DATA_SUCCEEDED,
FETCH_CONFIRMED_DETAILS,
FETCH_CONFIRMED_DETAILS_SUCCEEDED,
FETCH_CONFIRMED_DETAILS_FAILED,
FETCH_REQUEST_DETAILS_FAILED,
FETCH_CONFIRMED_DETAILS_SUCCEEDED,
FETCH_FACILITY_SETTINGS,
FETCH_FACILITY_SETTINGS_FAILED,
FETCH_FACILITY_SETTINGS_SUCCEEDED,
FETCH_FACILITY_SETTINGS,
FETCH_FUTURE_APPOINTMENTS,
FETCH_FUTURE_APPOINTMENTS_FAILED,
FETCH_FUTURE_APPOINTMENTS_SUCCEEDED,
FETCH_PAST_APPOINTMENTS,
FETCH_PAST_APPOINTMENTS_FAILED,
FETCH_PAST_APPOINTMENTS_SUCCEEDED,
FETCH_PROVIDER_SUCCEEDED,
FETCH_REQUEST_DETAILS,
FETCH_REQUEST_DETAILS_FAILED,
FETCH_REQUEST_DETAILS_SUCCEEDED,
} from './actions';

import {
FORM_SUBMIT_SUCCEEDED,
VACCINE_FORM_SUBMIT_SUCCEEDED,
} from '../../redux/sitewide';

import { FETCH_STATUS, APPOINTMENT_STATUS } from '../../utils/constants';
import {
FETCH_FACILITY_LIST_DATA_SUCCEEDED,
FETCH_PENDING_APPOINTMENTS,
FETCH_PENDING_APPOINTMENTS_FAILED,
FETCH_PENDING_APPOINTMENTS_SUCCEEDED,
} from '../../redux/actions';
import { APPOINTMENT_STATUS, FETCH_STATUS } from '../../utils/constants';

const initialState = {
pending: null,
Expand Down
19 changes: 0 additions & 19 deletions src/applications/vaos/appointment-list/redux/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
sortUpcoming,
groupAppointmentsByMonth,
isUpcomingAppointment,
sortByCreatedDateDescending,
isPendingOrCancelledRequest,
getAppointmentTimezone,
isClinicVideoAppointment,
Expand Down Expand Up @@ -127,14 +126,6 @@ export const selectUpcomingAppointments = createSelector(
},
);

export const selectPendingAppointments = createSelector(
state => state.appointments.pending,
pending =>
pending
?.filter(isPendingOrCancelledRequest)
.sort(sortByCreatedDateDescending) || null,
);

export const selectPastAppointments = createSelector(
state => state.appointments.past,
past => {
Expand Down Expand Up @@ -206,16 +197,6 @@ export function selectProviderAddress(appointment) {
return practitioners.length > 0 ? practitioners[0].address : null;
}

export function getRequestedAppointmentListInfo(state) {
return {
facilityData: state.appointments.facilityData,
pendingStatus: state.appointments.pendingStatus,
pendingAppointments: selectPendingAppointments(state),
isCernerOnlyPatient: selectIsCernerOnlyPatient(state),
showScheduleButton: selectFeatureRequests(state),
};
}

export function getUpcomingAppointmentListInfo(state) {
return {
facilityData: state.appointments.facilityData,
Expand Down
Loading

0 comments on commit 75b6da7

Please sign in to comment.