Skip to content

Commit

Permalink
Add ccc and patient name to manifest samples table and flu sample typ…
Browse files Browse the repository at this point in the history
…es (#498)

* Added clickable patient name together with cc number

* Cleaned styles for form

* Showing kdod dentifier for kdod sites and ccc identifier type for none kdod sites.Added sample types for FLU manifest type
  • Loading branch information
Omoshlawi authored Dec 3, 2024
1 parent a8c398a commit 969cf9a
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 42 deletions.
21 changes: 18 additions & 3 deletions packages/esm-lab-manifest-app/src/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,36 @@ export const configSchema = {
},
{
id: 3,
type: 'FLU',
type: 'Influenza',
},
],
},
sampleTypes: {
_type: Type.Array,
_description: 'List of sample types and list of manifest type id it applies',
_default: [
{ sampleType: 'Frozen plasma', labManifestType: ['2', '3'] },
{ sampleType: 'Whole Blood', labManifestType: ['2', '3'] },
{ sampleType: 'Frozen plasma', labManifestType: ['2'] },
{ sampleType: 'Whole Blood', labManifestType: ['2'] },
{ sampleType: 'DBS', labManifestType: ['1'] },
{ sampleType: 'Nasal Swab', labManifestType: ['3'] },
{ sampleType: 'NP', labManifestType: ['3'] },
{ sampleType: 'OP', labManifestType: ['3'] },
],
},
patientIdentifierTypes: {
_type: Type.Object,
_description: 'Patient identifier type uuids',
_default: {
cccNumberIdentifierType: '05ee9cf4-7242-4a17-b4d4-00f707265c8a',
kdodIdentifierType: 'b51ffe55-3e76-44f8-89a2-14f5eaf11079',
},
},
};
export interface LabManifestConfig {
labmanifestTypes: Array<{ id: number; type: string }>;
sampleTypes: Array<{ sampleType: string; labManifestType: Array<string> }>;
patientIdentifierTypes: {
cccNumberIdentifierType: string;
kdodIdentifierType: string;
};
}
62 changes: 35 additions & 27 deletions packages/esm-lab-manifest-app/src/forms/lab-manifest-form.scss
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
@use '@carbon/styles/scss/spacing';
@use '@carbon/styles/scss/type';
@use '@carbon/type';
@use '@carbon/layout';
@import '~@openmrs/esm-styleguide/src/vars';
@use '@carbon/colors';

.heading {
@include type.type-style('heading-compact-01');
margin: spacing.$spacing-05 0 spacing.$spacing-05;
margin: layout.$spacing-05 0 layout.$spacing-05;
}

.warningContainer {
background-color: $carbon--red-50;
padding: spacing.$spacing-04;
margin: spacing.$spacing-03 0 spacing.$spacing-03;
background-color: colors.$red-50;
padding: layout.$spacing-04;
margin: layout.$spacing-03 0 layout.$spacing-03;
display: flex;
justify-content: space-between;

.warning {
@include type.type-style('heading-01');
color: $ui-05;
color: colors.$gray-100;
}
}

Expand All @@ -28,33 +28,32 @@
}

.grid {
margin: 0 spacing.$spacing-05;
margin: 0 layout.$spacing-05;
padding: 0rem;
}

.input {
margin-top: spacing.$spacing-05;
margin-top: layout.$spacing-05;
}

.inputRow {
margin-top: spacing.$spacing-05;
width: 50%; // Adjust width as per your design requirements
margin-top: layout.$spacing-05;
display: flex;
flex: 1;

}

.datePickersRow {
display: flex;
flex-wrap: nowrap;
gap: spacing.$spacing-05; // Adjust gap between columns
gap: layout.$spacing-05; // Adjust gap between columns
align-items: center;
width: 100%;
}

.datePickerInput {
flex-grow: 1;
}

.button {
height: spacing.$spacing-10;
height: layout.$spacing-10;
display: flex;
align-content: flex-start;
align-items: baseline;
Expand All @@ -63,11 +62,11 @@

.buttonSet {
padding: 0rem;
margin-top: spacing.$spacing-05;
margin-top: layout.$spacing-05;
display: flex;
justify-content: space-between;
width: 100%;
margin-bottom: spacing.$spacing-05;
margin-bottom: layout.$spacing-05;
}

.datesContainer {
Expand All @@ -76,17 +75,19 @@
width: 100%;
display: flex;
}

.inlineActions {
display: flex;
gap: spacing.$spacing-05; /* Adjust the spacing as needed */
gap: layout.$spacing-05;
/* Adjust the spacing as needed */
}

.formTitle {
@include type.type-style('heading-02');
display: flex;
align-items: center;
justify-content: space-between;
margin: spacing.$spacing-05;
margin: layout.$spacing-05;
row-gap: 1.5rem;
position: relative;

Expand All @@ -100,7 +101,7 @@
left: 0;
}

& > span {
&>span {
@include type.type-style('body-01');
}
}
Expand All @@ -115,14 +116,21 @@
}

