@plumile/backoffice-react 0.1.199 → 0.1.200

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/README.md CHANGED
@@ -37,6 +37,11 @@ It does not try to become:
37
37
  npm install @plumile/backoffice-react
38
38
  ```
39
39
 
40
+ Use `createBackofficeAuthHeaders({ basePath })` as the Relay
41
+ `getAuthHeaders` callback. It permits anonymous GraphQL requests only from the
42
+ backoffice authentication routes and rejects protected requests before the
43
+ network when the short-lived session has expired.
44
+
40
45
  Peer dependencies:
41
46
 
42
47
  ```bash
@@ -0,0 +1,18 @@
1
+ import { isBackofficeAuthPath as e } from "../router/backofficeAuthPaths.js";
2
+ import { getShortAccessToken as t } from "@plumile/auth/shortAccessToken.js";
3
+ //#region src/auth/backofficeAuthHeaders.ts
4
+ var n = (n = {}) => {
5
+ let r = n.basePath ?? "/";
6
+ return async () => {
7
+ try {
8
+ return { Authorization: `Bearer ${await t()}` };
9
+ } catch (t) {
10
+ if (typeof window < "u" && e(r, window.location.pathname)) return {};
11
+ throw t;
12
+ }
13
+ };
14
+ };
15
+ //#endregion
16
+ export { n as createBackofficeAuthHeaders };
17
+
18
+ //# sourceMappingURL=backofficeAuthHeaders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backofficeAuthHeaders.js","names":[],"sources":["../../../src/auth/backofficeAuthHeaders.ts"],"sourcesContent":["import { getShortAccessToken } from '@plumile/auth/shortAccessToken.js';\n\nimport { isBackofficeAuthPath } from '../router/backofficeAuthPaths.js';\n\nexport type BackofficeAuthHeadersOptions = {\n basePath?: string;\n};\n\n/**\n * Builds the auth-header provider used by a backoffice Relay environment.\n *\n * Authentication failures are allowed to become anonymous requests only on\n * the explicit authentication routes. Protected operations reject before the\n * network request is sent, so an expired session cannot reach a private\n * GraphQL subgraph as an anonymous request.\n */\nexport const createBackofficeAuthHeaders = (\n options: BackofficeAuthHeadersOptions = {},\n): (() => Promise<Record<string, string>>) => {\n const basePath = options.basePath ?? '/';\n return async () => {\n try {\n const token = await getShortAccessToken();\n return { Authorization: `Bearer ${token}` };\n } catch (error: unknown) {\n if (\n typeof window !== 'undefined' &&\n isBackofficeAuthPath(basePath, window.location.pathname)\n ) {\n const anonymousHeaders: Record<string, string> = {};\n return anonymousHeaders;\n }\n throw error;\n }\n };\n};\n"],"mappings":";;;AAgBA,IAAa,KACX,IAAwC,CAAC,MACG;CAC5C,IAAM,IAAW,EAAQ,YAAY;CACrC,OAAO,YAAY;EACjB,IAAI;GAEF,OAAO,EAAE,eAAe,UAAU,MADd,EAAoB,IACE;EAC5C,SAAS,GAAgB;GACvB,IACE,OAAO,SAAW,OAClB,EAAqB,GAAU,OAAO,SAAS,QAAQ,GAGvD,OAAO,CAAA;GAET,MAAM;EACR;CACF;AACF"}
package/lib/esm/index.js CHANGED
@@ -1,77 +1,78 @@
1
1
  import { AuthRefreshNotice as e, useAuthRefreshStateSnapshot as t } from "./auth/AuthRefreshNotice.js";
2
2
  import { TotpQrCode as n, buildTotpOtpAuthUri as r } from "./auth/TotpQrCode.js";
