@plumile/backoffice-react 0.1.192 → 0.1.194
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/lib/esm/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.js +2 -2
- package/lib/esm/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.js +2 -1
- package/lib/esm/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.js.map +1 -1
- package/lib/esm/components/backoffice/routing/BackofficeRouteFallback.js +10 -20
- package/lib/esm/components/backoffice/routing/BackofficeRouteFallback.js.map +1 -1
- package/lib/esm/pages/BackofficeLayoutPage.js +68 -71
- package/lib/esm/pages/BackofficeLayoutPage.js.map +1 -1
- package/lib/esm/relay/connectionUtils.js +1 -1
- package/lib/esm/relay/connectionUtils.js.map +1 -1
- package/lib/esm/relay/typedRelayHooks.js.map +1 -1
- package/lib/esm/style.css +1 -1
- package/lib/types/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.d.ts.map +1 -1
- package/lib/types/components/backoffice/routing/BackofficeRouteFallback.d.ts.map +1 -1
- package/lib/types/pages/BackofficeLayoutPage.d.ts.map +1 -1
- package/lib/types/relay/connectionUtils.d.ts.map +1 -1
- package/lib/types/relay/typedRelayHooks.d.ts +1 -2
- package/lib/types/relay/typedRelayHooks.d.ts.map +1 -1
- package/package.json +19 -19
- package/lib/esm/components/backoffice/routing/backofficeRouteFallback.css.js +0 -6
- package/lib/esm/components/backoffice/routing/backofficeRouteFallback.css.js.map +0 -1
- package/lib/types/components/backoffice/routing/backofficeRouteFallback.css.d.ts +0 -3
- package/lib/types/components/backoffice/routing/backofficeRouteFallback.css.d.ts.map +0 -1
|
@@ -31,13 +31,13 @@ var g = (e) => {
|
|
|
31
31
|
children: [/* @__PURE__ */ p("li", {
|
|
32
32
|
className: o,
|
|
33
33
|
children: [x && /* @__PURE__ */ f("span", {
|
|
34
|
-
className: "_80s44h1
|
|
34
|
+
className: "_80s44h2 _80s44h1 qbwcuej qbwcueh txvbqbfqq txvbqbey txvbqbls4 txvbqb1tv txvbqb2rt txvbqb2tz txvbqb1b5h txvbqb1bgt txvbqbv txvbqbwvv txvbqb7h txvbqb76 txvbqb7t qbwcuei txvbqb1cu0 txvbqb1epc qbwcue4 txvbqb1f8e txvbqb1feu qbwcue0 txvbqb1fgi txvbqb1gaq qbwcuex qbwcuer txvbqbh6d txvbqbo4m qbwcue11 qbwcuev txvbqb19hf txvbqbjmh txvbqbvat txvbqbub2 txvbqb3f txvbqb1b8t txvbqb1bgr",
|
|
35
35
|
"aria-current": "page",
|
|
36
36
|
title: b,
|
|
37
37
|
children: w
|
|
38
38
|
}), !x && /* @__PURE__ */ f(m, {
|
|
39
39
|
to: y,
|
|
40
|
-
className: "
|
|
40
|
+
className: "_80s44h1 qbwcuej qbwcueh txvbqbfqq txvbqbey txvbqbls4 txvbqb1tv txvbqb2rt txvbqb2tz txvbqb1b5h txvbqb1bgt txvbqbv txvbqbwvv txvbqb7h txvbqb76 txvbqb7t qbwcuei txvbqb1cu0 txvbqb1epc qbwcue4 txvbqb1f8e txvbqb1feu qbwcue0 txvbqb1fgi txvbqb1gaq qbwcuex qbwcuer txvbqbh6d txvbqbo4m qbwcue11 qbwcuev txvbqb19hf txvbqbjmh txvbqbvat txvbqbub2 txvbqb3f",
|
|
41
41
|
"aria-label": b,
|
|
42
42
|
title: b,
|
|
43
43
|
preloadOnHover: "code-and-data",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
/* empty css */
|
|
1
2
|
//#region src/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.ts
|
|
2
|
-
var e = "txvbqbfpn txvbqbey txvbqb19us txvbqbv7x txvbqbu4k", t = "txvbqbfpn txvbqbey txvbqbhdl txvbqbo7v txvbqbwvv txvbqbo6s txvbqbh7g txvbqbv7x txvbqbu4k", n = "txvbqbfqq txvbqbey txvbqbhdl txvbqbv7x", r = "txvbqb1bgt
|
|
3
|
+
var e = "txvbqbfpn txvbqbey txvbqb19us txvbqbv7x txvbqbu4k", t = "_80s44h0 txvbqbfpn txvbqbey txvbqbhdl txvbqbo7v txvbqbwvv txvbqbo6s txvbqbh7g txvbqbv7x txvbqbu4k", n = "txvbqbfqq txvbqbey txvbqbhdl txvbqbv7x", r = "txvbqb1bgt txvbqbo5p", i = "_80s44h1 qbwcuej qbwcueh txvbqbfqq txvbqbey txvbqbls4 txvbqb1tv txvbqb2rt txvbqb2tz txvbqb1b5h txvbqb1bgt txvbqbv txvbqbwvv txvbqb7h txvbqb76 txvbqb7t qbwcuei txvbqb1cu0 txvbqb1epc qbwcue4 txvbqb1f8e txvbqb1feu qbwcue0 txvbqb1fgi txvbqb1gaq qbwcuex qbwcuer txvbqbh6d txvbqbo4m qbwcue11 qbwcuev txvbqb19hf txvbqbjmh txvbqbvat txvbqbub2 txvbqb3f", a = "_80s44h2 _80s44h1 qbwcuej qbwcueh txvbqbfqq txvbqbey txvbqbls4 txvbqb1tv txvbqb2rt txvbqb2tz txvbqb1b5h txvbqb1bgt txvbqbv txvbqbwvv txvbqb7h txvbqb76 txvbqb7t qbwcuei txvbqb1cu0 txvbqb1epc qbwcue4 txvbqb1f8e txvbqb1feu qbwcue0 txvbqb1fgi txvbqb1gaq qbwcuex qbwcuer txvbqbh6d txvbqbo4m qbwcue11 qbwcuev txvbqb19hf txvbqbjmh txvbqbvat txvbqbub2 txvbqb3f txvbqb1b8t txvbqb1bgr", o = "_4k5f060 txvbqb1tv txvbqb2rt txvbqb1j txvbqbk07 txvbqbonr txvbqbwr6 txvbqbwvv txvbqb13i7 txvbqb18fi txvbqblvq txvbqb19v5", s = "_80s44h3 qbwcuep qbwcuen txvbqbfqq txvbqbey txvbqbhd8 txvbqb1bgr txvbqb3f txvbqb7h txvbqb75 txvbqb7t qbwcueo txvbqb1gdj qbwcue0 txvbqb1fgi txvbqb1gaq txvbqb1bgt txvbqbo5p txvbqbv7x txvbqbu4k txvbqbws9", c = "txvbqb1bgr txvbqbo5p txvbqbhbf txvbqbv7x txvbqbu4k txvbqbws9";
|
|
3
4
|
//#endregion
|
|
4
5
|
export { c as current, a as homeCurrent, o as homeLabel, i as homeLink, n as item, s as link, t as list, e as nav, r as separator };
|
|
5
6
|
|
package/lib/esm/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backofficeTopbarBreadcrumb.css.js","names":[],"sources":["../../../../../../src/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.ts"],"sourcesContent":["import { style } from '@vanilla-extract/css';\nimport { sprinkles } from '@plumile/ui/theme/sprinkles.css.js';\nimport {\n entityReferenceLink,\n ghostIconButton,\n iconBox,\n} from '@plumile/ui/theme/styleRecipes.css.js';\nimport { visuallyHidden } from '@plumile/ui/theme/accessibility.css.js';\n\nconst INLINE_FLEX = 'inline-flex' as const;\n\nexport const nav = sprinkles({\n display: 'flex',\n alignItems: 'center',\n width: 'full',\n minWidth: 0,\n maxWidth: 'full',\n});\n\nexport const list = sprinkles({\n
|
|
1
|
+
{"version":3,"file":"backofficeTopbarBreadcrumb.css.js","names":[],"sources":["../../../../../../src/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.ts"],"sourcesContent":["import { style } from '@vanilla-extract/css';\nimport { sprinkles } from '@plumile/ui/theme/sprinkles.css.js';\nimport { vars } from '@plumile/ui/theme/themeContract.css.js';\nimport {\n entityReferenceLink,\n ghostIconButton,\n iconBox,\n} from '@plumile/ui/theme/styleRecipes.css.js';\nimport { visuallyHidden } from '@plumile/ui/theme/accessibility.css.js';\n\nconst INLINE_FLEX = 'inline-flex' as const;\n\nexport const nav = sprinkles({\n display: 'flex',\n alignItems: 'center',\n width: 'full',\n minWidth: 0,\n maxWidth: 'full',\n});\n\nexport const list = style([\n sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n margin: 0,\n padding: 0,\n listStyleType: 'none',\n flexWrap: 'wrap',\n minWidth: 0,\n maxWidth: 'full',\n }),\n {\n fontSize: vars.sidebar.itemFontSize,\n },\n]);\n\nexport const item = sprinkles({\n display: INLINE_FLEX,\n alignItems: 'center',\n gap: 2,\n minWidth: 0,\n});\n\nexport const separator = sprinkles({\n color: 'textSecondary',\n lineHeight: 'normal',\n});\n\nconst homeBase = style([\n ghostIconButton,\n iconBox({ size: 'lg' }),\n sprinkles({\n textDecoration: 'none',\n }),\n]);\n\nexport const homeLink = homeBase;\n\nexport const homeCurrent = style([\n homeBase,\n sprinkles({\n backgroundColor: 'surfaceMuted',\n color: 'text',\n }),\n]);\n\nexport const homeLabel = visuallyHidden;\n\nexport const link = style([\n entityReferenceLink,\n sprinkles({\n color: 'textSecondary',\n lineHeight: 'normal',\n minWidth: 0,\n maxWidth: 'full',\n overflowWrap: 'anywhere',\n }),\n]);\n\nexport const current = sprinkles({\n color: 'text',\n lineHeight: 'normal',\n fontWeight: 'semibold',\n minWidth: 0,\n maxWidth: 'full',\n overflowWrap: 'anywhere',\n});\n"],"mappings":""}
|
|
@@ -1,25 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { Spinner as a } from "@plumile/ui/backoffice/atoms/spinner/Spinner.js";
|
|
1
|
+
import { jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslation as t } from "react-i18next";
|
|
3
|
+
import { RouteFallback as n } from "@plumile/ui/components/routing/RouteFallback.js";
|
|
5
4
|
//#region src/components/backoffice/routing/BackofficeRouteFallback.tsx
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
size: 28,
|
|
13
|
-
ariaLabel: i
|
|
14
|
-
}), /* @__PURE__ */ n("div", {
|
|
15
|
-
className: e,
|
|
16
|
-
children: i
|
|
17
|
-
})]
|
|
18
|
-
}), s = () => {
|
|
19
|
-
let { t: e, i18n: t } = i("backofficeReact", { useSuspense: !1 }), r = "Loading...";
|
|
20
|
-
return t.isInitialized && (r = e("common.loading")), /* @__PURE__ */ n(o, { label: r });
|
|
5
|
+
var r = ({ label: t = "Loading..." }) => /* @__PURE__ */ e(n, {
|
|
6
|
+
variant: "page",
|
|
7
|
+
label: t
|
|
8
|
+
}), i = () => {
|
|
9
|
+
let { t: n, i18n: i } = t("backofficeReact", { useSuspense: !1 }), a = "Loading...";
|
|
10
|
+
return i.isInitialized && (a = n("common.loading")), /* @__PURE__ */ e(r, { label: a });
|
|
21
11
|
};
|
|
22
12
|
//#endregion
|
|
23
|
-
export {
|
|
13
|
+
export { i as BackofficeRouteFallback, i as default, r as BackofficeStaticRouteFallback };
|
|
24
14
|
|
|
25
15
|
//# sourceMappingURL=BackofficeRouteFallback.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeRouteFallback.js","names":[],"sources":["../../../../../src/components/backoffice/routing/BackofficeRouteFallback.tsx"],"sourcesContent":["import { type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport {
|
|
1
|
+
{"version":3,"file":"BackofficeRouteFallback.js","names":[],"sources":["../../../../../src/components/backoffice/routing/BackofficeRouteFallback.tsx"],"sourcesContent":["import { type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { RouteFallback } from '@plumile/ui/components/routing/RouteFallback.js';\n\nexport type BackofficeRouteFallbackProps = {\n label?: string;\n};\n\nexport const BackofficeStaticRouteFallback = ({\n label = 'Loading...',\n}: BackofficeRouteFallbackProps): JSX.Element => {\n return <RouteFallback variant=\"page\" label={label} />;\n};\n\nexport const BackofficeRouteFallback = (): JSX.Element => {\n const { t, i18n } = useTranslation('backofficeReact', {\n useSuspense: false,\n });\n let label = 'Loading...';\n if (i18n.isInitialized) {\n label = t('common.loading');\n }\n\n return <BackofficeStaticRouteFallback label={label} />;\n};\n\nexport default BackofficeRouteFallback;\n"],"mappings":";;;;AASA,IAAa,KAAiC,EAC5C,WAAQ,mBAED,kBAAC,GAAD;CAAe,SAAQ;CAAc;AAAQ,CAAA,GAGzC,UAA6C;CACxD,IAAM,EAAE,MAAG,YAAS,EAAe,mBAAmB,EACpD,aAAa,GACf,CAAC,GACG,IAAQ;CAKZ,OAJI,EAAK,kBACP,IAAQ,EAAE,gBAAgB,IAGrB,kBAAC,GAAD,EAAsC,SAAQ,CAAA;AACvD"}
|
|
@@ -15,13 +15,12 @@ import { useCallback as le, useContext as ue, useEffect as o, useMemo as s, useS
|
|
|
15
15
|
import { jsx as l } from "react/jsx-runtime";
|
|
16
16
|
import { useTranslation as de } from "react-i18next";
|
|
17
17
|
import { commitMutation as fe, usePreloadedQuery as u } from "react-relay";
|
|
18
|
-
import { ToastProvider as
|
|
19
|
-
import
|
|
20
|
-
import { GlobalSearchInput as
|
|
21
|
-
import
|
|
22
|
-
import { AdminShellLayout as
|
|
23
|
-
import {
|
|
24
|
-
import { SidebarProfileMenu as p } from "@plumile/ui/components/navigation/sidebar/SidebarProfileMenu.js";
|
|
18
|
+
import { ToastProvider as d } from "@plumile/ui/atomic/molecules/toast/ToastProvider.js";
|
|
19
|
+
import pe from "@plumile/router/routing/RoutingContext.js";
|
|
20
|
+
import { GlobalSearchInput as me } from "@plumile/ui/backoffice/molecules/global_search_input/GlobalSearchInput.js";
|
|
21
|
+
import he from "@plumile/router/routing/useLocation.js";
|
|
22
|
+
import { AdminShellLayout as ge } from "@plumile/ui/admin/templates/admin_shell_layout/AdminShellLayout.js";
|
|
23
|
+
import { SidebarProfileMenu as f } from "@plumile/ui/components/navigation/sidebar/SidebarProfileMenu.js";
|
|
25
24
|
//#region src/pages/BackofficeLayoutPage.tsx
|
|
26
25
|
var _e = "plumile:backoffice:recent-items", ve = "plumile:backoffice:sidebar", ye = (e) => {
|
|
27
26
|
if (typeof window > "u") return [];
|
|
@@ -37,19 +36,19 @@ var _e = "plumile:backoffice:recent-items", ve = "plumile:backoffice:sidebar", y
|
|
|
37
36
|
} catch {
|
|
38
37
|
return [];
|
|
39
38
|
}
|
|
40
|
-
},
|
|
39
|
+
}, p = (e, t) => {
|
|
41
40
|
if (!(typeof window > "u")) try {
|
|
42
41
|
window.localStorage.setItem(e, JSON.stringify(t));
|
|
43
42
|
} catch {}
|
|
44
43
|
}, m = ({ children: u, permissions: m, authStatus: h, activeGroupId: g }) => {
|
|
45
|
-
let { t: _ } = de(), { t: v } = e(), { pathname: y } =
|
|
44
|
+
let { t: _ } = de(), { t: v } = e(), { pathname: y } = he(), b = ue(pe), x = ae(), { auth: S, basePath: C, dashboards: w, entities: T, sidebar: E } = t(), [D, be] = c(""), O = E?.preferences?.storageKey ?? ve, k = E?.preferences?.persistCollapsed === !0, [A, xe] = c(() => {
|
|
46
45
|
if (!k || typeof window > "u") return !1;
|
|
47
46
|
try {
|
|
48
47
|
return window.localStorage.getItem(`${O}:collapsed`) === "true";
|
|
49
48
|
} catch {
|
|
50
49
|
return !1;
|
|
51
50
|
}
|
|
52
|
-
}), [j, M] = c(!1), [N,
|
|
51
|
+
}), [j, M] = c(!1), [N, P] = c(null), F = E?.recentItems, I = F?.enabled === !0, L = F?.storageKey ?? _e, R = F?.maxItems ?? 8, [z, Se] = c(() => I ? ye(L) : []);
|
|
53
52
|
o(() => {
|
|
54
53
|
if (!(!k || typeof window > "u")) try {
|
|
55
54
|
window.localStorage.setItem(`${O}:collapsed`, String(A));
|
|
@@ -59,52 +58,52 @@ var _e = "plumile:backoffice:recent-items", ve = "plumile:backoffice:sidebar", y
|
|
|
59
58
|
k,
|
|
60
59
|
O
|
|
61
60
|
]);
|
|
62
|
-
let
|
|
61
|
+
let B = s(() => i(T, E), [T, E]), Ce = s(() => Object.keys(B), [B]), we = s(() => Object.fromEntries(Object.entries(B).map(([e, t]) => [e, t.behavior?.defaultCollapsed ?? !0])), [B]), Te = s(() => ee(B, T, E, m), [
|
|
63
62
|
T,
|
|
64
|
-
|
|
63
|
+
B,
|
|
65
64
|
m,
|
|
66
65
|
E
|
|
67
|
-
]),
|
|
66
|
+
]), V = s(() => r(y, T), [T, y]);
|
|
68
67
|
o(() => {
|
|
69
|
-
if (!
|
|
70
|
-
let e = T[
|
|
68
|
+
if (!I || V == null) return;
|
|
69
|
+
let e = T[V];
|
|
71
70
|
if (e == null || e.kind !== "tool" && !e.hasList) return;
|
|
72
71
|
let t = e.routes.list, n = "entity";
|
|
73
72
|
e.kind === "tool" && (n = "tool");
|
|
74
73
|
let r = {
|
|
75
74
|
kind: n,
|
|
76
|
-
id:
|
|
75
|
+
id: V,
|
|
77
76
|
label: e.label(_),
|
|
78
77
|
href: t,
|
|
79
78
|
visitedAt: Date.now()
|
|
80
79
|
};
|
|
81
|
-
|
|
82
|
-
let t = [r, ...e.filter((e) => e.id !== r.id || e.kind !== r.kind)].slice(0,
|
|
83
|
-
return
|
|
80
|
+
Se((e) => {
|
|
81
|
+
let t = [r, ...e.filter((e) => e.id !== r.id || e.kind !== r.kind)].slice(0, R);
|
|
82
|
+
return p(L, t), t;
|
|
84
83
|
});
|
|
85
84
|
}, [
|
|
86
|
-
|
|
85
|
+
V,
|
|
87
86
|
T,
|
|
88
|
-
F,
|
|
89
|
-
L,
|
|
90
87
|
I,
|
|
88
|
+
R,
|
|
89
|
+
L,
|
|
91
90
|
_
|
|
92
91
|
]);
|
|
93
|
-
let
|
|
94
|
-
enabled:
|
|
92
|
+
let H = E?.pinnedItems?.enabled === !0, { pins: Ee, toggle: De, reorder: Oe } = oe({
|
|
93
|
+
enabled: H,
|
|
95
94
|
storageKey: E?.pinnedItems?.storageKey,
|
|
96
|
-
visibleEntityIds:
|
|
97
|
-
}),
|
|
98
|
-
|
|
99
|
-
let
|
|
100
|
-
E?.preferences?.storageKey != null && (
|
|
101
|
-
let { collapsedByGroupId:
|
|
102
|
-
groupIds:
|
|
95
|
+
visibleEntityIds: Te
|
|
96
|
+
}), U, W, G;
|
|
97
|
+
H && (U = Ee, W = De, G = Oe);
|
|
98
|
+
let K;
|
|
99
|
+
E?.preferences?.storageKey != null && (K = `${E.preferences.storageKey}:groups`);
|
|
100
|
+
let { collapsedByGroupId: q, setCollapsed: J } = se({
|
|
101
|
+
groupIds: Ce,
|
|
103
102
|
activeGroupId: g,
|
|
104
|
-
defaultCollapsedByGroupId:
|
|
103
|
+
defaultCollapsedByGroupId: we,
|
|
105
104
|
persist: E?.preferences?.persistGroups === !0,
|
|
106
|
-
storageKey:
|
|
107
|
-
}),
|
|
105
|
+
storageKey: K
|
|
106
|
+
}), ke = s(() => a({
|
|
108
107
|
basePath: C,
|
|
109
108
|
pathname: y,
|
|
110
109
|
entities: T,
|
|
@@ -114,30 +113,30 @@ var _e = "plumile:backoffice:recent-items", ve = "plumile:backoffice:sidebar", y
|
|
|
114
113
|
searchQuery: D,
|
|
115
114
|
tApp: _,
|
|
116
115
|
t: v,
|
|
117
|
-
pinnedEntityIds:
|
|
118
|
-
recentItems:
|
|
119
|
-
onTogglePin:
|
|
120
|
-
onReorderPin:
|
|
121
|
-
collapsedByGroupId:
|
|
122
|
-
onGroupCollapsedChange:
|
|
116
|
+
pinnedEntityIds: U,
|
|
117
|
+
recentItems: z,
|
|
118
|
+
onTogglePin: W,
|
|
119
|
+
onReorderPin: G,
|
|
120
|
+
collapsedByGroupId: q,
|
|
121
|
+
onGroupCollapsedChange: J,
|
|
123
122
|
sidebarCollapsed: !1
|
|
124
123
|
}), [
|
|
125
124
|
C,
|
|
126
|
-
|
|
125
|
+
q,
|
|
127
126
|
T,
|
|
128
127
|
w,
|
|
129
128
|
y,
|
|
130
129
|
m,
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
z,
|
|
131
|
+
J,
|
|
133
132
|
E,
|
|
134
|
-
|
|
133
|
+
U,
|
|
135
134
|
D,
|
|
135
|
+
G,
|
|
136
136
|
W,
|
|
137
|
-
U,
|
|
138
137
|
v,
|
|
139
138
|
_
|
|
140
|
-
]),
|
|
139
|
+
]), Ae = s(() => a({
|
|
141
140
|
basePath: C,
|
|
142
141
|
pathname: y,
|
|
143
142
|
entities: T,
|
|
@@ -147,30 +146,30 @@ var _e = "plumile:backoffice:recent-items", ve = "plumile:backoffice:sidebar", y
|
|
|
147
146
|
searchQuery: D,
|
|
148
147
|
tApp: _,
|
|
149
148
|
t: v,
|
|
150
|
-
pinnedEntityIds:
|
|
151
|
-
recentItems:
|
|
152
|
-
onTogglePin:
|
|
153
|
-
onReorderPin:
|
|
154
|
-
collapsedByGroupId:
|
|
155
|
-
onGroupCollapsedChange:
|
|
149
|
+
pinnedEntityIds: U,
|
|
150
|
+
recentItems: z,
|
|
151
|
+
onTogglePin: W,
|
|
152
|
+
onReorderPin: G,
|
|
153
|
+
collapsedByGroupId: q,
|
|
154
|
+
onGroupCollapsedChange: J,
|
|
156
155
|
sidebarCollapsed: !1
|
|
157
156
|
}), [
|
|
158
157
|
C,
|
|
159
|
-
|
|
158
|
+
q,
|
|
160
159
|
T,
|
|
161
160
|
w,
|
|
162
161
|
y,
|
|
163
162
|
m,
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
z,
|
|
164
|
+
J,
|
|
166
165
|
E,
|
|
167
|
-
|
|
166
|
+
U,
|
|
168
167
|
D,
|
|
168
|
+
G,
|
|
169
169
|
W,
|
|
170
|
-
U,
|
|
171
170
|
v,
|
|
172
171
|
_
|
|
173
|
-
]),
|
|
172
|
+
]), Y = le(() => {
|
|
174
173
|
j || (M(!0), (async () => {
|
|
175
174
|
try {
|
|
176
175
|
let e = await S.logout.load();
|
|
@@ -199,7 +198,7 @@ var _e = "plumile:backoffice:recent-items", ve = "plumile:backoffice:sidebar", y
|
|
|
199
198
|
]), X = h?.me ?? null, Z = s(() => ne({
|
|
200
199
|
viewer: X,
|
|
201
200
|
unknownUserLabel: v("sidebar.profile.unknownUser")
|
|
202
|
-
}), [v, X]),
|
|
201
|
+
}), [v, X]), je = /* @__PURE__ */ l(f, {
|
|
203
202
|
collapsed: !1,
|
|
204
203
|
viewer: Z,
|
|
205
204
|
labels: {
|
|
@@ -209,7 +208,7 @@ var _e = "plumile:backoffice:recent-items", ve = "plumile:backoffice:sidebar", y
|
|
|
209
208
|
},
|
|
210
209
|
onSignOut: Y,
|
|
211
210
|
isSigningOut: j
|
|
212
|
-
}),
|
|
211
|
+
}), Me = /* @__PURE__ */ l(f, {
|
|
213
212
|
collapsed: !1,
|
|
214
213
|
viewer: Z,
|
|
215
214
|
labels: {
|
|
@@ -221,34 +220,32 @@ var _e = "plumile:backoffice:recent-items", ve = "plumile:backoffice:sidebar", y
|
|
|
221
220
|
isSigningOut: j
|
|
222
221
|
}), Q = null;
|
|
223
222
|
N != null && (Q = /* @__PURE__ */ l(re, { children: u }));
|
|
224
|
-
let $ = /* @__PURE__ */ l(
|
|
223
|
+
let $ = /* @__PURE__ */ l(me, {
|
|
225
224
|
value: D,
|
|
226
|
-
onChange:
|
|
225
|
+
onChange: be,
|
|
227
226
|
placeholder: v("sidebar.search.placeholder"),
|
|
228
227
|
ariaLabel: v("sidebar.search.placeholder")
|
|
229
228
|
});
|
|
230
|
-
return /* @__PURE__ */ l(
|
|
229
|
+
return /* @__PURE__ */ l(d, { children: /* @__PURE__ */ l(ge, {
|
|
231
230
|
sidebar: {
|
|
232
|
-
sections:
|
|
233
|
-
header: /* @__PURE__ */ l(f, { environment: J }),
|
|
231
|
+
sections: ke,
|
|
234
232
|
search: $,
|
|
235
|
-
footer:
|
|
233
|
+
footer: je,
|
|
236
234
|
isCollapsed: A,
|
|
237
|
-
onCollapsedChange:
|
|
235
|
+
onCollapsedChange: xe,
|
|
238
236
|
collapseToggleLabel: v("sidebar.actions.collapseSidebar"),
|
|
239
237
|
expandToggleLabel: v("sidebar.actions.expandSidebar"),
|
|
240
238
|
navigationAriaLabel: v("sidebar.navigationAriaLabel")
|
|
241
239
|
},
|
|
242
240
|
mobileSidebar: {
|
|
243
|
-
sections:
|
|
244
|
-
header: /* @__PURE__ */ l(f, { environment: J }),
|
|
241
|
+
sections: Ae,
|
|
245
242
|
search: $,
|
|
246
|
-
footer:
|
|
243
|
+
footer: Me,
|
|
247
244
|
isCollapsed: !1,
|
|
248
245
|
hideCollapseToggle: !0,
|
|
249
246
|
navigationAriaLabel: v("sidebar.navigationAriaLabel")
|
|
250
247
|
},
|
|
251
|
-
topbar: { breadcrumb: /* @__PURE__ */ l("div", { ref:
|
|
248
|
+
topbar: { breadcrumb: /* @__PURE__ */ l("div", { ref: P }) },
|
|
252
249
|
contentScrollMode: "contained",
|
|
253
250
|
children: /* @__PURE__ */ l(te, {
|
|
254
251
|
permissions: m,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeLayoutPage.js","names":[],"sources":["../../../src/pages/BackofficeLayoutPage.tsx"],"sourcesContent":["import {\n useEffect,\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 from '@plumile/router/routing/RoutingContext.js';\nimport useLocation from '@plumile/router/routing/useLocation.js';\n\nimport { AdminShellLayout } from '@plumile/ui/admin/templates/admin_shell_layout/AdminShellLayout.js';\nimport { ToastProvider } from '@plumile/ui/atomic/molecules/toast/ToastProvider.js';\nimport { EnvironmentBadge } from '@plumile/ui/backoffice/atoms/environment_badge/EnvironmentBadge.js';\nimport { GlobalSearchInput } from '@plumile/ui/backoffice/molecules/global_search_input/GlobalSearchInput.js';\nimport { SidebarProfileMenu } from '@plumile/ui/components/navigation/sidebar/SidebarProfileMenu.js';\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 resolveActiveEntityId,\n resolveSidebarGroups,\n resolveVisibleEntityIds,\n} from '../components/backoffice/layout/sidebarUtils.js';\nimport { BackofficeTopbarPortalContextProvider } from '../components/backoffice/layout/breadcrumb/BackofficeTopbarPortalContext.js';\nimport { BackofficePermissionsProvider } from '../components/backoffice/layout/BackofficePermissionsContext.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';\nimport type { BackofficeSidebarRecentItem } from '../provider/types.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 DEFAULT_RECENT_ITEMS_STORAGE_KEY = 'plumile:backoffice:recent-items';\nconst DEFAULT_SIDEBAR_PREFS_STORAGE_KEY = 'plumile:backoffice:sidebar';\n\nconst readRecentItems = (\n storageKey: string,\n): readonly BackofficeSidebarRecentItem[] => {\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 unknown;\n if (!Array.isArray(parsed)) {\n return [];\n }\n return parsed.filter((item): item is BackofficeSidebarRecentItem => {\n if (item == null || typeof item !== 'object') {\n return false;\n }\n const candidate = item as Partial<BackofficeSidebarRecentItem>;\n return (\n (candidate.kind === 'entity' || candidate.kind === 'tool') &&\n typeof candidate.id === 'string' &&\n typeof candidate.label === 'string' &&\n typeof candidate.href === 'string' &&\n typeof candidate.visitedAt === 'number'\n );\n });\n } catch {\n return [];\n }\n};\n\nconst writeRecentItems = (\n storageKey: string,\n items: readonly BackofficeSidebarRecentItem[],\n): void => {\n if (typeof window === 'undefined') {\n return;\n }\n try {\n window.localStorage.setItem(storageKey, JSON.stringify(items));\n } catch {\n // Ignore storage quota / privacy mode failures.\n }\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 dashboards,\n entities,\n sidebar,\n } = useBackofficeConfig();\n const [sidebarQuery, setSidebarQuery] = useState('');\n const sidebarPreferencesStorageKey =\n sidebar?.preferences?.storageKey ?? DEFAULT_SIDEBAR_PREFS_STORAGE_KEY;\n const persistSidebarCollapsed =\n sidebar?.preferences?.persistCollapsed === true;\n const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(() => {\n if (!persistSidebarCollapsed || typeof window === 'undefined') {\n return false;\n }\n try {\n return (\n window.localStorage.getItem(\n `${sidebarPreferencesStorageKey}:collapsed`,\n ) === 'true'\n );\n } catch {\n return false;\n }\n });\n const [isSigningOut, setIsSigningOut] = useState(false);\n const [topbarTarget, setTopbarTarget] = useState<HTMLDivElement | null>(null);\n const recentItemsConfig = sidebar?.recentItems;\n const recentItemsEnabled = recentItemsConfig?.enabled === true;\n const recentItemsStorageKey =\n recentItemsConfig?.storageKey ?? DEFAULT_RECENT_ITEMS_STORAGE_KEY;\n const recentItemsMaxItems = recentItemsConfig?.maxItems ?? 8;\n const [recentItems, setRecentItems] = useState<\n readonly BackofficeSidebarRecentItem[]\n >(() => {\n if (!recentItemsEnabled) {\n return [];\n }\n return readRecentItems(recentItemsStorageKey);\n });\n\n useEffect(() => {\n if (!persistSidebarCollapsed || typeof window === 'undefined') {\n return;\n }\n try {\n window.localStorage.setItem(\n `${sidebarPreferencesStorageKey}:collapsed`,\n String(isSidebarCollapsed),\n );\n } catch {\n // Ignore storage quota / privacy mode failures.\n }\n }, [\n isSidebarCollapsed,\n persistSidebarCollapsed,\n sidebarPreferencesStorageKey,\n ]);\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 defaultCollapsedByGroupId = useMemo(() => {\n return Object.fromEntries(\n Object.entries(groups).map(([groupId, group]) => {\n return [groupId, group.behavior?.defaultCollapsed ?? true];\n }),\n );\n }, [groups]);\n\n const visibleEntityIds = useMemo(() => {\n return resolveVisibleEntityIds(groups, entities, sidebar, permissions);\n }, [entities, groups, permissions, sidebar]);\n\n const activeEntityId = useMemo(() => {\n return resolveActiveEntityId(pathname, entities);\n }, [entities, pathname]);\n\n useEffect(() => {\n if (!recentItemsEnabled || activeEntityId == null) {\n return;\n }\n const config = entities[activeEntityId];\n if (config == null) {\n return;\n }\n if (config.kind !== 'tool' && !config.hasList) {\n return;\n }\n const href = config.routes.list;\n let kind: BackofficeSidebarRecentItem['kind'] = 'entity';\n if (config.kind === 'tool') {\n kind = 'tool';\n }\n const item: BackofficeSidebarRecentItem = {\n kind,\n id: activeEntityId,\n label: config.label(tApp),\n href,\n visitedAt: Date.now(),\n };\n setRecentItems((prev) => {\n const next = [\n item,\n ...prev.filter((entry) => {\n return entry.id !== item.id || entry.kind !== item.kind;\n }),\n ].slice(0, recentItemsMaxItems);\n writeRecentItems(recentItemsStorageKey, next);\n return next;\n });\n }, [\n activeEntityId,\n entities,\n recentItemsEnabled,\n recentItemsMaxItems,\n recentItemsStorageKey,\n tApp,\n ]);\n\n const pinningEnabled = sidebar?.pinnedItems?.enabled === true;\n\n const {\n pins,\n toggle: togglePin,\n reorder: reorderPin,\n } = useBackofficeSidebarPins({\n enabled: pinningEnabled,\n storageKey: sidebar?.pinnedItems?.storageKey,\n visibleEntityIds,\n });\n\n let sidebarPinnedEntityIds: readonly string[] | undefined;\n let sidebarTogglePin: ((entityId: string) => void) | undefined;\n let sidebarReorderPin: ((fromId: string, toId: string) => void) | undefined;\n if (pinningEnabled) {\n sidebarPinnedEntityIds = pins;\n sidebarTogglePin = togglePin;\n sidebarReorderPin = reorderPin;\n }\n\n let groupCollapseStorageKey: string | undefined;\n if (sidebar?.preferences?.storageKey != null) {\n groupCollapseStorageKey = `${sidebar.preferences.storageKey}:groups`;\n }\n\n const { collapsedByGroupId, setCollapsed } = useSidebarGroupCollapse({\n groupIds,\n activeGroupId,\n defaultCollapsedByGroupId,\n persist: sidebar?.preferences?.persistGroups === true,\n storageKey: groupCollapseStorageKey,\n });\n\n const sections = useMemo(() => {\n return buildSidebarSections({\n basePath,\n pathname,\n entities,\n dashboards,\n sidebar,\n permissions,\n searchQuery: sidebarQuery,\n tApp,\n t,\n pinnedEntityIds: sidebarPinnedEntityIds,\n recentItems,\n onTogglePin: sidebarTogglePin,\n onReorderPin: sidebarReorderPin,\n collapsedByGroupId,\n onGroupCollapsedChange: setCollapsed,\n sidebarCollapsed: false,\n });\n }, [\n basePath,\n collapsedByGroupId,\n entities,\n dashboards,\n pathname,\n permissions,\n recentItems,\n setCollapsed,\n sidebar,\n sidebarPinnedEntityIds,\n sidebarQuery,\n sidebarReorderPin,\n sidebarTogglePin,\n t,\n tApp,\n ]);\n\n const mobileSections = useMemo(() => {\n return buildSidebarSections({\n basePath,\n pathname,\n entities,\n dashboards,\n sidebar,\n permissions,\n searchQuery: sidebarQuery,\n tApp,\n t,\n pinnedEntityIds: sidebarPinnedEntityIds,\n recentItems,\n onTogglePin: sidebarTogglePin,\n onReorderPin: sidebarReorderPin,\n collapsedByGroupId,\n onGroupCollapsedChange: setCollapsed,\n sidebarCollapsed: false,\n });\n }, [\n basePath,\n collapsedByGroupId,\n entities,\n dashboards,\n pathname,\n permissions,\n recentItems,\n setCollapsed,\n sidebar,\n sidebarPinnedEntityIds,\n sidebarQuery,\n sidebarReorderPin,\n sidebarTogglePin,\n t,\n tApp,\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 <SidebarProfileMenu\n collapsed={false}\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 const mobileSidebarFooter = (\n <SidebarProfileMenu\n collapsed={false}\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 const sidebarSearchNode = (\n <GlobalSearchInput\n value={sidebarQuery}\n onChange={setSidebarQuery}\n placeholder={t('sidebar.search.placeholder')}\n ariaLabel={t('sidebar.search.placeholder')}\n />\n );\n\n return (\n <ToastProvider>\n <AdminShellLayout\n sidebar={{\n sections,\n header: <EnvironmentBadge environment={environment} />,\n search: sidebarSearchNode,\n footer: sidebarFooter,\n isCollapsed: isSidebarCollapsed,\n onCollapsedChange: setIsSidebarCollapsed,\n collapseToggleLabel: t('sidebar.actions.collapseSidebar'),\n expandToggleLabel: t('sidebar.actions.expandSidebar'),\n navigationAriaLabel: t('sidebar.navigationAriaLabel'),\n }}\n mobileSidebar={{\n sections: mobileSections,\n header: <EnvironmentBadge environment={environment} />,\n search: sidebarSearchNode,\n footer: mobileSidebarFooter,\n isCollapsed: false,\n hideCollapseToggle: true,\n navigationAriaLabel: t('sidebar.navigationAriaLabel'),\n }}\n topbar={{\n breadcrumb: <div ref={setTopbarTarget} />,\n }}\n contentScrollMode=\"contained\"\n >\n <BackofficePermissionsProvider permissions={permissions}>\n <BackofficeTopbarPortalContextProvider\n value={{\n target: topbarTarget,\n dashboardHref: basePath,\n dashboardLabel: t('sidebar.items.dashboard'),\n }}\n >\n {contentNode}\n </BackofficeTopbarPortalContextProvider>\n </BackofficePermissionsProvider>\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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"}
|
|
1
|
+
{"version":3,"file":"BackofficeLayoutPage.js","names":[],"sources":["../../../src/pages/BackofficeLayoutPage.tsx"],"sourcesContent":["import {\n useEffect,\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 from '@plumile/router/routing/RoutingContext.js';\nimport useLocation from '@plumile/router/routing/useLocation.js';\n\nimport { AdminShellLayout } from '@plumile/ui/admin/templates/admin_shell_layout/AdminShellLayout.js';\nimport { ToastProvider } from '@plumile/ui/atomic/molecules/toast/ToastProvider.js';\nimport { GlobalSearchInput } from '@plumile/ui/backoffice/molecules/global_search_input/GlobalSearchInput.js';\nimport { SidebarProfileMenu } from '@plumile/ui/components/navigation/sidebar/SidebarProfileMenu.js';\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 resolveActiveEntityId,\n resolveSidebarGroups,\n resolveVisibleEntityIds,\n} from '../components/backoffice/layout/sidebarUtils.js';\nimport { BackofficeTopbarPortalContextProvider } from '../components/backoffice/layout/breadcrumb/BackofficeTopbarPortalContext.js';\nimport { BackofficePermissionsProvider } from '../components/backoffice/layout/BackofficePermissionsContext.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';\nimport type { BackofficeSidebarRecentItem } from '../provider/types.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 DEFAULT_RECENT_ITEMS_STORAGE_KEY = 'plumile:backoffice:recent-items';\nconst DEFAULT_SIDEBAR_PREFS_STORAGE_KEY = 'plumile:backoffice:sidebar';\n\nconst readRecentItems = (\n storageKey: string,\n): readonly BackofficeSidebarRecentItem[] => {\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 unknown;\n if (!Array.isArray(parsed)) {\n return [];\n }\n return parsed.filter((item): item is BackofficeSidebarRecentItem => {\n if (item == null || typeof item !== 'object') {\n return false;\n }\n const candidate = item as Partial<BackofficeSidebarRecentItem>;\n return (\n (candidate.kind === 'entity' || candidate.kind === 'tool') &&\n typeof candidate.id === 'string' &&\n typeof candidate.label === 'string' &&\n typeof candidate.href === 'string' &&\n typeof candidate.visitedAt === 'number'\n );\n });\n } catch {\n return [];\n }\n};\n\nconst writeRecentItems = (\n storageKey: string,\n items: readonly BackofficeSidebarRecentItem[],\n): void => {\n if (typeof window === 'undefined') {\n return;\n }\n try {\n window.localStorage.setItem(storageKey, JSON.stringify(items));\n } catch {\n // Ignore storage quota / privacy mode failures.\n }\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 dashboards,\n entities,\n sidebar,\n } = useBackofficeConfig();\n const [sidebarQuery, setSidebarQuery] = useState('');\n const sidebarPreferencesStorageKey =\n sidebar?.preferences?.storageKey ?? DEFAULT_SIDEBAR_PREFS_STORAGE_KEY;\n const persistSidebarCollapsed =\n sidebar?.preferences?.persistCollapsed === true;\n const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(() => {\n if (!persistSidebarCollapsed || typeof window === 'undefined') {\n return false;\n }\n try {\n return (\n window.localStorage.getItem(\n `${sidebarPreferencesStorageKey}:collapsed`,\n ) === 'true'\n );\n } catch {\n return false;\n }\n });\n const [isSigningOut, setIsSigningOut] = useState(false);\n const [topbarTarget, setTopbarTarget] = useState<HTMLDivElement | null>(null);\n const recentItemsConfig = sidebar?.recentItems;\n const recentItemsEnabled = recentItemsConfig?.enabled === true;\n const recentItemsStorageKey =\n recentItemsConfig?.storageKey ?? DEFAULT_RECENT_ITEMS_STORAGE_KEY;\n const recentItemsMaxItems = recentItemsConfig?.maxItems ?? 8;\n const [recentItems, setRecentItems] = useState<\n readonly BackofficeSidebarRecentItem[]\n >(() => {\n if (!recentItemsEnabled) {\n return [];\n }\n return readRecentItems(recentItemsStorageKey);\n });\n\n useEffect(() => {\n if (!persistSidebarCollapsed || typeof window === 'undefined') {\n return;\n }\n try {\n window.localStorage.setItem(\n `${sidebarPreferencesStorageKey}:collapsed`,\n String(isSidebarCollapsed),\n );\n } catch {\n // Ignore storage quota / privacy mode failures.\n }\n }, [\n isSidebarCollapsed,\n persistSidebarCollapsed,\n sidebarPreferencesStorageKey,\n ]);\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 defaultCollapsedByGroupId = useMemo(() => {\n return Object.fromEntries(\n Object.entries(groups).map(([groupId, group]) => {\n return [groupId, group.behavior?.defaultCollapsed ?? true];\n }),\n );\n }, [groups]);\n\n const visibleEntityIds = useMemo(() => {\n return resolveVisibleEntityIds(groups, entities, sidebar, permissions);\n }, [entities, groups, permissions, sidebar]);\n\n const activeEntityId = useMemo(() => {\n return resolveActiveEntityId(pathname, entities);\n }, [entities, pathname]);\n\n useEffect(() => {\n if (!recentItemsEnabled || activeEntityId == null) {\n return;\n }\n const config = entities[activeEntityId];\n if (config == null) {\n return;\n }\n if (config.kind !== 'tool' && !config.hasList) {\n return;\n }\n const href = config.routes.list;\n let kind: BackofficeSidebarRecentItem['kind'] = 'entity';\n if (config.kind === 'tool') {\n kind = 'tool';\n }\n const item: BackofficeSidebarRecentItem = {\n kind,\n id: activeEntityId,\n label: config.label(tApp),\n href,\n visitedAt: Date.now(),\n };\n setRecentItems((prev) => {\n const next = [\n item,\n ...prev.filter((entry) => {\n return entry.id !== item.id || entry.kind !== item.kind;\n }),\n ].slice(0, recentItemsMaxItems);\n writeRecentItems(recentItemsStorageKey, next);\n return next;\n });\n }, [\n activeEntityId,\n entities,\n recentItemsEnabled,\n recentItemsMaxItems,\n recentItemsStorageKey,\n tApp,\n ]);\n\n const pinningEnabled = sidebar?.pinnedItems?.enabled === true;\n\n const {\n pins,\n toggle: togglePin,\n reorder: reorderPin,\n } = useBackofficeSidebarPins({\n enabled: pinningEnabled,\n storageKey: sidebar?.pinnedItems?.storageKey,\n visibleEntityIds,\n });\n\n let sidebarPinnedEntityIds: readonly string[] | undefined;\n let sidebarTogglePin: ((entityId: string) => void) | undefined;\n let sidebarReorderPin: ((fromId: string, toId: string) => void) | undefined;\n if (pinningEnabled) {\n sidebarPinnedEntityIds = pins;\n sidebarTogglePin = togglePin;\n sidebarReorderPin = reorderPin;\n }\n\n let groupCollapseStorageKey: string | undefined;\n if (sidebar?.preferences?.storageKey != null) {\n groupCollapseStorageKey = `${sidebar.preferences.storageKey}:groups`;\n }\n\n const { collapsedByGroupId, setCollapsed } = useSidebarGroupCollapse({\n groupIds,\n activeGroupId,\n defaultCollapsedByGroupId,\n persist: sidebar?.preferences?.persistGroups === true,\n storageKey: groupCollapseStorageKey,\n });\n\n const sections = useMemo(() => {\n return buildSidebarSections({\n basePath,\n pathname,\n entities,\n dashboards,\n sidebar,\n permissions,\n searchQuery: sidebarQuery,\n tApp,\n t,\n pinnedEntityIds: sidebarPinnedEntityIds,\n recentItems,\n onTogglePin: sidebarTogglePin,\n onReorderPin: sidebarReorderPin,\n collapsedByGroupId,\n onGroupCollapsedChange: setCollapsed,\n sidebarCollapsed: false,\n });\n }, [\n basePath,\n collapsedByGroupId,\n entities,\n dashboards,\n pathname,\n permissions,\n recentItems,\n setCollapsed,\n sidebar,\n sidebarPinnedEntityIds,\n sidebarQuery,\n sidebarReorderPin,\n sidebarTogglePin,\n t,\n tApp,\n ]);\n\n const mobileSections = useMemo(() => {\n return buildSidebarSections({\n basePath,\n pathname,\n entities,\n dashboards,\n sidebar,\n permissions,\n searchQuery: sidebarQuery,\n tApp,\n t,\n pinnedEntityIds: sidebarPinnedEntityIds,\n recentItems,\n onTogglePin: sidebarTogglePin,\n onReorderPin: sidebarReorderPin,\n collapsedByGroupId,\n onGroupCollapsedChange: setCollapsed,\n sidebarCollapsed: false,\n });\n }, [\n basePath,\n collapsedByGroupId,\n entities,\n dashboards,\n pathname,\n permissions,\n recentItems,\n setCollapsed,\n sidebar,\n sidebarPinnedEntityIds,\n sidebarQuery,\n sidebarReorderPin,\n sidebarTogglePin,\n t,\n tApp,\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 <SidebarProfileMenu\n collapsed={false}\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 const mobileSidebarFooter = (\n <SidebarProfileMenu\n collapsed={false}\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 const sidebarSearchNode = (\n <GlobalSearchInput\n value={sidebarQuery}\n onChange={setSidebarQuery}\n placeholder={t('sidebar.search.placeholder')}\n ariaLabel={t('sidebar.search.placeholder')}\n />\n );\n\n return (\n <ToastProvider>\n <AdminShellLayout\n sidebar={{\n sections,\n search: sidebarSearchNode,\n footer: sidebarFooter,\n isCollapsed: isSidebarCollapsed,\n onCollapsedChange: setIsSidebarCollapsed,\n collapseToggleLabel: t('sidebar.actions.collapseSidebar'),\n expandToggleLabel: t('sidebar.actions.expandSidebar'),\n navigationAriaLabel: t('sidebar.navigationAriaLabel'),\n }}\n mobileSidebar={{\n sections: mobileSections,\n search: sidebarSearchNode,\n footer: mobileSidebarFooter,\n isCollapsed: false,\n hideCollapseToggle: true,\n navigationAriaLabel: t('sidebar.navigationAriaLabel'),\n }}\n topbar={{\n breadcrumb: <div ref={setTopbarTarget} />,\n }}\n contentScrollMode=\"contained\"\n >\n <BackofficePermissionsProvider permissions={permissions}>\n <BackofficeTopbarPortalContextProvider\n value={{\n target: topbarTarget,\n dashboardHref: basePath,\n dashboardLabel: t('sidebar.items.dashboard'),\n }}\n >\n {contentNode}\n </BackofficeTopbarPortalContextProvider>\n </BackofficePermissionsProvider>\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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"}
|
|
@@ -7,7 +7,7 @@ function n(e) {
|
|
|
7
7
|
let c = a.getDataID(), l = Array.from(new Set(i)).filter((e) => e.trim() !== "");
|
|
8
8
|
for (let e of l) {
|
|
9
9
|
let r = t.getConnection(s, e);
|
|
10
|
-
if (r != null && !r.getLinkedRecords("edges")
|
|
10
|
+
if (r != null && !(r.getLinkedRecords("edges")?.some((e) => (e?.getLinkedRecord("node"))?.getDataID() === c) ?? !1)) {
|
|
11
11
|
let e = t.createEdge(n, r, a, o);
|
|
12
12
|
t.insertEdgeAfter(r, e);
|
|
13
13
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connectionUtils.js","names":[],"sources":["../../../src/relay/connectionUtils.ts"],"sourcesContent":["import RelayRuntime, {\n type RecordProxy,\n type RecordSourceSelectorProxy,\n} from 'relay-runtime';\n\nconst { ConnectionHandler } = RelayRuntime;\n\nexport type AppendNodeToConnectionsOptions = {\n store: RecordSourceSelectorProxy;\n parentId: string;\n connectionKeys: readonly string[];\n node: RecordProxy;\n edgeTypeName: string;\n};\n\n/** Appends a node to existing Relay connections on the parent record. */\nexport function appendNodeToConnections(\n options: AppendNodeToConnectionsOptions,\n): void {\n const { store, parentId, connectionKeys, node, edgeTypeName } = options;\n const parentRecord = store.get(parentId);\n if (parentRecord == null) {\n return;\n }\n\n const nodeId = node.getDataID();\n const uniqueKeys = Array.from(new Set(connectionKeys)).filter((key) => {\n return key.trim() !== '';\n });\n\n for (const connectionKey of uniqueKeys) {\n const connection = ConnectionHandler.getConnection(\n parentRecord,\n connectionKey,\n );\n if (connection != null) {\n const edges =
|
|
1
|
+
{"version":3,"file":"connectionUtils.js","names":[],"sources":["../../../src/relay/connectionUtils.ts"],"sourcesContent":["import RelayRuntime, {\n type RecordProxy,\n type RecordSourceSelectorProxy,\n type ReadOnlyRecordProxy,\n} from 'relay-runtime';\n\nconst { ConnectionHandler } = RelayRuntime;\n\nexport type AppendNodeToConnectionsOptions = {\n store: RecordSourceSelectorProxy;\n parentId: string;\n connectionKeys: readonly string[];\n node: RecordProxy;\n edgeTypeName: string;\n};\n\n/** Appends a node to existing Relay connections on the parent record. */\nexport function appendNodeToConnections(\n options: AppendNodeToConnectionsOptions,\n): void {\n const { store, parentId, connectionKeys, node, edgeTypeName } = options;\n const parentRecord = store.get(parentId);\n if (parentRecord == null) {\n return;\n }\n\n const nodeId = node.getDataID();\n const uniqueKeys = Array.from(new Set(connectionKeys)).filter((key) => {\n return key.trim() !== '';\n });\n\n for (const connectionKey of uniqueKeys) {\n const connection = ConnectionHandler.getConnection(\n parentRecord,\n connectionKey,\n );\n if (connection != null) {\n const readOnlyConnection: ReadOnlyRecordProxy = connection;\n const edges = readOnlyConnection.getLinkedRecords('edges');\n const alreadyPresent =\n edges?.some((edge) => {\n const edgeNode = edge?.getLinkedRecord('node');\n return edgeNode?.getDataID() === nodeId;\n }) ?? false;\n\n if (!alreadyPresent) {\n const newEdge = ConnectionHandler.createEdge(\n store,\n connection,\n node,\n edgeTypeName,\n );\n ConnectionHandler.insertEdgeAfter(connection, newEdge);\n }\n }\n }\n}\n"],"mappings":";;AAMA,IAAM,EAAE,yBAAsB;AAW9B,SAAgB,EACd,GACM;CACN,IAAM,EAAE,UAAO,aAAU,mBAAgB,SAAM,oBAAiB,GAC1D,IAAe,EAAM,IAAI,CAAQ;CACvC,IAAI,KAAgB,MAClB;CAGF,IAAM,IAAS,EAAK,UAAU,GACxB,IAAa,MAAM,KAAK,IAAI,IAAI,CAAc,CAAC,CAAC,CAAC,QAAQ,MACtD,EAAI,KAAK,MAAM,EACvB;CAED,KAAK,IAAM,KAAiB,GAAY;EACtC,IAAM,IAAa,EAAkB,cACnC,GACA,CACF;EACA,IAAI,KAAc,QASZ,EAPU,EAAmB,iBAAiB,OAEhD,CAAA,EAAO,MAAM,OACM,GAAM,gBAAgB,MAAM,EAAA,EAC5B,UAAU,MAAM,CAClC,KAAK,KAEa;GACnB,IAAM,IAAU,EAAkB,WAChC,GACA,GACA,GACA,CACF;GACA,EAAkB,gBAAgB,GAAY,CAAO;EACvD;CAEJ;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typedRelayHooks.js","names":[],"sources":["../../../src/relay/typedRelayHooks.ts"],"sourcesContent":["import * as ReactRelay from 'react-relay';\nimport type {
|
|
1
|
+
{"version":3,"file":"typedRelayHooks.js","names":[],"sources":["../../../src/relay/typedRelayHooks.ts"],"sourcesContent":["import * as ReactRelay from 'react-relay';\nimport type { GraphQLTaggedNode, OperationType } from 'relay-runtime';\n\nexport type BackofficeFragmentInput = GraphQLTaggedNode;\n\nexport const useBackofficeFragment = <TRef, TData>(\n fragment: BackofficeFragmentInput,\n ref: TRef,\n): TData => {\n return ReactRelay.useFragment(fragment, ref as any) as TData;\n};\n\nexport const useBackofficePaginationFragment = <\n TQuery extends OperationType,\n TRef,\n TData,\n>(\n fragment: BackofficeFragmentInput,\n ref: TRef,\n): ReturnType<typeof ReactRelay.usePaginationFragment<TQuery, any>> & {\n data: TData;\n} => {\n return ReactRelay.usePaginationFragment<TQuery, any>(\n fragment,\n ref as any,\n ) as ReturnType<typeof ReactRelay.usePaginationFragment<TQuery, any>> & {\n data: TData;\n };\n};\n\nexport const useBackofficePreloadedQuery = <TQuery extends OperationType>(\n query: GraphQLTaggedNode,\n preloadedQuery: Parameters<typeof ReactRelay.usePreloadedQuery<TQuery>>[1],\n): TQuery['response'] => {\n return ReactRelay.usePreloadedQuery<TQuery>(query, preloadedQuery);\n};\n\nexport const readBackofficeInlineData = <TRef, TData>(\n fragment: GraphQLTaggedNode,\n ref: TRef,\n): TData => {\n return ReactRelay.readInlineData(fragment, ref as any) as TData;\n};\n"],"mappings":";;AAKA,IAAa,KACX,GACA,MAEO,EAAW,YAAY,GAAU,CAAU,GAGvC,KAKX,GACA,MAIO,EAAW,sBAChB,GACA,CACF,GAKW,KACX,GACA,MAEO,EAAW,kBAA0B,GAAO,CAAc,GAGtD,KACX,GACA,MAEO,EAAW,eAAe,GAAU,CAAU"}
|
package/lib/esm/style.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
.w8yhmy1:hover:not(:disabled){background-color:var(--_1ie8xnc5d);color:var(--_1ie8xnc5e);border-color:var(--_1ie8xnc5f)}.oa1uye0{column-gap:var(--_1ie8xnc2f);grid-template-columns:minmax(0,1fr) auto auto;grid-template-areas:"content pickAction clearAction";width:100%;min-height:2.5rem}.oa1uye0:hover{background-color:var(--_1ie8xnc4l)}.oa1uye1{grid-area:content;min-height:100%}.oa1uye1:focus-visible{outline:2px solid var(--_1ie8xnc4e);outline-offset:2px}.oa1uye1:disabled{cursor:not-allowed;opacity:.65}.oa1uye2:hover:not(:disabled){color:var(--_1ie8xnc4r);background-color:var(--_1ie8xnc4l)}.oa1uye2:focus-visible{outline:2px solid var(--_1ie8xnc4e);outline-offset:2px}.oa1uye2:disabled{cursor:not-allowed;opacity:.65}.oa1uye3{grid-area:pickAction}.oa1uye4{grid-area:clearAction}._13200uy0{grid-template-columns:minmax(0,1fr) repeat(4,minmax(0,auto))}.ds2thc0{min-width:3.75rem}.ds2thc1:hover:not(:disabled){color:var(--_1ie8xnc4r);background-color:var(--_1ie8xnc4l)}.ds2thc1:focus-visible{outline:2px solid var(--_1ie8xnc4e);outline-offset:2px}.ds2thc1:disabled{cursor:not-allowed;opacity:.45}.u4nszr0{min-height:92px}.u4nszr0:hover{border-color:var(--_1ie8xnc59);background-color:var(--_1ie8xnc4l);transform:translateY(-1px)}.u4nszr0:focus-visible{outline:2px solid var(--_1ie8xnc4e);outline-offset:2px}._1xws1b00{color:var(--
|
|
1
|
+
.w8yhmy1:hover:not(:disabled){background-color:var(--_1ie8xnc5d);color:var(--_1ie8xnc5e);border-color:var(--_1ie8xnc5f)}.oa1uye0{column-gap:var(--_1ie8xnc2f);grid-template-columns:minmax(0,1fr) auto auto;grid-template-areas:"content pickAction clearAction";width:100%;min-height:2.5rem}.oa1uye0:hover{background-color:var(--_1ie8xnc4l)}.oa1uye1{grid-area:content;min-height:100%}.oa1uye1:focus-visible{outline:2px solid var(--_1ie8xnc4e);outline-offset:2px}.oa1uye1:disabled{cursor:not-allowed;opacity:.65}.oa1uye2:hover:not(:disabled){color:var(--_1ie8xnc4r);background-color:var(--_1ie8xnc4l)}.oa1uye2:focus-visible{outline:2px solid var(--_1ie8xnc4e);outline-offset:2px}.oa1uye2:disabled{cursor:not-allowed;opacity:.65}.oa1uye3{grid-area:pickAction}.oa1uye4{grid-area:clearAction}._13200uy0{grid-template-columns:minmax(0,1fr) repeat(4,minmax(0,auto))}.ds2thc0{min-width:3.75rem}.ds2thc1:hover:not(:disabled){color:var(--_1ie8xnc4r);background-color:var(--_1ie8xnc4l)}.ds2thc1:focus-visible{outline:2px solid var(--_1ie8xnc4e);outline-offset:2px}.ds2thc1:disabled{cursor:not-allowed;opacity:.45}.u4nszr0{min-height:92px}.u4nszr0:hover{border-color:var(--_1ie8xnc59);background-color:var(--_1ie8xnc4l);transform:translateY(-1px)}.u4nszr0:focus-visible{outline:2px solid var(--_1ie8xnc4e);outline-offset:2px}._1xws1b00{color:var(--_1ie8xnc1cu)}._1xws1b00:hover:not(:disabled){background-color:var(--_1ie8xnc1cv);color:var(--_1ie8xnc1cw)}._1xws1b00:focus-visible{box-shadow:var(--_1ie8xnc1cx);outline:none}._1xws1b00:disabled{cursor:not-allowed;opacity:.6}._80s44h0{font-size:var(--_1ie8xnc1ce)}@media screen and (width<=1023px){._1f81p5z0{grid-template-columns:minmax(0,1fr)}}._1q232kj0{grid-template-columns:auto minmax(0,1fr);display:inline-grid}qbwcuem qbwcuek txvbqb10mx txvbqb11ki txvbqb12hq txvbqbxtt txvbqbfqq txvbqbey txvbqbls4 txvbqbhd8 txvbqbvb6 txvbqb1bgr txvbqb1b8r txvbqb1d9 txvbqb2sj txvbqb29r txvbqb2wi txvbqbhbf txvbqbo4m txvbqb3f txvbqb7g txvbqb75 txvbqb7t qbwcuel txvbqb1euf txvbqb1ctj txvbqb1du7 txvbqb1e3b qbwcue0 txvbqb1fgi txvbqb1gaq:hover .kk18lv0{color:var(--_1ie8xnc6b)}@keyframes _11exksg0{0%{transform:translate(-120%)}60%{transform:translate(30%)}to{transform:translate(120%)}}._11exksg1{height:3px}._11exksg2{background:var(--_1ie8xnc6t);animation:1.1s ease-in-out infinite _11exksg0}._8o9eh80:focus-visible{box-shadow:inset 0 0 0 2px var(--_1ie8xnc4e);outline:none}
|
|
2
2
|
/*$vite$:1*/
|
package/lib/types/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backofficeTopbarBreadcrumb.css.d.ts","sourceRoot":"","sources":["../../../../../../src/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backofficeTopbarBreadcrumb.css.d.ts","sourceRoot":"","sources":["../../../../../../src/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,GAAG,QAMd,CAAC;AAEH,eAAO,MAAM,IAAI,QAef,CAAC;AAEH,eAAO,MAAM,IAAI,QAKf,CAAC;AAEH,eAAO,MAAM,SAAS,QAGpB,CAAC;AAUH,eAAO,MAAM,QAAQ,QAAW,CAAC;AAEjC,eAAO,MAAM,WAAW,QAMtB,CAAC;AAEH,eAAO,MAAM,SAAS,QAAiB,CAAC;AAExC,eAAO,MAAM,IAAI,QASf,CAAC;AAEH,eAAO,MAAM,OAAO,QAOlB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeRouteFallback.d.ts","sourceRoot":"","sources":["../../../../../src/components/backoffice/routing/BackofficeRouteFallback.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"BackofficeRouteFallback.d.ts","sourceRoot":"","sources":["../../../../../src/components/backoffice/routing/BackofficeRouteFallback.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAKjC,MAAM,MAAM,4BAA4B,GAAG;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,6BAA6B,eAEvC,4BAA4B,KAAG,GAAG,CAAC,OAErC,CAAC;AAEF,eAAO,MAAM,uBAAuB,QAAO,GAAG,CAAC,OAU9C,CAAC;eAEa,uBAAuB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeLayoutPage.d.ts","sourceRoot":"","sources":["../../../src/pages/BackofficeLayoutPage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,GAAG,EACR,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAEf,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,iBAAiB,EAEjB,aAAa,EACd,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"BackofficeLayoutPage.d.ts","sourceRoot":"","sources":["../../../src/pages/BackofficeLayoutPage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,GAAG,EACR,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAEf,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,iBAAiB,EAEjB,aAAa,EACd,MAAM,eAAe,CAAC;AAuBvB,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,kEAAkE,CAAC;AAM1E,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,EAAE,SAAS,CAAC;IACpB,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,EAAE,cAAc,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IAChD,UAAU,CAAC,EAAE;QACX,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;QAC5B,EAAE,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;KACtC,GAAG,IAAI,CAAC;IACT,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAydF,eAAO,MAAM,oBAAoB,yEAM9B,yBAAyB,KAAG,GAAG,CAAC,OAuBlC,CAAC;eAEa,oBAAoB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connectionUtils.d.ts","sourceRoot":"","sources":["../../../src/relay/connectionUtils.ts"],"names":[],"mappings":"AAAA,OAAqB,EACnB,KAAK,WAAW,EAChB,KAAK,yBAAyB,
|
|
1
|
+
{"version":3,"file":"connectionUtils.d.ts","sourceRoot":"","sources":["../../../src/relay/connectionUtils.ts"],"names":[],"mappings":"AAAA,OAAqB,EACnB,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAE/B,MAAM,eAAe,CAAC;AAIvB,MAAM,MAAM,8BAA8B,GAAG;IAC3C,KAAK,EAAE,yBAAyB,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAGF,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,8BAA8B,GACtC,IAAI,CAqCN"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as ReactRelay from 'react-relay';
|
|
2
|
-
import type { KeyType } from 'react-relay/ReactRelayTypes.js';
|
|
3
2
|
import type { GraphQLTaggedNode, OperationType } from 'relay-runtime';
|
|
4
3
|
export type BackofficeFragmentInput = GraphQLTaggedNode;
|
|
5
4
|
export declare const useBackofficeFragment: <TRef, TData>(fragment: BackofficeFragmentInput, ref: TRef) => TData;
|
|
6
|
-
export declare const useBackofficePaginationFragment: <TQuery extends OperationType, TRef, TData>(fragment: BackofficeFragmentInput, ref: TRef) => ReturnType<typeof ReactRelay.usePaginationFragment<TQuery,
|
|
5
|
+
export declare const useBackofficePaginationFragment: <TQuery extends OperationType, TRef, TData>(fragment: BackofficeFragmentInput, ref: TRef) => ReturnType<typeof ReactRelay.usePaginationFragment<TQuery, any>> & {
|
|
7
6
|
data: TData;
|
|
8
7
|
};
|
|
9
8
|
export declare const useBackofficePreloadedQuery: <TQuery extends OperationType>(query: GraphQLTaggedNode, preloadedQuery: Parameters<typeof ReactRelay.usePreloadedQuery<TQuery>>[1]) => TQuery['response'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typedRelayHooks.d.ts","sourceRoot":"","sources":["../../../src/relay/typedRelayHooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"typedRelayHooks.d.ts","sourceRoot":"","sources":["../../../src/relay/typedRelayHooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEtE,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAExD,eAAO,MAAM,qBAAqB,GAAI,IAAI,EAAE,KAAK,YACrC,uBAAuB,OAC5B,IAAI,KACR,KAEF,CAAC;AAEF,eAAO,MAAM,+BAA+B,GAC1C,MAAM,SAAS,aAAa,EAC5B,IAAI,EACJ,KAAK,YAEK,uBAAuB,OAC5B,IAAI,KACR,UAAU,CAAC,OAAO,UAAU,CAAC,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG;IACpE,IAAI,EAAE,KAAK,CAAC;CAQb,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAI,MAAM,SAAS,aAAa,SAC/D,iBAAiB,kBACR,UAAU,CAAC,OAAO,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KACzE,MAAM,CAAC,UAAU,CAEnB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,IAAI,EAAE,KAAK,YACxC,iBAAiB,OACtB,IAAI,KACR,KAEF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plumile/backoffice-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.194",
|
|
4
4
|
"description": "React provider and pages for Kronex backoffice",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -173,40 +173,40 @@
|
|
|
173
173
|
"graphql-ws": "6.1.0",
|
|
174
174
|
"i18next": "^26.3.6",
|
|
175
175
|
"i18next-browser-languagedetector": "8.2.1",
|
|
176
|
-
"react-i18next": "^17.0.
|
|
176
|
+
"react-i18next": "^17.0.10",
|
|
177
177
|
"react-qr-code": "^2.2.0",
|
|
178
178
|
"relay-runtime": "^21.0.1",
|
|
179
179
|
"tslib": "^2.8.1"
|
|
180
180
|
},
|
|
181
181
|
"devDependencies": {
|
|
182
|
-
"@plumile/auth": "^0.1.
|
|
183
|
-
"@plumile/backoffice-core": "^0.1.
|
|
184
|
-
"@plumile/filter-query": "^0.1.
|
|
185
|
-
"@plumile/relay": "^0.1.
|
|
186
|
-
"@plumile/router": "^0.1.
|
|
187
|
-
"@plumile/ui": "^0.1.
|
|
182
|
+
"@plumile/auth": "^0.1.194",
|
|
183
|
+
"@plumile/backoffice-core": "^0.1.194",
|
|
184
|
+
"@plumile/filter-query": "^0.1.194",
|
|
185
|
+
"@plumile/relay": "^0.1.194",
|
|
186
|
+
"@plumile/router": "^0.1.194",
|
|
187
|
+
"@plumile/ui": "^0.1.194",
|
|
188
188
|
"@types/react": "19.2.17",
|
|
189
189
|
"@types/react-dom": "19.2.3",
|
|
190
190
|
"@types/relay-runtime": "20.1.1",
|
|
191
191
|
"@typescript/native": "npm:typescript@7.0.2",
|
|
192
192
|
"i18next": "26.3.6",
|
|
193
|
-
"react": "19.2.
|
|
194
|
-
"react-dom": "19.2.
|
|
193
|
+
"react": "19.2.8",
|
|
194
|
+
"react-dom": "19.2.8",
|
|
195
195
|
"react-relay": "21.0.1",
|
|
196
196
|
"relay-test-utils": "21.0.1",
|
|
197
197
|
"rimraf": "6.1.3"
|
|
198
198
|
},
|
|
199
199
|
"peerDependencies": {
|
|
200
|
-
"@plumile/auth": "^0.1.
|
|
201
|
-
"@plumile/backoffice-core": "^0.1.
|
|
202
|
-
"@plumile/filter-query": "^0.1.
|
|
203
|
-
"@plumile/relay": "^0.1.
|
|
204
|
-
"@plumile/router": "^0.1.
|
|
205
|
-
"@plumile/ui": "^0.1.
|
|
200
|
+
"@plumile/auth": "^0.1.193",
|
|
201
|
+
"@plumile/backoffice-core": "^0.1.193",
|
|
202
|
+
"@plumile/filter-query": "^0.1.193",
|
|
203
|
+
"@plumile/relay": "^0.1.193",
|
|
204
|
+
"@plumile/router": "^0.1.193",
|
|
205
|
+
"@plumile/ui": "^0.1.193",
|
|
206
206
|
"i18next": "^26.3.6",
|
|
207
|
-
"react": "^19.2.
|
|
208
|
-
"react-dom": "^19.2.
|
|
209
|
-
"react-i18next": "^17.0.
|
|
207
|
+
"react": "^19.2.8",
|
|
208
|
+
"react-dom": "^19.2.8",
|
|
209
|
+
"react-i18next": "^17.0.10",
|
|
210
210
|
"react-qr-code": "^2.2.0",
|
|
211
211
|
"react-relay": "^21.0.1",
|
|
212
212
|
"relay-runtime": "^21.0.1"
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
//#region src/components/backoffice/routing/backofficeRouteFallback.css.ts
|
|
2
|
-
var e = "txvbqbfpn txvbqbh4x txvbqbey txvbqbls4 txvbqbv7k txvbqb19us txvbqbheb txvbqb1b8r txvbqb1bgt", t = "txvbqb1bgv";
|
|
3
|
-
//#endregion
|
|
4
|
-
export { t as label, e as root };
|
|
5
|
-
|
|
6
|
-
//# sourceMappingURL=backofficeRouteFallback.css.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"backofficeRouteFallback.css.js","names":[],"sources":["../../../../../src/components/backoffice/routing/backofficeRouteFallback.css.ts"],"sourcesContent":["import { sprinkles } from '@plumile/ui/theme/sprinkles.css.js';\n\nexport const root = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: 'screen',\n width: 'full',\n gap: 4,\n backgroundColor: 'surfaceSecondary',\n color: 'textSecondary',\n});\n\nexport const label = sprinkles({\n color: 'textMuted',\n});\n"],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"backofficeRouteFallback.css.d.ts","sourceRoot":"","sources":["../../../../../src/components/backoffice/routing/backofficeRouteFallback.css.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,IAAI,QAUf,CAAC;AAEH,eAAO,MAAM,KAAK,QAEhB,CAAC"}
|