@cc-openmrs/cc-esm-active-prescriptions 1.0.67 → 1.0.68

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.
@@ -46,6 +46,30 @@
46
46
  "hash": "6ab7a8d81edef660",
47
47
  "childrenByOrder": {}
48
48
  },
49
+ {
50
+ "rendered": true,
51
+ "initial": false,
52
+ "entry": false,
53
+ "recorded": false,
54
+ "size": 77163,
55
+ "sizes": {
56
+ "javascript": 77163
57
+ },
58
+ "names": [],
59
+ "idHints": [],
60
+ "runtime": [
61
+ "@cc-openmrs/cc-esm-active-prescriptions",
62
+ "main"
63
+ ],
64
+ "files": [
65
+ "63.js"
66
+ ],
67
+ "auxiliaryFiles": [
68
+ "63.js.map"
69
+ ],
70
+ "hash": "10c6f8f9ff72f6b5",
71
+ "childrenByOrder": {}
72
+ },
49
73
  {
50
74
  "rendered": false,
51
75
  "initial": false,
@@ -428,6 +452,33 @@
428
452
  "hash": "6eb7a892027c3df2",
429
453
  "childrenByOrder": {}
430
454
  },
455
+ {
456
+ "rendered": true,
457
+ "initial": false,
458
+ "entry": false,
459
+ "recorded": false,
460
+ "reason": "split chunk (cache group: defaultVendors)",
461
+ "size": 1238873,
462
+ "sizes": {
463
+ "javascript": 1238873
464
+ },
465
+ "names": [],
466
+ "idHints": [
467
+ "vendors"
468
+ ],
469
+ "runtime": [
470
+ "@cc-openmrs/cc-esm-active-prescriptions",
471
+ "main"
472
+ ],
473
+ "files": [
474
+ "464.js"
475
+ ],
476
+ "auxiliaryFiles": [
477
+ "464.js.map"
478
+ ],
479
+ "hash": "f2a75dc7b86dc2b0",
480
+ "childrenByOrder": {}
481
+ },
431
482
  {
432
483
  "rendered": false,
433
484
  "initial": false,
@@ -497,7 +548,7 @@
497
548
  "auxiliaryFiles": [
498
549
  "499.js.map"
499
550
  ],
500
- "hash": "61c5d69ab6c9d9e4",
551
+ "hash": "e717bdccf6384c47",
501
552
  "childrenByOrder": {}
502
553
  },
503
554
  {
@@ -616,33 +667,6 @@
616
667
  "hash": "776b6a0cc9aef773",
617
668
  "childrenByOrder": {}
618
669
  },
619
- {
620
- "rendered": true,
621
- "initial": false,
622
- "entry": false,
623
- "recorded": false,
624
- "reason": "split chunk (cache group: defaultVendors)",
625
- "size": 1217086,
626
- "sizes": {
627
- "javascript": 1217086
628
- },
629
- "names": [],
630
- "idHints": [
631
- "vendors"
632
- ],
633
- "runtime": [
634
- "@cc-openmrs/cc-esm-active-prescriptions",
635
- "main"
636
- ],
637
- "files": [
638
- "765.js"
639
- ],
640
- "auxiliaryFiles": [
641
- "765.js.map"
642
- ],
643
- "hash": "9d2c34e50fd4d0e1",
644
- "childrenByOrder": {}
645
- },
646
670
  {
647
671
  "rendered": true,
648
672
  "initial": false,
@@ -695,31 +719,7 @@
695
719
  "auxiliaryFiles": [
696
720
  "main.js.map"
697
721
  ],
698
- "hash": "f48f0fc69c5b0259",
699
- "childrenByOrder": {}
700
- },
701
- {
702
- "rendered": true,
703
- "initial": false,
704
- "entry": false,
705
- "recorded": false,
706
- "size": 55412,
707
- "sizes": {
708
- "javascript": 55412
709
- },
710
- "names": [],
711
- "idHints": [],
712
- "runtime": [
713
- "@cc-openmrs/cc-esm-active-prescriptions",
714
- "main"
715
- ],
716
- "files": [
717
- "845.js"
718
- ],
719
- "auxiliaryFiles": [
720
- "845.js.map"
721
- ],
722
- "hash": "be25ff4f6d0d5b74",
722
+ "hash": "e11b484efaa3b75d",
723
723
  "childrenByOrder": {}
724
724
  },