3
- import { LoginFlow as i } from "./auth/login/LoginFlow.js";
4
- import { synchronizeAuthStatusQuery as a } from "./auth/login/synchronizeAuthStatusQuery.js";
5
- import { AcceptInvitationScreen as o } from "./auth/pages/AcceptInvitationScreen.js";
6
- import { PasswordResetCompleteScreen as s } from "./auth/pages/PasswordResetCompleteScreen.js";
7
- import { PasswordResetRequestScreen as c } from "./auth/pages/PasswordResetRequestScreen.js";
8
- import { VerifyEmailScreen as l } from "./auth/pages/VerifyEmailScreen.js";
9
- import { requireField as u, requireLinkedRecordId as d, resolveAgentStartOutcome as f, resolveMutationOutcome as p } from "./relay/mutationResult.js";
10
- import { useBackofficeConfig as m } from "./provider/BackofficeConfigContext.js";
11
- import { EntityIdFilterField as h } from "./components/backoffice/filters/EntityIdFilterField.js";
12
- import { BackofficeErrorBoundary as g } from "./components/backoffice/errors/BackofficeErrorBoundary.js";
13
- import { EntityIdPickerDialog as _ } from "./components/backoffice/pickers/EntityIdPickerDialog.js";
14
- import { BackofficeBillingUsageChart as v } from "./components/backoffice/billing/BackofficeBillingUsageChart.js";
15
- import { resolveBackofficeTargetIcon as y } from "./components/backoffice/links/resolveBackofficeTargetIcon.js";
16
- import { resolveBackofficeLink as b } from "./components/backoffice/links/resolveBackofficeLink.js";
17
- import { useBackofficeLink as x } from "./components/backoffice/links/useBackofficeLink.js";
18
- import { BackofficeInlineLink as S } from "./components/backoffice/links/BackofficeInlineLink.js";
19
- import { buildDataTableColumns as C } from "./components/backoffice/columns/buildDataTableColumns.js";
20
- import { BackofficeDetailBadgeRow as w } from "./components/backoffice/detail/BackofficeDetailBadgeRow.js";
21
- import { BackofficeStatusMetaBadge as T } from "./components/backoffice/detail/BackofficeStatusMetaBadge.js";
22
- import { BackofficeEntitySummaryHeader as E } from "./components/backoffice/detail/BackofficeEntitySummaryHeader.js";
23
- import { BackofficeEnumLabel as D } from "./components/backoffice/detail/BackofficeEnumLabel.js";
24
- import { BackofficeLifecycleTimelineSection as O } from "./components/backoffice/detail/BackofficeLifecycleTimelineSection.js";
25
- import { BackofficeReferenceValue as k } from "./components/backoffice/detail/BackofficeReferenceValue.js";
26
- import { BackofficeRelationsSummaryGrid as A } from "./components/backoffice/detail/BackofficeRelationsSummaryGrid.js";
27
- import { BackofficeStatusGroup as j } from "./components/backoffice/detail/BackofficeStatusGroup.js";
28
- import { BackofficeTokenUsageBreakdown as M } from "./components/backoffice/detail/BackofficeTokenUsageBreakdown.js";
29
- import { BackofficeUsageCostBreakdown as N } from "./components/backoffice/detail/BackofficeUsageCostBreakdown.js";
30
- import { createBackofficeEntityLinkProps as P } from "./components/backoffice/detail/createBackofficeEntityLinkProps.js";
31
- import { formatListAsMarkdown as F } from "./components/backoffice/detail/detailPayloadUtils.js";
32
- import { BackofficeFilterAction as I } from "./components/backoffice/filters/BackofficeFilterAction.js";
33
- import { EntityFilterValue as L, EntityFilterValueText as R } from "./components/backoffice/filters/EntityFilterValue.js";
34
- import { BackofficeHubTemplate as z } from "./components/backoffice/hub/BackofficeHubTemplate.js";
35
- import { BackofficeLink as B } from "./components/backoffice/links/BackofficeLink.js";
36
- import { BackofficeLinkLabel as V } from "./components/backoffice/links/BackofficeLinkLabel.js";
37
- import { BackofficeRightPageLayout as H } from "./components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js";
38
- import { BackofficeOverviewLayout as U } from "./components/backoffice/overview/BackofficeOverviewLayout.js";
39
- import { BackofficeFilterableCell as W } from "./components/backoffice/shared/BackofficeFilterableCell.js";
40
- import { BackofficeEntityLink as G } from "./components/backoffice/refs/BackofficeEntityLink.js";
41
- import { BackofficeLazyEntityCount as K } from "./components/backoffice/refs/BackofficeLazyEntityCount.js";
42
- import { BackofficeRelatedCountLink as q } from "./components/backoffice/refs/BackofficeRelatedCountLink.js";
43
- import { BackofficeTabbedDetailShell as J } from "./components/backoffice/scaffolds/BackofficeTabbedDetailShell.js";
44
- import { BackofficeFormattedCurrency as Y } from "./components/backoffice/shared/BackofficeFormattedCurrency.js";
45
- import { BackofficeFormattedNumber as ee } from "./components/backoffice/shared/BackofficeFormattedNumber.js";
46
- import { BackofficeInlineFilterRow as X } from "./components/backoffice/shared/BackofficeInlineFilterRow.js";
47
- import { BackofficeToolsDocPanel as Z } from "./components/backoffice/tools/BackofficeToolsDocPanel.js";
48
- import { BackofficeToolsErrorFallback as Q } from "./components/backoffice/tools/BackofficeToolsErrorFallback.js";
49
- import { BackofficeToolsJsonForm as $ } from "./components/backoffice/tools/BackofficeToolsJsonForm.js";
50
- import { BackofficeToolsQueryBoundary as te } from "./components/backoffice/tools/BackofficeToolsQueryBoundary.js";
51
- import { parseToolJson as ne } from "./components/backoffice/tools/parseToolJson.js";
52
- import { configureRelayEnvironment as re, getEnvironment as ie, getNetwork as ae, getRelayOperationActivitySnapshot as oe, getRelayTransportSnapshot as se, reconnectRelayWebSocket as ce, refreshRelayWebSocketAuthentication as le, resetRelayStore as ue, subscribeRelayOperationActivity as de, subscribeRelayTransport as fe } from "./relay/environment.js";
53
- import { base64UrlToBuffer as pe, bufferToBase64Url as me, mapWebAuthnRegistrationError as he, parseSignCount as ge } from "./modules/webauthn.js";
54
- import { createUseAuth as _e } from "./hooks/useAuth.js";
55
- import { useBackofficeListUrlState as ve } from "./hooks/useBackofficeListUrlState.js";
56
- import { useConditionalSubscription as ye } from "./hooks/useConditionalSubscription.js";
57
- import be from "./hooks/useCopyToClipboard.js";
58
- import xe from "./hooks/useInfiniteConnection.js";
59
- import { useRefetchNeededReload as Se } from "./hooks/useRefetchNeededReload.js";
60
- import { createI18nInstance as Ce } from "./i18n/createI18nInstance.js";
61
- import { backofficeReactI18nResources as we, withBackofficeReactI18nResources as Te } from "./i18n/resources.js";
62
- import { useReviewStatusLabel as Ee } from "./i18n/useReviewStatusLabel.js";
63
- import { BackofficeProvider as De } from "./provider/BackofficeProvider.js";
64
- import { createBackofficeLazyValue as Oe } from "./provider/lazyValue.js";
65
- import { decodeBase64ToUtf8 as ke, encodeUtf8ToBase64 as Ae } from "./modules/base64.js";
66
- import { formatFileSize as je } from "./modules/formatFileSize.js";
67
- import { uploadFilesSequentially as Me } from "./modules/uploads.js";
68
- import { resolveVisibleDetailPages as Ne } from "./pages/detail/pageResolution.js";
69
- import { createInlineDataReader as Pe } from "./relay/createInlineReader.js";
70
- import { appendNodeToConnections as Fe } from "./relay/connectionUtils.js";
71
- import { RelayProvider as Ie } from "./relay/RelayProvider.js";
72
- import { useRelayOperationActivity as Le } from "./relay/useRelayOperationActivity.js";
73
- import { configureBackofficeShortAccessTokenRelayEnvironment as Re, configureShortAccessTokenRelayEnvironment as ze } from "./relay/shortAccessTokenEnvironment.js";
74
- import { useMutationAction as Be } from "./relay/useMutationAction.js";
75
- import { identityView as Ve } from "./relay/identityView.js";
76
- import { useCursorResumableSubscription as He } from "./subscriptions/useCursorResumableSubscription.js";
77
- export { o as AcceptInvitationScreen, e as AuthRefreshNotice, v as BackofficeBillingUsageChart, w as BackofficeDetailBadgeRow, G as BackofficeEntityLink, E as BackofficeEntitySummaryHeader, D as BackofficeEnumLabel, g as BackofficeErrorBoundary, I as BackofficeFilterAction, W as BackofficeFilterableCell, Y as BackofficeFormattedCurrency, ee as BackofficeFormattedNumber, z as BackofficeHubTemplate, X as BackofficeInlineFilterRow, S as BackofficeInlineLink, K as BackofficeLazyEntityCount, O as BackofficeLifecycleTimelineSection, B as BackofficeLink, V as BackofficeLinkLabel, U as BackofficeOverviewLayout, De as BackofficeProvider, k as BackofficeReferenceValue, q as BackofficeRelatedCountLink, A as BackofficeRelationGrid, A as BackofficeRelationsSummaryGrid, H as BackofficeRightPageLayout, j as BackofficeStatusGroup, T as BackofficeStatusMetaBadge, J as BackofficeTabbedDetailShell, M as BackofficeTokenUsageBreakdown, Z as BackofficeToolsDocPanel, Q as BackofficeToolsErrorFallback, $ as BackofficeToolsJsonForm, te as BackofficeToolsQueryBoundary, N as BackofficeUsageCostBreakdown, L as EntityFilterValue, R as EntityFilterValueText, h as EntityIdFilterField, _ as EntityIdPickerDialog, i as LoginFlow, s as PasswordResetCompleteScreen, c as PasswordResetRequestScreen, Ie as RelayProvider, n as TotpQrCode, l as VerifyEmailScreen, Fe as appendNodeToConnections, we as backofficeReactI18nResources, pe as base64UrlToBuffer, me as bufferToBase64Url, C as buildDataTableColumns, r as buildTotpOtpAuthUri, Re as configureBackofficeShortAccessTokenRelayEnvironment, re as configureRelayEnvironment, ze as configureShortAccessTokenRelayEnvironment, P as createBackofficeEntityLinkProps, Oe as createBackofficeLazyValue, Ce as createI18nInstance, Pe as createInlineDataReader, _e as createUseAuth, ke as decodeBase64ToUtf8, Ae as encodeUtf8ToBase64, je as formatFileSize, F as formatListAsMarkdown, ie as getEnvironment, ae as getNetwork, oe as getRelayOperationActivitySnapshot, se as getRelayTransportSnapshot, Ve as identityView, he as mapWebAuthnRegistrationError, ge as parseSignCount, ne as parseToolJson, ce as reconnectRelayWebSocket, le as refreshRelayWebSocketAuthentication, u as requireField, d as requireLinkedRecordId, ue as resetRelayStore, f as resolveAgentStartOutcome, b as resolveBackofficeLink, y as resolveBackofficeTargetIcon, p as resolveMutationOutcome, Ne as resolveVisibleDetailPages, de as subscribeRelayOperationActivity, fe as subscribeRelayTransport, a as synchronizeAuthStatusQuery, Me as uploadFilesSequentially, t as useAuthRefreshStateSnapshot, m as useBackofficeConfig, x as useBackofficeLink, ve as useBackofficeListUrlState, ye as useConditionalSubscription, be as useCopyToClipboard, He as useCursorResumableSubscription, xe as useInfiniteConnection, Be as useMutationAction, Se as useRefetchNeededReload, Le as useRelayOperationActivity, Ee as useReviewStatusLabel, Te as withBackofficeReactI18nResources };
3
+ import { createBackofficeAuthHeaders as i } from "./auth/backofficeAuthHeaders.js";
4
+ import { LoginFlow as a } from "./auth/login/LoginFlow.js";
5
+ import { synchronizeAuthStatusQuery as o } from "./auth/login/synchronizeAuthStatusQuery.js";
6
+ import { AcceptInvitationScreen as s } from "./auth/pages/AcceptInvitationScreen.js";
7
+ import { PasswordResetCompleteScreen as c } from "./auth/pages/PasswordResetCompleteScreen.js";
8
+ import { PasswordResetRequestScreen as l } from "./auth/pages/PasswordResetRequestScreen.js";
9
+ import { VerifyEmailScreen as u } from "./auth/pages/VerifyEmailScreen.js";
10
+ import { requireField as d, requireLinkedRecordId as f, resolveAgentStartOutcome as p, resolveMutationOutcome as m } from "./relay/mutationResult.js";
11
+ import { useBackofficeConfig as h } from "./provider/BackofficeConfigContext.js";
12
+ import { EntityIdFilterField as g } from "./components/backoffice/filters/EntityIdFilterField.js";
13
+ import { BackofficeErrorBoundary as _ } from "./components/backoffice/errors/BackofficeErrorBoundary.js";
14
+ import { EntityIdPickerDialog as v } from "./components/backoffice/pickers/EntityIdPickerDialog.js";
15
+ import { BackofficeBillingUsageChart as y } from "./components/backoffice/billing/BackofficeBillingUsageChart.js";
16
+ import { resolveBackofficeTargetIcon as b } from "./components/backoffice/links/resolveBackofficeTargetIcon.js";
17
+ import { resolveBackofficeLink as x } from "./components/backoffice/links/resolveBackofficeLink.js";
18
+ import { useBackofficeLink as S } from "./components/backoffice/links/useBackofficeLink.js";
19
+ import { BackofficeInlineLink as C } from "./components/backoffice/links/BackofficeInlineLink.js";
20
+ import { buildDataTableColumns as w } from "./components/backoffice/columns/buildDataTableColumns.js";
21
+ import { BackofficeDetailBadgeRow as T } from "./components/backoffice/detail/BackofficeDetailBadgeRow.js";
22
+ import { BackofficeStatusMetaBadge as E } from "./components/backoffice/detail/BackofficeStatusMetaBadge.js";
23
+ import { BackofficeEntitySummaryHeader as D } from "./components/backoffice/detail/BackofficeEntitySummaryHeader.js";
24
+ import { BackofficeEnumLabel as O } from "./components/backoffice/detail/BackofficeEnumLabel.js";
25
+ import { BackofficeLifecycleTimelineSection as k } from "./components/backoffice/detail/BackofficeLifecycleTimelineSection.js";
26
+ import { BackofficeReferenceValue as A } from "./components/backoffice/detail/BackofficeReferenceValue.js";
27
+ import { BackofficeRelationsSummaryGrid as j } from "./components/backoffice/detail/BackofficeRelationsSummaryGrid.js";
28
+ import { BackofficeStatusGroup as M } from "./components/backoffice/detail/BackofficeStatusGroup.js";
29
+ import { BackofficeTokenUsageBreakdown as N } from "./components/backoffice/detail/BackofficeTokenUsageBreakdown.js";
30
+ import { BackofficeUsageCostBreakdown as P } from "./components/backoffice/detail/BackofficeUsageCostBreakdown.js";
31
+ import { createBackofficeEntityLinkProps as F } from "./components/backoffice/detail/createBackofficeEntityLinkProps.js";
32
+ import { formatListAsMarkdown as I } from "./components/backoffice/detail/detailPayloadUtils.js";
33
+ import { BackofficeFilterAction as L } from "./components/backoffice/filters/BackofficeFilterAction.js";
34
+ import { EntityFilterValue as R, EntityFilterValueText as z } from "./components/backoffice/filters/EntityFilterValue.js";
35
+ import { BackofficeHubTemplate as B } from "./components/backoffice/hub/BackofficeHubTemplate.js";
36
+ import { BackofficeLink as V } from "./components/backoffice/links/BackofficeLink.js";
37
+ import { BackofficeLinkLabel as H } from "./components/backoffice/links/BackofficeLinkLabel.js";
38
+ import { BackofficeRightPageLayout as U } from "./components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js";
39
+ import { BackofficeOverviewLayout as W } from "./components/backoffice/overview/BackofficeOverviewLayout.js";
40
+ import { BackofficeFilterableCell as G } from "./components/backoffice/shared/BackofficeFilterableCell.js";
41
+ import { BackofficeEntityLink as K } from "./components/backoffice/refs/BackofficeEntityLink.js";
42
+ import { BackofficeLazyEntityCount as q } from "./components/backoffice/refs/BackofficeLazyEntityCount.js";
43
+ import { BackofficeRelatedCountLink as J } from "./components/backoffice/refs/BackofficeRelatedCountLink.js";
44
+ import { BackofficeTabbedDetailShell as Y } from "./components/backoffice/scaffolds/BackofficeTabbedDetailShell.js";
45
+ import { BackofficeFormattedCurrency as X } from "./components/backoffice/shared/BackofficeFormattedCurrency.js";
46
+ import { BackofficeFormattedNumber as Z } from "./components/backoffice/shared/BackofficeFormattedNumber.js";
47
+ import { BackofficeInlineFilterRow as Q } from "./components/backoffice/shared/BackofficeInlineFilterRow.js";
48
+ import { BackofficeToolsDocPanel as $ } from "./components/backoffice/tools/BackofficeToolsDocPanel.js";
49
+ import { BackofficeToolsErrorFallback as ee } from "./components/backoffice/tools/BackofficeToolsErrorFallback.js";
50
+ import { BackofficeToolsJsonForm as te } from "./components/backoffice/tools/BackofficeToolsJsonForm.js";
51
+ import { BackofficeToolsQueryBoundary as ne } from "./components/backoffice/tools/BackofficeToolsQueryBoundary.js";
52
+ import { parseToolJson as re } from "./components/backoffice/tools/parseToolJson.js";
53
+ import { configureRelayEnvironment as ie, getEnvironment as ae, getNetwork as oe, getRelayOperationActivitySnapshot as se, getRelayTransportSnapshot as ce, reconnectRelayWebSocket as le, refreshRelayWebSocketAuthentication as ue, resetRelayStore as de, subscribeRelayOperationActivity as fe, subscribeRelayTransport as pe } from "./relay/environment.js";
54
+ import { base64UrlToBuffer as me, bufferToBase64Url as he, mapWebAuthnRegistrationError as ge, parseSignCount as _e } from "./modules/webauthn.js";
55
+ import { createUseAuth as ve } from "./hooks/useAuth.js";
56
+ import { useBackofficeListUrlState as ye } from "./hooks/useBackofficeListUrlState.js";
57
+ import { useConditionalSubscription as be } from "./hooks/useConditionalSubscription.js";
58
+ import xe from "./hooks/useCopyToClipboard.js";
59
+ import Se from "./hooks/useInfiniteConnection.js";
60
+ import { useRefetchNeededReload as Ce } from "./hooks/useRefetchNeededReload.js";
61
+ import { createI18nInstance as we } from "./i18n/createI18nInstance.js";
62
+ import { backofficeReactI18nResources as Te, withBackofficeReactI18nResources as Ee } from "./i18n/resources.js";
63
+ import { useReviewStatusLabel as De } from "./i18n/useReviewStatusLabel.js";
64
+ import { BackofficeProvider as Oe } from "./provider/BackofficeProvider.js";
65
+ import { createBackofficeLazyValue as ke } from "./provider/lazyValue.js";
66
+ import { decodeBase64ToUtf8 as Ae, encodeUtf8ToBase64 as je } from "./modules/base64.js";
67
+ import { formatFileSize as Me } from "./modules/formatFileSize.js";
68
+ import { uploadFilesSequentially as Ne } from "./modules/uploads.js";
69
+ import { resolveVisibleDetailPages as Pe } from "./pages/detail/pageResolution.js";
70
+ import { createInlineDataReader as Fe } from "./relay/createInlineReader.js";
71
+ import { appendNodeToConnections as Ie } from "./relay/connectionUtils.js";
72
+ import { RelayProvider as Le } from "./relay/RelayProvider.js";
73
+ import { useRelayOperationActivity as Re } from "./relay/useRelayOperationActivity.js";
74
+ import { configureBackofficeShortAccessTokenRelayEnvironment as ze, configureShortAccessTokenRelayEnvironment as Be } from "./relay/shortAccessTokenEnvironment.js";
75
+ import { useMutationAction as Ve } from "./relay/useMutationAction.js";
76
+ import { identityView as He } from "./relay/identityView.js";
77
+ import { useCursorResumableSubscription as Ue } from "./subscriptions/useCursorResumableSubscription.js";
78
+ export { s as AcceptInvitationScreen, e as AuthRefreshNotice, y as BackofficeBillingUsageChart, T as BackofficeDetailBadgeRow, K as BackofficeEntityLink, D as BackofficeEntitySummaryHeader, O as BackofficeEnumLabel, _ as BackofficeErrorBoundary, L as BackofficeFilterAction, G as BackofficeFilterableCell, X as BackofficeFormattedCurrency, Z as BackofficeFormattedNumber, B as BackofficeHubTemplate, Q as BackofficeInlineFilterRow, C as BackofficeInlineLink, q as BackofficeLazyEntityCount, k as BackofficeLifecycleTimelineSection, V as BackofficeLink, H as BackofficeLinkLabel, W as BackofficeOverviewLayout, Oe as BackofficeProvider, A as BackofficeReferenceValue, J as BackofficeRelatedCountLink, j as BackofficeRelationGrid, j as BackofficeRelationsSummaryGrid, U as BackofficeRightPageLayout, M as BackofficeStatusGroup, E as BackofficeStatusMetaBadge, Y as BackofficeTabbedDetailShell, N as BackofficeTokenUsageBreakdown, $ as BackofficeToolsDocPanel, ee as BackofficeToolsErrorFallback, te as BackofficeToolsJsonForm, ne as BackofficeToolsQueryBoundary, P as BackofficeUsageCostBreakdown, R as EntityFilterValue, z as EntityFilterValueText, g as EntityIdFilterField, v as EntityIdPickerDialog, a as LoginFlow, c as PasswordResetCompleteScreen, l as PasswordResetRequestScreen, Le as RelayProvider, n as TotpQrCode, u as VerifyEmailScreen, Ie as appendNodeToConnections, Te as backofficeReactI18nResources, me as base64UrlToBuffer, he as bufferToBase64Url, w as buildDataTableColumns, r as buildTotpOtpAuthUri, ze as configureBackofficeShortAccessTokenRelayEnvironment, ie as configureRelayEnvironment, Be as configureShortAccessTokenRelayEnvironment, i as createBackofficeAuthHeaders, F as createBackofficeEntityLinkProps, ke as createBackofficeLazyValue, we as createI18nInstance, Fe as createInlineDataReader, ve as createUseAuth, Ae as decodeBase64ToUtf8, je as encodeUtf8ToBase64, Me as formatFileSize, I as formatListAsMarkdown, ae as getEnvironment, oe as getNetwork, se as getRelayOperationActivitySnapshot, ce as getRelayTransportSnapshot, He as identityView, ge as mapWebAuthnRegistrationError, _e as parseSignCount, re as parseToolJson, le as reconnectRelayWebSocket, ue as refreshRelayWebSocketAuthentication, d as requireField, f as requireLinkedRecordId, de as resetRelayStore, p as resolveAgentStartOutcome, x as resolveBackofficeLink, b as resolveBackofficeTargetIcon, m as resolveMutationOutcome, Pe as resolveVisibleDetailPages, fe as subscribeRelayOperationActivity, pe as subscribeRelayTransport, o as synchronizeAuthStatusQuery, Ne as uploadFilesSequentially, t as useAuthRefreshStateSnapshot, h as useBackofficeConfig, S as useBackofficeLink, ye as useBackofficeListUrlState, be as useConditionalSubscription, xe as useCopyToClipboard, Ue as useCursorResumableSubscription, Se as useInfiniteConnection, Ve as useMutationAction, Ce as useRefetchNeededReload, Re as useRelayOperationActivity, De as useReviewStatusLabel, Ee as withBackofficeReactI18nResources };
@@ -1,18 +1,18 @@
1
- import { AcceptInvitationScreen as e } from "../auth/pages/AcceptInvitationScreen.js";
2
- import { useBackofficeConfig as t } from "../provider/BackofficeConfigContext.js";
3
- import { useBackofficeAuth as n } from "../hooks/useBackofficeAuth.js";
4
- import { getBackofficeLoginPath as r } from "../router/backofficeAuthPaths.js";
1
+ import { getBackofficeLoginPath as e } from "../router/backofficeAuthPaths.js";
2
+ import { AcceptInvitationScreen as t } from "../auth/pages/AcceptInvitationScreen.js";
3
+ import { useBackofficeConfig as n } from "../provider/BackofficeConfigContext.js";
4
+ import { useBackofficeAuth as r } from "../hooks/useBackofficeAuth.js";
5
5
  import { useCallback as i, useContext as a } from "react";
