@plumile/backoffice-react 0.1.99 → 0.1.102

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 (110) hide show
  1. package/lib/esm/AcceptInvitationScreen-B1IPafwD.js.map +1 -1
  2. package/lib/esm/{BackofficeAcceptInvitationPage-CEtApVwL.js → BackofficeAcceptInvitationPage-BfRsORii.js} +3 -3
  3. package/lib/esm/{BackofficeAcceptInvitationPage-CEtApVwL.js.map → BackofficeAcceptInvitationPage-BfRsORii.js.map} +1 -1
  4. package/lib/esm/{BackofficeDashboardPage-YWvoQODn.js → BackofficeDashboardPage-COKOYq4D.js} +7 -4
  5. package/lib/esm/BackofficeDashboardPage-COKOYq4D.js.map +1 -0
  6. package/lib/esm/BackofficeDetailPayload-P61MDRLE.js.map +1 -1
  7. package/lib/esm/{BackofficeEntityActionFormDialog-BgRTJ_JS.js → BackofficeEntityActionFormDialog-BgMuhyU8.js} +2 -2
  8. package/lib/esm/{BackofficeEntityActionFormDialog-BgRTJ_JS.js.map → BackofficeEntityActionFormDialog-BgMuhyU8.js.map} +1 -1
  9. package/lib/esm/{BackofficeEntityDetailLayoutContext-C_tBqkVq.js → BackofficeEntityDetailLayoutContext-DeuH5PCW.js} +1 -1
  10. package/lib/esm/{BackofficeEntityDetailLayoutContext-C_tBqkVq.js.map → BackofficeEntityDetailLayoutContext-DeuH5PCW.js.map} +1 -1
  11. package/lib/esm/{BackofficeEntityDetailLayoutPage-DXjRqvcZ.js → BackofficeEntityDetailLayoutPage-Duc_DcIV.js} +2 -2
  12. package/lib/esm/{BackofficeEntityDetailLayoutPage-DXjRqvcZ.js.map → BackofficeEntityDetailLayoutPage-Duc_DcIV.js.map} +1 -1
  13. package/lib/esm/{BackofficeEntityDetailPage-DPFXbJxC.js → BackofficeEntityDetailPage-ByioPO5K.js} +29 -20
  14. package/lib/esm/BackofficeEntityDetailPage-ByioPO5K.js.map +1 -0
  15. package/lib/esm/{BackofficeEntityDetailUnknownPageRedirect-DRWTeox-.js → BackofficeEntityDetailUnknownPageRedirect-xupMeril.js} +2 -2
  16. package/lib/esm/{BackofficeEntityDetailUnknownPageRedirect-DRWTeox-.js.map → BackofficeEntityDetailUnknownPageRedirect-xupMeril.js.map} +1 -1
  17. package/lib/esm/{BackofficeEntityListPage-C8Ucmc_E.js → BackofficeEntityListPage-dyE4er_s.js} +7 -4
  18. package/lib/esm/BackofficeEntityListPage-dyE4er_s.js.map +1 -0
  19. package/lib/esm/BackofficeErrorBoundary-BwRVSDHU.js.map +1 -1
  20. package/lib/esm/BackofficeHubPage-D2k0ZO6c.js +136 -0
  21. package/lib/esm/BackofficeHubPage-D2k0ZO6c.js.map +1 -0
  22. package/lib/esm/BackofficeLayoutPage-BiSUwAi9.js +625 -0
  23. package/lib/esm/BackofficeLayoutPage-BiSUwAi9.js.map +1 -0
  24. package/lib/esm/{BackofficeLoginPage-Cc3kcOQV.js → BackofficeLoginPage-BMPhO1cr.js} +4 -4
  25. package/lib/esm/{BackofficeLoginPage-Cc3kcOQV.js.map → BackofficeLoginPage-BMPhO1cr.js.map} +1 -1
  26. package/lib/esm/{BackofficePasswordResetCompletePage-CF_0t3Nq.js → BackofficePasswordResetCompletePage-OApMUiOi.js} +3 -3
  27. package/lib/esm/{BackofficePasswordResetCompletePage-CF_0t3Nq.js.map → BackofficePasswordResetCompletePage-OApMUiOi.js.map} +1 -1
  28. package/lib/esm/{BackofficePasswordResetRequestPage-BJOrQXcy.js → BackofficePasswordResetRequestPage-DPDImb37.js} +2 -2
  29. package/lib/esm/{BackofficePasswordResetRequestPage-BJOrQXcy.js.map → BackofficePasswordResetRequestPage-DPDImb37.js.map} +1 -1
  30. package/lib/esm/BackofficePermissionsContext-CmWwudBU.js +11 -0
  31. package/lib/esm/BackofficePermissionsContext-CmWwudBU.js.map +1 -0
  32. package/lib/esm/BackofficeRightPageLayout-BZb7LhT-.js +53 -0
  33. package/lib/esm/BackofficeRightPageLayout-BZb7LhT-.js.map +1 -0
  34. package/lib/esm/{BackofficeTopbarPortalContext-iD7dm4_h.js → BackofficeTopbarPortalContext-CphoSrZD.js} +1 -1
  35. package/lib/esm/{BackofficeTopbarPortalContext-iD7dm4_h.js.map → BackofficeTopbarPortalContext-CphoSrZD.js.map} +1 -1
  36. package/lib/esm/{BackofficeVerifyEmailPage-C81LlsNM.js → BackofficeVerifyEmailPage-DHuSOxDf.js} +3 -3
  37. package/lib/esm/{BackofficeVerifyEmailPage-C81LlsNM.js.map → BackofficeVerifyEmailPage-DHuSOxDf.js.map} +1 -1
  38. package/lib/esm/EntityFilterValue-BWUdPBwp.js.map +1 -1
  39. package/lib/esm/EntityIdPickerDialog-Yhmr-WsV.js.map +1 -1
  40. package/lib/esm/{LazyBackofficeEntityActionFormDialog-DVPQyWlr.js → LazyBackofficeEntityActionFormDialog-DwPGe2Qv.js} +110 -123
  41. package/lib/esm/LazyBackofficeEntityActionFormDialog-DwPGe2Qv.js.map +1 -0
  42. package/lib/esm/PasswordResetCompleteScreen-Cgg96DPo.js.map +1 -1
  43. package/lib/esm/PasswordResetRequestScreen-I1nFvGLd.js.map +1 -1
  44. package/lib/esm/VerifyEmailScreen-Br5KyHjg.js.map +1 -1
  45. package/lib/esm/backoffice-react.js +295 -252
  46. package/lib/esm/backoffice-react.js.map +1 -1
  47. package/lib/esm/{backofficeAuthPaths-BiJvoI5Q.js → backofficeAuthPaths-2KMmkBLv.js} +1 -1
  48. package/lib/esm/{backofficeAuthPaths-BiJvoI5Q.js.map → backofficeAuthPaths-2KMmkBLv.js.map} +1 -1
  49. package/lib/esm/{buildBreadcrumbs-CqF9Nh6x.js → buildBreadcrumbs-C9cyiXb7.js} +8 -4
  50. package/lib/esm/buildBreadcrumbs-C9cyiXb7.js.map +1 -0
  51. package/lib/esm/buildDataTableColumns-D95yRO2W.js +65 -0
  52. package/lib/esm/buildDataTableColumns-D95yRO2W.js.map +1 -0
  53. package/lib/esm/environment-DQfVyWHJ.js.map +1 -1
  54. package/lib/esm/mutationResult-CcQMY13J.js.map +1 -1
  55. package/lib/esm/pageResolution-hAQA5C6S.js.map +1 -1
  56. package/lib/esm/sidebarUtils-BZETlHea.js +74 -0
  57. package/lib/esm/sidebarUtils-BZETlHea.js.map +1 -0
  58. package/lib/esm/style.css +1 -1
  59. package/lib/esm/synchronizeAuthStatusQuery-BoPKMrP1.js.map +1 -1
  60. package/lib/esm/{toastViewAction-BGTS7vqm.js → toastViewAction-DJkv_4p9.js} +1 -1
  61. package/lib/esm/{toastViewAction-BGTS7vqm.js.map → toastViewAction-DJkv_4p9.js.map} +1 -1
  62. package/lib/esm/useAuth-CheTnq60.js.map +1 -1
  63. package/lib/esm/{useBackofficeAuth-ers1FUGe.js → useBackofficeAuth-DVAXNAjP.js} +1 -1
  64. package/lib/esm/{useBackofficeAuth-ers1FUGe.js.map → useBackofficeAuth-DVAXNAjP.js.map} +1 -1
  65. package/lib/esm/{useBackofficeLazyValue-Bh_13h8A.js → useBackofficeLazyValue-CoIAK-5N.js} +1 -1
  66. package/lib/esm/{useBackofficeLazyValue-Bh_13h8A.js.map → useBackofficeLazyValue-CoIAK-5N.js.map} +1 -1
  67. package/lib/esm/useBackofficeListUrlState-D4fx5O7u.js.map +1 -1
  68. package/lib/esm/useBackofficeReactTranslation-Btt58EIo.js.map +1 -1
  69. package/lib/types/components/backoffice/columns/buildDataTableColumns.d.ts.map +1 -1
  70. package/lib/types/components/backoffice/layout/BackofficePermissionsContext.d.ts +8 -0
  71. package/lib/types/components/backoffice/layout/BackofficePermissionsContext.d.ts.map +1 -0
  72. package/lib/types/components/backoffice/layout/breadcrumb/buildBreadcrumbs.d.ts +4 -0
  73. package/lib/types/components/backoffice/layout/breadcrumb/buildBreadcrumbs.d.ts.map +1 -1
  74. package/lib/types/components/backoffice/layout/buildSidebarSections.d.ts +2 -1
  75. package/lib/types/components/backoffice/layout/buildSidebarSections.d.ts.map +1 -1
  76. package/lib/types/components/backoffice/layout/sidebarUtils.d.ts +13 -2
  77. package/lib/types/components/backoffice/layout/sidebarUtils.d.ts.map +1 -1
  78. package/lib/types/components/backoffice/scaffolds/BackofficeEntityListScaffold.d.ts.map +1 -1
  79. package/lib/types/hooks/useSidebarGroupCollapse.d.ts +1 -0
  80. package/lib/types/hooks/useSidebarGroupCollapse.d.ts.map +1 -1
  81. package/lib/types/i18n/resources.d.ts +30 -0
  82. package/lib/types/i18n/resources.d.ts.map +1 -1
  83. package/lib/types/pages/BackofficeDashboardPage.d.ts.map +1 -1
  84. package/lib/types/pages/BackofficeDashboardPage.helpers.d.ts.map +1 -1
  85. package/lib/types/pages/BackofficeEntityDetailPage.d.ts.map +1 -1
  86. package/lib/types/pages/BackofficeEntityDetailPage.view-helpers.d.ts +1 -0
  87. package/lib/types/pages/BackofficeEntityDetailPage.view-helpers.d.ts.map +1 -1
  88. package/lib/types/pages/BackofficeEntityListPage.d.ts.map +1 -1
  89. package/lib/types/pages/BackofficeEntityListPage.helpers.d.ts.map +1 -1
  90. package/lib/types/pages/BackofficeHubPage.d.ts +8 -0
  91. package/lib/types/pages/BackofficeHubPage.d.ts.map +1 -0
  92. package/lib/types/pages/BackofficeLayoutPage.d.ts.map +1 -1
  93. package/lib/types/pages/backofficeHubPage.css.d.ts +15 -0
  94. package/lib/types/pages/backofficeHubPage.css.d.ts.map +1 -0
  95. package/lib/types/provider/types.d.ts +81 -1
  96. package/lib/types/provider/types.d.ts.map +1 -1
  97. package/lib/types/router/createBackofficeRoutes.d.ts +6 -1
  98. package/lib/types/router/createBackofficeRoutes.d.ts.map +1 -1
  99. package/package.json +14 -14
  100. package/lib/esm/BackofficeDashboardPage-YWvoQODn.js.map +0 -1
  101. package/lib/esm/BackofficeEntityDetailPage-DPFXbJxC.js.map +0 -1
  102. package/lib/esm/BackofficeEntityListPage-C8Ucmc_E.js.map +0 -1
  103. package/lib/esm/BackofficeLayoutPage-CKXS0nDO.js +0 -485
  104. package/lib/esm/BackofficeLayoutPage-CKXS0nDO.js.map +0 -1
  105. package/lib/esm/BackofficeRightPageLayout-DZQvIHnj.js +0 -107
  106. package/lib/esm/BackofficeRightPageLayout-DZQvIHnj.js.map +0 -1
  107. package/lib/esm/LazyBackofficeEntityActionFormDialog-DVPQyWlr.js.map +0 -1
  108. package/lib/esm/buildBreadcrumbs-CqF9Nh6x.js.map +0 -1
  109. package/lib/esm/sidebarUtils-CuwJ_3mD.js +0 -34
  110. package/lib/esm/sidebarUtils-CuwJ_3mD.js.map +0 -1
