@kenyaemr/esm-patient-clinical-view-app 5.4.2-pre.2668 → 5.4.2-pre.2676

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"kenyaemr":"^19.0.0"},"pages":[],"extensions":[{"name":"hiv-care-and-treatment-dashboard-link","component":"hivCareAndTreatmentLink","slot":"patient-chart-dashboard-slot","meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-hiv-care-and-treatment-dashboard-slot","path":"hiv-care-and-treatment-dashboard","layoutMode":"anchored"}},{"name":"hiv-care-and-treatment-dashboard","slot":"patient-chart-hiv-care-and-treatment-dashboard-slot","component":"hivCareAndTreatment","order":0,"online":true,"offline":false},{"name":"relationship-dashboard-link","component":"relationshipsLink","order":24,"online":true,"offline":false,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-relationship-slot","path":"relationships","layoutMode":"anchored"}},{"name":"relationship-dashboard","slot":"patient-chart-relationship-slot","component":"relationships","order":0,"online":true,"offline":false},{"name":"clinical-encounter-dashboard-link","component":"clinicalEncounterLink","order":25,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-clinical-encounter-slot","path":"clinical-encounter","layoutMode":"anchored"}},{"name":"clinical-encounter-dashboard","slot":"patient-chart-clinical-encounter-slot","component":"clinicalEncounter","order":0,"online":true,"offline":false},{"name":"maternal-and-child-health-dashboard-link","component":"maternalAndChildHealthDashboardLink","order":26,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-maternal-and-child-health-slot","path":"maternal-and-child-health","layoutMode":"anchored"}},{"name":"maternal-and-child-health-dashboard","slot":"patient-chart-maternal-and-child-health-slot","component":"maternalAndChildHealthDashboard","order":0,"online":true,"offline":false},{"name":"maternal-and-child-health-partograph","slot":"maternal-and-child-health-partograph-slot","component":"partograph","order":0,"online":true,"offline":false},{"name":"contact-list-dashboard-link","component":"contactListLink","order":27,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-contact-list-slot","path":"contact-list","layoutMode":"anchored"}},{"name":"contact-list-dashboard","slot":"patient-chart-contact-list-slot","component":"contactList","order":0,"online":true,"offline":false},{"component":"caseManagementDashboardLink","name":"case-management-dashboard-link","meta":{"name":"case-management","title":"Case Management","slot":"case-management-dashboard-slot","path":"/case-management"}},{"name":"in-patient-dashboard-link","component":"inPatientChartLink","order":7,"meta":{"slot":"patient-chart-in-patient-dashboard-slot","path":"in-patient","layoutMode":"anchored","columns":1,"columnSpan":1}},{"name":"in-patient-dashboard","slot":"patient-chart-in-patient-dashboard-slot","component":"inPatientChartDashboard","meta":{"fullWidth":false}},{"name":"wrap-component-view","slot":"case-management-dashboard-slot","component":"wrapComponent","order":2,"online":true,"offline":false},{"name":"case-encounter-link","component":"caseEncounterDashboardLink","order":14,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-case-encounter-slot","path":"case-management-encounters","layoutMode":"anchored"}},{"name":"case-encounter-table","slot":"patient-chart-case-encounter-slot","component":"caseEncounterTable","order":0,"online":true,"offline":false},{"component":"peerCalendarDashboardLink","name":"peer-calendar-dashboard-link","meta":{"name":"peer-calendar","title":"Peer Calendar","slot":"peer-calendar-dashboard-slot","path":"peer-management"}},{"name":"peer-calendar","slot":"peer-calendar-dashboard-slot","component":"peerCalendar","order":0,"online":true,"offline":false},{"name":"special-clinics-dashboard-link","component":"specialClinicsDashboardLink","order":15,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-special-clinics-slot","path":"special-clinics","layoutMode":"anchored"}},{"name":"special-clinics-dashboard","slot":"patient-chart-special-clinics-slot","component":"specialClinicsDashboard","order":0,"online":true,"offline":false}],"modals":[{"name":"birth-date-calculator","component":"birthDateCalculator"},{"name":"relationship-delete-confirm-dialog","component":"relationshipDeleteConfirmialog"},{"name":"end-relationship-dialog","component":"endRelationshipModal"}],"workspaces":[{"name":"contact-list-form","component":"contactListForm","title":"Contact List Form","type":"form"},{"name":"case-management-form","component":"caseManagementForm","title":"Case Management Form","type":"form"},{"name":"family-relationship-form","component":"familyRelationshipForm","title":"Family Relationship Form","type":"form"},{"name":"peers-form","component":"peersForm","title":"Add New Peer","type":"form"},{"name":"kenyaemr-cusom-form-entry-workspace","component":"peerCalendarFormEntry","title":"KVP Peer Educator Outreach Calendar","type":"form","width":"extra-wide","canMaximize":true,"canHide":true},{"name":"contact-list-update-form","component":"contactListUpdateForm","title":"Contact List Update Form","type":"form"},{"name":"other-relationship-form","component":"otherRelationshipsForm","title":"Other Relationships Form","type":"form"},{"name":"end-relationship-form","component":"endRelationshipWorkspace","title":"Discontinue relationship form","type":"form"}],"version":"5.4.2-pre.2668"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"kenyaemr":"^19.0.0"},"pages":[],"extensions":[{"name":"hiv-care-and-treatment-dashboard-link","component":"hivCareAndTreatmentLink","slot":"patient-chart-dashboard-slot","meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-hiv-care-and-treatment-dashboard-slot","path":"hiv-care-and-treatment-dashboard","layoutMode":"anchored"}},{"name":"hiv-care-and-treatment-dashboard","slot":"patient-chart-hiv-care-and-treatment-dashboard-slot","component":"hivCareAndTreatment","order":0,"online":true,"offline":false},{"name":"relationship-dashboard-link","component":"relationshipsLink","order":24,"online":true,"offline":false,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-relationship-slot","path":"relationships","layoutMode":"anchored"}},{"name":"relationship-dashboard","slot":"patient-chart-relationship-slot","component":"relationships","order":0,"online":true,"offline":false},{"name":"clinical-encounter-dashboard-link","component":"clinicalEncounterLink","order":25,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-clinical-encounter-slot","path":"clinical-encounter","layoutMode":"anchored"}},{"name":"clinical-encounter-dashboard","slot":"patient-chart-clinical-encounter-slot","component":"clinicalEncounter","order":0,"online":true,"offline":false},{"name":"maternal-and-child-health-dashboard-link","component":"maternalAndChildHealthDashboardLink","order":26,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-maternal-and-child-health-slot","path":"maternal-and-child-health","layoutMode":"anchored"}},{"name":"maternal-and-child-health-dashboard","slot":"patient-chart-maternal-and-child-health-slot","component":"maternalAndChildHealthDashboard","order":0,"online":true,"offline":false},{"name":"maternal-and-child-health-partograph","slot":"maternal-and-child-health-partograph-slot","component":"partograph","order":0,"online":true,"offline":false},{"name":"contact-list-dashboard-link","component":"contactListLink","order":27,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-contact-list-slot","path":"contact-list","layoutMode":"anchored"}},{"name":"contact-list-dashboard","slot":"patient-chart-contact-list-slot","component":"contactList","order":0,"online":true,"offline":false},{"component":"caseManagementDashboardLink","name":"case-management-dashboard-link","meta":{"name":"case-management","title":"Case Management","slot":"case-management-dashboard-slot","path":"/case-management"}},{"name":"in-patient-dashboard-link","component":"inPatientChartLink","order":7,"meta":{"slot":"patient-chart-in-patient-dashboard-slot","path":"in-patient","layoutMode":"anchored","columns":1,"columnSpan":1}},{"name":"in-patient-dashboard","slot":"patient-chart-in-patient-dashboard-slot","component":"inPatientChartDashboard","meta":{"fullWidth":false}},{"name":"wrap-component-view","slot":"case-management-dashboard-slot","component":"wrapComponent","order":2,"online":true,"offline":false},{"name":"case-encounter-link","component":"caseEncounterDashboardLink","order":14,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-case-encounter-slot","path":"case-management-encounters","layoutMode":"anchored"}},{"name":"case-encounter-table","slot":"patient-chart-case-encounter-slot","component":"caseEncounterTable","order":0,"online":true,"offline":false},{"component":"peerCalendarDashboardLink","name":"peer-calendar-dashboard-link","meta":{"name":"peer-calendar","title":"Peer Calendar","slot":"peer-calendar-dashboard-slot","path":"peer-management"}},{"name":"peer-calendar","slot":"peer-calendar-dashboard-slot","component":"peerCalendar","order":0,"online":true,"offline":false},{"name":"special-clinics-dashboard-link","component":"specialClinicsDashboardLink","order":15,"meta":{"columns":1,"columnSpan":1,"slot":"patient-chart-special-clinics-slot","path":"special-clinics","layoutMode":"anchored"}},{"name":"special-clinics-dashboard","slot":"patient-chart-special-clinics-slot","component":"specialClinicsDashboard","order":0,"online":true,"offline":false}],"modals":[{"name":"birth-date-calculator","component":"birthDateCalculator"},{"name":"relationship-delete-confirm-dialog","component":"relationshipDeleteConfirmialog"},{"name":"end-relationship-dialog","component":"endRelationshipModal"}],"workspaces":[{"name":"contact-list-form","component":"contactListForm","title":"Contact List Form","type":"form"},{"name":"case-management-form","component":"caseManagementForm","title":"Case Management Form","type":"form"},{"name":"add-patient-case-form","component":"addPatientCaseForm","title":"Add patient case Form","type":"form"},{"name":"family-relationship-form","component":"familyRelationshipForm","title":"Family Relationship Form","type":"form"},{"name":"peers-form","component":"peersForm","title":"Add New Peer","type":"form"},{"name":"kenyaemr-cusom-form-entry-workspace","component":"peerCalendarFormEntry","title":"KVP Peer Educator Outreach Calendar","type":"form","width":"extra-wide","canMaximize":true,"canHide":true},{"name":"contact-list-update-form","component":"contactListUpdateForm","title":"Contact List Update Form","type":"form"},{"name":"other-relationship-form","component":"otherRelationshipsForm","title":"Other Relationships Form","type":"form"},{"name":"end-relationship-form","component":"endRelationshipWorkspace","title":"Discontinue relationship form","type":"form"}],"version":"5.4.2-pre.2676"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenyaemr/esm-patient-clinical-view-app",
3
- "version": "5.4.2-pre.2668",
3
+ "version": "5.4.2-pre.2676",
4
4
  "description": "Patient clinical view microfrontend for the OpenMRS SPA",
5
5
  "keywords": [
6
6
  "openmrs"
@@ -16,6 +16,7 @@ import { ConfigObject } from '../../config-schema';
16
16
  import GenericTable from '../../specialized-clinics/generic-nav-links/generic-table.component';
17
17
  import styles from './case-encounter-header.scss';
18
18
  import { deleteEncounter, useInfiniteVisits } from './case-encounter-table.resource';
19
+ import PatientHasActiveCase from './patient-has-active-case.component.tsx';
19
20
 
20
21
  interface CaseEncounterProps {
21
22
  mutate: KeyedMutator<any>;
@@ -198,7 +199,7 @@ const CaseEncounterOverviewComponent = ({ patientUuid }: CaseEncounterOverviewCo
198
199
  }
199
200
 
200
201
  return (
201
- <>
202
+ <PatientHasActiveCase patientUuid={patientUuid}>
202
203
  <CaseEncounterHeader patientUuid={patientUuid} mutate={mutateVisits} onFilterChange={setFilterFormUuid} />
203
204
  {filteredEncounters.length === 0 ? (
204
205
  <Layer>
@@ -230,7 +231,7 @@ const CaseEncounterOverviewComponent = ({ patientUuid }: CaseEncounterOverviewCo
230
231
  />
231
232
  </div>
232
233
  )}
233
- </>
234
+ </PatientHasActiveCase>
234
235
  );
235
236
  };
236
237
 
@@ -1,5 +1,9 @@
1
- import { openmrsFetch, restBaseUrl, useConfig } from '@openmrs/esm-framework';
1
+ import { FetchResponse, openmrsFetch, restBaseUrl, useConfig } from '@openmrs/esm-framework';
2
+ import { useMemo } from 'react';
3
+ import useSWR from 'swr';
2
4
  import useSWRInfinite from 'swr/infinite';
5
+ import { ConfigObject } from '../../config-schema';
6
+ import dayjs from 'dayjs';
3
7
 
4
8
  export interface ChartConfig {
5
9
  freeTextFieldConceptUuid: string;
@@ -101,3 +105,45 @@ export function deleteEncounter(encounterUuid: string, abortController: AbortCon
101
105
  signal: abortController.signal,
102
106
  });
103
107
  }
108
+
109
+ type Relationship = {
110
+ display: string;
111
+ uuid: string;
112
+ personA: {
113
+ uuid: string;
114
+ display: string;
115
+ };
116
+ personB: {
117
+ uuid: string;
118
+ display: string;
119
+ };
120
+ startDate: string;
121
+ endDate: string;
122
+ relationshipType: {
123
+ uuid: string;
124
+ display: string;
125
+ };
126
+ };
127
+
128
+ export const usePatientActiveCases = (patientUuid: string) => {
129
+ const { caseManagerRelationshipType } = useConfig<ConfigObject>();
130
+ const rep =
131
+ 'custom:(display,uuid,personA:(uuid,display),personB:(uuid,display),startDate,endDate,relationshipType:(uuid,display))';
132
+ const url = `${restBaseUrl}/relationship?person=${patientUuid}&v=${rep}`;
133
+ const { data, error, isLoading, mutate } = useSWR<FetchResponse<{ results: Array<Relationship> }>>(url, openmrsFetch);
134
+ const activeCases = useMemo(
135
+ () =>
136
+ (data?.data?.results ?? []).filter(
137
+ (rel) =>
138
+ rel.relationshipType.uuid === caseManagerRelationshipType &&
139
+ (!rel.endDate || dayjs(rel.endDate).isAfter(dayjs())),
140
+ ),
141
+ [data, caseManagerRelationshipType],
142
+ );
143
+ return {
144
+ activeCases,
145
+ isLoading,
146
+ mutate,
147
+ error,
148
+ };
149
+ };
@@ -0,0 +1,36 @@
1
+ @use '@carbon/type';
2
+ @use '@carbon/layout';
3
+ @use '@carbon/colors';
4
+
5
+ .form {
6
+ display: flex;
7
+ flex-direction: column;
8
+ justify-content: space-between;
9
+ width: 100%;
10
+ height: 100%;
11
+ }
12
+
13
+ .grid {
14
+ margin: layout.$spacing-05 layout.$spacing-05;
15
+ padding: layout.$spacing-05 0 0 0;
16
+ }
17
+
18
+ .button {
19
+ display: flex;
20
+ align-content: flex-start;
21
+ align-items: baseline;
22
+ min-width: 50%;
23
+ }
24
+
25
+ .buttonSet {
26
+ display: flex;
27
+ justify-content: space-between;
28
+ width: 100%;
29
+ }
30
+
31
+ .datePickerInput span,
32
+ .datePickerInput div,
33
+ .datePickerInput input,
34
+ .datePickerInput {
35
+ min-width: 100%;
36
+ }
@@ -0,0 +1,182 @@
1
+ import React, { FC } from 'react';
2
+ import { saveRelationship, useCaseManagers } from '../workspace/case-management.resource';
3
+ import { DefaultWorkspaceProps, showSnackbar, useConfig } from '@openmrs/esm-framework';
4
+ import usePerson from '../../contact-list/contact-list.resource';
5
+ import { relationshipFormSchema } from '../../relationships/relationship.resources';
6
+ import { Controller, useForm } from 'react-hook-form';
7
+ import z from 'zod';
8
+ import { zodResolver } from '@hookform/resolvers/zod';
9
+ import {
10
+ Button,
11
+ ButtonSet,
12
+ Column,
13
+ ComboBox,
14
+ DatePicker,
15
+ DatePickerInput,
16
+ Form,
17
+ Stack,
18
+ TextInput,
19
+ } from '@carbon/react';
20
+ import styles from './patient-case-form.scss';
21
+ import { useTranslation } from 'react-i18next';
22
+ import { extractNameString, uppercaseText } from '../../utils/expression-helper';
23
+ import { ConfigObject } from '../../config-schema';
24
+ import { usePatientActiveCases } from './case-encounter-table.resource';
25
+
26
+ type PatientCaseFormProps = DefaultWorkspaceProps & { patientUuid: string };
27
+ const formSchema = relationshipFormSchema.pick({
28
+ personA: true,
29
+ personB: true,
30
+ relationshipType: true,
31
+ startDate: true,
32
+ endDate: true,
33
+ });
34
+
35
+ type FormType = z.infer<typeof formSchema>;
36
+
37
+ const PatientCaseForm: FC<PatientCaseFormProps> = ({ closeWorkspace, patientUuid }) => {
38
+ const { data } = useCaseManagers();
39
+ const { isLoading, person } = usePerson(patientUuid);
40
+ const { caseManagerRelationshipType } = useConfig<ConfigObject>();
41
+ const { mutate } = usePatientActiveCases(patientUuid);
42
+ const { t } = useTranslation();
43
+ const caseManagers =
44
+ data?.data.results.map((manager) => ({
45
+ id: manager.person.uuid,
46
+ text: manager.display,
47
+ })) || [];
48
+
49
+ const form = useForm<FormType>({
50
+ mode: 'all',
51
+ defaultValues: {
52
+ personA: patientUuid,
53
+ personB: '',
54
+ relationshipType: caseManagerRelationshipType,
55
+ },
56
+ resolver: zodResolver(formSchema),
57
+ });
58
+
59
+ const onSubmit = async (values: FormType) => {
60
+ try {
61
+ await saveRelationship(values);
62
+ showSnackbar({
63
+ kind: 'success',
64
+ title: t('success', 'Success'),
65
+ subtitle: t('caseSavedSuccesfully', 'Case saved successfully'),
66
+ isLowContrast: true,
67
+ });
68
+ mutate();
69
+ closeWorkspace();
70
+ } catch (error) {
71
+ showSnackbar({
72
+ kind: 'error',
73
+ title: t('error', 'Error'),
74
+ subtitle: t('errorAddingCase', 'Error Adding patient case'),
75
+ isLowContrast: true,
76
+ });
77
+ }
78
+ };
79
+
80
+ return (
81
+ <Form onSubmit={form.handleSubmit(onSubmit)} className={styles.form}>
82
+ <Stack gap={4} className={styles.grid}>
83
+ <Column>
84
+ <Controller
85
+ control={form.control}
86
+ name="startDate"
87
+ render={({ field, fieldState: { error } }) => (
88
+ <DatePicker
89
+ className={styles.datePickerInput}
90
+ dateFormat="d/m/Y"
91
+ datePickerType="single"
92
+ {...field}
93
+ onChange={([date]) => field.onChange(date)}
94
+ ref={undefined}
95
+ invalid={!!error?.message}
96
+ invalidText={error?.message}>
97
+ <DatePickerInput
98
+ id={`startdate-input`}
99
+ invalid={!!error?.message}
100
+ invalidText={error?.message}
101
+ placeholder="mm/dd/yyyy"
102
+ labelText={t('startDate', 'Start Date')}
103
+ size="lg"
104
+ />
105
+ </DatePicker>
106
+ )}
107
+ />
108
+ </Column>
109
+ <Column>
110
+ <Controller
111
+ control={form.control}
112
+ name="endDate"
113
+ render={({ field, fieldState: { error } }) => (
114
+ <DatePicker
115
+ className={styles.datePickerInput}
116
+ dateFormat="d/m/Y"
117
+ datePickerType="single"
118
+ {...field}
119
+ onChange={([date]) => field.onChange(date)}
120
+ invalid={!!error?.message}
121
+ invalidText={error?.message}>
122
+ <DatePickerInput
123
+ id="endDate"
124
+ invalid={!!error?.message}
125
+ invalidText={error?.message}
126
+ placeholder="mm/dd/yyyy"
127
+ labelText={t('endDate', 'End Date')}
128
+ size="lg"
129
+ />
130
+ </DatePicker>
131
+ )}
132
+ />
133
+ </Column>
134
+ <Column>
135
+ <TextInput id="patient" labelText={t('patient', 'Patient')} value={person?.display} readOnly />
136
+ </Column>
137
+ <Column>
138
+ <Controller
139
+ name="personB"
140
+ control={form.control}
141
+ render={({ field, fieldState }) => {
142
+ return (
143
+ <ComboBox
144
+ id="case_manager_name"
145
+ titleText={t('manager', 'Case Manager')}
146
+ placeholder="Select Case Manager"
147
+ items={caseManagers}
148
+ itemToString={(item) => uppercaseText(extractNameString(item ? item.text : ''))}
149
+ onChange={(e) => {
150
+ field.onChange(e.selectedItem?.id);
151
+ }}
152
+ selectedItem={caseManagers.find((manager) => manager.id === field.value)}
153
+ invalid={!!fieldState.error}
154
+ invalidText={fieldState.error?.message}
155
+ />
156
+ );
157
+ }}
158
+ />
159
+ </Column>
160
+ <Column>
161
+ <TextInput
162
+ id="relationshipType"
163
+ labelText={t('relationshipType', 'Relationship to patient')}
164
+ value={t('caseManager', 'Case Manager')}
165
+ readOnly
166
+ />
167
+ </Column>
168
+ </Stack>
169
+
170
+ <ButtonSet className={styles.buttonSet}>
171
+ <Button className={styles.button} kind="secondary" onClick={() => closeWorkspace()}>
172
+ {t('discard', 'Discard')}
173
+ </Button>
174
+ <Button className={styles.button} kind="primary" type="submit" disabled={form.formState.isSubmitting}>
175
+ {t('submit', 'Submit')}
176
+ </Button>
177
+ </ButtonSet>
178
+ </Form>
179
+ );
180
+ };
181
+
182
+ export default PatientCaseForm;
@@ -0,0 +1,34 @@
1
+ import React, { FC, PropsWithChildren } from 'react';
2
+ import { usePatientActiveCases } from './case-encounter-table.resource';
3
+ import { DataTableSkeleton } from '@carbon/react';
4
+ import { ErrorState, launchWorkspace } from '@openmrs/esm-framework';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { EmptyState } from '@openmrs/esm-patient-common-lib';
7
+
8
+ type PatientHasActiveCaseProps = PropsWithChildren<{ patientUuid: string }>;
9
+
10
+ const PatientHasActiveCase: FC<PatientHasActiveCaseProps> = ({ patientUuid, children }) => {
11
+ const { activeCases, error, isLoading } = usePatientActiveCases(patientUuid);
12
+ const { t } = useTranslation();
13
+ const handleAddPatientCase = () => {
14
+ launchWorkspace('add-patient-case-form', { workspaceTitle: 'Add Patient Case', patientUuid });
15
+ };
16
+ if (isLoading) {
17
+ return <DataTableSkeleton />;
18
+ }
19
+ if (error) {
20
+ return <ErrorState error={error} headerTitle={t('patientCases', 'Patient Cases')} />;
21
+ }
22
+ if (!activeCases?.length) {
23
+ return (
24
+ <EmptyState
25
+ headerTitle={t('patientCases', 'Patient Cases')}
26
+ displayText={t('patientActiveCase', 'Patient Active case')}
27
+ launchForm={handleAddPatientCase}
28
+ />
29
+ );
30
+ }
31
+ return <>{children}</>;
32
+ };
33
+
34
+ export default PatientHasActiveCase;
@@ -52,6 +52,7 @@ export const configSchema = {
52
52
  peerCalendarOutreactForm: '7492cffe-5874-4144-a1e6-c9e455472a35',
53
53
  autopsyFormUuid: '2b61a73-4971-4fc0-b20b-9a30176317e2',
54
54
  htsClientTracingFormUuid: '15ed03d2-c972-11e9-a32f-2a2ae2dbcce4',
55
+ admissionRequestFormUuid: '0bae7646-b079-4cbb-8130-b24274fc16f7',
55
56
  },
56
57
  },
57
58
  htsClientTracingConceptsUuids: {
@@ -409,6 +410,11 @@ export const configSchema = {
409
410
  },
410
411
  },
411
412
  },
