Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions apps/ehr/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ import {
GetAppointmentsZambdaOutput,
GetConversationInput,
GetConversationZambdaOutput,
GetCreateInHouseLabOrderResourcesParameters,
GetCreateInHouseLabOrderResourcesResponse,
GetEmployeesResponse,
GetInHouseOrdersParameters,
GetLabelPdfParameters,
Expand Down Expand Up @@ -162,7 +160,6 @@ const CREATE_SCHEDULE_ZAMBDA_ID = 'create-schedule';
const CREATE_SLOT_ZAMBDA_ID = 'create-slot';
const CREATE_IN_HOUSE_LAB_ORDER_ZAMBDA_ID = 'create-in-house-lab-order';
const GET_IN_HOUSE_ORDERS_ZAMBDA_ID = 'get-in-house-orders';
const GET_CREATE_IN_HOUSE_LAB_ORDER_RESOURCES = 'get-create-in-house-lab-order-resources';
const COLLECT_IN_HOUSE_LAB_SPECIMEN = 'collect-in-house-lab-specimen';
const HANDLE_IN_HOUSE_LAB_RESULTS = 'handle-in-house-lab-results';
const DELETE_IN_HOUSE_LAB_ORDER = 'delete-in-house-lab-order';
Expand Down Expand Up @@ -1054,25 +1051,6 @@ export const getInHouseOrders = async <RequestParameters extends GetInHouseOrder
}
};

export const getCreateInHouseLabOrderResources = async (
oystehr: Oystehr,
parameters: GetCreateInHouseLabOrderResourcesParameters
): Promise<GetCreateInHouseLabOrderResourcesResponse> => {
try {
if (GET_CREATE_IN_HOUSE_LAB_ORDER_RESOURCES == null) {
throw new Error('get create in house lab order resources zambda environment variable could not be loaded');
}
const response = await oystehr.zambda.execute({
id: GET_CREATE_IN_HOUSE_LAB_ORDER_RESOURCES,
...parameters,
});
return chooseJson(response);
} catch (error: unknown) {
console.log(error);
throw error;
}
};

