Skip to content

Commit

Permalink
Save Interactions
Browse files Browse the repository at this point in the history
  • Loading branch information
jmbrunskill committed Feb 2, 2024
1 parent 9b44ed8 commit fdc92e7
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ export const DrugOrGroupSelector: FC<DrugOrGroupSelectorProps> = ({

const groupOptions = useMemo<SelectionOption[]>(() => {
if (!groups) return [];
return groups.map(drug => ({
id: drug.id,
name: drug.description ?? 'Unknown',
label: drug.name ?? 'Unknown',
return groups.map(group => ({
id: group.id,
name: group.name ?? 'Unknown',
label: group.name ?? 'Unknown',
}));
}, [groups]);

Expand Down
111 changes: 95 additions & 16 deletions frontend/system/src/Admin/Interactions/InteractionEditModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import { useAllDrugInteractionGroups } from './api';
import { DrugOrGroupSelector } from './DrugOrGroupSelector';
import { DrugInteractionSeverityNode } from '@common/types';
import { DrugInteractionFragment } from './api/operations.generated';
import { useUpsertDrugInteraction } from './api/hooks/useUpsertInteraction';
import Alert from '@mui/material/Alert';
import AlertTitle from '@mui/material/AlertTitle';

type InteractionEditModalProps = {
isOpen: boolean;
Expand Down Expand Up @@ -50,6 +53,8 @@ export const InteractionEditModal = ({
group2: interaction?.group2,
});

const [addDrugInteration, invalidateQueries] = useUpsertDrugInteraction();

const { data: drugs, isLoading: drugListLoading } = useEntities({
filter: {
categories: ['drug'],
Expand All @@ -66,10 +71,10 @@ export const InteractionEditModal = ({
const { data: groups, isLoading: groupListLoading } =
useAllDrugInteractionGroups();

const { Modal } = useDialog({ isOpen, onClose });
const [isLoading, setIsLoading] = useState(false);
const [errorMessage, setErrorMessage] = useState('');

// TODO: set from queries
const isLoading = false;
const { Modal } = useDialog({ isOpen, onClose });

const isInvalid = !draft.name || !draft.description || !draft.severity;
const modalWidth = Math.min(window.innerWidth - 200, 800);
Expand All @@ -81,9 +86,33 @@ export const InteractionEditModal = ({
<LoadingButton
disabled={isInvalid}
onClick={() => {
// TODO: save and handle errors
console.log('value to be saved:', draft);
onClose();
addDrugInteration({
input: {
id: draft.id,
name: draft.name,
description: draft.description ?? '',
action: draft.action ?? '',
reference: draft.reference ?? '',
severity: draft.severity,
drug1: draft.drug1?.code,
drug2: draft.drug2?.code,
group1: draft.group1?.id,
group2: draft.group2?.id,
},
})
.catch(err => {
setIsLoading(false);
if (!err || !err.message) {
err = { message: t('messages.unknown-error') };
}
setErrorMessage(err.message);
})
.then(() => {
invalidateQueries();
setIsLoading(false);
onClose();
});
setIsLoading(false);
}}
isLoading={isLoading}
startIcon={<CheckIcon />}
Expand All @@ -110,7 +139,6 @@ export const InteractionEditModal = ({
value={draft?.name ?? ''}
onChange={e => setDraft({ ...draft, name: e.currentTarget.value })}
/>

<DrugOrGroupSelector
drugs={drugs?.data ?? []}
groups={groups ?? []}
Expand All @@ -119,16 +147,34 @@ export const InteractionEditModal = ({
drugId?: string | undefined;
groupId?: string | undefined;
}): void {
// TODO....
// throw new Error('Function not implemented.');
if (input.drugId) {
setDraft({
...draft,
drug1: {
code: input.drugId,
description: '',
__typename: 'EntityType',
},
group1: undefined,
});
}
if (input.groupId) {
setDraft({
...draft,
group1: {
id: input.groupId,
name: '',
__typename: 'DrugInteractionGroupNode',
},
drug1: undefined,
});
}
}}
isLoading={drugListLoading || groupListLoading}
/>

<Grid item>
<Typography variant="h6">Interacts with</Typography>
</Grid>

<DrugOrGroupSelector
drugs={drugs?.data ?? []}
groups={groups ?? []}
Expand All @@ -137,12 +183,31 @@ export const InteractionEditModal = ({
drugId?: string | undefined;
groupId?: string | undefined;
}): void {
// TODO....
// throw new Error('Function not implemented.');
if (input.drugId) {
setDraft({
...draft,
drug2: {
code: input.drugId,
description: '',
__typename: 'EntityType',
},
group2: undefined,
});
}
if (input.groupId) {
setDraft({
...draft,
group2: {
id: input.groupId,
name: '',
__typename: 'DrugInteractionGroupNode',
},
drug2: undefined,
});
}
}}
isLoading={drugListLoading || groupListLoading}
/>

<Select
label={t('label.severity')}
required
Expand Down Expand Up @@ -176,8 +241,8 @@ export const InteractionEditModal = ({
borderRadius: '8px',
},
}}
InputLabelProps={{ shrink: true }}
/>

<TextArea
label={t('label.action')}
value={draft?.action ?? ''}
Expand All @@ -192,8 +257,8 @@ export const InteractionEditModal = ({
borderRadius: '8px',
},
}}
InputLabelProps={{ shrink: true }}
/>

<TextArea
label={t('label.reference')}
value={draft?.reference ?? ''}
Expand All @@ -208,7 +273,21 @@ export const InteractionEditModal = ({
borderRadius: '8px',
},
}}
InputLabelProps={{ shrink: true }}
/>
{errorMessage ? (
<Grid item>
<Alert
severity="error"
onClose={() => {
setErrorMessage('');
}}
>
<AlertTitle>{t('error')}</AlertTitle>
{errorMessage}
</Alert>
</Grid>
) : null}{' '}
</Grid>
)}
</Modal>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ export const InteractionGroupEditModal = ({
const onUpdate = (patch: Partial<InteractionGroupFragment>) => {
setGroup({ ...group, ...patch });
};
const [addConfigItem, invalidateQueries] = useUpsertDrugInteractionGroup();
const [addDrugInterationGroup, invalidateQueries] =
useUpsertDrugInteractionGroup();

const { data, isLoading: drugListLoading } = useEntities({
filter: {
Expand All @@ -75,7 +76,7 @@ export const InteractionGroupEditModal = ({
<LoadingButton
onClick={() => {
setIsLoading(true);
addConfigItem({
addDrugInterationGroup({
input: {
id: group.id,
name: group.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const InteractionGroupTabComponent = () => {
const { onOpen, onClose, isOpen, entity, mode } =
useEditModal<InteractionGroupFragment>();

const { data, isLoading } = useAllDrugInteractionGroups();
const { data, isLoading, isError } = useAllDrugInteractionGroups();

const [deleteErrors, setDeleteErrors] = React.useState<DeleteError[]>([]);
const selectedRows = useTableStore(state =>
Expand Down Expand Up @@ -170,6 +170,7 @@ const InteractionGroupTabComponent = () => {
columns={columns}
data={data}
isLoading={isLoading}
isError={isError}
onRowClick={onOpen}
/>
</>
Expand Down
54 changes: 48 additions & 6 deletions frontend/system/src/Admin/Interactions/InteractionsTab.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,50 @@
import React from 'react';
import { AppBarButtonsPortal, LoadingButton } from '@common/components';
import {
AppBarButtonsPortal,
AppBarContentPortal,
DeleteLinesDropdownItem,
DropdownMenu,
LoadingButton,
} from '@common/components';
import { useTranslation } from '@common/intl';
import {
createTableStore,
DataTable,
PlusCircleIcon,
TableProvider,
useColumns,
useTableStore,
} from '@common/ui';
import { useEditModal } from '@common/hooks';
import { InteractionEditModal } from './InteractionEditModal';
import { useAllDrugInteractions } from './api/hooks/useInteractions';
import { DrugInteractionFragment } from './api/operations.generated';
import { useDeleteInteraction } from './api/hooks/useDeleteInteraction';

export const InteractionTab = () => {
export const InteractionTabComponent = () => {
const t = useTranslation('system');
const { onOpen, onClose, isOpen, entity, mode } =
useEditModal<DrugInteractionFragment>(); //TODO replace with actual data type
useEditModal<DrugInteractionFragment>();

const { mutateAsync: deleteInteraction } = useDeleteInteraction();

const columns = useColumns<DrugInteractionFragment>([
{ key: 'name', label: 'label.name' },
{ key: 'severity', label: 'label.severity' },
'selection',
]);

const { data, isLoading } = useAllDrugInteractions();
const { data, isLoading, isError } = useAllDrugInteractions();

const selectedRows = useTableStore(state =>
Object.keys(state.rowState)
.filter(id => state.rowState[id]?.isSelected)
.map(selectedId => data?.find(({ id }) => selectedId === id))
.filter(Boolean)
);

return (
<TableProvider createStore={createTableStore}>
<>
{isOpen && (
<InteractionEditModal
isOpen={isOpen}
Expand All @@ -44,8 +62,32 @@ export const InteractionTab = () => {
{t('label.add-interaction')}
</LoadingButton>
</AppBarButtonsPortal>
<AppBarContentPortal marginBottom={'10px'}>
<DropdownMenu label={t('label.select')}>
<DeleteLinesDropdownItem
selectedRows={selectedRows}
deleteItem={async (item: DrugInteractionFragment) => {
await deleteInteraction(item.id);
}}
/>
</DropdownMenu>
</AppBarContentPortal>

<DataTable columns={columns} data={data} onRowClick={onOpen} />
<DataTable
columns={columns}
isLoading={isLoading}
isError={isError}
data={data}
onRowClick={onOpen}
/>
</>
);
};

export const InteractionTab = () => {
return (
<TableProvider createStore={createTableStore}>
<InteractionTabComponent />
</TableProvider>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useGql, useMutation, useQueryClient } from '@uc-frontend/common';
import { getSdk } from '../operations.generated';
import { DRUG_INTERACTION_KEY } from '.';

export const useDeleteInteraction = () => {
const { client } = useGql();
const sdk = getSdk(client);
const queryClient = useQueryClient();

return useMutation(async (id: string) => sdk.DeleteDrugInteraction({ id }), {
onSettled: () => queryClient.invalidateQueries(DRUG_INTERACTION_KEY),
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useQueryClient, useGql } from '@uc-frontend/common';
import { getSdk } from '../operations.generated';
import { DRUG_INTERACTION_KEY } from '.';

export const useUpsertDrugInteraction = () => {
const { client } = useGql();
const sdk = getSdk(client);
const queryClient = useQueryClient();

const invalidateQueries = () => {
queryClient.invalidateQueries([DRUG_INTERACTION_KEY]);
};

return [sdk.UpsertDrugInteraction, invalidateQueries] as const;
};

0 comments on commit fdc92e7

Please sign in to comment.