@burdenoff/microfe-assethandler 2026.624.1 → 2026.625.2

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.
Files changed (113) hide show
  1. package/dist/assethandler/pages/AiPredictionsPage.js +49 -42
  2. package/dist/assethandler/pages/AiPredictionsPage.js.map +1 -1
  3. package/dist/assethandler/pages/AnalyticsPage.js +539 -514
  4. package/dist/assethandler/pages/AnalyticsPage.js.map +1 -1
  5. package/dist/assethandler/pages/AssetsAssetCategoriesPage.js +143 -133
  6. package/dist/assethandler/pages/AssetsAssetCategoriesPage.js.map +1 -1
  7. package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js +90 -92
  8. package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js.map +1 -1
  9. package/dist/assethandler/pages/AssetsAssetCreatePage.js +131 -124
  10. package/dist/assethandler/pages/AssetsAssetCreatePage.js.map +1 -1
  11. package/dist/assethandler/pages/AssetsAssetDetailPage.js +220 -191
  12. package/dist/assethandler/pages/AssetsAssetDetailPage.js.map +1 -1
  13. package/dist/assethandler/pages/AssetsAssetEditPage.js +168 -156
  14. package/dist/assethandler/pages/AssetsAssetEditPage.js.map +1 -1
  15. package/dist/assethandler/pages/AssetsAssetListPage.js +219 -193
  16. package/dist/assethandler/pages/AssetsAssetListPage.js.map +1 -1
  17. package/dist/assethandler/pages/AssetsAssetTrackingPage.js +82 -71
  18. package/dist/assethandler/pages/AssetsAssetTrackingPage.js.map +1 -1
  19. package/dist/assethandler/pages/AuditTrailPage.js +127 -109
  20. package/dist/assethandler/pages/AuditTrailPage.js.map +1 -1
  21. package/dist/assethandler/pages/CmdbBrowserPage.js +39 -34
  22. package/dist/assethandler/pages/CmdbBrowserPage.js.map +1 -1
  23. package/dist/assethandler/pages/DashboardPage.js +245 -197
  24. package/dist/assethandler/pages/DashboardPage.js.map +1 -1
  25. package/dist/assethandler/pages/DigitalTwinPage.js +32 -27
  26. package/dist/assethandler/pages/DigitalTwinPage.js.map +1 -1
  27. package/dist/assethandler/pages/DiscoveryJobsPage.js +57 -51
  28. package/dist/assethandler/pages/DiscoveryJobsPage.js.map +1 -1
  29. package/dist/assethandler/pages/EsgDashboardPage.js +50 -43
  30. package/dist/assethandler/pages/EsgDashboardPage.js.map +1 -1
  31. package/dist/assethandler/pages/FinanceBudgetDetailPage.js +98 -84
  32. package/dist/assethandler/pages/FinanceBudgetDetailPage.js.map +1 -1
  33. package/dist/assethandler/pages/FinanceFinanceHubPage.js +151 -117
  34. package/dist/assethandler/pages/FinanceFinanceHubPage.js.map +1 -1
  35. package/dist/assethandler/pages/FinanceInvoiceDetailPage.js +77 -66
  36. package/dist/assethandler/pages/FinanceInvoiceDetailPage.js.map +1 -1
  37. package/dist/assethandler/pages/IotDevicesPage.js +41 -36
  38. package/dist/assethandler/pages/IotDevicesPage.js.map +1 -1
  39. package/dist/assethandler/pages/ItilChangeDetailPage.js +236 -199
  40. package/dist/assethandler/pages/ItilChangeDetailPage.js.map +1 -1
  41. package/dist/assethandler/pages/ItilChangeManagementPage.js +69 -67
  42. package/dist/assethandler/pages/ItilChangeManagementPage.js.map +1 -1
  43. package/dist/assethandler/pages/ItilIncidentDetailPage.js +237 -200
  44. package/dist/assethandler/pages/ItilIncidentDetailPage.js.map +1 -1
  45. package/dist/assethandler/pages/ItilIncidentManagementPage.js +103 -101
  46. package/dist/assethandler/pages/ItilIncidentManagementPage.js.map +1 -1
  47. package/dist/assethandler/pages/ItilItilhubPage.js +168 -124
  48. package/dist/assethandler/pages/ItilItilhubPage.js.map +1 -1
  49. package/dist/assethandler/pages/ItilProblemDetailPage.js +193 -156
  50. package/dist/assethandler/pages/ItilProblemDetailPage.js.map +1 -1
  51. package/dist/assethandler/pages/ItilProblemManagementPage.js +66 -64
  52. package/dist/assethandler/pages/ItilProblemManagementPage.js.map +1 -1
  53. package/dist/assethandler/pages/KnowledgeBasePage.js +52 -44
  54. package/dist/assethandler/pages/KnowledgeBasePage.js.map +1 -1
  55. package/dist/assethandler/pages/MaintenanceMaintenanceCalendarPage.js +72 -70
  56. package/dist/assethandler/pages/MaintenanceMaintenanceCalendarPage.js.map +1 -1
  57. package/dist/assethandler/pages/MaintenanceMaintenanceSchedulerPage.js +77 -62
  58. package/dist/assethandler/pages/MaintenanceMaintenanceSchedulerPage.js.map +1 -1
  59. package/dist/assethandler/pages/MarketplaceMarketplaceDetailPage.js +162 -151
  60. package/dist/assethandler/pages/MarketplaceMarketplaceDetailPage.js.map +1 -1
  61. package/dist/assethandler/pages/MarketplaceMarketplaceListPage.js +68 -61
  62. package/dist/assethandler/pages/MarketplaceMarketplaceListPage.js.map +1 -1
  63. package/dist/assethandler/pages/MarketplaceMarketplaceOrdersPage.js +125 -108
  64. package/dist/assethandler/pages/MarketplaceMarketplaceOrdersPage.js.map +1 -1
  65. package/dist/assethandler/pages/MarketplaceMarketplaceSellPage.js +67 -61
  66. package/dist/assethandler/pages/MarketplaceMarketplaceSellPage.js.map +1 -1
  67. package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js +203 -166
  68. package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js.map +1 -1
  69. package/dist/assethandler/pages/OperationsOperationsHubPage.js +126 -96
  70. package/dist/assethandler/pages/OperationsOperationsHubPage.js.map +1 -1
  71. package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js +165 -151
  72. package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js.map +1 -1
  73. package/dist/assethandler/pages/PortfolioPortfolioOverviewPage.js +123 -105
  74. package/dist/assethandler/pages/PortfolioPortfolioOverviewPage.js.map +1 -1
  75. package/dist/assethandler/pages/ProvenancePage.js +60 -52
  76. package/dist/assethandler/pages/ProvenancePage.js.map +1 -1
  77. package/dist/assethandler/pages/ReportsReportBuilderPage.js +80 -73
  78. package/dist/assethandler/pages/ReportsReportBuilderPage.js.map +1 -1
  79. package/dist/assethandler/pages/ReportsReportsDashboardPage.js +114 -79
  80. package/dist/assethandler/pages/ReportsReportsDashboardPage.js.map +1 -1
  81. package/dist/assethandler/pages/ReportsReportsListPage.js +119 -103
  82. package/dist/assethandler/pages/ReportsReportsListPage.js.map +1 -1
  83. package/dist/assethandler/pages/SamLicensesPage.js +39 -34
  84. package/dist/assethandler/pages/SamLicensesPage.js.map +1 -1
  85. package/dist/assethandler/pages/SecurityComplianceDetailPage.js +63 -55
  86. package/dist/assethandler/pages/SecurityComplianceDetailPage.js.map +1 -1
  87. package/dist/assethandler/pages/SecurityPolicyDetailPage.js +134 -117
  88. package/dist/assethandler/pages/SecurityPolicyDetailPage.js.map +1 -1
  89. package/dist/assethandler/pages/SecurityScheduleBackupPage.js +64 -58
  90. package/dist/assethandler/pages/SecurityScheduleBackupPage.js.map +1 -1
  91. package/dist/assethandler/pages/SecuritySecurityEventDetailPage.js +131 -117
  92. package/dist/assethandler/pages/SecuritySecurityEventDetailPage.js.map +1 -1
  93. package/dist/assethandler/pages/SecuritySecurityHubPage.js +151 -117
  94. package/dist/assethandler/pages/SecuritySecurityHubPage.js.map +1 -1
  95. package/dist/assethandler/pages/TransactionsTransactionDetailPage.js +235 -218
  96. package/dist/assethandler/pages/TransactionsTransactionDetailPage.js.map +1 -1
  97. package/dist/assethandler/pages/TransactionsTransactionListPage.js +145 -127
  98. package/dist/assethandler/pages/TransactionsTransactionListPage.js.map +1 -1
  99. package/dist/assethandler/pages/UsersPage.js +135 -110
  100. package/dist/assethandler/pages/UsersPage.js.map +1 -1
  101. package/dist/assethandler/pages/UsersUserCreatePage.js +74 -67
  102. package/dist/assethandler/pages/UsersUserCreatePage.js.map +1 -1
  103. package/dist/assethandler/pages/UsersUserManagementHubPage.js +178 -130
  104. package/dist/assethandler/pages/UsersUserManagementHubPage.js.map +1 -1
  105. package/dist/assethandler/pages/WorkflowsWorkflowBuilderPage.js +211 -193
  106. package/dist/assethandler/pages/WorkflowsWorkflowBuilderPage.js.map +1 -1
  107. package/dist/assethandler/pages/WorkflowsWorkflowExecutionsPage.js +126 -108
  108. package/dist/assethandler/pages/WorkflowsWorkflowExecutionsPage.js.map +1 -1
  109. package/dist/assethandler/pages/WorkflowsWorkflowListPage.js +71 -63
  110. package/dist/assethandler/pages/WorkflowsWorkflowListPage.js.map +1 -1
  111. package/dist/assethandler/pages/WorkflowsWorkflowTemplatesPage.js +96 -81
  112. package/dist/assethandler/pages/WorkflowsWorkflowTemplatesPage.js.map +1 -1
  113. package/package.json +2 -2
