@argusoft/medplat-product-management 1.0.3 → 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-NSvaMXWg.js → BrandsPage-BE3kn-8b.js} +79 -78
- package/dist/{BrandsPage-NSvaMXWg.js.map → BrandsPage-BE3kn-8b.js.map} +1 -1
- package/dist/{CategoriesPage-aZBZrDOi.js → CategoriesPage-COqi3pMi.js} +70 -69
- package/dist/{CategoriesPage-aZBZrDOi.js.map → CategoriesPage-COqi3pMi.js.map} +1 -1
- package/dist/{DashboardPage-DjwlOhrd.js → DashboardPage-C_H1Jrey.js} +91 -90
- package/dist/{DashboardPage-DjwlOhrd.js.map → DashboardPage-C_H1Jrey.js.map} +1 -1
- package/dist/{FacilityPicker-Chh-ZaR0.js → FacilityPicker-Diq2hnYg.js} +2 -2
- package/dist/{FacilityPicker-Chh-ZaR0.js.map → FacilityPicker-Diq2hnYg.js.map} +1 -1
- package/dist/{InventoryPage-cy76UsMp.js → InventoryPage-Bjpw6vTz.js} +113 -112
- package/dist/{InventoryPage-cy76UsMp.js.map → InventoryPage-Bjpw6vTz.js.map} +1 -1
- package/dist/{MemberProfileCard-CinPt09F.js → MemberProfileCard-BLUVRILO.js} +6 -5
- package/dist/{MemberProfileCard-CinPt09F.js.map → MemberProfileCard-BLUVRILO.js.map} +1 -1
- package/dist/{PaymentCreatePage-BJe3LyFF.js → PaymentCreatePage-B5VOgTx9.js} +125 -124
- package/dist/{PaymentCreatePage-BJe3LyFF.js.map → PaymentCreatePage-B5VOgTx9.js.map} +1 -1
- package/dist/{PaymentsPage-DxHoKksN.js → PaymentsPage-DY6BclkN.js} +21 -20
- package/dist/{PaymentsPage-DxHoKksN.js.map → PaymentsPage-DY6BclkN.js.map} +1 -1
- package/dist/{PickupCreatePage-Cq8zJ62Y.js → PickupCreatePage-CCSiyFQF.js} +63 -62
- package/dist/{PickupCreatePage-Cq8zJ62Y.js.map → PickupCreatePage-CCSiyFQF.js.map} +1 -1
- package/dist/{PickupsPage-BOygBQAb.js → PickupsPage-DGi6T5Of.js} +42 -41
- package/dist/{PickupsPage-BOygBQAb.js.map → PickupsPage-DGi6T5Of.js.map} +1 -1
- package/dist/PmGuard-C90yhpsN.js +592 -0
- package/dist/PmGuard-C90yhpsN.js.map +1 -0
- package/dist/{PmTable-CCpaJEA_.js → PmTable-BkK65bJQ.js} +96 -96
- package/dist/{PmTable-CCpaJEA_.js.map → PmTable-BkK65bJQ.js.map} +1 -1
- package/dist/{ProductEditPage-DmdHO-fS.js → ProductEditPage-CQj9egzW.js} +130 -129
- package/dist/{ProductEditPage-DmdHO-fS.js.map → ProductEditPage-CQj9egzW.js.map} +1 -1
- package/dist/{ProductsPage-BglMe8EM.js → ProductsPage-i8QVw_Jm.js} +64 -63
- package/dist/{ProductsPage-BglMe8EM.js.map → ProductsPage-i8QVw_Jm.js.map} +1 -1
- package/dist/{PurchaseCreatePage-1tYk41RS.js → PurchaseCreatePage-Bp6bl9n8.js} +120 -119
- package/dist/{PurchaseCreatePage-1tYk41RS.js.map → PurchaseCreatePage-Bp6bl9n8.js.map} +1 -1
- package/dist/{PurchaseRequestDetailPage-BYLx3aBI.js → PurchaseRequestDetailPage-CNAqIFef.js} +216 -215
- package/dist/{PurchaseRequestDetailPage-BYLx3aBI.js.map → PurchaseRequestDetailPage-CNAqIFef.js.map} +1 -1
- package/dist/{PurchaseRequestsPage-D2yorc4s.js → PurchaseRequestsPage-BJqDlNrc.js} +57 -56
- package/dist/{PurchaseRequestsPage-D2yorc4s.js.map → PurchaseRequestsPage-BJqDlNrc.js.map} +1 -1
- package/dist/{PurchasesPage-CanQTjlw.js → PurchasesPage-BQEToymQ.js} +76 -75
- package/dist/{PurchasesPage-CanQTjlw.js.map → PurchasesPage-BQEToymQ.js.map} +1 -1
- package/dist/{SaleCreatePage-DxFvPvju.js → SaleCreatePage-DbfBK4PH.js} +89 -88
- package/dist/{SaleCreatePage-DxFvPvju.js.map → SaleCreatePage-DbfBK4PH.js.map} +1 -1
- package/dist/{SalesPage-CPMrdr5-.js → SalesPage-CTBJMxZe.js} +46 -45
- package/dist/{SalesPage-CPMrdr5-.js.map → SalesPage-CTBJMxZe.js.map} +1 -1
- package/dist/{SettingsPage-CEy922rW.js → SettingsPage-CiwVmzM3.js} +47 -46
- package/dist/{SettingsPage-CEy922rW.js.map → SettingsPage-CiwVmzM3.js.map} +1 -1
- package/dist/{StorageUnitsPage-DfLT6xC_.js → StorageUnitsPage-BV7nK_iE.js} +55 -54
- package/dist/{StorageUnitsPage-DfLT6xC_.js.map → StorageUnitsPage-BV7nK_iE.js.map} +1 -1
- package/dist/{TransactionsPage-KFUJ4O5g.js → TransactionsPage-Cocn4901.js} +54 -53
- package/dist/{TransactionsPage-KFUJ4O5g.js.map → TransactionsPage-Cocn4901.js.map} +1 -1
- package/dist/{TransferCreatePage-k1tsRGB3.js → TransferCreatePage-DbjcjuOg.js} +74 -73
- package/dist/{TransferCreatePage-k1tsRGB3.js.map → TransferCreatePage-DbjcjuOg.js.map} +1 -1
- package/dist/{TransfersPage-CDafSVO9.js → TransfersPage-BFVF7Xvc.js} +108 -107
- package/dist/{TransfersPage-CDafSVO9.js.map → TransfersPage-BFVF7Xvc.js.map} +1 -1
- 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/VialsPage-DPsYFgaQ.js +0 -897
- package/dist/VialsPage-DPsYFgaQ.js.map +0 -1
- package/dist/currency-bVQ7aEk2.js +0 -1007
- package/dist/currency-bVQ7aEk2.js.map +0 -1
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { c as
|
|
3
|
-
import {
|
|
4
|
-
import { t as
|
|
5
|
-
import {
|
|
6
|
-
import { t as l } from "./
|
|
1
|
+
import { T as e, h as t, tt as n } from "./settingsStore-KW217unV.js";
|
|
2
|
+
import { c as r, o as i, s as ee, t as te } from "./PmTable-BkK65bJQ.js";
|
|
3
|
+
import { o as a, p as ne } from "./constants-5ZCZo-Zm.js";
|
|
4
|
+
import { h as re, m as o, n as ie, t as ae } from "./validation-Ba7puFIO.js";
|
|
5
|
+
import { t as oe } from "./useFieldErrors-hDG8ox_x.js";
|
|
6
|
+
import { a as se, i as ce, n as s, r as c, t as l } from "./PmGuard-C90yhpsN.js";
|
|
7
|
+
import { t as le } from "./FacilityPicker-Diq2hnYg.js";
|
|
7
8
|
import { useState as u } from "react";
|
|
8
9
|
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
10
|
+
import { Alert as ue, Box as p, Button as m, Checkbox as de, Chip as h, Dialog as g, DialogActions as fe, DialogContent as pe, DialogTitle as me, Divider as _, FormControlLabel as v, Skeleton as he, Stack as y, TableBody as ge, TableCell as b, TableHead as _e, TableRow as x, TextField as S, Typography as C } from "@mui/material";
|
|
11
|
+
import { showToast as w } from "@/common/toaster/toaster";
|
|
12
|
+
import { v4 as ve } from "uuid";
|
|
13
|
+
import T from "@mui/icons-material/AddRounded";
|
|
12
14
|
import ye from "@mui/icons-material/RefreshRounded";
|
|
13
|
-
import { showToast as T } from "@/common/toaster/toaster";
|
|
14
15
|
import E from "@/views/custom-components/CustomSwitch";
|
|
15
16
|
import D from "@mui/icons-material/WarehouseRounded";
|
|
16
17
|
//#region src/views/StorageUnitsPage.jsx
|
|
@@ -19,7 +20,7 @@ var O = [{
|
|
|
19
20
|
label: "Facility"
|
|
20
21
|
}];
|
|
21
22
|
function k() {
|
|
22
|
-
let k =
|
|
23
|
+
let k = ce().has("update.manage.productManagement.storageUnit"), [A, j] = u([]), [M, N] = u({}), [P, F] = u(!1), [I, L] = u(""), [be, R] = u(!1), [z, B] = u(null), [V, H] = u(G()), [U, xe] = u(!1), W = oe();
|
|
23
24
|
function G() {
|
|
24
25
|
return {
|
|
25
26
|
id: "",
|
|
@@ -39,12 +40,12 @@ function k() {
|
|
|
39
40
|
async function K() {
|
|
40
41
|
F(!0), L("");
|
|
41
42
|
try {
|
|
42
|
-
let
|
|
43
|
-
j(
|
|
44
|
-
let
|
|
45
|
-
if (
|
|
43
|
+
let n = await e({ activeOnly: !1 });
|
|
44
|
+
j(n);
|
|
45
|
+
let r = Array.from(new Set(n.map((e) => e.ownerId).filter(Boolean)));
|
|
46
|
+
if (r.length === 0) N({});
|
|
46
47
|
else try {
|
|
47
|
-
let e = await
|
|
48
|
+
let e = await t(r), n = {};
|
|
48
49
|
e.forEach((e) => {
|
|
49
50
|
n[e.id] = e.name;
|
|
50
51
|
}), N(n);
|
|
@@ -53,7 +54,7 @@ function k() {
|
|
|
53
54
|
}
|
|
54
55
|
} catch (e) {
|
|
55
56
|
let t = e?.response?.data?.message ?? e?.message ?? "Failed to load storage units";
|
|
56
|
-
L(t),
|
|
57
|
+
L(t), w({
|
|
57
58
|
message: t,
|
|
58
59
|
type: "error"
|
|
59
60
|
});
|
|
@@ -61,7 +62,7 @@ function k() {
|
|
|
61
62
|
F(!1);
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
+
c("view.manage.productManagement.storageUnit", () => {
|
|
65
66
|
K();
|
|
66
67
|
}, []);
|
|
67
68
|
function Se(e) {
|
|
@@ -70,7 +71,7 @@ function k() {
|
|
|
70
71
|
function q() {
|
|
71
72
|
B(null), H({
|
|
72
73
|
...G(),
|
|
73
|
-
id:
|
|
74
|
+
id: ve()
|
|
74
75
|
}), W.reset(), L(""), R(!0);
|
|
75
76
|
}
|
|
76
77
|
function Ce(e) {
|
|
@@ -89,22 +90,22 @@ function k() {
|
|
|
89
90
|
isActive: e.isActive !== !1
|
|
90
91
|
}), R(!0);
|
|
91
92
|
}
|
|
92
|
-
let J =
|
|
93
|
-
ownerType:
|
|
94
|
-
ownerId:
|
|
95
|
-
unitName:
|
|
93
|
+
let J = re(V.operatingTempMinCelsius, V.operatingTempMaxCelsius), Y = ie(V.unitCode, { required: !0 }), X = (V.unitCode || "").trim().toUpperCase(), we = !Y && X && V.ownerId && A.some((e) => e.id !== V.id && e.ownerId === V.ownerId && (e.unitCode || "").toUpperCase() === X), Z = {
|
|
94
|
+
ownerType: o(V.ownerType, "Owner type"),
|
|
95
|
+
ownerId: o(V.ownerId, "Facility"),
|
|
96
|
+
unitName: o(V.unitName, "Name"),
|
|
96
97
|
unitCode: Y || (we ? "Code is already in use for this facility." : ""),
|
|
97
|
-
unitType:
|
|
98
|
+
unitType: o(V.unitType, "Type"),
|
|
98
99
|
operatingTempMinCelsius: J.min,
|
|
99
100
|
operatingTempMaxCelsius: J.max
|
|
100
|
-
}, Q =
|
|
101
|
+
}, Q = ae(Z);
|
|
101
102
|
async function Te() {
|
|
102
103
|
if (!Q) {
|
|
103
104
|
W.markAllTouched(), L("Please fix the highlighted fields.");
|
|
104
105
|
return;
|
|
105
106
|
}
|
|
106
107
|
try {
|
|
107
|
-
await
|
|
108
|
+
await n({
|
|
108
109
|
id: V.id,
|
|
109
110
|
ownerId: V.ownerId,
|
|
110
111
|
unitName: V.unitName.trim(),
|
|
@@ -116,45 +117,45 @@ function k() {
|
|
|
116
117
|
operatingTempMinCelsius: V.operatingTempMinCelsius === "" ? null : Number(V.operatingTempMinCelsius),
|
|
117
118
|
operatingTempMaxCelsius: V.operatingTempMaxCelsius === "" ? null : Number(V.operatingTempMaxCelsius),
|
|
118
119
|
isActive: V.isActive
|
|
119
|
-
}),
|
|
120
|
+
}), w({
|
|
120
121
|
message: "Storage unit saved.",
|
|
121
122
|
type: "success"
|
|
122
123
|
}), R(!1), await K();
|
|
123
124
|
} catch (e) {
|
|
124
125
|
let t = e?.response?.data?.message ?? e?.message ?? "Failed to save storage unit";
|
|
125
|
-
L(t),
|
|
126
|
+
L(t), w({
|
|
126
127
|
message: t,
|
|
127
128
|
type: "error"
|
|
128
129
|
});
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
132
|
let $ = U ? A : A.filter((e) => e.isActive !== !1);
|
|
132
|
-
return /* @__PURE__ */ f(
|
|
133
|
+
return /* @__PURE__ */ f(p, { children: [/* @__PURE__ */ d(s, {}), /* @__PURE__ */ f(l, {
|
|
133
134
|
perm: "view.manage.productManagement.storageUnit",
|
|
134
|
-
children: [/* @__PURE__ */ f(
|
|
135
|
+
children: [/* @__PURE__ */ f(se, {
|
|
135
136
|
title: "Storage Units",
|
|
136
137
|
subtitle: "Cold-chain equipment for storing vaccine and product batches. Currently managed per facility.",
|
|
137
138
|
chips: ["Catalog", "Facility-owned"],
|
|
138
139
|
actions: /* @__PURE__ */ f(y, {
|
|
139
140
|
direction: "row",
|
|
140
141
|
spacing: 1,
|
|
141
|
-
children: [/* @__PURE__ */ d(
|
|
142
|
+
children: [/* @__PURE__ */ d(m, {
|
|
142
143
|
variant: "outlined",
|
|
143
144
|
startIcon: /* @__PURE__ */ d(ye, {}),
|
|
144
145
|
onClick: () => void K(),
|
|
145
146
|
children: "Refresh"
|
|
146
|
-
}), k ? /* @__PURE__ */ d(
|
|
147
|
+
}), k ? /* @__PURE__ */ d(m, {
|
|
147
148
|
variant: "contained",
|
|
148
|
-
startIcon: /* @__PURE__ */ d(
|
|
149
|
+
startIcon: /* @__PURE__ */ d(T, {}),
|
|
149
150
|
onClick: q,
|
|
150
151
|
children: "New Storage Unit"
|
|
151
152
|
}) : null]
|
|
152
153
|
}),
|
|
153
|
-
children: [I ? /* @__PURE__ */ d(
|
|
154
|
+
children: [I ? /* @__PURE__ */ d(ue, {
|
|
154
155
|
severity: "error",
|
|
155
156
|
sx: { mb: 2 },
|
|
156
157
|
children: I
|
|
157
|
-
}) : null, /* @__PURE__ */ d(
|
|
158
|
+
}) : null, /* @__PURE__ */ d(r, {
|
|
158
159
|
eyebrow: "Cold-chain network",
|
|
159
160
|
title: "Storage units",
|
|
160
161
|
subtitle: P ? "Loading…" : `${$.length} ${$.length === 1 ? "unit" : "units"}`,
|
|
@@ -174,7 +175,7 @@ function k() {
|
|
|
174
175
|
ml: 0
|
|
175
176
|
}
|
|
176
177
|
}),
|
|
177
|
-
children: /* @__PURE__ */ f(
|
|
178
|
+
children: /* @__PURE__ */ f(ee, { children: [/* @__PURE__ */ d(_e, { children: /* @__PURE__ */ f(x, { children: [
|
|
178
179
|
/* @__PURE__ */ d(b, { children: "Code" }),
|
|
179
180
|
/* @__PURE__ */ d(b, { children: "Name" }),
|
|
180
181
|
/* @__PURE__ */ d(b, { children: "Facility" }),
|
|
@@ -185,22 +186,22 @@ function k() {
|
|
|
185
186
|
align: "right",
|
|
186
187
|
children: "Action"
|
|
187
188
|
})
|
|
188
|
-
] }) }), /* @__PURE__ */ d(
|
|
189
|
+
] }) }), /* @__PURE__ */ d(ge, { children: P ? Array.from({ length: 4 }).map((e, t) => /* @__PURE__ */ d(x, { children: Array.from({ length: 7 }).map((e, t) => /* @__PURE__ */ d(b, { children: /* @__PURE__ */ d(he, { height: 22 }) }, t)) }, t)) : $.length === 0 ? /* @__PURE__ */ d(te, {
|
|
189
190
|
colSpan: 7,
|
|
190
191
|
icon: D,
|
|
191
192
|
title: A.length === 0 ? "No storage units yet" : "No active storage units",
|
|
192
193
|
hint: A.length === 0 ? "You need storage equipment to keep vaccine batches safe." : "Turn on “Show inactive” to see deactivated storage units.",
|
|
193
|
-
action: A.length === 0 && k ? /* @__PURE__ */ d(
|
|
194
|
+
action: A.length === 0 && k ? /* @__PURE__ */ d(m, {
|
|
194
195
|
variant: "contained",
|
|
195
196
|
size: "small",
|
|
196
|
-
startIcon: /* @__PURE__ */ d(
|
|
197
|
+
startIcon: /* @__PURE__ */ d(T, {}),
|
|
197
198
|
onClick: q,
|
|
198
199
|
children: "Create first unit"
|
|
199
200
|
}) : null
|
|
200
201
|
}) : $.map((e) => /* @__PURE__ */ f(x, {
|
|
201
202
|
hover: !0,
|
|
202
203
|
children: [
|
|
203
|
-
/* @__PURE__ */ d(b, { children: /* @__PURE__ */ d(
|
|
204
|
+
/* @__PURE__ */ d(b, { children: /* @__PURE__ */ d(p, {
|
|
204
205
|
component: "span",
|
|
205
206
|
sx: {
|
|
206
207
|
display: "inline-flex",
|
|
@@ -224,9 +225,9 @@ function k() {
|
|
|
224
225
|
color: "text.secondary",
|
|
225
226
|
children: Se(e.ownerId)
|
|
226
227
|
}) }),
|
|
227
|
-
/* @__PURE__ */ d(b, { children: /* @__PURE__ */ d(
|
|
228
|
+
/* @__PURE__ */ d(b, { children: /* @__PURE__ */ d(h, {
|
|
228
229
|
size: "small",
|
|
229
|
-
label:
|
|
230
|
+
label: ne(a, e.unitType),
|
|
230
231
|
variant: "outlined",
|
|
231
232
|
sx: {
|
|
232
233
|
fontWeight: 700,
|
|
@@ -251,7 +252,7 @@ function k() {
|
|
|
251
252
|
color: "text.disabled",
|
|
252
253
|
children: "—"
|
|
253
254
|
}) }),
|
|
254
|
-
/* @__PURE__ */ d(b, { children: /* @__PURE__ */ d(
|
|
255
|
+
/* @__PURE__ */ d(b, { children: /* @__PURE__ */ d(h, {
|
|
255
256
|
size: "small",
|
|
256
257
|
label: e.isActive ? "Active" : "Inactive",
|
|
257
258
|
color: e.isActive ? "success" : "default",
|
|
@@ -264,7 +265,7 @@ function k() {
|
|
|
264
265
|
}) }),
|
|
265
266
|
/* @__PURE__ */ d(b, {
|
|
266
267
|
align: "right",
|
|
267
|
-
children: k ? /* @__PURE__ */ d(
|
|
268
|
+
children: k ? /* @__PURE__ */ d(m, {
|
|
268
269
|
size: "small",
|
|
269
270
|
variant: "outlined",
|
|
270
271
|
onClick: () => Ce(e),
|
|
@@ -274,7 +275,7 @@ function k() {
|
|
|
274
275
|
]
|
|
275
276
|
}, e.id)) })] })
|
|
276
277
|
})]
|
|
277
|
-
}), /* @__PURE__ */ f(
|
|
278
|
+
}), /* @__PURE__ */ f(g, {
|
|
278
279
|
open: be,
|
|
279
280
|
onClose: () => R(!1),
|
|
280
281
|
fullWidth: !0,
|
|
@@ -287,7 +288,7 @@ function k() {
|
|
|
287
288
|
spacing: 2,
|
|
288
289
|
sx: { pt: 1 },
|
|
289
290
|
children: [
|
|
290
|
-
/* @__PURE__ */ d(
|
|
291
|
+
/* @__PURE__ */ d(i, {
|
|
291
292
|
label: "Owner Type",
|
|
292
293
|
required: !0,
|
|
293
294
|
disabled: !!z,
|
|
@@ -302,7 +303,7 @@ function k() {
|
|
|
302
303
|
helperText: W.show("ownerType") && Z.ownerType ? Z.ownerType : "Only Facility is available currently.",
|
|
303
304
|
options: O
|
|
304
305
|
}),
|
|
305
|
-
/* @__PURE__ */ d(
|
|
306
|
+
/* @__PURE__ */ d(le, {
|
|
306
307
|
required: !0,
|
|
307
308
|
disabled: !!z || V.ownerType !== "FACILITY",
|
|
308
309
|
value: V.ownerId,
|
|
@@ -314,7 +315,7 @@ function k() {
|
|
|
314
315
|
error: W.show("ownerId") && !!Z.ownerId,
|
|
315
316
|
helperText: W.show("ownerId") && Z.ownerId ? Z.ownerId : "Search by name. The owner cannot be changed once created."
|
|
316
317
|
}),
|
|
317
|
-
/* @__PURE__ */ d(
|
|
318
|
+
/* @__PURE__ */ d(_, {}),
|
|
318
319
|
/* @__PURE__ */ d(S, {
|
|
319
320
|
required: !0,
|
|
320
321
|
label: "Unit name",
|
|
@@ -347,7 +348,7 @@ function k() {
|
|
|
347
348
|
error: W.show("unitCode") && !!Z.unitCode,
|
|
348
349
|
helperText: W.show("unitCode") && Z.unitCode ? Z.unitCode : "Auto-generated from the name. Edit if needed to make it unique within this facility."
|
|
349
350
|
}),
|
|
350
|
-
/* @__PURE__ */ d(
|
|
351
|
+
/* @__PURE__ */ d(i, {
|
|
351
352
|
label: "Type",
|
|
352
353
|
required: !0,
|
|
353
354
|
value: V.unitType,
|
|
@@ -357,7 +358,7 @@ function k() {
|
|
|
357
358
|
}),
|
|
358
359
|
onBlur: W.onBlur("unitType"),
|
|
359
360
|
error: W.show("unitType") && !!Z.unitType,
|
|
360
|
-
options:
|
|
361
|
+
options: a
|
|
361
362
|
}),
|
|
362
363
|
/* @__PURE__ */ f(y, {
|
|
363
364
|
direction: "row",
|
|
@@ -439,7 +440,7 @@ function k() {
|
|
|
439
440
|
helperText: "Notes about placement, maintenance schedule, or other details."
|
|
440
441
|
}),
|
|
441
442
|
/* @__PURE__ */ d(v, {
|
|
442
|
-
control: /* @__PURE__ */ d(
|
|
443
|
+
control: /* @__PURE__ */ d(de, {
|
|
443
444
|
checked: V.isActive,
|
|
444
445
|
onChange: (e) => H({
|
|
445
446
|
...V,
|
|
@@ -451,10 +452,10 @@ function k() {
|
|
|
451
452
|
]
|
|
452
453
|
})
|
|
453
454
|
}),
|
|
454
|
-
/* @__PURE__ */ f(fe, { children: [/* @__PURE__ */ d(
|
|
455
|
+
/* @__PURE__ */ f(fe, { children: [/* @__PURE__ */ d(m, {
|
|
455
456
|
onClick: () => R(!1),
|
|
456
457
|
children: "Cancel"
|
|
457
|
-
}), /* @__PURE__ */ d(
|
|
458
|
+
}), /* @__PURE__ */ d(m, {
|
|
458
459
|
variant: "contained",
|
|
459
460
|
disabled: !Q,
|
|
460
461
|
onClick: () => void Te(),
|
|
@@ -467,4 +468,4 @@ function k() {
|
|
|
467
468
|
//#endregion
|
|
468
469
|
export { k as default };
|
|
469
470
|
|
|
470
|
-
//# sourceMappingURL=StorageUnitsPage-
|
|
471
|
+
//# sourceMappingURL=StorageUnitsPage-BV7nK_iE.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageUnitsPage-DfLT6xC_.js","names":[],"sources":["../src/views/StorageUnitsPage.jsx"],"sourcesContent":["import { useState } from 'react';\nimport { v4 as uuidv4 } from 'uuid';\nimport {\n Alert,\n Box,\n Button,\n Checkbox,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Divider,\n FormControlLabel,\n Skeleton,\n Stack,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TextField,\n Typography,\n} from '@mui/material';\nimport AddRoundedIcon from '@mui/icons-material/AddRounded';\nimport RefreshRoundedIcon from '@mui/icons-material/RefreshRounded';\nimport WarehouseRoundedIcon from '@mui/icons-material/WarehouseRounded';\nimport { showToast } from '@/common/toaster/toaster';\nimport CustomSwitch from '@/views/custom-components/CustomSwitch';\nimport PmPageShell from '@pm/components/PmPageShell';\nimport PmNav from '@pm/components/PmNav';\nimport PmGuard from '@pm/components/PmGuard';\nimport { usePermissionedEffect, usePmPermissions } from '@pm/utils/permissions';\nimport { PmEmptyRow, PmSelect, PmTable, PmTableCard } from '@pm/components/PmTable';\nimport { STORAGE_UNIT_TYPES, labelOf } from '@pm/utils/constants';\nimport {\n getFacilitiesByIds,\n getStorageUnits,\n upsertStorageUnit,\n} from '@pm/services/pmApi';\nimport FacilityPicker from '@pm/components/FacilityPicker';\nimport {\n isClean,\n validateCode,\n validateRequired,\n validateTempRange,\n} from '@pm/utils/validation';\nimport { useFieldErrors } from '@pm/utils/useFieldErrors';\n\n// Today only FACILITY-owned storage units exist. The dropdown is kept so the\n// UI is ready for future owner kinds (REGIONAL_DEPOT, etc.) without a redesign.\nconst OWNER_TYPES = [{ value: 'FACILITY', label: 'Facility' }];\n\nexport default function StorageUnitsPage() {\n const perms = usePmPermissions();\n const canWrite = perms.has('update.manage.productManagement.storageUnit');\n const [items, setItems] = useState([]);\n // Map of facility id → name, hydrated for the ownerIds present on the\n // loaded storage units. Avoids loading the entire facility table just to\n // render the \"Facility\" column.\n const [facilityNames, setFacilityNames] = useState({});\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [openDialog, setOpenDialog] = useState(false);\n const [editing, setEditing] = useState(null);\n const [form, setForm] = useState(emptyForm());\n // Default to active-only; the toggle above the table reveals inactive rows.\n const [showInactive, setShowInactive] = useState(false);\n const fieldErrors = useFieldErrors();\n\n function emptyForm() {\n return {\n id: '',\n ownerType: 'FACILITY',\n ownerId: '',\n unitName: '',\n unitCode: '',\n unitType: 'REFRIGERATOR',\n make: '',\n model: '',\n comments: '',\n operatingTempMinCelsius: '',\n operatingTempMaxCelsius: '',\n isActive: true,\n };\n }\n\n async function load() {\n setLoading(true);\n setError('');\n try {\n const units = await getStorageUnits({ activeOnly: false });\n setItems(units);\n // Hydrate display names only for the facilities actually referenced\n // by the loaded units. Storage units are short — even the largest\n // deployment is a few hundred — so this is one cheap call.\n const ids = Array.from(new Set(units.map((u) => u.ownerId).filter(Boolean)));\n if (ids.length === 0) {\n setFacilityNames({});\n } else {\n try {\n const refs = await getFacilitiesByIds(ids);\n const map = {};\n refs.forEach((r) => { map[r.id] = r.name; });\n setFacilityNames(map);\n } catch {\n setFacilityNames({});\n }\n }\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to load storage units';\n setError(message);\n showToast({ message, type: 'error' });\n } finally {\n setLoading(false);\n }\n }\n\n usePermissionedEffect('view.manage.productManagement.storageUnit', () => {\n void load();\n }, []);\n\n function facilityNameFor(id) {\n return facilityNames[id] ?? id;\n }\n\n function openCreate() {\n setEditing(null);\n setForm({ ...emptyForm(), id: uuidv4() });\n fieldErrors.reset();\n setError('');\n setOpenDialog(true);\n }\n\n function openEdit(item) {\n setEditing(item);\n fieldErrors.reset();\n setError('');\n setForm({\n id: item.id,\n ownerType: item.ownerType ?? 'FACILITY',\n ownerId: item.ownerId ?? '',\n unitName: item.unitName ?? '',\n unitCode: item.unitCode ?? '',\n unitType: item.unitType ?? 'REFRIGERATOR',\n make: item.make ?? '',\n model: item.model ?? '',\n comments: item.comments ?? '',\n operatingTempMinCelsius: item.operatingTempMinCelsius ?? '',\n operatingTempMaxCelsius: item.operatingTempMaxCelsius ?? '',\n isActive: item.isActive !== false,\n });\n setOpenDialog(true);\n }\n\n const tempErrors = validateTempRange(form.operatingTempMinCelsius, form.operatingTempMaxCelsius);\n // Code uniqueness is enforced per facility in the DB. Mirror that scope here so\n // the operator gets the duplicate warning inline instead of as a 500 after save.\n const codeBase = validateCode(form.unitCode, { required: true });\n const codeNorm = (form.unitCode || '').trim().toUpperCase();\n const codeClash = !codeBase\n && codeNorm\n && form.ownerId\n && items.some((u) => u.id !== form.id\n && u.ownerId === form.ownerId\n && (u.unitCode || '').toUpperCase() === codeNorm);\n const formErrors = {\n ownerType: validateRequired(form.ownerType, 'Owner type'),\n ownerId: validateRequired(form.ownerId, 'Facility'),\n unitName: validateRequired(form.unitName, 'Name'),\n unitCode: codeBase || (codeClash ? 'Code is already in use for this facility.' : ''),\n unitType: validateRequired(form.unitType, 'Type'),\n operatingTempMinCelsius: tempErrors.min,\n operatingTempMaxCelsius: tempErrors.max,\n };\n const formIsValid = isClean(formErrors);\n\n async function save() {\n if (!formIsValid) {\n fieldErrors.markAllTouched();\n setError('Please fix the highlighted fields.');\n return;\n }\n try {\n await upsertStorageUnit({\n id: form.id,\n ownerId: form.ownerId,\n unitName: form.unitName.trim(),\n unitCode: form.unitCode.trim().toUpperCase(),\n unitType: form.unitType,\n make: form.make?.trim() || null,\n model: form.model?.trim() || null,\n comments: form.comments?.trim() || null,\n operatingTempMinCelsius: form.operatingTempMinCelsius === '' ? null : Number(form.operatingTempMinCelsius),\n operatingTempMaxCelsius: form.operatingTempMaxCelsius === '' ? null : Number(form.operatingTempMaxCelsius),\n isActive: form.isActive,\n });\n showToast({ message: 'Storage unit saved.', type: 'success' });\n setOpenDialog(false);\n await load();\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to save storage unit';\n setError(message);\n showToast({ message, type: 'error' });\n }\n }\n\n const visible = showInactive ? items : items.filter((u) => u.isActive !== false);\n\n return (\n <Box>\n <PmNav />\n <PmGuard perm={'view.manage.productManagement.storageUnit'}>\n <PmPageShell\n title=\"Storage Units\"\n subtitle=\"Cold-chain equipment for storing vaccine and product batches. Currently managed per facility.\"\n chips={['Catalog', 'Facility-owned']}\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"outlined\" startIcon={<RefreshRoundedIcon />} onClick={() => void load()}>Refresh</Button>\n {canWrite ? (\n <Button variant=\"contained\" startIcon={<AddRoundedIcon />} onClick={openCreate}>New Storage Unit</Button>\n ) : null}\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n <PmTableCard\n eyebrow=\"Cold-chain network\"\n title=\"Storage units\"\n subtitle={loading ? 'Loading…' : `${visible.length} ${visible.length === 1 ? 'unit' : 'units'}`}\n actions={\n <FormControlLabel\n control={<CustomSwitch checked={showInactive}\n onChange={(e) => setShowInactive(e.target.checked)} />}\n label={<Typography variant=\"body2\" sx={{ fontWeight: 600 }}>Show inactive</Typography>}\n labelPlacement=\"start\"\n sx={{ mr: 0.5, ml: 0 }}\n />\n }\n >\n <PmTable>\n <TableHead>\n <TableRow>\n <TableCell>Code</TableCell>\n <TableCell>Name</TableCell>\n <TableCell>Facility</TableCell>\n <TableCell>Type</TableCell>\n <TableCell>Operating range</TableCell>\n <TableCell>Status</TableCell>\n <TableCell align=\"right\">Action</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n Array.from({ length: 4 }).map((_, i) => (\n <TableRow key={i}>\n {Array.from({ length: 7 }).map((__, j) => (\n <TableCell key={j}><Skeleton height={22} /></TableCell>\n ))}\n </TableRow>\n ))\n ) : visible.length === 0 ? (\n <PmEmptyRow\n colSpan={7}\n icon={WarehouseRoundedIcon}\n title={items.length === 0 ? 'No storage units yet' : 'No active storage units'}\n hint={items.length === 0\n ? 'You need storage equipment to keep vaccine batches safe.'\n : 'Turn on “Show inactive” to see deactivated storage units.'}\n action={items.length === 0 && canWrite ? (\n <Button variant=\"contained\" size=\"small\" startIcon={<AddRoundedIcon />} onClick={openCreate}>\n Create first unit\n </Button>\n ) : null}\n />\n ) : visible.map((u) => (\n <TableRow key={u.id} hover>\n <TableCell>\n <Box component=\"span\" sx={{\n display: 'inline-flex', px: 0.85, py: 0.25, borderRadius: 1,\n bgcolor: 'grey.100', fontFamily: 'monospace', fontSize: '0.72rem', fontWeight: 800,\n }}>\n {u.unitCode}\n </Box>\n </TableCell>\n <TableCell><Typography variant=\"body2\" sx={{ fontWeight: 700 }}>{u.unitName}</Typography></TableCell>\n <TableCell><Typography variant=\"caption\" color=\"text.secondary\">{facilityNameFor(u.ownerId)}</Typography></TableCell>\n <TableCell>\n <Chip size=\"small\" label={labelOf(STORAGE_UNIT_TYPES, u.unitType)} variant=\"outlined\"\n sx={{ fontWeight: 700, borderRadius: 1.5, height: 22 }} />\n </TableCell>\n <TableCell>\n {u.operatingTempMinCelsius != null && u.operatingTempMaxCelsius != null ? (\n <Typography variant=\"caption\" sx={{ fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>\n {u.operatingTempMinCelsius}°C → {u.operatingTempMaxCelsius}°C\n </Typography>\n ) : <Typography variant=\"caption\" color=\"text.disabled\">—</Typography>}\n </TableCell>\n <TableCell>\n <Chip size=\"small\"\n label={u.isActive ? 'Active' : 'Inactive'}\n color={u.isActive ? 'success' : 'default'}\n variant={u.isActive ? 'filled' : 'outlined'}\n sx={{ fontWeight: 700, borderRadius: 1.5, height: 22 }} />\n </TableCell>\n <TableCell align=\"right\">\n {canWrite ? (\n <Button size=\"small\" variant=\"outlined\" onClick={() => openEdit(u)}>Edit</Button>\n ) : null}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </PmTable>\n </PmTableCard>\n </PmPageShell>\n\n <Dialog open={openDialog} onClose={() => setOpenDialog(false)} fullWidth maxWidth=\"sm\">\n <DialogTitle>{editing ? 'Edit Storage Unit' : 'New Storage Unit'}</DialogTitle>\n <DialogContent dividers>\n <Stack spacing={2} sx={{ pt: 1 }}>\n\n {/* ------- Ownership: who this storage unit belongs to ------- */}\n <PmSelect\n label=\"Owner Type\"\n required\n disabled={!!editing}\n value={form.ownerType}\n onChange={(v) => setForm({ ...form, ownerType: v, ownerId: '' })}\n onBlur={fieldErrors.onBlur('ownerType')}\n error={fieldErrors.show('ownerType') && !!formErrors.ownerType}\n helperText={fieldErrors.show('ownerType') && formErrors.ownerType\n ? formErrors.ownerType\n : 'Only Facility is available currently.'}\n options={OWNER_TYPES}\n />\n\n <FacilityPicker\n required\n disabled={!!editing || form.ownerType !== 'FACILITY'}\n value={form.ownerId}\n onChange={(id) => setForm({ ...form, ownerId: id })}\n onBlur={fieldErrors.onBlur('ownerId')}\n error={fieldErrors.show('ownerId') && !!formErrors.ownerId}\n helperText={\n fieldErrors.show('ownerId') && formErrors.ownerId\n ? formErrors.ownerId\n : 'Search by name. The owner cannot be changed once created.'\n }\n />\n\n <Divider />\n\n {/* ------- Unit details ------- */}\n <TextField\n required\n label=\"Unit name\" size=\"small\" fullWidth\n value={form.unitName}\n onChange={(e) => {\n const nextName = e.target.value;\n // Derive a default code from the name on create — initials, A-Z/0-9\n // only. We never overwrite a code on edit (it's already curated and\n // ownerCode-scoped uniqueness depends on it).\n const auto = nextName\n .split(/\\s+/)\n .filter(Boolean)\n .map((w) => w[0])\n .join('')\n .toUpperCase()\n .replace(/[^A-Z0-9_]/g, '');\n setForm((f) => ({\n ...f,\n unitName: nextName,\n unitCode: editing ? f.unitCode : auto,\n }));\n }}\n onBlur={fieldErrors.onBlur('unitName')}\n error={fieldErrors.show('unitName') && !!formErrors.unitName}\n helperText={fieldErrors.show('unitName') ? formErrors.unitName : ''}\n />\n <TextField\n required\n label=\"Unit code (unique within facility)\" size=\"small\" fullWidth\n value={form.unitCode}\n onChange={(e) => setForm({ ...form, unitCode: e.target.value.toUpperCase() })}\n onBlur={fieldErrors.onBlur('unitCode')}\n error={fieldErrors.show('unitCode') && !!formErrors.unitCode}\n helperText={\n fieldErrors.show('unitCode') && formErrors.unitCode\n ? formErrors.unitCode\n : 'Auto-generated from the name. Edit if needed to make it unique within this facility.'\n }\n />\n <PmSelect\n label=\"Type\"\n required\n value={form.unitType}\n onChange={(v) => setForm({ ...form, unitType: v })}\n onBlur={fieldErrors.onBlur('unitType')}\n error={fieldErrors.show('unitType') && !!formErrors.unitType}\n options={STORAGE_UNIT_TYPES}\n />\n\n <Stack direction=\"row\" spacing={2}>\n <TextField label=\"Make\" size=\"small\" fullWidth\n value={form.make}\n onChange={(e) => setForm({ ...form, make: e.target.value })}\n helperText=\"Example: Godrej, Vestfrost\" />\n <TextField label=\"Model\" size=\"small\" fullWidth\n value={form.model}\n onChange={(e) => setForm({ ...form, model: e.target.value })}\n helperText=\"Example: GVR-100\" />\n </Stack>\n <Stack direction=\"row\" spacing={2}>\n <TextField\n label=\"Min °C\" size=\"small\" type=\"number\" fullWidth\n inputProps={{ step: '0.1', min: -90, max: 30 }}\n value={form.operatingTempMinCelsius}\n onChange={(e) => setForm({ ...form, operatingTempMinCelsius: e.target.value })}\n onBlur={fieldErrors.onBlur('operatingTempMinCelsius')}\n error={fieldErrors.show('operatingTempMinCelsius') && !!formErrors.operatingTempMinCelsius}\n helperText={\n fieldErrors.show('operatingTempMinCelsius') && formErrors.operatingTempMinCelsius\n ? formErrors.operatingTempMinCelsius\n : 'Allowed range: −90°C to +30°C'\n }\n />\n <TextField\n label=\"Max °C\" size=\"small\" type=\"number\" fullWidth\n inputProps={{ step: '0.1', min: -90, max: 30 }}\n value={form.operatingTempMaxCelsius}\n onChange={(e) => setForm({ ...form, operatingTempMaxCelsius: e.target.value })}\n onBlur={fieldErrors.onBlur('operatingTempMaxCelsius')}\n error={fieldErrors.show('operatingTempMaxCelsius') && !!formErrors.operatingTempMaxCelsius}\n helperText={\n fieldErrors.show('operatingTempMaxCelsius') && formErrors.operatingTempMaxCelsius\n ? formErrors.operatingTempMaxCelsius\n : 'Allowed range: −90°C to +30°C'\n }\n />\n </Stack>\n <TextField label=\"Comments\" size=\"small\" multiline minRows={2} fullWidth\n value={form.comments}\n onChange={(e) => setForm({ ...form, comments: e.target.value })}\n helperText=\"Notes about placement, maintenance schedule, or other details.\" />\n <FormControlLabel control={<Checkbox checked={form.isActive}\n onChange={(e) => setForm({ ...form, isActive: e.target.checked })} />} label=\"Active\" />\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setOpenDialog(false)}>Cancel</Button>\n <Button variant=\"contained\" disabled={!formIsValid} onClick={() => void save()}>Save</Button>\n </DialogActions>\n </Dialog>\n </PmGuard>\n </Box>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"StorageUnitsPage-BV7nK_iE.js","names":[],"sources":["../src/views/StorageUnitsPage.jsx"],"sourcesContent":["import { useState } from 'react';\nimport { v4 as uuidv4 } from 'uuid';\nimport {\n Alert,\n Box,\n Button,\n Checkbox,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Divider,\n FormControlLabel,\n Skeleton,\n Stack,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TextField,\n Typography,\n} from '@mui/material';\nimport AddRoundedIcon from '@mui/icons-material/AddRounded';\nimport RefreshRoundedIcon from '@mui/icons-material/RefreshRounded';\nimport WarehouseRoundedIcon from '@mui/icons-material/WarehouseRounded';\nimport { showToast } from '@/common/toaster/toaster';\nimport CustomSwitch from '@/views/custom-components/CustomSwitch';\nimport PmPageShell from '@pm/components/PmPageShell';\nimport PmNav from '@pm/components/PmNav';\nimport PmGuard from '@pm/components/PmGuard';\nimport { usePermissionedEffect, usePmPermissions } from '@pm/utils/permissions';\nimport { PmEmptyRow, PmSelect, PmTable, PmTableCard } from '@pm/components/PmTable';\nimport { STORAGE_UNIT_TYPES, labelOf } from '@pm/utils/constants';\nimport {\n getFacilitiesByIds,\n getStorageUnits,\n upsertStorageUnit,\n} from '@pm/services/pmApi';\nimport FacilityPicker from '@pm/components/FacilityPicker';\nimport {\n isClean,\n validateCode,\n validateRequired,\n validateTempRange,\n} from '@pm/utils/validation';\nimport { useFieldErrors } from '@pm/utils/useFieldErrors';\n\n// Today only FACILITY-owned storage units exist. The dropdown is kept so the\n// UI is ready for future owner kinds (REGIONAL_DEPOT, etc.) without a redesign.\nconst OWNER_TYPES = [{ value: 'FACILITY', label: 'Facility' }];\n\nexport default function StorageUnitsPage() {\n const perms = usePmPermissions();\n const canWrite = perms.has('update.manage.productManagement.storageUnit');\n const [items, setItems] = useState([]);\n // Map of facility id → name, hydrated for the ownerIds present on the\n // loaded storage units. Avoids loading the entire facility table just to\n // render the \"Facility\" column.\n const [facilityNames, setFacilityNames] = useState({});\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [openDialog, setOpenDialog] = useState(false);\n const [editing, setEditing] = useState(null);\n const [form, setForm] = useState(emptyForm());\n // Default to active-only; the toggle above the table reveals inactive rows.\n const [showInactive, setShowInactive] = useState(false);\n const fieldErrors = useFieldErrors();\n\n function emptyForm() {\n return {\n id: '',\n ownerType: 'FACILITY',\n ownerId: '',\n unitName: '',\n unitCode: '',\n unitType: 'REFRIGERATOR',\n make: '',\n model: '',\n comments: '',\n operatingTempMinCelsius: '',\n operatingTempMaxCelsius: '',\n isActive: true,\n };\n }\n\n async function load() {\n setLoading(true);\n setError('');\n try {\n const units = await getStorageUnits({ activeOnly: false });\n setItems(units);\n // Hydrate display names only for the facilities actually referenced\n // by the loaded units. Storage units are short — even the largest\n // deployment is a few hundred — so this is one cheap call.\n const ids = Array.from(new Set(units.map((u) => u.ownerId).filter(Boolean)));\n if (ids.length === 0) {\n setFacilityNames({});\n } else {\n try {\n const refs = await getFacilitiesByIds(ids);\n const map = {};\n refs.forEach((r) => { map[r.id] = r.name; });\n setFacilityNames(map);\n } catch {\n setFacilityNames({});\n }\n }\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to load storage units';\n setError(message);\n showToast({ message, type: 'error' });\n } finally {\n setLoading(false);\n }\n }\n\n usePermissionedEffect('view.manage.productManagement.storageUnit', () => {\n void load();\n }, []);\n\n function facilityNameFor(id) {\n return facilityNames[id] ?? id;\n }\n\n function openCreate() {\n setEditing(null);\n setForm({ ...emptyForm(), id: uuidv4() });\n fieldErrors.reset();\n setError('');\n setOpenDialog(true);\n }\n\n function openEdit(item) {\n setEditing(item);\n fieldErrors.reset();\n setError('');\n setForm({\n id: item.id,\n ownerType: item.ownerType ?? 'FACILITY',\n ownerId: item.ownerId ?? '',\n unitName: item.unitName ?? '',\n unitCode: item.unitCode ?? '',\n unitType: item.unitType ?? 'REFRIGERATOR',\n make: item.make ?? '',\n model: item.model ?? '',\n comments: item.comments ?? '',\n operatingTempMinCelsius: item.operatingTempMinCelsius ?? '',\n operatingTempMaxCelsius: item.operatingTempMaxCelsius ?? '',\n isActive: item.isActive !== false,\n });\n setOpenDialog(true);\n }\n\n const tempErrors = validateTempRange(form.operatingTempMinCelsius, form.operatingTempMaxCelsius);\n // Code uniqueness is enforced per facility in the DB. Mirror that scope here so\n // the operator gets the duplicate warning inline instead of as a 500 after save.\n const codeBase = validateCode(form.unitCode, { required: true });\n const codeNorm = (form.unitCode || '').trim().toUpperCase();\n const codeClash = !codeBase\n && codeNorm\n && form.ownerId\n && items.some((u) => u.id !== form.id\n && u.ownerId === form.ownerId\n && (u.unitCode || '').toUpperCase() === codeNorm);\n const formErrors = {\n ownerType: validateRequired(form.ownerType, 'Owner type'),\n ownerId: validateRequired(form.ownerId, 'Facility'),\n unitName: validateRequired(form.unitName, 'Name'),\n unitCode: codeBase || (codeClash ? 'Code is already in use for this facility.' : ''),\n unitType: validateRequired(form.unitType, 'Type'),\n operatingTempMinCelsius: tempErrors.min,\n operatingTempMaxCelsius: tempErrors.max,\n };\n const formIsValid = isClean(formErrors);\n\n async function save() {\n if (!formIsValid) {\n fieldErrors.markAllTouched();\n setError('Please fix the highlighted fields.');\n return;\n }\n try {\n await upsertStorageUnit({\n id: form.id,\n ownerId: form.ownerId,\n unitName: form.unitName.trim(),\n unitCode: form.unitCode.trim().toUpperCase(),\n unitType: form.unitType,\n make: form.make?.trim() || null,\n model: form.model?.trim() || null,\n comments: form.comments?.trim() || null,\n operatingTempMinCelsius: form.operatingTempMinCelsius === '' ? null : Number(form.operatingTempMinCelsius),\n operatingTempMaxCelsius: form.operatingTempMaxCelsius === '' ? null : Number(form.operatingTempMaxCelsius),\n isActive: form.isActive,\n });\n showToast({ message: 'Storage unit saved.', type: 'success' });\n setOpenDialog(false);\n await load();\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to save storage unit';\n setError(message);\n showToast({ message, type: 'error' });\n }\n }\n\n const visible = showInactive ? items : items.filter((u) => u.isActive !== false);\n\n return (\n <Box>\n <PmNav />\n <PmGuard perm={'view.manage.productManagement.storageUnit'}>\n <PmPageShell\n title=\"Storage Units\"\n subtitle=\"Cold-chain equipment for storing vaccine and product batches. Currently managed per facility.\"\n chips={['Catalog', 'Facility-owned']}\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"outlined\" startIcon={<RefreshRoundedIcon />} onClick={() => void load()}>Refresh</Button>\n {canWrite ? (\n <Button variant=\"contained\" startIcon={<AddRoundedIcon />} onClick={openCreate}>New Storage Unit</Button>\n ) : null}\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n <PmTableCard\n eyebrow=\"Cold-chain network\"\n title=\"Storage units\"\n subtitle={loading ? 'Loading…' : `${visible.length} ${visible.length === 1 ? 'unit' : 'units'}`}\n actions={\n <FormControlLabel\n control={<CustomSwitch checked={showInactive}\n onChange={(e) => setShowInactive(e.target.checked)} />}\n label={<Typography variant=\"body2\" sx={{ fontWeight: 600 }}>Show inactive</Typography>}\n labelPlacement=\"start\"\n sx={{ mr: 0.5, ml: 0 }}\n />\n }\n >\n <PmTable>\n <TableHead>\n <TableRow>\n <TableCell>Code</TableCell>\n <TableCell>Name</TableCell>\n <TableCell>Facility</TableCell>\n <TableCell>Type</TableCell>\n <TableCell>Operating range</TableCell>\n <TableCell>Status</TableCell>\n <TableCell align=\"right\">Action</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n Array.from({ length: 4 }).map((_, i) => (\n <TableRow key={i}>\n {Array.from({ length: 7 }).map((__, j) => (\n <TableCell key={j}><Skeleton height={22} /></TableCell>\n ))}\n </TableRow>\n ))\n ) : visible.length === 0 ? (\n <PmEmptyRow\n colSpan={7}\n icon={WarehouseRoundedIcon}\n title={items.length === 0 ? 'No storage units yet' : 'No active storage units'}\n hint={items.length === 0\n ? 'You need storage equipment to keep vaccine batches safe.'\n : 'Turn on “Show inactive” to see deactivated storage units.'}\n action={items.length === 0 && canWrite ? (\n <Button variant=\"contained\" size=\"small\" startIcon={<AddRoundedIcon />} onClick={openCreate}>\n Create first unit\n </Button>\n ) : null}\n />\n ) : visible.map((u) => (\n <TableRow key={u.id} hover>\n <TableCell>\n <Box component=\"span\" sx={{\n display: 'inline-flex', px: 0.85, py: 0.25, borderRadius: 1,\n bgcolor: 'grey.100', fontFamily: 'monospace', fontSize: '0.72rem', fontWeight: 800,\n }}>\n {u.unitCode}\n </Box>\n </TableCell>\n <TableCell><Typography variant=\"body2\" sx={{ fontWeight: 700 }}>{u.unitName}</Typography></TableCell>\n <TableCell><Typography variant=\"caption\" color=\"text.secondary\">{facilityNameFor(u.ownerId)}</Typography></TableCell>\n <TableCell>\n <Chip size=\"small\" label={labelOf(STORAGE_UNIT_TYPES, u.unitType)} variant=\"outlined\"\n sx={{ fontWeight: 700, borderRadius: 1.5, height: 22 }} />\n </TableCell>\n <TableCell>\n {u.operatingTempMinCelsius != null && u.operatingTempMaxCelsius != null ? (\n <Typography variant=\"caption\" sx={{ fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>\n {u.operatingTempMinCelsius}°C → {u.operatingTempMaxCelsius}°C\n </Typography>\n ) : <Typography variant=\"caption\" color=\"text.disabled\">—</Typography>}\n </TableCell>\n <TableCell>\n <Chip size=\"small\"\n label={u.isActive ? 'Active' : 'Inactive'}\n color={u.isActive ? 'success' : 'default'}\n variant={u.isActive ? 'filled' : 'outlined'}\n sx={{ fontWeight: 700, borderRadius: 1.5, height: 22 }} />\n </TableCell>\n <TableCell align=\"right\">\n {canWrite ? (\n <Button size=\"small\" variant=\"outlined\" onClick={() => openEdit(u)}>Edit</Button>\n ) : null}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </PmTable>\n </PmTableCard>\n </PmPageShell>\n\n <Dialog open={openDialog} onClose={() => setOpenDialog(false)} fullWidth maxWidth=\"sm\">\n <DialogTitle>{editing ? 'Edit Storage Unit' : 'New Storage Unit'}</DialogTitle>\n <DialogContent dividers>\n <Stack spacing={2} sx={{ pt: 1 }}>\n\n {/* ------- Ownership: who this storage unit belongs to ------- */}\n <PmSelect\n label=\"Owner Type\"\n required\n disabled={!!editing}\n value={form.ownerType}\n onChange={(v) => setForm({ ...form, ownerType: v, ownerId: '' })}\n onBlur={fieldErrors.onBlur('ownerType')}\n error={fieldErrors.show('ownerType') && !!formErrors.ownerType}\n helperText={fieldErrors.show('ownerType') && formErrors.ownerType\n ? formErrors.ownerType\n : 'Only Facility is available currently.'}\n options={OWNER_TYPES}\n />\n\n <FacilityPicker\n required\n disabled={!!editing || form.ownerType !== 'FACILITY'}\n value={form.ownerId}\n onChange={(id) => setForm({ ...form, ownerId: id })}\n onBlur={fieldErrors.onBlur('ownerId')}\n error={fieldErrors.show('ownerId') && !!formErrors.ownerId}\n helperText={\n fieldErrors.show('ownerId') && formErrors.ownerId\n ? formErrors.ownerId\n : 'Search by name. The owner cannot be changed once created.'\n }\n />\n\n <Divider />\n\n {/* ------- Unit details ------- */}\n <TextField\n required\n label=\"Unit name\" size=\"small\" fullWidth\n value={form.unitName}\n onChange={(e) => {\n const nextName = e.target.value;\n // Derive a default code from the name on create — initials, A-Z/0-9\n // only. We never overwrite a code on edit (it's already curated and\n // ownerCode-scoped uniqueness depends on it).\n const auto = nextName\n .split(/\\s+/)\n .filter(Boolean)\n .map((w) => w[0])\n .join('')\n .toUpperCase()\n .replace(/[^A-Z0-9_]/g, '');\n setForm((f) => ({\n ...f,\n unitName: nextName,\n unitCode: editing ? f.unitCode : auto,\n }));\n }}\n onBlur={fieldErrors.onBlur('unitName')}\n error={fieldErrors.show('unitName') && !!formErrors.unitName}\n helperText={fieldErrors.show('unitName') ? formErrors.unitName : ''}\n />\n <TextField\n required\n label=\"Unit code (unique within facility)\" size=\"small\" fullWidth\n value={form.unitCode}\n onChange={(e) => setForm({ ...form, unitCode: e.target.value.toUpperCase() })}\n onBlur={fieldErrors.onBlur('unitCode')}\n error={fieldErrors.show('unitCode') && !!formErrors.unitCode}\n helperText={\n fieldErrors.show('unitCode') && formErrors.unitCode\n ? formErrors.unitCode\n : 'Auto-generated from the name. Edit if needed to make it unique within this facility.'\n }\n />\n <PmSelect\n label=\"Type\"\n required\n value={form.unitType}\n onChange={(v) => setForm({ ...form, unitType: v })}\n onBlur={fieldErrors.onBlur('unitType')}\n error={fieldErrors.show('unitType') && !!formErrors.unitType}\n options={STORAGE_UNIT_TYPES}\n />\n\n <Stack direction=\"row\" spacing={2}>\n <TextField label=\"Make\" size=\"small\" fullWidth\n value={form.make}\n onChange={(e) => setForm({ ...form, make: e.target.value })}\n helperText=\"Example: Godrej, Vestfrost\" />\n <TextField label=\"Model\" size=\"small\" fullWidth\n value={form.model}\n onChange={(e) => setForm({ ...form, model: e.target.value })}\n helperText=\"Example: GVR-100\" />\n </Stack>\n <Stack direction=\"row\" spacing={2}>\n <TextField\n label=\"Min °C\" size=\"small\" type=\"number\" fullWidth\n inputProps={{ step: '0.1', min: -90, max: 30 }}\n value={form.operatingTempMinCelsius}\n onChange={(e) => setForm({ ...form, operatingTempMinCelsius: e.target.value })}\n onBlur={fieldErrors.onBlur('operatingTempMinCelsius')}\n error={fieldErrors.show('operatingTempMinCelsius') && !!formErrors.operatingTempMinCelsius}\n helperText={\n fieldErrors.show('operatingTempMinCelsius') && formErrors.operatingTempMinCelsius\n ? formErrors.operatingTempMinCelsius\n : 'Allowed range: −90°C to +30°C'\n }\n />\n <TextField\n label=\"Max °C\" size=\"small\" type=\"number\" fullWidth\n inputProps={{ step: '0.1', min: -90, max: 30 }}\n value={form.operatingTempMaxCelsius}\n onChange={(e) => setForm({ ...form, operatingTempMaxCelsius: e.target.value })}\n onBlur={fieldErrors.onBlur('operatingTempMaxCelsius')}\n error={fieldErrors.show('operatingTempMaxCelsius') && !!formErrors.operatingTempMaxCelsius}\n helperText={\n fieldErrors.show('operatingTempMaxCelsius') && formErrors.operatingTempMaxCelsius\n ? formErrors.operatingTempMaxCelsius\n : 'Allowed range: −90°C to +30°C'\n }\n />\n </Stack>\n <TextField label=\"Comments\" size=\"small\" multiline minRows={2} fullWidth\n value={form.comments}\n onChange={(e) => setForm({ ...form, comments: e.target.value })}\n helperText=\"Notes about placement, maintenance schedule, or other details.\" />\n <FormControlLabel control={<Checkbox checked={form.isActive}\n onChange={(e) => setForm({ ...form, isActive: e.target.checked })} />} label=\"Active\" />\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setOpenDialog(false)}>Cancel</Button>\n <Button variant=\"contained\" disabled={!formIsValid} onClick={() => void save()}>Save</Button>\n </DialogActions>\n </Dialog>\n </PmGuard>\n </Box>\n );\n}\n"],"mappings":"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"}
|