export const collectInHouseLabSpecimen = async (
oystehr: Oystehr,
parameters: CollectInHouseLabSpecimenParameters
Expand Down
36 changes: 10 additions & 26 deletions apps/ehr/src/features/external-labs/components/LabSets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,23 @@ import { LoadingButton } from '@mui/lab';
import { Box, Dialog, DialogContent, DialogTitle, Divider, Grid, IconButton, Typography } from '@mui/material';
import Oystehr from '@oystehr/sdk';
import { FC, useState } from 'react';
import { useOystehrAPIClient } from 'src/features/visits/shared/hooks/useOystehrAPIClient';
import { LabListsDTO, OrderableItemSearchResult } from 'utils';
import { LabListsDTO } from 'utils';

type LabSetsProps = {
labSets: LabListsDTO[];
setSelectedLabs: React.Dispatch<React.SetStateAction<OrderableItemSearchResult[]>>;
setSelectedLabs: (labSet: LabListsDTO) => Promise<void>;
};

export const LabSets: FC<LabSetsProps> = ({ labSets, setSelectedLabs }) => {
const [open, setOpen] = useState(false);
const [loadingId, setLoadingId] = useState<string | null>(null);
const [error, setError] = useState<string[] | undefined>(undefined);

const apiClient = useOystehrAPIClient();

const handleSelectLabSet = async (labSet: LabListsDTO): Promise<void> => {
setLoadingId(labSet.listId); // start loading for this button only
try {
const res = await apiClient?.getCreateExternalLabResources({
selectedLabSet: labSet,
});
const labs = res?.labs;

if (labs) {
setSelectedLabs((currentLabs) => {
const existingCodes = new Set(currentLabs.map((lab) => `${lab.item.itemCode}${lab.lab.labGuid}`));

const newLabs = labs.filter((lab) => !existingCodes.has(`${lab.item.itemCode}${lab.lab.labGuid}`));

return [...currentLabs, ...newLabs];
});
setOpen(false);
}
await setSelectedLabs(labSet);
setOpen(false);
} catch (e) {
const sdkError = e as Oystehr.OystehrSdkError;
console.log('error selecting this lab set', sdkError.code, sdkError.message);
Expand Down Expand Up @@ -67,7 +51,7 @@ export const LabSets: FC<LabSetsProps> = ({ labSets, setSelectedLabs }) => {
p: '24px 24px 16px 24px',
}}
>
<Typography variant="h4" color="primary.dark">
<Typography variant="h4" component="div" color="primary.dark">
Lab Sets
</Typography>
<IconButton
Expand All @@ -82,8 +66,8 @@ export const LabSets: FC<LabSetsProps> = ({ labSets, setSelectedLabs }) => {

<DialogContent dividers>
{labSets.map((set, idx) => (
<>
<Grid key={`set-${idx}-${set.listId}`} container>
<Box key={`set-${idx}-${set.listId}`}>
<Grid container>
<Grid
item
xs={9}
Expand All @@ -96,8 +80,8 @@ export const LabSets: FC<LabSetsProps> = ({ labSets, setSelectedLabs }) => {
<Typography variant="h6" fontWeight="700" color="primary.dark">
{set.listName}:
</Typography>
{set.labs.map((lab) => (
<Typography>{lab.display}</Typography>
{set.labs.map((lab, idx) => (
<Typography key={`set-item-${set.listId}-${idx}`}>{lab.display}</Typography>
))}
</Grid>
<Grid item xs={3} sx={{ textAlign: 'right' }}>
Expand All @@ -114,7 +98,7 @@ export const LabSets: FC<LabSetsProps> = ({ labSets, setSelectedLabs }) => {
</Grid>
</Grid>
{idx < labSets.length - 1 && <Divider sx={{ my: 2 }} />}
</>
</Box>
))}
{Array.isArray(error) &&
error.length > 0 &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { enqueueSnackbar } from 'notistack';
import { FC, useState } from 'react';
import { ActionsList } from 'src/components/ActionsList';
import { DeleteIconButton } from 'src/components/DeleteIconButton';
import { useOystehrAPIClient } from 'src/features/visits/shared/hooks/useOystehrAPIClient';
import { useGetCreateExternalLabResources } from 'src/features/visits/shared/stores/appointment/appointment.queries';
import { useDebounce } from 'src/shared/hooks/useDebounce';
import { LabListsDTO, nameLabTest, OrderableItemSearchResult } from 'utils';
import { LabListsDTO, LabType, nameLabTest, OrderableItemSearchResult } from 'utils';
import { LabSets } from './LabSets';

type LabsAutocompleteProps = {
Expand All @@ -18,6 +19,7 @@ type LabsAutocompleteProps = {
export const LabsAutocomplete: FC<LabsAutocompleteProps> = (props) => {
const { selectedLabs, setSelectedLabs, labOrgIdsString, labSets } = props;
const [debouncedLabSearchTerm, setDebouncedLabSearchTerm] = useState<string | undefined>(undefined);
const apiClient = useOystehrAPIClient();

const {
isFetching,
Expand All @@ -40,6 +42,25 @@ export const LabsAutocomplete: FC<LabsAutocompleteProps> = (props) => {

if (resourceFetchError) console.log('resourceFetchError', resourceFetchError);

const handleSetSelectedLabsViaLabSets = async (labSet: LabListsDTO): Promise<void> => {
if (labSet.listType === LabType.external) {
const res = await apiClient?.getCreateExternalLabResources({
selectedLabSet: labSet,
});
const labs = res?.labs;

if (labs) {
setSelectedLabs((currentLabs) => {
const existingCodes = new Set(currentLabs.map((lab) => `${lab.item.itemCode}${lab.lab.labGuid}`));

const newLabs = labs.filter((lab) => !existingCodes.has(`${lab.item.itemCode}${lab.lab.labGuid}`));

return [...currentLabs, ...newLabs];
});
}
}
};

return (
<>
<Autocomplete
Expand Down Expand Up @@ -79,7 +100,7 @@ export const LabsAutocomplete: FC<LabsAutocompleteProps> = (props) => {
)}
/>

{labSets && <LabSets labSets={labSets} setSelectedLabs={setSelectedLabs} />}
{labSets && <LabSets labSets={labSets} setSelectedLabs={handleSetSelectedLabsViaLabSets} />}

{selectedLabs.length > 0 && (
<Grid container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ import { DatePicker } from '@mui/x-date-pickers';
import { LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon';
import { DateTime } from 'luxon';
import { ReactElement, useEffect, useState } from 'react';
import { ReactElement, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { getCreateInHouseLabOrderResources } from 'src/api/api';
import { DropdownPlaceholder } from 'src/features/common/DropdownPlaceholder';
import { getInHouseLabOrderDetailsUrl } from 'src/features/visits/in-person/routing/helpers';
import { useApiClients } from 'src/hooks/useAppClients';
import { InHouseOrderListPageItemDTO, InHouseOrdersSearchBy, TestItem } from 'utils';
import { useGetCreateInHouseLabResources } from 'src/features/visits/shared/stores/appointment/appointment.queries';
import { InHouseOrderListPageItemDTO, InHouseOrdersSearchBy } from 'utils';
import { LabOrdersSearchBy } from 'utils/lib/types/data/labs';
import { InHouseLabsTableRow } from './InHouseLabsTableRow';
import { useInHouseLabOrders } from './useInHouseLabOrders';
Expand Down Expand Up @@ -78,32 +77,9 @@ export const InHouseLabsTable = <SearchBy extends LabOrdersSearchBy>({
const [testTypeQuery, setTestTypeQuery] = useState<string>('');
const [tempDateFilter, setTempDateFilter] = useState<DateTime | null>(visitDateFilter);

const [availableTests, setAvailableTests] = useState<TestItem[]>([]);
const [loadingTests, setLoadingTests] = useState(false);
const { isFetching: loadingTests, data: createInHouseLabResources } = useGetCreateInHouseLabResources({});

const { oystehrZambda } = useApiClients();

// set data for filters
useEffect(() => {
if (!oystehrZambda || !showFilters) {
return;
}

const fetchTests = async (): Promise<void> => {
try {
setLoadingTests(true);
const response = await getCreateInHouseLabOrderResources(oystehrZambda, {});
const testItems = response.labs || [];
setAvailableTests(testItems.sort((a, b) => a.name.localeCompare(b.name)));
} catch (error) {
console.error('Error fetching tests:', error);
} finally {
setLoadingTests(false);
}
};

void fetchTests();
}, [oystehrZambda, showFilters]);
const availableTests = Object.values(createInHouseLabResources?.labs || {});

const submitFilterByDate = (date?: DateTime | null): void => {
const dateToSet = date || tempDateFilter;
Expand Down
Loading