src/applications/vaos/new-appointment/redux/selectors.js
import { selectVAPResidentialAddress } from 'platform/user/selectors';
import {
getTimezoneByFacilityId,
getTimezoneDescByFacilityId,
} from '../../utils/timezone';
import {
FACILITY_TYPES,
TYPES_OF_CARE,
TYPES_OF_SLEEP_CARE,
TYPES_OF_EYE_CARE,
FETCH_STATUS,
AUDIOLOGY_TYPES_OF_CARE,
FACILITY_SORT_METHODS,
} from '../../utils/constants';
import { getSiteIdFromFacilityId } from '../../services/location';
import {
selectHasVAPResidentialAddress,
selectFeatureCommunityCare,
selectFeatureDirectScheduling,
selectRegisteredCernerFacilityIds,
selectFeatureVAOSServiceVAAppointments,
selectFeatureRemovePodiatry,
} from '../../redux/selectors';
import { removeDuplicateId } from '../../utils/data';
export function getNewAppointment(state) {
return state.newAppointment;
}
export function getFormData(state) {
return getNewAppointment(state).data;
}
export function selectPageChangeInProgress(state) {
return getNewAppointment(state).pageChangeInProgress;
}
export function getFlowType(state) {
return getNewAppointment(state)?.flowType;
}
export function getAppointmentLength(state) {
return getNewAppointment(state).appointmentLength;
}
export function getFormPageInfo(state, pageKey) {
return {
schema: getNewAppointment(state).pages[pageKey],
data: getFormData(state),
pageChangeInProgress: getNewAppointment(state).pageChangeInProgress,
};
}
const AUDIOLOGY = '203';
const SLEEP_CARE = 'SLEEP';
const EYE_CARE = 'EYE';
export function getTypeOfCare(data) {
if (data.typeOfCareId === SLEEP_CARE) {
return TYPES_OF_SLEEP_CARE.find(care => care.id === data.typeOfSleepCareId);
}
if (data.typeOfCareId === EYE_CARE) {
return TYPES_OF_EYE_CARE.find(care => care.id === data.typeOfEyeCareId);
}
if (
data.typeOfCareId === AUDIOLOGY &&
data.facilityType === FACILITY_TYPES.COMMUNITY_CARE
) {
return AUDIOLOGY_TYPES_OF_CARE.find(
care => care.ccId === data.audiologyType,
);
}
return TYPES_OF_CARE.find(care => care.id === data.typeOfCareId);
}
export function getCCEType(state) {
const data = getFormData(state);
let typeOfCare = TYPES_OF_CARE.find(care => care.id === data.typeOfCareId);
if (typeOfCare.id === 'EYE') {
typeOfCare = TYPES_OF_EYE_CARE.find(
care => care.id === data.typeOfEyeCareId,
);
}
return typeOfCare?.cceType;
}
export function getTypeOfCareFacilities(state) {
const data = getFormData(state);
const { facilities } = getNewAppointment(state);
const typeOfCareId = getTypeOfCare(data)?.id;
return facilities[`${typeOfCareId}`];
}
export function getChosenFacilityInfo(state) {
return (
getTypeOfCareFacilities(state)?.find(
facility => facility.id === getFormData(state).vaFacility,
) || null
);
}
export function selectCommunityCareSupportedSites(state) {
return getNewAppointment(state).ccEnabledSystems;
}
export function getChosenCCSystemById(state) {
const { communityCareSystemId } = getFormData(state);
if (!communityCareSystemId) {
return null;
}
return selectCommunityCareSupportedSites(state).find(
facility => facility.id === communityCareSystemId,
);
}
export function getSiteIdForChosenFacility(state) {
return getSiteIdFromFacilityId(getFormData(state).vaFacility);
}
export function selectEligibility(state) {
const data = getFormData(state);
const newAppointment = getNewAppointment(state);
const typeOfCareId = getTypeOfCare(data)?.id;
return (
newAppointment.eligibility[`${data.vaFacility}_${typeOfCareId}`] || null
);
}
export function getPreferredDate(state, pageKey) {
const data = getFormData(state);
const typeOfCare = getTypeOfCare(data)?.name;
return { ...getFormPageInfo(state, pageKey), typeOfCare };
}
export function getChosenSlot(state) {
const { availableSlots } = getNewAppointment(state);
const selectedTime = getFormData(state).selectedDates?.[0];
return availableSlots?.find(slot => slot.start === selectedTime);
}
export function getDateTimeSelect(state, pageKey) {
const newAppointment = getNewAppointment(state);
const { appointmentSlotsStatus } = newAppointment;
const data = getFormData(state);
const formInfo = getFormPageInfo(state, pageKey);
const { availableSlots } = newAppointment;
const eligibilityStatus = selectEligibility(state);
const timezoneDescription = getTimezoneDescByFacilityId(data.vaFacility);
const timezone = getTimezoneByFacilityId(data.vaFacility);
const typeOfCareId = getTypeOfCare(data)?.id;
return {
...formInfo,
availableSlots,
eligibleForRequests: eligibilityStatus.request,
facilityId: data.vaFacility,
appointmentSlotsStatus,
preferredDate: data.preferredDate,
timezone,
timezoneDescription,
typeOfCareId,
};
}
export function selectProviderSelectionInfo(state) {
const {
communityCareProviders,
data,
requestStatus,
requestLocationStatus,
currentLocation,
ccProviderPageSortMethod: sortMethod,
ccEnabledSystems,
selectedCCFacility,
} = getNewAppointment(state);
const typeOfCare = getTypeOfCare(data);
const ccProviderCacheKey =
sortMethod === FACILITY_SORT_METHODS.distanceFromFacility
? `${sortMethod}_${selectedCCFacility.id}_${typeOfCare.ccId}`
: `${sortMethod}_${typeOfCare.ccId}`;
const updatedSortMethod =
sortMethod === FACILITY_SORT_METHODS.distanceFromFacility
? selectedCCFacility.id
: sortMethod;
return {
address: selectVAPResidentialAddress(state),
ccEnabledSystems,
communityCareProviderList: !communityCareProviders[ccProviderCacheKey]
? communityCareProviders[ccProviderCacheKey]
: removeDuplicateId(communityCareProviders[ccProviderCacheKey]),
currentLocation,
requestLocationStatus,
requestStatus,
selectedCCFacility,
sortMethod: updatedSortMethod,
typeOfCareName: typeOfCare.name,
};
}
export function selectFacilityPageSortMethod(state) {
return getNewAppointment(state).facilityPageSortMethod;
}
export function selectNoValidVAFacilities(state) {
const newAppointment = getNewAppointment(state);
const formInfo = getFormPageInfo(state, 'vaFacilityV2');
const { childFacilitiesStatus } = newAppointment;
const validFacilities = formInfo.schema?.properties.vaFacility.enum;
return (
childFacilitiesStatus === FETCH_STATUS.succeeded && !validFacilities?.length
);
}
export function selectSingleValidVALocation(state) {
const formInfo = getFormPageInfo(state, 'vaFacilityV2');
const data = getFormData(state);
const validFacilities = formInfo.schema?.properties.vaFacility.enum;
return validFacilities?.length === 1 && !!data.vaFacility;
}
export function selectSingleSupportedVALocation(state) {
return getNewAppointment(state)?.data?.isSingleVaFacility;
}
export function getFacilityPageV2Info(state) {
const formInfo = getFormPageInfo(state, 'vaFacilityV2');
const data = getFormData(state);
const newAppointment = getNewAppointment(state);
const typeOfCare = getTypeOfCare(data);
const {
childFacilitiesStatus,
requestLocationStatus,
showEligibilityModal,
} = newAppointment;
const address = selectVAPResidentialAddress(state);
const facilities = newAppointment.facilities[(typeOfCare?.id)];
const eligibility = selectEligibility(state);
return {
...formInfo,
address,
canScheduleAtChosenFacility: eligibility?.direct || eligibility?.request,
childFacilitiesStatus,
eligibility,
facilities,
hasDataFetchingError:
childFacilitiesStatus === FETCH_STATUS.failed ||
newAppointment.eligibilityStatus === FETCH_STATUS.failed,
loadingEligibilityStatus: newAppointment.eligibilityStatus,
noValidVAFacilities: selectNoValidVAFacilities(state),
requestLocationStatus,
selectedFacility: getChosenFacilityInfo(state),
singleValidVALocation: selectSingleValidVALocation(state),
showEligibilityModal,
sortMethod: selectFacilityPageSortMethod(state),
typeOfCare,
cernerSiteIds: selectRegisteredCernerFacilityIds(state),
};
}
export function getChosenClinicInfo(state) {
const data = getFormData(state);
const { clinics } = getNewAppointment(state);
const typeOfCareId = getTypeOfCare(data)?.id;
return (
clinics[`${data.vaFacility}_${typeOfCareId}`]?.find(
clinic => clinic.id === data.clinicId,
) || null
);
}
export function getClinicsForChosenFacility(state) {
const data = getFormData(state);
const { clinics } = getNewAppointment(state);
const typeOfCareId = getTypeOfCare(data)?.id;
return clinics[`${data.vaFacility}_${typeOfCareId}`] || null;
}
export function selectPastAppointments(state) {
return getNewAppointment(state).pastAppointments;
}
export function selectTypeOfCare(state) {
return getTypeOfCare(getFormData(state));
}
export function selectIsNewAppointmentStarted(state) {
return getNewAppointment(state)?.isNewAppointmentStarted;
}
export function selectChosenFacilityInfo(state) {
const formData = getFormData(state);
const typeOfCare = getTypeOfCare(formData);
const newAppointment = getNewAppointment(state);
return newAppointment.facilities[typeOfCare.id].find(
facility => facility.id === formData.vaFacility,
);
}
export function getPatientProviderRelationships(state) {
return {
patientProviderRelationships: state.patientProviderRelationships,
patientProviderRelationshipsStatus:
state.patientProviderRelationshipsStatus,
};
}
export function getChosenVACityState(state) {
const schema =
state.newAppointment.pages.ccPreferences?.properties.communityCareSystemId;
if (schema?.enum?.length > 1) {
const index = schema.enum.indexOf(
state.newAppointment.data.communityCareSystemId,
);
return schema.enumNames[index];
}
return null;
}
export function selectConfirmationPage(state) {
return {
data: getFormData(state),
clinic: getChosenClinicInfo(state),
facilityDetails: getChosenFacilityInfo(state),
slot: getChosenSlot(state),
systemId: getSiteIdForChosenFacility(state),
submitStatus: getNewAppointment(state).submitStatus,
flowType: getFlowType(state),
appointmentLength: getAppointmentLength(state),
hasResidentialAddress: selectHasVAPResidentialAddress(state),
};
}
export function selectReviewPage(state) {
return {
clinic: getChosenClinicInfo(state),
data: getFormData(state),
facility: getChosenFacilityInfo(state),
flowType: getFlowType(state),
parentFacility: getChosenCCSystemById(state),
submitStatus: state.newAppointment.submitStatus,
submitStatusVaos400: state.newAppointment.submitStatusVaos400,
submitStatusVaos409: state.newAppointment.submitStatusVaos409,
systemId: getSiteIdForChosenFacility(state),
hasResidentialAddress: selectHasVAPResidentialAddress(state),
vaCityState: getChosenVACityState(state),
};
}
export function selectTypeOfCarePage(state) {
const newAppointment = getNewAppointment(state);
const address = selectVAPResidentialAddress(state);
const featureVAOSServiceVAAppointments = selectFeatureVAOSServiceVAAppointments(
state,
);
return {
...address,
hideUpdateAddressAlert: newAppointment.hideUpdateAddressAlert,
initialData: getFormData(state),
pageChangeInProgress: selectPageChangeInProgress(state),
showCommunityCare: selectFeatureCommunityCare(state),
showDirectScheduling: selectFeatureDirectScheduling(state),
removePodiatry: selectFeatureRemovePodiatry(state),
showPodiatryApptUnavailableModal:
newAppointment.showPodiatryAppointmentUnavailableModal,
useV2: featureVAOSServiceVAAppointments,
};
}
export function selectFacilitiesRadioWidget(state) {
const newAppointment = getNewAppointment(state);
const {
eligibilityStatus,
facilityPageSortMethod,
requestLocationStatus,
} = newAppointment;
const cernerSiteIds = selectRegisteredCernerFacilityIds(state);
const sortMethod = facilityPageSortMethod;
return {
cernerSiteIds,
loadingEligibility: eligibilityStatus === FETCH_STATUS.loading,
requestLocationStatus,
sortMethod,
};
}
export function selectAppointmentSlotsStatus(state) {
return getNewAppointment(state).appointmentSlotsStatus;
}
export function getSelectedDate(state) {
return getFormData(state).selectedDates?.length
? getFormData(state).selectedDates[0]
: '';
}