@plumile/backoffice-react 0.2.10 → 0.2.12
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 +7 -0
- package/lib/esm/auth/authRefreshNotice.css.js +1 -1
- package/lib/esm/auth/login/OidcButtons.js +16 -15
- package/lib/esm/auth/login/OidcButtons.js.map +1 -1
- package/lib/esm/auth/login/loginPage.css.js +1 -1
- package/lib/esm/auth/pages/AcceptInvitationScreen.js +7 -9
- package/lib/esm/auth/pages/AcceptInvitationScreen.js.map +1 -1
- package/lib/esm/auth/pages/PasswordResetCompleteScreen.js +7 -9
- package/lib/esm/auth/pages/PasswordResetCompleteScreen.js.map +1 -1
- package/lib/esm/auth/pages/PasswordResetRequestScreen.js +1 -1
- package/lib/esm/auth/pages/PasswordResetRequestScreen.js.map +1 -1
- package/lib/esm/components/backoffice/actions/BackofficeEntityActionFormDialog.js +1 -1
- package/lib/esm/components/backoffice/actions/backofficeEntityActionFormDialog.css.js +1 -1
- package/lib/esm/components/backoffice/billing/BackofficeBillingUsageChart.js +1 -1
- package/lib/esm/components/backoffice/billing/backofficeBillingUsageChart.css.js +1 -1
- package/lib/esm/components/backoffice/columns/buildDataTableColumns.js +71 -68
- package/lib/esm/components/backoffice/columns/buildDataTableColumns.js.map +1 -1
- package/lib/esm/components/backoffice/detail/BackofficeEntitySummaryHeader.js +6 -6
- package/lib/esm/components/backoffice/detail/BackofficeRelationsSummaryGrid.js +1 -1
- package/lib/esm/components/backoffice/detail/BackofficeUsageCostBreakdown.js +21 -18
- package/lib/esm/components/backoffice/detail/BackofficeUsageCostBreakdown.js.map +1 -1
- package/lib/esm/components/backoffice/detail/backofficeDetailBadgeRow.css.js +1 -1
- package/lib/esm/components/backoffice/detail/backofficeDetailErrorList.css.js +1 -1
- package/lib/esm/components/backoffice/detail/backofficeDetailLayout.css.js +1 -1
- package/lib/esm/components/backoffice/detail/backofficeDetailRelationList.css.js +1 -1
- package/lib/esm/components/backoffice/detail/backofficeEntitySummaryHeader.css.js +1 -1
- package/lib/esm/components/backoffice/detail/backofficeRelationsSummaryGrid.css.js +1 -1
- package/lib/esm/components/backoffice/detail/backofficeUsageCostBreakdown.css.js +1 -1
- package/lib/esm/components/backoffice/filters/EntityIdFilterField.js +1 -1
- package/lib/esm/components/backoffice/filters/backofficeFilterAction.css.js +1 -1
- package/lib/esm/components/backoffice/filters/deferredFilterSearchInput.css.js +1 -1
- package/lib/esm/components/backoffice/filters/deferredFilterSearchInput.css.js.map +1 -1
- package/lib/esm/components/backoffice/filters/entityIdFilterField.css.js +1 -1
- package/lib/esm/components/backoffice/hub/BackofficeHubTemplate.js +5 -5
- package/lib/esm/components/backoffice/hub/backofficeHubTemplate.css.js +1 -1
- package/lib/esm/components/backoffice/layout/backofficeSidebarActions.css.js +1 -1
- package/lib/esm/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.js +2 -2
- package/lib/esm/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.js +1 -1
- package/lib/esm/components/backoffice/links/BackofficeLinkContent.js +1 -1
- package/lib/esm/components/backoffice/links/backofficeLink.css.js +1 -1
- package/lib/esm/components/backoffice/list/RowFlagsCell.css.js +1 -1
- package/lib/esm/components/backoffice/overview/backofficeOverviewLayout.css.js +1 -1
- package/lib/esm/components/backoffice/pickers/entityIdPickerDialog.css.js +1 -1
- package/lib/esm/components/backoffice/refs/backofficeRelatedCountLink.css.js +1 -1
- package/lib/esm/components/backoffice/routing/backofficeContentBoundary.css.js +1 -1
- package/lib/esm/components/backoffice/routing/backofficeContentError.css.js +1 -1
- package/lib/esm/components/backoffice/routing/backofficeContentFallback.css.js +1 -1
- package/lib/esm/components/backoffice/scaffolds/backofficeEntityListScaffold.css.js +1 -1
- package/lib/esm/components/backoffice/scaffolds/backofficeTabbedDetailShell.css.js +1 -1
- package/lib/esm/components/backoffice/shared/backofficeFilterableCell.css.js +5 -5
- package/lib/esm/components/backoffice/shared/backofficeInlineFilterRow.css.js +1 -1
- package/lib/esm/components/backoffice/tools/BackofficeToolsDocPanel.js +1 -1
- package/lib/esm/components/backoffice/tools/BackofficeToolsErrorFallback.js +2 -1
- package/lib/esm/components/backoffice/tools/BackofficeToolsErrorFallback.js.map +1 -1
- package/lib/esm/components/backoffice/tools/backofficeToolsDocPanel.css.js +1 -1
- package/lib/esm/components/backoffice/tools/backofficeToolsForm.css.js +1 -1
- package/lib/esm/components/backoffice/tools/backofficeToolsJsonForm.css.js +1 -1
- package/lib/esm/hooks/useBackofficeSidebarPins.js +1 -1
- package/lib/esm/hooks/useBackofficeSidebarPins.js.map +1 -1
- package/lib/esm/hooks/useSidebarGroupCollapse.js +1 -1
- package/lib/esm/hooks/useSidebarGroupCollapse.js.map +1 -1
- package/lib/esm/pages/BackofficeDashboardPage.js +54 -52
- package/lib/esm/pages/BackofficeDashboardPage.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js +67 -64
- package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityDetailPage.view-helpers.js +10 -9
- package/lib/esm/pages/BackofficeEntityDetailPage.view-helpers.js.map +1 -1
- package/lib/esm/pages/BackofficeLayoutPage.js +2 -2
- package/lib/esm/pages/BackofficeLayoutPage.js.map +1 -1
- package/lib/esm/pages/backofficeDashboardPage.css.js +1 -1
- package/lib/esm/pages/backofficeEntityDetailPage.css.js +1 -1
- package/lib/esm/pages/backofficeEntityListPage.css.js +1 -1
- package/lib/esm/storybook/backofficeDashboardPageStory.css.js +1 -1
- package/lib/esm/storybook/relay/RelayStory.css.js +1 -1
- package/lib/esm/style.css +1 -1
- package/lib/types/auth/login/OidcButtons.d.ts.map +1 -1
- package/lib/types/auth/pages/AcceptInvitationScreen.d.ts.map +1 -1
- package/lib/types/auth/pages/PasswordResetCompleteScreen.d.ts.map +1 -1
- package/lib/types/components/backoffice/columns/buildDataTableColumns.d.ts.map +1 -1
- package/lib/types/components/backoffice/detail/BackofficeUsageCostBreakdown.d.ts +8 -4
- package/lib/types/components/backoffice/detail/BackofficeUsageCostBreakdown.d.ts.map +1 -1
- package/lib/types/components/backoffice/filters/deferredFilterSearchInput.css.d.ts.map +1 -1
- package/lib/types/components/backoffice/tools/BackofficeToolsErrorFallback.d.ts.map +1 -1
- package/lib/types/pages/BackofficeDashboardPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityDetailLayoutPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityDetailPage.view-helpers.d.ts +4 -3
- package/lib/types/pages/BackofficeEntityDetailPage.view-helpers.d.ts.map +1 -1
- package/package.json +19 -19
package/README.md
CHANGED
|
@@ -66,6 +66,9 @@ packages.
|
|
|
66
66
|
- `AcceptInvitationScreen`
|
|
67
67
|
- `PasswordResetRequestScreen`
|
|
68
68
|
- `PasswordResetCompleteScreen`
|
|
69
|
+
- Invitation acceptance and password reset use the shared `PasswordField`
|
|
70
|
+
reveal/hide controls while retaining new-password autocomplete and the
|
|
71
|
+
screen-owned password validation.
|
|
69
72
|
- `VerifyEmailScreen`
|
|
70
73
|
- `createUseAuth`
|
|
71
74
|
- `AuthRefreshNotice` keeps the backoffice session-refresh subscription and
|
|
@@ -140,6 +143,10 @@ only helpers tied to backoffice mutations, connections, and typed data.
|
|
|
140
143
|
The reusable picker visuals live in `@plumile/ui` as
|
|
141
144
|
`BackofficePickerShell`, `BackofficePickerList`, and `BackofficePickerRow`.
|
|
142
145
|
|
|
146
|
+
`BackofficeUsageCostBreakdown` totals accept rich `value` content when copying
|
|
147
|
+
is disabled. A total with `copyValue` requires a `UiText` value (`string | number`),
|
|
148
|
+
matching the shared `MetricCard` copy contract at compile time.
|
|
149
|
+
|
|
143
150
|
Backoffice React no longer exports generic toolbar or detail-header wrappers.
|
|
144
151
|
Use `BackofficeToolbar`, `BackofficeListFilterToolbar`,
|
|
145
152
|
`BackofficeListFooter`, and `PageHeader` from `@plumile/ui` for
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* empty css */
|
|
2
2
|
//#region src/auth/authRefreshNotice.css.ts
|
|
3
|
-
var e = "tc0xii0
|
|
3
|
+
var e = "tc0xii0 txvbqbk6s txvbqb2mn txvbqb1j5 txvbqb1lr txvbqb16q txvbqbbx0 txvbqbcbg txvbqb19c";
|
|
4
4
|
//#endregion
|
|
5
5
|
export { e as root };
|
|
6
6
|
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import { brandGhostButton as e,
|
|
2
|
-
import { useBackofficeReactTranslation as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { brandGhostButton as e, footer as t, stack as n } from "./loginPage.css.js";
|
|
2
|
+
import { useBackofficeReactTranslation as r } from "../../i18n/useBackofficeReactTranslation.js";
|
|
3
|
+
import { cx as i } from "@plumile/ui/theme";
|
|
4
|
+
import { jsx as a } from "react/jsx-runtime";
|
|
5
|
+
import { Button as o } from "@plumile/ui/button";
|
|
5
6
|
//#region src/auth/login/OidcButtons.tsx
|
|
6
|
-
var
|
|
7
|
-
let { t:
|
|
8
|
-
return
|
|
9
|
-
className: t,
|
|
10
|
-
children:
|
|
11
|
-
let n =
|
|
12
|
-
t === "GOOGLE" ? n =
|
|
13
|
-
let
|
|
14
|
-
return /* @__PURE__ */
|
|
7
|
+
var s = "/auth/oidc/start", c = ({ providers: c }) => {
|
|
8
|
+
let { t: l } = r();
|
|
9
|
+
return c.length === 0 ? null : /* @__PURE__ */ a("div", {
|
|
10
|
+
className: i(n, t),
|
|
11
|
+
children: c.map((t) => {
|
|
12
|
+
let n = l("auth.oidc.buttons.generic");
|
|
13
|
+
t === "GOOGLE" ? n = l("auth.oidc.buttons.google") : t === "APPLE" && (n = l("auth.oidc.buttons.apple"));
|
|
14
|
+
let r = t.toLowerCase();
|
|
15
|
+
return /* @__PURE__ */ a(o, {
|
|
15
16
|
type: "button",
|
|
16
17
|
variant: "soft",
|
|
17
18
|
className: e,
|
|
18
19
|
onClick: () => {
|
|
19
|
-
window.location.assign(`${
|
|
20
|
+
window.location.assign(`${s}?provider=${r}`);
|
|
20
21
|
},
|
|
21
22
|
tone: "neutral",
|
|
22
23
|
children: n
|
|
@@ -25,6 +26,6 @@ var a = "/auth/oidc/start", o = ({ providers: o }) => {
|
|
|
25
26
|
});
|
|
26
27
|
};
|
|
27
28
|
//#endregion
|
|
28
|
-
export {
|
|
29
|
+
export { c as OidcButtons };
|
|
29
30
|
|
|
30
31
|
//# sourceMappingURL=OidcButtons.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OidcButtons.js","names":[],"sources":["../../../../src/auth/login/OidcButtons.tsx"],"sourcesContent":["import { type JSX } from 'react';\n\nimport { Button } from '@plumile/ui/button';\n\nimport type { OidcProviderKind } from '../../modules/sharedSchemaTypes.js';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport * as styles from './loginPage.css.js';\n\nconst OIDC_START_PATH = '/auth/oidc/start';\n\ntype Props = {\n providers: readonly OidcProviderKind[];\n};\n\nexport const OidcButtons = ({ providers }: Props): JSX.Element | null => {\n const { t } = useBackofficeReactTranslation();\n\n if (providers.length === 0) {\n return null;\n }\n\n return (\n <div className={styles.stack}>\n {providers.map((provider) => {\n let label = t('auth.oidc.buttons.generic');\n if (provider === 'GOOGLE') {\n label = t('auth.oidc.buttons.google');\n } else if (provider === 'APPLE') {\n label = t('auth.oidc.buttons.apple');\n }\n const providerName = provider.toLowerCase();\n return (\n <Button\n key={provider}\n type=\"button\"\n variant=\"soft\"\n className={styles.brandGhostButton}\n onClick={() => {\n window.location.assign(\n `${OIDC_START_PATH}?provider=${providerName}`,\n );\n }}\n tone=\"neutral\"\n >\n {label}\n </Button>\n );\n })}\n </div>\n );\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"OidcButtons.js","names":[],"sources":["../../../../src/auth/login/OidcButtons.tsx"],"sourcesContent":["import { type JSX } from 'react';\n\nimport { Button } from '@plumile/ui/button';\nimport { cx } from '@plumile/ui/theme';\n\nimport type { OidcProviderKind } from '../../modules/sharedSchemaTypes.js';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport * as styles from './loginPage.css.js';\n\nconst OIDC_START_PATH = '/auth/oidc/start';\n\ntype Props = {\n providers: readonly OidcProviderKind[];\n};\n\nexport const OidcButtons = ({ providers }: Props): JSX.Element | null => {\n const { t } = useBackofficeReactTranslation();\n\n if (providers.length === 0) {\n return null;\n }\n\n return (\n <div className={cx(styles.stack, styles.footer)}>\n {providers.map((provider) => {\n let label = t('auth.oidc.buttons.generic');\n if (provider === 'GOOGLE') {\n label = t('auth.oidc.buttons.google');\n } else if (provider === 'APPLE') {\n label = t('auth.oidc.buttons.apple');\n }\n const providerName = provider.toLowerCase();\n return (\n <Button\n key={provider}\n type=\"button\"\n variant=\"soft\"\n className={styles.brandGhostButton}\n onClick={() => {\n window.location.assign(\n `${OIDC_START_PATH}?provider=${providerName}`,\n );\n }}\n tone=\"neutral\"\n >\n {label}\n </Button>\n );\n })}\n </div>\n );\n};\n"],"mappings":";;;;;;AAUA,IAAM,IAAkB,oBAMX,KAAe,EAAE,mBAA2C;CACvE,IAAM,EAAE,SAAM,EAA8B;CAM5C,OAJI,EAAU,WAAW,IAChB,OAIP,kBAAC,OAAD;EAAK,WAAW,EAAG,GAAc,CAAa;EAC3C,UAAA,EAAU,KAAK,MAAa;GAC3B,IAAI,IAAQ,EAAE,2BAA2B;GACzC,AAAI,MAAa,WACf,IAAQ,EAAE,0BAA0B,IAC3B,MAAa,YACtB,IAAQ,EAAE,yBAAyB;GAErC,IAAM,IAAe,EAAS,YAAY;GAC1C,OACE,kBAAC,GAAD;IAEE,MAAK;IACL,SAAQ;IACR,WAAW;IACX,eAAe;KACb,OAAO,SAAS,OACd,GAAG,EAAgB,YAAY,GACjC;IACF;IACA,MAAK;IAEJ,UAAA;GACK,GAZD,CAYC;EAEZ,CAAC;CACE,CAAA;AAET"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* empty css */
|
|
2
2
|
//#region src/auth/login/loginPage.css.ts
|
|
3
|
-
var e = "
|
|
3
|
+
var e = "txvbqb5m2 txvbqb6mq txvbqb6su", t = "txvbqb5m2 txvbqb6mq txvbqbla8", n = "txvbqbei txvbqb6o4 txvbqb1s4 txvbqb1rd", r = "txvbqb2ny txvbqbei txvbqb5m2 txvbqb6sa txvbqbax6 txvbqb8r4", i = "txvbqbbg txvbqb856 txvbqb1cw txvbqbnj txvbqbgg", a = "txvbqb2ny txvbqb5m2 txvbqb1d5 txvbqb6sk txvbqb8pg txvbqbawm", o = "w8yhmy0 txvbqb8y txvbqbkk txvbqbn6 txvbqbf4 txvbqbv txvbqb1dg txvbqbf5e txvbqb3p txvbqb7y txvbqb7j txvbqb89 txvbqbodq txvbqbpwu", s = "txvbqb132 txvbqb12m txvbqb13u txvbqb13j txvbqbis8 txvbqbji2", c = "txvbqb5m2 txvbqb6mq txvbqb6su", l = "txvbqbla8", u = "txvbqb1s4 txvbqb6oy txvbqb1dh txvbqbf4 txvbqb1oa", d = "txvbqbaww", f = "w8yhmy1 txvbqbjf txvbqbls txvbqbn8 txvbqbf4 txvbqbbe txvbqb7y txvbqb7h txvbqb89";
|
|
4
4
|
//#endregion
|
|
5
5
|
export { a as actionsRow, c as block, f as brandGhostButton, r as divider, i as dividerLine, d as footer, t as formSurface, l as fullWidth, n as helper, o as inlineLink, s as panel, u as panelTitle, e as stack };
|
|
6
6
|
|
|
@@ -3,7 +3,7 @@ import { AuthPanel as n } from "../login/AuthPanel.js";
|
|
|
3
3
|
import { useBackofficeReactTranslation as r } from "../../i18n/useBackofficeReactTranslation.js";
|
|
4
4
|
import { MfaChallengeForm as i } from "../login/MfaChallengeForm.js";
|
|
5
5
|
import { useCallback as a, useMemo as o, useState as s } from "react";
|
|
6
|
-
import { AuthLayout as c, Form as l, FormError as u,
|
|
6
|
+
import { AuthLayout as c, Form as l, FormError as u, PasswordField as d } from "@plumile/ui";
|
|
7
7
|
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
8
8
|
import { Button as m } from "@plumile/ui/button";
|
|
9
9
|
//#region src/auth/pages/AcceptInvitationScreen.tsx
|
|
@@ -78,12 +78,11 @@ var h = ({ auth: h, onSuccessRedirect: g, onBackToLogin: _, token: v }) => {
|
|
|
78
78
|
k != null && j == null ? /* @__PURE__ */ f(u, { children: k }) : null,
|
|
79
79
|
/* @__PURE__ */ f(d, {
|
|
80
80
|
label: y("auth.acceptInvitation.form.passwordLabel"),
|
|
81
|
-
error: j === "password" ? k :
|
|
81
|
+
error: j === "password" ? k ?? void 0 : void 0,
|
|
82
82
|
name: "password",
|
|
83
|
-
type: "password",
|
|
84
83
|
value: C,
|
|
85
|
-
|
|
86
|
-
w(e
|
|
84
|
+
onValueChange: (e) => {
|
|
85
|
+
w(e), A(null), M(null), x === "error" && S("idle");
|
|
87
86
|
},
|
|
88
87
|
placeholder: y("auth.acceptInvitation.form.passwordPlaceholder"),
|
|
89
88
|
autoComplete: "new-password",
|
|
@@ -91,12 +90,11 @@ var h = ({ auth: h, onSuccessRedirect: g, onBackToLogin: _, token: v }) => {
|
|
|
91
90
|
}),
|
|
92
91
|
/* @__PURE__ */ f(d, {
|
|
93
92
|
label: y("auth.acceptInvitation.form.confirmLabel"),
|
|
94
|
-
error: j === "passwordConfirmation" ? k :
|
|
93
|
+
error: j === "passwordConfirmation" ? k ?? void 0 : void 0,
|
|
95
94
|
name: "password-confirmation",
|
|
96
|
-
type: "password",
|
|
97
95
|
value: T,
|
|
98
|
-
|
|
99
|
-
E(e
|
|
96
|
+
onValueChange: (e) => {
|
|
97
|
+
E(e), A(null), M(null), x === "error" && S("idle");
|
|
100
98
|
},
|
|
101
99
|
placeholder: y("auth.acceptInvitation.form.confirmPlaceholder"),
|
|
102
100
|
autoComplete: "new-password",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AcceptInvitationScreen.js","names":[],"sources":["../../../../src/auth/pages/AcceptInvitationScreen.tsx"],"sourcesContent":["import {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { Button } from '@plumile/ui/button';\nimport { FormError,
|
|
1
|
+
{"version":3,"file":"AcceptInvitationScreen.js","names":[],"sources":["../../../../src/auth/pages/AcceptInvitationScreen.tsx"],"sourcesContent":["import {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { Button } from '@plumile/ui/button';\nimport { FormError, PasswordField, Form, AuthLayout } from '@plumile/ui';\n\nimport type { UseAuthReturn } from '../../hooks/useAuth.js';\nimport { MfaChallengeForm } from '../login/MfaChallengeForm.js';\nimport { AuthPanel } from '../login/AuthPanel.js';\nimport * as styles from '../login/loginPage.css.js';\n\ntype AcceptanceState = 'pending' | 'mfa' | 'completed' | 'error' | 'idle';\ntype InvitationErrorField = 'password' | 'passwordConfirmation' | null;\n\ntype Props = {\n auth: UseAuthReturn;\n onSuccessRedirect: () => void;\n onBackToLogin: () => void;\n token?: string;\n};\n\nexport const AcceptInvitationScreen = ({\n auth,\n onSuccessRedirect,\n onBackToLogin,\n token,\n}: Props): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const { acceptInvitation } = auth;\n const [status, setStatus] = useState<AcceptanceState>('idle');\n const [password, setPassword] = useState('');\n const [passwordConfirmation, setPasswordConfirmation] = useState('');\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const [errorField, setErrorField] = useState<InvitationErrorField>(null);\n\n const resolvedToken = useMemo(() => {\n if (token != null) {\n return token;\n }\n if (typeof window === 'undefined') {\n return '';\n }\n const params = new URLSearchParams(window.location.search);\n return params.get('token') ?? '';\n }, [token]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setErrorField(null);\n if (resolvedToken === '') {\n setErrorMessage(t('auth.acceptInvitation.errors.missingToken'));\n setStatus('error');\n return;\n }\n\n if (password === '') {\n setErrorMessage(\n t('auth.acceptInvitation.errors.passwordPolicyViolation'),\n );\n setErrorField('password');\n setStatus('error');\n return;\n }\n\n if (passwordConfirmation === '') {\n setErrorMessage(t('auth.acceptInvitation.errors.passwordMismatch'));\n setErrorField('passwordConfirmation');\n setStatus('error');\n return;\n }\n\n if (password !== passwordConfirmation) {\n setErrorMessage(t('auth.acceptInvitation.errors.passwordMismatch'));\n setErrorField('passwordConfirmation');\n setStatus('error');\n return;\n }\n\n setStatus('pending');\n setErrorMessage(null);\n setIsSubmitting(true);\n\n // eslint-disable-next-line no-void\n void acceptInvitation({\n token: resolvedToken,\n password,\n passwordConfirmation,\n })\n .then((result) => {\n if (result === 'mfa-required') {\n setStatus('mfa');\n return;\n }\n setStatus('completed');\n onSuccessRedirect();\n })\n .catch(() => {\n setStatus('error');\n setErrorMessage(t('auth.acceptInvitation.errors.default'));\n })\n .finally(() => {\n setIsSubmitting(false);\n });\n },\n [\n acceptInvitation,\n onSuccessRedirect,\n password,\n passwordConfirmation,\n resolvedToken,\n t,\n ],\n );\n\n const handleMfaSuccess = useCallback(() => {\n setStatus('completed');\n onSuccessRedirect();\n }, [onSuccessRedirect]);\n\n const handleRetry = useCallback(() => {\n setStatus('idle');\n setErrorMessage(null);\n setErrorField(null);\n setIsSubmitting(false);\n }, []);\n\n if (status === 'mfa') {\n return (\n <AuthLayout\n title={t('auth.acceptInvitation.mfaTitle')}\n subtitle={t('auth.acceptInvitation.mfaSubtitle')}\n >\n <MfaChallengeForm\n auth={auth}\n onSuccess={handleMfaSuccess}\n onBack={() => {\n auth.reset();\n handleRetry();\n }}\n />\n </AuthLayout>\n );\n }\n\n let content: JSX.Element;\n if (status === 'completed') {\n content = (\n <AuthPanel>\n <p className={styles.helper}>\n {t('auth.acceptInvitation.status.success')}\n </p>\n </AuthPanel>\n );\n } else {\n content = (\n <AuthPanel description={t('auth.acceptInvitation.subtitle')}>\n <Form\n className={styles.formSurface}\n onSubmit={handleSubmit}\n noValidate\n initialFocus=\"first-form-control\"\n >\n {errorMessage != null && errorField == null ? (\n <FormError>{errorMessage}</FormError>\n ) : null}\n <PasswordField\n label={t('auth.acceptInvitation.form.passwordLabel')}\n error={\n errorField === 'password'\n ? (errorMessage ?? undefined)\n : undefined\n }\n name=\"password\"\n value={password}\n onValueChange={(value) => {\n setPassword(value);\n setErrorMessage(null);\n setErrorField(null);\n if (status === 'error') {\n setStatus('idle');\n }\n }}\n placeholder={t('auth.acceptInvitation.form.passwordPlaceholder')}\n autoComplete=\"new-password\"\n required\n />\n <PasswordField\n label={t('auth.acceptInvitation.form.confirmLabel')}\n error={\n errorField === 'passwordConfirmation'\n ? (errorMessage ?? undefined)\n : undefined\n }\n name=\"password-confirmation\"\n value={passwordConfirmation}\n onValueChange={(value) => {\n setPasswordConfirmation(value);\n setErrorMessage(null);\n setErrorField(null);\n if (status === 'error') {\n setStatus('idle');\n }\n }}\n placeholder={t('auth.acceptInvitation.form.confirmPlaceholder')}\n autoComplete=\"new-password\"\n required\n />\n <Button type=\"submit\" loading={isSubmitting}>\n {status === 'pending'\n ? t('auth.acceptInvitation.status.workingButton')\n : t('auth.acceptInvitation.form.submit')}\n </Button>\n <Button\n type=\"button\"\n variant=\"soft\"\n onClick={onBackToLogin}\n tone=\"neutral\"\n >\n {t('auth.acceptInvitation.actions.backToLogin')}\n </Button>\n </Form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout title={t('auth.acceptInvitation.title')}>{content}</AuthLayout>\n );\n};\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { brandGhostButton as e, formSurface as t, helper as n } from "../login/l
|
|
|
2
2
|
import { AuthPanel as r } from "../login/AuthPanel.js";
|
|
3
3
|
import { useBackofficeReactTranslation as i } from "../../i18n/useBackofficeReactTranslation.js";
|
|
4
4
|
import { useCallback as a, useMemo as o, useState as s } from "react";
|
|
5
|
-
import { AuthLayout as c, Form as l, FormError as u,
|
|
5
|
+
import { AuthLayout as c, Form as l, FormError as u, PasswordField as d } from "@plumile/ui";
|
|
6
6
|
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
7
7
|
import { Button as m } from "@plumile/ui/button";
|
|
8
8
|
//#region src/auth/pages/PasswordResetCompleteScreen.tsx
|
|
@@ -66,12 +66,11 @@ var h = 8, g = ({ onBackToLogin: g, onCompletePasswordReset: _, token: v }) => {
|
|
|
66
66
|
E != null && O == null ? /* @__PURE__ */ f(u, { children: E }) : null,
|
|
67
67
|
/* @__PURE__ */ f(d, {
|
|
68
68
|
label: y("auth.passwordResetComplete.form.passwordLabel"),
|
|
69
|
-
error: O === "password" ? E :
|
|
69
|
+
error: O === "password" ? E ?? void 0 : void 0,
|
|
70
70
|
name: "new-password",
|
|
71
|
-
type: "password",
|
|
72
71
|
value: b,
|
|
73
|
-
|
|
74
|
-
x(e
|
|
72
|
+
onValueChange: (e) => {
|
|
73
|
+
x(e), D(null), k(null);
|
|
75
74
|
},
|
|
76
75
|
placeholder: y("auth.passwordResetComplete.form.passwordPlaceholder"),
|
|
77
76
|
autoComplete: "new-password",
|
|
@@ -79,12 +78,11 @@ var h = 8, g = ({ onBackToLogin: g, onCompletePasswordReset: _, token: v }) => {
|
|
|
79
78
|
}),
|
|
80
79
|
/* @__PURE__ */ f(d, {
|
|
81
80
|
label: y("auth.passwordResetComplete.form.confirmLabel"),
|
|
82
|
-
error: O === "passwordConfirm" ? E :
|
|
81
|
+
error: O === "passwordConfirm" ? E ?? void 0 : void 0,
|
|
83
82
|
name: "confirm-password",
|
|
84
|
-
type: "password",
|
|
85
83
|
value: S,
|
|
86
|
-
|
|
87
|
-
C(e
|
|
84
|
+
onValueChange: (e) => {
|
|
85
|
+
C(e), D(null), k(null);
|
|
88
86
|
},
|
|
89
87
|
placeholder: y("auth.passwordResetComplete.form.confirmPlaceholder"),
|
|
90
88
|
autoComplete: "new-password",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordResetCompleteScreen.js","names":[],"sources":["../../../../src/auth/pages/PasswordResetCompleteScreen.tsx"],"sourcesContent":["import {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { Button } from '@plumile/ui/button';\nimport { FormError,
|
|
1
|
+
{"version":3,"file":"PasswordResetCompleteScreen.js","names":[],"sources":["../../../../src/auth/pages/PasswordResetCompleteScreen.tsx"],"sourcesContent":["import {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { Button } from '@plumile/ui/button';\nimport { FormError, PasswordField, Form, AuthLayout } from '@plumile/ui';\n\nimport * as styles from '../login/loginPage.css.js';\nimport { AuthPanel } from '../login/AuthPanel.js';\n\nconst MIN_PASSWORD_LENGTH = 8;\ntype PasswordResetErrorField = 'password' | 'passwordConfirm' | null;\n\ntype Props = {\n onBackToLogin: () => void;\n onCompletePasswordReset: (input: {\n newPassword: string;\n token: string;\n }) => Promise<boolean>;\n token?: string;\n};\n\nexport const PasswordResetCompleteScreen = ({\n onBackToLogin,\n onCompletePasswordReset,\n token,\n}: Props): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const [password, setPassword] = useState('');\n const [passwordConfirm, setPasswordConfirm] = useState('');\n const [status, setStatus] = useState<'idle' | 'completed'>('idle');\n const [error, setError] = useState<string | null>(null);\n const [errorField, setErrorField] = useState<PasswordResetErrorField>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const resolvedToken = useMemo(() => {\n if (token != null) {\n return token;\n }\n if (typeof window === 'undefined') {\n return '';\n }\n const params = new URLSearchParams(window.location.search);\n return params.get('token') ?? '';\n }, [token]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n setErrorField(null);\n\n if (resolvedToken === '') {\n setError(t('auth.passwordResetComplete.errors.missingToken'));\n return;\n }\n\n if (password.length < MIN_PASSWORD_LENGTH) {\n setError(\n t('auth.passwordResetComplete.errors.minLength', {\n minLength: MIN_PASSWORD_LENGTH,\n }),\n );\n setErrorField('password');\n return;\n }\n\n if (password !== passwordConfirm) {\n setError(t('auth.passwordResetComplete.errors.mismatch'));\n setErrorField('passwordConfirm');\n return;\n }\n\n setIsSubmitting(true);\n\n const completePasswordReset = async (): Promise<void> => {\n try {\n const success = await onCompletePasswordReset({\n newPassword: password,\n token: resolvedToken,\n });\n if (success) {\n setStatus('completed');\n } else {\n setError(t('auth.passwordResetComplete.errors.invalid'));\n }\n } catch (mutationError) {\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.passwordResetComplete.errors.invalid'),\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n completePasswordReset().catch(() => {\n return undefined;\n });\n },\n [onCompletePasswordReset, password, passwordConfirm, resolvedToken, t],\n );\n\n let content: JSX.Element;\n if (status === 'completed') {\n content = (\n <AuthPanel\n title={t('auth.passwordResetComplete.success.title')}\n description={t('auth.passwordResetComplete.success.description')}\n footer={\n <Button\n type=\"button\"\n variant=\"soft\"\n className={styles.brandGhostButton}\n onClick={onBackToLogin}\n tone=\"neutral\"\n >\n {t('auth.passwordResetComplete.success.action')}\n </Button>\n }\n >\n <p className={styles.helper}>\n {t('auth.passwordResetComplete.success.helper')}\n </p>\n </AuthPanel>\n );\n } else {\n content = (\n <AuthPanel\n title={t('auth.passwordResetComplete.form.title')}\n description={t('auth.passwordResetComplete.form.description')}\n >\n <Form\n className={styles.formSurface}\n onSubmit={handleSubmit}\n noValidate\n initialFocus=\"first-form-control\"\n >\n {error != null && errorField == null ? (\n <FormError>{error}</FormError>\n ) : null}\n <PasswordField\n label={t('auth.passwordResetComplete.form.passwordLabel')}\n error={errorField === 'password' ? (error ?? undefined) : undefined}\n name=\"new-password\"\n value={password}\n onValueChange={(value) => {\n setPassword(value);\n setError(null);\n setErrorField(null);\n }}\n placeholder={t(\n 'auth.passwordResetComplete.form.passwordPlaceholder',\n )}\n autoComplete=\"new-password\"\n required\n />\n <PasswordField\n label={t('auth.passwordResetComplete.form.confirmLabel')}\n error={\n errorField === 'passwordConfirm'\n ? (error ?? undefined)\n : undefined\n }\n name=\"confirm-password\"\n value={passwordConfirm}\n onValueChange={(value) => {\n setPasswordConfirm(value);\n setError(null);\n setErrorField(null);\n }}\n placeholder={t(\n 'auth.passwordResetComplete.form.confirmPlaceholder',\n )}\n autoComplete=\"new-password\"\n required\n />\n <Button type=\"submit\" loading={isSubmitting}>\n {t('auth.passwordResetComplete.form.submit')}\n </Button>\n </Form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout\n title={t('auth.passwordResetComplete.title')}\n subtitle={t('auth.passwordResetComplete.subtitle')}\n >\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ var m = ({ onStartPasswordReset: m }) => {
|
|
|
10
10
|
let { i18n: h, t: g } = r(), [_, v] = o(""), [y, b] = o("idle"), [x, S] = o(null), [C, w] = o(!1), [T, E] = o(!1), D = a(() => {
|
|
11
11
|
let e = h.language.trim();
|
|
12
12
|
if (e !== "") return e;
|
|
13
|
-
if (
|
|
13
|
+
if (typeof navigator < "u") return navigator.language;
|
|
14
14
|
}, [h.language]), O = i((e) => {
|
|
15
15
|
if (e.preventDefault(), S(null), w(!1), _.trim() === "") {
|
|
16
16
|
S(g("auth.passwordResetRequest.errors.emailRequired")), w(!0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordResetRequestScreen.js","names":[],"sources":["../../../../src/auth/pages/PasswordResetRequestScreen.tsx"],"sourcesContent":["import {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { Button } from '@plumile/ui/button';\nimport { FormError, FormField, Form, AuthLayout } from '@plumile/ui';\n\nimport * as styles from '../login/loginPage.css.js';\nimport { AuthPanel } from '../login/AuthPanel.js';\n\ntype Props = {\n onStartPasswordReset: (input: {\n email: string;\n locale?: string;\n }) => Promise<boolean>;\n};\n\nexport const PasswordResetRequestScreen = ({\n onStartPasswordReset,\n}: Props): JSX.Element => {\n const { i18n, t } = useBackofficeReactTranslation();\n const [email, setEmail] = useState('');\n const [status, setStatus] = useState<'idle' | 'sent'>('idle');\n const [error, setError] = useState<string | null>(null);\n const [hasEmailError, setHasEmailError] = useState(false);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const locale = useMemo(() => {\n const language = i18n.language.trim();\n if (language !== '') {\n return language;\n }\n if (typeof navigator === 'undefined') {\n return undefined;\n }\n return navigator.language;\n }, [i18n.language]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n setHasEmailError(false);\n\n if (email.trim() === '') {\n setError(t('auth.passwordResetRequest.errors.emailRequired'));\n setHasEmailError(true);\n return;\n }\n\n const emailInput = event.currentTarget.elements.namedItem('email');\n if (\n emailInput instanceof HTMLInputElement &&\n !emailInput.validity.valid\n ) {\n setError(t('auth.passwordResetRequest.errors.invalidEmail'));\n setHasEmailError(true);\n return;\n }\n\n setIsSubmitting(true);\n onStartPasswordReset({\n email: email.trim(),\n locale,\n })\n .then((success) => {\n if (success) {\n setStatus('sent');\n } else {\n setError(t('auth.passwordResetRequest.errors.startFailed'));\n }\n })\n .catch((mutationError) => {\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.passwordResetRequest.errors.startFailed'),\n );\n })\n .finally(() => {\n setIsSubmitting(false);\n });\n },\n [email, locale, onStartPasswordReset, t],\n );\n\n let content: JSX.Element;\n if (status === 'sent') {\n content = (\n <AuthPanel\n title={t('auth.passwordResetRequest.sent.title')}\n description={t('auth.passwordResetRequest.sent.description', { email })}\n footer={\n <Button\n type=\"button\"\n variant=\"soft\"\n onClick={() => {\n setStatus('idle');\n }}\n tone=\"neutral\"\n >\n {t('auth.passwordResetRequest.sent.action')}\n </Button>\n }\n >\n <p className={styles.helper}>\n {t('auth.passwordResetRequest.sent.helper')}\n </p>\n </AuthPanel>\n );\n } else {\n content = (\n <AuthPanel description={t('auth.passwordResetRequest.form.description')}>\n <Form\n className={styles.formSurface}\n onSubmit={handleSubmit}\n noValidate\n initialFocus=\"first-form-control\"\n >\n {error != null && !hasEmailError ? (\n <FormError>{error}</FormError>\n ) : null}\n <FormField\n label={t('auth.passwordResetRequest.form.emailLabel')}\n error={hasEmailError ? error : null}\n name=\"email\"\n type=\"email\"\n value={email}\n onChange={(event) => {\n setEmail(event.target.value);\n setError(null);\n setHasEmailError(false);\n }}\n placeholder={t('auth.passwordResetRequest.form.emailPlaceholder')}\n autoComplete=\"email\"\n required\n />\n <Button type=\"submit\" loading={isSubmitting}>\n {t('auth.passwordResetRequest.form.submit')}\n </Button>\n </Form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout title={t('auth.passwordResetRequest.title')}>\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":";;;;;;;;AAsBA,IAAa,KAA8B,EACzC,8BACwB;CACxB,IAAM,EAAE,SAAM,SAAM,EAA8B,GAC5C,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,CAAC,GAAQ,KAAa,EAA0B,MAAM,GACtD,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAe,KAAoB,EAAS,EAAK,GAClD,CAAC,GAAc,KAAmB,EAAS,EAAK,GAEhD,IAAS,QAAc;EAC3B,IAAM,IAAW,EAAK,SAAS,KAAK;EACpC,IAAI,MAAa,IACf,OAAO;EAEL,
|
|
1
|
+
{"version":3,"file":"PasswordResetRequestScreen.js","names":[],"sources":["../../../../src/auth/pages/PasswordResetRequestScreen.tsx"],"sourcesContent":["import {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { Button } from '@plumile/ui/button';\nimport { FormError, FormField, Form, AuthLayout } from '@plumile/ui';\n\nimport * as styles from '../login/loginPage.css.js';\nimport { AuthPanel } from '../login/AuthPanel.js';\n\ntype Props = {\n onStartPasswordReset: (input: {\n email: string;\n locale?: string;\n }) => Promise<boolean>;\n};\n\nexport const PasswordResetRequestScreen = ({\n onStartPasswordReset,\n}: Props): JSX.Element => {\n const { i18n, t } = useBackofficeReactTranslation();\n const [email, setEmail] = useState('');\n const [status, setStatus] = useState<'idle' | 'sent'>('idle');\n const [error, setError] = useState<string | null>(null);\n const [hasEmailError, setHasEmailError] = useState(false);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const locale = useMemo(() => {\n const language = i18n.language.trim();\n if (language !== '') {\n return language;\n }\n if (typeof navigator === 'undefined') {\n return undefined;\n }\n return navigator.language;\n }, [i18n.language]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n setHasEmailError(false);\n\n if (email.trim() === '') {\n setError(t('auth.passwordResetRequest.errors.emailRequired'));\n setHasEmailError(true);\n return;\n }\n\n const emailInput = event.currentTarget.elements.namedItem('email');\n if (\n emailInput instanceof HTMLInputElement &&\n !emailInput.validity.valid\n ) {\n setError(t('auth.passwordResetRequest.errors.invalidEmail'));\n setHasEmailError(true);\n return;\n }\n\n setIsSubmitting(true);\n onStartPasswordReset({\n email: email.trim(),\n locale,\n })\n .then((success) => {\n if (success) {\n setStatus('sent');\n } else {\n setError(t('auth.passwordResetRequest.errors.startFailed'));\n }\n })\n .catch((mutationError) => {\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.passwordResetRequest.errors.startFailed'),\n );\n })\n .finally(() => {\n setIsSubmitting(false);\n });\n },\n [email, locale, onStartPasswordReset, t],\n );\n\n let content: JSX.Element;\n if (status === 'sent') {\n content = (\n <AuthPanel\n title={t('auth.passwordResetRequest.sent.title')}\n description={t('auth.passwordResetRequest.sent.description', { email })}\n footer={\n <Button\n type=\"button\"\n variant=\"soft\"\n onClick={() => {\n setStatus('idle');\n }}\n tone=\"neutral\"\n >\n {t('auth.passwordResetRequest.sent.action')}\n </Button>\n }\n >\n <p className={styles.helper}>\n {t('auth.passwordResetRequest.sent.helper')}\n </p>\n </AuthPanel>\n );\n } else {\n content = (\n <AuthPanel description={t('auth.passwordResetRequest.form.description')}>\n <Form\n className={styles.formSurface}\n onSubmit={handleSubmit}\n noValidate\n initialFocus=\"first-form-control\"\n >\n {error != null && !hasEmailError ? (\n <FormError>{error}</FormError>\n ) : null}\n <FormField\n label={t('auth.passwordResetRequest.form.emailLabel')}\n error={hasEmailError ? error : null}\n name=\"email\"\n type=\"email\"\n value={email}\n onChange={(event) => {\n setEmail(event.target.value);\n setError(null);\n setHasEmailError(false);\n }}\n placeholder={t('auth.passwordResetRequest.form.emailPlaceholder')}\n autoComplete=\"email\"\n required\n />\n <Button type=\"submit\" loading={isSubmitting}>\n {t('auth.passwordResetRequest.form.submit')}\n </Button>\n </Form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout title={t('auth.passwordResetRequest.title')}>\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":";;;;;;;;AAsBA,IAAa,KAA8B,EACzC,8BACwB;CACxB,IAAM,EAAE,SAAM,SAAM,EAA8B,GAC5C,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,CAAC,GAAQ,KAAa,EAA0B,MAAM,GACtD,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAe,KAAoB,EAAS,EAAK,GAClD,CAAC,GAAc,KAAmB,EAAS,EAAK,GAEhD,IAAS,QAAc;EAC3B,IAAM,IAAW,EAAK,SAAS,KAAK;EACpC,IAAI,MAAa,IACf,OAAO;EAEL,WAAO,YAAc,KAGzB,OAAO,UAAU;CACnB,GAAG,CAAC,EAAK,QAAQ,CAAC,GAEZ,IAAe,GAClB,MAAsC;EAKrC,IAJA,EAAM,eAAe,GACrB,EAAS,IAAI,GACb,EAAiB,EAAK,GAElB,EAAM,KAAK,MAAM,IAAI;GAEvB,AADA,EAAS,EAAE,gDAAgD,CAAC,GAC5D,EAAiB,EAAI;GACrB;EACF;EAEA,IAAM,IAAa,EAAM,cAAc,SAAS,UAAU,OAAO;EACjE,IACE,aAAsB,oBACtB,CAAC,EAAW,SAAS,OACrB;GAEA,AADA,EAAS,EAAE,+CAA+C,CAAC,GAC3D,EAAiB,EAAI;GACrB;EACF;EAGA,AADA,EAAgB,EAAI,GACpB,EAAqB;GACnB,OAAO,EAAM,KAAK;GAClB;EACF,CAAC,CAAC,CACC,MAAM,MAAY;GACjB,AAAI,IACF,EAAU,MAAM,IAEhB,EAAS,EAAE,8CAA8C,CAAC;EAE9D,CAAC,CAAC,CACD,OAAO,MAAkB;GACxB,EACE,aAAyB,QACrB,EAAc,UACd,EAAE,8CAA8C,CACtD;EACF,CAAC,CAAC,CACD,cAAc;GACb,EAAgB,EAAK;EACvB,CAAC;CACL,GACA;EAAC;EAAO;EAAQ;EAAsB;CAAC,CACzC,GAEI;CA2DJ,OA1DA,AAwBE,IAxBE,MAAW,SAEX,kBAAC,GAAD;EACE,OAAO,EAAE,sCAAsC;EAC/C,aAAa,EAAE,8CAA8C,EAAE,SAAM,CAAC;EACtE,QACE,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,eAAe;IACb,EAAU,MAAM;GAClB;GACA,MAAK;GAEJ,UAAA,EAAE,uCAAuC;EACpC,CAAA;EAGV,UAAA,kBAAC,KAAD;GAAG,WAAW;GACX,UAAA,EAAE,uCAAuC;EACzC,CAAA;CACM,CAAA,IAIX,kBAAC,GAAD;EAAW,aAAa,EAAE,4CAA4C;EACpE,UAAA,kBAAC,GAAD;GACE,WAAW;GACX,UAAU;GACV,YAAA;GACA,cAAa;GAJf,UAAA;IAMG,KAAS,QAAQ,CAAC,IACjB,kBAAC,GAAD,EAAA,UAAY,EAAiB,CAAA,IAC3B;IACJ,kBAAC,GAAD;KACE,OAAO,EAAE,2CAA2C;KACpD,OAAO,IAAgB,IAAQ;KAC/B,MAAK;KACL,MAAK;KACL,OAAO;KACP,WAAW,MAAU;MAGnB,AAFA,EAAS,EAAM,OAAO,KAAK,GAC3B,EAAS,IAAI,GACb,EAAiB,EAAK;KACxB;KACA,aAAa,EAAE,iDAAiD;KAChE,cAAa;KACb,UAAA;IACD,CAAA;IACD,kBAAC,GAAD;KAAQ,MAAK;KAAS,SAAS;KAC5B,UAAA,EAAE,uCAAuC;IACpC,CAAA;GACJ;;CACG,CAAA,GAKb,kBAAC,GAAD;EAAY,OAAO,EAAE,iCAAiC;EACnD,UAAA;CACS,CAAA;AAEhB"}
|
|
@@ -564,7 +564,7 @@ var { commitMutation: me, useRelayEnvironment: he } = b, x = (e, t) => e(t), S =
|
|
|
564
564
|
})
|
|
565
565
|
}) }),
|
|
566
566
|
$ && /* @__PURE__ */ v("div", {
|
|
567
|
-
className: "
|
|
567
|
+
className: "txvbqb5m2 txvbqb6mq txvbqb6sa",
|
|
568
568
|
children: [z != null && Q != null && /* @__PURE__ */ _(oe, {
|
|
569
569
|
badgeLabel: Q,
|
|
570
570
|
copyCode: z,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/backoffice/actions/backofficeEntityActionFormDialog.css.ts
|
|
2
|
-
var e = "
|
|
2
|
+
var e = "txvbqb5m2 txvbqb6mq txvbqb6sk", t = "txvbqb5m2 txvbqb8ow txvbqb1d5 txvbqb6sa", n = "txvbqbkk txvbqb1s4 txvbqbe1y txvbqbf5e", r = "txvbqb6o4 txvbqb1df txvbqbeh txvbqbf5e", i = "txvbqb9ge txvbqbfq", a = "txvbqb5m2 txvbqb6mq txvbqb6sa", o = "txvbqb5m2 txvbqb6mq txvbqb6sa", s = "txvbqb6nu txvbqbfq", c = "txvbqb6nu txvbqbe6", l = "txvbqb5mw txvbqb2ny txvbqb6sa txvbqbire txvbqbjgy txvbqbnc txvbqban txvbqblp txvbqbn8 txvbqbja txvbqbei txvbqb6o4 txvbqb19b";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { t as actions, a as checkboxGroup, c as fieldDescription, s as fieldError, n as fieldset, e as form, l as lazyFallback, r as legend, i as requiredMark, o as resultSection };
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/backoffice/billing/backofficeBillingUsageChart.css.ts
|
|
2
|
-
var e = "
|
|
2
|
+
var e = "txvbqb5m2 txvbqb6mq txvbqb6sk", t = "txvbqb6p8 txvbqb6pk txvbqb1dg txvbqbeh txvbqb1s4", n = "txvbqb6nu txvbqbej txvbqb1s4";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { n as rangeText, e as root, t as totalValue };
|
|
5
5
|
|
|
@@ -14,76 +14,79 @@ var c = (e, t) => e(t), l = (e, t) => e == null || typeof e == "string" && e.tri
|
|
|
14
14
|
};
|
|
15
15
|
function f(f, p) {
|
|
16
16
|
let { tApp: m, t: h } = p, g = h("common.notAvailable");
|
|
17
|
-
return f.filter((e) => e.key !== "id").map((f) =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
17
|
+
return f.filter((e) => e.key !== "id").map((f) => {
|
|
18
|
+
let p = u(f);
|
|
19
|
+
return {
|
|
20
|
+
id: f.key,
|
|
21
|
+
header: c(f.header, m),
|
|
22
|
+
size: f.size,
|
|
23
|
+
isPrimary: f.visibility.priority === "primary",
|
|
24
|
+
priority: f.visibility.priority,
|
|
25
|
+
align: f.visibility.align,
|
|
26
|
+
mobileRole: p,
|
|
27
|
+
minVisibleAt: d(f.visibility.minVisibleAt),
|
|
28
|
+
cell: (c) => {
|
|
29
|
+
let { cell: u } = f;
|
|
30
|
+
switch (u.type) {
|
|
31
|
+
case "text": return l(u.value(c), g);
|
|
32
|
+
case "link": {
|
|
33
|
+
let e = u.value(c);
|
|
34
|
+
return e == null || typeof e == "string" && e.trim() === "" ? g : /* @__PURE__ */ i(o, {
|
|
35
|
+
to: u.to(c),
|
|
36
|
+
preloadOnHover: "code",
|
|
37
|
+
children: e
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
case "badge": {
|
|
41
|
+
let e = u.value(c);
|
|
42
|
+
if (e == null || e.trim() === "") return g;
|
|
43
|
+
let { tone: t } = u;
|
|
44
|
+
return typeof t == "function" && (t = t(c)), /* @__PURE__ */ i(s, {
|
|
45
|
+
tone: t,
|
|
46
|
+
children: e
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
case "dateTime": {
|
|
50
|
+
let e = u.value(c);
|
|
51
|
+
return /* @__PURE__ */ i(t, {
|
|
52
|
+
value: e,
|
|
53
|
+
fallback: g,
|
|
54
|
+
options: a
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
case "entityRef": {
|
|
58
|
+
let t = u.value(c);
|
|
59
|
+
if (t.trim() === "") return g;
|
|
60
|
+
let n = u.label?.(c);
|
|
61
|
+
if (n == null || n.trim() === "") return h("filters.placeholders.unresolved");
|
|
62
|
+
let r = {
|
|
63
|
+
kind: "entity-detail",
|
|
64
|
+
entityId: u.entity,
|
|
65
|
+
id: t
|
|
66
|
+
};
|
|
67
|
+
return /* @__PURE__ */ i(e, {
|
|
68
|
+
target: r,
|
|
69
|
+
children: n
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
case "technicalIdentifier": {
|
|
73
|
+
let e = u.value(c);
|
|
74
|
+
return e == null || String(e).trim() === "" ? g : /* @__PURE__ */ i(n, {
|
|
75
|
+
value: e,
|
|
76
|
+
copyValue: u.copyValue?.(c) ?? void 0,
|
|
77
|
+
abbreviation: u.abbreviation,
|
|
78
|
+
copyLabel: h("common.actions.copy")
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
case "custom": {
|
|
82
|
+
let e = u.render(c);
|
|
83
|
+
return e == null || e === "" ? g : /* @__PURE__ */ i(r, { children: e });
|
|
84
|
+
}
|
|
85
|
+
default: return g;
|
|
37
86
|
}
|
|
38
|
-
case "badge": {
|
|
39
|
-
let e = u.value(c);
|
|
40
|
-
if (e == null || e.trim() === "") return g;
|
|
41
|
-
let { tone: t } = u;
|
|
42
|
-
return typeof t == "function" && (t = t(c)), /* @__PURE__ */ i(s, {
|
|
43
|
-
tone: t,
|
|
44
|
-
children: e
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
case "dateTime": {
|
|
48
|
-
let e = u.value(c);
|
|
49
|
-
return /* @__PURE__ */ i(t, {
|
|
50
|
-
value: e,
|
|
51
|
-
fallback: g,
|
|
52
|
-
options: a
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
case "entityRef": {
|
|
56
|
-
let t = u.value(c);
|
|
57
|
-
if (t.trim() === "") return g;
|
|
58
|
-
let n = u.label?.(c);
|
|
59
|
-
if (n == null || n.trim() === "") return h("filters.placeholders.unresolved");
|
|
60
|
-
let r = {
|
|
61
|
-
kind: "entity-detail",
|
|
62
|
-
entityId: u.entity,
|
|
63
|
-
id: t
|
|
64
|
-
};
|
|
65
|
-
return /* @__PURE__ */ i(e, {
|
|
66
|
-
target: r,
|
|
67
|
-
children: n
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
case "technicalIdentifier": {
|
|
71
|
-
let e = u.value(c);
|
|
72
|
-
return e == null || String(e).trim() === "" ? g : /* @__PURE__ */ i(n, {
|
|
73
|
-
value: e,
|
|
74
|
-
copyValue: u.copyValue?.(c) ?? void 0,
|
|
75
|
-
abbreviation: u.abbreviation,
|
|
76
|
-
copyLabel: h("common.actions.copy")
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
case "custom": {
|
|
80
|
-
let e = u.render(c);
|
|
81
|
-
return e == null || e === "" ? g : /* @__PURE__ */ i(r, { children: e });
|
|
82
|
-
}
|
|
83
|
-
default: return g;
|
|
84
87
|
}
|
|
85
|
-
}
|
|
86
|
-
})
|
|
88
|
+
};
|
|
89
|
+
});
|
|
87
90
|
}
|
|
88
91
|
//#endregion
|
|
89
92
|
export { f as buildDataTableColumns };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildDataTableColumns.js","names":[],"sources":["../../../../../src/components/backoffice/columns/buildDataTableColumns.tsx"],"sourcesContent":["import { BACKOFFICE_DATE_TIME_OPTIONS } from '@plumile/backoffice-core/constants.js';\nimport type {\n BackofficeColumnSpec,\n BackofficeFieldSize,\n BackofficeListColumnVisibility,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type { TFunction } from 'i18next';\nimport Link from '@plumile/router/routing/Link.js';\nimport {\n FormattedDate,\n TechnicalIdentifierValue,\n type DataTableBreakpoint,\n type ResponsiveRecordListColumn,\n} from '@plumile/ui';\nimport { Tag } from '@plumile/ui/backoffice/atoms/tag/Tag.js';\n\nimport { BackofficeInlineLink } from '../links/BackofficeInlineLink.js';\nimport type { BackofficeLinkTarget } from '../links/types.js';\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst resolveTextValue = (\n value: string | number | null,\n fallback: string,\n): string => {\n if (value == null) {\n return fallback;\n }\n if (typeof value === 'string' && value.trim() === '') {\n return fallback;\n }\n return String(value);\n};\n\nexport type BuildDataTableColumnsOptions = {\n tApp: TFunction;\n t: TFunction;\n};\n\nexport type BackofficeSizedDataTableColumn<Row> =\n ResponsiveRecordListColumn<Row> & {\n size: BackofficeFieldSize;\n };\n\nconst resolveMobileRole = <Row,>(\n column: BackofficeColumnSpec<Row>,\n): ResponsiveRecordListColumn<Row>['mobileRole'] => {\n const role = column.visibility?.mobile;\n if (role == null) {\n throw new Error(\n `[buildDataTableColumns] column \"${column.key}\" must declare visibility.mobile.`,\n );\n }\n return role;\n};\n\nconst resolveBreakpoint = (\n value: BackofficeListColumnVisibility['minVisibleAt'] | undefined,\n): DataTableBreakpoint | undefined => {\n if (\n value === 'sm' ||\n value === 'md' ||\n value === 'lg' ||\n value === 'xl' ||\n value === '2xl'\n ) {\n return value;\n }\n return undefined;\n};\n\n/**\n *\n */\nexport function buildDataTableColumns<Row>(\n columns: readonly BackofficeColumnSpec<Row>[],\n options: BuildDataTableColumnsOptions,\n): readonly BackofficeSizedDataTableColumn<Row>[] {\n const { tApp, t } = options;\n const fallback = t('common.notAvailable');\n const filteredColumns = columns.filter((column) => {\n return column.key !== 'id';\n });\n\n return filteredColumns.map((column) => {\n return {\n id: column.key,\n header: resolveLabel(column.header, tApp),\n size: column.size,\n isPrimary: column.visibility
|
|
1
|
+
{"version":3,"file":"buildDataTableColumns.js","names":[],"sources":["../../../../../src/components/backoffice/columns/buildDataTableColumns.tsx"],"sourcesContent":["import { BACKOFFICE_DATE_TIME_OPTIONS } from '@plumile/backoffice-core/constants.js';\nimport type {\n BackofficeColumnSpec,\n BackofficeFieldSize,\n BackofficeListColumnVisibility,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type { TFunction } from 'i18next';\nimport Link from '@plumile/router/routing/Link.js';\nimport {\n FormattedDate,\n TechnicalIdentifierValue,\n type DataTableBreakpoint,\n type ResponsiveRecordListColumn,\n} from '@plumile/ui';\nimport { Tag } from '@plumile/ui/backoffice/atoms/tag/Tag.js';\n\nimport { BackofficeInlineLink } from '../links/BackofficeInlineLink.js';\nimport type { BackofficeLinkTarget } from '../links/types.js';\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst resolveTextValue = (\n value: string | number | null,\n fallback: string,\n): string => {\n if (value == null) {\n return fallback;\n }\n if (typeof value === 'string' && value.trim() === '') {\n return fallback;\n }\n return String(value);\n};\n\nexport type BuildDataTableColumnsOptions = {\n tApp: TFunction;\n t: TFunction;\n};\n\nexport type BackofficeSizedDataTableColumn<Row> =\n ResponsiveRecordListColumn<Row> & {\n size: BackofficeFieldSize;\n };\n\nconst resolveMobileRole = <Row,>(\n column: BackofficeColumnSpec<Row>,\n): ResponsiveRecordListColumn<Row>['mobileRole'] => {\n // JavaScript callers can bypass the required TypeScript contract.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const role = column.visibility?.mobile;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Untyped callers.\n if (role == null) {\n throw new Error(\n `[buildDataTableColumns] column \"${column.key}\" must declare visibility.mobile.`,\n );\n }\n return role;\n};\n\nconst resolveBreakpoint = (\n value: BackofficeListColumnVisibility['minVisibleAt'] | undefined,\n): DataTableBreakpoint | undefined => {\n if (\n value === 'sm' ||\n value === 'md' ||\n value === 'lg' ||\n value === 'xl' ||\n value === '2xl'\n ) {\n return value;\n }\n return undefined;\n};\n\n/**\n *\n */\nexport function buildDataTableColumns<Row>(\n columns: readonly BackofficeColumnSpec<Row>[],\n options: BuildDataTableColumnsOptions,\n): readonly BackofficeSizedDataTableColumn<Row>[] {\n const { tApp, t } = options;\n const fallback = t('common.notAvailable');\n const filteredColumns = columns.filter((column) => {\n return column.key !== 'id';\n });\n\n return filteredColumns.map((column) => {\n const mobileRole = resolveMobileRole(column);\n return {\n id: column.key,\n header: resolveLabel(column.header, tApp),\n size: column.size,\n isPrimary: column.visibility.priority === 'primary',\n priority: column.visibility.priority,\n align: column.visibility.align,\n mobileRole,\n minVisibleAt: resolveBreakpoint(column.visibility.minVisibleAt),\n cell: (row) => {\n const { cell } = column;\n switch (cell.type) {\n case 'text': {\n return resolveTextValue(cell.value(row), fallback);\n }\n case 'link': {\n const value = cell.value(row);\n if (\n value == null ||\n (typeof value === 'string' && value.trim() === '')\n ) {\n return fallback;\n }\n return (\n <Link to={cell.to(row)} preloadOnHover=\"code\">\n {value}\n </Link>\n );\n }\n case 'badge': {\n const value = cell.value(row);\n if (value == null || value.trim() === '') {\n return fallback;\n }\n let { tone } = cell;\n if (typeof tone === 'function') {\n tone = tone(row);\n }\n return <Tag tone={tone}>{value}</Tag>;\n }\n case 'dateTime': {\n const value = cell.value(row);\n return (\n <FormattedDate\n value={value}\n fallback={fallback}\n options={BACKOFFICE_DATE_TIME_OPTIONS}\n />\n );\n }\n case 'entityRef': {\n const id = cell.value(row);\n if (id.trim() === '') {\n return fallback;\n }\n const label = cell.label?.(row);\n if (label == null || label.trim() === '') {\n return t('filters.placeholders.unresolved');\n }\n const target = {\n kind: 'entity-detail',\n entityId: cell.entity,\n id,\n } as BackofficeLinkTarget;\n return (\n <BackofficeInlineLink target={target}>\n {label}\n </BackofficeInlineLink>\n );\n }\n case 'technicalIdentifier': {\n const value = cell.value(row);\n if (value == null || String(value).trim() === '') {\n return fallback;\n }\n return (\n <TechnicalIdentifierValue\n value={value}\n copyValue={cell.copyValue?.(row) ?? undefined}\n abbreviation={cell.abbreviation}\n copyLabel={t('common.actions.copy')}\n />\n );\n }\n case 'custom': {\n const rendered = cell.render(row);\n if (rendered == null || rendered === '') {\n return fallback;\n }\n return <>{rendered}</>;\n }\n default: {\n return fallback;\n }\n }\n },\n };\n });\n}\n"],"mappings":";;;;;;;AAoBA,IAAM,KAAgB,GAAkB,MAC/B,EAAM,CAAI,GAGb,KACJ,GACA,MAEI,KAAS,QAGT,OAAO,KAAU,YAAY,EAAM,KAAK,MAAM,KACzC,IAEF,OAAO,CAAK,GAaf,KACJ,MACkD;CAGlD,IAAM,IAAO,EAAO,YAAY;CAEhC,IAAI,KAAQ,MACV,MAAU,MACR,mCAAmC,EAAO,IAAI,kCAChD;CAEF,OAAO;AACT,GAEM,KACJ,MACoC;CACpC,IACE,MAAU,QACV,MAAU,QACV,MAAU,QACV,MAAU,QACV,MAAU,OAEV,OAAO;AAGX;AAKA,SAAgB,EACd,GACA,GACgD;CAChD,IAAM,EAAE,SAAM,SAAM,GACd,IAAW,EAAE,qBAAqB;CAKxC,OAJwB,EAAQ,QAAQ,MAC/B,EAAO,QAAQ,IAGjB,CAAA,CAAgB,KAAK,MAAW;EACrC,IAAM,IAAa,EAAkB,CAAM;EAC3C,OAAO;GACL,IAAI,EAAO;GACX,QAAQ,EAAa,EAAO,QAAQ,CAAI;GACxC,MAAM,EAAO;GACb,WAAW,EAAO,WAAW,aAAa;GAC1C,UAAU,EAAO,WAAW;GAC5B,OAAO,EAAO,WAAW;GACzB;GACA,cAAc,EAAkB,EAAO,WAAW,YAAY;GAC9D,OAAO,MAAQ;IACb,IAAM,EAAE,YAAS;IACjB,QAAQ,EAAK,MAAb;KACE,KAAK,QACH,OAAO,EAAiB,EAAK,MAAM,CAAG,GAAG,CAAQ;KAEnD,KAAK,QAAQ;MACX,IAAM,IAAQ,EAAK,MAAM,CAAG;MAO5B,OALE,KAAS,QACR,OAAO,KAAU,YAAY,EAAM,KAAK,MAAM,KAExC,IAGP,kBAAC,GAAD;OAAM,IAAI,EAAK,GAAG,CAAG;OAAG,gBAAe;OACpC,UAAA;MACG,CAAA;KAEV;KACA,KAAK,SAAS;MACZ,IAAM,IAAQ,EAAK,MAAM,CAAG;MAC5B,IAAI,KAAS,QAAQ,EAAM,KAAK,MAAM,IACpC,OAAO;MAET,IAAI,EAAE,YAAS;MAIf,OAHI,OAAO,KAAS,eAClB,IAAO,EAAK,CAAG,IAEV,kBAAC,GAAD;OAAW;OAAO,UAAA;MAAW,CAAA;KACtC;KACA,KAAK,YAAY;MACf,IAAM,IAAQ,EAAK,MAAM,CAAG;MAC5B,OACE,kBAAC,GAAD;OACS;OACG;OACV,SAAS;MACV,CAAA;KAEL;KACA,KAAK,aAAa;MAChB,IAAM,IAAK,EAAK,MAAM,CAAG;MACzB,IAAI,EAAG,KAAK,MAAM,IAChB,OAAO;MAET,IAAM,IAAQ,EAAK,QAAQ,CAAG;MAC9B,IAAI,KAAS,QAAQ,EAAM,KAAK,MAAM,IACpC,OAAO,EAAE,iCAAiC;MAE5C,IAAM,IAAS;OACb,MAAM;OACN,UAAU,EAAK;OACf;MACF;MACA,OACE,kBAAC,GAAD;OAA8B;OAC3B,UAAA;MACmB,CAAA;KAE1B;KACA,KAAK,uBAAuB;MAC1B,IAAM,IAAQ,EAAK,MAAM,CAAG;MAI5B,OAHI,KAAS,QAAQ,OAAO,CAAK,CAAC,CAAC,KAAK,MAAM,KACrC,IAGP,kBAAC,GAAD;OACS;OACP,WAAW,EAAK,YAAY,CAAG,KAAK,KAAA;OACpC,cAAc,EAAK;OACnB,WAAW,EAAE,qBAAqB;MACnC,CAAA;KAEL;KACA,KAAK,UAAU;MACb,IAAM,IAAW,EAAK,OAAO,CAAG;MAIhC,OAHI,KAAY,QAAQ,MAAa,KAC5B,IAEF,kBAAA,GAAA,EAAA,UAAG,EAAW,CAAA;KACvB;KACA,SACE,OAAO;IAEX;GACF;EACF;CACF,CAAC;AACH"}
|
|
@@ -41,15 +41,15 @@ var f = (e) => {
|
|
|
41
41
|
h != null && /* @__PURE__ */ o(d, { status: h })
|
|
42
42
|
]
|
|
43
43
|
}), m != null && /* @__PURE__ */ o("div", {
|
|
44
|
-
className: "
|
|
44
|
+
className: "txvbqb6o4 txvbqbei txvbqb20h",
|
|
45
45
|
children: m
|
|
46
46
|
})]
|
|
47
47
|
}), b.length > 0 && /* @__PURE__ */ o("div", {
|
|
48
|
-
className: "
|
|
48
|
+
className: "txvbqb5m2 txvbqb2ny txvbqb8ow txvbqb6sa txvbqb1d5",
|
|
49
49
|
children: b.map(f)
|
|
50
50
|
})]
|
|
51
51
|
}), g != null && g.length > 0 && /* @__PURE__ */ o("div", {
|
|
52
|
-
className: "
|
|
52
|
+
className: "txvbqb5mc txvbqb6sk txvbqb7qg",
|
|
53
53
|
children: g.map((e) => {
|
|
54
54
|
let t = e.value;
|
|
55
55
|
return e.copyValue != null && e.copyValue !== "" && (t = /* @__PURE__ */ o(u, {
|
|
@@ -59,12 +59,12 @@ var f = (e) => {
|
|
|
59
59
|
copyLabel: y("common.actions.copy"),
|
|
60
60
|
copiedLabel: y("common.actions.copied")
|
|
61
61
|
})), /* @__PURE__ */ s("div", {
|
|
62
|
-
className: "
|
|
62
|
+
className: "txvbqb5m2 txvbqb6mq txvbqb6s0 txvbqbe1y",
|
|
63
63
|
children: [/* @__PURE__ */ o("span", {
|
|
64
|
-
className: "
|
|
64
|
+
className: "txvbqb6nu txvbqb6k txvbqb1og txvbqbei",
|
|
65
65
|
children: e.label
|
|
66
66
|
}), /* @__PURE__ */ o("span", {
|
|
67
|
-
className: "
|
|
67
|
+
className: "txvbqb6o4 txvbqbeh txvbqb20h",
|
|
68
68
|
children: t
|
|
69
69
|
})]
|
|
70
70
|
}, e.id);
|