6
6
  import { jsx as o } from "react/jsx-runtime";
7
7
  import s from "@plumile/router/routing/RoutingContext.js";
8
8
  //#region src/pages/BackofficeAcceptInvitationPage.tsx
9
9
  var c = () => {
10
- let c = a(s), { basePath: l } = t(), u = n(), d = i(() => {
10
+ let c = a(s), { basePath: l } = n(), u = r(), d = i(() => {
11
11
  c?.history.push({ pathname: l });
12
12
  }, [l, c?.history]), f = i(() => {
13
- c?.history.push({ pathname: r(l) });
13
+ c?.history.push({ pathname: e(l) });
14
14
  }, [l, c?.history]);
15
- return /* @__PURE__ */ o(e, {
15
+ return /* @__PURE__ */ o(t, {
16
16
  auth: u,
17
17
  onSuccessRedirect: d,
18
18
  onBackToLogin: f
@@ -1,21 +1,21 @@
1
- import { useBackofficeReactTranslation as e } from "../i18n/useBackofficeReactTranslation.js";
2
- import { useBackofficeConfig as t } from "../provider/BackofficeConfigContext.js";
3
- import { BackofficeTopbarPortalContextProvider as n } from "../components/backoffice/layout/breadcrumb/BackofficeTopbarPortalContext.js";
4
- import { resolveActiveEntityId as r, resolveSidebarGroups as i, resolveVisibleEntityIds as a } from "../components/backoffice/layout/sidebarUtils.js";
5
- import { BackofficePermissionsProvider as ee } from "../components/backoffice/layout/BackofficePermissionsContext.js";
6
- import { buildSidebarSections as o } from "../components/backoffice/layout/buildSidebarSections.js";
1
+ import { getBackofficeLoginPath as e } from "../router/backofficeAuthPaths.js";
2
+ import { useBackofficeReactTranslation as t } from "../i18n/useBackofficeReactTranslation.js";
3
+ import { useBackofficeConfig as n } from "../provider/BackofficeConfigContext.js";
4
+ import { BackofficeTopbarPortalContextProvider as r } from "../components/backoffice/layout/breadcrumb/BackofficeTopbarPortalContext.js";
5
+ import { resolveActiveEntityId as i, resolveSidebarGroups as a, resolveVisibleEntityIds as ee } from "../components/backoffice/layout/sidebarUtils.js";
6
+ import { BackofficePermissionsProvider as o } from "../components/backoffice/layout/BackofficePermissionsContext.js";
7
+ import { buildSidebarSections as s } from "../components/backoffice/layout/buildSidebarSections.js";
7
8
  import te from "../components/backoffice/layout/mapViewerToSidebarProfileView.js";
8
9
  import { BackofficeContentBoundary as ne } from "../components/backoffice/routing/BackofficeContentBoundary.js";
9
10
  import { resetRelayStore as re } from "../relay/environment.js";
10
11
  import { useRelayEnvironment as ie } from "../relay/useRelayEnvironment.js";
11
12
  import ae from "../hooks/useBackofficeSidebarPins.js";
12
13
  import oe from "../hooks/useSidebarGroupCollapse.js";
13
- import { getBackofficeLoginPath as se } from "../router/backofficeAuthPaths.js";
14
- import { useCallback as ce, useContext as le, useEffect as s, useMemo as c, useState as l } from "react";
15
- import { jsx as u } from "react/jsx-runtime";
16
- import { useTranslation as ue } from "react-i18next";
17
- import { commitMutation as de, usePreloadedQuery as d } from "react-relay";
18
- import { ToastProvider as f } from "@plumile/ui/atomic/molecules/toast/ToastProvider.js";
14
+ import { useCallback as se, useContext as ce, useEffect as c, useMemo as l, useState as u } from "react";
15
+ import { jsx as d } from "react/jsx-runtime";
16
+ import { useTranslation as le } from "react-i18next";
17
+ import { commitMutation as ue, usePreloadedQuery as f } from "react-relay";
18
+ import { ToastProvider as de } from "@plumile/ui/atomic/molecules/toast/ToastProvider.js";
19
19
  import fe from "@plumile/router/routing/RoutingContext.js";
20
20
  import { GlobalSearchInput as pe } from "@plumile/ui/backoffice/molecules/global_search_input/GlobalSearchInput.js";
21
21
  import me from "@plumile/router/routing/useLocation.js";
@@ -40,16 +40,16 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
40
40
  if (!(typeof window > "u")) try {
41
41
  window.localStorage.setItem(e, JSON.stringify(t));
42
42
  } catch {}
43
- }, m = ({ children: d, permissions: m, authStatus: h, activeGroupId: g }) => {
44
- let { t: _ } = ue(), { t: v } = e(), { pathname: y } = me(), b = le(fe), x = ie(), { auth: S, basePath: C, dashboards: w, entities: T, sidebar: E } = t(), [D, be] = l(""), O = E?.preferences?.storageKey ?? _e, k = E?.preferences?.persistCollapsed === !0, [A, xe] = l(() => {
43
+ }, m = ({ children: f, permissions: m, authStatus: h, activeGroupId: g }) => {
44
+ let { t: _ } = le(), { t: v } = t(), { pathname: y } = me(), b = ce(fe), x = ie(), { auth: S, basePath: C, dashboards: w, entities: T, sidebar: E } = n(), [D, be] = u(""), O = E?.preferences?.storageKey ?? _e, k = E?.preferences?.persistCollapsed === !0, [A, xe] = u(() => {
45
45
  if (!k || typeof window > "u") return !1;
46
46
  try {
47
47
  return window.localStorage.getItem(`${O}:collapsed`) === "true";
48
48
  } catch {
49
49
  return !1;
50
50
  }
51
- }), [j, M] = l(!1), [N, P] = l(null), F = E?.recentItems, I = F?.enabled === !0, L = F?.storageKey ?? ge, R = F?.maxItems ?? 8, [z, Se] = l(() => I ? ve(L) : []);
52
- s(() => {
51
+ }), [j, M] = u(!1), [N, P] = u(null), F = E?.recentItems, I = F?.enabled === !0, L = F?.storageKey ?? ge, R = F?.maxItems ?? 8, [z, Se] = u(() => I ? ve(L) : []);
52
+ c(() => {
53
53
  if (!(!k || typeof window > "u")) try {
54
54
  window.localStorage.setItem(`${O}:collapsed`, String(A));
55
55
  } catch {}
@@ -58,13 +58,13 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
58
58
  k,
59
59
  O
60
60
  ]);
61
- let B = c(() => i(T, E), [T, E]), Ce = c(() => Object.keys(B), [B]), we = c(() => Object.fromEntries(Object.entries(B).map(([e, t]) => [e, t.behavior?.defaultCollapsed ?? !0])), [B]), Te = c(() => a(B, T, E, m), [
61
+ let B = l(() => a(T, E), [T, E]), Ce = l(() => Object.keys(B), [B]), we = l(() => Object.fromEntries(Object.entries(B).map(([e, t]) => [e, t.behavior?.defaultCollapsed ?? !0])), [B]), Te = l(() => ee(B, T, E, m), [
62
62
  T,
63
63
  B,
64
64
  m,
65
65
  E
66
- ]), V = c(() => r(y, T), [T, y]);
67
- s(() => {
66
+ ]), V = l(() => i(y, T), [T, y]);
67
+ c(() => {
68
68
  if (!I || V == null) return;
69
69
  let e = T[V];
70
70
  if (e == null || e.kind !== "tool" && !e.hasList) return;
@@ -103,7 +103,7 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
103
103
  defaultCollapsedByGroupId: we,
104
104
  persist: E?.preferences?.persistGroups === !0,
105
105
  storageKey: K
106
- }), ke = c(() => o({
106
+ }), ke = l(() => s({
107
107
  basePath: C,
108
108
  pathname: y,
109
109
  entities: T,
@@ -136,7 +136,7 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
136
136
  W,
137
137
  v,
138
138
  _
139
- ]), Ae = c(() => o({
139
+ ]), Ae = l(() => s({
140
140
  basePath: C,
141
141
  pathname: y,
142
142
  entities: T,
@@ -169,22 +169,22 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
169
169
  W,
170
170
  v,
171
171
  _
172
- ]), Y = ce(() => {
172
+ ]), Y = se(() => {
173
173
  j || (M(!0), (async () => {
174
174
  try {
175
- let e = await S.logout.load();
176
- await new Promise((t, n) => {
177
- de(x, {
178
- mutation: e.logoutMutation,
175
+ let t = await S.logout.load();
176
+ await new Promise((e, n) => {
177
+ ue(x, {
178
+ mutation: t.logoutMutation,
179
179
  variables: {},
180
180
  onCompleted: () => {
181
- t();
181
+ e();
182
182
  },
183
183
  onError: (e) => {
184
184
  n(e);
185
185
  }
186
186
  });
187
- }), localStorage.removeItem("auth_token"), localStorage.removeItem("remember_me"), re(), b?.history.push({ pathname: se(C) });
187
+ }), localStorage.removeItem("auth_token"), localStorage.removeItem("remember_me"), re(), b?.history.push({ pathname: e(C) });
188
188
  } finally {
189
189
  M(!1);
190
190
  }
@@ -195,10 +195,10 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
195
195
  j,
196
196
  x,
197
197
  b
198
- ]), X = h?.me ?? null, Z = c(() => te({
198
+ ]), X = h?.me ?? null, Z = l(() => te({
199
199
  viewer: X,
200
200
  unknownUserLabel: v("sidebar.profile.unknownUser")
201
- }), [v, X]), je = /* @__PURE__ */ u(p, {
201
+ }), [v, X]), je = /* @__PURE__ */ d(p, {
202
202
  collapsed: !1,
203
203
  viewer: Z,
204
204
  labels: {
@@ -208,7 +208,7 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
208
208
  },
209
209
  onSignOut: Y,
210
210
  isSigningOut: j
211
- }), Me = /* @__PURE__ */ u(p, {
211
+ }), Me = /* @__PURE__ */ d(p, {
212
212
  collapsed: !1,
213
213
  viewer: Z,
214
214
  labels: {
@@ -219,14 +219,14 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
219
219
  onSignOut: Y,
220
220
  isSigningOut: j
221
221
  }), Q = null;
222
- N != null && (Q = /* @__PURE__ */ u(ne, { children: d }));
223
- let $ = /* @__PURE__ */ u(pe, {
222
+ N != null && (Q = /* @__PURE__ */ d(ne, { children: f }));
223
+ let $ = /* @__PURE__ */ d(pe, {
224
224
  value: D,
225
225
  onChange: be,
226
226
  placeholder: v("sidebar.search.placeholder"),
227
227
  ariaLabel: v("sidebar.search.placeholder")
228
228
  });
229
- return /* @__PURE__ */ u(f, { children: /* @__PURE__ */ u(he, {
229
+ return /* @__PURE__ */ d(de, { children: /* @__PURE__ */ d(he, {
230
230
  sidebar: {
231
231
  sections: ke,
232
232
  search: $,
@@ -245,11 +245,11 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
245
245
  hideCollapseToggle: !0,
246
246
  navigationAriaLabel: v("sidebar.navigationAriaLabel")
247
247
  },
248
- topbar: { breadcrumb: /* @__PURE__ */ u("div", { ref: P }) },
248
+ topbar: { breadcrumb: /* @__PURE__ */ d("div", { ref: P }) },
249
249
  contentScrollMode: "contained",
250
- children: /* @__PURE__ */ u(ee, {
250
+ children: /* @__PURE__ */ d(o, {
251
251
  permissions: m,
252
- children: /* @__PURE__ */ u(n, {
252
+ children: /* @__PURE__ */ d(r, {
253
253
  value: {
254
254
  target: N,
255
255
  dashboardHref: C,
@@ -260,20 +260,20 @@ var ge = "plumile:backoffice:recent-items", _e = "plumile:backoffice:sidebar", v
260
260
  })
261
261
  }) });
262
262
  }, h = ({ children: e, permissionsQuery: t, prepared: n, authStatus: r, activeGroupId: i }) => {
263
- let a = d(t, n);
264
- return /* @__PURE__ */ u(m, {
263
+ let a = f(t, n);
264
+ return /* @__PURE__ */ d(m, {
265
265
  permissions: a,
266
266
  authStatus: r,
267
267
  activeGroupId: i,
268
268
  children: e
269
269
  });
270
- }, g = ({ children: e, permissionsQuery: t, prepared: n, authStatus: r, activeGroupId: i }) => t != null && n != null ? /* @__PURE__ */ u(h, {
270
+ }, g = ({ children: e, permissionsQuery: t, prepared: n, authStatus: r, activeGroupId: i }) => t != null && n != null ? /* @__PURE__ */ d(h, {
271
271
  permissionsQuery: t,
272
272
  prepared: n,
273
273
  authStatus: r,
274
274
  activeGroupId: i,
275
275
  children: e
276
- }) : /* @__PURE__ */ u(m, {
276
+ }) : /* @__PURE__ */ d(m, {
277
277
  permissions: null,
278
278
  authStatus: r,
279
279
  activeGroupId: i,
@@ -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 { 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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"}
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":";;;;;;;;;;;;;;;;;;;;;;;;AAwEA,IAAM,KAAmC,mCACnC,KAAoC,8BAEpC,MACJ,MAC2C;CAC3C,IAAI,OAAO,SAAW,KACpB,OAAO,CAAC;CAEV,IAAI;EACF,IAAM,IAAM,OAAO,aAAa,QAAQ,CAAU;EAClD,IAAI,KAAO,MACT,OAAO,CAAC;EAEV,IAAM,IAAS,KAAK,MAAM,CAAG;EAI7B,OAHK,MAAM,QAAQ,CAAM,IAGlB,EAAO,QAAQ,MAA8C;GAClE,IAAoB,OAAO,KAAS,aAAhC,GACF,OAAO;GAET,IAAM,IAAY;GAClB,QACG,EAAU,SAAS,YAAY,EAAU,SAAS,WACnD,OAAO,EAAU,MAAO,YACxB,OAAO,EAAU,SAAU,YAC3B,OAAO,EAAU,QAAS,YAC1B,OAAO,EAAU,aAAc;EAEnC,CAAC,IAdQ,CAAC;CAeZ,QAAQ;EACN,OAAO,CAAC;CACV;AACF,GAEM,MACJ,GACA,MACS;CACL,aAAO,SAAW,MAGtB,IAAI;EACF,OAAO,aAAa,QAAQ,GAAY,KAAK,UAAU,CAAK,CAAC;CAC/D,QAAQ,CAER;AACF,GAEM,KAAyB,EAC7B,aACA,gBACA,eACA,uBACmC;CACnC,IAAM,EAAE,GAAG,MAAS,GAAe,GAC7B,EAAE,SAAM,EAA8B,GACtC,EAAE,gBAAa,GAAY,GAC3B,IAAU,GAAW,EAAc,GACnC,IAAmB,GAAoB,GACvC,EACJ,MAAM,GACN,aACA,eACA,aACA,eACE,EAAoB,GAClB,CAAC,GAAc,MAAmB,EAAS,EAAE,GAC7C,IACJ,GAAS,aAAa,cAAc,IAChC,IACJ,GAAS,aAAa,qBAAqB,IACvC,CAAC,GAAoB,MAAyB,QAAe;EACjE,IAAI,CAAC,KAA2B,OAAO,SAAW,KAChD,OAAO;EAET,IAAI;GACF,OACE,OAAO,aAAa,QAClB,GAAG,EAA6B,WAClC,MAAM;EAEV,QAAQ;GACN,OAAO;EACT;CACF,CAAC,GACK,CAAC,GAAc,KAAmB,EAAS,EAAK,GAChD,CAAC,GAAc,KAAmB,EAAgC,IAAI,GACtE,IAAoB,GAAS,aAC7B,IAAqB,GAAmB,YAAY,IACpD,IACJ,GAAmB,cAAc,IAC7B,IAAsB,GAAmB,YAAY,GACrD,CAAC,GAAa,MAAkB,QAG/B,IAGE,GAAgB,CAAqB,IAFnC,CAAC,CAGX;CAED,QAAgB;EACV,OAAC,KAA2B,OAAO,SAAW,MAGlD,IAAI;GACF,OAAO,aAAa,QAClB,GAAG,EAA6B,aAChC,OAAO,CAAkB,CAC3B;EACF,QAAQ,CAER;CACF,GAAG;EACD;EACA;EACA;CACF,CAAC;CAED,IAAM,IAAS,QACN,EAAqB,GAAU,CAAO,GAC5C,CAAC,GAAU,CAAO,CAAC,GAEhB,KAAW,QACR,OAAO,KAAK,CAAM,GACxB,CAAC,CAAM,CAAC,GAEL,KAA4B,QACzB,OAAO,YACZ,OAAO,QAAQ,CAAM,CAAC,CAAC,KAAK,CAAC,GAAS,OAC7B,CAAC,GAAS,EAAM,UAAU,oBAAoB,EAAI,CAC1D,CACH,GACC,CAAC,CAAM,CAAC,GAEL,KAAmB,QAChB,GAAwB,GAAQ,GAAU,GAAS,CAAW,GACpE;EAAC;EAAU;EAAQ;EAAa;CAAO,CAAC,GAErC,IAAiB,QACd,EAAsB,GAAU,CAAQ,GAC9C,CAAC,GAAU,CAAQ,CAAC;CAEvB,QAAgB;EACd,IAAI,CAAC,KAAsB,KAAkB,MAC3C;EAEF,IAAM,IAAS,EAAS;EAIxB,IAHI,KAAU,QAGV,EAAO,SAAS,UAAU,CAAC,EAAO,SACpC;EAEF,IAAM,IAAO,EAAO,OAAO,MACvB,IAA4C;EAChD,AAAI,EAAO,SAAS,WAClB,IAAO;EAET,IAAM,IAAoC;GACxC;GACA,IAAI;GACJ,OAAO,EAAO,MAAM,CAAI;GACxB;GACA,WAAW,KAAK,IAAI;EACtB;EACA,IAAgB,MAAS;GACvB,IAAM,IAAO,CACX,GACA,GAAG,EAAK,QAAQ,MACP,EAAM,OAAO,EAAK,MAAM,EAAM,SAAS,EAAK,IACpD,CACH,CAAC,CAAC,MAAM,GAAG,CAAmB;GAE9B,OADA,GAAiB,GAAuB,CAAI,GACrC;EACT,CAAC;CACH,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,IAAM,IAAiB,GAAS,aAAa,YAAY,IAEnD,EACJ,UACA,QAAQ,IACR,SAAS,OACP,GAAyB;EAC3B,SAAS;EACT,YAAY,GAAS,aAAa;EAClC;CACF,CAAC,GAEG,GACA,GACA;CACJ,AAAI,MACF,IAAyB,IACzB,IAAmB,IACnB,IAAoB;CAGtB,IAAI;CACJ,AAAI,GAAS,aAAa,cAAc,SACtC,IAA0B,GAAG,EAAQ,YAAY,WAAW;CAG9D,IAAM,EAAE,uBAAoB,oBAAiB,GAAwB;EACnE;EACA;EACA;EACA,SAAS,GAAS,aAAa,kBAAkB;EACjD,YAAY;CACd,CAAC,GAEK,KAAW,QACR,EAAqB;EAC1B;EACA;EACA;EACA;EACA;EACA;EACA,aAAa;EACb;EACA;EACA,iBAAiB;EACjB;EACA,aAAa;EACb,cAAc;EACd;EACA,wBAAwB;EACxB,kBAAkB;CACpB,CAAC,GACA;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,GAEK,KAAiB,QACd,EAAqB;EAC1B;EACA;EACA;EACA;EACA;EACA;EACA,aAAa;EACb;EACA;EACA,iBAAiB;EACjB;EACA,aAAa;EACb,cAAc;EACd;EACA,wBAAwB;EACxB,kBAAkB;CACpB,CAAC,GACA;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,GAEK,IAAgB,SAAkB;EAClC,MASJ,EAAgB,EAAI,IA0BpB,YAxB8C;GAC5C,IAAI;IACF,IAAM,IAAS,MAAM,EAAW,OAAO,KAAK;IAgB5C,AAfA,MAAM,IAAI,SAAe,GAAS,MAAW;KAC3C,GAA+B,GAAkB;MAC/C,UAAU,EAAO;MACjB,WAAW,CAAC;MACZ,mBAAmB;OACjB,EAAQ;MACV;MACA,UAAU,MAAU;OAClB,EAAO,CAAK;MACd;KACF,CAAC;IACH,CAAC,GACD,aAAa,WAAW,YAAY,GACpC,aAAa,WAAW,aAAa,GACrC,GAAgB,GAChB,GAAS,QAAQ,KAAK,EAAE,UAAU,EAAuB,CAAQ,EAAE,CAAC;GACtE,UAAU;IACR,EAAgB,EAAK;GACvB;EACF,EAEA,CAAW,CAAC,CAAC,YAAY,CAEzB,CAAC;CACH,GAAG;EAAC,EAAW;EAAQ;EAAU;EAAc;EAAkB;CAAO,CAAC,GAEnE,IAAS,GAAY,MAAM,MAC3B,IAAiB,QACd,GAA8B;EACnC;EACA,kBAAkB,EAAE,6BAA6B;CACnD,CAAC,GACA,CAAC,GAAG,CAAM,CAAC,GAER,KACJ,kBAAC,GAAD;EACE,WAAW;EACX,QAAQ;EACR,QAAQ;GACN,cAAc,EAAE,uBAAuB;GACvC,eAAe,EAAE,+BAA+B;GAChD,SAAS,EAAE,iCAAiC;EAC9C;EACA,WAAW;EACG;CACf,CAAA,GAGG,KACJ,kBAAC,GAAD;EACE,WAAW;EACX,QAAQ;EACR,QAAQ;GACN,cAAc,EAAE,uBAAuB;GACvC,eAAe,EAAE,+BAA+B;GAChD,SAAS,EAAE,iCAAiC;EAC9C;EACA,WAAW;EACG;CACf,CAAA,GAGC,IAAkC;CACtC,AAAI,KAAgB,SAClB,IACE,kBAAC,IAAD,EAA4B,YAAoC,CAAA;CAIpE,IAAM,IACJ,kBAAC,IAAD;EACE,OAAO;EACP,UAAU;EACV,aAAa,EAAE,4BAA4B;EAC3C,WAAW,EAAE,4BAA4B;CAC1C,CAAA;CAGH,OACE,kBAAC,IAAD,EAAA,UACE,kBAAC,IAAD;EACE,SAAS;GACP;GACA,QAAQ;GACR,QAAQ;GACR,aAAa;GACb,mBAAmB;GACnB,qBAAqB,EAAE,iCAAiC;GACxD,mBAAmB,EAAE,+BAA+B;GACpD,qBAAqB,EAAE,6BAA6B;EACtD;EACA,eAAe;GACb,UAAU;GACV,QAAQ;GACR,QAAQ;GACR,aAAa;GACb,oBAAoB;GACpB,qBAAqB,EAAE,6BAA6B;EACtD;EACA,QAAQ,EACN,YAAY,kBAAC,OAAD,EAAK,KAAK,EAAkB,CAAA,EAC1C;EACA,mBAAkB;EAElB,UAAA,kBAAC,GAAD;GAA4C;GAC1C,UAAA,kBAAC,GAAD;IACE,OAAO;KACL,QAAQ;KACR,eAAe;KACf,gBAAgB,EAAE,yBAAyB;IAC7C;IAEC,UAAA;GACoC,CAAA;EACV,CAAA;CACf,CAAA,EACL,CAAA;AAEnB,GAaM,KAAyB,EAC7B,aACA,qBACA,aACA,eACA,uBAC6C;CAC7C,IAAM,IAAc,EAAkB,GAAkB,CAAQ;CAEhE,OACE,kBAAC,GAAD;EACe;EACD;EACG;EAEd;CACoB,CAAA;AAE3B,GAEa,KAAwB,EACnC,aACA,qBACA,aACA,eACA,uBAEI,KAAoB,QAAQ,KAAY,OAExC,kBAAC,GAAD;CACoB;CACR;CACE;CACG;CAEd;AACoB,CAAA,IAKzB,kBAAC,GAAD;CACE,aAAa;CACD;CACG;CAEd;AACoB,CAAA"}
@@ -1,17 +1,17 @@
1
- import { LoginFlow as e } from "../auth/login/LoginFlow.js";
2
- import { synchronizeAuthStatusQuery as t } from "../auth/login/synchronizeAuthStatusQuery.js";
3
- import { useBackofficeConfig as n } from "../provider/BackofficeConfigContext.js";
4
- import { useRelayEnvironment as r } from "../relay/useRelayEnvironment.js";
5
- import { useBackofficeAuth as i } from "../hooks/useBackofficeAuth.js";
6
- import { useBackofficeAuthLoginConfig as a } from "../provider/useBackofficeLazyValue.js";
7
- import { getBackofficePasswordResetPath as o } from "../router/backofficeAuthPaths.js";
1
+ import { getBackofficePasswordResetPath as e } from "../router/backofficeAuthPaths.js";
2
+ import { LoginFlow as t } from "../auth/login/LoginFlow.js";
3
+ import { synchronizeAuthStatusQuery as n } from "../auth/login/synchronizeAuthStatusQuery.js";
4
+ import { useBackofficeConfig as r } from "../provider/BackofficeConfigContext.js";
5
+ import { useRelayEnvironment as i } from "../relay/useRelayEnvironment.js";
6
+ import { useBackofficeAuth as a } from "../hooks/useBackofficeAuth.js";
7
+ import { useBackofficeAuthLoginConfig as o } from "../provider/useBackofficeLazyValue.js";
8
8
  import { useCallback as s, useContext as c, useRef as l } from "react";
9
9
  import { jsx as u } from "react/jsx-runtime";
10
10
  import * as d from "react-relay";
11
11
  import f from "@plumile/router/routing/RoutingContext.js";
12
12
  //#region src/pages/BackofficeLoginPage.tsx
13
13
  var { usePreloadedQuery: p } = d, m = ({ prepared: d }) => {
14
- let m = c(f), { auth: h, basePath: g } = n(), _ = a(), v = i(), y = r(), b = l(!1), x = p(_.loginQuery, d.query).oidcProviders ?? [], S = s(() => {
14
+ let m = c(f), { auth: h, basePath: g } = r(), _ = o(), v = a(), y = i(), b = l(!1), x = p(_.loginQuery, d.query).oidcProviders ?? [], S = s(() => {
15
15
  b.current || (b.current = !0, (async () => {
16
16
  try {
17
17
  let e = await h.session.load();
@@ -19,7 +19,7 @@ var { usePreloadedQuery: p } = d, m = ({ prepared: d }) => {
19
19
  m?.history.push({ pathname: g });
20
20
  return;
21
21
  }
22
- if (await h.lifecycle?.onLoginSuccess?.(), !await t(y, e.authStatusQuery)) return;
22
+ if (await h.lifecycle?.onLoginSuccess?.(), !await n(y, e.authStatusQuery)) return;
23
23
  m?.history.push({ pathname: g });
24
24
  } catch {} finally {
25
25
  b.current = !1;
@@ -32,9 +32,9 @@ var { usePreloadedQuery: p } = d, m = ({ prepared: d }) => {
32
32
  y,
33
33
  m?.history
34
34
  ]), C = s(() => {
35
- m?.history.push({ pathname: o(g) });
35
+ m?.history.push({ pathname: e(g) });
36
36
  }, [g, m?.history]);
37
- return /* @__PURE__ */ u(e, {
37
+ return /* @__PURE__ */ u(t, {
38
38
  auth: v,
39
39
  oidcProviders: x,
40
40
  onLoginSuccess: S,