413
+ caseManagerRelationshipType: {
414
+ _type: Type.UUID,
415
+ _description: 'Case manager/Client relationship type UUID',
416
+ _default: '9065e3c6-b2f5-4f99-9cbf-f67fd9f82ec5',
417
+ },
412
418
  };
413
419
 
414
420
  export interface ConfigObject {
@@ -442,6 +448,7 @@ export interface ConfigObject {
442
448
  peerCalendarOutreactForm: string;
443
449
  autopsyFormUuid: string;
444
450
  htsClientTracingFormUuid: string;
451
+ admissionRequestFormUuid: string;
445
452
  };
446
453
  defaulterTracingEncounterUuid: string;
447
454
  autopsyEncounterFormUuid: string;
@@ -501,6 +508,7 @@ export interface ConfigObject {
501
508
  bloodPressureDecrement: number;
502
509
  };
503
510
  };
511
+ caseManagerRelationshipType: string;
504
512
  }
505
513
 
506
514
  export interface PartograpyComponents {
@@ -0,0 +1,117 @@
1
+ import React, { useMemo } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import {
4
+ Button,
5
+ DataTable,
6
+ DataTableSkeleton,
7
+ Table,
8
+ TableBody,
9
+ TableCell,
10
+ TableHead,
11
+ TableHeader,
12
+ TableRow,
13
+ } from '@carbon/react';
14
+ import { formatDatetime, isDesktop, launchWorkspace, useConfig, useLayoutType } from '@openmrs/esm-framework';
15
+ import { CardHeader, EmptyState, ErrorState } from '@openmrs/esm-patient-common-lib';
16
+
17
+ import { useAdmissionRequest } from './in-patient.resource';
18
+ import { ConfigObject } from '../config-schema';
19
+ import { Add } from '@carbon/react/icons';
20
+
21
+ type AdmissionRequestProps = {
22
+ patientUuid: string;
23
+ };
24
+
25
+ const AdmissionRequest: React.FC<AdmissionRequestProps> = ({ patientUuid }) => {
26
+ const { t } = useTranslation();
27
+ const layout = useLayoutType();
28
+ const controlSize = isDesktop(layout) ? 'sm' : 'md';
29
+ const {
30
+ formsList: { admissionRequestFormUuid },
31
+ } = useConfig<ConfigObject>();
32
+ const { admissionRequest, isLoading, error, mutate } = useAdmissionRequest(patientUuid);
33
+
34
+ const rows = useMemo(() => {
35
+ return admissionRequest.map((admissionRequest) => ({
36
+ id: admissionRequest.patient.uuid,
37
+ admissionLocation: admissionRequest.dispositionLocation?.display,
38
+ admissionType: admissionRequest.dispositionType,
39
+ disposition: admissionRequest.disposition.display,
40
+ requestDatetime: formatDatetime(new Date(admissionRequest.dispositionEncounter.encounterDatetime), {
41
+ mode: 'standard',
42
+ }),
43
+ }));
44
+ }, [admissionRequest]);
45
+
46
+ const headers = useMemo(() => {
47
+ return [
48
+ { key: 'requestDatetime', header: t('requestDatetime', 'Request Datetime') },
49
+ { key: 'admissionLocation', header: t('admissionLocation', 'Admission Location') },
50
+ { key: 'admissionType', header: t('admissionType', 'Admission Type') },
51
+ { key: 'disposition', header: t('disposition', 'Disposition') },
52
+ ];
53
+ }, []);
54
+
55
+ const handleLaunchAdmissionRequestForm = () => {
56
+ launchWorkspace('patient-form-entry-workspace', {
57
+ workspaceTitle: 'Admission Request',
58
+ mutateForm: mutate,
59
+ formInfo: {
60
+ formUuid: admissionRequestFormUuid,
61
+ encounterUuid: '',
62
+ },
63
+ });
64
+ };
65
+
66
+ if (isLoading) {
67
+ return <DataTableSkeleton />;
68
+ }
69
+
70
+ if (error) {
71
+ return <ErrorState error={error} headerTitle={t('admissionRequest', 'Admission Request')} />;
72
+ }
73
+
74
+ if (admissionRequest.length === 0) {
75
+ return (
76
+ <EmptyState
77
+ displayText={t('admissionRequests', 'admission requests')}
78
+ headerTitle={t('admissionRequest', 'Admission Request')}
79
+ launchForm={handleLaunchAdmissionRequestForm}
80
+ />
81
+ );
82
+ }
83
+
84
+ return (
85
+ <div>
86
+ <CardHeader title={t('admissionRequest', 'Admission Request')}>
87
+ <Button renderIcon={Add} onClick={handleLaunchAdmissionRequestForm} kind="ghost">
88
+ {t('add', 'Add')}
89
+ </Button>
90
+ </CardHeader>
91
+ <DataTable size={controlSize} rows={rows} headers={headers}>
92
+ {({ rows, headers, getTableProps, getHeaderProps, getRowProps, getCellProps }) => (
93
+ <Table {...getTableProps()}>
94
+ <TableHead>
95
+ <TableRow>
96
+ {headers.map((header) => (
97
+ <TableHeader {...getHeaderProps({ header })}>{header.header}</TableHeader>
98
+ ))}
99
+ </TableRow>
100
+ </TableHead>
101
+ <TableBody>
102
+ {rows.map((row) => (
103
+ <TableRow {...getRowProps({ row })}>
104
+ {row.cells.map((cell) => (
105
+ <TableCell {...getCellProps({ cell })}>{cell.value}</TableCell>
106
+ ))}
107
+ </TableRow>
108
+ ))}
109
+ </TableBody>
110
+ </Table>
111
+ )}
112
+ </DataTable>
113
+ </div>
114
+ );
115
+ };
116
+
117
+ export default AdmissionRequest;