.buttonSet {
padding: spacing.$spacing-06 spacing.$spacing-05;
background-color: $ui-02;
padding: layout.$spacing-06 layout.$spacing-05;
background-color: colors.$white;
justify-content: flex-end;
gap: spacing.$spacing-05;
gap: layout.$spacing-05;
}
}

.previewContainer {
margin-top: spacing.$spacing-05;
margin-bottom: spacing.$spacing-05;
margin-top: layout.$spacing-05;
margin-bottom: layout.$spacing-05;
}

.datePickerInput span,
.datePickerInput div,
.datePickerInput input,
.datePickerInput {
min-width: 100%;
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const LabManifestForm: React.FC<LabManifestFormProps> = ({ closeWorkspace, manif
dateFormat="d/m/Y"
id="startDate"
datePickerType="single"
className={styles.datePickerInput}
invalid={form.formState.errors[field.name]?.message}
invalidText={form.formState.errors[field.name]?.message}>
<DatePickerInput
Expand All @@ -97,6 +98,7 @@ const LabManifestForm: React.FC<LabManifestFormProps> = ({ closeWorkspace, manif
<DatePicker
value={field.value}
onChange={field.onChange}
className={styles.datePickerInput}
dateFormat="d/m/Y"
id="endDate"
datePickerType="single"
Expand Down Expand Up @@ -146,6 +148,7 @@ const LabManifestForm: React.FC<LabManifestFormProps> = ({ closeWorkspace, manif
dateFormat="d/m/Y"
id="dispatchDate"
datePickerType="single"
className={styles.datePickerInput}
{...field}
invalid={form.formState.errors[field.name]?.message}
invalidText={form.formState.errors[field.name]?.message}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import { showSnackbar, useConfig } from '@openmrs/esm-framework';
import React from 'react';
import { Controller, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { mutate } from 'swr';
import { z } from 'zod';
import { LabManifestConfig } from '../config-schema';
import { useLabManifest } from '../hooks';
import {
addOrderToManifest,
Expand All @@ -28,7 +28,6 @@ import {
import { ActiveRequestOrder } from '../types';
import ActiveOrdersSelectionPreview from './active-order-selection-preview';
import styles from './lab-manifest-form.scss';
import { LabManifestConfig } from '../config-schema';

interface LabManifestOrdersToManifestFormProps {
onClose: () => void;
Expand All @@ -54,7 +53,6 @@ const LabManifestOrdersToManifestForm: React.FC<LabManifestOrdersToManifestFormP
}) => {
const { t } = useTranslation();
const form = useForm<OrderToManifestFormType>({
defaultValues: {},
resolver: zodResolver(labManifestOrderToManifestFormSchema),
});
const { sampleTypes } = useConfig<LabManifestConfig>();
Expand All @@ -67,15 +65,27 @@ const LabManifestOrdersToManifestForm: React.FC<LabManifestOrdersToManifestFormP
);
results.forEach((res) => {
if (res.status === 'fulfilled') {
showSnackbar({ title: 'Success', kind: 'success', subtitle: 'Order added succesfully' });
showSnackbar({
title: 'Success',
kind: 'success',
subtitle: t('manifestorderAddSuccess', 'Order added succesfully'),
});
} else {
showSnackbar({ title: 'Failure', kind: 'error', subtitle: 'Error adding order to the manifest' });
showSnackbar({
title: 'Failure',
kind: 'error',
subtitle: t('manifestOrderError', 'Error adding order to the manifest') + ` ${res.reason}`,
});
}
});
mutateManifestLinks(manifest?.uuid, manifest?.manifestStatus);
onClose();
} catch (error) {
showSnackbar({ title: 'Failure', kind: 'error', subtitle: 'Error adding orders to the manifest' });
showSnackbar({
title: 'Failure',
kind: 'error',
subtitle: t('manifestOrderError', 'Error adding order to the manifest') + ` ${error?.message}`,
});
}
};

Expand Down Expand Up @@ -112,12 +122,13 @@ const LabManifestOrdersToManifestForm: React.FC<LabManifestOrdersToManifestFormP
/>
</Column>
<Row className={styles.datePickersRow}>
<Column className={styles.datePickerInput}>
<Column className={styles.inputRow}>
<Controller
control={form.control}
name="sampleCollectionDate"
render={({ field }) => (
<DatePicker
className={styles.datePickerInput}
dateFormat="d/m/Y"
id="sampleCollectionDate"
datePickerType="single"
Expand All @@ -129,17 +140,19 @@ const LabManifestOrdersToManifestForm: React.FC<LabManifestOrdersToManifestFormP
invalidText={form.formState.errors[field.name]?.message}
placeholder="mm/dd/yyyy"
labelText={t('sampleCollectionDate', 'Sample collection date')}
size="xl"
/>
</DatePicker>
)}
/>
</Column>
<Column className={styles.datePickerInput}>
<Column className={styles.inputRow}>
<Controller
control={form.control}
name="sampleSeparationDate"
render={({ field }) => (
<DatePicker
className={styles.datePickerInput}
dateFormat="d/m/Y"
id="sampleSeparationDate"
datePickerType="single"
Expand All @@ -151,6 +164,7 @@ const LabManifestOrdersToManifestForm: React.FC<LabManifestOrdersToManifestFormP
invalidText={form.formState.errors[field.name]?.message}
placeholder="mm/dd/yyyy"
labelText={t('sampleSeparationDate', 'Sample seperation date')}
size="xl"
/>
</DatePicker>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import styles from '../tables/lab-manifest-table.scss';
import { LabManifestSample } from '../types';
import PatientNameCell from '../tables/patient-name-cell.component';
import PatientCCCNumbercell from '../tables/patient-ccc-no-cell.component';

interface SampleDeleteConfirmDialogProps {
onClose: () => void;
Expand All @@ -30,7 +32,11 @@ const SampleDeleteConfirmDialog: React.FC<SampleDeleteConfirmDialogProps> = ({ o

const headers = [
{
header: t('patientIdentifier', 'Patient Identifier'),
header: t('patient', 'Patient'),
key: 'patient',
},
{
header: t('cccKDODNumber', 'CCC/KDOD Number'),
key: 'cccKDODNumber',
},
{
Expand Down Expand Up @@ -62,7 +68,12 @@ const SampleDeleteConfirmDialog: React.FC<SampleDeleteConfirmDialogProps> = ({ o
sampleType: sample.sampleType ?? '--',
status: sample.status,
batchNumber: sample.batchNumber ?? '--',
cccKDODNumber: sample?.order?.patient?.identifiers[0]?.identifier ?? '--',
patient: sample?.order?.patient?.uuid ? <PatientNameCell patientUuid={sample?.order?.patient?.uuid} /> : '--',
cccKDODNumber: sample?.order?.patient?.uuid ? (
<PatientCCCNumbercell patientUuid={sample?.order?.patient?.uuid} />
) : (
'--'
),
dateRequested: sample.dateSent ? formatDate(parseDate(sample.dateSent)) : '--',
resultDate: sample.resultDate ? formatDate(parseDate(sample.resultDate)) : '--',
result: sample.result ?? '--',
Expand Down
16 changes: 16 additions & 0 deletions packages/esm-lab-manifest-app/src/hooks/useIsKDoDSite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
import React from 'react';
import useSWR from 'swr';

const useIsKDoDSite = () => {
const key = 'kenyaemr.isKDoD';
const customeRep = 'custom:(property,value)';
const url = `${restBaseUrl}/systemsetting?v=${customeRep}&q=${key}`;
const { data, error, isLoading } = useSWR<FetchResponse<{ results: Array<{ property: string; value: string }> }>>(
url,
openmrsFetch,
);
return { isKDoDSite: data?.data?.results?.find((res) => res?.property === key)?.value === 'true', isLoading, error };
};

export default useIsKDoDSite;
16 changes: 16 additions & 0 deletions packages/esm-lab-manifest-app/src/hooks/usePatient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
import useSWR from 'swr';

const usePatient = (patientUuid: string) => {
const customerep = 'custom:(person:(display),identifiers:(identifier,identifierType:(uuid)))';
const url = `${restBaseUrl}/patient/${patientUuid}?v=${customerep}`;
const { data, error, isLoading } = useSWR<
FetchResponse<{
person: { display: string };
identifiers: Array<{ identifier: string; identifierType: { uuid: string } }>;
}>
>(url, openmrsFetch);
return { patient: data?.data, error, isLoading };
};

export default usePatient;
Loading

0 comments on commit 969cf9a

Please sign in to comment.