@@ -2,151 +2,171 @@ import { useAssetHandlerStore as e } from "../store/assethandlerStore.js";
2
2
  import { tWithFallback as t } from "../utils/i18n.js";
3
3
  import { useState as n } from "react";
4
4
  import { Building as r, Filter as i, Plus as a, Search as o, Shield as s, UserCheck as c, Users as l } from "lucide-react";
5
- import { Badge as u, Button as d, Card as f, CardContent as p, CardHeader as m, CardTitle as h, Input as g, Select as _, SelectContent as v, SelectItem as y, SelectTrigger as b, SelectValue as x, Table as S, TableBody as C, TableCell as w, TableHead as T, TableHeader as E, TableRow as D } from "@burdenoff/fe-libs/ui";
6
- import { useI18n as O } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
7
- import { jsx as k, jsxs as A } from "react/jsx-runtime";
5
+ import { useNavigate as u } from "react-router-dom";
6
+ import { Badge as d, Button as f, Card as p, CardContent as m, CardHeader as h, CardTitle as g, GlassCard as _, GradientText as v, IllustratedEmptyState as y, Input as b, PagePurpose as x, Select as S, SelectContent as C, SelectItem as w, SelectTrigger as T, SelectValue as E, Table as D, TableBody as O, TableCell as k, TableHead as A, TableHeader as j, TableRow as M } from "@burdenoff/fe-libs/ui";
7
+ import { useI18n as N } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
8
+ import { jsx as P, jsxs as F } from "react/jsx-runtime";
8
9
  //#region src/assethandler/pages/UsersPage.tsx
