@openmrs/esm-patient-immunizations-app 11.3.1-pre.9452 → 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/.turbo/turbo-build.log +6 -6
- package/dist/3606.js +1 -1
- package/dist/3606.js.map +1 -1
- package/dist/3677.js +1 -1
- package/dist/3677.js.map +1 -1
- package/dist/7955.js +1 -0
- package/dist/7955.js.map +1 -0
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-patient-immunizations-app.js +1 -1
- package/dist/openmrs-esm-patient-immunizations-app.js.buildmanifest.json +35 -35
- package/dist/routes.json +1 -1
- package/package.json +2 -2
- package/src/immunizations/immunizations-detailed-summary.component.tsx +2 -2
- package/src/immunizations/immunizations-detailed-summary.test.tsx +24 -8
- package/src/immunizations/immunizations-form.test.tsx +14 -8
- package/src/immunizations/immunizations-form.workspace.tsx +157 -162
- package/src/immunizations/immunizations-overview.component.tsx +2 -2
- package/src/routes.json +12 -6
- package/dist/5858.js +0 -1
- package/dist/5858.js.map +0 -1
|
@@ -14,8 +14,9 @@ import {
|
|
|
14
14
|
useConfig,
|
|
15
15
|
useLayoutType,
|
|
16
16
|
useSession,
|
|
17
|
+
Workspace2,
|
|
17
18
|
} from '@openmrs/esm-framework';
|
|
18
|
-
import { type
|
|
19
|
+
import { type PatientWorkspace2DefinitionProps } from '@openmrs/esm-patient-common-lib';
|
|
19
20
|
import { DoseInput } from './components/dose-input.component';
|
|
20
21
|
import { immunizationFormSub } from './utils';
|
|
21
22
|
import { mapToFHIRImmunizationResource } from './immunization-mapper';
|
|
@@ -26,13 +27,9 @@ import { useImmunizations } from '../hooks/useImmunizations';
|
|
|
26
27
|
import { useImmunizationsConceptSet } from '../hooks/useImmunizationsConceptSet';
|
|
27
28
|
import styles from './immunizations-form.scss';
|
|
28
29
|
|
|
29
|
-
const ImmunizationsForm: React.FC<
|
|
30
|
-
patient,
|
|
31
|
-
patientUuid,
|
|
30
|
+
const ImmunizationsForm: React.FC<PatientWorkspace2DefinitionProps<{}, {}>> = ({
|
|
32
31
|
closeWorkspace,
|
|
33
|
-
|
|
34
|
-
promptBeforeClosing,
|
|
35
|
-
visitContext,
|
|
32
|
+
groupProps: { patientUuid, patient, visitContext },
|
|
36
33
|
}) => {
|
|
37
34
|
const config = useConfig<ImmunizationConfigObject>();
|
|
38
35
|
const currentUser = useSession();
|
|
@@ -45,7 +42,6 @@ const ImmunizationsForm: React.FC<DefaultPatientWorkspaceProps> = ({
|
|
|
45
42
|
immunizationObsUuid: string;
|
|
46
43
|
visitUuid?: string;
|
|
47
44
|
}>();
|
|
48
|
-
const now = useMemo(() => new Date(), []);
|
|
49
45
|
|
|
50
46
|
const immunizationFormSchema = useMemo(() => {
|
|
51
47
|
return z.object({
|
|
@@ -59,7 +55,7 @@ const ImmunizationsForm: React.FC<DefaultPatientWorkspaceProps> = ({
|
|
|
59
55
|
(date) => {
|
|
60
56
|
// Normalize both dates to start of day in local timezone
|
|
61
57
|
const inputDate = dayjs(date).startOf('day');
|
|
62
|
-
const today = dayjs(
|
|
58
|
+
const today = dayjs().startOf('day');
|
|
63
59
|
return inputDate.isSame(today) || inputDate.isBefore(today);
|
|
64
60
|
},
|
|
65
61
|
{
|
|
@@ -74,7 +70,7 @@ const ImmunizationsForm: React.FC<DefaultPatientWorkspaceProps> = ({
|
|
|
74
70
|
lotNumber: z.string().nullable().optional(),
|
|
75
71
|
manufacturer: z.string().nullable().optional(),
|
|
76
72
|
});
|
|
77
|
-
}, [patient.birthDate, t
|
|
73
|
+
}, [patient.birthDate, t]);
|
|
78
74
|
|
|
79
75
|
type ImmunizationFormInputData = z.infer<typeof immunizationFormSchema>;
|
|
80
76
|
const formProps = useForm<ImmunizationFormInputData>({
|
|
@@ -82,7 +78,7 @@ const ImmunizationsForm: React.FC<DefaultPatientWorkspaceProps> = ({
|
|
|
82
78
|
resolver: zodResolver(immunizationFormSchema),
|
|
83
79
|
defaultValues: {
|
|
84
80
|
vaccineUuid: '',
|
|
85
|
-
vaccinationDate: dayjs(
|
|
81
|
+
vaccinationDate: dayjs().startOf('day').toDate(),
|
|
86
82
|
doseNumber: 1,
|
|
87
83
|
nextDoseDate: null,
|
|
88
84
|
note: '',
|
|
@@ -100,17 +96,12 @@ const ImmunizationsForm: React.FC<DefaultPatientWorkspaceProps> = ({
|
|
|
100
96
|
watch,
|
|
101
97
|
} = formProps;
|
|
102
98
|
const vaccinationDate = watch('vaccinationDate');
|
|
103
|
-
|
|
104
|
-
useEffect(() => {
|
|
105
|
-
promptBeforeClosing(() => isDirty);
|
|
106
|
-
}, [isDirty, promptBeforeClosing]);
|
|
107
|
-
|
|
108
99
|
const vaccineUuid = watch('vaccineUuid');
|
|
109
100
|
|
|
110
101
|
useEffect(() => {
|
|
111
102
|
const sub = immunizationFormSub.subscribe((props) => {
|
|
112
103
|
if (props) {
|
|
113
|
-
const vaccinationDateOrNow = props.vaccinationDate ? parseDate(props.vaccinationDate) :
|
|
104
|
+
const vaccinationDateOrNow = props.vaccinationDate ? parseDate(props.vaccinationDate) : new Date();
|
|
114
105
|
reset({
|
|
115
106
|
vaccineUuid: props.vaccineUuid,
|
|
116
107
|
vaccinationDate: vaccinationDateOrNow,
|
|
@@ -129,7 +120,7 @@ const ImmunizationsForm: React.FC<DefaultPatientWorkspaceProps> = ({
|
|
|
129
120
|
sub.unsubscribe();
|
|
130
121
|
immunizationFormSub.next(null);
|
|
131
122
|
};
|
|
132
|
-
}, [reset
|
|
123
|
+
}, [reset]);
|
|
133
124
|
|
|
134
125
|
const onSubmit = useCallback(
|
|
135
126
|
async (data: ImmunizationFormInputData) => {
|
|
@@ -170,7 +161,7 @@ const ImmunizationsForm: React.FC<DefaultPatientWorkspaceProps> = ({
|
|
|
170
161
|
immunizationToEditMeta?.immunizationObsUuid,
|
|
171
162
|
abortController,
|
|
172
163
|
);
|
|
173
|
-
|
|
164
|
+
closeWorkspace({ discardUnsavedChanges: true });
|
|
174
165
|
mutate();
|
|
175
166
|
showSnackbar({
|
|
176
167
|
kind: 'success',
|
|
@@ -193,157 +184,161 @@ const ImmunizationsForm: React.FC<DefaultPatientWorkspaceProps> = ({
|
|
|
193
184
|
visitContext?.uuid,
|
|
194
185
|
immunizationToEditMeta,
|
|
195
186
|
immunizationsConceptSet,
|
|
196
|
-
|
|
187
|
+
closeWorkspace,
|
|
197
188
|
t,
|
|
198
189
|
mutate,
|
|
199
190
|
],
|
|
200
191
|
);
|
|
201
192
|
return (
|
|
202
|
-
<
|
|
203
|
-
<
|
|
204
|
-
<
|
|
205
|
-
<
|
|
206
|
-
<Controller
|
|
207
|
-
name="vaccinationDate"
|
|
208
|
-
control={control}
|
|
209
|
-
render={({ field, fieldState }) => (
|
|
210
|
-
<OpenmrsDatePicker
|
|
211
|
-
{...field}
|
|
212
|
-
className={styles.datePicker}
|
|
213
|
-
id="vaccinationDate"
|
|
214
|
-
invalid={Boolean(fieldState?.error?.message)}
|
|
215
|
-
invalidText={fieldState?.error?.message}
|
|
216
|
-
labelText={t('vaccinationDate', 'Vaccination date')}
|
|
217
|
-
maxDate={now}
|
|
218
|
-
/>
|
|
219
|
-
)}
|
|
220
|
-
/>
|
|
221
|
-
</ResponsiveWrapper>
|
|
222
|
-
<ResponsiveWrapper>
|
|
223
|
-
<Controller
|
|
224
|
-
name="vaccineUuid"
|
|
225
|
-
control={control}
|
|
226
|
-
render={({ field: { onChange, value } }) => (
|
|
227
|
-
<Dropdown
|
|
228
|
-
disabled={!!immunizationToEditMeta}
|
|
229
|
-
id="immunization"
|
|
230
|
-
invalid={!!errors?.vaccineUuid}
|
|
231
|
-
invalidText={errors?.vaccineUuid?.message}
|
|
232
|
-
itemToString={(item) =>
|
|
233
|
-
immunizationsConceptSet?.answers.find((candidate) => candidate.uuid == item)?.display
|
|
234
|
-
}
|
|
235
|
-
items={immunizationsConceptSet?.answers?.map((item) => item.uuid) || []}
|
|
236
|
-
label={t('selectImmunization', 'Select immunization')}
|
|
237
|
-
onChange={(val) => onChange(val.selectedItem)}
|
|
238
|
-
selectedItem={value}
|
|
239
|
-
titleText={t('immunization', 'Immunization')}
|
|
240
|
-
/>
|
|
241
|
-
)}
|
|
242
|
-
/>
|
|
243
|
-
</ResponsiveWrapper>
|
|
244
|
-
{vaccineUuid && (
|
|
193
|
+
<Workspace2 title={t('immunizationWorkspaceTitle', 'Immunization')} hasUnsavedChanges={isDirty}>
|
|
194
|
+
<FormProvider {...formProps}>
|
|
195
|
+
<Form className={styles.form} onSubmit={handleSubmit(onSubmit)}>
|
|
196
|
+
<Stack gap={5} className={styles.container}>
|
|
245
197
|
<ResponsiveWrapper>
|
|
246
|
-
<
|
|
198
|
+
<Controller
|
|
199
|
+
name="vaccinationDate"
|
|
200
|
+
control={control}
|
|
201
|
+
render={({ field, fieldState }) => (
|
|
202
|
+
<OpenmrsDatePicker
|
|
203
|
+
{...field}
|
|
204
|
+
className={styles.datePicker}
|
|
205
|
+
id="vaccinationDate"
|
|
206
|
+
invalid={Boolean(fieldState?.error?.message)}
|
|
207
|
+
invalidText={fieldState?.error?.message}
|
|
208
|
+
labelText={t('vaccinationDate', 'Vaccination date')}
|
|
209
|
+
maxDate={new Date()}
|
|
210
|
+
/>
|
|
211
|
+
)}
|
|
212
|
+
/>
|
|
247
213
|
</ResponsiveWrapper>
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
type="text"
|
|
275
|
-
value={value}
|
|
276
|
-
/>
|
|
277
|
-
)}
|
|
278
|
-
/>
|
|
279
|
-
</ResponsiveWrapper>
|
|
280
|
-
<ResponsiveWrapper>
|
|
281
|
-
<Controller
|
|
282
|
-
name="expirationDate"
|
|
283
|
-
control={control}
|
|
284
|
-
render={({ field, fieldState }) => (
|
|
285
|
-
<OpenmrsDatePicker
|
|
286
|
-
{...field}
|
|
287
|
-
className={styles.datePicker}
|
|
288
|
-
id="vaccinationExpiration"
|
|
289
|
-
invalid={Boolean(fieldState?.error?.message)}
|
|
290
|
-
invalidText={fieldState?.error?.message}
|
|
291
|
-
labelText={t('expirationDate', 'Expiration date')}
|
|
292
|
-
minDate={vaccinationDate}
|
|
293
|
-
/>
|
|
294
|
-
)}
|
|
295
|
-
/>
|
|
296
|
-
</ResponsiveWrapper>
|
|
297
|
-
<ResponsiveWrapper>
|
|
298
|
-
<Controller
|
|
299
|
-
name="note"
|
|
300
|
-
control={control}
|
|
301
|
-
render={({ field: { onChange, value } }) => (
|
|
302
|
-
<TextArea
|
|
303
|
-
enableCounter
|
|
304
|
-
id="note"
|
|
305
|
-
invalidText={errors?.note?.message}
|
|
306
|
-
labelText={t('note', 'Note')}
|
|
307
|
-
maxCount={255}
|
|
308
|
-
onChange={(evt) => onChange(evt.target.value)}
|
|
309
|
-
placeholder={t('immunizationNotePlaceholder', 'For example: mild redness at injection site')}
|
|
310
|
-
value={value}
|
|
311
|
-
/>
|
|
312
|
-
)}
|
|
313
|
-
/>
|
|
314
|
-
</ResponsiveWrapper>
|
|
315
|
-
<ResponsiveWrapper>
|
|
316
|
-
<Controller
|
|
317
|
-
name="nextDoseDate"
|
|
318
|
-
control={control}
|
|
319
|
-
render={({ field, fieldState }) => (
|
|
320
|
-
<OpenmrsDatePicker
|
|
321
|
-
{...field}
|
|
322
|
-
className={styles.datePicker}
|
|
323
|
-
id="nextDoseDate"
|
|
324
|
-
invalid={Boolean(fieldState?.error?.message)}
|
|
325
|
-
invalidText={fieldState?.error?.message}
|
|
326
|
-
labelText={t('nextDoseDate', 'Next dose date')}
|
|
327
|
-
minDate={vaccinationDate}
|
|
328
|
-
/>
|
|
329
|
-
)}
|
|
330
|
-
/>
|
|
331
|
-
</ResponsiveWrapper>
|
|
332
|
-
</Stack>
|
|
333
|
-
<ButtonSet className={isTablet ? styles.tablet : styles.desktop}>
|
|
334
|
-
<Button className={styles.button} kind="secondary" onClick={() => closeWorkspace()}>
|
|
335
|
-
{getCoreTranslation('cancel')}
|
|
336
|
-
</Button>
|
|
337
|
-
<Button className={styles.button} kind="primary" disabled={isSubmitting} type="submit">
|
|
338
|
-
{isSubmitting ? (
|
|
339
|
-
<InlineLoading className={styles.spinner} description={t('saving', 'Saving') + '...'} />
|
|
340
|
-
) : (
|
|
341
|
-
<span>{getCoreTranslation('save')}</span>
|
|
214
|
+
<ResponsiveWrapper>
|
|
215
|
+
<Controller
|
|
216
|
+
name="vaccineUuid"
|
|
217
|
+
control={control}
|
|
218
|
+
render={({ field: { onChange, value } }) => (
|
|
219
|
+
<Dropdown
|
|
220
|
+
disabled={!!immunizationToEditMeta}
|
|
221
|
+
id="immunization"
|
|
222
|
+
invalid={!!errors?.vaccineUuid}
|
|
223
|
+
invalidText={errors?.vaccineUuid?.message}
|
|
224
|
+
itemToString={(item) =>
|
|
225
|
+
immunizationsConceptSet?.answers.find((candidate) => candidate.uuid == item)?.display
|
|
226
|
+
}
|
|
227
|
+
items={immunizationsConceptSet?.answers?.map((item) => item.uuid) || []}
|
|
228
|
+
label={t('selectImmunization', 'Select immunization')}
|
|
229
|
+
onChange={(val) => onChange(val.selectedItem)}
|
|
230
|
+
selectedItem={value}
|
|
231
|
+
titleText={t('immunization', 'Immunization')}
|
|
232
|
+
/>
|
|
233
|
+
)}
|
|
234
|
+
/>
|
|
235
|
+
</ResponsiveWrapper>
|
|
236
|
+
{vaccineUuid && (
|
|
237
|
+
<ResponsiveWrapper>
|
|
238
|
+
<DoseInput vaccine={vaccineUuid} sequences={config.sequenceDefinitions} control={control} />
|
|
239
|
+
</ResponsiveWrapper>
|
|
342
240
|
)}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
241
|
+
<div className={styles.vaccineBatchHeading}>
|
|
242
|
+
{t('vaccineBatchInformation', 'Vaccine Batch Information')}
|
|
243
|
+
</div>
|
|
244
|
+
<ResponsiveWrapper>
|
|
245
|
+
<Controller
|
|
246
|
+
name="manufacturer"
|
|
247
|
+
control={control}
|
|
248
|
+
render={({ field: { onChange, value } }) => (
|
|
249
|
+
<TextInput
|
|
250
|
+
id="manufacturer"
|
|
251
|
+
labelText={t('manufacturer', 'Manufacturer')}
|
|
252
|
+
onChange={(evt) => onChange(evt.target.value)}
|
|
253
|
+
type="text"
|
|
254
|
+
value={value}
|
|
255
|
+
/>
|
|
256
|
+
)}
|
|
257
|
+
/>
|
|
258
|
+
</ResponsiveWrapper>
|
|
259
|
+
<ResponsiveWrapper>
|
|
260
|
+
<Controller
|
|
261
|
+
name="lotNumber"
|
|
262
|
+
control={control}
|
|
263
|
+
render={({ field: { onChange, value } }) => (
|
|
264
|
+
<TextInput
|
|
265
|
+
id="lotNumber"
|
|
266
|
+
labelText={t('lotNumber', 'Lot Number')}
|
|
267
|
+
onChange={(evt) => onChange(evt.target.value)}
|
|
268
|
+
type="text"
|
|
269
|
+
value={value}
|
|
270
|
+
/>
|
|
271
|
+
)}
|
|
272
|
+
/>
|
|
273
|
+
</ResponsiveWrapper>
|
|
274
|
+
<ResponsiveWrapper>
|
|
275
|
+
<Controller
|
|
276
|
+
name="expirationDate"
|
|
277
|
+
control={control}
|
|
278
|
+
render={({ field, fieldState }) => (
|
|
279
|
+
<OpenmrsDatePicker
|
|
280
|
+
{...field}
|
|
281
|
+
className={styles.datePicker}
|
|
282
|
+
id="vaccinationExpiration"
|
|
283
|
+
invalid={Boolean(fieldState?.error?.message)}
|
|
284
|
+
invalidText={fieldState?.error?.message}
|
|
285
|
+
labelText={t('expirationDate', 'Expiration date')}
|
|
286
|
+
minDate={vaccinationDate}
|
|
287
|
+
/>
|
|
288
|
+
)}
|
|
289
|
+
/>
|
|
290
|
+
</ResponsiveWrapper>
|
|
291
|
+
<ResponsiveWrapper>
|
|
292
|
+
<Controller
|
|
293
|
+
name="note"
|
|
294
|
+
control={control}
|
|
295
|
+
render={({ field: { onChange, value } }) => (
|
|
296
|
+
<TextArea
|
|
297
|
+
enableCounter
|
|
298
|
+
id="note"
|
|
299
|
+
invalidText={errors?.note?.message}
|
|
300
|
+
labelText={t('note', 'Note')}
|
|
301
|
+
maxCount={255}
|
|
302
|
+
onChange={(evt) => onChange(evt.target.value)}
|
|
303
|
+
placeholder={t('immunizationNotePlaceholder', 'For example: mild redness at injection site')}
|
|
304
|
+
value={value}
|
|
305
|
+
/>
|
|
306
|
+
)}
|
|
307
|
+
/>
|
|
308
|
+
</ResponsiveWrapper>
|
|
309
|
+
<ResponsiveWrapper>
|
|
310
|
+
<Controller
|
|
311
|
+
name="nextDoseDate"
|
|
312
|
+
control={control}
|
|
313
|
+
render={({ field, fieldState }) => (
|
|
314
|
+
<OpenmrsDatePicker
|
|
315
|
+
{...field}
|
|
316
|
+
className={styles.datePicker}
|
|
317
|
+
id="nextDoseDate"
|
|
318
|
+
invalid={Boolean(fieldState?.error?.message)}
|
|
319
|
+
invalidText={fieldState?.error?.message}
|
|
320
|
+
labelText={t('nextDoseDate', 'Next dose date')}
|
|
321
|
+
minDate={vaccinationDate}
|
|
322
|
+
/>
|
|
323
|
+
)}
|
|
324
|
+
/>
|
|
325
|
+
</ResponsiveWrapper>
|
|
326
|
+
</Stack>
|
|
327
|
+
<ButtonSet className={isTablet ? styles.tablet : styles.desktop}>
|
|
328
|
+
<Button className={styles.button} kind="secondary" onClick={() => closeWorkspace()}>
|
|
329
|
+
{getCoreTranslation('cancel')}
|
|
330
|
+
</Button>
|
|
331
|
+
<Button className={styles.button} kind="primary" disabled={isSubmitting} type="submit">
|
|
332
|
+
{isSubmitting ? (
|
|
333
|
+
<InlineLoading className={styles.spinner} description={t('saving', 'Saving') + '...'} />
|
|
334
|
+
) : (
|
|
335
|
+
<span>{getCoreTranslation('save')}</span>
|
|
336
|
+
)}
|
|
337
|
+
</Button>
|
|
338
|
+
</ButtonSet>
|
|
339
|
+
</Form>
|
|
340
|
+
</FormProvider>
|
|
341
|
+
</Workspace2>
|
|
347
342
|
);
|
|
348
343
|
};
|
|
349
344
|
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
TableHeader,
|
|
15
15
|
TableRow,
|
|
16
16
|
} from '@carbon/react';
|
|
17
|
-
import { AddIcon, formatDate,
|
|
17
|
+
import { AddIcon, formatDate, launchWorkspace2, parseDate, usePagination } from '@openmrs/esm-framework';
|
|
18
18
|
import { CardHeader, EmptyState, ErrorState, PatientChartPagination } from '@openmrs/esm-patient-common-lib';
|
|
19
19
|
import { useImmunizations } from '../hooks/useImmunizations';
|
|
20
20
|
import styles from './immunizations-overview.scss';
|
|
@@ -36,7 +36,7 @@ const ImmunizationsOverview: React.FC<ImmunizationsOverviewProps> = ({ patient,
|
|
|
36
36
|
const { data: immunizations, error, isLoading, isValidating } = useImmunizations(patientUuid);
|
|
37
37
|
const { results: paginatedImmunizations, goTo, currentPage } = usePagination(immunizations ?? [], immunizationsCount);
|
|
38
38
|
|
|
39
|
-
const launchImmunizationsForm = React.useCallback(() =>
|
|
39
|
+
const launchImmunizationsForm = React.useCallback(() => launchWorkspace2('immunization-form-workspace'), []);
|
|
40
40
|
|
|
41
41
|
const tableHeaders = [
|
|
42
42
|
{
|
package/src/routes.json
CHANGED
|
@@ -37,17 +37,23 @@
|
|
|
37
37
|
}
|
|
38
38
|
],
|
|
39
39
|
"pages": [],
|
|
40
|
-
"
|
|
40
|
+
"modals": [
|
|
41
|
+
{
|
|
42
|
+
"name": "immunization-delete-confirmation-modal",
|
|
43
|
+
"component": "deleteImmunizationConfirmationModal"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"workspaces2": [
|
|
41
47
|
{
|
|
42
48
|
"name": "immunization-form-workspace",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
49
|
+
"component": "immunizationFormWorkspace",
|
|
50
|
+
"window": "immunization-form-window"
|
|
45
51
|
}
|
|
46
52
|
],
|
|
47
|
-
"
|
|
53
|
+
"workspaceWindows2": [
|
|
48
54
|
{
|
|
49
|
-
"name": "immunization-
|
|
50
|
-
"
|
|
55
|
+
"name": "immunization-form-window",
|
|
56
|
+
"group": "patient-chart"
|
|
51
57
|
}
|
|
52
58
|
]
|
|
53
59
|
}
|