@@ -1,485 +0,0 @@
1
- import { o as e } from "./environment-DQfVyWHJ.js";
2
- import { t } from "./useRelayEnvironment-vQ86aW-n.js";
3
- import { r as n, t as r } from "./useBackofficeReactTranslation-Btt58EIo.js";
4
- import { a as i, i as a, n as o, r as s, t as c } from "./sidebarUtils-CuwJ_3mD.js";
5
- import { t as l } from "./BackofficeErrorBoundary-BwRVSDHU.js";
6
- import { t as u } from "./BackofficeTopbarPortalContext-iD7dm4_h.js";
7
- import { t as d } from "./backofficeAuthPaths-BiJvoI5Q.js";
8
- import { Suspense as f, useCallback as p, useContext as m, useEffect as h, useMemo as g, useState as _ } from "react";
9
- import { useTranslation as v } from "react-i18next";
10
- import { RoutingContext as y, useLocation as b } from "@plumile/router";
11
- import { AdminShellLayout as x, BackofficeSidebarProfileMenu as S, Button as C, EnvironmentBadge as ee, GlobalSearchInput as w, GripDotsSvg as T, InlineBanner as E, PinFilledSvg as D, PinSvg as O, SidebarHomeSvg as k, SidebarTasksSvg as A, Skeleton as j, ToastProvider as M } from "@plumile/ui";
12
- import { commitMutation as te, usePreloadedQuery as N } from "react-relay";
13
- import { jsx as P, jsxs as F } from "react/jsx-runtime";
14
- //#region src/hooks/useBackofficeSidebarPins.ts
15
- var I = "backoffice.sidebar.pins.v1", L = (e) => {
16
- if (typeof window > "u") return [];
17
- try {
18
- let t = window.localStorage.getItem(e);
19
- if (t == null) return [];
20
- let n = JSON.parse(t);
21
- return Array.isArray(n) ? n.filter((e) => typeof e == "string") : [];
22
- } catch {
23
- return [];
24
- }
25
- }, R = (e, t) => {
26
- let n = [], r = /* @__PURE__ */ new Set();
27
- return e.forEach((e) => {
28
- t.has(e) && (r.has(e) || (r.add(e), n.push(e)));
29
- }), n;
30
- }, ne = (e) => {
31
- let { storageKey: t = I, visibleEntityIds: n } = e, r = g(() => new Set(n), [n]), [i, a] = _(() => R(L(t), r));
32
- h(() => {
33
- a((e) => {
34
- let t = R(e, r);
35
- if (t.length === e.length) {
36
- let n = !0;
37
- for (let r = 0; r < t.length; r += 1) if (t[r] !== e[r]) {
38
- n = !1;
39
- break;
40
- }
41
- if (n) return e;
42
- }
43
- return t;
44
- });
45
- }, [r]), h(() => {
46
- a(R(L(t), r));
47
- }, [t, r]), h(() => {
48
- if (!(typeof window > "u")) try {
49
- window.localStorage.setItem(t, JSON.stringify(i));
50
- } catch {}
51
- }, [i, t]);
52
- let o = g(() => new Set(i), [i]), s = p((e) => {
53
- r.has(e) && a((t) => t.includes(e) ? t : [...t, e]);
54
- }, [r]), c = p((e) => {
55
- a((t) => t.filter((t) => t !== e));
56
- }, []), l = p((e) => {
57
- o.has(e) ? c(e) : s(e);
58
- }, [
59
- s,
60
- o,
61
- c
62
- ]), u = p((e, t) => {
63
- e !== t && a((n) => {
64
- let r = n.indexOf(e), i = n.indexOf(t);
65
- if (r === -1 || i === -1 || r === i) return n;
66
- let a = [...n];
67
- return a.splice(r, 1), a.splice(i, 0, e), a;
68
- });
69
- }, []);
70
- return {
71
- pins: i,
72
- isPinned: p((e) => o.has(e), [o]),
73
- pin: s,
74
- unpin: c,
75
- toggle: l,
76
- reorder: u
77
- };
78
- }, z = (e, t) => {
79
- let n = {};
80
- return e.forEach((e) => {
81
- n[e] = !0;
82
- }), t != null && e.includes(t) && (n[t] = !1), n;
83
- }, re = (e) => {
84
- let { groupIds: t, activeGroupId: n } = e, r = g(() => [...t], [t]), [i, a] = _(() => z(r, n));
85
- return h(() => {
86
- a((e) => {
87
- let t = {};
88
- return r.forEach((n) => {
89
- t[n] = e[n] ?? !0;
90
- }), n != null && r.includes(n) && (t[n] = !1), t;
91
- });
92
- }, [n, r]), h(() => {
93
- n != null && a((e) => e[n] === !1 ? e : {
94
- ...e,
95
- [n]: !1
96
- });
97
- }, [n]), {
98
- collapsedByGroupId: i,
99
- setCollapsed: p((e, t) => {
100
- a((n) => n[e] === t ? n : {
101
- ...n,
102
- [e]: t
103
- });
104
- }, [])
105
- };
106
- }, B = "_1xws1b00 txvbqb9jg txvbqbcp txvbqbdoy txvbqbtxp txvbqbc6p txvbqb1rg txvbqb12g txvbqb1py txvbqblag txvbqbv0t txvbqbva1 txvbqbv txvbqb78 txvbqb6x txvbqb7k", V = (e, t) => e == null ? t ?? null : /* @__PURE__ */ P(e, {
107
- width: 18,
108
- height: 18,
109
- "aria-hidden": "true"
110
- });
111
- function ie(e) {
112
- let { basePath: t, pathname: n, entities: r, sidebar: i, permissions: l, searchQuery: u, tApp: d, t: f, pinnedEntityIds: p = [], onTogglePin: m, onReorderPin: h, collapsedByGroupId: g, onGroupCollapsedChange: _ } = e, v = a(r, i), y = Object.entries(v), b = new Set(p), x = f("sidebar.actions.pin"), S = f("sidebar.actions.unpin"), C = f("sidebar.actions.reorder"), ee = c(v), w = u?.trim().toLowerCase() ?? "", E = (e) => {
113
- if (m == null) return null;
114
- let t = b.has(e), n = x, r = O;
115
- return t && (n = S, r = D), /* @__PURE__ */ P("button", {
116
- type: "button",
117
- className: B,
118
- "aria-pressed": t,
119
- "aria-label": n,
120
- title: n,
121
- onClick: (t) => {
122
- t.preventDefault(), t.stopPropagation(), m(e);
123
- },
124
- children: /* @__PURE__ */ P(r, {
125
- width: 14,
126
- height: 14,
127
- "aria-hidden": "true"
128
- })
129
- });
130
- }, j = (e) => {
131
- let { entityId: t, groupId: a, groupIcon: c, enableReorder: u } = e, f = r[t];
132
- if (f == null) return null;
133
- let p = {
134
- kind: "entity",
135
- id: t
136
- };
137
- if (f.kind === "tool" && (p = {
138
- kind: "tool",
139
- id: t
140
- }), i?.isItemVisible?.(p, l) === !1) return null;
141
- if (f.kind === "tool") {
142
- let e = s(f.label, d);
143
- return w !== "" && !e.toLowerCase().includes(w) ? null : {
144
- id: `tool-${t}`,
145
- data: {
146
- kind: "tool",
147
- id: t,
148
- groupId: a
149
- },
150
- label: e,
151
- href: f.routes.list,
152
- icon: V(c, /* @__PURE__ */ P(A, {
153
- width: 18,
154
- height: 18,
155
- "aria-hidden": "true"
156
- })),
157
- isActive: o(n, f.routes.list),
158
- ariaLabel: e,
159
- actionSlot: E(t)
160
- };
161
- }
162
- if (!f.hasList) return null;
163
- let m = s(f.label, d);
164
- if (w !== "" && !m.toLowerCase().includes(w)) return null;
165
- let g, _, v, y, b = !1;
166
- u === !0 && h != null && (b = !0, g = /* @__PURE__ */ P(T, {
167
- width: 14,
168
- height: 14,
169
- "aria-hidden": "true"
170
- }), _ = (e) => {
171
- let { dataTransfer: n } = e;
172
- n.effectAllowed = "move", n.setData("text/plain", t);
173
- }, v = (e) => {
174
- e.preventDefault();
175
- let { dataTransfer: t } = e;
176
- t.dropEffect = "move";
177
- }, y = (e) => {
178
- e.preventDefault();
179
- let n = e.dataTransfer.getData("text/plain");
180
- n === "" || n === t || h(n, t);
181
- });
182
- let x;
183
- return g != null && (x = C), {
184
- id: t,
185
- data: {
186
- kind: "entity",
187
- id: t,
188
- groupId: a
189
- },
190
- label: m,
191
- href: f.routes.list,
192
- icon: V(c, /* @__PURE__ */ P(A, {
193
- width: 18,
194
- height: 18,
195
- "aria-hidden": "true"
196
- })),
197
- isActive: o(n, f.routes.list),
198
- ariaLabel: m,
199
- actionSlot: E(t),
200
- dragHandleSlot: g,
201
- dragHandleLabel: x,
202
- draggable: b,
203
- onDragStart: _,
204
- onDragOver: v,
205
- onDrop: y
206
- };
207
- }, M = [];
208
- if (p.length > 0) {
209
- let e = p.map((e) => {
210
- let t = ee.get(e);
211
- return j({
212
- entityId: e,
213
- groupId: t?.groupId,
214
- groupIcon: t?.icon,
215
- enableReorder: !0
216
- });
217
- }).filter((e) => e != null);
218
- e.length > 0 && M.push({
219
- id: "pinned",
220
- title: f("sidebar.sections.pinned"),
221
- items: e,
222
- collapsible: !1
223
- });
224
- }
225
- return y.forEach(([e, r], a) => {
226
- if (r.isVisible != null && !r.isVisible(l)) return;
227
- let c = [];
228
- if (a === 0 && i?.isItemVisible?.({
229
- kind: "dashboard",
230
- id: "dashboard"
231
- }, l) !== !1) {
232
- let r = f("sidebar.items.dashboard");
233
- if (w !== "" && !r.toLowerCase().includes(w)) return;
234
- c.push({
235
- id: "dashboard",
236
- data: {
237
- kind: "dashboard",
238
- id: "dashboard",
239
- groupId: e
240
- },
241
- label: r,
242
- href: t,
243
- icon: V(void 0, /* @__PURE__ */ P(k, {
244
- width: 18,
245
- height: 18,
246
- "aria-hidden": "true"
247
- })),
248
- isActive: o(n, t),
249
- ariaLabel: f("sidebar.items.dashboard")
250
- });
251
- }
252
- if (r.entities != null && r.entities.forEach((t) => {
253
- let n = j({
254
- entityId: t,
255
- groupId: e,
256
- groupIcon: r.icon
257
- });
258
- n != null && c.push(n);
259
- }), c.length === 0) return;
260
- let u;
261
- r.title != null && (u = s(r.title, d));
262
- let p = g?.[e], m;
263
- _ != null && (m = (t) => {
264
- _(e, t);
265
- }), M.push({
266
- id: e,
267
- title: u,
268
- items: c,
269
- collapsible: !0,
270
- defaultCollapsed: !0,
271
- isCollapsed: p,
272
- onCollapsedChange: m
273
- });
274
- }), M;
275
- }
276
- //#endregion
277
- //#region src/components/backoffice/routing/backofficeContentError.css.ts
278
- var H = "txvbqb9ip txvbqbai7 txvbqbu7g", U = "txvbqbwy", W = (e) => {
279
- if (e instanceof Error) {
280
- let t = e.message.trim();
281
- return t.length > 0 ? t : null;
282
- }
283
- if (typeof e == "string") {
284
- let t = e.trim();
285
- return t.length > 0 ? t : null;
286
- }
287
- return null;
288
- }, G = ({ error: e, onRetry: t }) => {
289
- let { t: n } = r(), i = W(e);
290
- return /* @__PURE__ */ P("div", {
291
- className: H,
292
- role: "alert",
293
- children: /* @__PURE__ */ P(E, {
294
- tone: "danger",
295
- className: U,
296
- actions: /* @__PURE__ */ P(C, {
297
- type: "button",
298
- variant: "secondary",
299
- size: "small",
300
- onClick: t,
301
- children: n("common.actions.retry")
302
- }),
303
- children: i
304
- })
305
- });
306
- }, K = "txvbqb9ip txvbqbai7 txvbqbaop txvbqbu7g txvbqbjs7", q = "txvbqbjfg", J = "txvbqb9iy txvbqbaop txvbqbc17", Y = "txvbqb9ip txvbqbai7 txvbqbaog txvbqblbg txvbqbjny txvbqb1ry txvbqb1cp txvbqb1qg txvbqbwp txvbqbv45", X = () => /* @__PURE__ */ F("div", {
307
- className: K,
308
- role: "status",
309
- "aria-live": "polite",
310
- "aria-busy": "true",
311
- children: [
312
- /* @__PURE__ */ P(j, {
313
- variant: "text",
314
- width: "38%",
315
- className: q
316
- }),
317
- /* @__PURE__ */ P(j, {
318
- variant: "text",
319
- width: "62%"
320
- }),
321
- /* @__PURE__ */ P("div", {
322
- className: J,
323
- children: Array.from({ length: 4 }, (e, t) => /* @__PURE__ */ F("div", {
324
- className: Y,
325
- children: [
326
- /* @__PURE__ */ P(j, {
327
- variant: "text",
328
- width: "46%"
329
- }),
330
- /* @__PURE__ */ P(j, {
331
- variant: "text",
332
- width: "82%",
333
- lines: 2
334
- }),
335
- /* @__PURE__ */ P(j, {
336
- variant: "block",
337
- width: "100%",
338
- height: 120
339
- })
340
- ]
341
- }, `content-skeleton-${t}`))
342
- })
343
- ]
344
- }), Z = "txvbqb9ip txvbqbai7 txvbqbjs7 txvbqbu7g txvbqbk5y", ae = ({ children: e }) => /* @__PURE__ */ P("div", {
345
- className: Z,
346
- children: /* @__PURE__ */ P(l, {
347
- fallback: ({ error: e, reset: t }) => /* @__PURE__ */ P(G, {
348
- error: e,
349
- onRetry: t
350
- }),
351
- children: /* @__PURE__ */ P(f, {
352
- fallback: /* @__PURE__ */ P(X, {}),
353
- children: e
354
- })
355
- })
356
- }), Q = (e) => e?.trim() ?? "", oe = ({ viewer: e, unknownUserLabel: t }) => {
357
- let n = [Q(e?.firstName), Q(e?.lastName)].filter((e) => e !== "").join(" ").trim();
358
- n === "" && (n = t);
359
- let r = Q(e?.email), i = Q(e?.initials);
360
- i === "" && (i = "?");
361
- let a = [n];
362
- return r !== "" && a.push(r), {
363
- displayName: n,
364
- email: r,
365
- initials: i,
366
- ariaLabel: a.join(" - ")
367
- };
368
- }, $ = ({ children: o, permissions: s, authStatus: c, activeGroupId: l }) => {
369
- let { t: f } = v(), { t: h } = r(), { pathname: C } = b(), T = m(y), E = t(), { auth: D, basePath: O, entities: k, sidebar: A } = n(), [j, N] = _(""), [F, I] = _(!1), [L, R] = _(!1), [z, B] = _(null), V = g(() => a(k, A), [k, A]), H = g(() => Object.keys(V), [V]), { pins: U, toggle: W, reorder: G } = ne({ visibleEntityIds: g(() => i(V, k, A, s), [
370
- k,
371
- V,
372
- s,
373
- A
374
- ]) }), { collapsedByGroupId: K, setCollapsed: q } = re({
375
- groupIds: H,
376
- activeGroupId: l
377
- }), J = g(() => ie({
378
- basePath: O,
379
- pathname: C,
380
- entities: k,
381
- sidebar: A,
382
- permissions: s,
383
- searchQuery: j,
384
- tApp: f,
385
- t: h,
386
- pinnedEntityIds: U,
387
- onTogglePin: W,
388
- onReorderPin: G,
389
- collapsedByGroupId: K,
390
- onGroupCollapsedChange: q
391
- }), [
392
- O,
393
- K,
394
- k,
395
- C,
396
- s,
397
- U,
398
- G,
399
- q,
400
- A,
401
- j,
402
- h,
403
- f,
404
- W
405
- ]), Y = g(() => import.meta.env?.DEV === !0 ? "dev" : "prod", []), X = p(() => {
406
- L || (R(!0), (async () => {
407
- try {
408
- let t = await D.logout.load();
409
- await new Promise((e, n) => {
410
- te(E, {
411
- mutation: t.logoutMutation,
412
- variables: {},
413
- onCompleted: () => {
414
- e();
415
- },
416
- onError: (e) => {
417
- n(e);
418
- }
419
- });
420
- }), localStorage.removeItem("auth_token"), localStorage.removeItem("remember_me"), e(), T?.history.push({ pathname: d(O) });
421
- } finally {
422
- R(!1);
423
- }
424
- })().catch(() => {}));
425
- }, [
426
- D.logout,
427
- O,
428
- L,
429
- E,
430
- T
431
- ]), Z = c?.me ?? null, Q = /* @__PURE__ */ P(S, {
432
- collapsed: F,
433
- viewer: g(() => oe({
434
- viewer: Z,
435
- unknownUserLabel: h("sidebar.profile.unknownUser")
436
- }), [h, Z]),
437
- labels: {
438
- sectionTitle: h("sidebar.profile.title"),
439
- menuAriaLabel: h("sidebar.profile.menuAriaLabel"),
440
- signOut: h("sidebar.profile.actions.signOut")
441
- },
442
- onSignOut: X,
443
- isSigningOut: L
444
- }), $ = null;
445
- return z != null && ($ = /* @__PURE__ */ P(ae, { children: o })), /* @__PURE__ */ P(M, { children: /* @__PURE__ */ P(x, {
446
- sidebar: {
447
- sections: J,
448
- header: /* @__PURE__ */ P(ee, { environment: Y }),
449
- search: /* @__PURE__ */ P(w, {
450
- value: j,
451
- onChange: N,
452
- placeholder: h("sidebar.search.placeholder"),
453
- ariaLabel: h("sidebar.search.placeholder")
454
- }),
455
- footer: Q,
456
- isCollapsed: F,
457
- onCollapsedChange: I
458
- },
459
- topbar: { breadcrumb: /* @__PURE__ */ P("div", { ref: B }) },
460
- children: /* @__PURE__ */ P(u, {
461
- value: { target: z },
462
- children: $
463
- })
464
- }) });
465
- }, se = ({ children: e, permissionsQuery: t, prepared: n, authStatus: r, activeGroupId: i }) => /* @__PURE__ */ P($, {
466
- permissions: N(t, n),
467
- authStatus: r,
468
- activeGroupId: i,
469
- children: e
470
- }), ce = ({ children: e, permissionsQuery: t, prepared: n, authStatus: r, activeGroupId: i }) => t != null && n != null ? /* @__PURE__ */ P(se, {
471
- permissionsQuery: t,
472
- prepared: n,
473
- authStatus: r,
474
- activeGroupId: i,
475
- children: e
476
- }) : /* @__PURE__ */ P($, {
477
- permissions: null,
478
- authStatus: r,
479
- activeGroupId: i,
480
- children: e
481
- });
482
- //#endregion
483
- export { ce as BackofficeLayoutPage, ce as default };
484
-
485
- //# sourceMappingURL=BackofficeLayoutPage-CKXS0nDO.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BackofficeLayoutPage-CKXS0nDO.js","names":[],"sources":["../../src/hooks/useBackofficeSidebarPins.ts","../../src/hooks/useSidebarGroupCollapse.ts","../../src/components/backoffice/layout/backofficeSidebarActions.css.ts","../../src/components/backoffice/layout/buildSidebarSections.tsx","../../src/components/backoffice/routing/backofficeContentError.css.ts","../../src/components/backoffice/routing/BackofficeContentError.tsx","../../src/components/backoffice/routing/backofficeContentFallback.css.ts","../../src/components/backoffice/routing/BackofficeContentFallback.tsx","../../src/components/backoffice/routing/backofficeContentBoundary.css.ts","../../src/components/backoffice/routing/BackofficeContentBoundary.tsx","../../src/components/backoffice/layout/mapViewerToSidebarProfileView.ts","../../src/pages/BackofficeLayoutPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from 'react';\n\nconst DEFAULT_STORAGE_KEY = 'backoffice.sidebar.pins.v1';\n\ntype PinsPayload = unknown;\n\nconst readPinsFromStorage = (storageKey: string): string[] => {\n if (typeof window === 'undefined') {\n return [];\n }\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (raw == null) {\n return [];\n }\n const parsed = JSON.parse(raw) as PinsPayload;\n if (!Array.isArray(parsed)) {\n return [];\n }\n return parsed.filter((entry): entry is string => {\n return typeof entry === 'string';\n });\n } catch {\n return [];\n }\n};\n\nconst normalizePins = (\n pins: readonly string[],\n validIds: Set<string>,\n): string[] => {\n const output: string[] = [];\n const seen = new Set<string>();\n pins.forEach((entry) => {\n if (!validIds.has(entry)) {\n return;\n }\n if (seen.has(entry)) {\n return;\n }\n seen.add(entry);\n output.push(entry);\n });\n return output;\n};\n\nexport type SidebarPinsState = {\n pins: readonly string[];\n isPinned: (id: string) => boolean;\n pin: (id: string) => void;\n unpin: (id: string) => void;\n toggle: (id: string) => void;\n reorder: (fromId: string, toId: string) => void;\n};\n\nexport type UseBackofficeSidebarPinsInput = {\n storageKey?: string;\n visibleEntityIds: readonly string[];\n};\n\nexport const useBackofficeSidebarPins = (\n input: UseBackofficeSidebarPinsInput,\n): SidebarPinsState => {\n const { storageKey = DEFAULT_STORAGE_KEY, visibleEntityIds } = input;\n const validIds = useMemo(() => {\n return new Set(visibleEntityIds);\n }, [visibleEntityIds]);\n\n const [pins, setPins] = useState<string[]>(() => {\n const stored = readPinsFromStorage(storageKey);\n return normalizePins(stored, validIds);\n });\n\n useEffect(() => {\n setPins((prev) => {\n const normalized = normalizePins(prev, validIds);\n if (normalized.length === prev.length) {\n let unchanged = true;\n for (let index = 0; index < normalized.length; index += 1) {\n if (normalized[index] !== prev[index]) {\n unchanged = false;\n break;\n }\n }\n if (unchanged) {\n return prev;\n }\n }\n return normalized;\n });\n }, [validIds]);\n\n useEffect(() => {\n const stored = readPinsFromStorage(storageKey);\n setPins(normalizePins(stored, validIds));\n }, [storageKey, validIds]);\n\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n try {\n window.localStorage.setItem(storageKey, JSON.stringify(pins));\n } catch {\n // Ignore storage errors in non-browser or restricted environments.\n }\n }, [pins, storageKey]);\n\n const pinsSet = useMemo(() => {\n return new Set(pins);\n }, [pins]);\n\n const pin = useCallback(\n (id: string) => {\n if (!validIds.has(id)) {\n return;\n }\n setPins((prev) => {\n if (prev.includes(id)) {\n return prev;\n }\n return [...prev, id];\n });\n },\n [validIds],\n );\n\n const unpin = useCallback((id: string) => {\n setPins((prev) => {\n return prev.filter((entry) => {\n return entry !== id;\n });\n });\n }, []);\n\n const toggle = useCallback(\n (id: string) => {\n if (pinsSet.has(id)) {\n unpin(id);\n } else {\n pin(id);\n }\n },\n [pin, pinsSet, unpin],\n );\n\n const reorder = useCallback((fromId: string, toId: string) => {\n if (fromId === toId) {\n return;\n }\n setPins((prev) => {\n const fromIndex = prev.indexOf(fromId);\n const toIndex = prev.indexOf(toId);\n if (fromIndex === -1 || toIndex === -1) {\n return prev;\n }\n if (fromIndex === toIndex) {\n return prev;\n }\n const next = [...prev];\n next.splice(fromIndex, 1);\n next.splice(toIndex, 0, fromId);\n return next;\n });\n }, []);\n\n const isPinned = useCallback(\n (id: string) => {\n return pinsSet.has(id);\n },\n [pinsSet],\n );\n\n return {\n pins,\n isPinned,\n pin,\n unpin,\n toggle,\n reorder,\n };\n};\n\nexport const __test = {\n normalizePins,\n readPinsFromStorage,\n};\n\nexport default useBackofficeSidebarPins;\n","import { useCallback, useEffect, useMemo, useState } from 'react';\n\nexport type SidebarGroupCollapseState = Record<string, boolean | undefined>;\n\nexport type UseSidebarGroupCollapseInput = {\n groupIds: readonly string[];\n activeGroupId?: string | null;\n};\n\nconst buildInitialState = (\n groupIds: readonly string[],\n activeGroupId?: string | null,\n): SidebarGroupCollapseState => {\n const state: SidebarGroupCollapseState = {};\n groupIds.forEach((groupId) => {\n state[groupId] = true;\n });\n if (activeGroupId != null && groupIds.includes(activeGroupId)) {\n state[activeGroupId] = false;\n }\n return state;\n};\n\nexport const useSidebarGroupCollapse = (\n input: UseSidebarGroupCollapseInput,\n): {\n collapsedByGroupId: SidebarGroupCollapseState;\n setCollapsed: (groupId: string, collapsed: boolean) => void;\n} => {\n const { groupIds, activeGroupId } = input;\n\n const groupIdList = useMemo(() => {\n return [...groupIds];\n }, [groupIds]);\n\n const [collapsedByGroupId, setCollapsedByGroupId] =\n useState<SidebarGroupCollapseState>(() => {\n return buildInitialState(groupIdList, activeGroupId);\n });\n\n useEffect(() => {\n setCollapsedByGroupId((prev) => {\n const next: SidebarGroupCollapseState = {};\n\n groupIdList.forEach((groupId) => {\n const existing = prev[groupId];\n next[groupId] = existing ?? true;\n });\n\n if (activeGroupId != null && groupIdList.includes(activeGroupId)) {\n next[activeGroupId] = false;\n }\n\n return next;\n });\n }, [activeGroupId, groupIdList]);\n\n useEffect(() => {\n if (activeGroupId == null) {\n return;\n }\n setCollapsedByGroupId((prev) => {\n if (prev[activeGroupId] === false) {\n return prev;\n }\n return {\n ...prev,\n [activeGroupId]: false,\n };\n });\n }, [activeGroupId]);\n\n const setCollapsed = useCallback((groupId: string, collapsed: boolean) => {\n setCollapsedByGroupId((prev) => {\n if (prev[groupId] === collapsed) {\n return prev;\n }\n return {\n ...prev,\n [groupId]: collapsed,\n };\n });\n }, []);\n\n return {\n collapsedByGroupId,\n setCollapsed,\n };\n};\n\nexport default useSidebarGroupCollapse;\n","import { style } from '@vanilla-extract/css';\n\nimport { sprinkles, vars } from '@plumile/ui';\n\nexport const actionButton = style([\n sprinkles({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 6,\n height: 6,\n borderRadius: 'md',\n borderWidth: 0,\n borderStyle: 'none',\n padding: 0,\n backgroundColor: 'transparent',\n color: 'textSecondary',\n cursor: 'pointer',\n transitionProperty: 'colors',\n transitionDuration: 150,\n transitionTimingFunction: 'ease',\n }),\n {\n selectors: {\n '&:hover': {\n backgroundColor: vars.colors.surfaceMuted,\n color: vars.colors.text,\n },\n '&:focus-visible': {\n outline: `2px solid ${vars.colors['blue-500']}`,\n outlineOffset: 2,\n },\n },\n },\n]);\n","import { type DragEvent, type ReactNode } from 'react';\nimport type { TFunction } from 'i18next';\n\nimport type { BackofficeEntityManifestMap } from '@plumile/backoffice-core/types.js';\nimport type {\n BackofficeSidebarConfig,\n BackofficeSidebarItemDescriptor,\n BackofficeIconComponent,\n} from '../../../provider/types.js';\nimport {\n type AdminSidebarSection,\n type SidebarNavSectionItem,\n GripDotsSvg,\n PinFilledSvg,\n PinSvg,\n SidebarHomeSvg,\n SidebarTasksSvg,\n} from '@plumile/ui';\nimport type { SidebarGroupCollapseState } from '../../../hooks/useSidebarGroupCollapse.js';\nimport * as styles from './backofficeSidebarActions.css.js';\nimport {\n buildEntityGroupLookup,\n isActivePath,\n resolveLabel,\n resolveSidebarGroups,\n} from './sidebarUtils.js';\n\nconst renderIcon = (\n Icon?: BackofficeIconComponent,\n fallback?: ReactNode,\n): ReactNode => {\n if (Icon != null) {\n return <Icon width={18} height={18} aria-hidden=\"true\" />;\n }\n return fallback ?? null;\n};\n\nexport type BuildSidebarSectionsInput = {\n basePath: string;\n pathname: string;\n entities: BackofficeEntityManifestMap;\n sidebar?: BackofficeSidebarConfig;\n permissions: unknown;\n searchQuery?: string;\n tApp: TFunction;\n t: TFunction;\n pinnedEntityIds?: readonly string[];\n onTogglePin?: (entityId: string) => void;\n onReorderPin?: (fromId: string, toId: string) => void;\n collapsedByGroupId?: SidebarGroupCollapseState;\n onGroupCollapsedChange?: (groupId: string, collapsed: boolean) => void;\n};\n\n/**\n * Builds the sidebar sections for the backoffice layout.\n */\nexport function buildSidebarSections(\n input: BuildSidebarSectionsInput,\n): readonly AdminSidebarSection[] {\n const {\n basePath,\n pathname,\n entities,\n sidebar,\n permissions,\n searchQuery,\n tApp,\n t,\n pinnedEntityIds = [],\n onTogglePin,\n onReorderPin,\n collapsedByGroupId,\n onGroupCollapsedChange,\n } = input;\n\n const groups = resolveSidebarGroups(entities, sidebar);\n const entries = Object.entries(groups);\n const pinnedSet = new Set(pinnedEntityIds);\n const pinLabel = t('sidebar.actions.pin');\n const unpinLabel = t('sidebar.actions.unpin');\n const reorderLabel = t('sidebar.actions.reorder');\n const entityGroupLookup = buildEntityGroupLookup(groups);\n const normalizedQuery = searchQuery?.trim().toLowerCase() ?? '';\n\n const renderPinAction = (entityId: string): ReactNode | null => {\n if (onTogglePin == null) {\n return null;\n }\n const isPinned = pinnedSet.has(entityId);\n let label = pinLabel;\n let Icon = PinSvg;\n if (isPinned) {\n label = unpinLabel;\n Icon = PinFilledSvg;\n }\n\n return (\n <button\n type=\"button\"\n className={styles.actionButton}\n aria-pressed={isPinned}\n aria-label={label}\n title={label}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n onTogglePin(entityId);\n }}\n >\n <Icon width={14} height={14} aria-hidden=\"true\" />\n </button>\n );\n };\n\n const buildEntityItem = (inputItem: {\n entityId: string;\n groupId?: string;\n groupIcon?: BackofficeIconComponent;\n enableReorder?: boolean;\n }): SidebarNavSectionItem | null => {\n const { entityId, groupId, groupIcon, enableReorder } = inputItem;\n const config = entities[entityId];\n if (config == null) {\n return null;\n }\n\n let descriptor: BackofficeSidebarItemDescriptor = {\n kind: 'entity',\n id: entityId,\n };\n if (config.kind === 'tool') {\n descriptor = { kind: 'tool', id: entityId };\n }\n const isEntityVisible = sidebar?.isItemVisible?.(descriptor, permissions);\n if (isEntityVisible === false) {\n return null;\n }\n\n if (config.kind === 'tool') {\n const label = resolveLabel(config.label, tApp);\n if (\n normalizedQuery !== '' &&\n !label.toLowerCase().includes(normalizedQuery)\n ) {\n return null;\n }\n return {\n id: `tool-${entityId}`,\n data: {\n kind: 'tool',\n id: entityId,\n groupId,\n },\n label,\n href: config.routes.list,\n icon: renderIcon(\n groupIcon,\n <SidebarTasksSvg width={18} height={18} aria-hidden=\"true\" />,\n ),\n isActive: isActivePath(pathname, config.routes.list),\n ariaLabel: label,\n actionSlot: renderPinAction(entityId),\n };\n }\n\n if (!config.hasList) {\n return null;\n }\n\n const label = resolveLabel(config.label, tApp);\n if (\n normalizedQuery !== '' &&\n !label.toLowerCase().includes(normalizedQuery)\n ) {\n return null;\n }\n\n let dragHandleSlot: ReactNode | undefined;\n let onDragStart: ((event: DragEvent) => void) | undefined;\n let onDragOver: ((event: DragEvent) => void) | undefined;\n let onDrop: ((event: DragEvent) => void) | undefined;\n let draggable = false;\n\n if (enableReorder === true && onReorderPin != null) {\n draggable = true;\n dragHandleSlot = (\n <GripDotsSvg width={14} height={14} aria-hidden=\"true\" />\n );\n onDragStart = (event) => {\n const { dataTransfer } = event;\n dataTransfer.effectAllowed = 'move';\n dataTransfer.setData('text/plain', entityId);\n };\n onDragOver = (event) => {\n event.preventDefault();\n const { dataTransfer } = event;\n dataTransfer.dropEffect = 'move';\n };\n onDrop = (event) => {\n event.preventDefault();\n const fromId = event.dataTransfer.getData('text/plain');\n if (fromId === '' || fromId === entityId) {\n return;\n }\n onReorderPin(fromId, entityId);\n };\n }\n\n let dragHandleLabel: string | undefined;\n if (dragHandleSlot != null) {\n dragHandleLabel = reorderLabel;\n }\n\n return {\n id: entityId,\n data: {\n kind: 'entity',\n id: entityId,\n groupId,\n },\n label,\n href: config.routes.list,\n icon: renderIcon(\n groupIcon,\n <SidebarTasksSvg width={18} height={18} aria-hidden=\"true\" />,\n ),\n isActive: isActivePath(pathname, config.routes.list),\n ariaLabel: label,\n actionSlot: renderPinAction(entityId),\n dragHandleSlot,\n dragHandleLabel,\n draggable,\n onDragStart,\n onDragOver,\n onDrop,\n };\n };\n\n const sections: AdminSidebarSection[] = [];\n\n if (pinnedEntityIds.length > 0) {\n const pinnedItems = pinnedEntityIds\n .map((entityId) => {\n const groupMeta = entityGroupLookup.get(entityId);\n return buildEntityItem({\n entityId,\n groupId: groupMeta?.groupId,\n groupIcon: groupMeta?.icon,\n enableReorder: true,\n });\n })\n .filter((item): item is SidebarNavSectionItem => {\n return item != null;\n });\n\n if (pinnedItems.length > 0) {\n sections.push({\n id: 'pinned',\n title: t('sidebar.sections.pinned'),\n items: pinnedItems,\n collapsible: false,\n });\n }\n }\n\n entries.forEach(([groupId, group], index) => {\n if (group.isVisible != null && !group.isVisible(permissions)) {\n return;\n }\n\n const items: SidebarNavSectionItem[] = [];\n\n if (index === 0) {\n const dashboardDescriptor: BackofficeSidebarItemDescriptor = {\n kind: 'dashboard',\n id: 'dashboard',\n };\n const isDashboardVisible = sidebar?.isItemVisible?.(\n dashboardDescriptor,\n permissions,\n );\n if (isDashboardVisible !== false) {\n const dashboardLabel = t('sidebar.items.dashboard');\n if (\n normalizedQuery !== '' &&\n !dashboardLabel.toLowerCase().includes(normalizedQuery)\n ) {\n return;\n }\n items.push({\n id: 'dashboard',\n data: {\n kind: 'dashboard',\n id: 'dashboard',\n groupId,\n },\n label: dashboardLabel,\n href: basePath,\n icon: renderIcon(\n undefined,\n <SidebarHomeSvg width={18} height={18} aria-hidden=\"true\" />,\n ),\n isActive: isActivePath(pathname, basePath),\n ariaLabel: t('sidebar.items.dashboard'),\n });\n }\n }\n\n if (group.entities != null) {\n group.entities.forEach((entityId) => {\n const item = buildEntityItem({\n entityId,\n groupId,\n groupIcon: group.icon,\n });\n if (item != null) {\n items.push(item);\n }\n });\n }\n\n if (items.length === 0) {\n return;\n }\n\n let title: string | undefined;\n if (group.title != null) {\n title = resolveLabel(group.title, tApp);\n }\n\n const isCollapsed = collapsedByGroupId?.[groupId];\n let onCollapsedChange: ((collapsed: boolean) => void) | undefined;\n if (onGroupCollapsedChange != null) {\n onCollapsedChange = (collapsed: boolean) => {\n onGroupCollapsedChange(groupId, collapsed);\n };\n }\n\n sections.push({\n id: groupId,\n title,\n items,\n collapsible: true,\n defaultCollapsed: true,\n isCollapsed,\n onCollapsedChange,\n });\n });\n\n return sections;\n}\n","import { sprinkles } from '@plumile/ui';\n\nexport const root = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n width: 'full',\n});\n\nexport const banner = sprinkles({\n borderColor: 'borderStrong',\n});\n","import { type JSX } from 'react';\n\nimport { Button, InlineBanner } from '@plumile/ui';\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\n\nimport * as styles from './backofficeContentError.css.js';\n\ntype BackofficeContentErrorProps = {\n error: unknown;\n onRetry: () => void;\n};\n\nconst resolveErrorMessage = (error: unknown): string | null => {\n if (error instanceof Error) {\n const message = error.message.trim();\n if (message.length > 0) {\n return message;\n }\n return null;\n }\n if (typeof error === 'string') {\n const message = error.trim();\n if (message.length > 0) {\n return message;\n }\n return null;\n }\n return null;\n};\n\nexport const BackofficeContentError = ({\n error,\n onRetry,\n}: BackofficeContentErrorProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const description = resolveErrorMessage(error);\n\n return (\n <div className={styles.root} role=\"alert\">\n <InlineBanner\n tone=\"danger\"\n className={styles.banner}\n actions={\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={onRetry}\n >\n {t('common.actions.retry')}\n </Button>\n }\n >\n {description}\n </InlineBanner>\n </div>\n );\n};\n\nexport default BackofficeContentError;\n","import { sprinkles } from '@plumile/ui';\n\nexport const container = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n width: 'full',\n minHeight: 'full',\n});\n\nexport const title = sprinkles({\n maxWidth: 'md',\n});\n\nexport const grid = sprinkles({\n display: 'grid',\n gap: 4,\n gridTemplateColumns: 'autoFitMinmax240',\n});\n\nexport const card = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n padding: 4,\n minHeight: 44,\n borderRadius: 'xl',\n borderWidth: 'default',\n borderStyle: 'solid',\n borderColor: 'borderSubtle',\n backgroundColor: 'surfaceMuted',\n});\n","import { type JSX } from 'react';\n\nimport { Skeleton } from '@plumile/ui';\n\nimport * as styles from './backofficeContentFallback.css.js';\n\nexport const BackofficeContentFallback = (): JSX.Element => {\n return (\n <div\n className={styles.container}\n role=\"status\"\n aria-live=\"polite\"\n aria-busy=\"true\"\n >\n <Skeleton variant=\"text\" width=\"38%\" className={styles.title} />\n <Skeleton variant=\"text\" width=\"62%\" />\n <div className={styles.grid}>\n {Array.from({ length: 4 }, (_, index) => {\n return (\n <div key={`content-skeleton-${index}`} className={styles.card}>\n <Skeleton variant=\"text\" width=\"46%\" />\n <Skeleton variant=\"text\" width=\"82%\" lines={2} />\n <Skeleton variant=\"block\" width=\"100%\" height={120} />\n </div>\n );\n })}\n </div>\n </div>\n );\n};\n\nexport default BackofficeContentFallback;\n","import { sprinkles } from '@plumile/ui';\n\nexport const root = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n minHeight: 'full',\n width: 'full',\n minWidth: 0,\n});\n","import { Suspense, type JSX, type ReactNode } from 'react';\n\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\n\nimport { BackofficeContentError } from './BackofficeContentError.js';\nimport { BackofficeContentFallback } from './BackofficeContentFallback.js';\nimport * as styles from './backofficeContentBoundary.css.js';\n\nexport type BackofficeContentBoundaryProps = {\n children: ReactNode;\n};\n\nexport const BackofficeContentBoundary = ({\n children,\n}: BackofficeContentBoundaryProps): JSX.Element => {\n return (\n <div className={styles.root}>\n <BackofficeErrorBoundary\n fallback={({ error, reset }) => {\n return <BackofficeContentError error={error} onRetry={reset} />;\n }}\n >\n <Suspense fallback={<BackofficeContentFallback />}>{children}</Suspense>\n </BackofficeErrorBoundary>\n </div>\n );\n};\n\nexport default BackofficeContentBoundary;\n","import type { BackofficeSidebarProfileViewer } from '@plumile/ui';\n\nexport type BackofficeViewerIdentity = {\n id: string;\n firstName: string;\n lastName: string;\n email: string;\n initials: string;\n};\n\ntype MapViewerToSidebarProfileViewInput = {\n viewer: BackofficeViewerIdentity | null | undefined;\n unknownUserLabel: string;\n};\n\nconst sanitizeToken = (value: string | null | undefined): string => {\n return value?.trim() ?? '';\n};\n\nexport const mapViewerToSidebarProfileView = ({\n viewer,\n unknownUserLabel,\n}: MapViewerToSidebarProfileViewInput): BackofficeSidebarProfileViewer => {\n const firstName = sanitizeToken(viewer?.firstName);\n const lastName = sanitizeToken(viewer?.lastName);\n const joinedDisplayName = [firstName, lastName]\n .filter((token) => {\n return token !== '';\n })\n .join(' ')\n .trim();\n let displayName = joinedDisplayName;\n if (displayName === '') {\n displayName = unknownUserLabel;\n }\n\n const email = sanitizeToken(viewer?.email);\n const initialsToken = sanitizeToken(viewer?.initials);\n let initials = initialsToken;\n if (initials === '') {\n initials = '?';\n }\n\n const ariaParts = [displayName];\n if (email !== '') {\n ariaParts.push(email);\n }\n\n return {\n displayName,\n email,\n initials,\n ariaLabel: ariaParts.join(' - '),\n };\n};\n\nexport default mapViewerToSidebarProfileView;\n","import {\n useMemo,\n type JSX,\n type ReactNode,\n useCallback,\n useContext,\n useState,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n commitMutation,\n usePreloadedQuery,\n type PreloadedQuery,\n} from 'react-relay';\nimport type {\n GraphQLTaggedNode,\n MutationParameters,\n OperationType,\n} from 'relay-runtime';\nimport { RoutingContext, useLocation } from '@plumile/router';\n\nimport {\n AdminShellLayout,\n BackofficeSidebarProfileMenu,\n EnvironmentBadge,\n GlobalSearchInput,\n ToastProvider,\n} from '@plumile/ui';\n\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport type { LogoutResponse, LogoutVariables } from '../hooks/useAuth.js';\nimport { useBackofficeSidebarPins } from '../hooks/useBackofficeSidebarPins.js';\nimport { useSidebarGroupCollapse } from '../hooks/useSidebarGroupCollapse.js';\nimport { buildSidebarSections } from '../components/backoffice/layout/buildSidebarSections.js';\nimport { BackofficeContentBoundary } from '../components/backoffice/routing/BackofficeContentBoundary.js';\nimport {\n resolveSidebarGroups,\n resolveVisibleEntityIds,\n} from '../components/backoffice/layout/sidebarUtils.js';\nimport { BackofficeTopbarPortalContextProvider } from '../components/backoffice/layout/breadcrumb/BackofficeTopbarPortalContext.js';\nimport {\n mapViewerToSidebarProfileView,\n type BackofficeViewerIdentity,\n} from '../components/backoffice/layout/mapViewerToSidebarProfileView.js';\nimport { resetRelayStore } from '../relay/environment.js';\nimport { useRelayEnvironment } from '../relay/useRelayEnvironment.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\n\nexport type BackofficeLayoutPageProps = {\n children: ReactNode;\n permissionsQuery?: GraphQLTaggedNode;\n prepared?: PreloadedQuery<OperationType> | null;\n authStatus?: {\n isLoggedIn?: boolean | null;\n me?: BackofficeViewerIdentity | null;\n } | null;\n activeGroupId?: string | null;\n};\n\ntype LayoutShellProps = {\n children: ReactNode;\n permissions: unknown;\n authStatus?: {\n isLoggedIn?: boolean | null;\n me?: BackofficeViewerIdentity | null;\n } | null;\n activeGroupId?: string | null;\n};\n\nconst BackofficeLayoutShell = ({\n children,\n permissions,\n authStatus,\n activeGroupId,\n}: LayoutShellProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { pathname } = useLocation();\n const routing = useContext(RoutingContext);\n const relayEnvironment = useRelayEnvironment();\n const {\n auth: authConfig,\n basePath,\n entities,\n sidebar,\n } = useBackofficeConfig();\n const [sidebarQuery, setSidebarQuery] = useState('');\n const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);\n const [isSigningOut, setIsSigningOut] = useState(false);\n const [topbarTarget, setTopbarTarget] = useState<HTMLDivElement | null>(null);\n\n const groups = useMemo(() => {\n return resolveSidebarGroups(entities, sidebar);\n }, [entities, sidebar]);\n\n const groupIds = useMemo(() => {\n return Object.keys(groups);\n }, [groups]);\n\n const visibleEntityIds = useMemo(() => {\n return resolveVisibleEntityIds(groups, entities, sidebar, permissions);\n }, [entities, groups, permissions, sidebar]);\n\n const {\n pins,\n toggle: togglePin,\n reorder: reorderPin,\n } = useBackofficeSidebarPins({ visibleEntityIds });\n\n const { collapsedByGroupId, setCollapsed } = useSidebarGroupCollapse({\n groupIds,\n activeGroupId,\n });\n\n const sections = useMemo(() => {\n return buildSidebarSections({\n basePath,\n pathname,\n entities,\n sidebar,\n permissions,\n searchQuery: sidebarQuery,\n tApp,\n t,\n pinnedEntityIds: pins,\n onTogglePin: togglePin,\n onReorderPin: reorderPin,\n collapsedByGroupId,\n onGroupCollapsedChange: setCollapsed,\n });\n }, [\n basePath,\n collapsedByGroupId,\n entities,\n pathname,\n permissions,\n pins,\n reorderPin,\n setCollapsed,\n sidebar,\n sidebarQuery,\n t,\n tApp,\n togglePin,\n ]);\n\n const environment = useMemo(() => {\n const meta = import.meta as unknown as { env?: Record<string, unknown> };\n if (meta.env?.DEV === true) {\n return 'dev' as const;\n }\n return 'prod' as const;\n }, []);\n\n const handleSignOut = useCallback(() => {\n if (isSigningOut) {\n return;\n }\n\n type LogoutMutation = MutationParameters & {\n response: LogoutResponse;\n variables: LogoutVariables;\n };\n\n setIsSigningOut(true);\n\n const runSignOut = async (): Promise<void> => {\n try {\n const config = await authConfig.logout.load();\n await new Promise<void>((resolve, reject) => {\n commitMutation<LogoutMutation>(relayEnvironment, {\n mutation: config.logoutMutation,\n variables: {},\n onCompleted: () => {\n resolve();\n },\n onError: (error) => {\n reject(error);\n },\n });\n });\n localStorage.removeItem('auth_token');\n localStorage.removeItem('remember_me');\n resetRelayStore();\n routing?.history.push({ pathname: getBackofficeLoginPath(basePath) });\n } finally {\n setIsSigningOut(false);\n }\n };\n\n runSignOut().catch(() => {\n /* noop */\n });\n }, [authConfig.logout, basePath, isSigningOut, relayEnvironment, routing]);\n\n const viewer = authStatus?.me ?? null;\n const sidebarProfile = useMemo(() => {\n return mapViewerToSidebarProfileView({\n viewer,\n unknownUserLabel: t('sidebar.profile.unknownUser'),\n });\n }, [t, viewer]);\n\n const sidebarFooter = (\n <BackofficeSidebarProfileMenu\n collapsed={isSidebarCollapsed}\n viewer={sidebarProfile}\n labels={{\n sectionTitle: t('sidebar.profile.title'),\n menuAriaLabel: t('sidebar.profile.menuAriaLabel'),\n signOut: t('sidebar.profile.actions.signOut'),\n }}\n onSignOut={handleSignOut}\n isSigningOut={isSigningOut}\n />\n );\n\n let contentNode: JSX.Element | null = null;\n if (topbarTarget != null) {\n contentNode = (\n <BackofficeContentBoundary>{children}</BackofficeContentBoundary>\n );\n }\n\n return (\n <ToastProvider>\n <AdminShellLayout\n sidebar={{\n sections,\n header: <EnvironmentBadge environment={environment} />,\n search: (\n <GlobalSearchInput\n value={sidebarQuery}\n onChange={setSidebarQuery}\n placeholder={t('sidebar.search.placeholder')}\n ariaLabel={t('sidebar.search.placeholder')}\n />\n ),\n footer: sidebarFooter,\n isCollapsed: isSidebarCollapsed,\n onCollapsedChange: setIsSidebarCollapsed,\n }}\n topbar={{\n breadcrumb: <div ref={setTopbarTarget} />,\n }}\n >\n <BackofficeTopbarPortalContextProvider value={{ target: topbarTarget }}>\n {contentNode}\n </BackofficeTopbarPortalContextProvider>\n </AdminShellLayout>\n </ToastProvider>\n );\n};\n\ntype LayoutWithPermissionsProps = {\n children: ReactNode;\n permissionsQuery: GraphQLTaggedNode;\n prepared: PreloadedQuery<OperationType>;\n authStatus?: {\n isLoggedIn?: boolean | null;\n me?: BackofficeViewerIdentity | null;\n } | null;\n activeGroupId?: string | null;\n};\n\nconst LayoutWithPermissions = ({\n children,\n permissionsQuery,\n prepared,\n authStatus,\n activeGroupId,\n}: LayoutWithPermissionsProps): JSX.Element => {\n const permissions = usePreloadedQuery(permissionsQuery, prepared);\n\n return (\n <BackofficeLayoutShell\n permissions={permissions}\n authStatus={authStatus}\n activeGroupId={activeGroupId}\n >\n {children}\n </BackofficeLayoutShell>\n );\n};\n\nexport const BackofficeLayoutPage = ({\n children,\n permissionsQuery,\n prepared,\n authStatus,\n activeGroupId,\n}: BackofficeLayoutPageProps): JSX.Element => {\n if (permissionsQuery != null && prepared != null) {\n return (\n <LayoutWithPermissions\n permissionsQuery={permissionsQuery}\n prepared={prepared}\n authStatus={authStatus}\n activeGroupId={activeGroupId}\n >\n {children}\n </LayoutWithPermissions>\n );\n }\n\n return (\n <BackofficeLayoutShell\n permissions={null}\n authStatus={authStatus}\n activeGroupId={activeGroupId}\n >\n {children}\n </BackofficeLayoutShell>\n );\n};\n\nexport default BackofficeLayoutPage;\n"],"mappings":"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"}