@bahmni/reports-app 0.0.1-dev.422

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/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # @bahmni/reports
2
+
3
+ Reports application for Bahmni.
4
+
5
+ This library was generated with [Nx](https://nx.dev).
6
+
7
+ ## Running unit tests
8
+
9
+ Run `nx test @bahmni/reports` to execute the unit tests via [Jest](https://jestjs.io/).
package/dist/App.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export declare function App(): import("react/jsx-runtime").JSX.Element;
2
+ export default App;
3
+ //# sourceMappingURL=App.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"AAoBA,wBAAgB,GAAG,4CA4ClB;AAED,eAAe,GAAG,CAAC"}
@@ -0,0 +1,227 @@
1
+ import { jsx as r, jsxs as p, Fragment as Y } from "react/jsx-runtime";
2
+ import { v as x, u as G, z as W, E as J, q as X, w as Z, Y as ee, p as te } from "./index-BMa5QlCF.js";
3
+ import { useQuery as ae } from "@tanstack/react-query";
4
+ import { useState as l, useCallback as h, useEffect as I, useMemo as _ } from "react";
5
+ const ne = "DocumentsTable-module_documentsTableBody__6iR3w", oe = "DocumentsTable-module_viewAttachmentsLink__aQ1on", re = "DocumentsTable-module_documentViewerContainer__F5m8D", de = "DocumentsTable-module_attachmentItem__17KA7", se = "DocumentsTable-module_attachmentCounter__WFiI3", me = "DocumentsTable-module_attachmentError__RI4U2", ce = "DocumentsTable-module_documentIframe__ptq5I", le = "DocumentsTable-module_documentImage__KQVgS", d = {
6
+ documentsTableBody: ne,
7
+ viewAttachmentsLink: oe,
8
+ documentViewerContainer: re,
9
+ attachmentItem: de,
10
+ attachmentCounter: se,
11
+ attachmentError: me,
12
+ documentIframe: ce,
13
+ documentImage: le
14
+ }, ue = {
15
+ documentIdentifier: "DOCUMENTS_DOCUMENT_IDENTIFIER",
16
+ documentType: "DOCUMENTS_TYPE",
17
+ uploadedOn: "DOCUMENTS_UPLOADED_ON",
18
+ uploadedBy: "DOCUMENTS_UPLOADED_BY",
19
+ attachments: "DOCUMENTS_ATTACHMENTS"
20
+ };
21
+ function R(a) {
22
+ return !a || a.includes(":") ? "#" : `/openmrs/auth?requested_document=/document_images/${a}`;
23
+ }
24
+ function ie(a, E) {
25
+ return a.map((s) => ({
26
+ key: s,
27
+ header: E(ue[s])
28
+ }));
29
+ }
30
+ const Te = [
31
+ "documentIdentifier",
32
+ "documentType",
33
+ "attachments",
34
+ "uploadedOn",
35
+ "uploadedBy"
36
+ ], pe = /\.(jpg|jpeg|png|gif|webp|bmp|svg)$/i, B = (a) => a.attachments.length > 0 ? a.attachments : a.documentUrl ? [{ url: a.documentUrl, contentType: a.contentType }] : [], Ne = ({ config: a, encounterUuids: E }) => {
37
+ const [s, w] = l(!1), [o, U] = l(
38
+ null
39
+ ), [$, O] = l(
40
+ /* @__PURE__ */ new Set()
41
+ ), g = x(), { t: n } = G(), { addNotification: L } = W(), k = Number(a?.pageSize) || 5, [f, C] = l(1), [u, V] = l(k), [q, A] = l(void 0), M = h((e) => {
42
+ U(e), w(!0);
43
+ }, []), F = h(() => {
44
+ w(!1), U(null), O(/* @__PURE__ */ new Set());
45
+ }, []), v = h((e) => {
46
+ O((t) => new Set(t).add(e));
47
+ }, []), { data: i, isLoading: H, isError: y, error: b } = ae({
48
+ queryKey: [
49
+ "documents",
50
+ g,
51
+ E,
52
+ f,
53
+ u
54
+ ],
55
+ enabled: !!g,
56
+ queryFn: () => J(
57
+ g,
58
+ E,
59
+ u,
60
+ f
61
+ )
62
+ });
63
+ I(() => {
64
+ i && A(i.total);
65
+ }, [i]), I(() => {
66
+ C(1), A(void 0);
67
+ }, [g]), I(() => {
68
+ y && L({
69
+ title: n("ERROR_DEFAULT_TITLE"),
70
+ message: b?.message ?? "",
71
+ type: "error"
72
+ });
73
+ }, [y, b, L, n]), I(() => {
74
+ const e = new AbortController();
75
+ return (async () => {
76
+ if (!s || !o) return;
77
+ const t = /* @__PURE__ */ new Set(), m = B(o);
78
+ for (let c = 0; c < m.length; c++) {
79
+ const S = R(m[c].url);
80
+ try {
81
+ (await fetch(S, {
82
+ method: "HEAD",
83
+ signal: e.signal
84
+ })).ok || t.add(c);
85
+ } catch (D) {
86
+ D instanceof Error && D.name !== "AbortError" && t.add(c);
87
+ }
88
+ }
89
+ e.signal.aborted || O(t);
90
+ })(), () => e.abort();
91
+ }, [s, o]);
92
+ const z = h(
93
+ (e, t) => {
94
+ t !== u ? (V(t), C(1), A(void 0)) : C(e);
95
+ },
96
+ [u]
97
+ ), N = _(
98
+ () => a?.fields ?? Te,
99
+ [a?.fields]
100
+ ), j = _(() => [...i?.documents ?? []].sort((e, t) => !e.uploadedOn && !t.uploadedOn ? 0 : e.uploadedOn ? t.uploadedOn ? new Date(t.uploadedOn).getTime() - new Date(e.uploadedOn).getTime() : -1 : 1), [i]), P = _(() => ie(N, n), [N, n]), K = _(
101
+ () => N.map((e) => ({
102
+ key: e,
103
+ sortable: e !== "attachments"
104
+ })),
105
+ [N]
106
+ ), T = _(
107
+ () => o ? B(o) : [],
108
+ [o]
109
+ ), Q = h(
110
+ (e, t) => {
111
+ switch (t) {
112
+ case "documentIdentifier":
113
+ return /* @__PURE__ */ r("span", { children: e.documentIdentifier });
114
+ case "documentType":
115
+ return e.documentType ?? n("DOCUMENTS_NOT_AVAILABLE");
116
+ case "uploadedOn":
117
+ return Z(
118
+ e.uploadedOn,
119
+ n,
120
+ !0
121
+ ).formattedResult || n("DOCUMENTS_NOT_AVAILABLE");
122
+ case "uploadedBy":
123
+ return e.uploadedBy ?? n("DOCUMENTS_NOT_AVAILABLE");
124
+ case "attachments":
125
+ return e.attachments.length > 0 || e.documentUrl ? /* @__PURE__ */ r(
126
+ X,
127
+ {
128
+ onClick: () => M(e),
129
+ className: d.viewAttachmentsLink,
130
+ "data-testid": `view-attachments-${e.id}`,
131
+ children: n("DOCUMENTS_VIEW_ATTACHMENTS")
132
+ }
133
+ ) : "--";
134
+ default:
135
+ return null;
136
+ }
137
+ },
138
+ [M, n]
139
+ );
140
+ return /* @__PURE__ */ p(Y, { children: [
141
+ /* @__PURE__ */ r("div", { "data-testid": "documents-table", children: /* @__PURE__ */ r(
142
+ ee,
143
+ {
144
+ headers: P,
145
+ ariaLabel: n("DOCUMENTS_TABLE_HEADING"),
146
+ rows: j,
147
+ loading: H,
148
+ errorStateMessage: y ? b?.message : null,
149
+ sortable: K,
150
+ emptyStateMessage: n("DOCUMENTS_NO_RECORDS"),
151
+ renderCell: Q,
152
+ className: d.documentsTableBody,
153
+ dataTestId: "documents-table",
154
+ pageSize: u,
155
+ totalItems: q,
156
+ page: f,
157
+ onPageChange: z
158
+ }
159
+ ) }),
160
+ s && o && /* @__PURE__ */ r(
161
+ te,
162
+ {
163
+ id: "modalIdForActionAreaLayout",
164
+ portalId: "main-display-area",
165
+ open: s,
166
+ onRequestClose: F,
167
+ modalHeading: o.documentIdentifier,
168
+ passiveModal: !0,
169
+ size: "lg",
170
+ testId: "document-view-modal",
171
+ children: /* @__PURE__ */ r("div", { className: d.documentViewerContainer, children: T.map((e, t) => {
172
+ const m = R(e.url), c = e.contentType?.toLowerCase().includes("pdf"), S = (e.contentType?.toLowerCase().includes("image") ?? !1) || pe.test(e.url ?? ""), D = $.has(t);
173
+ return m === "#" || D ? /* @__PURE__ */ p(
174
+ "div",
175
+ {
176
+ className: d.attachmentError,
177
+ "data-testid": `attachment-error-${t}`,
178
+ children: [
179
+ T.length > 1 && /* @__PURE__ */ p("p", { className: d.attachmentCounter, children: [
180
+ t + 1,
181
+ "/",
182
+ T.length
183
+ ] }),
184
+ /* @__PURE__ */ r("p", { children: n("DOCUMENTS_ERROR_LOADING_ATTACHMENT") })
185
+ ]
186
+ },
187
+ `${o.id}-${e.url}`
188
+ ) : /* @__PURE__ */ p(
189
+ "div",
190
+ {
191
+ className: d.attachmentItem,
192
+ "data-testid": `attachment-item-${t}`,
193
+ children: [
194
+ T.length > 1 && /* @__PURE__ */ p("p", { className: d.attachmentCounter, children: [
195
+ t + 1,
196
+ "/",
197
+ T.length
198
+ ] }),
199
+ S ? /* @__PURE__ */ r(
200
+ "img",
201
+ {
202
+ src: m,
203
+ alt: o.documentIdentifier,
204
+ className: d.documentImage,
205
+ onError: () => v(t)
206
+ }
207
+ ) : /* @__PURE__ */ r(
208
+ "iframe",
209
+ {
210
+ src: c ? `${m}#toolbar=0` : m,
211
+ className: d.documentIframe,
212
+ title: o.documentIdentifier,
213
+ onError: () => v(t)
214
+ }
215
+ )
216
+ ]
217
+ },
218
+ `${o.id}-${e.url}`
219
+ );
220
+ }) })
221
+ }
222
+ )
223
+ ] });
224
+ };
225
+ export {
226
+ Ne as default
227
+ };
@@ -0,0 +1,272 @@
1
+ import { jsx as n, jsxs as $, Fragment as ge } from "react/jsx-runtime";
2
+ import { u as he, v as Ne, i as Te, e as Oe, a as be, b as Ie, J as Ae, N as Ee, c as _e, m as ve, d as Fe, V as Me, y as Se, S as x, w as Be, A as K, f as j, q as Ce, Y as z, P as De, F as Le, p as Ue, h as Re, g as qe } from "./index-BMa5QlCF.js";
3
+ import { useQueryClient as we, useQuery as T } from "@tanstack/react-query";
4
+ import { useState as Q, useMemo as i, useCallback as d } from "react";
5
+ const ke = "FormsTable-module_formsTableBody__SvGha", Ve = "FormsTable-module_modalHeading__wnTmA", He = "FormsTable-module_customAccordianItem__isszs", O = {
6
+ formsTableBody: ke,
7
+ modalHeading: Ve,
8
+ customAccordianItem: He
9
+ }, Ge = "startConsultation", je = ({
10
+ episodeOfCareUuids: F,
11
+ encounterUuids: l,
12
+ config: Y,
13
+ disableActions: J = !1,
14
+ activeEncounterUuid: y = null
15
+ }) => {
16
+ const { t } = he(), m = Ne(), [p, M] = Q(!1), [o, S] = Q(null), {
17
+ numberOfVisits: Z,
18
+ hideThumbnail: X = !1,
19
+ forms: g
20
+ } = Y ?? {}, W = Te(
21
+ qe.EDIT_OBSERVATIONS
22
+ ), { userPrivileges: h } = Oe(), b = W && !J && !!y, B = be(
23
+ F,
24
+ l
25
+ ), ee = we(), {
26
+ data: C = [],
27
+ isLoading: D,
28
+ isError: L,
29
+ error: re,
30
+ refetch: ae
31
+ } = T({
32
+ queryKey: ["forms", m, F],
33
+ queryFn: () => Ie(m, void 0, Z),
34
+ enabled: !!m && !B
35
+ }), U = i(() => {
36
+ let e = C;
37
+ return l && l.length > 0 && (e = e.filter(
38
+ (r) => l.includes(r.encounterUuid)
39
+ )), Array.isArray(g) && g.length > 0 && (e = e.filter(
40
+ (r) => g.some((a) => a.toLowerCase() === r.formName.toLowerCase())
41
+ )), e;
42
+ }, [C, l, g]), { data: N = [] } = T({
43
+ queryKey: ["observationForms"],
44
+ queryFn: () => Ae()
45
+ }), R = d(
46
+ (e) => {
47
+ const r = N.find((s) => s.name === e);
48
+ if (!r?.privileges || r.privileges.length === 0) return !0;
49
+ if (!h || h.length === 0) return !1;
50
+ const a = new Set(h.map((s) => s.name));
51
+ return r.privileges.some(
52
+ (s) => a.has(s.privilegeName) && s.editable
53
+ );
54
+ },
55
+ [N, h]
56
+ ), u = d(
57
+ (e) => !y || e.encounterUuid !== y ? !1 : R(e.formName),
58
+ [y, R]
59
+ ), q = d(
60
+ (e) => N.find((r) => r.name === e)?.uuid,
61
+ [N]
62
+ ), I = i(() => {
63
+ if (o)
64
+ return q(o.formName);
65
+ }, [o, q]), {
66
+ data: w,
67
+ isLoading: oe,
68
+ isError: te,
69
+ error: A
70
+ } = T({
71
+ queryKey: ["formMetadata", I],
72
+ queryFn: () => Ee(I),
73
+ enabled: !!I && p
74
+ }), {
75
+ data: E,
76
+ isLoading: se,
77
+ isError: ne,
78
+ error: _
79
+ } = T({
80
+ queryKey: ["formsEncounterFHIR", o?.encounterUuid],
81
+ queryFn: () => _e(o.encounterUuid),
82
+ enabled: !!o?.encounterUuid && p
83
+ });
84
+ ve(
85
+ (e) => {
86
+ e.patientUUID === m && (ae(), ee.invalidateQueries({ queryKey: ["formsEncounterFHIR"] }));
87
+ },
88
+ [m]
89
+ );
90
+ const ie = i(() => !E?.entry || !o?.formName ? [] : E.entry.filter((e) => e.resource?.resourceType === "Observation").map((e) => e.resource).filter((e) => Fe(e) ? Me(e)?.toLowerCase() === o.formName.toLowerCase() : !0), [E, o?.formName]), { controlOrder: de, sectionMap: le, conceptDatatypeMap: me } = i(
91
+ () => Se(w?.schema),
92
+ [w]
93
+ ), ue = i(() => {
94
+ if (A)
95
+ return x(A).message;
96
+ if (_)
97
+ return x(_).message;
98
+ }, [A, _]), c = i(
99
+ () => [
100
+ { key: "recordedOn", header: t("RECORDED_ON") },
101
+ { key: "recordedBy", header: t("RECORDED_BY") }
102
+ ],
103
+ [t]
104
+ ), k = i(
105
+ () => [...c, { key: "actions", header: t("ACTIONS") }],
106
+ [c, t]
107
+ ), ce = d(
108
+ (e) => b && e.some((r) => u(r)) ? k : c,
109
+ [b, u, k, c]
110
+ ), fe = c, ye = i(
111
+ () => [
112
+ { key: "recordedOn", sortable: !0 },
113
+ { key: "recordedBy", sortable: !0 }
114
+ ],
115
+ []
116
+ ), V = i(() => {
117
+ const e = U.reduce(
118
+ (r, a) => {
119
+ const s = a.formName;
120
+ r[s] ??= [];
121
+ const f = a.providers.map((pe) => pe.providerName).filter(Boolean).join(", ");
122
+ return r[s].push({
123
+ id: a.encounterUuid,
124
+ formName: a.formName,
125
+ recordedOn: Be(a.encounterDateTime, t, !0).formattedResult,
126
+ recordedBy: f ?? "--",
127
+ encounterDateTime: a.encounterDateTime,
128
+ encounterUuid: a.encounterUuid
129
+ }), r;
130
+ },
131
+ {}
132
+ );
133
+ return Object.entries(e).map(
134
+ ([r, a]) => ({
135
+ formName: r,
136
+ records: a.sort(
137
+ (s, f) => f.encounterDateTime - s.encounterDateTime
138
+ )
139
+ })
140
+ ).sort((r, a) => r.formName.localeCompare(a.formName));
141
+ }, [U, t]), H = d((e) => {
142
+ S(e), M(!0);
143
+ }, []), G = d(() => {
144
+ M(!1), S(null);
145
+ }, []), v = d((e) => {
146
+ globalThis.dispatchEvent(
147
+ new CustomEvent(Ge, {
148
+ detail: {
149
+ editOnly: "observationForms",
150
+ editTitle: "EDIT_OBSERVATION_FORM_TITLE",
151
+ sourceEncounterUuid: e.encounterUuid,
152
+ formName: e.formName,
153
+ directFormMode: !0
154
+ }
155
+ })
156
+ );
157
+ }, []), P = d(
158
+ (e, r) => {
159
+ switch (r) {
160
+ case "recordedOn":
161
+ return /* @__PURE__ */ n(Ce, { onClick: () => H(e), children: e.recordedOn });
162
+ case "recordedBy":
163
+ return e.recordedBy;
164
+ case "actions":
165
+ return u(e) ? /* @__PURE__ */ n(
166
+ K,
167
+ {
168
+ label: t("EDIT_OBSERVATION_FORM"),
169
+ kind: "ghost",
170
+ size: "sm",
171
+ testId: `edit-form-${e.encounterUuid}`,
172
+ onClick: () => v(e),
173
+ children: /* @__PURE__ */ n(j, {})
174
+ }
175
+ ) : null;
176
+ default:
177
+ return null;
178
+ }
179
+ },
180
+ [H, v, u, t]
181
+ );
182
+ return /* @__PURE__ */ $(ge, { children: [
183
+ /* @__PURE__ */ n("div", { id: "forms-table", "data-testid": "forms-table", children: D || L || V.length === 0 || B ? /* @__PURE__ */ n(
184
+ z,
185
+ {
186
+ headers: fe,
187
+ ariaLabel: t("FORMS_HEADING"),
188
+ rows: [],
189
+ loading: D,
190
+ errorStateMessage: L ? re?.message : void 0,
191
+ emptyStateMessage: t("FORMS_UNAVAILABLE"),
192
+ renderCell: P,
193
+ className: O.formsTableBody,
194
+ dataTestId: "forms-table"
195
+ }
196
+ ) : /* @__PURE__ */ n(De, { align: "start", children: V.map((e, r) => {
197
+ const { formName: a, records: s } = e, f = ce(s);
198
+ return /* @__PURE__ */ n(
199
+ Le,
200
+ {
201
+ title: a,
202
+ className: O.customAccordianItem,
203
+ testId: `accordian-title-${a}`,
204
+ open: r === 0,
205
+ children: /* @__PURE__ */ n(
206
+ z,
207
+ {
208
+ headers: f,
209
+ ariaLabel: t("FORMS_HEADING"),
210
+ rows: s,
211
+ loading: !1,
212
+ errorStateMessage: "",
213
+ sortable: ye,
214
+ emptyStateMessage: t("FORMS_UNAVAILABLE"),
215
+ renderCell: P,
216
+ className: O.formsTableBody,
217
+ dataTestId: `forms-table-${a}`
218
+ }
219
+ )
220
+ },
221
+ a
222
+ );
223
+ }) }) }),
224
+ p && o && /* @__PURE__ */ n(
225
+ Ue,
226
+ {
227
+ id: "modalIdForActionAreaLayout",
228
+ portalId: "main-display-area",
229
+ open: p,
230
+ onRequestClose: G,
231
+ modalHeading: /* @__PURE__ */ $("div", { className: O.modalHeading, children: [
232
+ /* @__PURE__ */ n("span", { children: o.formName }),
233
+ b && u(o) && /* @__PURE__ */ n(
234
+ K,
235
+ {
236
+ label: t("EDIT_OBSERVATION_FORM"),
237
+ kind: "ghost",
238
+ size: "sm",
239
+ testId: `edit-form-modal-${o.encounterUuid}`,
240
+ onClick: () => {
241
+ G(), v(o);
242
+ },
243
+ children: /* @__PURE__ */ n(j, {})
244
+ }
245
+ )
246
+ ] }),
247
+ modalLabel: `${o.recordedOn} | ${o.recordedBy}`,
248
+ passiveModal: !0,
249
+ size: "md",
250
+ testId: "form-details-modal",
251
+ children: /* @__PURE__ */ n(
252
+ Re,
253
+ {
254
+ observations: ie,
255
+ isLoading: oe || se,
256
+ isError: te || ne,
257
+ errorMessage: ue,
258
+ emptyStateMessage: t("NO_FORM_DATA_AVAILABLE"),
259
+ testIdPrefix: o.formName,
260
+ hideThumbnail: X,
261
+ controlOrder: de,
262
+ sectionMap: le,
263
+ conceptDatatypeMap: me
264
+ }
265
+ )
266
+ }
267
+ )
268
+ ] });
269
+ };
270
+ export {
271
+ je as default
272
+ };
@@ -0,0 +1,33 @@
1
+ import { c, T as l, P as m, a as u, D as v, Q as i } from "./YPM2AS64-C0pi-hgq.js";
2
+ import { Z as d, a0 as f, a1 as e } from "./index-BMa5QlCF.js";
3
+ var p = (a) => {
4
+ const [r, t] = c({
5
+ prefix: "TanstackQueryDevtools"
6
+ }), n = d(), s = f(() => {
7
+ const o = r.theme_preference || l;
8
+ return o !== "system" ? o : n();
9
+ });
10
+ return e(i.Provider, {
11
+ value: a,
12
+ get children() {
13
+ return e(m, {
14
+ localStore: r,
15
+ setLocalStore: t,
16
+ get children() {
17
+ return e(u.Provider, {
18
+ value: s,
19
+ get children() {
20
+ return e(v, {
21
+ localStore: r,
22
+ setLocalStore: t
23
+ });
24
+ }
25
+ });
26
+ }
27
+ });
28
+ }
29
+ });
30
+ }, C = p;
31
+ export {
32
+ C as default
33
+ };
@@ -0,0 +1,42 @@
1
+ import { c as s, T as c, P as u, a as i, b as m, C as P, Q as d } from "./YPM2AS64-C0pi-hgq.js";
2
+ import { Z as v, a0 as C, a1 as e } from "./index-BMa5QlCF.js";
3
+ var h = (t) => {
4
+ const [r, o] = s({
5
+ prefix: "TanstackQueryDevtools"
6
+ }), a = v(), l = C(() => {
7
+ const n = r.theme_preference || c;
8
+ return n !== "system" ? n : a();
9
+ });
10
+ return e(d.Provider, {
11
+ value: t,
12
+ get children() {
13
+ return e(u, {
14
+ disabled: !0,
15
+ localStore: r,
16
+ setLocalStore: o,
17
+ get children() {
18
+ return e(i.Provider, {
19
+ value: l,
20
+ get children() {
21
+ return e(m, {
22
+ get children() {
23
+ return e(P, {
24
+ localStore: r,
25
+ setLocalStore: o,
26
+ get onClose() {
27
+ return t.onClose;
28
+ },
29
+ showPanelViewOnly: !0
30
+ });
31
+ }
32
+ });
33
+ }
34
+ });
35
+ }
36
+ });
37
+ }
38
+ });
39
+ }, p = h;
40
+ export {
41
+ p as default
42
+ };