@openmrs/esm-patient-common-lib 11.3.1-pre.9447 → 11.3.1-pre.9455

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-patient-common-lib",
3
- "version": "11.3.1-pre.9447",
3
+ "version": "11.3.1-pre.9455",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Library for common patient chart components",
6
6
  "browser": "dist/openmrs-esm-patient-common-lib.js",
@@ -1,10 +1,10 @@
1
1
  import React from 'react';
2
2
  import userEvent from '@testing-library/user-event';
3
3
  import { render, screen } from '@testing-library/react';
4
- import { launchWorkspace } from '@openmrs/esm-framework';
4
+ import { launchWorkspace2 } from '@openmrs/esm-framework';
5
5
  import { EmptyState } from '.';
6
6
 
7
- const mockLaunchWorkspace = jest.mocked(launchWorkspace);
7
+ const mockLaunchWorkspace = jest.mocked(launchWorkspace2);
8
8
 
9
9
  describe('EmptyState', () => {
10
10
  it('renders an empty state widget card', () => {
@@ -12,7 +12,7 @@ describe('EmptyState', () => {
12
12
  <EmptyState
13
13
  headerTitle="appointments"
14
14
  displayText="appointments"
15
- launchForm={() => launchWorkspace('sample-form-workspace')}
15
+ launchForm={() => launchWorkspace2('sample-form-workspace')}
16
16
  />,
17
17
  );
18
18
 
@@ -28,7 +28,7 @@ describe('EmptyState', () => {
28
28
  <EmptyState
29
29
  headerTitle="appointments"
30
30
  displayText="appointments"
31
- launchForm={() => launchWorkspace('sample-form-workspace')}
31
+ launchForm={() => launchWorkspace2('sample-form-workspace')}
32
32
  />,
33
33
  );
34
34
 
@@ -1,4 +1,4 @@
1
- import { type HtmlFormEntryForm } from '../types';
1
+ import { type Encounter, type Visit, type Workspace2DefinitionProps } from '@openmrs/esm-framework';
2
2
 
3
3
  export interface FormEntryProps {
4
4
  encounterUuid?: string;
@@ -7,6 +7,26 @@ export interface FormEntryProps {
7
7
  visitTypeUuid?: string;
8
8
  visitStartDatetime?: string;
9
9
  visitStopDatetime?: string;
10
- htmlForm?: HtmlFormEntryForm;
11
10
  additionalProps?: Record<string, any>;
12
11
  }
12
+
13
+ /**
14
+ * Workspace control props are made optional to support usage in non-workspace contexts,
15
+ * such as the Fast Data Entry app or other standalone form zones.
16
+ */
17
+ export interface FormRendererProps {
18
+ additionalProps?: Record<string, any>;
19
+ encounterUuid?: string;
20
+ formUuid: string;
21
+ patientUuid: string;
22
+ patient: fhir.Patient;
23
+ visit?: Visit;
24
+ visitUuid?: string;
25
+ hideControls?: boolean;
26
+ hidePatientBanner?: boolean;
27
+ handlePostResponse?: (encounter: Encounter) => void;
28
+ preFilledQuestions?: Record<string, string>;
29
+ launchChildWorkspace?: Workspace2DefinitionProps['launchChildWorkspace'];
30
+ closeWorkspace?: Workspace2DefinitionProps['closeWorkspace'];
31
+ setHasUnsavedChanges?(hasUnsavedChanges: boolean);
32
+ }
package/src/index.ts CHANGED
@@ -3,7 +3,6 @@ export * from './compare';
3
3
  export * from './dashboards/createDashboardLink';
4
4
  export * from './empty-state';
5
5
  export * from './error-state';
6
- export * from './form-entry-interop';
7
6
  export * from './form-entry/form-entry';
8
7
  export * from './launchStartVisitPrompt';
9
8
  export * from './offline/visit';
@@ -1,7 +1,8 @@
1
1
  import { showModal } from '@openmrs/esm-framework';
2
2
 
3
- export function launchStartVisitPrompt() {
3
+ export async function launchStartVisitPrompt(onVisitStarted?: () => void) {
4
4
  const dispose = showModal('start-visit-dialog', {
5
5
  closeModal: () => dispose(),
6
+ onVisitStarted,
6
7
  });
7
8
  }
@@ -1,7 +1,9 @@
1
- export * from './useOrderBasket';
2
1
  export * from './postOrders';
3
- export * from './useOrders';
2
+ export * from './showOrderSuccessToast';
4
3
  export * from './types';
4
+ export * from './useMutatePatientOrders';
5
+ export * from './useOrderBasket';
5
6
  export * from './useOrderableConceptSets';
7
+ export * from './useOrders';
6
8
  export * from './useOrderType';
7
9
  export * from './useOrderTypes';
@@ -120,7 +120,7 @@ export async function postOrders(patientUuid: string, encounterUuid: string, abo
120
120
  return erroredItems;
121
121
  }
122
122
 
123
- function postOrder(body: OrderPost, abortController?: AbortController) {
123
+ export function postOrder(body: OrderPost, abortController?: AbortController) {
124
124
  return openmrsFetch(`${restBaseUrl}/order`, {
125
125
  method: 'POST',
126
126
  signal: abortController?.signal,
@@ -0,0 +1,28 @@
1
+ import { showSnackbar } from '@openmrs/esm-framework';
2
+ import { type TFunction } from 'i18next';
3
+ import { type OrderBasketItem } from './types';
4
+
5
+ export function showOrderSuccessToast(t: TFunction, patientOrderItems: OrderBasketItem[]) {
6
+ const orderedString = patientOrderItems
7
+ .filter((item) => ['NEW', 'RENEW'].includes(item.action))
8
+ .map((item) => item.display)
9
+ .join(', ');
10
+ const updatedString = patientOrderItems
11
+ .filter((item) => item.action === 'REVISE')
12
+ .map((item) => item.display)
13
+ .join(', ');
14
+ const discontinuedString = patientOrderItems
15
+ .filter((item) => item.action === 'DISCONTINUE')
16
+ .map((item) => item.display)
17
+ .join(', ');
18
+
19
+ showSnackbar({
20
+ isLowContrast: true,
21
+ kind: 'success',
22
+ title: t('orderCompleted', 'Placed orders'),
23
+ subtitle:
24
+ (orderedString && `${t('ordered', 'Placed order for')} ${orderedString}. `) +
25
+ (updatedString && `${t('updated', 'Updated')} ${updatedString}. `) +
26
+ (discontinuedString && `${t('discontinued', 'Discontinued')} ${discontinuedString}.`),
27
+ });
28
+ }
@@ -1,4 +1,4 @@
1
- import type { OpenmrsResource } from '@openmrs/esm-framework';
1
+ import type { Encounter, OpenmrsResource, Visit, Workspace2DefinitionProps } from '@openmrs/esm-framework';
2
2
 
3
3
  export interface Concept extends OpenmrsResource {
4
4
  name?: {
@@ -71,6 +71,8 @@ export interface OrderBasketItem {
71
71
  orderType?: string;
72
72
  orderNumber?: string;
73
73
  scheduledDate?: Date;
74
+ encounterUuid?: string;
75
+ visit: Visit;
74
76
  }
75
77
 
76
78
  export type OrderUrgency = 'ROUTINE' | 'STAT' | 'ON_SCHEDULED_DATE';
@@ -142,7 +144,7 @@ export interface Order {
142
144
  drug: Drug;
143
145
  duration: number;
144
146
  durationUnits: OpenmrsResource;
145
- encounter: OpenmrsResource;
147
+ encounter: Encounter;
146
148
  frequency: OpenmrsResource;
147
149
  instructions?: string | null;
148
150
  numRefills: number;
@@ -207,16 +209,114 @@ export interface OrderType {
207
209
  description: string;
208
210
  }
209
211
 
210
- export type FulfillerStatus =
211
- | 'RECEIVED'
212
- | 'IN_PROGRESS'
213
- | 'EXCEPTION'
214
- | 'ON_HOLD'
215
- | 'DECLINED'
216
- | 'COMPLETED';
212
+ export type FulfillerStatus = 'RECEIVED' | 'IN_PROGRESS' | 'EXCEPTION' | 'ON_HOLD' | 'DECLINED' | 'COMPLETED';
217
213
 
218
214
  export type PostDataPrepFunction = (
219
215
  order: OrderBasketItem,
220
216
  patientUuid: string,
221
217
  encounterUuid: string | null,
222
218
  ) => OrderPost;
219
+
220
+ export interface OrderBasketExtensionProps {
221
+ patient: fhir.Patient;
222
+ launchDrugOrderForm(order?: DrugOrderBasketItem): void;
223
+ launchLabOrderForm(orderTypeUuid: string, order?: TestOrderBasketItem): void;
224
+ launchGeneralOrderForm(orderTypeUuid: string, order?: OrderBasketItem): void;
225
+ }
226
+
227
+ export interface DrugOrderBasketItem extends OrderBasketItem {
228
+ drug: Drug;
229
+ unit: DosingUnit;
230
+ commonMedicationName: string;
231
+ dosage: number;
232
+ frequency: MedicationFrequency;
233
+ route: MedicationRoute;
234
+ quantityUnits: QuantityUnit;
235
+ patientInstructions: string;
236
+ asNeeded: boolean;
237
+ asNeededCondition: string;
238
+ startDate: Date | string;
239
+ durationUnit: DurationUnit;
240
+ duration: number | null;
241
+ pillsDispensed: number | null;
242
+ numRefills: number | null;
243
+ indication: string;
244
+ isFreeTextDosage: boolean;
245
+ freeTextDosage: string;
246
+ previousOrder?: string;
247
+ template?: OrderTemplate;
248
+ }
249
+
250
+ export interface DrugOrderTemplate {
251
+ uuid: string;
252
+ name: string;
253
+ drug: Drug;
254
+ template: OrderTemplate;
255
+ }
256
+
257
+ export interface OrderTemplate {
258
+ type: string;
259
+ dosingType: string;
260
+ dosingInstructions: DosingInstructions;
261
+ }
262
+
263
+ export interface DosingInstructions {
264
+ dose: Array<MedicationDosage>;
265
+ units: Array<DosingUnit>;
266
+ route: Array<MedicationRoute>;
267
+ frequency: Array<MedicationFrequency>;
268
+ instructions?: Array<MedicationInstructions>;
269
+ durationUnits?: Array<DurationUnit>;
270
+ quantityUnits?: Array<QuantityUnit>;
271
+ asNeeded?: boolean;
272
+ asNeededCondition?: string;
273
+ }
274
+
275
+ export interface MedicationDosage extends Omit<CommonMedicationProps, 'value'> {
276
+ value: number;
277
+ }
278
+
279
+ export type MedicationFrequency = CommonMedicationValueCoded;
280
+
281
+ export type MedicationRoute = CommonMedicationValueCoded;
282
+
283
+ export type MedicationInstructions = CommonMedicationProps;
284
+
285
+ export type DosingUnit = CommonMedicationValueCoded;
286
+
287
+ export type QuantityUnit = CommonMedicationValueCoded;
288
+
289
+ export type DurationUnit = CommonMedicationValueCoded;
290
+
291
+ interface CommonMedicationProps {
292
+ value: string;
293
+ default?: boolean;
294
+ }
295
+
296
+ export interface CommonMedicationValueCoded extends CommonMedicationProps {
297
+ valueCoded: string;
298
+ names?: string[];
299
+ }
300
+ export interface TestOrderBasketItem extends OrderBasketItem {
301
+ testType: {
302
+ label: string;
303
+ conceptUuid: string;
304
+ };
305
+ orderReason?: string;
306
+ specimenSource?: string;
307
+ }
308
+
309
+ export interface OrderBasketWindowProps {
310
+ encounterUuid: string;
311
+ }
312
+
313
+ export interface ExportedOrderBasketWindowProps {
314
+ encounterUuid: string;
315
+ drugOrderWorkspaceName: string;
316
+ labOrderWorkspaceName: string;
317
+ generalOrderWorkspaceName: string;
318
+ patient: fhir.Patient;
319
+ patientUuid: string;
320
+ visitContext: Visit;
321
+ mutateVisitContext: () => void;
322
+ }
@@ -0,0 +1,28 @@
1
+ import { restBaseUrl } from '@openmrs/esm-framework';
2
+ import { useCallback } from 'react';
3
+ import { useSWRConfig } from 'swr';
4
+
5
+ /**
6
+ * Returns a function which refreshes the patient orders cache. Uses SWR's mutate function.
7
+ * Refreshes patient orders for all kinds of orders.
8
+ *
9
+ * @param patientUuid The UUID of the patient to get an order mutate function for.
10
+ */
11
+ export function useMutatePatientOrders(patientUuid: string) {
12
+ const { mutate } = useSWRConfig();
13
+ const mutateOrders = useCallback(
14
+ () =>
15
+ mutate(
16
+ (key) => {
17
+ return typeof key === 'string' && key.startsWith(`${restBaseUrl}/order?patient=${patientUuid}`);
18
+ },
19
+ undefined,
20
+ { revalidate: true },
21
+ ),
22
+ [patientUuid, mutate],
23
+ );
24
+
25
+ return {
26
+ mutate: mutateOrders,
27
+ };
28
+ }
@@ -1,7 +1,7 @@
1
1
  import { useCallback, useMemo } from 'react';
2
2
  import useSWR, { useSWRConfig } from 'swr';
3
3
  import { type FetchResponse, openmrsFetch, restBaseUrl, translateFrom } from '@openmrs/esm-framework';
4
- import type { PatientOrderFetchResponse, PriorityOption } from './types';
4
+ import type { Order, PatientOrderFetchResponse, PriorityOption } from './types';
5
5
 
6
6
  export type Status = 'ACTIVE' | 'any';
7
7
  export const careSettingUuid = '6f0c9a92-6f24-11e3-af88-005056821db0';
@@ -10,7 +10,7 @@ const patientChartAppModuleName = '@openmrs/esm-patient-chart-app';
10
10
  export const drugCustomRepresentation =
11
11
  'custom:(uuid,dosingType,orderNumber,accessionNumber,' +
12
12
  'patient:ref,action,careSetting:ref,previousOrder:ref,dateActivated,scheduledDate,dateStopped,autoExpireDate,' +
13
- 'orderType:ref,encounter:ref,orderer:(uuid,display,person:(display)),orderReason,orderReasonNonCoded,orderType,urgency,instructions,' +
13
+ 'orderType:ref,encounter:(uuid,display,visit),orderer:(uuid,display,person:(display)),orderReason,orderReasonNonCoded,orderType,urgency,instructions,' +
14
14
  'commentToFulfiller,drug:(uuid,display,strength,dosageForm:(display,uuid),concept),dose,doseUnits:ref,' +
15
15
  'frequency:ref,asNeeded,asNeededCondition,quantity,quantityUnits:ref,numRefills,dosingInstructions,' +
16
16
  'duration,durationUnits:ref,route:ref,brandName,dispenseAsWritten)';
@@ -60,7 +60,7 @@ export function usePatientOrders(
60
60
  }
61
61
 
62
62
  export function getDrugOrderByUuid(orderUuid: string) {
63
- return openmrsFetch(`${restBaseUrl}/order/${orderUuid}?v=${drugCustomRepresentation}`);
63
+ return openmrsFetch<Order>(`${restBaseUrl}/order/${orderUuid}?v=${drugCustomRepresentation}`);
64
64
  }
65
65
 
66
66
  // See the Urgency enum in https://github.com/openmrs/openmrs-core/blob/492dcd35b85d48730bd19da48f6db146cc882c22/api/src/main/java/org/openmrs/Order.java
@@ -30,7 +30,7 @@ export function useOptimisticVisitMutations(patientUuid: string) {
30
30
  (visitUuid: string, updates: Partial<Visit>) => {
31
31
  // Update current visit SWR cache if it matches
32
32
  if (visitContext?.uuid === visitUuid) {
33
- mutateVisitContext();
33
+ mutateVisitContext?.();
34
34
  }
35
35
 
36
36
  // Update visit lists across all hooks using regex pattern matching
@@ -82,7 +82,7 @@ export function useOptimisticVisitMutations(patientUuid: string) {
82
82
 
83
83
  // If deleted visit was current, revalidate current visit to get new state
84
84
  if (visitContext?.uuid === visitUuid) {
85
- mutateVisitContext();
85
+ mutateVisitContext?.();
86
86
  }
87
87
  },
88
88
  [visitContext, mutateVisitContext, mutate, patientUuid],
package/src/workspaces.ts CHANGED
@@ -1,23 +1,29 @@
1
1
  import { useCallback } from 'react';
2
2
  import {
3
- type DefaultWorkspaceProps,
4
- launchWorkspace,
5
- navigateAndLaunchWorkspace,
3
+ launchWorkspace2,
4
+ navigate,
6
5
  showModal,
7
6
  useFeatureFlag,
8
7
  type Visit,
8
+ type Workspace2DefinitionProps,
9
9
  } from '@openmrs/esm-framework';
10
- import { launchStartVisitPrompt } from './launchStartVisitPrompt';
11
10
  import { usePatientChartStore } from './store/patient-chart-store';
12
11
  import { useSystemVisitSetting } from './useSystemVisitSetting';
13
12
 
14
- export interface DefaultPatientWorkspaceProps extends DefaultWorkspaceProps {
13
+ export interface PatientWorkspaceGroupProps {
15
14
  patient: fhir.Patient;
16
15
  patientUuid: string;
17
16
  visitContext: Visit;
18
17
  mutateVisitContext: () => void;
19
18
  }
20
19
 
20
+ export interface PatientChartWorkspaceActionButtonProps {
21
+ groupProps: PatientWorkspaceGroupProps;
22
+ }
23
+
24
+ export interface PatientWorkspace2DefinitionProps<WorkspaceProps extends Object, WindowProps extends Object>
25
+ extends Workspace2DefinitionProps<WorkspaceProps, WindowProps, PatientWorkspaceGroupProps> {}
26
+
21
27
  export function launchPatientChartWithWorkspaceOpen({
22
28
  patientUuid,
23
29
  workspaceName,
@@ -29,37 +35,55 @@ export function launchPatientChartWithWorkspaceOpen({
29
35
  dashboardName?: string;
30
36
  additionalProps?: object;
31
37
  }) {
32
- navigateAndLaunchWorkspace({
33
- targetUrl: '${openmrsSpaBase}/patient/' + `${patientUuid}/chart` + (dashboardName ? `/${dashboardName}` : ''),
34
- workspaceName: workspaceName,
35
- contextKey: `patient/${patientUuid}`,
36
- additionalProps,
37
- });
38
+ launchWorkspace2(workspaceName, additionalProps);
39
+ navigate({ to: '${openmrsSpaBase}/patient/' + `${patientUuid}/chart` + (dashboardName ? `/${dashboardName}` : '') });
38
40
  }
39
41
 
40
42
  export function useLaunchWorkspaceRequiringVisit<T extends object>(patientUuid: string, workspaceName: string) {
43
+ const startVisitIfNeeded = useStartVisitIfNeeded(patientUuid);
44
+ const launchPatientWorkspaceCb = useCallback(
45
+ (workspaceProps?: T, windowProps?: any, groupProps?: any) => {
46
+ startVisitIfNeeded().then((didStartVisit) => {
47
+ if (didStartVisit) {
48
+ launchWorkspace2(workspaceName, workspaceProps, windowProps);
49
+ }
50
+ });
51
+ },
52
+ [startVisitIfNeeded, workspaceName],
53
+ );
54
+ return launchPatientWorkspaceCb;
55
+ }
56
+
57
+ export function useStartVisitIfNeeded(patientUuid: string) {
41
58
  const { visitContext } = usePatientChartStore(patientUuid);
42
59
  const { systemVisitEnabled } = useSystemVisitSetting();
43
60
  const isRdeEnabled = useFeatureFlag('rde');
44
61
 
45
- const launchPatientWorkspaceCb = useCallback(
46
- (additionalProps?: T) => {
47
- if (!systemVisitEnabled || visitContext) {
48
- launchWorkspace(workspaceName, additionalProps);
49
- } else {
62
+ const startVisitIfNeeded = useCallback(async (): Promise<boolean> => {
63
+ if (!systemVisitEnabled || visitContext) {
64
+ return true;
65
+ } else {
66
+ return new Promise<boolean>((resolve) => {
50
67
  if (isRdeEnabled) {
51
68
  const dispose = showModal('visit-context-switcher', {
52
69
  patientUuid,
53
- closeModal: () => dispose(),
54
- onAfterVisitSelected: () => launchWorkspace(workspaceName, additionalProps),
70
+ closeModal: () => {
71
+ dispose();
72
+ resolve(false);
73
+ },
74
+ onAfterVisitSelected: () => {
75
+ resolve(true);
76
+ },
55
77
  size: 'sm',
56
78
  });
57
79
  } else {
58
- launchStartVisitPrompt();
80
+ const dispose = showModal('start-visit-dialog', {
81
+ closeModal: () => dispose(),
82
+ onVisitStarted: () => resolve(true),
83
+ });
59
84
  }
60
- }
61
- },
62
- [visitContext, systemVisitEnabled, workspaceName, isRdeEnabled, patientUuid],
63
- );
64
- return launchPatientWorkspaceCb;
85
+ });
86
+ }
87
+ }, [visitContext, systemVisitEnabled, isRdeEnabled, patientUuid]);
88
+ return startVisitIfNeeded;
65
89
  }
@@ -1,152 +0,0 @@
1
- import { launchWorkspace } from '@openmrs/esm-framework';
2
- import { type Form, type HtmlFormEntryForm } from './types';
3
- import { launchStartVisitPrompt } from './launchStartVisitPrompt';
4
-
5
- export const clinicalFormsWorkspace = 'clinical-forms-workspace';
6
- export const formEntryWorkspace = 'patient-form-entry-workspace';
7
- export const htmlFormEntryWorkspace = 'patient-html-form-entry-workspace';
8
-
9
- const formEngineResourceName = 'formEngine';
10
- const htmlformentryFormEngine = 'htmlformentry';
11
- const uiStyleResourceName = 'uiStyle';
12
- const uiStyleSimple = 'simple';
13
-
14
- export function launchFormEntryOrHtmlForms(
15
- htmlFormEntryForms: Array<HtmlFormEntryForm>,
16
- patientUuid: string,
17
- form: Form,
18
- visitUuid?: string,
19
- encounterUuid?: string,
20
- visitTypeUuid?: string,
21
- visitStartDatetime?: string,
22
- visitStopDatetime?: string,
23
- mutateForms?: () => void,
24
- clinicalFormsWorkspaceName = clinicalFormsWorkspace,
25
- formEntryWorkspaceName = formEntryWorkspace,
26
- htmlFormEntryWorkspaceName = htmlFormEntryWorkspace,
27
- ) {
28
- if (visitUuid) {
29
- const { uuid: formUuid, display, name } = form ?? {};
30
- const formName = display ?? name ?? '--';
31
-
32
- const htmlForm = toHtmlForm(form, htmlFormEntryForms);
33
- if (htmlForm) {
34
- launchHtmlFormEntry(patientUuid, formName, encounterUuid, visitUuid, htmlForm, htmlFormEntryWorkspaceName);
35
- } else {
36
- launchFormEntry(
37
- formUuid,
38
- patientUuid,
39
- encounterUuid,
40
- formName,
41
- visitUuid,
42
- visitTypeUuid,
43
- visitStartDatetime,
44
- visitStopDatetime,
45
- htmlForm,
46
- mutateForms,
47
- clinicalFormsWorkspaceName,
48
- formEntryWorkspaceName,
49
- );
50
- }
51
- } else {
52
- launchStartVisitPrompt();
53
- }
54
- }
55
-
56
- export function launchFormEntry(
57
- formUuid: string,
58
- patientUuid: string,
59
- encounterUuid?: string,
60
- formName?: string,
61
- visitUuid?: string,
62
- visitTypeUuid?: string,
63
- visitStartDatetime?: string,
64
- visitStopDatetime?: string,
65
- htmlForm?: HtmlFormEntryForm,
66
- mutateForm?: () => void,
67
- clinicalFormsWorkspaceName = clinicalFormsWorkspace,
68
- formEntryWorkspaceName = formEntryWorkspace,
69
- ) {
70
- launchWorkspace(formEntryWorkspaceName, {
71
- workspaceTitle: formName,
72
- clinicalFormsWorkspaceName,
73
- formEntryWorkspaceName,
74
- patientUuid,
75
- mutateForm,
76
- formInfo: {
77
- encounterUuid,
78
- formUuid,
79
- patientUuid,
80
- visitTypeUuid: visitTypeUuid,
81
- visitUuid: visitUuid,
82
- visitStartDatetime,
83
- visitStopDatetime,
84
- htmlForm,
85
- },
86
- });
87
- }
88
-
89
- export function launchHtmlFormEntry(
90
- patientUuid: string,
91
- formName: string,
92
- encounterUuid: string,
93
- visitUuid: string,
94
- htmlForm: HtmlFormEntryForm,
95
- workspaceName = htmlFormEntryWorkspace,
96
- ) {
97
- launchWorkspace(workspaceName, {
98
- workspaceTitle: formName,
99
- patientUuid,
100
- formInfo: {
101
- encounterUuid,
102
- visitUuid,
103
- htmlForm,
104
- },
105
- });
106
- }
107
-
108
- /**
109
- * For a given form , check if it is an HTML form. If it is, return the HtmlFormEntryForm object,
110
- * otherwise return null
111
- * @param form
112
- * @param htmlFormEntryForms A list of HTML forms configured in @esm-patient-forms-app's config
113
- *
114
- * @returns
115
- */
116
- function toHtmlForm(form: Form, htmlFormEntryForms: Array<HtmlFormEntryForm>): HtmlFormEntryForm {
117
- const isHtmlForm =
118
- htmlFormEntryForms?.some((hfeForm) => hfeForm.formUuid === form.uuid) ||
119
- form.resources?.some((resource) => {
120
- return resource.name === formEngineResourceName && resource.valueReference === htmlformentryFormEngine;
121
- });
122
- if (isHtmlForm) {
123
- const hfeForm = htmlFormEntryForms?.find((f) => f.formUuid === form.uuid);
124
- const simple = form.resources?.some((r) => r.name === uiStyleResourceName && r.valueReference === uiStyleSimple);
125
-
126
- return {
127
- formUuid: form.uuid,
128
- formName: hfeForm?.formName ?? form.display ?? form.name,
129
- formUiResource: hfeForm?.formUiResource,
130
- formUiPage: hfeForm?.formUiPage ?? (simple ? 'enterHtmlFormWithSimpleUi' : 'enterHtmlFormWithStandardUi'),
131
- formEditUiPage: hfeForm?.formEditUiPage ?? (simple ? 'editHtmlFormWithSimpleUi' : 'editHtmlFormWithStandardUi'),
132
- };
133
- } else {
134
- return null;
135
- }
136
- }
137
-
138
- /**
139
- * Given a list of forms and a list of HtmlFormEntryForm objects from configuration, return a List of HtmlFormEntryForm
140
- * returned forms either
141
- * a) have a form resource with a name of `formEngine` and a value of `htmlformentry, or
142
- * b) have an entry in the HtmlFormEntryForm array for a given form uuid
143
- * The HtmlFormEntryForm configuration provides a means to override the name and rendering mode of a given form
144
- * @param allForms
145
- * @param htmlFormEntryForms
146
- */
147
- export function mapFormsToHtmlFormEntryForms(
148
- allForms: Array<Form>,
149
- htmlFormEntryForms: Array<HtmlFormEntryForm>,
150
- ): Array<HtmlFormEntryForm> {
151
- return allForms?.map((form) => toHtmlForm(form, htmlFormEntryForms))?.filter((form) => form !== null);
152
- }