@argusoft/medplat-product-management 1.0.2 → 1.0.4
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/{BrandsPage-CSA3meke.js → BrandsPage-BE3kn-8b.js} +77 -75
- package/dist/BrandsPage-BE3kn-8b.js.map +1 -0
- package/dist/{CategoriesPage-BrspzkJL.js → CategoriesPage-COqi3pMi.js} +71 -70
- package/dist/{CategoriesPage-BrspzkJL.js.map → CategoriesPage-COqi3pMi.js.map} +1 -1
- package/dist/{DashboardPage-CqaquOs2.js → DashboardPage-C_H1Jrey.js} +90 -89
- package/dist/DashboardPage-C_H1Jrey.js.map +1 -0
- package/dist/{FacilityPicker-Dv_H95WW.js → FacilityPicker-Diq2hnYg.js} +2 -2
- package/dist/{FacilityPicker-Dv_H95WW.js.map → FacilityPicker-Diq2hnYg.js.map} +1 -1
- package/dist/{InventoryPage-CPbzfDMR.js → InventoryPage-Bjpw6vTz.js} +106 -115
- package/dist/InventoryPage-Bjpw6vTz.js.map +1 -0
- package/dist/{MemberProfileCard-0vjO3Gzd.js → MemberProfileCard-BLUVRILO.js} +10 -9
- package/dist/MemberProfileCard-BLUVRILO.js.map +1 -0
- package/dist/{PaymentCreatePage-BYmDZAIB.js → PaymentCreatePage-B5VOgTx9.js} +173 -177
- package/dist/PaymentCreatePage-B5VOgTx9.js.map +1 -0
- package/dist/{PaymentsPage-BXPvKon-.js → PaymentsPage-DY6BclkN.js} +24 -23
- package/dist/{PaymentsPage-BXPvKon-.js.map → PaymentsPage-DY6BclkN.js.map} +1 -1
- package/dist/PickupCreatePage-CCSiyFQF.js +706 -0
- package/dist/PickupCreatePage-CCSiyFQF.js.map +1 -0
- package/dist/{PickupsPage-D66_Wta4.js → PickupsPage-DGi6T5Of.js} +83 -90
- package/dist/PickupsPage-DGi6T5Of.js.map +1 -0
- package/dist/PmGuard-C90yhpsN.js +592 -0
- package/dist/PmGuard-C90yhpsN.js.map +1 -0
- package/dist/{PmTable-B9970kPY.js → PmTable-BkK65bJQ.js} +98 -98
- package/dist/PmTable-BkK65bJQ.js.map +1 -0
- package/dist/{ProductEditPage-B8qFTCW9.js → ProductEditPage-CQj9egzW.js} +138 -137
- package/dist/ProductEditPage-CQj9egzW.js.map +1 -0
- package/dist/{ProductsPage-C7_r9cKn.js → ProductsPage-i8QVw_Jm.js} +65 -64
- package/dist/{ProductsPage-C7_r9cKn.js.map → ProductsPage-i8QVw_Jm.js.map} +1 -1
- package/dist/PurchaseCreatePage-Bp6bl9n8.js +591 -0
- package/dist/PurchaseCreatePage-Bp6bl9n8.js.map +1 -0
- package/dist/{PurchaseRequestDetailPage-C7aAwEqw.js → PurchaseRequestDetailPage-CNAqIFef.js} +216 -215
- package/dist/PurchaseRequestDetailPage-CNAqIFef.js.map +1 -0
- package/dist/{PurchaseRequestsPage-BwCkbpaX.js → PurchaseRequestsPage-BJqDlNrc.js} +57 -56
- package/dist/{PurchaseRequestsPage-BwCkbpaX.js.map → PurchaseRequestsPage-BJqDlNrc.js.map} +1 -1
- package/dist/{PurchasesPage-CvaZouVy.js → PurchasesPage-BQEToymQ.js} +76 -75
- package/dist/{PurchasesPage-CvaZouVy.js.map → PurchasesPage-BQEToymQ.js.map} +1 -1
- package/dist/{SaleCreatePage-DP1Qmltu.js → SaleCreatePage-DbfBK4PH.js} +149 -173
- package/dist/SaleCreatePage-DbfBK4PH.js.map +1 -0
- package/dist/{SalesPage-CO3cdYX5.js → SalesPage-CTBJMxZe.js} +50 -49
- package/dist/SalesPage-CTBJMxZe.js.map +1 -0
- package/dist/SettingsPage-CiwVmzM3.js +663 -0
- package/dist/SettingsPage-CiwVmzM3.js.map +1 -0
- package/dist/{StorageUnitsPage-B9Hr_RkW.js → StorageUnitsPage-BV7nK_iE.js} +57 -56
- package/dist/{StorageUnitsPage-B9Hr_RkW.js.map → StorageUnitsPage-BV7nK_iE.js.map} +1 -1
- package/dist/{TransactionsPage-HKIGwEZN.js → TransactionsPage-Cocn4901.js} +55 -54
- package/dist/TransactionsPage-Cocn4901.js.map +1 -0
- package/dist/TransferCreatePage-DbjcjuOg.js +316 -0
- package/dist/TransferCreatePage-DbjcjuOg.js.map +1 -0
- package/dist/TransfersPage-BFVF7Xvc.js +471 -0
- package/dist/TransfersPage-BFVF7Xvc.js.map +1 -0
- package/dist/VialsPage-BNzYTLVd.js +321 -0
- package/dist/VialsPage-BNzYTLVd.js.map +1 -0
- package/dist/index.js +652 -34
- package/dist/index.js.map +1 -1
- package/dist/settingsStore-KW217unV.js +417 -0
- package/dist/settingsStore-KW217unV.js.map +1 -0
- package/package.json +1 -1
- package/dist/BrandsPage-CSA3meke.js.map +0 -1
- package/dist/DashboardPage-CqaquOs2.js.map +0 -1
- package/dist/InventoryPage-CPbzfDMR.js.map +0 -1
- package/dist/MemberProfileCard-0vjO3Gzd.js.map +0 -1
- package/dist/PaymentCreatePage-BYmDZAIB.js.map +0 -1
- package/dist/PickupCreatePage-CMGwoAXj.js +0 -426
- package/dist/PickupCreatePage-CMGwoAXj.js.map +0 -1
- package/dist/PickupsPage-D66_Wta4.js.map +0 -1
- package/dist/PmTable-B9970kPY.js.map +0 -1
- package/dist/ProductEditPage-B8qFTCW9.js.map +0 -1
- package/dist/PurchaseCreatePage-CDfNDcKG.js +0 -627
- package/dist/PurchaseCreatePage-CDfNDcKG.js.map +0 -1
- package/dist/PurchaseRequestDetailPage-C7aAwEqw.js.map +0 -1
- package/dist/SaleCreatePage-DP1Qmltu.js.map +0 -1
- package/dist/SalesPage-CO3cdYX5.js.map +0 -1
- package/dist/SettingsPage-DvVRwSFw.js +0 -711
- package/dist/SettingsPage-DvVRwSFw.js.map +0 -1
- package/dist/TransactionsPage-HKIGwEZN.js.map +0 -1
- package/dist/TransferCreatePage-DMuZqQ3c.js +0 -363
- package/dist/TransferCreatePage-DMuZqQ3c.js.map +0 -1
- package/dist/TransfersPage-COIyouL4.js +0 -480
- package/dist/TransfersPage-COIyouL4.js.map +0 -1
- package/dist/VialsPage-BNPUwGCU.js +0 -922
- package/dist/VialsPage-BNPUwGCU.js.map +0 -1
- package/dist/currency-ClRLIEg2.js +0 -1372
- package/dist/currency-ClRLIEg2.js.map +0 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as
|
|
1
|
+
import { E as e, L as t, M as n, S as r, i, j as a, m as o, p as s, r as c, z as l } from "./settingsStore-KW217unV.js";
|
|
2
|
+
import { n as u, r as d } from "./format-UOyOu75i.js";
|
|
3
|
+
import { a as f, i as p, n as m, o as h, r as g, t as _ } from "./PmGuard-C90yhpsN.js";
|
|
3
4
|
import { useState as v } from "react";
|
|
4
5
|
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
5
|
-
import
|
|
6
|
-
import j from "
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import x from "prop-types";
|
|
7
|
+
import { Box as S, Card as C, CardContent as w, Chip as T, Grid as E, Grow as D, LinearProgress as O, Skeleton as k, Stack as A, Typography as j } from "@mui/material";
|
|
8
|
+
import { alpha as M, useTheme as N } from "@mui/material/styles";
|
|
9
|
+
import { useNavigate as P } from "react-router-dom";
|
|
9
10
|
import F from "@mui/icons-material/ArrowForwardRounded";
|
|
10
11
|
//#region src/views/DashboardPage.jsx
|
|
11
12
|
var I = {
|
|
@@ -23,7 +24,7 @@ var I = {
|
|
|
23
24
|
TRANSFER_IN: "default"
|
|
24
25
|
};
|
|
25
26
|
function L({ label: e, value: t, loading: n }) {
|
|
26
|
-
return /* @__PURE__ */ b(
|
|
27
|
+
return /* @__PURE__ */ b(S, { children: [/* @__PURE__ */ y(j, {
|
|
27
28
|
variant: "caption",
|
|
28
29
|
color: "text.secondary",
|
|
29
30
|
sx: {
|
|
@@ -31,10 +32,10 @@ function L({ label: e, value: t, loading: n }) {
|
|
|
31
32
|
letterSpacing: .5
|
|
32
33
|
},
|
|
33
34
|
children: e.toUpperCase()
|
|
34
|
-
}), n ? /* @__PURE__ */ y(
|
|
35
|
+
}), n ? /* @__PURE__ */ y(k, {
|
|
35
36
|
width: 48,
|
|
36
37
|
height: 32
|
|
37
|
-
}) : /* @__PURE__ */ y(
|
|
38
|
+
}) : /* @__PURE__ */ y(j, {
|
|
38
39
|
variant: "h5",
|
|
39
40
|
sx: {
|
|
40
41
|
fontWeight: 800,
|
|
@@ -46,25 +47,25 @@ function L({ label: e, value: t, loading: n }) {
|
|
|
46
47
|
})] });
|
|
47
48
|
}
|
|
48
49
|
L.propTypes = {
|
|
49
|
-
label:
|
|
50
|
-
value:
|
|
51
|
-
loading:
|
|
50
|
+
label: x.string,
|
|
51
|
+
value: x.node,
|
|
52
|
+
loading: x.bool
|
|
52
53
|
};
|
|
53
54
|
function R({ workspace: e, metrics: t, loading: n, onItemClick: r }) {
|
|
54
|
-
let i =
|
|
55
|
-
return /* @__PURE__ */ y(
|
|
55
|
+
let i = N(), a = e.icon;
|
|
56
|
+
return /* @__PURE__ */ y(C, {
|
|
56
57
|
sx: {
|
|
57
|
-
borderRadius:
|
|
58
|
+
borderRadius: 1.5,
|
|
58
59
|
height: "100%",
|
|
59
60
|
position: "relative",
|
|
60
61
|
overflow: "hidden",
|
|
61
|
-
border: `1px solid ${
|
|
62
|
-
background: `linear-gradient(180deg, ${
|
|
63
|
-
boxShadow: `0 16px 36px ${
|
|
62
|
+
border: `1px solid ${M(e.accent, .18)}`,
|
|
63
|
+
background: `linear-gradient(180deg, ${M(e.accent, .06)} 0%, ${M(i.palette.background.paper, 1)} 35%)`,
|
|
64
|
+
boxShadow: `0 16px 36px ${M(e.accent, .08)}`,
|
|
64
65
|
transition: "transform 240ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow 240ms",
|
|
65
66
|
"&:hover": {
|
|
66
67
|
transform: "translateY(-3px)",
|
|
67
|
-
boxShadow: `0 22px 50px ${
|
|
68
|
+
boxShadow: `0 22px 50px ${M(e.accent, .18)}`
|
|
68
69
|
},
|
|
69
70
|
"&::before": {
|
|
70
71
|
content: "\"\"",
|
|
@@ -76,7 +77,7 @@ function R({ workspace: e, metrics: t, loading: n, onItemClick: r }) {
|
|
|
76
77
|
background: `linear-gradient(90deg, ${e.accent} 0%, ${e.accentDark} 100%)`
|
|
77
78
|
}
|
|
78
79
|
},
|
|
79
|
-
children: /* @__PURE__ */ b(
|
|
80
|
+
children: /* @__PURE__ */ b(w, {
|
|
80
81
|
sx: {
|
|
81
82
|
pt: 3,
|
|
82
83
|
display: "flex",
|
|
@@ -84,28 +85,28 @@ function R({ workspace: e, metrics: t, loading: n, onItemClick: r }) {
|
|
|
84
85
|
height: "100%"
|
|
85
86
|
},
|
|
86
87
|
children: [
|
|
87
|
-
/* @__PURE__ */ b(
|
|
88
|
+
/* @__PURE__ */ b(A, {
|
|
88
89
|
direction: "row",
|
|
89
90
|
alignItems: "center",
|
|
90
91
|
spacing: 1.5,
|
|
91
|
-
children: [/* @__PURE__ */ y(
|
|
92
|
+
children: [/* @__PURE__ */ y(S, {
|
|
92
93
|
sx: {
|
|
93
94
|
width: 44,
|
|
94
95
|
height: 44,
|
|
95
|
-
borderRadius:
|
|
96
|
+
borderRadius: 1.5,
|
|
96
97
|
display: "grid",
|
|
97
98
|
placeItems: "center",
|
|
98
99
|
color: "#fff",
|
|
99
100
|
background: `linear-gradient(135deg, ${e.accent} 0%, ${e.accentDark} 100%)`,
|
|
100
|
-
boxShadow: `0 8px 18px ${
|
|
101
|
+
boxShadow: `0 8px 18px ${M(e.accent, .3)}`
|
|
101
102
|
},
|
|
102
103
|
children: /* @__PURE__ */ y(a, { sx: { fontSize: 24 } })
|
|
103
|
-
}), /* @__PURE__ */ b(
|
|
104
|
+
}), /* @__PURE__ */ b(S, {
|
|
104
105
|
sx: {
|
|
105
106
|
flexGrow: 1,
|
|
106
107
|
minWidth: 0
|
|
107
108
|
},
|
|
108
|
-
children: [/* @__PURE__ */ y(
|
|
109
|
+
children: [/* @__PURE__ */ y(j, {
|
|
109
110
|
variant: "overline",
|
|
110
111
|
sx: {
|
|
111
112
|
color: e.accentDark,
|
|
@@ -114,7 +115,7 @@ function R({ workspace: e, metrics: t, loading: n, onItemClick: r }) {
|
|
|
114
115
|
lineHeight: 1
|
|
115
116
|
},
|
|
116
117
|
children: "Workspace"
|
|
117
|
-
}), /* @__PURE__ */ y(
|
|
118
|
+
}), /* @__PURE__ */ y(j, {
|
|
118
119
|
variant: "h6",
|
|
119
120
|
sx: {
|
|
120
121
|
fontWeight: 800,
|
|
@@ -124,7 +125,7 @@ function R({ workspace: e, metrics: t, loading: n, onItemClick: r }) {
|
|
|
124
125
|
})]
|
|
125
126
|
})]
|
|
126
127
|
}),
|
|
127
|
-
/* @__PURE__ */ y(
|
|
128
|
+
/* @__PURE__ */ y(j, {
|
|
128
129
|
variant: "body2",
|
|
129
130
|
color: "text.secondary",
|
|
130
131
|
sx: {
|
|
@@ -133,7 +134,7 @@ function R({ workspace: e, metrics: t, loading: n, onItemClick: r }) {
|
|
|
133
134
|
},
|
|
134
135
|
children: e.description
|
|
135
136
|
}),
|
|
136
|
-
t?.length ? /* @__PURE__ */ y(
|
|
137
|
+
t?.length ? /* @__PURE__ */ y(A, {
|
|
137
138
|
direction: "row",
|
|
138
139
|
spacing: 3,
|
|
139
140
|
sx: { mb: 2.5 },
|
|
@@ -143,16 +144,16 @@ function R({ workspace: e, metrics: t, loading: n, onItemClick: r }) {
|
|
|
143
144
|
loading: n
|
|
144
145
|
}, e.label))
|
|
145
146
|
}) : null,
|
|
146
|
-
/* @__PURE__ */ y(
|
|
147
|
+
/* @__PURE__ */ y(S, {
|
|
147
148
|
sx: { mt: "auto" },
|
|
148
|
-
children: /* @__PURE__ */ y(
|
|
149
|
+
children: /* @__PURE__ */ y(A, {
|
|
149
150
|
direction: "row",
|
|
150
151
|
spacing: 1,
|
|
151
152
|
flexWrap: "wrap",
|
|
152
153
|
useFlexGap: !0,
|
|
153
154
|
children: e.items.map((t) => {
|
|
154
155
|
let n = t.icon;
|
|
155
|
-
return /* @__PURE__ */ y(
|
|
156
|
+
return /* @__PURE__ */ y(T, {
|
|
156
157
|
icon: n ? /* @__PURE__ */ y(n, { sx: {
|
|
157
158
|
fontSize: "1rem !important",
|
|
158
159
|
color: `${e.accentDark} !important`
|
|
@@ -162,12 +163,12 @@ function R({ workspace: e, metrics: t, loading: n, onItemClick: r }) {
|
|
|
162
163
|
sx: {
|
|
163
164
|
borderRadius: 2,
|
|
164
165
|
fontWeight: 700,
|
|
165
|
-
backgroundColor:
|
|
166
|
+
backgroundColor: M(e.accent, .08),
|
|
166
167
|
color: e.accentDark,
|
|
167
|
-
border: `1px solid ${
|
|
168
|
+
border: `1px solid ${M(e.accent, .18)}`,
|
|
168
169
|
transition: "all 180ms ease",
|
|
169
170
|
"&:hover": {
|
|
170
|
-
backgroundColor:
|
|
171
|
+
backgroundColor: M(e.accent, .18),
|
|
171
172
|
transform: "translateY(-1px)"
|
|
172
173
|
}
|
|
173
174
|
}
|
|
@@ -180,13 +181,13 @@ function R({ workspace: e, metrics: t, loading: n, onItemClick: r }) {
|
|
|
180
181
|
});
|
|
181
182
|
}
|
|
182
183
|
R.propTypes = {
|
|
183
|
-
workspace:
|
|
184
|
-
metrics:
|
|
185
|
-
loading:
|
|
186
|
-
onItemClick:
|
|
184
|
+
workspace: x.object.isRequired,
|
|
185
|
+
metrics: x.array,
|
|
186
|
+
loading: x.bool,
|
|
187
|
+
onItemClick: x.func.isRequired
|
|
187
188
|
};
|
|
188
189
|
function z() {
|
|
189
|
-
let
|
|
190
|
+
let x = P(), L = N(), z = c(), B = p(), V = i(z?.currencyCode), H = h(B, z), U = B.has("view.manage.productManagement.ledger"), [W, G] = v(!0), [K, q] = v({
|
|
190
191
|
categories: 0,
|
|
191
192
|
brands: 0,
|
|
192
193
|
products: 0,
|
|
@@ -199,19 +200,19 @@ function z() {
|
|
|
199
200
|
async function J() {
|
|
200
201
|
G(!0);
|
|
201
202
|
try {
|
|
202
|
-
let
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
203
|
+
let i = (e, t) => B.has(e) ? t().catch(() => []) : Promise.resolve([]), [c, u, d, f, p, m, h, g] = await Promise.all([
|
|
204
|
+
i("view.manage.productManagement.category", () => o()),
|
|
205
|
+
i("view.manage.productManagement.brand", () => s()),
|
|
206
|
+
i("view.manage.productManagement.product", () => r()),
|
|
207
|
+
i("view.manage.productManagement.inventory", () => e()),
|
|
208
|
+
i("view.manage.productManagement.vial", () => a()),
|
|
209
|
+
i("view.manage.productManagement.sale", () => t(0, 100)),
|
|
210
|
+
i("view.manage.productManagement.payment", () => n(0, 100)),
|
|
211
|
+
i("view.manage.productManagement.ledger", () => l(0, 8))
|
|
211
212
|
]);
|
|
212
213
|
q({
|
|
213
214
|
categories: c.length,
|
|
214
|
-
brands:
|
|
215
|
+
brands: u.length,
|
|
215
216
|
products: d.length,
|
|
216
217
|
batches: f.length,
|
|
217
218
|
openVials: p.length,
|
|
@@ -223,7 +224,7 @@ function z() {
|
|
|
223
224
|
G(!1);
|
|
224
225
|
}
|
|
225
226
|
}
|
|
226
|
-
|
|
227
|
+
g("view.manage.productManagement", () => {
|
|
227
228
|
J();
|
|
228
229
|
}, []);
|
|
229
230
|
let Y = {
|
|
@@ -260,9 +261,9 @@ function z() {
|
|
|
260
261
|
value: K.txns.length
|
|
261
262
|
}]
|
|
262
263
|
};
|
|
263
|
-
return /* @__PURE__ */ b(
|
|
264
|
+
return /* @__PURE__ */ b(S, { children: [/* @__PURE__ */ y(m, {}), /* @__PURE__ */ y(_, {
|
|
264
265
|
perm: "view.manage.productManagement",
|
|
265
|
-
children: /* @__PURE__ */ b(
|
|
266
|
+
children: /* @__PURE__ */ b(f, {
|
|
266
267
|
title: "Product Management",
|
|
267
268
|
subtitle: "Choose where to start. Use Catalog to set up, Operations for daily work, and Ledger to review history.",
|
|
268
269
|
chips: [
|
|
@@ -271,45 +272,45 @@ function z() {
|
|
|
271
272
|
"Ledger-driven"
|
|
272
273
|
],
|
|
273
274
|
children: [
|
|
274
|
-
W ? /* @__PURE__ */ y(
|
|
275
|
+
W ? /* @__PURE__ */ y(O, { sx: {
|
|
275
276
|
mb: 2,
|
|
276
277
|
borderRadius: 1
|
|
277
278
|
} }) : null,
|
|
278
|
-
/* @__PURE__ */ y(
|
|
279
|
+
/* @__PURE__ */ y(E, {
|
|
279
280
|
container: !0,
|
|
280
281
|
spacing: 2.5,
|
|
281
|
-
children: H.map((e, t) => /* @__PURE__ */ y(
|
|
282
|
+
children: H.map((e, t) => /* @__PURE__ */ y(E, {
|
|
282
283
|
item: !0,
|
|
283
284
|
xs: 12,
|
|
284
285
|
md: 4,
|
|
285
|
-
children: /* @__PURE__ */ y(
|
|
286
|
+
children: /* @__PURE__ */ y(D, {
|
|
286
287
|
in: !0,
|
|
287
288
|
timeout: 420,
|
|
288
289
|
style: { transitionDelay: `${t * 80}ms` },
|
|
289
|
-
children: /* @__PURE__ */ y(
|
|
290
|
+
children: /* @__PURE__ */ y(S, {
|
|
290
291
|
sx: { height: "100%" },
|
|
291
292
|
children: /* @__PURE__ */ y(R, {
|
|
292
293
|
workspace: e,
|
|
293
294
|
metrics: Y[e.id],
|
|
294
295
|
loading: W,
|
|
295
|
-
onItemClick: (e) =>
|
|
296
|
+
onItemClick: (e) => x(e.path)
|
|
296
297
|
})
|
|
297
298
|
})
|
|
298
299
|
})
|
|
299
300
|
}, e.id))
|
|
300
301
|
}),
|
|
301
|
-
U ? /* @__PURE__ */ y(
|
|
302
|
+
U ? /* @__PURE__ */ y(C, {
|
|
302
303
|
sx: {
|
|
303
|
-
borderRadius:
|
|
304
|
+
borderRadius: 1.5,
|
|
304
305
|
mt: 3,
|
|
305
|
-
boxShadow: `0 12px 32px ${
|
|
306
|
+
boxShadow: `0 12px 32px ${M(L.palette.common.black, .05)}`
|
|
306
307
|
},
|
|
307
|
-
children: /* @__PURE__ */ b(
|
|
308
|
+
children: /* @__PURE__ */ b(w, { children: [/* @__PURE__ */ b(A, {
|
|
308
309
|
direction: "row",
|
|
309
310
|
justifyContent: "space-between",
|
|
310
311
|
alignItems: "center",
|
|
311
312
|
sx: { mb: 1.5 },
|
|
312
|
-
children: [/* @__PURE__ */ b(
|
|
313
|
+
children: [/* @__PURE__ */ b(S, { children: [/* @__PURE__ */ y(j, {
|
|
313
314
|
variant: "overline",
|
|
314
315
|
sx: {
|
|
315
316
|
color: "text.secondary",
|
|
@@ -317,34 +318,34 @@ function z() {
|
|
|
317
318
|
letterSpacing: 1
|
|
318
319
|
},
|
|
319
320
|
children: "Stock Ledger"
|
|
320
|
-
}), /* @__PURE__ */ y(
|
|
321
|
+
}), /* @__PURE__ */ y(j, {
|
|
321
322
|
variant: "h6",
|
|
322
323
|
sx: {
|
|
323
324
|
fontWeight: 800,
|
|
324
325
|
lineHeight: 1.2
|
|
325
326
|
},
|
|
326
327
|
children: "Recent activity"
|
|
327
|
-
})] }), /* @__PURE__ */ y(
|
|
328
|
+
})] }), /* @__PURE__ */ y(T, {
|
|
328
329
|
clickable: !0,
|
|
329
330
|
icon: /* @__PURE__ */ y(F, { sx: { fontSize: "1rem !important" } }),
|
|
330
331
|
label: "View ledger",
|
|
331
|
-
onClick: () =>
|
|
332
|
+
onClick: () => x("/ui/medplat/manage/pm/transactions"),
|
|
332
333
|
sx: {
|
|
333
334
|
borderRadius: 2,
|
|
334
335
|
fontWeight: 700,
|
|
335
|
-
bgcolor:
|
|
336
|
+
bgcolor: M(L.palette.primary.main, .08),
|
|
336
337
|
color: "primary.dark",
|
|
337
|
-
"&:hover": { bgcolor:
|
|
338
|
+
"&:hover": { bgcolor: M(L.palette.primary.main, .16) }
|
|
338
339
|
}
|
|
339
340
|
})]
|
|
340
|
-
}), K.txns.length === 0 && !W ? /* @__PURE__ */ y(
|
|
341
|
+
}), K.txns.length === 0 && !W ? /* @__PURE__ */ y(j, {
|
|
341
342
|
variant: "body2",
|
|
342
343
|
color: "text.secondary",
|
|
343
344
|
children: "No activity yet — record a purchase or a sale to see entries here."
|
|
344
|
-
}) : /* @__PURE__ */ y(
|
|
345
|
-
divider: /* @__PURE__ */ y(
|
|
345
|
+
}) : /* @__PURE__ */ y(A, {
|
|
346
|
+
divider: /* @__PURE__ */ y(S, { sx: { borderTop: `1px dashed ${L.palette.divider}` } }),
|
|
346
347
|
spacing: 0,
|
|
347
|
-
children: (W ? Array.from({ length: 4 }) : K.txns).map((e, t) => /* @__PURE__ */ b(
|
|
348
|
+
children: (W ? Array.from({ length: 4 }) : K.txns).map((e, t) => /* @__PURE__ */ b(S, {
|
|
348
349
|
sx: {
|
|
349
350
|
display: "flex",
|
|
350
351
|
justifyContent: "space-between",
|
|
@@ -352,16 +353,16 @@ function z() {
|
|
|
352
353
|
py: 1.25,
|
|
353
354
|
gap: 2
|
|
354
355
|
},
|
|
355
|
-
children: [/* @__PURE__ */ b(
|
|
356
|
+
children: [/* @__PURE__ */ b(A, {
|
|
356
357
|
direction: "row",
|
|
357
358
|
alignItems: "center",
|
|
358
359
|
spacing: 1.5,
|
|
359
360
|
sx: { minWidth: 0 },
|
|
360
|
-
children: [W ? /* @__PURE__ */ y(
|
|
361
|
+
children: [W ? /* @__PURE__ */ y(k, {
|
|
361
362
|
variant: "rounded",
|
|
362
363
|
width: 92,
|
|
363
364
|
height: 22
|
|
364
|
-
}) : /* @__PURE__ */ y(
|
|
365
|
+
}) : /* @__PURE__ */ y(T, {
|
|
365
366
|
size: "small",
|
|
366
367
|
label: e.transactionType,
|
|
367
368
|
color: I[e.transactionType] || "default",
|
|
@@ -370,19 +371,19 @@ function z() {
|
|
|
370
371
|
borderRadius: 1.5,
|
|
371
372
|
height: 22
|
|
372
373
|
}
|
|
373
|
-
}), /* @__PURE__ */ b(
|
|
374
|
+
}), /* @__PURE__ */ b(S, {
|
|
374
375
|
sx: { minWidth: 0 },
|
|
375
|
-
children: [W ? /* @__PURE__ */ y(
|
|
376
|
+
children: [W ? /* @__PURE__ */ y(k, {
|
|
376
377
|
width: 220,
|
|
377
378
|
height: 20
|
|
378
|
-
}) : /* @__PURE__ */ b(
|
|
379
|
+
}) : /* @__PURE__ */ b(j, {
|
|
379
380
|
variant: "body2",
|
|
380
381
|
sx: {
|
|
381
382
|
fontWeight: 700,
|
|
382
383
|
lineHeight: 1.2
|
|
383
384
|
},
|
|
384
385
|
noWrap: !0,
|
|
385
|
-
children: [e.productName || "—", e.lotNumber ? /* @__PURE__ */ b(
|
|
386
|
+
children: [e.productName || "—", e.lotNumber ? /* @__PURE__ */ b(j, {
|
|
386
387
|
component: "span",
|
|
387
388
|
variant: "body2",
|
|
388
389
|
color: "text.secondary",
|
|
@@ -392,24 +393,24 @@ function z() {
|
|
|
392
393
|
},
|
|
393
394
|
children: ["lot ", e.lotNumber]
|
|
394
395
|
}) : null]
|
|
395
|
-
}), W ? /* @__PURE__ */ y(
|
|
396
|
+
}), W ? /* @__PURE__ */ y(k, {
|
|
396
397
|
width: 120,
|
|
397
398
|
height: 16
|
|
398
|
-
}) : /* @__PURE__ */ y(
|
|
399
|
+
}) : /* @__PURE__ */ y(j, {
|
|
399
400
|
variant: "caption",
|
|
400
401
|
color: "text.secondary",
|
|
401
|
-
children:
|
|
402
|
+
children: u(e.transactionTime)
|
|
402
403
|
})]
|
|
403
404
|
})]
|
|
404
|
-
}), /* @__PURE__ */ y(
|
|
405
|
+
}), /* @__PURE__ */ y(S, {
|
|
405
406
|
sx: {
|
|
406
407
|
textAlign: "right",
|
|
407
408
|
whiteSpace: "nowrap"
|
|
408
409
|
},
|
|
409
|
-
children: W ? /* @__PURE__ */ y(
|
|
410
|
+
children: W ? /* @__PURE__ */ y(k, {
|
|
410
411
|
width: 70,
|
|
411
412
|
height: 20
|
|
412
|
-
}) : /* @__PURE__ */ b(
|
|
413
|
+
}) : /* @__PURE__ */ b(j, {
|
|
413
414
|
variant: "body2",
|
|
414
415
|
sx: {
|
|
415
416
|
fontWeight: 800,
|
|
@@ -417,8 +418,8 @@ function z() {
|
|
|
417
418
|
},
|
|
418
419
|
children: [
|
|
419
420
|
e.quantity == null ? "" : `qty ${e.quantity}`,
|
|
420
|
-
e.volumeMl == null ? "" : `${e.quantity == null ? "" : " · "}${
|
|
421
|
-
e.monetaryAmount == null ? "" : `${e.quantity != null || e.volumeMl != null ? " · " : ""}${V}${
|
|
421
|
+
e.volumeMl == null ? "" : `${e.quantity == null ? "" : " · "}${d(e.volumeMl)} ml`,
|
|
422
|
+
e.monetaryAmount == null ? "" : `${e.quantity != null || e.volumeMl != null ? " · " : ""}${V}${d(e.monetaryAmount)}`
|
|
422
423
|
]
|
|
423
424
|
})
|
|
424
425
|
})]
|
|
@@ -432,4 +433,4 @@ function z() {
|
|
|
432
433
|
//#endregion
|
|
433
434
|
export { z as default };
|
|
434
435
|
|
|
435
|
-
//# sourceMappingURL=DashboardPage-
|
|
436
|
+
//# sourceMappingURL=DashboardPage-C_H1Jrey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DashboardPage-C_H1Jrey.js","names":[],"sources":["../src/views/DashboardPage.jsx"],"sourcesContent":["import { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Box,\n Card,\n CardContent,\n Chip,\n Grid,\n Grow,\n LinearProgress,\n Skeleton,\n Stack,\n Typography,\n} from '@mui/material';\nimport { alpha, useTheme } from '@mui/material/styles';\nimport ArrowForwardRoundedIcon from '@mui/icons-material/ArrowForwardRounded';\nimport {\n getCategories,\n getBrands,\n getProducts,\n listBatches,\n listOpenVials,\n listSales,\n listPayments,\n listTransactions,\n} from '@pm/services/pmApi';\nimport PmPageShell from '@pm/components/PmPageShell';\nimport PmNav from '@pm/components/PmNav';\nimport PmGuard from '@pm/components/PmGuard';\nimport { getVisibleWorkspaces } from '@pm/utils/workspaces';\nimport { usePermissionedEffect, usePmPermissions } from '@pm/utils/permissions';\nimport { formatDateTime, formatNumber } from '@pm/utils/format';\nimport { currencySymbol } from '@pm/utils/currency';\nimport { usePmSettings } from '@pm/utils/settingsStore';\n\n// Color hint per ledger transaction type — keeps the recent-activity feed\n// glanceable.\nconst TXN_COLOR = {\n RECEIPT: 'success',\n SALE: 'primary',\n PAYMENT: 'info',\n VIAL_OPENED: 'info',\n ADMINISTRATION: 'info',\n WASTAGE: 'warning',\n EXPIRY: 'error',\n QUARANTINE: 'error',\n RECALL: 'error',\n UNQUARANTINE: 'success',\n TRANSFER_OUT: 'default',\n TRANSFER_IN: 'default',\n};\n\nfunction MetricCell({ label, value, loading }) {\n return (\n <Box>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ fontWeight: 700, letterSpacing: 0.5 }}>\n {label.toUpperCase()}\n </Typography>\n {loading ? (\n <Skeleton width={48} height={32} />\n ) : (\n <Typography variant=\"h5\" sx={{ fontWeight: 800, fontVariantNumeric: 'tabular-nums', lineHeight: 1.1, mt: 0.25 }}>\n {value}\n </Typography>\n )}\n </Box>\n );\n}\nMetricCell.propTypes = {\n label: PropTypes.string,\n value: PropTypes.node,\n loading: PropTypes.bool,\n};\n\nfunction WorkspaceCard({ workspace, metrics, loading, onItemClick }) {\n const theme = useTheme();\n const Icon = workspace.icon;\n\n return (\n <Card\n sx={{\n borderRadius: 1.5,\n height: '100%',\n position: 'relative',\n overflow: 'hidden',\n border: `1px solid ${alpha(workspace.accent, 0.18)}`,\n background: `linear-gradient(180deg, ${alpha(workspace.accent, 0.06)} 0%, ${alpha(theme.palette.background.paper, 1)} 35%)`,\n boxShadow: `0 16px 36px ${alpha(workspace.accent, 0.08)}`,\n transition: 'transform 240ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow 240ms',\n '&:hover': {\n transform: 'translateY(-3px)',\n boxShadow: `0 22px 50px ${alpha(workspace.accent, 0.18)}`,\n },\n // Accent strip across the very top.\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n left: 0,\n right: 0,\n top: 0,\n height: 4,\n background: `linear-gradient(90deg, ${workspace.accent} 0%, ${workspace.accentDark} 100%)`,\n },\n }}\n >\n <CardContent sx={{ pt: 3, display: 'flex', flexDirection: 'column', height: '100%' }}>\n <Stack direction=\"row\" alignItems=\"center\" spacing={1.5}>\n <Box\n sx={{\n width: 44,\n height: 44,\n borderRadius: 1.5,\n display: 'grid',\n placeItems: 'center',\n color: '#fff',\n background: `linear-gradient(135deg, ${workspace.accent} 0%, ${workspace.accentDark} 100%)`,\n boxShadow: `0 8px 18px ${alpha(workspace.accent, 0.3)}`,\n }}\n >\n <Icon sx={{ fontSize: 24 }} />\n </Box>\n <Box sx={{ flexGrow: 1, minWidth: 0 }}>\n <Typography variant=\"overline\" sx={{ color: workspace.accentDark, fontWeight: 800, letterSpacing: 1.1, lineHeight: 1 }}>\n Workspace\n </Typography>\n <Typography variant=\"h6\" sx={{ fontWeight: 800, lineHeight: 1.2 }}>\n {workspace.label}\n </Typography>\n </Box>\n </Stack>\n\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mt: 1.5, mb: 2 }}>\n {workspace.description}\n </Typography>\n\n {/* Quick stats */}\n {metrics?.length ? (\n <Stack direction=\"row\" spacing={3} sx={{ mb: 2.5 }}>\n {metrics.map((m) => (\n <MetricCell key={m.label} label={m.label} value={m.value} loading={loading} />\n ))}\n </Stack>\n ) : null}\n\n {/* Sub-item quick access — clickable chips */}\n <Box sx={{ mt: 'auto' }}>\n <Stack direction=\"row\" spacing={1} flexWrap=\"wrap\" useFlexGap>\n {workspace.items.map((it) => {\n const ItemIcon = it.icon;\n return (\n <Chip\n key={it.id}\n icon={ItemIcon ? <ItemIcon sx={{ fontSize: '1rem !important', color: `${workspace.accentDark} !important` }} /> : undefined}\n label={it.label}\n onClick={() => onItemClick(it)}\n sx={{\n borderRadius: 2,\n fontWeight: 700,\n backgroundColor: alpha(workspace.accent, 0.08),\n color: workspace.accentDark,\n border: `1px solid ${alpha(workspace.accent, 0.18)}`,\n transition: 'all 180ms ease',\n '&:hover': {\n backgroundColor: alpha(workspace.accent, 0.18),\n transform: 'translateY(-1px)',\n },\n }}\n />\n );\n })}\n </Stack>\n </Box>\n </CardContent>\n </Card>\n );\n}\nWorkspaceCard.propTypes = {\n workspace: PropTypes.object.isRequired,\n metrics: PropTypes.array,\n loading: PropTypes.bool,\n onItemClick: PropTypes.func.isRequired,\n};\n\nexport default function DashboardPage() {\n const navigate = useNavigate();\n const theme = useTheme();\n const settings = usePmSettings();\n const perms = usePmPermissions();\n const cur = currencySymbol(settings?.currencyCode);\n // Same filter PmNav uses — only workspaces with at least one accessible\n // (perm-granted, not-hidden-by-settings) item show as cards.\n const visibleWorkspaces = getVisibleWorkspaces(perms, settings);\n const showLedgerActivity = perms.has('view.manage.productManagement.ledger');\n const [loading, setLoading] = useState(true);\n const [data, setData] = useState({\n categories: 0, brands: 0, products: 0,\n batches: 0, openVials: 0, sales: 0, payments: 0,\n txns: [],\n });\n\n async function load() {\n setLoading(true);\n try {\n // Each fetch is gated by its own view perm. A user with only the\n // ledger perm fires the transactions call alone — every other tile\n // stays at zero and the page never touches the corresponding API.\n // .catch returns [] so a backend 403 (e.g. perm just revoked) still\n // renders the dashboard with zeroes rather than crashing.\n const gate = (perm, fn) => perms.has(perm) ? fn().catch(() => []) : Promise.resolve([]);\n const [cats, brands, products, batches, vials, sales, payments, txns] = await Promise.all([\n gate('view.manage.productManagement.category', () => getCategories()),\n gate('view.manage.productManagement.brand', () => getBrands()),\n gate('view.manage.productManagement.product', () => getProducts()),\n gate('view.manage.productManagement.inventory', () => listBatches()),\n gate('view.manage.productManagement.vial', () => listOpenVials()),\n gate('view.manage.productManagement.sale', () => listSales(0, 100)),\n gate('view.manage.productManagement.payment', () => listPayments(0, 100)),\n gate('view.manage.productManagement.ledger', () => listTransactions(0, 8)),\n ]);\n setData({\n categories: cats.length,\n brands: brands.length,\n products: products.length,\n batches: batches.length,\n openVials: vials.length,\n sales: sales.length,\n payments: payments.length,\n txns,\n });\n } finally {\n setLoading(false);\n }\n }\n\n // Root module perm gates the dashboard's entire fetch pass; each call\n // inside `load()` does its own per-feature perm check on top.\n usePermissionedEffect('view.manage.productManagement', () => {\n void load();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const metricsByWorkspace = {\n catalog: [\n { label: 'Categories', value: data.categories },\n { label: 'Brands', value: data.brands },\n { label: 'Products', value: data.products },\n ],\n operations: [\n { label: 'Batches', value: data.batches },\n { label: 'Open vials', value: data.openVials },\n { label: 'Sales', value: data.sales },\n ],\n ledger: [\n { label: 'Recent', value: data.txns.length },\n ],\n };\n\n return (\n <Box>\n <PmNav />\n <PmGuard perm={'view.manage.productManagement'}>\n <PmPageShell\n title=\"Product Management\"\n subtitle=\"Choose where to start. Use Catalog to set up, Operations for daily work, and Ledger to review history.\"\n chips={['Generic', 'Vaccine-aware', 'Ledger-driven']}\n >\n {loading ? <LinearProgress sx={{ mb: 2, borderRadius: 1 }} /> : null}\n\n <Grid container spacing={2.5}>\n {visibleWorkspaces.map((ws, idx) => (\n <Grid item xs={12} md={4} key={ws.id}>\n <Grow in timeout={420} style={{ transitionDelay: `${idx * 80}ms` }}>\n <Box sx={{ height: '100%' }}>\n <WorkspaceCard\n workspace={ws}\n metrics={metricsByWorkspace[ws.id]}\n loading={loading}\n onItemClick={(it) => navigate(it.path)}\n />\n </Box>\n </Grow>\n </Grid>\n ))}\n </Grid>\n\n {/* Recent stock activity — last 8 ledger entries with semantic colour.\n Hidden when the user can't access the ledger; the underlying\n transactions API would 403 anyway. */}\n {showLedgerActivity ? (\n <Card sx={{ borderRadius: 1.5, mt: 3, boxShadow: `0 12px 32px ${alpha(theme.palette.common.black, 0.05)}` }}>\n <CardContent>\n <Stack direction=\"row\" justifyContent=\"space-between\" alignItems=\"center\" sx={{ mb: 1.5 }}>\n <Box>\n <Typography variant=\"overline\" sx={{ color: 'text.secondary', fontWeight: 800, letterSpacing: 1 }}>\n Stock Ledger\n </Typography>\n <Typography variant=\"h6\" sx={{ fontWeight: 800, lineHeight: 1.2 }}>\n Recent activity\n </Typography>\n </Box>\n <Chip\n clickable\n icon={<ArrowForwardRoundedIcon sx={{ fontSize: '1rem !important' }} />}\n label=\"View ledger\"\n onClick={() => navigate('/ui/medplat/manage/pm/transactions')}\n sx={{\n borderRadius: 2, fontWeight: 700,\n bgcolor: alpha(theme.palette.primary.main, 0.08),\n color: 'primary.dark',\n '&:hover': { bgcolor: alpha(theme.palette.primary.main, 0.16) },\n }}\n />\n </Stack>\n\n {data.txns.length === 0 && !loading ? (\n <Typography variant=\"body2\" color=\"text.secondary\">No activity yet — record a purchase or a sale to see entries here.</Typography>\n ) : (\n <Stack divider={<Box sx={{ borderTop: `1px dashed ${theme.palette.divider}` }} />} spacing={0}>\n {(loading ? Array.from({ length: 4 }) : data.txns).map((t, i) => (\n <Box key={t?.id ?? i} sx={{\n display: 'flex', justifyContent: 'space-between', alignItems: 'center',\n py: 1.25, gap: 2,\n }}>\n <Stack direction=\"row\" alignItems=\"center\" spacing={1.5} sx={{ minWidth: 0 }}>\n {loading ? (\n <Skeleton variant=\"rounded\" width={92} height={22} />\n ) : (\n <Chip\n size=\"small\"\n label={t.transactionType}\n color={TXN_COLOR[t.transactionType] || 'default'}\n sx={{ fontWeight: 700, borderRadius: 1.5, height: 22 }}\n />\n )}\n <Box sx={{ minWidth: 0 }}>\n {loading ? (\n <Skeleton width={220} height={20} />\n ) : (\n <Typography variant=\"body2\" sx={{ fontWeight: 700, lineHeight: 1.2 }} noWrap>\n {t.productName || '—'}\n {t.lotNumber ? (\n <Typography component=\"span\" variant=\"body2\" color=\"text.secondary\" sx={{ fontFamily: 'monospace', ml: 1 }}>\n lot {t.lotNumber}\n </Typography>\n ) : null}\n </Typography>\n )}\n {loading ? (\n <Skeleton width={120} height={16} />\n ) : (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {formatDateTime(t.transactionTime)}\n </Typography>\n )}\n </Box>\n </Stack>\n\n <Box sx={{ textAlign: 'right', whiteSpace: 'nowrap' }}>\n {loading ? (\n <Skeleton width={70} height={20} />\n ) : (\n <Typography variant=\"body2\" sx={{ fontWeight: 800, fontVariantNumeric: 'tabular-nums' }}>\n {t.quantity != null ? `qty ${t.quantity}` : ''}\n {t.volumeMl != null ? `${t.quantity != null ? ' · ' : ''}${formatNumber(t.volumeMl)} ml` : ''}\n {t.monetaryAmount != null ? `${(t.quantity != null || t.volumeMl != null) ? ' · ' : ''}${cur}${formatNumber(t.monetaryAmount)}` : ''}\n </Typography>\n )}\n </Box>\n </Box>\n ))}\n </Stack>\n )}\n </CardContent>\n </Card>\n ) : null}\n </PmPageShell>\n </PmGuard>\n </Box>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { O as e, h as t } from "./settingsStore-KW217unV.js";
|
|
2
2
|
import { useEffect as n, useMemo as r, useState as i } from "react";
|
|
3
3
|
import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
4
4
|
import { Autocomplete as c, CircularProgress as l, TextField as u } from "@mui/material";
|
|
@@ -76,4 +76,4 @@ function d({ value: d, onChange: f, label: p = "Facility", required: m = !1, dis
|
|
|
76
76
|
//#endregion
|
|
77
77
|
export { d as t };
|
|
78
78
|
|
|
79
|
-
//# sourceMappingURL=FacilityPicker-
|
|
79
|
+
//# sourceMappingURL=FacilityPicker-Diq2hnYg.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FacilityPicker-
|
|
1
|
+
{"version":3,"file":"FacilityPicker-Diq2hnYg.js","names":[],"sources":["../src/components/FacilityPicker.jsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport { Autocomplete, CircularProgress, TextField } from '@mui/material';\nimport { getFacilitiesByIds, listFacilities } from '@pm/services/pmApi';\n\n// Synchronous facility picker. The backend now scopes /pm/facilities to the\n// current operator's assigned set (joined off user_health_infrastructure),\n// which is small — typically a handful of facilities — so we just fetch the\n// whole list once and let MUI's default client-side filter handle search.\n//\n// `value` is the facility id (string). Editing a saved row whose facility is\n// no longer in the assigned set (e.g. assignment was revoked) is supported\n// via /facilities/by-ids hydration so the picker still shows a name.\nexport default function FacilityPicker({\n value,\n onChange,\n label = 'Facility',\n required = false,\n disabled = false,\n error = false,\n helperText = '',\n onBlur,\n size = 'small',\n fullWidth = true,\n}) {\n const [open, setOpen] = useState(false);\n const [facilities, setFacilities] = useState([]);\n const [loading, setLoading] = useState(false);\n const [loaded, setLoaded] = useState(false);\n const [selectedFacility, setSelectedFacility] = useState(null);\n\n // Hydrate the selected facility's name when `value` changes. Tries the\n // already-loaded assigned list first, then /by-ids as a fallback so a\n // facility that's no longer assigned still resolves to a name on edit.\n useEffect(() => {\n if (!value) {\n setSelectedFacility(null);\n return undefined;\n }\n if (selectedFacility?.id === value) return undefined;\n const fromAssigned = facilities.find((f) => f.id === value);\n if (fromAssigned) {\n setSelectedFacility(fromAssigned);\n return undefined;\n }\n let cancelled = false;\n (async () => {\n try {\n const found = await getFacilitiesByIds([value]);\n if (!cancelled && found[0]) setSelectedFacility(found[0]);\n } catch {\n // Leave the picker showing a raw id rather than crashing — operator\n // can still re-pick.\n }\n })();\n return () => { cancelled = true; };\n // facilities is intentionally excluded from the dep array so the picker\n // doesn't re-hydrate every time the list loads; the in-list lookup runs\n // synchronously on each render anyway.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value]);\n\n // Load the assigned-facility list once on first open. The list isn't huge\n // and the backend scopes it; no point in pre-fetching at mount.\n useEffect(() => {\n if (!open || loaded) return undefined;\n let cancelled = false;\n setLoading(true);\n (async () => {\n try {\n const rows = await listFacilities();\n if (!cancelled) setFacilities(rows);\n } catch {\n if (!cancelled) setFacilities([]);\n } finally {\n if (!cancelled) {\n setLoading(false);\n setLoaded(true);\n }\n }\n })();\n return () => { cancelled = true; };\n }, [open, loaded]);\n\n // Make sure the currently-selected facility is in the option set so the\n // Autocomplete can render its label without an out-of-range warning.\n const displayedOptions = useMemo(() => {\n if (!selectedFacility) return facilities;\n if (facilities.some((o) => o.id === selectedFacility.id)) return facilities;\n return [selectedFacility, ...facilities];\n }, [facilities, selectedFacility]);\n\n const noOptionsText = loading\n ? 'Loading…'\n : loaded && facilities.length === 0\n ? 'No facilities assigned to your account'\n : 'No matches';\n\n const defaultHelper = 'Only facilities assigned to your account are shown. Type to filter.';\n\n return (\n <Autocomplete\n size={size}\n fullWidth={fullWidth}\n disabled={disabled}\n open={open}\n onOpen={() => setOpen(true)}\n onClose={() => setOpen(false)}\n value={selectedFacility}\n isOptionEqualToValue={(a, b) => a?.id === b?.id}\n getOptionLabel={(o) => o?.name ?? ''}\n options={displayedOptions}\n loading={loading}\n onChange={(_, next) => {\n setSelectedFacility(next ?? null);\n onChange?.(next?.id ?? '');\n }}\n noOptionsText={noOptionsText}\n renderInput={(params) => (\n <TextField\n {...params}\n required={required}\n label={label}\n error={error}\n helperText={helperText || defaultHelper}\n onBlur={onBlur}\n InputProps={{\n ...params.InputProps,\n endAdornment: (\n <>\n {loading ? <CircularProgress color=\"inherit\" size={16} /> : null}\n {params.InputProps.endAdornment}\n </>\n ),\n }}\n />\n )}\n />\n );\n}\n"],"mappings":";;;;;AAYA,SAAwB,EAAe,EACrC,UACA,aACA,WAAQ,YACR,cAAW,IACX,cAAW,IACX,WAAQ,IACR,gBAAa,IACb,WACA,UAAO,SACP,eAAY,MACX;CACD,IAAM,CAAC,GAAM,KAAW,EAAS,EAAK,GAChC,CAAC,GAAY,KAAiB,EAAS,CAAC,CAAC,GACzC,CAAC,GAAS,KAAc,EAAS,EAAK,GACtC,CAAC,GAAQ,KAAa,EAAS,EAAK,GACpC,CAAC,GAAkB,KAAuB,EAAS,IAAI;CAuE7D,OAlEA,QAAgB;EACd,IAAI,CAAC,GAAO;GACV,EAAoB,IAAI;GACxB;EACF;EACA,IAAI,GAAkB,OAAO,GAAO;EACpC,IAAM,IAAe,EAAW,MAAM,MAAM,EAAE,OAAO,CAAK;EAC1D,IAAI,GAAc;GAChB,EAAoB,CAAY;GAChC;EACF;EACA,IAAI,IAAY;EAUhB,QATC,YAAY;GACX,IAAI;IACF,IAAM,IAAQ,MAAM,EAAmB,CAAC,CAAK,CAAC;IAC9C,AAAI,CAAC,KAAa,EAAM,MAAI,EAAoB,EAAM,EAAE;GAC1D,QAAQ,CAGR;EACF,GAAG,SACU;GAAE,IAAY;EAAM;CAKnC,GAAG,CAAC,CAAK,CAAC,GAIV,QAAgB;EACd,IAAI,CAAC,KAAQ,GAAQ;EACrB,IAAI,IAAY;EAehB,OAdA,EAAW,EAAI,IACd,YAAY;GACX,IAAI;IACF,IAAM,IAAO,MAAM,EAAe;IAClC,AAAK,KAAW,EAAc,CAAI;GACpC,QAAQ;IACN,AAAK,KAAW,EAAc,CAAC,CAAC;GAClC,UAAU;IACR,AAAK,MACH,EAAW,EAAK,GAChB,EAAU,EAAI;GAElB;EACF,GAAG,SACU;GAAE,IAAY;EAAM;CACnC,GAAG,CAAC,GAAM,CAAM,CAAC,GAmBf,kBAAC,GAAD;EACQ;EACK;EACD;EACJ;EACN,cAAc,EAAQ,EAAI;EAC1B,eAAe,EAAQ,EAAK;EAC5B,OAAO;EACP,uBAAuB,GAAG,MAAM,GAAG,OAAO,GAAG;EAC7C,iBAAiB,MAAM,GAAG,QAAQ;EAClC,SAzBqB,QACnB,CAAC,KACD,EAAW,MAAM,MAAM,EAAE,OAAO,EAAiB,EAAE,IAAU,IAC1D,CAAC,GAAkB,GAAG,CAAU,GACtC,CAAC,GAAY,CAAgB,CAqBnB;EACA;EACT,WAAW,GAAG,MAAS;GAErB,AADA,EAAoB,KAAQ,IAAI,GAChC,IAAW,GAAM,MAAM,EAAE;EAC3B;EACe,eAzBG,IAClB,aACA,KAAU,EAAW,WAAW,IAC9B,2CACA;EAsBF,cAAc,MACZ,kBAAC,GAAD;GACE,GAAI;GACM;GACH;GACA;GACP,YAAY,KAAc;GAClB;GACR,YAAY;IACV,GAAG,EAAO;IACV,cACE,kBAAA,GAAA,EAAA,UAAA,CACG,IAAU,kBAAC,GAAD;KAAkB,OAAM;KAAU,MAAM;IAAK,CAAA,IAAI,MAC3D,EAAO,WAAW,YACnB,EAAA,CAAA;GAEN;EACD,CAAA;CAEJ,CAAA;AAEL"}
|