Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ccc and patient name to manifest samples table and flu sample types #498

Merged
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
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'),
Copy link
Collaborator

@makombe makombe Dec 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the KDOD number same as ccc number? I can't remember cc @njorocs

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats how it was named in 2.x, unless they are different

Copy link
Collaborator Author

@Omoshlawi Omoshlawi Dec 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just saw that we have kdod identifier type, should it check for ccc, if not found then look for kdod identifier for the patient?and if all are available which one should be displayed? cc @PatrickWaweru @donaldkibet

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It depends on the system type. If it is a KDOD system, display KDOD. Else, display CCC.

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
Loading