725
725
  {
package/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":">=2.2.0"},"extensions":[{"name":"Red box","component":"redBox","slot":"Boxes"},{"name":"Blue box","component":"blueBox","slot":"Boxes"},{"name":"Brand box","component":"blueBox","slot":"Boxes"}],"workspaces2":[{"name":"active-prescriptions-workspace","component":"root","window":"active-prescriptions-workspace"}],"workspaceWindows2":[{"name":"active-prescriptions-workspace","group":"patient-chart","icon":"prescriptionsActionButton","width":"wider","order":4}],"version":"1.0.57"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":">=2.2.0"},"extensions":[{"name":"Red box","component":"redBox","slot":"Boxes"},{"name":"Blue box","component":"blueBox","slot":"Boxes"},{"name":"Brand box","component":"blueBox","slot":"Boxes"}],"workspaces2":[{"name":"active-prescriptions-workspace","component":"root","window":"active-prescriptions-workspace"}],"workspaceWindows2":[{"name":"active-prescriptions-workspace","group":"patient-chart","icon":"prescriptionsActionButton","width":"wider","order":4}],"version":"1.0.68"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cc-openmrs/cc-esm-active-prescriptions",
3
- "version": "1.0.67",
3
+ "version": "1.0.68",
4
4
  "license": "MPL-2.0",
5
5
  "description": "An OpenMRS frontend module for managing patient lists in the Patient Chart",
6
6
  "browser": "dist/openmrs-esm-patient-lists-app.js",