9
- var j = {
10
+ var I = {
10
11
  admin: "destructive",
11
12
  manager: "default",
12
13
  technician: "secondary",
13
14
  viewer: "outline",
14
15
  auditor: "secondary"
15
- }, M = {
16
+ }, L = {
16
17
  active: "default",
17
18
  inactive: "secondary",
18
19
  suspended: "destructive",
19
20
  pending: "outline"
20
21
  };
21
- function N() {
22
- let { t: N } = O(), { users: P } = e(), [F, I] = n(""), [L, R] = n("all"), z = P.filter((e) => {
23
- if (L !== "all" && e.role !== L) return !1;
24
- if (F) {
25
- let t = F.toLowerCase();
22
+ function R() {
23
+ let { t: R } = N(), z = u(), { users: B } = e(), [V, H] = n(""), [U, W] = n("all"), G = B.filter((e) => {
24
+ if (U !== "all" && e.role !== U) return !1;
25
+ if (V) {
26
+ let t = V.toLowerCase();
26
27
  return e.firstName.toLowerCase().includes(t) || e.lastName.toLowerCase().includes(t) || e.email.toLowerCase().includes(t);
27
28
  }
28
29
  return !0;
29
- }), B = P.filter((e) => e.status === "active").length, V = P.filter((e) => e.role === "admin").length, H = [...new Set(P.map((e) => e.department))].length;
30
- return /* @__PURE__ */ A("div", {
30
+ }), K = B.filter((e) => e.status === "active").length, q = B.filter((e) => e.role === "admin").length, J = [...new Set(B.map((e) => e.department))].length;
31
+ return /* @__PURE__ */ F("div", {
31
32
  className: "space-y-6 p-6",
32
33
  children: [
33
- /* @__PURE__ */ A("div", {
34
+ /* @__PURE__ */ F("div", {
34
35
  className: "flex items-center justify-between",
35
- children: [/* @__PURE__ */ A("div", { children: [/* @__PURE__ */ k("h1", {
36
+ children: [/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("h1", {
36
37
  className: "text-2xl font-semibold",
37
- children: t(N, "assethandler.users.title", "Users")
38
- }), /* @__PURE__ */ k("p", {
38
+ children: /* @__PURE__ */ P(v, { children: t(R, "assethandler.users.title", "Users") })
39
+ }), /* @__PURE__ */ P("p", {
39
40
  className: "text-sm text-text-secondary",
40
- children: t(N, "assethandler.users.description", "Manage user accounts, roles, and access permissions.")
41
- })] }), /* @__PURE__ */ A(d, {
41
+ children: t(R, "assethandler.users.description", "Manage user accounts, roles, and access permissions.")
42
+ })] }), /* @__PURE__ */ F(f, {
42
43
  size: "sm",
43
- children: [/* @__PURE__ */ k(a, { className: "mr-2 h-4 w-4" }), t(N, "assethandler.users.actions.addUser", "Add User")]
44
+ onClick: () => z("/users/user-create"),
45
+ children: [/* @__PURE__ */ P(a, { className: "mr-2 h-4 w-4" }), t(R, "assethandler.users.actions.addUser", "Add User")]
44
46
  })]
45
47
  }),
46
- /* @__PURE__ */ A("div", {
48
+ /* @__PURE__ */ P(x, { children: t(R, "assethandler.users.purpose", "The directory of everyone who uses Asset Handler — their role, department, status and how many assets they hold. Use it to onboard and offboard people, adjust access, and see at a glance who is responsible for what.") }),
49
+ /* @__PURE__ */ F("div", {
47
50
  className: "grid gap-4 md:grid-cols-4",
48
51
  children: [
49
- /* @__PURE__ */ A(f, { children: [/* @__PURE__ */ A(m, {
50
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
51
- children: [/* @__PURE__ */ k(h, {
52
- className: "text-sm font-medium",
53
- children: t(N, "assethandler.users.stats.totalUsers", "Total Users")
54
- }), /* @__PURE__ */ k(l, { className: "h-4 w-4 text-text-secondary" })]
55
- }), /* @__PURE__ */ k(p, { children: /* @__PURE__ */ k("div", {
56
- className: "text-2xl font-bold",
57
- children: P.length
58
- }) })] }),
59
- /* @__PURE__ */ A(f, { children: [/* @__PURE__ */ A(m, {
60
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
61
- children: [/* @__PURE__ */ k(h, {
62
- className: "text-sm font-medium",
63
- children: t(N, "assethandler.users.stats.activeUsers", "Active Users")
64
- }), /* @__PURE__ */ k(c, { className: "h-4 w-4 text-green-500" })]
65
- }), /* @__PURE__ */ k(p, { children: /* @__PURE__ */ k("div", {
66
- className: "text-2xl font-bold",
67
- children: B
68
- }) })] }),
69
- /* @__PURE__ */ A(f, { children: [/* @__PURE__ */ A(m, {
70
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
71
- children: [/* @__PURE__ */ k(h, {
72
- className: "text-sm font-medium",
73
- children: t(N, "assethandler.users.stats.administrators", "Administrators")
74
- }), /* @__PURE__ */ k(s, { className: "h-4 w-4 text-red-500" })]
75
- }), /* @__PURE__ */ k(p, { children: /* @__PURE__ */ k("div", {
76
- className: "text-2xl font-bold",
77
- children: V
78
- }) })] }),
79
- /* @__PURE__ */ A(f, { children: [/* @__PURE__ */ A(m, {
80
- className: "flex flex-row items-center justify-between space-y-0 pb-2",
81
- children: [/* @__PURE__ */ k(h, {
82
- className: "text-sm font-medium",
83
- children: t(N, "assethandler.users.stats.departments", "Departments")
84
- }), /* @__PURE__ */ k(r, { className: "h-4 w-4 text-text-secondary" })]
85
- }), /* @__PURE__ */ k(p, { children: /* @__PURE__ */ k("div", {
86
- className: "text-2xl font-bold",
87
- children: H
88
- }) })] })
52
+ /* @__PURE__ */ F(_, {
53
+ treatment: "glass",
54
+ glow: !0,
55
+ className: "border-border-seam",
56
+ children: [/* @__PURE__ */ F(h, {
57
+ className: "flex flex-row items-center justify-between space-y-0 pb-2",
58
+ children: [/* @__PURE__ */ P(g, {
59
+ className: "text-sm font-medium",
60
+ children: t(R, "assethandler.users.stats.totalUsers", "Total Users")
61
+ }), /* @__PURE__ */ P(l, { className: "h-4 w-4 text-text-secondary" })]
62
+ }), /* @__PURE__ */ P(m, { children: /* @__PURE__ */ P("div", {
63
+ className: "text-2xl font-bold tabular-nums",
64
+ children: B.length
65
+ }) })]
66
+ }),
67
+ /* @__PURE__ */ F(_, {
68
+ treatment: "metric",
69
+ className: "border-border-seam",
70
+ children: [/* @__PURE__ */ F(h, {
71
+ className: "flex flex-row items-center justify-between space-y-0 pb-2",
72
+ children: [/* @__PURE__ */ P(g, {
73
+ className: "text-sm font-medium",
74
+ children: t(R, "assethandler.users.stats.activeUsers", "Active Users")
75
+ }), /* @__PURE__ */ P(c, { className: "h-4 w-4 text-status-success-text" })]
76
+ }), /* @__PURE__ */ P(m, { children: /* @__PURE__ */ P("div", {
77
+ className: "text-2xl font-bold tabular-nums",
78
+ children: K
79
+ }) })]
80
+ }),
81
+ /* @__PURE__ */ F(_, {
82
+ treatment: "metric",
83
+ className: "border-border-seam",
84
+ children: [/* @__PURE__ */ F(h, {
85
+ className: "flex flex-row items-center justify-between space-y-0 pb-2",
86
+ children: [/* @__PURE__ */ P(g, {
87
+ className: "text-sm font-medium",
88
+ children: t(R, "assethandler.users.stats.administrators", "Administrators")
89
+ }), /* @__PURE__ */ P(s, { className: "h-4 w-4 text-status-error-text" })]
90
+ }), /* @__PURE__ */ P(m, { children: /* @__PURE__ */ P("div", {
91
+ className: "text-2xl font-bold tabular-nums",
92
+ children: q
93
+ }) })]
94
+ }),
95
+ /* @__PURE__ */ F(_, {
96
+ treatment: "metric",
97
+ className: "border-border-seam",
98
+ children: [/* @__PURE__ */ F(h, {
99
+ className: "flex flex-row items-center justify-between space-y-0 pb-2",
100
+ children: [/* @__PURE__ */ P(g, {
101
+ className: "text-sm font-medium",
102
+ children: t(R, "assethandler.users.stats.departments", "Departments")
103
+ }), /* @__PURE__ */ P(r, { className: "h-4 w-4 text-text-secondary" })]
104
+ }), /* @__PURE__ */ P(m, { children: /* @__PURE__ */ P("div", {
105
+ className: "text-2xl font-bold tabular-nums",
106
+ children: J
107
+ }) })]
108
+ })
89
109
  ]
90
110
  }),
91
- /* @__PURE__ */ A(f, { children: [/* @__PURE__ */ k(m, { children: /* @__PURE__ */ A("div", {
111
+ /* @__PURE__ */ F(p, { children: [/* @__PURE__ */ P(h, { children: /* @__PURE__ */ F("div", {
92
112
  className: "flex items-center justify-between",
93
- children: [/* @__PURE__ */ k(h, { children: t(N, "assethandler.users.table.title", "All Users") }), /* @__PURE__ */ A("div", {
113
+ children: [/* @__PURE__ */ P(g, { children: t(R, "assethandler.users.table.title", "All Users") }), /* @__PURE__ */ F("div", {
94
114
  className: "flex items-center gap-2",
95
- children: [/* @__PURE__ */ A("div", {
115
+ children: [/* @__PURE__ */ F("div", {
96
116
  className: "relative",
97
- children: [/* @__PURE__ */ k(o, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ k(g, {
98
- placeholder: t(N, "assethandler.users.search.placeholder", "Search users..."),
99
- value: F,
100
- onChange: (e) => I(e.target.value),
117
+ children: [/* @__PURE__ */ P(o, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ P(b, {
118
+ placeholder: t(R, "assethandler.users.search.placeholder", "Search users..."),
119
+ value: V,
120
+ onChange: (e) => H(e.target.value),
101
121
  className: "pl-9 w-[220px]"
102
122
  })]
103
- }), /* @__PURE__ */ A(_, {
104
- value: L,
105
- onValueChange: R,
106
- children: [/* @__PURE__ */ A(b, {
123
+ }), /* @__PURE__ */ F(S, {
124
+ value: U,
125
+ onValueChange: W,
126
+ children: [/* @__PURE__ */ F(T, {
107
127
  className: "w-[150px]",
108
- children: [/* @__PURE__ */ k(i, { className: "mr-2 h-4 w-4" }), /* @__PURE__ */ k(x, { placeholder: t(N, "assethandler.users.filters.role.placeholder", "Role") })]
109
- }), /* @__PURE__ */ A(v, { children: [
110
- /* @__PURE__ */ k(y, {
128
+ children: [/* @__PURE__ */ P(i, { className: "mr-2 h-4 w-4" }), /* @__PURE__ */ P(E, { placeholder: t(R, "assethandler.users.filters.role.placeholder", "Role") })]
129
+ }), /* @__PURE__ */ F(C, { children: [
130
+ /* @__PURE__ */ P(w, {
111
131
  value: "all",
112
- children: t(N, "assethandler.users.filters.role.all", "All Roles")
132
+ children: t(R, "assethandler.users.filters.role.all", "All Roles")
113
133
  }),
114
- /* @__PURE__ */ k(y, {
134
+ /* @__PURE__ */ P(w, {
115
135
  value: "admin",
116
- children: t(N, "assethandler.users.filters.role.admin", "Admin")
136
+ children: t(R, "assethandler.users.filters.role.admin", "Admin")
117
137
  }),
118
- /* @__PURE__ */ k(y, {
138
+ /* @__PURE__ */ P(w, {
119
139
  value: "manager",
120
- children: t(N, "assethandler.users.filters.role.manager", "Manager")
140
+ children: t(R, "assethandler.users.filters.role.manager", "Manager")
121
141
  }),
122
- /* @__PURE__ */ k(y, {
142
+ /* @__PURE__ */ P(w, {
123
143
  value: "technician",
124
- children: t(N, "assethandler.users.filters.role.technician", "Technician")
144
+ children: t(R, "assethandler.users.filters.role.technician", "Technician")
125
145
  }),
126
- /* @__PURE__ */ k(y, {
146
+ /* @__PURE__ */ P(w, {
127
147
  value: "viewer",
128
- children: t(N, "assethandler.users.filters.role.viewer", "Viewer")
148
+ children: t(R, "assethandler.users.filters.role.viewer", "Viewer")
129
149
  }),
130
- /* @__PURE__ */ k(y, {
150
+ /* @__PURE__ */ P(w, {
131
151
  value: "auditor",
132
- children: t(N, "assethandler.users.filters.role.auditor", "Auditor")
152
+ children: t(R, "assethandler.users.filters.role.auditor", "Auditor")
133
153
  })
134
154
  ] })]
135
155
  })]
136
156
  })]
137
- }) }), /* @__PURE__ */ k(p, { children: /* @__PURE__ */ A(S, { children: [/* @__PURE__ */ k(E, { children: /* @__PURE__ */ A(D, { children: [
138
- /* @__PURE__ */ k(T, { children: t(N, "assethandler.users.table.name", "Name") }),
139
- /* @__PURE__ */ k(T, { children: t(N, "assethandler.users.table.email", "Email") }),
140
- /* @__PURE__ */ k(T, { children: t(N, "assethandler.users.table.role", "Role") }),
141
- /* @__PURE__ */ k(T, { children: t(N, "assethandler.users.table.department", "Department") }),
142
- /* @__PURE__ */ k(T, { children: t(N, "assethandler.users.table.status", "Status") }),
143
- /* @__PURE__ */ k(T, { children: t(N, "assethandler.users.table.lastLogin", "Last Login") }),
144
- /* @__PURE__ */ k(T, {
157
+ }) }), /* @__PURE__ */ F(m, { children: [/* @__PURE__ */ F(D, { children: [/* @__PURE__ */ P(j, { children: /* @__PURE__ */ F(M, { children: [
158
+ /* @__PURE__ */ P(A, { children: t(R, "assethandler.users.table.name", "Name") }),
159
+ /* @__PURE__ */ P(A, { children: t(R, "assethandler.users.table.email", "Email") }),
160
+ /* @__PURE__ */ P(A, { children: t(R, "assethandler.users.table.role", "Role") }),
161
+ /* @__PURE__ */ P(A, { children: t(R, "assethandler.users.table.department", "Department") }),
162
+ /* @__PURE__ */ P(A, { children: t(R, "assethandler.users.table.status", "Status") }),
163
+ /* @__PURE__ */ P(A, { children: t(R, "assethandler.users.table.lastLogin", "Last Login") }),
164
+ /* @__PURE__ */ P(A, {
145
165
  className: "text-right",
146
- children: t(N, "assethandler.users.table.assets", "Assets")
166
+ children: t(R, "assethandler.users.table.assets", "Assets")
147
167
  })
148
- ] }) }), /* @__PURE__ */ A(C, { children: [z.map((e) => /* @__PURE__ */ A(D, { children: [
149
- /* @__PURE__ */ A(w, {
168
+ ] }) }), /* @__PURE__ */ P(O, { children: G.map((e) => /* @__PURE__ */ F(M, { children: [
169
+ /* @__PURE__ */ F(k, {
150
170
  className: "font-medium",
151
171
  children: [
152
172
  e.firstName,
@@ -154,30 +174,35 @@ function N() {
154
174
  e.lastName
155
175
  ]
156
176
  }),
157
- /* @__PURE__ */ k(w, { children: e.email }),
158
- /* @__PURE__ */ k(w, { children: /* @__PURE__ */ k(u, {
159
- variant: j[e.role] || "secondary",
177
+ /* @__PURE__ */ P(k, { children: e.email }),
178
+ /* @__PURE__ */ P(k, { children: /* @__PURE__ */ P(d, {
179
+ variant: I[e.role] || "secondary",
160
180
  children: e.role
161
181
  }) }),
162
- /* @__PURE__ */ k(w, { children: e.department }),
163
- /* @__PURE__ */ k(w, { children: /* @__PURE__ */ k(u, {
164
- variant: M[e.status] || "secondary",
182
+ /* @__PURE__ */ P(k, { children: e.department }),
183
+ /* @__PURE__ */ P(k, { children: /* @__PURE__ */ P(d, {
184
+ variant: L[e.status] || "secondary",
165
185
  children: e.status
166
186
  }) }),
167
- /* @__PURE__ */ k(w, { children: new Date(e.lastLogin).toLocaleDateString() }),
168
- /* @__PURE__ */ k(w, {
187
+ /* @__PURE__ */ P(k, { children: new Date(e.lastLogin).toLocaleDateString() }),
188
+ /* @__PURE__ */ P(k, {
169
189
  className: "text-right",
170
190
  children: e.assetsAssigned
171
191
  })
172
- ] }, e.id)), z.length === 0 && /* @__PURE__ */ k(D, { children: /* @__PURE__ */ k(w, {
173
- colSpan: 7,
174
- className: "text-center text-text-secondary py-8",
175
- children: t(N, "assethandler.users.empty", "No users found.")
176
- }) })] })] }) })] })
192
+ ] }, e.id)) })] }), G.length === 0 && /* @__PURE__ */ P(y, {
193
+ illustration: "empty-people",
194
+ title: t(R, "assethandler.users.empty", "No users found"),
195
+ description: "No users match your search or filters. Add a user or clear the filters to see results.",
196
+ action: /* @__PURE__ */ F(f, {
197
+ size: "sm",
198
+ onClick: () => z("/users/user-create"),
199
+ children: [/* @__PURE__ */ P(a, { className: "mr-2 h-4 w-4" }), t(R, "assethandler.users.actions.addUser", "Add User")]
200
+ })
201
+ })] })] })
177
202
  ]
178
203
  });
179
204
  }
180
205
  //#endregion
181
- export { N as UsersPage };
206
+ export { R as UsersPage };
182
207
 
183
208
  //# sourceMappingURL=UsersPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UsersPage.js","names":[],"sources":["../../../src/assethandler/pages/UsersPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@burdenoff/fe-libs/ui';\nimport { Plus, Search, Filter, Users, UserCheck, Shield, Building } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { tWithFallback } from '../utils/i18n';\n\nconst roleColors: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n admin: 'destructive',\n manager: 'default',\n technician: 'secondary',\n viewer: 'outline',\n auditor: 'secondary',\n};\n\nconst statusColors: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n active: 'default',\n inactive: 'secondary',\n suspended: 'destructive',\n pending: 'outline',\n};\n\nexport function UsersPage() {\n const { t } = useI18n();\n const { users } = useAssetHandlerStore();\n const [search, setSearch] = useState('');\n const [roleFilter, setRoleFilter] = useState('all');\n\n const filtered = users.filter((u) => {\n if (roleFilter !== 'all' && u.role !== roleFilter) return false;\n if (search) {\n const q = search.toLowerCase();\n return (\n u.firstName.toLowerCase().includes(q) ||\n u.lastName.toLowerCase().includes(q) ||\n u.email.toLowerCase().includes(q)\n );\n }\n return true;\n });\n\n const activeUsers = users.filter((u) => u.status === 'active').length;\n const adminCount = users.filter((u) => u.role === 'admin').length;\n const departments = [...new Set(users.map((u) => u.department))].length;\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n {tWithFallback(t, 'assethandler.users.title', 'Users')}\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n 'assethandler.users.description',\n 'Manage user accounts, roles, and access permissions.'\n )}\n </p>\n </div>\n <Button size=\"sm\">\n <Plus className=\"mr-2 h-4 w-4\" />\n {tWithFallback(t, 'assethandler.users.actions.addUser', 'Add User')}\n </Button>\n </div>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {tWithFallback(t, 'assethandler.users.stats.totalUsers', 'Total Users')}\n </CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{users.length}</div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {tWithFallback(t, 'assethandler.users.stats.activeUsers', 'Active Users')}\n </CardTitle>\n <UserCheck className=\"h-4 w-4 text-green-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{activeUsers}</div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {tWithFallback(t, 'assethandler.users.stats.administrators', 'Administrators')}\n </CardTitle>\n <Shield className=\"h-4 w-4 text-red-500\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{adminCount}</div>\n </CardContent>\n </Card>\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {tWithFallback(t, 'assethandler.users.stats.departments', 'Departments')}\n </CardTitle>\n <Building className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold\">{departments}</div>\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle>{tWithFallback(t, 'assethandler.users.table.title', 'All Users')}</CardTitle>\n <div className=\"flex items-center gap-2\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={tWithFallback(\n t,\n 'assethandler.users.search.placeholder',\n 'Search users...'\n )}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9 w-[220px]\"\n />\n </div>\n <Select value={roleFilter} onValueChange={setRoleFilter}>\n <SelectTrigger className=\"w-[150px]\">\n <Filter className=\"mr-2 h-4 w-4\" />\n <SelectValue\n placeholder={tWithFallback(\n t,\n 'assethandler.users.filters.role.placeholder',\n 'Role'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(t, 'assethandler.users.filters.role.all', 'All Roles')}\n </SelectItem>\n <SelectItem value=\"admin\">\n {tWithFallback(t, 'assethandler.users.filters.role.admin', 'Admin')}\n </SelectItem>\n <SelectItem value=\"manager\">\n {tWithFallback(t, 'assethandler.users.filters.role.manager', 'Manager')}\n </SelectItem>\n <SelectItem value=\"technician\">\n {tWithFallback(t, 'assethandler.users.filters.role.technician', 'Technician')}\n </SelectItem>\n <SelectItem value=\"viewer\">\n {tWithFallback(t, 'assethandler.users.filters.role.viewer', 'Viewer')}\n </SelectItem>\n <SelectItem value=\"auditor\">\n {tWithFallback(t, 'assethandler.users.filters.role.auditor', 'Auditor')}\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{tWithFallback(t, 'assethandler.users.table.name', 'Name')}</TableHead>\n <TableHead>{tWithFallback(t, 'assethandler.users.table.email', 'Email')}</TableHead>\n <TableHead>{tWithFallback(t, 'assethandler.users.table.role', 'Role')}</TableHead>\n <TableHead>\n {tWithFallback(t, 'assethandler.users.table.department', 'Department')}\n </TableHead>\n <TableHead>\n {tWithFallback(t, 'assethandler.users.table.status', 'Status')}\n </TableHead>\n <TableHead>\n {tWithFallback(t, 'assethandler.users.table.lastLogin', 'Last Login')}\n </TableHead>\n <TableHead className=\"text-right\">\n {tWithFallback(t, 'assethandler.users.table.assets', 'Assets')}\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {filtered.map((user) => (\n <TableRow key={user.id}>\n <TableCell className=\"font-medium\">\n {user.firstName} {user.lastName}\n </TableCell>\n <TableCell>{user.email}</TableCell>\n <TableCell>\n <Badge variant={roleColors[user.role] || 'secondary'}>{user.role}</Badge>\n </TableCell>\n <TableCell>{user.department}</TableCell>\n <TableCell>\n <Badge variant={statusColors[user.status] || 'secondary'}>{user.status}</Badge>\n </TableCell>\n <TableCell>{new Date(user.lastLogin).toLocaleDateString()}</TableCell>\n <TableCell className=\"text-right\">{user.assetsAssigned}</TableCell>\n </TableRow>\n ))}\n {filtered.length === 0 && (\n <TableRow>\n <TableCell colSpan={7} className=\"text-center text-text-secondary py-8\">\n {tWithFallback(t, 'assethandler.users.empty', 'No users found.')}\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"UsersPage.js","names":[],"sources":["../../../src/assethandler/pages/UsersPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n GradientText,\n GlassCard,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { Plus, Search, Filter, Users, UserCheck, Shield, Building } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useNavigate } from 'react-router-dom';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { tWithFallback } from '../utils/i18n';\n\nconst roleColors: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n admin: 'destructive',\n manager: 'default',\n technician: 'secondary',\n viewer: 'outline',\n auditor: 'secondary',\n};\n\nconst statusColors: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n active: 'default',\n inactive: 'secondary',\n suspended: 'destructive',\n pending: 'outline',\n};\n\nexport function UsersPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const { users } = useAssetHandlerStore();\n const [search, setSearch] = useState('');\n const [roleFilter, setRoleFilter] = useState('all');\n\n const filtered = users.filter((u) => {\n if (roleFilter !== 'all' && u.role !== roleFilter) return false;\n if (search) {\n const q = search.toLowerCase();\n return (\n u.firstName.toLowerCase().includes(q) ||\n u.lastName.toLowerCase().includes(q) ||\n u.email.toLowerCase().includes(q)\n );\n }\n return true;\n });\n\n const activeUsers = users.filter((u) => u.status === 'active').length;\n const adminCount = users.filter((u) => u.role === 'admin').length;\n const departments = [...new Set(users.map((u) => u.department))].length;\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">\n <GradientText>{tWithFallback(t, 'assethandler.users.title', 'Users')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n 'assethandler.users.description',\n 'Manage user accounts, roles, and access permissions.'\n )}\n </p>\n </div>\n <Button size=\"sm\" onClick={() => navigate('/users/user-create')}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {tWithFallback(t, 'assethandler.users.actions.addUser', 'Add User')}\n </Button>\n </div>\n\n <PagePurpose>\n {tWithFallback(\n t,\n 'assethandler.users.purpose',\n 'The directory of everyone who uses Asset Handler — their role, department, status and how many assets they hold. Use it to onboard and offboard people, adjust access, and see at a glance who is responsible for what.'\n )}\n </PagePurpose>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {tWithFallback(t, 'assethandler.users.stats.totalUsers', 'Total Users')}\n </CardTitle>\n <Users className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{users.length}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {tWithFallback(t, 'assethandler.users.stats.activeUsers', 'Active Users')}\n </CardTitle>\n <UserCheck className=\"h-4 w-4 text-status-success-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{activeUsers}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {tWithFallback(t, 'assethandler.users.stats.administrators', 'Administrators')}\n </CardTitle>\n <Shield className=\"h-4 w-4 text-status-error-text\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{adminCount}</div>\n </CardContent>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">\n {tWithFallback(t, 'assethandler.users.stats.departments', 'Departments')}\n </CardTitle>\n <Building className=\"h-4 w-4 text-text-secondary\" />\n </CardHeader>\n <CardContent>\n <div className=\"text-2xl font-bold tabular-nums\">{departments}</div>\n </CardContent>\n </GlassCard>\n </div>\n\n <Card>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle>{tWithFallback(t, 'assethandler.users.table.title', 'All Users')}</CardTitle>\n <div className=\"flex items-center gap-2\">\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={tWithFallback(\n t,\n 'assethandler.users.search.placeholder',\n 'Search users...'\n )}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9 w-[220px]\"\n />\n </div>\n <Select value={roleFilter} onValueChange={setRoleFilter}>\n <SelectTrigger className=\"w-[150px]\">\n <Filter className=\"mr-2 h-4 w-4\" />\n <SelectValue\n placeholder={tWithFallback(\n t,\n 'assethandler.users.filters.role.placeholder',\n 'Role'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(t, 'assethandler.users.filters.role.all', 'All Roles')}\n </SelectItem>\n <SelectItem value=\"admin\">\n {tWithFallback(t, 'assethandler.users.filters.role.admin', 'Admin')}\n </SelectItem>\n <SelectItem value=\"manager\">\n {tWithFallback(t, 'assethandler.users.filters.role.manager', 'Manager')}\n </SelectItem>\n <SelectItem value=\"technician\">\n {tWithFallback(t, 'assethandler.users.filters.role.technician', 'Technician')}\n </SelectItem>\n <SelectItem value=\"viewer\">\n {tWithFallback(t, 'assethandler.users.filters.role.viewer', 'Viewer')}\n </SelectItem>\n <SelectItem value=\"auditor\">\n {tWithFallback(t, 'assethandler.users.filters.role.auditor', 'Auditor')}\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{tWithFallback(t, 'assethandler.users.table.name', 'Name')}</TableHead>\n <TableHead>{tWithFallback(t, 'assethandler.users.table.email', 'Email')}</TableHead>\n <TableHead>{tWithFallback(t, 'assethandler.users.table.role', 'Role')}</TableHead>\n <TableHead>\n {tWithFallback(t, 'assethandler.users.table.department', 'Department')}\n </TableHead>\n <TableHead>\n {tWithFallback(t, 'assethandler.users.table.status', 'Status')}\n </TableHead>\n <TableHead>\n {tWithFallback(t, 'assethandler.users.table.lastLogin', 'Last Login')}\n </TableHead>\n <TableHead className=\"text-right\">\n {tWithFallback(t, 'assethandler.users.table.assets', 'Assets')}\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {filtered.map((user) => (\n <TableRow key={user.id}>\n <TableCell className=\"font-medium\">\n {user.firstName} {user.lastName}\n </TableCell>\n <TableCell>{user.email}</TableCell>\n <TableCell>\n <Badge variant={roleColors[user.role] || 'secondary'}>{user.role}</Badge>\n </TableCell>\n <TableCell>{user.department}</TableCell>\n <TableCell>\n <Badge variant={statusColors[user.status] || 'secondary'}>{user.status}</Badge>\n </TableCell>\n <TableCell>{new Date(user.lastLogin).toLocaleDateString()}</TableCell>\n <TableCell className=\"text-right\">{user.assetsAssigned}</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n {filtered.length === 0 && (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title={tWithFallback(t, 'assethandler.users.empty', 'No users found')}\n description=\"No users match your search or filters. Add a user or clear the filters to see results.\"\n action={\n <Button size=\"sm\" onClick={() => navigate('/users/user-create')}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {tWithFallback(t, 'assethandler.users.actions.addUser', 'Add User')}\n </Button>\n }\n />\n )}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}