@burdenoff/microfe-assethandler 2026.625.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.
- package/dist/assethandler/pages/AiPredictionsPage.js +42 -41
- package/dist/assethandler/pages/AiPredictionsPage.js.map +1 -1
- package/dist/assethandler/pages/AnalyticsPage.js +538 -534
- package/dist/assethandler/pages/AnalyticsPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCategoriesPage.js +135 -125
- package/dist/assethandler/pages/AssetsAssetCategoriesPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js +90 -92
- package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCreatePage.js +131 -124
- package/dist/assethandler/pages/AssetsAssetCreatePage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetDetailPage.js +214 -185
- package/dist/assethandler/pages/AssetsAssetDetailPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetEditPage.js +168 -156
- package/dist/assethandler/pages/AssetsAssetEditPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetListPage.js +207 -187
- package/dist/assethandler/pages/AssetsAssetListPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetTrackingPage.js +82 -71
- package/dist/assethandler/pages/AssetsAssetTrackingPage.js.map +1 -1
- package/dist/assethandler/pages/AuditTrailPage.js +93 -91
- package/dist/assethandler/pages/AuditTrailPage.js.map +1 -1
- package/dist/assethandler/pages/CmdbBrowserPage.js +32 -33
- package/dist/assethandler/pages/CmdbBrowserPage.js.map +1 -1
- package/dist/assethandler/pages/DashboardPage.js +157 -126
- package/dist/assethandler/pages/DashboardPage.js.map +1 -1
- package/dist/assethandler/pages/DigitalTwinPage.js +25 -26
- package/dist/assethandler/pages/DigitalTwinPage.js.map +1 -1
- package/dist/assethandler/pages/DiscoveryJobsPage.js +50 -50
- package/dist/assethandler/pages/DiscoveryJobsPage.js.map +1 -1
- package/dist/assethandler/pages/EsgDashboardPage.js +43 -42
- package/dist/assethandler/pages/EsgDashboardPage.js.map +1 -1
- package/dist/assethandler/pages/FinanceBudgetDetailPage.js +96 -82
- package/dist/assethandler/pages/FinanceBudgetDetailPage.js.map +1 -1
- package/dist/assethandler/pages/FinanceFinanceHubPage.js +137 -103
- package/dist/assethandler/pages/FinanceFinanceHubPage.js.map +1 -1
- package/dist/assethandler/pages/FinanceInvoiceDetailPage.js +77 -66
- package/dist/assethandler/pages/FinanceInvoiceDetailPage.js.map +1 -1
- package/dist/assethandler/pages/IotDevicesPage.js +34 -35
- package/dist/assethandler/pages/IotDevicesPage.js.map +1 -1
- package/dist/assethandler/pages/ItilChangeDetailPage.js +236 -199
- package/dist/assethandler/pages/ItilChangeDetailPage.js.map +1 -1
- package/dist/assethandler/pages/ItilChangeManagementPage.js +66 -64
- package/dist/assethandler/pages/ItilChangeManagementPage.js.map +1 -1
- package/dist/assethandler/pages/ItilIncidentDetailPage.js +237 -200
- package/dist/assethandler/pages/ItilIncidentDetailPage.js.map +1 -1
- package/dist/assethandler/pages/ItilIncidentManagementPage.js +99 -97
- package/dist/assethandler/pages/ItilIncidentManagementPage.js.map +1 -1
- package/dist/assethandler/pages/ItilItilhubPage.js +166 -122
- package/dist/assethandler/pages/ItilItilhubPage.js.map +1 -1
- package/dist/assethandler/pages/ItilProblemDetailPage.js +193 -156
- package/dist/assethandler/pages/ItilProblemDetailPage.js.map +1 -1
- package/dist/assethandler/pages/ItilProblemManagementPage.js +63 -61
- package/dist/assethandler/pages/ItilProblemManagementPage.js.map +1 -1
- package/dist/assethandler/pages/KnowledgeBasePage.js +45 -43
- package/dist/assethandler/pages/KnowledgeBasePage.js.map +1 -1
- package/dist/assethandler/pages/MaintenanceMaintenanceCalendarPage.js +70 -68
- package/dist/assethandler/pages/MaintenanceMaintenanceCalendarPage.js.map +1 -1
- package/dist/assethandler/pages/MaintenanceMaintenanceSchedulerPage.js +77 -62
- package/dist/assethandler/pages/MaintenanceMaintenanceSchedulerPage.js.map +1 -1
- package/dist/assethandler/pages/MarketplaceMarketplaceDetailPage.js +162 -151
- package/dist/assethandler/pages/MarketplaceMarketplaceDetailPage.js.map +1 -1
- package/dist/assethandler/pages/MarketplaceMarketplaceListPage.js +64 -57
- package/dist/assethandler/pages/MarketplaceMarketplaceListPage.js.map +1 -1
- package/dist/assethandler/pages/MarketplaceMarketplaceOrdersPage.js +125 -108
- package/dist/assethandler/pages/MarketplaceMarketplaceOrdersPage.js.map +1 -1
- package/dist/assethandler/pages/MarketplaceMarketplaceSellPage.js +67 -61
- package/dist/assethandler/pages/MarketplaceMarketplaceSellPage.js.map +1 -1
- package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js +203 -166
- package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js.map +1 -1
- package/dist/assethandler/pages/OperationsOperationsHubPage.js +125 -95
- package/dist/assethandler/pages/OperationsOperationsHubPage.js.map +1 -1
- package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js +165 -151
- package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js.map +1 -1
- package/dist/assethandler/pages/PortfolioPortfolioOverviewPage.js +83 -81
- package/dist/assethandler/pages/PortfolioPortfolioOverviewPage.js.map +1 -1
- package/dist/assethandler/pages/ProvenancePage.js +56 -53
- package/dist/assethandler/pages/ProvenancePage.js.map +1 -1
- package/dist/assethandler/pages/ReportsReportBuilderPage.js +80 -73
- package/dist/assethandler/pages/ReportsReportBuilderPage.js.map +1 -1
- package/dist/assethandler/pages/ReportsReportsDashboardPage.js +112 -77
- package/dist/assethandler/pages/ReportsReportsDashboardPage.js.map +1 -1
- package/dist/assethandler/pages/ReportsReportsListPage.js +119 -103
- package/dist/assethandler/pages/ReportsReportsListPage.js.map +1 -1
- package/dist/assethandler/pages/SamLicensesPage.js +32 -33
- package/dist/assethandler/pages/SamLicensesPage.js.map +1 -1
- package/dist/assethandler/pages/SecurityComplianceDetailPage.js +60 -52
- package/dist/assethandler/pages/SecurityComplianceDetailPage.js.map +1 -1
- package/dist/assethandler/pages/SecurityPolicyDetailPage.js +134 -117
- package/dist/assethandler/pages/SecurityPolicyDetailPage.js.map +1 -1
- package/dist/assethandler/pages/SecurityScheduleBackupPage.js +63 -57
- package/dist/assethandler/pages/SecurityScheduleBackupPage.js.map +1 -1
- package/dist/assethandler/pages/SecuritySecurityEventDetailPage.js +131 -117
- package/dist/assethandler/pages/SecuritySecurityEventDetailPage.js.map +1 -1
- package/dist/assethandler/pages/SecuritySecurityHubPage.js +147 -113
- package/dist/assethandler/pages/SecuritySecurityHubPage.js.map +1 -1
- package/dist/assethandler/pages/TransactionsTransactionDetailPage.js +235 -218
- package/dist/assethandler/pages/TransactionsTransactionDetailPage.js.map +1 -1
- package/dist/assethandler/pages/TransactionsTransactionListPage.js +118 -116
- package/dist/assethandler/pages/TransactionsTransactionListPage.js.map +1 -1
- package/dist/assethandler/pages/UsersPage.js +108 -99
- package/dist/assethandler/pages/UsersPage.js.map +1 -1
- package/dist/assethandler/pages/UsersUserCreatePage.js +74 -67
- package/dist/assethandler/pages/UsersUserCreatePage.js.map +1 -1
- package/dist/assethandler/pages/UsersUserManagementHubPage.js +128 -93
- package/dist/assethandler/pages/UsersUserManagementHubPage.js.map +1 -1
- package/dist/assethandler/pages/WorkflowsWorkflowBuilderPage.js +211 -193
- package/dist/assethandler/pages/WorkflowsWorkflowBuilderPage.js.map +1 -1
- package/dist/assethandler/pages/WorkflowsWorkflowExecutionsPage.js +88 -86
- package/dist/assethandler/pages/WorkflowsWorkflowExecutionsPage.js.map +1 -1
- package/dist/assethandler/pages/WorkflowsWorkflowListPage.js +68 -60
- package/dist/assethandler/pages/WorkflowsWorkflowListPage.js.map +1 -1
- package/dist/assethandler/pages/WorkflowsWorkflowTemplatesPage.js +71 -68
- package/dist/assethandler/pages/WorkflowsWorkflowTemplatesPage.js.map +1 -1
- package/package.json +2 -2
|
@@ -2,167 +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 {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
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
|
|
10
|
+
var I = {
|
|
10
11
|
admin: "destructive",
|
|
11
12
|
manager: "default",
|
|
12
13
|
technician: "secondary",
|
|
13
14
|
viewer: "outline",
|
|
14
15
|
auditor: "secondary"
|
|
15
|
-
},
|
|
16
|
+
}, L = {
|
|
16
17
|
active: "default",
|
|
17
18
|
inactive: "secondary",
|
|
18
19
|
suspended: "destructive",
|
|
19
20
|
pending: "outline"
|
|
20
21
|
};
|
|
21
|
-
function
|
|
22
|
-
let { t:
|
|
23
|
-
if (
|
|
24
|
-
if (
|
|
25
|
-
let t =
|
|
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
|
-
}),
|
|
30
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
34
|
+
/* @__PURE__ */ F("div", {
|
|
34
35
|
className: "flex items-center justify-between",
|
|
35
|
-
children: [/* @__PURE__ */
|
|
36
|
+
children: [/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("h1", {
|
|
36
37
|
className: "text-2xl font-semibold",
|
|
37
|
-
children: /* @__PURE__ */
|
|
38
|
-
}), /* @__PURE__ */
|
|
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(
|
|
41
|
-
})] }), /* @__PURE__ */
|
|
41
|
+
children: t(R, "assethandler.users.description", "Manage user accounts, roles, and access permissions.")
|
|
42
|
+
})] }), /* @__PURE__ */ F(f, {
|
|
42
43
|
size: "sm",
|
|
43
|
-
|
|
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__ */
|
|
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__ */
|
|
50
|
-
treatment: "
|
|
52
|
+
/* @__PURE__ */ F(_, {
|
|
53
|
+
treatment: "glass",
|
|
54
|
+
glow: !0,
|
|
51
55
|
className: "border-border-seam",
|
|
52
|
-
children: [/* @__PURE__ */
|
|
56
|
+
children: [/* @__PURE__ */ F(h, {
|
|
53
57
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
54
|
-
children: [/* @__PURE__ */
|
|
58
|
+
children: [/* @__PURE__ */ P(g, {
|
|
55
59
|
className: "text-sm font-medium",
|
|
56
|
-
children: t(
|
|
57
|
-
}), /* @__PURE__ */
|
|
58
|
-
}), /* @__PURE__ */
|
|
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", {
|
|
59
63
|
className: "text-2xl font-bold tabular-nums",
|
|
60
|
-
children:
|
|
64
|
+
children: B.length
|
|
61
65
|
}) })]
|
|
62
66
|
}),
|
|
63
|
-
/* @__PURE__ */
|
|
67
|
+
/* @__PURE__ */ F(_, {
|
|
64
68
|
treatment: "metric",
|
|
65
69
|
className: "border-border-seam",
|
|
66
|
-
children: [/* @__PURE__ */
|
|
70
|
+
children: [/* @__PURE__ */ F(h, {
|
|
67
71
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
68
|
-
children: [/* @__PURE__ */
|
|
72
|
+
children: [/* @__PURE__ */ P(g, {
|
|
69
73
|
className: "text-sm font-medium",
|
|
70
|
-
children: t(
|
|
71
|
-
}), /* @__PURE__ */
|
|
72
|
-
}), /* @__PURE__ */
|
|
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", {
|
|
73
77
|
className: "text-2xl font-bold tabular-nums",
|
|
74
|
-
children:
|
|
78
|
+
children: K
|
|
75
79
|
}) })]
|
|
76
80
|
}),
|
|
77
|
-
/* @__PURE__ */
|
|
81
|
+
/* @__PURE__ */ F(_, {
|
|
78
82
|
treatment: "metric",
|
|
79
83
|
className: "border-border-seam",
|
|
80
|
-
children: [/* @__PURE__ */
|
|
84
|
+
children: [/* @__PURE__ */ F(h, {
|
|
81
85
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
82
|
-
children: [/* @__PURE__ */
|
|
86
|
+
children: [/* @__PURE__ */ P(g, {
|
|
83
87
|
className: "text-sm font-medium",
|
|
84
|
-
children: t(
|
|
85
|
-
}), /* @__PURE__ */
|
|
86
|
-
}), /* @__PURE__ */
|
|
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", {
|
|
87
91
|
className: "text-2xl font-bold tabular-nums",
|
|
88
|
-
children:
|
|
92
|
+
children: q
|
|
89
93
|
}) })]
|
|
90
94
|
}),
|
|
91
|
-
/* @__PURE__ */
|
|
95
|
+
/* @__PURE__ */ F(_, {
|
|
92
96
|
treatment: "metric",
|
|
93
97
|
className: "border-border-seam",
|
|
94
|
-
children: [/* @__PURE__ */
|
|
98
|
+
children: [/* @__PURE__ */ F(h, {
|
|
95
99
|
className: "flex flex-row items-center justify-between space-y-0 pb-2",
|
|
96
|
-
children: [/* @__PURE__ */
|
|
100
|
+
children: [/* @__PURE__ */ P(g, {
|
|
97
101
|
className: "text-sm font-medium",
|
|
98
|
-
children: t(
|
|
99
|
-
}), /* @__PURE__ */
|
|
100
|
-
}), /* @__PURE__ */
|
|
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", {
|
|
101
105
|
className: "text-2xl font-bold tabular-nums",
|
|
102
|
-
children:
|
|
106
|
+
children: J
|
|
103
107
|
}) })]
|
|
104
108
|
})
|
|
105
109
|
]
|
|
106
110
|
}),
|
|
107
|
-
/* @__PURE__ */
|
|
111
|
+
/* @__PURE__ */ F(p, { children: [/* @__PURE__ */ P(h, { children: /* @__PURE__ */ F("div", {
|
|
108
112
|
className: "flex items-center justify-between",
|
|
109
|
-
children: [/* @__PURE__ */
|
|
113
|
+
children: [/* @__PURE__ */ P(g, { children: t(R, "assethandler.users.table.title", "All Users") }), /* @__PURE__ */ F("div", {
|
|
110
114
|
className: "flex items-center gap-2",
|
|
111
|
-
children: [/* @__PURE__ */
|
|
115
|
+
children: [/* @__PURE__ */ F("div", {
|
|
112
116
|
className: "relative",
|
|
113
|
-
children: [/* @__PURE__ */
|
|
114
|
-
placeholder: t(
|
|
115
|
-
value:
|
|
116
|
-
onChange: (e) =>
|
|
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),
|
|
117
121
|
className: "pl-9 w-[220px]"
|
|
118
122
|
})]
|
|
119
|
-
}), /* @__PURE__ */
|
|
120
|
-
value:
|
|
121
|
-
onValueChange:
|
|
122
|
-
children: [/* @__PURE__ */
|
|
123
|
+
}), /* @__PURE__ */ F(S, {
|
|
124
|
+
value: U,
|
|
125
|
+
onValueChange: W,
|
|
126
|
+
children: [/* @__PURE__ */ F(T, {
|
|
123
127
|
className: "w-[150px]",
|
|
124
|
-
children: [/* @__PURE__ */
|
|
125
|
-
}), /* @__PURE__ */
|
|
126
|
-
/* @__PURE__ */
|
|
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, {
|
|
127
131
|
value: "all",
|
|
128
|
-
children: t(
|
|
132
|
+
children: t(R, "assethandler.users.filters.role.all", "All Roles")
|
|
129
133
|
}),
|
|
130
|
-
/* @__PURE__ */
|
|
134
|
+
/* @__PURE__ */ P(w, {
|
|
131
135
|
value: "admin",
|
|
132
|
-
children: t(
|
|
136
|
+
children: t(R, "assethandler.users.filters.role.admin", "Admin")
|
|
133
137
|
}),
|
|
134
|
-
/* @__PURE__ */
|
|
138
|
+
/* @__PURE__ */ P(w, {
|
|
135
139
|
value: "manager",
|
|
136
|
-
children: t(
|
|
140
|
+
children: t(R, "assethandler.users.filters.role.manager", "Manager")
|
|
137
141
|
}),
|
|
138
|
-
/* @__PURE__ */
|
|
142
|
+
/* @__PURE__ */ P(w, {
|
|
139
143
|
value: "technician",
|
|
140
|
-
children: t(
|
|
144
|
+
children: t(R, "assethandler.users.filters.role.technician", "Technician")
|
|
141
145
|
}),
|
|
142
|
-
/* @__PURE__ */
|
|
146
|
+
/* @__PURE__ */ P(w, {
|
|
143
147
|
value: "viewer",
|
|
144
|
-
children: t(
|
|
148
|
+
children: t(R, "assethandler.users.filters.role.viewer", "Viewer")
|
|
145
149
|
}),
|
|
146
|
-
/* @__PURE__ */
|
|
150
|
+
/* @__PURE__ */ P(w, {
|
|
147
151
|
value: "auditor",
|
|
148
|
-
children: t(
|
|
152
|
+
children: t(R, "assethandler.users.filters.role.auditor", "Auditor")
|
|
149
153
|
})
|
|
150
154
|
] })]
|
|
151
155
|
})]
|
|
152
156
|
})]
|
|
153
|
-
}) }), /* @__PURE__ */
|
|
154
|
-
/* @__PURE__ */
|
|
155
|
-
/* @__PURE__ */
|
|
156
|
-
/* @__PURE__ */
|
|
157
|
-
/* @__PURE__ */
|
|
158
|
-
/* @__PURE__ */
|
|
159
|
-
/* @__PURE__ */
|
|
160
|
-
/* @__PURE__ */
|
|
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, {
|
|
161
165
|
className: "text-right",
|
|
162
|
-
children: t(
|
|
166
|
+
children: t(R, "assethandler.users.table.assets", "Assets")
|
|
163
167
|
})
|
|
164
|
-
] }) }), /* @__PURE__ */
|
|
165
|
-
/* @__PURE__ */
|
|
168
|
+
] }) }), /* @__PURE__ */ P(O, { children: G.map((e) => /* @__PURE__ */ F(M, { children: [
|
|
169
|
+
/* @__PURE__ */ F(k, {
|
|
166
170
|
className: "font-medium",
|
|
167
171
|
children: [
|
|
168
172
|
e.firstName,
|
|
@@ -170,30 +174,35 @@ function F() {
|
|
|
170
174
|
e.lastName
|
|
171
175
|
]
|
|
172
176
|
}),
|
|
173
|
-
/* @__PURE__ */
|
|
174
|
-
/* @__PURE__ */
|
|
175
|
-
variant:
|
|
177
|
+
/* @__PURE__ */ P(k, { children: e.email }),
|
|
178
|
+
/* @__PURE__ */ P(k, { children: /* @__PURE__ */ P(d, {
|
|
179
|
+
variant: I[e.role] || "secondary",
|
|
176
180
|
children: e.role
|
|
177
181
|
}) }),
|
|
178
|
-
/* @__PURE__ */
|
|
179
|
-
/* @__PURE__ */
|
|
180
|
-
variant:
|
|
182
|
+
/* @__PURE__ */ P(k, { children: e.department }),
|
|
183
|
+
/* @__PURE__ */ P(k, { children: /* @__PURE__ */ P(d, {
|
|
184
|
+
variant: L[e.status] || "secondary",
|
|
181
185
|
children: e.status
|
|
182
186
|
}) }),
|
|
183
|
-
/* @__PURE__ */
|
|
184
|
-
/* @__PURE__ */
|
|
187
|
+
/* @__PURE__ */ P(k, { children: new Date(e.lastLogin).toLocaleDateString() }),
|
|
188
|
+
/* @__PURE__ */ P(k, {
|
|
185
189
|
className: "text-right",
|
|
186
190
|
children: e.assetsAssigned
|
|
187
191
|
})
|
|
188
|
-
] }, e.id)),
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
+
})] })] })
|
|
193
202
|
]
|
|
194
203
|
});
|
|
195
204
|
}
|
|
196
205
|
//#endregion
|
|
197
|
-
export {
|
|
206
|
+
export { R as UsersPage };
|
|
198
207
|
|
|
199
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 GradientText,\n GlassCard,\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 <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\">\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 <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.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 {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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"}
|