@@ -0,0 +1,186 @@
1
+ import React, { useState } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { Button, Checkbox, ComboBox, TextInput } from '@carbon/react';
4
+ import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
5
+ import useSWR from 'swr';
6
+
7
+ export interface PrescriptionDrugItem {
8
+ drug: { uuid: string; name: string; display: string };
9
+ dosage: string;
10
+ unit: string;
11
+ route: string;
12
+ frequency: string;
13
+ patientInstructions?: string;
14
+ asNeeded?: boolean;
15
+ asNeededCondition?: string;
16
+ indication?: string;
17
+ }
18
+
19
+ export interface AddDrugPrescriptionProps {
20
+ initialData?: PrescriptionDrugItem;
21
+ onSave: (item: PrescriptionDrugItem) => void;
22
+ onCancel: () => void;
23
+ }
24
+
25
+ const UNITS = [{ value: 'mg' }, { value: 'ml' }, { value: 'g' }, { value: 'mcg' }, { value: 'comprimido(s)' }];
26
+
27
+ const ROUTES = [
28
+ { value: 'Oral' },
29
+ { value: 'Intravenoso (IV)' },
30
+ { value: 'Intramuscular (IM)' },
31
+ { value: 'Subcutâneo (SC)' },
32
+ { value: 'Tópico' },
33
+ { value: 'Inalatório' },
34
+ { value: 'Sublingual' },
35
+ ];
36
+
37
+ const FREQUENCIES = [
38
+ { value: '1x ao dia' },
39
+ { value: '2x ao dia' },
40
+ { value: '3x ao dia' },
41
+ { value: '4x ao dia' },
42
+ { value: '6/6h' },
43
+ { value: '8/8h' },
44
+ { value: '12/12h' },
45
+ { value: 'Se necessário' },
46
+ ];
47
+
48
+ function useDrugSearch(query: string) {
49
+ const url =
50
+ query?.length >= 3
51
+ ? `${restBaseUrl}/drug?q=${encodeURIComponent(query)}&v=custom:(uuid,name,display)&limit=10`
52
+ : null;
53
+ const { data, isValidating } = useSWR<any>(url, openmrsFetch);
54
+ return {
55
+ drugs: (data?.data?.results ?? []) as Array<{ uuid: string; name: string; display: string }>,
56
+ isLoading: isValidating,
57
+ };
58
+ }
59
+
60
+ const AddDrugPrescription: React.FC<AddDrugPrescriptionProps> = ({ initialData, onSave, onCancel }) => {
61
+ const { t } = useTranslation();
62
+
63
+ const [drugQuery, setDrugQuery] = useState(initialData?.drug?.name ?? '');
64
+ const [selectedDrug, setSelectedDrug] = useState<PrescriptionDrugItem['drug'] | null>(initialData?.drug ?? null);
65
+ const [dosage, setDosage] = useState(initialData?.dosage ?? '');
66
+ const [unit, setUnit] = useState(initialData?.unit ?? '');
67
+ const [route, setRoute] = useState(initialData?.route ?? '');
68
+ const [frequency, setFrequency] = useState(initialData?.frequency ?? '');
69
+ const [patientInstructions, setPatientInstructions] = useState(initialData?.patientInstructions ?? '');
70
+ const [asNeeded, setAsNeeded] = useState(initialData?.asNeeded ?? false);
71
+ const [asNeededCondition, setAsNeededCondition] = useState(initialData?.asNeededCondition ?? '');
72
+ const [indication, setIndication] = useState(initialData?.indication ?? '');
73
+
74
+ const { drugs, isLoading } = useDrugSearch(drugQuery);
75
+
76
+ const handleSubmit = (e: React.FormEvent) => {
77
+ e.preventDefault();
78
+ if (!selectedDrug || !dosage || !unit || !frequency) return;
79
+ onSave({
80
+ drug: selectedDrug,
81
+ dosage,
82
+ unit,
83
+ route,
84
+ frequency,
85
+ patientInstructions: patientInstructions || undefined,
86
+ asNeeded,
87
+ asNeededCondition: asNeeded ? asNeededCondition || undefined : undefined,
88
+ indication: indication || undefined,
89
+ });
90
+ };
91
+
92
+ return (
93
+ <form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
94
+ <ComboBox
95
+ id="drug-search"
96
+ titleText={t('drugName', 'Medicamento')}
97
+ placeholder={t('drugSearchPlaceholder', 'Digite para buscar (mín. 3 letras)...')}
98
+ items={drugs.map((d) => ({ id: d.uuid, label: d.display || d.name, ...d }))}
99
+ itemToString={(item: any) => item?.label ?? ''}
100
+ selectedItem={selectedDrug ? { id: selectedDrug.uuid, label: selectedDrug.display } : null}
101
+ onInputChange={(v: string) => {
102
+ setDrugQuery(v);
103
+ if (!v) setSelectedDrug(null);
104
+ }}
105
+ onChange={({ selectedItem }: any) => {
106
+ if (selectedItem) {
107
+ setSelectedDrug({
108
+ uuid: selectedItem.uuid,
109
+ name: selectedItem.name,
110
+ display: selectedItem.display ?? selectedItem.name,
111
+ });
112
+ }
113
+ }}
114
+ disabled={isLoading}
115
+ helperText={isLoading ? t('searching', 'Buscando...') : undefined}
116
+ />
117
+ <TextInput
118
+ id="dosage"
119
+ labelText={t('dosage', 'Dose')}
120
+ value={dosage}
121
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => setDosage(e.target.value)}
122
+ required
123
+ />
124
+ <ComboBox
125
+ id="unit"
126
+ titleText={t('unit', 'Unidade')}
127
+ items={UNITS}
128
+ itemToString={(item: any) => item?.value ?? ''}
129
+ selectedItem={UNITS.find((u) => u.value === unit) ?? null}
130
+ onChange={({ selectedItem }: any) => setUnit(selectedItem?.value ?? '')}
131
+ />
132
+ <ComboBox
133
+ id="route"
134
+ titleText={t('route', 'Via de administração')}
135
+ items={ROUTES}
136
+ itemToString={(item: any) => item?.value ?? ''}
137
+ selectedItem={ROUTES.find((r) => r.value === route) ?? null}
138
+ onChange={({ selectedItem }: any) => setRoute(selectedItem?.value ?? '')}
139
+ />
140
+ <ComboBox
141
+ id="frequency"
142
+ titleText={t('frequency', 'Frequência')}
143
+ items={FREQUENCIES}
144
+ itemToString={(item: any) => item?.value ?? ''}
145
+ selectedItem={FREQUENCIES.find((f) => f.value === frequency) ?? null}
146
+ onChange={({ selectedItem }: any) => setFrequency(selectedItem?.value ?? '')}
147
+ />
148
+ <TextInput
149
+ id="patient-instructions"
150
+ labelText={t('patientInstructions', 'Instruções ao paciente')}
151
+ value={patientInstructions}
152
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => setPatientInstructions(e.target.value)}
153
+ />
154
+ <Checkbox
155
+ id="as-needed"
156
+ labelText={t('asNeeded', 'Tomar se necessário (P.R.N.)')}
157
+ checked={asNeeded}
158
+ onChange={(_: any, { checked }: any) => setAsNeeded(checked)}
159
+ />
160
+ {asNeeded && (
161
+ <TextInput
162
+ id="as-needed-condition"
163
+ labelText={t('asNeededCondition', 'Motivo P.R.N.')}
164
+ value={asNeededCondition}
165
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => setAsNeededCondition(e.target.value)}
166
+ />
167
+ )}
168
+ <TextInput
169
+ id="indication"
170
+ labelText={t('indication', 'Indicação')}
171
+ value={indication}
172
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => setIndication(e.target.value)}
173
+ />
174
+ <div style={{ display: 'flex', gap: '0.5rem', marginTop: '0.5rem' }}>
175
+ <Button type="submit" kind="primary" disabled={!selectedDrug || !dosage || !unit || !frequency}>
176
+ {t('saveMedication', 'Salvar medicamento')}
177
+ </Button>
178
+ <Button type="button" kind="secondary" onClick={onCancel}>
179
+ {t('cancel', 'Cancelar')}
180
+ </Button>
181
+ </div>
182
+ </form>
183
+ );
184
+ };
185
+
186
+ export default AddDrugPrescription;
@@ -0,0 +1 @@
1
+ @import "../add-drug-order/add-drug-order.scss";
@@ -0,0 +1,2 @@
1
+ export { default } from './add-drug-prescription.component';
2
+ export type { PrescriptionDrugItem, AddDrugPrescriptionProps } from './add-drug-prescription.component';