@plumile/backoffice-react 0.1.75 → 0.1.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +25 -0
  2. package/lib/esm/{AcceptInvitationScreen-CNLlSbdx.js → AcceptInvitationScreen-b2yaZeKV.js} +4 -4
  3. package/lib/esm/{AcceptInvitationScreen-CNLlSbdx.js.map → AcceptInvitationScreen-b2yaZeKV.js.map} +1 -1
  4. package/lib/esm/{AuthPanel-ttoH9YxE.js → AuthPanel-Co626p7A.js} +2 -2
  5. package/lib/esm/{AuthPanel-ttoH9YxE.js.map → AuthPanel-Co626p7A.js.map} +1 -1
  6. package/lib/esm/{BackofficeAcceptInvitationPage-DRxM1Z-U.js → BackofficeAcceptInvitationPage-BBHL6VvG.js} +7 -7
  7. package/lib/esm/{BackofficeAcceptInvitationPage-DRxM1Z-U.js.map → BackofficeAcceptInvitationPage-BBHL6VvG.js.map} +1 -1
  8. package/lib/esm/{sprinkles.css.ts.vanilla-n-NK_DwW.js → BackofficeConfigContext-R0t1owTI.js} +1 -1
  9. package/lib/esm/BackofficeConfigContext-R0t1owTI.js.map +1 -0
  10. package/lib/esm/{BackofficeDashboardPage-GKyT60qb.js → BackofficeDashboardPage-B5_YC1ZL.js} +5 -5
  11. package/lib/esm/BackofficeDashboardPage-B5_YC1ZL.js.map +1 -0
  12. package/lib/esm/{BackofficeDetailPayload-B-qs8Fai.js → BackofficeDetailPayload-CbsZKnw6.js} +10 -10
  13. package/lib/esm/BackofficeDetailPayload-CbsZKnw6.js.map +1 -0
  14. package/lib/esm/{BackofficeEntityActionFormDialog-FHlW0vys.js → BackofficeEntityActionFormDialog-BzKi1eyv.js} +19 -19
  15. package/lib/esm/BackofficeEntityActionFormDialog-BzKi1eyv.js.map +1 -0
  16. package/lib/esm/{BackofficeEntityDetailPage-CdrMXu5a.js → BackofficeEntityDetailPage-CE4tl5ZJ.js} +11 -11
  17. package/lib/esm/BackofficeEntityDetailPage-CE4tl5ZJ.js.map +1 -0
  18. package/lib/esm/{BackofficeEntityListPage-BxgqdFpL.js → BackofficeEntityListPage-CtLI15-L.js} +7 -7
  19. package/lib/esm/BackofficeEntityListPage-CtLI15-L.js.map +1 -0
  20. package/lib/esm/{BackofficeLayoutPage-k9OkLfXb.js → BackofficeLayoutPage-DpvTzwtK.js} +6 -6
  21. package/lib/esm/BackofficeLayoutPage-DpvTzwtK.js.map +1 -0
  22. package/lib/esm/{BackofficeLoginPage-C64BcxMw.js → BackofficeLoginPage-BeihjFO2.js} +8 -8
  23. package/lib/esm/{BackofficeLoginPage-C64BcxMw.js.map → BackofficeLoginPage-BeihjFO2.js.map} +1 -1
  24. package/lib/esm/{BackofficePasswordResetCompletePage-BA7kkUxN.js → BackofficePasswordResetCompletePage-CkaMaFNT.js} +6 -6
  25. package/lib/esm/{BackofficePasswordResetCompletePage-BA7kkUxN.js.map → BackofficePasswordResetCompletePage-CkaMaFNT.js.map} +1 -1
  26. package/lib/esm/{BackofficePasswordResetRequestPage-B9wSZcyn.js → BackofficePasswordResetRequestPage-Df8mcLkC.js} +6 -6
  27. package/lib/esm/{BackofficePasswordResetRequestPage-B9wSZcyn.js.map → BackofficePasswordResetRequestPage-Df8mcLkC.js.map} +1 -1
  28. package/lib/esm/{BackofficeRightPageLayout-ktdlvTZJ.js → BackofficeRightPageLayout-D7QRE8KZ.js} +3 -3
  29. package/lib/esm/BackofficeRightPageLayout-D7QRE8KZ.js.map +1 -0
  30. package/lib/esm/{BackofficeVerifyEmailPage-CAzMqo2K.js → BackofficeVerifyEmailPage-CE_6-wGN.js} +5 -5
  31. package/lib/esm/{BackofficeVerifyEmailPage-CAzMqo2K.js.map → BackofficeVerifyEmailPage-CE_6-wGN.js.map} +1 -1
  32. package/lib/esm/{EntityFilterValue-SC_jkj4O.js → EntityFilterValue-Bn9VGr2M.js} +2 -2
  33. package/lib/esm/{EntityFilterValue-SC_jkj4O.js.map → EntityFilterValue-Bn9VGr2M.js.map} +1 -1
  34. package/lib/esm/{EntityIdPickerDialog-FMC5Hx_I.js → EntityIdPickerDialog-D_qAlrU6.js} +4 -4
  35. package/lib/esm/EntityIdPickerDialog-D_qAlrU6.js.map +1 -0
  36. package/lib/esm/{LazyBackofficeEntityActionFormDialog-DOEgoIfT.js → LazyBackofficeEntityActionFormDialog-DndjG4kV.js} +5 -5
  37. package/lib/esm/LazyBackofficeEntityActionFormDialog-DndjG4kV.js.map +1 -0
  38. package/lib/esm/{PasswordResetCompleteScreen-C4GQdavL.js → PasswordResetCompleteScreen-CWxk9AWl.js} +3 -3
  39. package/lib/esm/{PasswordResetCompleteScreen-C4GQdavL.js.map → PasswordResetCompleteScreen-CWxk9AWl.js.map} +1 -1
  40. package/lib/esm/{PasswordResetRequestScreen-aUY_yDqM.js → PasswordResetRequestScreen-DBIHOmsl.js} +3 -3
  41. package/lib/esm/{PasswordResetRequestScreen-aUY_yDqM.js.map → PasswordResetRequestScreen-DBIHOmsl.js.map} +1 -1
  42. package/lib/esm/{VerifyEmailScreen-2DuHJgdY.js → VerifyEmailScreen-CUOEwmf1.js} +2 -2
  43. package/lib/esm/{VerifyEmailScreen-2DuHJgdY.js.map → VerifyEmailScreen-CUOEwmf1.js.map} +1 -1
  44. package/lib/esm/backoffice-react.js +21 -21
  45. package/lib/esm/backoffice-react.js.map +1 -1
  46. package/lib/esm/loginPage.css-4M4PrzUn.js +12 -0
  47. package/lib/esm/loginPage.css-4M4PrzUn.js.map +1 -0
  48. package/lib/esm/style.css +1 -1
  49. package/lib/esm/{synchronizeAuthStatusQuery-lLR0XFew.js → synchronizeAuthStatusQuery-Ba776lwa.js} +4 -4
  50. package/lib/esm/{synchronizeAuthStatusQuery-lLR0XFew.js.map → synchronizeAuthStatusQuery-Ba776lwa.js.map} +1 -1
  51. package/lib/esm/{useAuth-AczFS-oL.js → useAuth-DzWJXJ_9.js} +2 -2
  52. package/lib/esm/{useAuth-AczFS-oL.js.map → useAuth-DzWJXJ_9.js.map} +1 -1
  53. package/lib/esm/{useBackofficeAuth-BHteJQzA.js → useBackofficeAuth-L9k9i9BI.js} +3 -3
  54. package/lib/esm/{useBackofficeAuth-BHteJQzA.js.map → useBackofficeAuth-L9k9i9BI.js.map} +1 -1
  55. package/lib/esm/{useBackofficeLazyValue-B0-ckL6e.js → useBackofficeLazyValue-Dnii1_dE.js} +2 -2
  56. package/lib/esm/{useBackofficeLazyValue-B0-ckL6e.js.map → useBackofficeLazyValue-Dnii1_dE.js.map} +1 -1
  57. package/lib/types/auth/login/loginPage.css.d.ts.map +1 -1
  58. package/lib/types/components/backoffice/detail/backofficeDetailRelationLink.css.d.ts.map +1 -1
  59. package/lib/types/components/backoffice/filters/backofficeFilterAction.css.d.ts.map +1 -1
  60. package/lib/types/components/backoffice/layout/backofficeSidebarActions.css.d.ts.map +1 -1
  61. package/lib/types/components/backoffice/routing/backofficeRoutePendingBar.css.d.ts.map +1 -1
  62. package/package.json +5 -5
  63. package/lib/esm/BackofficeDashboardPage-GKyT60qb.js.map +0 -1
  64. package/lib/esm/BackofficeDetailPayload-B-qs8Fai.js.map +0 -1
  65. package/lib/esm/BackofficeEntityActionFormDialog-FHlW0vys.js.map +0 -1
  66. package/lib/esm/BackofficeEntityDetailPage-CdrMXu5a.js.map +0 -1
  67. package/lib/esm/BackofficeEntityListPage-BxgqdFpL.js.map +0 -1
  68. package/lib/esm/BackofficeLayoutPage-k9OkLfXb.js.map +0 -1
  69. package/lib/esm/BackofficeRightPageLayout-ktdlvTZJ.js.map +0 -1
  70. package/lib/esm/EntityIdPickerDialog-FMC5Hx_I.js.map +0 -1
  71. package/lib/esm/LazyBackofficeEntityActionFormDialog-DOEgoIfT.js.map +0 -1
  72. package/lib/esm/loginPage.css-BDQJNcSr.js +0 -12
  73. package/lib/esm/loginPage.css-BDQJNcSr.js.map +0 -1
  74. package/lib/esm/sprinkles.css.ts.vanilla-n-NK_DwW.js.map +0 -1
package/README.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  React provider and pages for Plumile backoffice.
4
4
 
5
+ ## Role
6
+
7
+ `@plumile/backoffice-react` is the optional React composition layer for
8
+ data-driven backoffice applications.
9
+
10
+ It builds on top of:
11
+
12
+ - `@plumile/ui` for visual components
13
+ - `@plumile/backoffice-core` for manifests, facets and shared types
14
+
15
+ It should contain:
16
+
17
+ - providers
18
+ - auth flows and generic auth pages
19
+ - routing and page scaffolds
20
+ - backoffice hooks
21
+ - Relay integration helpers
22
+ - entity registry and facet loading
23
+
24
+ It should not become:
25
+
26
+ - a second UI component library
27
+ - a container for product-specific business components
28
+ - a replacement for app-level domain code
29
+
5
30
  ## Instrumentation
6
31
 
7
32
  `BackofficeProvider` forwards router instrumentations to the internal
@@ -1,6 +1,6 @@
1
- import { a as e, d as t, f as n, s as r } from "./loginPage.css-BDQJNcSr.js";
2
- import { o as i } from "./useAuth-AczFS-oL.js";
3
- import { t as a } from "./AuthPanel-ttoH9YxE.js";
1
+ import { a as e, d as t, f as n, s as r } from "./loginPage.css-4M4PrzUn.js";
2
+ import { o as i } from "./useAuth-DzWJXJ_9.js";
3
+ import { t as a } from "./AuthPanel-Co626p7A.js";
4
4
  import { useCallback as o, useMemo as s, useState as c } from "react";
5
5
  import { AuthLayout as l, Button as u, FormError as d, FormField as f } from "@plumile/ui";
6
6
  import { jsx as p, jsxs as m } from "react/jsx-runtime";
@@ -113,4 +113,4 @@ var h = ({ auth: h, onSuccessRedirect: g, onBackToLogin: _, token: v }) => {
113
113
  //#endregion
114
114
  export { h as t };
115
115
 
116
- //# sourceMappingURL=AcceptInvitationScreen-CNLlSbdx.js.map
116
+ //# sourceMappingURL=AcceptInvitationScreen-b2yaZeKV.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AcceptInvitationScreen-CNLlSbdx.js","names":[],"sources":["../../src/auth/pages/AcceptInvitationScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useSharedTranslation } from '../../i18n/useSharedTranslation.js';\n\nimport { AuthLayout, Button, FormError, FormField } 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';\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 } = useSharedTranslation();\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\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 if (resolvedToken === '') {\n setErrorMessage(t('auth.acceptInvitation.errors.missingToken'));\n setStatus('error');\n return;\n }\n\n if (password !== passwordConfirmation) {\n setErrorMessage(t('auth.acceptInvitation.errors.passwordMismatch'));\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((error) => {\n setStatus('error');\n if (error instanceof Error) {\n setErrorMessage(error.message);\n } else if (typeof error === 'string') {\n setErrorMessage(error);\n } else {\n setErrorMessage(t('auth.acceptInvitation.errors.default'));\n }\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 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 <div className={styles.stack}>\n <p className={styles.helper}>\n {t('auth.acceptInvitation.status.success')}\n </p>\n </div>\n );\n } else {\n content = (\n <AuthPanel description={t('auth.acceptInvitation.subtitle')}>\n <form className={styles.formSurface} onSubmit={handleSubmit} noValidate>\n {errorMessage != null ? <FormError>{errorMessage}</FormError> : null}\n <FormField\n label={t('auth.acceptInvitation.form.passwordLabel')}\n name=\"password\"\n type=\"password\"\n value={password}\n onChange={(event) => {\n setPassword(event.target.value);\n setErrorMessage(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 <FormField\n label={t('auth.acceptInvitation.form.confirmLabel')}\n name=\"password-confirmation\"\n type=\"password\"\n value={passwordConfirmation}\n onChange={(event) => {\n setPasswordConfirmation(event.target.value);\n setErrorMessage(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\" isLoading={isSubmitting}>\n {status === 'pending'\n ? t('auth.acceptInvitation.status.workingButton')\n : t('auth.acceptInvitation.form.submit')}\n </Button>\n <Button type=\"button\" variant=\"secondary\" onClick={onBackToLogin}>\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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"}
1
+ {"version":3,"file":"AcceptInvitationScreen-b2yaZeKV.js","names":[],"sources":["../../src/auth/pages/AcceptInvitationScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useSharedTranslation } from '../../i18n/useSharedTranslation.js';\n\nimport { AuthLayout, Button, FormError, FormField } 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';\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 } = useSharedTranslation();\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\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 if (resolvedToken === '') {\n setErrorMessage(t('auth.acceptInvitation.errors.missingToken'));\n setStatus('error');\n return;\n }\n\n if (password !== passwordConfirmation) {\n setErrorMessage(t('auth.acceptInvitation.errors.passwordMismatch'));\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((error) => {\n setStatus('error');\n if (error instanceof Error) {\n setErrorMessage(error.message);\n } else if (typeof error === 'string') {\n setErrorMessage(error);\n } else {\n setErrorMessage(t('auth.acceptInvitation.errors.default'));\n }\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 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 <div className={styles.stack}>\n <p className={styles.helper}>\n {t('auth.acceptInvitation.status.success')}\n </p>\n </div>\n );\n } else {\n content = (\n <AuthPanel description={t('auth.acceptInvitation.subtitle')}>\n <form className={styles.formSurface} onSubmit={handleSubmit} noValidate>\n {errorMessage != null ? <FormError>{errorMessage}</FormError> : null}\n <FormField\n label={t('auth.acceptInvitation.form.passwordLabel')}\n name=\"password\"\n type=\"password\"\n value={password}\n onChange={(event) => {\n setPassword(event.target.value);\n setErrorMessage(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 <FormField\n label={t('auth.acceptInvitation.form.confirmLabel')}\n name=\"password-confirmation\"\n type=\"password\"\n value={passwordConfirmation}\n onChange={(event) => {\n setPasswordConfirmation(event.target.value);\n setErrorMessage(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\" isLoading={isSubmitting}>\n {status === 'pending'\n ? t('auth.acceptInvitation.status.workingButton')\n : t('auth.acceptInvitation.form.submit')}\n </Button>\n <Button type=\"button\" variant=\"secondary\" onClick={onBackToLogin}>\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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"}
@@ -1,4 +1,4 @@
1
- import { i as e, l as t, n, s as r, u as i } from "./loginPage.css-BDQJNcSr.js";
1
+ import { i as e, l as t, n, s as r, u as i } from "./loginPage.css-4M4PrzUn.js";
2
2
  import { jsx as a, jsxs as o } from "react/jsx-runtime";
3
3
  //#region src/auth/login/AuthPanel.tsx
4
4
  var s = ({ title: s, description: c, children: l, footer: u }) => /* @__PURE__ */ a("div", {
@@ -25,4 +25,4 @@ var s = ({ title: s, description: c, children: l, footer: u }) => /* @__PURE__ *
25
25
  //#endregion
26
26
  export { s as t };
27
27
 
28
- //# sourceMappingURL=AuthPanel-ttoH9YxE.js.map
28
+ //# sourceMappingURL=AuthPanel-Co626p7A.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuthPanel-ttoH9YxE.js","names":[],"sources":["../../src/auth/login/AuthPanel.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport { type JSX, type ReactNode } from 'react';\n\nimport * as styles from './loginPage.css.js';\n\ntype Props = {\n title?: string;\n description?: string;\n children: ReactNode;\n footer?: ReactNode;\n};\n\nexport const AuthPanel = ({\n title,\n description,\n children,\n footer,\n}: Props): JSX.Element => {\n return (\n <div className={styles.panel}>\n <div className={styles.block}>\n {title != null ? <h2 className={styles.panelTitle}>{title}</h2> : null}\n {description != null ? (\n <p className={styles.helper}>{description}</p>\n ) : null}\n {children}\n {footer != null ? <div className={styles.footer}>{footer}</div> : null}\n </div>\n </div>\n );\n};\n\nexport default AuthPanel;\n"],"mappings":";;;AAYA,IAAa,KAAa,EACxB,UACA,gBACA,aACA,QAAA,QAGE,kBAAC,OAAD;CAAK,WAAW;WACd,kBAAC,OAAD;EAAK,WAAW;YAAhB;GACG,KAAS,OAAwD,OAAjD,kBAAC,MAAD;IAAI,WAAW;cAAoB;IAAW,CAAA;GAC9D,KAAe,OAEZ,OADF,kBAAC,KAAD;IAAG,WAAW;cAAgB;IAAgB,CAAA;GAE/C;GACA,KAAU,OAAuD,OAAhD,kBAAC,OAAD;IAAK,WAAW;cAAgB;IAAa,CAAA;GAC3D;;CACF,CAAA"}
1
+ {"version":3,"file":"AuthPanel-Co626p7A.js","names":[],"sources":["../../src/auth/login/AuthPanel.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport { type JSX, type ReactNode } from 'react';\n\nimport * as styles from './loginPage.css.js';\n\ntype Props = {\n title?: string;\n description?: string;\n children: ReactNode;\n footer?: ReactNode;\n};\n\nexport const AuthPanel = ({\n title,\n description,\n children,\n footer,\n}: Props): JSX.Element => {\n return (\n <div className={styles.panel}>\n <div className={styles.block}>\n {title != null ? <h2 className={styles.panelTitle}>{title}</h2> : null}\n {description != null ? (\n <p className={styles.helper}>{description}</p>\n ) : null}\n {children}\n {footer != null ? <div className={styles.footer}>{footer}</div> : null}\n </div>\n </div>\n );\n};\n\nexport default AuthPanel;\n"],"mappings":";;;AAYA,IAAa,KAAa,EACxB,UACA,gBACA,aACA,QAAA,QAGE,kBAAC,OAAD;CAAK,WAAW;WACd,kBAAC,OAAD;EAAK,WAAW;YAAhB;GACG,KAAS,OAAwD,OAAjD,kBAAC,MAAD;IAAI,WAAW;cAAoB;IAAW,CAAA;GAC9D,KAAe,OAEZ,OADF,kBAAC,KAAD;IAAG,WAAW;cAAgB;IAAgB,CAAA;GAE/C;GACA,KAAU,OAAuD,OAAhD,kBAAC,OAAD;IAAK,WAAW;cAAgB;IAAa,CAAA;GAC3D;;CACF,CAAA"}
@@ -1,12 +1,12 @@
1
1
  import "./environment-BJeJTbIN.js";
2
2
  import "./useRelayEnvironment-vQ86aW-n.js";
3
- import { n as e } from "./sprinkles.css.ts.vanilla-n-NK_DwW.js";
4
- import "./loginPage.css-BDQJNcSr.js";
5
- import "./useAuth-AczFS-oL.js";
6
- import "./AuthPanel-ttoH9YxE.js";
7
- import { t } from "./AcceptInvitationScreen-CNLlSbdx.js";
3
+ import { n as e } from "./BackofficeConfigContext-R0t1owTI.js";
4
+ import "./loginPage.css-4M4PrzUn.js";
5
+ import "./useAuth-DzWJXJ_9.js";
6
+ import "./AuthPanel-Co626p7A.js";
7
+ import { t } from "./AcceptInvitationScreen-b2yaZeKV.js";
8
8
  import "./mutationResult-CcQMY13J.js";
9
- import { t as n } from "./useBackofficeAuth-BHteJQzA.js";
9
+ import { t as n } from "./useBackofficeAuth-L9k9i9BI.js";
10
10
  import { t as r } from "./backofficeAuthPaths-BiJvoI5Q.js";
11
11
  import { useCallback as i, useContext as a } from "react";
12
12
  import { RoutingContext as o } from "@plumile/router";
@@ -27,4 +27,4 @@ var c = () => {
27
27
  //#endregion
28
28
  export { c as BackofficeAcceptInvitationPage, c as default };
29
29
 
30
- //# sourceMappingURL=BackofficeAcceptInvitationPage-DRxM1Z-U.js.map
30
+ //# sourceMappingURL=BackofficeAcceptInvitationPage-BBHL6VvG.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeAcceptInvitationPage-DRxM1Z-U.js","names":[],"sources":["../../src/pages/BackofficeAcceptInvitationPage.tsx"],"sourcesContent":["import { useCallback, useContext, type JSX } from 'react';\nimport { RoutingContext } from '@plumile/router';\n\nimport { AcceptInvitationScreen } from '../auth/pages/AcceptInvitationScreen.js';\nimport { useBackofficeAuth } from '../hooks/useBackofficeAuth.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\n\nexport const BackofficeAcceptInvitationPage = (): JSX.Element => {\n const routerContext = useContext(RoutingContext);\n const { basePath } = useBackofficeConfig();\n const auth = useBackofficeAuth();\n\n const handleSuccessRedirect = useCallback(() => {\n routerContext?.history.push({ pathname: basePath });\n }, [basePath, routerContext?.history]);\n\n const handleBackToLogin = useCallback(() => {\n routerContext?.history.push({ pathname: getBackofficeLoginPath(basePath) });\n }, [basePath, routerContext?.history]);\n\n return (\n <AcceptInvitationScreen\n auth={auth}\n onSuccessRedirect={handleSuccessRedirect}\n onBackToLogin={handleBackToLogin}\n />\n );\n};\n\nexport default BackofficeAcceptInvitationPage;\n"],"mappings":";;;;;;;;;;;;;;AAQA,IAAa,UAAoD;CAC/D,IAAM,IAAgB,EAAW,EAAe,EAC1C,EAAE,gBAAa,GAAqB;AAW1C,QACE,kBAAC,GAAD;EACQ,MAZG,GAAmB;EAa5B,mBAX0B,QAAkB;AAC9C,MAAe,QAAQ,KAAK,EAAE,UAAU,GAAU,CAAC;KAClD,CAAC,GAAU,GAAe,QAAQ,CAAC;EAUlC,eARsB,QAAkB;AAC1C,MAAe,QAAQ,KAAK,EAAE,UAAU,EAAuB,EAAS,EAAE,CAAC;KAC1E,CAAC,GAAU,GAAe,QAAQ,CAAC;EAOlC,CAAA"}
1
+ {"version":3,"file":"BackofficeAcceptInvitationPage-BBHL6VvG.js","names":[],"sources":["../../src/pages/BackofficeAcceptInvitationPage.tsx"],"sourcesContent":["import { useCallback, useContext, type JSX } from 'react';\nimport { RoutingContext } from '@plumile/router';\n\nimport { AcceptInvitationScreen } from '../auth/pages/AcceptInvitationScreen.js';\nimport { useBackofficeAuth } from '../hooks/useBackofficeAuth.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\n\nexport const BackofficeAcceptInvitationPage = (): JSX.Element => {\n const routerContext = useContext(RoutingContext);\n const { basePath } = useBackofficeConfig();\n const auth = useBackofficeAuth();\n\n const handleSuccessRedirect = useCallback(() => {\n routerContext?.history.push({ pathname: basePath });\n }, [basePath, routerContext?.history]);\n\n const handleBackToLogin = useCallback(() => {\n routerContext?.history.push({ pathname: getBackofficeLoginPath(basePath) });\n }, [basePath, routerContext?.history]);\n\n return (\n <AcceptInvitationScreen\n auth={auth}\n onSuccessRedirect={handleSuccessRedirect}\n onBackToLogin={handleBackToLogin}\n />\n );\n};\n\nexport default BackofficeAcceptInvitationPage;\n"],"mappings":";;;;;;;;;;;;;;AAQA,IAAa,UAAoD;CAC/D,IAAM,IAAgB,EAAW,EAAe,EAC1C,EAAE,gBAAa,GAAqB;AAW1C,QACE,kBAAC,GAAD;EACQ,MAZG,GAAmB;EAa5B,mBAX0B,QAAkB;AAC9C,MAAe,QAAQ,KAAK,EAAE,UAAU,GAAU,CAAC;KAClD,CAAC,GAAU,GAAe,QAAQ,CAAC;EAUlC,eARsB,QAAkB;AAC1C,MAAe,QAAQ,KAAK,EAAE,UAAU,EAAuB,EAAS,EAAE,CAAC;KAC1E,CAAC,GAAU,GAAe,QAAQ,CAAC;EAOlC,CAAA"}
@@ -9,4 +9,4 @@ function i() {
9
9
  //#endregion
10
10
  export { i as n, r as t };
11
11
 
12
- //# sourceMappingURL=sprinkles.css.ts.vanilla-n-NK_DwW.js.map
12
+ //# sourceMappingURL=BackofficeConfigContext-R0t1owTI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackofficeConfigContext-R0t1owTI.js","names":[],"sources":["../../src/provider/BackofficeConfigContext.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\n\nimport type { BackofficeEntityManifestMap } from '@plumile/backoffice-core/types.js';\n\nimport type {\n BackofficeAuthConfig,\n BackofficeDashboardModule,\n BackofficeGraphQLConfig,\n BackofficeSidebarConfig,\n} from './types.js';\nimport type { BackofficeEntityRegistry } from './entityRegistry.js';\n\nexport type BackofficeConfigContextValue = {\n basePath: string;\n entities: BackofficeEntityManifestMap;\n entityManifest: BackofficeEntityManifestMap;\n entityRegistry: BackofficeEntityRegistry;\n filterColumnAliases?: Record<string, string>;\n sidebar?: BackofficeSidebarConfig;\n dashboard?: BackofficeDashboardModule;\n auth: BackofficeAuthConfig;\n graphql: BackofficeGraphQLConfig;\n};\n\nconst BackofficeConfigContext =\n createContext<BackofficeConfigContextValue | null>(null);\n\nexport const BackofficeConfigProvider = BackofficeConfigContext.Provider;\n\n/**\n * Hook to access the Backoffice configuration context\n */\nexport function useBackofficeConfig(): BackofficeConfigContextValue {\n const context = useContext(BackofficeConfigContext);\n if (context == null) {\n throw new Error('BackofficeProvider is missing in the component tree.');\n }\n return context;\n}\n\nexport default BackofficeConfigContext;\n"],"mappings":";;AAwBA,IAAM,IACJ,EAAmD,KAAK,EAE7C,IAA2B,EAAwB;AAKhE,SAAgB,IAAoD;CAClE,IAAM,IAAU,EAAW,EAAwB;AACnD,KAAI,KAAW,KACb,OAAU,MAAM,uDAAuD;AAEzE,QAAO"}
@@ -1,8 +1,8 @@
1
- import { n as e } from "./sprinkles.css.ts.vanilla-n-NK_DwW.js";
1
+ import { n as e } from "./BackofficeConfigContext-R0t1owTI.js";
2
2
  import { n as t, t as n } from "./useBackofficeReactTranslation-WfXU8kCf.js";
3
- import { n as r, t as i } from "./BackofficeRightPageLayout-ktdlvTZJ.js";
3
+ import { n as r, t as i } from "./BackofficeRightPageLayout-D7QRE8KZ.js";
4
4
  import "./BackofficeTopbarPortalContext-iD7dm4_h.js";
5
- import { a } from "./useBackofficeLazyValue-B0-ckL6e.js";
5
+ import { a } from "./useBackofficeLazyValue-Dnii1_dE.js";
6
6
  import { t as o } from "./buildBreadcrumbs-CqF9Nh6x.js";
7
7
  import { Suspense as s } from "react";
8
8
  import { useTranslation as c } from "react-i18next";
@@ -11,7 +11,7 @@ import { DataTable as u, DetailPageTemplate as d, InfoTile as f } from "@plumile
11
11
  import * as p from "react-relay";
12
12
  import { jsx as m, jsxs as h } from "react/jsx-runtime";
13
13
  //#region src/pages/backofficeDashboardPage.css.ts
14
- var g = "mt26ef0 vncd899ix vncd89byo vncd89aoo", _ = "mt26ef1 vncd899io vncd89ai6 vncd89ao6", v = "mt26ef2 vncd89a6 vncd89amx vncd89egx", y = "mt26ef3 vncd899io vncd89ajx vncd89qh6 vncd898vf", { useLazyLoadQuery: b } = p, x = (e, t) => e(t), S = (e, t) => {
14
+ var g = "txvbqb9ix txvbqbbyo txvbqbaoo", _ = "txvbqb9io txvbqbai6 txvbqbao6", v = "txvbqba6 txvbqbamx txvbqbegx", y = "txvbqb9io txvbqbajx txvbqbqh6 txvbqb8vf", { useLazyLoadQuery: b } = p, x = (e, t) => e(t), S = (e, t) => {
15
15
  switch (e.kind) {
16
16
  case "entityCount":
17
17
  case "shortcut": return e.label;
@@ -192,4 +192,4 @@ var g = "mt26ef0 vncd899ix vncd89byo vncd89aoo", _ = "mt26ef1 vncd899io vncd89ai
192
192
  //#endregion
193
193
  export { O as BackofficeDashboardPage, O as default };
194
194
 
195
- //# sourceMappingURL=BackofficeDashboardPage-GKyT60qb.js.map
195
+ //# sourceMappingURL=BackofficeDashboardPage-B5_YC1ZL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackofficeDashboardPage-B5_YC1ZL.js","names":[],"sources":["../../src/pages/backofficeDashboardPage.css.ts","../../src/pages/BackofficeDashboardPage.tsx"],"sourcesContent":["import { sprinkles } from '@plumile/ui';\n\nexport const tilesGrid = sprinkles({\n display: 'grid',\n gridTemplateColumns: 'autoFillMinmax320',\n gap: 4,\n});\n\nexport const tileBody = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n});\n\nexport const tileCount = sprinkles({\n fontSize: '3xl',\n fontWeight: 'bold',\n lineHeight: 1,\n});\n\nexport const links = sprinkles({\n display: 'flex',\n flexWrap: 'wrap',\n rowGap: 2,\n columnGap: 3,\n});\n","/* eslint-disable no-ternary */\nimport { type JSX, Suspense } from 'react';\nimport { Link } from '@plumile/router';\nimport type {\n BackofficeDashboardConfig,\n BackofficeDashboardWidget,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport { DataTable, DetailPageTemplate, InfoTile } from '@plumile/ui';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\nimport type { GraphQLTaggedNode, OperationType } from 'relay-runtime';\n\nimport { BackofficeErrorBoundary } from '../components/backoffice/errors/BackofficeErrorBoundary.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeDashboardConfig } from '../provider/useBackofficeLazyValue.js';\nimport { buildDataTableColumns } from '../components/backoffice/columns/buildDataTableColumns.js';\nimport { BackofficeRightPageLayout } from '../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport { buildDashboardBreadcrumb } from '../components/backoffice/layout/breadcrumb/buildBreadcrumbs.js';\n\nimport * as styles from './backofficeDashboardPage.css.js';\n\nconst { useLazyLoadQuery } = ReactRelay;\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst getWidgetLabel = (\n widget: BackofficeDashboardWidget,\n config: BackofficeDashboardConfig,\n): I18nLabel => {\n switch (widget.kind) {\n case 'entityCount':\n case 'shortcut':\n return widget.label;\n case 'tablePreview':\n case 'textBlock':\n return widget.title;\n default:\n return config.title;\n }\n};\n\nconst hasWidgetQuery = (\n widget: BackofficeDashboardWidget,\n): widget is BackofficeDashboardWidget & { query: GraphQLTaggedNode } => {\n return 'query' in widget && widget.query != null;\n};\n\ntype WidgetContentProps = {\n widget: BackofficeDashboardWidget;\n globalData: unknown;\n};\n\nconst WidgetContent = ({\n widget,\n globalData,\n}: WidgetContentProps): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities } = useBackofficeConfig();\n\n const resolveData = (data: unknown): unknown => {\n if ('resolve' in widget && widget.resolve != null) {\n return widget.resolve(data);\n }\n return null;\n };\n\n if (widget.kind === 'textBlock') {\n const title = resolveLabel(widget.title, tApp);\n const body = resolveLabel(widget.body, tApp);\n return (\n <InfoTile title={title}>\n <div className={styles.tileBody}>{body}</div>\n </InfoTile>\n );\n }\n\n if (widget.kind === 'shortcut') {\n const entity = entities[widget.entityId];\n if (entity == null) {\n return null;\n }\n const title = resolveLabel(widget.label, tApp);\n if (entity.kind === 'tool') {\n return (\n <InfoTile title={title}>\n <div className={styles.links}>\n <Link to={entity.routes.list}>\n {t('dashboard.actions.openTool')}\n </Link>\n </div>\n </InfoTile>\n );\n }\n return (\n <InfoTile title={title}>\n <div className={styles.links}>\n <Link to={entity.routes.list}>{t('dashboard.actions.openList')}</Link>\n </div>\n </InfoTile>\n );\n }\n\n if (widget.kind === 'tablePreview') {\n const resolved = resolveData(globalData) as {\n columns: readonly unknown[];\n rows: readonly unknown[];\n } | null;\n if (resolved == null) {\n return null;\n }\n const columns = buildDataTableColumns(resolved.columns as never, {\n tApp,\n t,\n resolveEntityHref: (entityId, refId) => {\n const entityConfig = entities[entityId];\n if (entityConfig == null) {\n return null;\n }\n return entityConfig.routes.detail(refId);\n },\n });\n const title = resolveLabel(widget.title, tApp);\n return (\n <InfoTile title={title}>\n <DataTable\n columns={columns}\n rows={resolved.rows}\n getRowId={(row, index) => {\n if (row != null && typeof row === 'object') {\n const record = row as Record<string, unknown>;\n const { id } = record;\n if (typeof id === 'string' && id.trim() !== '') {\n return id;\n }\n }\n return String(index);\n }}\n />\n </InfoTile>\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (widget.kind === 'entityCount') {\n const entityManifest = entities[widget.entityId];\n if (entityManifest?.kind !== 'list-detail') {\n return null;\n }\n const resolved = resolveData(globalData) as { count: number | null } | null;\n let countLabel: number | string = t('common.notAvailable');\n if (typeof resolved?.count === 'number') {\n countLabel = resolved.count;\n }\n const title = resolveLabel(widget.label, tApp);\n return (\n <InfoTile title={title}>\n <div className={styles.tileBody}>\n <div className={styles.tileCount}>{countLabel}</div>\n <div className={styles.links}>\n <Link to={entityManifest.routes.list}>\n {t('dashboard.actions.openList')}\n </Link>\n </div>\n </div>\n </InfoTile>\n );\n }\n\n return null;\n};\n\ntype WidgetWithQueryProps = {\n widget: BackofficeDashboardWidget & { query: GraphQLTaggedNode };\n};\n\nconst WidgetWithQuery = ({ widget }: WidgetWithQueryProps): JSX.Element => {\n const data = useLazyLoadQuery<OperationType>(\n widget.query,\n {},\n {\n fetchPolicy: 'store-or-network',\n },\n );\n\n return <WidgetContent widget={widget} globalData={data} />;\n};\n\ntype DashboardContentProps = {\n config: BackofficeDashboardConfig;\n globalData: unknown;\n};\n\nconst DashboardContent = ({\n config,\n globalData,\n}: DashboardContentProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n\n const title = resolveLabel(config.title, tApp);\n const subtitle =\n config.subtitle != null ? resolveLabel(config.subtitle, tApp) : undefined;\n\n return (\n <DetailPageTemplate\n header={{\n title,\n subtitle: subtitle ?? t('dashboard.subtitle'),\n }}\n >\n <div className={styles.tilesGrid}>\n {config.widgets.map((widget) => {\n const content = hasWidgetQuery(widget) ? (\n <WidgetWithQuery widget={widget} />\n ) : (\n <WidgetContent widget={widget} globalData={globalData} />\n );\n\n return (\n <BackofficeErrorBoundary\n key={widget.id}\n fallback={() => {\n return (\n <InfoTile\n title={resolveLabel(getWidgetLabel(widget, config), tApp)}\n >\n <div className={styles.tileBody}>\n {t('common.notAvailable')}\n </div>\n </InfoTile>\n );\n }}\n >\n <Suspense\n fallback={\n <InfoTile\n title={resolveLabel(getWidgetLabel(widget, config), tApp)}\n >\n <div className={styles.tileBody}>{t('common.loading')}</div>\n </InfoTile>\n }\n >\n {content}\n </Suspense>\n </BackofficeErrorBoundary>\n );\n })}\n </div>\n </DetailPageTemplate>\n );\n};\n\ntype DashboardWithQueryProps = {\n config: BackofficeDashboardConfig;\n};\n\nconst DashboardWithQuery = ({\n config,\n}: DashboardWithQueryProps): JSX.Element => {\n const data = useLazyLoadQuery<OperationType>(\n config.query as never,\n {},\n { fetchPolicy: 'store-or-network' },\n );\n\n return <DashboardContent config={config} globalData={data} />;\n};\n\nexport const BackofficeDashboardPage = (): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities } = useBackofficeConfig();\n const dashboard = useBackofficeDashboardConfig();\n const breadcrumb = buildDashboardBreadcrumb(t);\n\n if (dashboard == null) {\n const items = Object.values(entities)\n .filter((config) => {\n return config.kind === 'list-detail' && config.hasList;\n })\n .map((config) => {\n return {\n config,\n label: resolveLabel(config.label, tApp),\n };\n })\n .sort((left, right) => {\n return left.label.localeCompare(right.label);\n });\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DetailPageTemplate\n header={{\n title: t('dashboard.title'),\n subtitle: t('dashboard.subtitle'),\n }}\n >\n <div className={styles.tilesGrid}>\n {items.map(({ config, label }) => {\n return (\n <InfoTile key={config.id} title={label}>\n <div className={styles.tileBody}>\n <div className={styles.tileCount}>\n {t('common.notAvailable')}\n </div>\n <div className={styles.links}>\n <Link to={config.routes.list}>\n {t('dashboard.actions.openList')}\n </Link>\n </div>\n </div>\n </InfoTile>\n );\n })}\n </div>\n </DetailPageTemplate>\n </BackofficeRightPageLayout>\n );\n }\n\n if (dashboard.query != null) {\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DashboardWithQuery config={dashboard} />\n </BackofficeRightPageLayout>\n );\n }\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DashboardContent config={dashboard} globalData={null} />\n </BackofficeRightPageLayout>\n );\n};\n\nexport default BackofficeDashboardPage;\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { useTranslation as t } from "react-i18next";
3
3
  import { CopyableText as n, LazyMarkdownRenderer as r, Tag as i, cx as a } from "@plumile/ui";
4
4
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
5
5
  //#region src/components/backoffice/detail/backofficeDetailBadgeRow.css.ts
6
- var c = "lqrxsj0 vncd899io vncd89ajx vncd89ao6 vncd89co", l = ({ items: e }) => {
6
+ var c = "txvbqb9io txvbqbajx txvbqbao6 txvbqbco", l = ({ items: e }) => {
7
7
  let { t: n } = t();
8
8
  return /* @__PURE__ */ o("div", {
9
9
  className: c,
@@ -15,13 +15,13 @@ var c = "lqrxsj0 vncd899io vncd89ajx vncd89ao6 vncd89co", l = ({ items: e }) =>
15
15
  }, e.id);
16
16
  })
17
17
  });
18
- }, u = "_1vn15b70 vncd899io vncd89ai6 vncd89anx vncd89k4x", d = "_1vn15b71 vncd898o vncd8966 vncd89eeo vncd89v8r", f = "_1vn15b72 vncd898x vncd89v8p vncd89ut6", p = "_1vn15b73 vncd89bg6", m = {
19
- xs: "_1vn15b74",
20
- s: "_1vn15b75",
21
- m: "_1vn15b76",
22
- l: "_1vn15b77",
23
- xl: "_1vn15b78",
24
- fluid: "_1vn15b79"
18
+ }, u = "txvbqb9io txvbqbai6 txvbqbanx txvbqbk4x", d = "txvbqb8o txvbqb66 txvbqbeeo txvbqbv8r", f = "txvbqb8x txvbqbv8p txvbqbut6", p = "txvbqbbg6", m = {
19
+ xs: "_1vn15b70",
20
+ s: "_1vn15b71",
21
+ m: "_1vn15b72",
22
+ l: "_1vn15b73",
23
+ xl: "_1vn15b74",
24
+ fluid: "_1vn15b75"
25
25
  }, h = ({ label: t, size: r, value: i, copyValue: c, fullWidth: l = !1 }) => {
26
26
  let { t: h } = e(), g = i;
27
27
  (g == null || typeof g == "string" && g.trim() === "") && (g = h("common.notAvailable")), c != null && c !== "" && (g = /* @__PURE__ */ o(n, {
@@ -42,7 +42,7 @@ var c = "lqrxsj0 vncd899io vncd89ajx vncd89ao6 vncd89co", l = ({ items: e }) =>
42
42
  children: g
43
43
  })]
44
44
  });
45
- }, g = "_1v7vur60 vncd899io vncd89ai6 vncd89aoo vncd89lax vncd891rf vncd89v2r vncd891co vncd891qf vncd89wo vncd898qx", _ = "_1v7vur61 vncd899io vncd89ai6 vncd89anx", v = "_1v7vur62 vncd8996 vncd89amo vncd89v8p", y = "_1v7vur63 vncd898x vncd89v8r", b = "_1v7vur64 vncd899ix vncd89aoo vncd89c0f", x = ({ title: e, description: t, items: n, children: r }) => {
45
+ }, g = "txvbqb9io txvbqbai6 txvbqbaoo txvbqblax txvbqb1rf txvbqbv2r txvbqb1co txvbqb1qf txvbqbwo txvbqb8qx", _ = "txvbqb9io txvbqbai6 txvbqbanx", v = "txvbqb96 txvbqbamo txvbqbv8p", y = "txvbqb8x txvbqbv8r", b = "txvbqb9ix txvbqbaoo txvbqbc0f", x = ({ title: e, description: t, items: n, children: r }) => {
46
46
  let i = null;
47
47
  t != null && t !== "" && (i = /* @__PURE__ */ o("p", {
48
48
  className: y,
@@ -91,4 +91,4 @@ var C = ({ title: t, content: n, format: i = "markdown", description: a }) => {
91
91
  //#endregion
92
92
  export { l as a, h as i, S as n, x as r, C as t };
93
93
 
94
- //# sourceMappingURL=BackofficeDetailPayload-B-qs8Fai.js.map
94
+ //# sourceMappingURL=BackofficeDetailPayload-CbsZKnw6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackofficeDetailPayload-CbsZKnw6.js","names":[],"sources":["../../src/components/backoffice/detail/backofficeDetailBadgeRow.css.ts","../../src/components/backoffice/detail/BackofficeDetailBadgeRow.tsx","../../src/components/backoffice/detail/backofficeDetailField.css.ts","../../src/components/backoffice/detail/BackofficeDetailField.tsx","../../src/components/backoffice/detail/backofficeDetailSection.css.ts","../../src/components/backoffice/detail/BackofficeDetailSection.tsx","../../src/components/backoffice/detail/detailPayloadUtils.ts","../../src/components/backoffice/detail/BackofficeDetailPayload.tsx"],"sourcesContent":["import { sprinkles } from '@plumile/ui';\n\nexport const row = sprinkles({\n display: 'flex',\n flexWrap: 'wrap',\n gap: 2,\n alignItems: 'center',\n});\n","/* eslint-disable no-ternary */\nimport { type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport type { BackofficeBadgeItem } from '@plumile/backoffice-core/types.js';\nimport { Tag } from '@plumile/ui';\n\nimport * as styles from './backofficeDetailBadgeRow.css.js';\n\nexport type BackofficeDetailBadgeRowProps = {\n items: readonly BackofficeBadgeItem[];\n};\n\nexport const BackofficeDetailBadgeRow = ({\n items,\n}: BackofficeDetailBadgeRowProps): JSX.Element => {\n const { t } = useTranslation();\n return (\n <div className={styles.row}>\n {items.map((item) => {\n const label =\n typeof item.label === 'function' ? item.label(t) : item.label;\n return (\n <Tag key={item.id} tone={item.tone ?? 'neutral'}>\n {label}\n </Tag>\n );\n })}\n </div>\n );\n};\n\nexport default BackofficeDetailBadgeRow;\n","import { style } from '@vanilla-extract/css';\nimport { sprinkles } from '@plumile/ui';\n\nexport const field = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 1,\n minWidth: 0,\n});\n\nexport const label = sprinkles({\n fontSize: 'xs',\n textTransform: 'uppercase',\n letterSpacing: 'capsTight',\n color: 'textSecondary',\n});\n\nexport const value = sprinkles({\n fontSize: 'sm',\n color: 'text',\n wordBreak: 'break-word',\n});\n\nexport const fullWidth = sprinkles({\n gridColumn: 'span-full',\n});\n\nexport const size = {\n xs: style({ maxWidth: '10ch' }),\n s: style({ maxWidth: '18ch' }),\n m: style({ maxWidth: '28ch' }),\n l: style({ maxWidth: '44ch' }),\n xl: style({ maxWidth: '64ch' }),\n fluid: style({ maxWidth: '100%' }),\n};\n","import { type JSX, type ReactNode } from 'react';\nimport type { BackofficeFieldSize } from '@plumile/backoffice-core/types.js';\n\nimport { CopyableText, cx } from '@plumile/ui';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\n\nimport * as styles from './backofficeDetailField.css.js';\n\nexport type BackofficeDetailFieldProps = {\n id: string;\n label: string;\n size: BackofficeFieldSize;\n value: ReactNode | null | undefined;\n copyValue?: string;\n fullWidth?: boolean;\n};\n\nexport const BackofficeDetailField = ({\n label,\n size,\n value,\n copyValue,\n fullWidth = false,\n}: BackofficeDetailFieldProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n let resolvedValue: ReactNode = value;\n if (\n resolvedValue == null ||\n (typeof resolvedValue === 'string' && resolvedValue.trim() === '')\n ) {\n resolvedValue = t('common.notAvailable');\n }\n\n if (copyValue != null && copyValue !== '') {\n resolvedValue = (\n <CopyableText\n value={copyValue}\n copyValue={copyValue}\n truncate={false}\n copyLabel={t('common.actions.copy')}\n copiedLabel={t('common.actions.copied')}\n />\n );\n }\n\n const fieldClassNames = [styles.field, styles.size[size]];\n if (fullWidth) {\n fieldClassNames.push(styles.fullWidth);\n }\n\n return (\n <div className={cx(...fieldClassNames)}>\n <span className={styles.label}>{label}</span>\n <div className={styles.value}>{resolvedValue}</div>\n </div>\n );\n};\n\nexport default BackofficeDetailField;\n","import { sprinkles } from '@plumile/ui';\n\nexport const section = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n padding: 6,\n borderRadius: 'md',\n backgroundColor: 'surface',\n borderWidth: 'default',\n borderStyle: 'solid',\n borderColor: 'borderSubtle',\n boxShadow: 'inkSoft',\n});\n\nexport const header = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 1,\n});\n\nexport const title = sprinkles({\n fontSize: 'base',\n fontWeight: 'semibold',\n color: 'text',\n});\n\nexport const description = sprinkles({\n fontSize: 'sm',\n color: 'textSecondary',\n});\n\nexport const grid = sprinkles({\n display: 'grid',\n gap: 4,\n gridTemplateColumns: 'autoFitMinmax220',\n});\n","import { type JSX, type ReactNode } from 'react';\n\nimport {\n BackofficeDetailField,\n type BackofficeDetailFieldProps,\n} from './BackofficeDetailField.js';\nimport * as styles from './backofficeDetailSection.css.js';\n\nexport type BackofficeDetailSectionProps = {\n title: string;\n description?: string;\n items?: readonly BackofficeDetailFieldProps[];\n children?: ReactNode;\n};\n\nexport const BackofficeDetailSection = ({\n title,\n description,\n items,\n children,\n}: BackofficeDetailSectionProps): JSX.Element => {\n let descriptionNode: JSX.Element | null = null;\n if (description != null && description !== '') {\n descriptionNode = <p className={styles.description}>{description}</p>;\n }\n\n let itemsNode: JSX.Element | null = null;\n if (items != null && items.length > 0) {\n itemsNode = (\n <div className={styles.grid}>\n {items.map((item) => {\n return <BackofficeDetailField key={item.id} {...item} />;\n })}\n </div>\n );\n }\n\n return (\n <section className={styles.section}>\n <header className={styles.header}>\n <h3 className={styles.title}>{title}</h3>\n {descriptionNode}\n </header>\n {itemsNode}\n {children}\n </section>\n );\n};\n\nexport default BackofficeDetailSection;\n","/**\n * Formats a JSON payload into a fenced Markdown code block.\n */\nexport function formatJsonPayload(value: unknown): string {\n if (value == null) {\n return '';\n }\n try {\n return `\\`\\`\\`json\\n${JSON.stringify(value, null, 2)}\\n\\`\\`\\``;\n } catch {\n let fallback = '[unserializable]';\n if (typeof value === 'string') {\n fallback = value;\n } else if (typeof value === 'number' || typeof value === 'boolean') {\n fallback = String(value);\n }\n return `\\`\\`\\`\\n${fallback}\\n\\`\\`\\``;\n }\n}\n\n/**\n * Formats a list of strings as a Markdown bullet list.\n */\nexport function formatListAsMarkdown(items: readonly string[]): string {\n if (items.length === 0) {\n return '';\n }\n return items\n .map((item) => {\n return `- ${item}`;\n })\n .join('\\n');\n}\n","import { type JSX } from 'react';\n\nimport { LazyMarkdownRenderer } from '@plumile/ui';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { BackofficeDetailSection } from './BackofficeDetailSection.js';\nimport { formatJsonPayload } from './detailPayloadUtils.js';\n\nexport type BackofficeDetailPayloadProps = {\n title: string;\n content: unknown;\n format?: 'markdown' | 'json' | 'text';\n description?: string;\n};\n\nexport const BackofficeDetailPayload = ({\n title,\n content,\n format = 'markdown',\n description,\n}: BackofficeDetailPayloadProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n let resolved = '';\n if (format === 'json') {\n resolved = formatJsonPayload(content);\n } else if (content != null) {\n if (typeof content === 'string') {\n resolved = content;\n } else if (typeof content === 'number' || typeof content === 'boolean') {\n resolved = String(content);\n } else {\n resolved = formatJsonPayload(content);\n }\n }\n\n if (resolved.trim() === '') {\n resolved = t('common.notAvailable');\n }\n\n return (\n <BackofficeDetailSection title={title} description={description}>\n <LazyMarkdownRenderer content={resolved} />\n </BackofficeDetailSection>\n );\n};\n\nexport default BackofficeDetailPayload;\n"],"mappings":";;;;;kDCaa,KAA4B,EACvC,eACgD;CAChD,IAAM,EAAE,SAAM,GAAgB;AAC9B,QACE,kBAAC,OAAD;EAAK,WAAW;YACb,EAAM,KAAK,MAAS;GACnB,IAAM,IACJ,OAAO,EAAK,SAAU,aAAa,EAAK,MAAM,EAAE,GAAG,EAAK;AAC1D,UACE,kBAAC,GAAD;IAAmB,MAAM,EAAK,QAAQ;cACnC;IACG,EAFI,EAAK,GAET;IAER;EACE,CAAA;;;;;;;;GEVG,KAAyB,EACpC,OAAA,GACA,MAAA,GACA,OAAA,GACA,cACA,WAAA,IAAY,SACiC;CAC7C,IAAM,EAAE,SAAM,GAA+B,EACzC,IAA2B;AAQ/B,EANE,KAAiB,QAChB,OAAO,KAAkB,YAAY,EAAc,MAAM,KAAK,QAE/D,IAAgB,EAAE,sBAAsB,GAGtC,KAAa,QAAQ,MAAc,OACrC,IACE,kBAAC,GAAD;EACE,OAAO;EACI;EACX,UAAU;EACV,WAAW,EAAE,sBAAsB;EACnC,aAAa,EAAE,wBAAwB;EACvC,CAAA;CAIN,IAAM,IAAkB,CAAC,GAAc,EAAY,GAAM;AAKzD,QAJI,KACF,EAAgB,KAAK,EAAiB,EAItC,kBAAC,OAAD;EAAK,WAAW,EAAG,GAAG,EAAgB;YAAtC,CACE,kBAAC,QAAD;GAAM,WAAW;aAAe;GAAa,CAAA,EAC7C,kBAAC,OAAD;GAAK,WAAW;aAAe;GAAoB,CAAA,CAC/C;;qPExCG,KAA2B,EACtC,OAAA,GACA,aAAA,GACA,UACA,kBAC+C;CAC/C,IAAI,IAAsC;AAC1C,CAAI,KAAe,QAAQ,MAAgB,OACzC,IAAkB,kBAAC,KAAD;EAAG,WAAW;YAAqB;EAAgB,CAAA;CAGvE,IAAI,IAAgC;AAWpC,QAVI,KAAS,QAAQ,EAAM,SAAS,MAClC,IACE,kBAAC,OAAD;EAAK,WAAW;YACb,EAAM,KAAK,MACH,kBAAC,GAAD,EAAqC,GAAI,GAAQ,EAArB,EAAK,GAAgB,CACxD;EACE,CAAA,GAKR,kBAAC,WAAD;EAAS,WAAW;YAApB;GACE,kBAAC,UAAD;IAAQ,WAAW;cAAnB,CACE,kBAAC,MAAD;KAAI,WAAW;eAAe;KAAW,CAAA,EACxC,EACM;;GACR;GACA;GACO;;;;;AC1Cd,SAAgB,EAAkB,GAAwB;AACxD,KAAI,KAAS,KACX,QAAO;AAET,KAAI;AACF,SAAO,eAAe,KAAK,UAAU,GAAO,MAAM,EAAE,CAAC;SAC/C;EACN,IAAI,IAAW;AAMf,SALI,OAAO,KAAU,WACnB,IAAW,KACF,OAAO,KAAU,YAAY,OAAO,KAAU,eACvD,IAAW,OAAO,EAAM,GAEnB,WAAW,EAAS;;;;;ACD/B,IAAa,KAA2B,EACtC,UACA,YACA,YAAS,YACT,qBAC+C;CAC/C,IAAM,EAAE,SAAM,GAA+B,EACzC,IAAW;AAiBf,QAhBI,MAAW,SACb,IAAW,EAAkB,EAAQ,GAC5B,KAAW,SACpB,AAKE,IALE,OAAO,KAAY,WACV,IACF,OAAO,KAAY,YAAY,OAAO,KAAY,YAChD,OAAO,EAAQ,GAEf,EAAkB,EAAQ,GAIrC,EAAS,MAAM,KAAK,OACtB,IAAW,EAAE,sBAAsB,GAInC,kBAAC,GAAD;EAAgC;EAAoB;YAClD,kBAAC,GAAD,EAAsB,SAAS,GAAY,CAAA;EACnB,CAAA"}
@@ -1,6 +1,6 @@
1
- import { n as e } from "./sprinkles.css.ts.vanilla-n-NK_DwW.js";
1
+ import { n as e } from "./BackofficeConfigContext-R0t1owTI.js";
2
2
  import { t } from "./useBackofficeReactTranslation-WfXU8kCf.js";
3
- import { i as n, t as r } from "./EntityIdPickerDialog-FMC5Hx_I.js";
3
+ import { i as n, t as r } from "./EntityIdPickerDialog-D_qAlrU6.js";
4
4
  import { i } from "./mutationResult-CcQMY13J.js";
5
5
  import { n as a, t as o } from "./toastViewAction-BGTS7vqm.js";
6
6
  import { useCallback as s, useContext as ee, useEffect as te, useMemo as c, useState as l } from "react";
@@ -10,7 +10,7 @@ import { BackofficeFormSection as ie, Button as u, CheckboxField as d, Form as a
10
10
  import * as h from "react-relay";
11
11
  import { Fragment as fe, jsx as g, jsxs as _ } from "react/jsx-runtime";
12
12
  //#region src/components/backoffice/actions/backofficeEntityActionFormDialog.css.ts
13
- var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vncd89do6 vncd89ao6", he = "_15f5d9v2 vncd899io vncd89ai6 vncd89ao6", { commitMutation: ge, useRelayEnvironment: _e } = h, v = (e, t) => e(t), y = (e) => typeof e == "object" && !!e && !Array.isArray(e), ve = (e) => {
13
+ var pe = "txvbqb9io txvbqbai6 txvbqbaof", me = "txvbqb9io txvbqbdo6 txvbqbao6", he = "txvbqb9io txvbqbai6 txvbqbao6", { commitMutation: ge, useRelayEnvironment: _e } = h, v = (e, t) => e(t), y = (e) => typeof e == "object" && !!e && !Array.isArray(e), ve = (e) => {
14
14
  if (!y(e)) return null;
15
15
  for (let t of Object.values(e)) if (y(t) && ("status" in t || "result" in t)) return t;
16
16
  return null;
@@ -313,7 +313,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
313
313
  return e.placeholder != null && (a = v(e.placeholder, w)), /* @__PURE__ */ _(f, { children: [
314
314
  /* @__PURE__ */ g(m, { children: t }),
315
315
  r != null && /* @__PURE__ */ g("span", {
316
- className: "_15f5d9v5 vncd898o vncd89v83",
316
+ className: "txvbqb8o txvbqbv83",
317
317
  children: r
318
318
  }),
319
319
  /* @__PURE__ */ g(p, {
@@ -326,7 +326,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
326
326
  fullWidth: !0
327
327
  }),
328
328
  N[e.id] != null && /* @__PURE__ */ g("span", {
329
- className: "_15f5d9v4 vncd898o vncd89v93",
329
+ className: "txvbqb8o txvbqbv93",
330
330
  children: N[e.id]
331
331
  })
332
332
  ] }, e.id);
@@ -338,7 +338,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
338
338
  return e.placeholder != null && (a = v(e.placeholder, w)), /* @__PURE__ */ _(f, { children: [
339
339
  /* @__PURE__ */ g(m, { children: t }),
340
340
  r != null && /* @__PURE__ */ g("span", {
341
- className: "_15f5d9v5 vncd898o vncd89v83",
341
+ className: "txvbqb8o txvbqbv83",
342
342
  children: r
343
343
  }),
344
344
  /* @__PURE__ */ g(p, {
@@ -351,7 +351,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
351
351
  fullWidth: !0
352
352
  }),
353
353
  N[e.id] != null && /* @__PURE__ */ g("span", {
354
- className: "_15f5d9v4 vncd898o vncd89v93",
354
+ className: "txvbqb8o txvbqbv93",
355
355
  children: N[e.id]
356
356
  })
357
357
  ] }, e.id);
@@ -363,7 +363,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
363
363
  return e.placeholder != null && (a = v(e.placeholder, w)), /* @__PURE__ */ _(f, { children: [
364
364
  /* @__PURE__ */ g(m, { children: t }),
365
365
  r != null && /* @__PURE__ */ g("span", {
366
- className: "_15f5d9v5 vncd898o vncd89v83",
366
+ className: "txvbqb8o txvbqbv83",
367
367
  children: r
368
368
  }),
369
369
  /* @__PURE__ */ g(ue, {
@@ -376,7 +376,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
376
376
  fullWidth: !0
377
377
  }),
378
378
  N[e.id] != null && /* @__PURE__ */ g("span", {
379
- className: "_15f5d9v4 vncd898o vncd89v93",
379
+ className: "txvbqb8o txvbqbv93",
380
380
  children: N[e.id]
381
381
  })
382
382
  ] }, e.id);
@@ -392,7 +392,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
392
392
  return /* @__PURE__ */ _(f, { children: [
393
393
  /* @__PURE__ */ g(m, { children: t }),
394
394
  r != null && /* @__PURE__ */ g("span", {
395
- className: "_15f5d9v5 vncd898o vncd89v83",
395
+ className: "txvbqb8o txvbqbv83",
396
396
  children: r
397
397
  }),
398
398
  /* @__PURE__ */ g(le, {
@@ -404,7 +404,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
404
404
  }
405
405
  }),
406
406
  N[e.id] != null && /* @__PURE__ */ g("span", {
407
- className: "_15f5d9v4 vncd898o vncd89v93",
407
+ className: "txvbqb8o txvbqbv93",
408
408
  children: N[e.id]
409
409
  })
410
410
  ] }, e.id);
@@ -413,7 +413,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
413
413
  let n = A[e.id] === !0;
414
414
  return /* @__PURE__ */ _(f, { children: [
415
415
  r != null && /* @__PURE__ */ g("span", {
416
- className: "_15f5d9v5 vncd898o vncd89v83",
416
+ className: "txvbqb8o txvbqbv83",
417
417
  children: r
418
418
  }),
419
419
  /* @__PURE__ */ g(d, {
@@ -424,7 +424,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
424
424
  }
425
425
  }),
426
426
  N[e.id] != null && /* @__PURE__ */ g("span", {
427
- className: "_15f5d9v4 vncd898o vncd89v93",
427
+ className: "txvbqb8o txvbqbv93",
428
428
  children: N[e.id]
429
429
  })
430
430
  ] }, e.id);
@@ -434,7 +434,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
434
434
  return typeof i == "string" && (a = i), /* @__PURE__ */ _(f, { children: [
435
435
  /* @__PURE__ */ g(m, { children: t }),
436
436
  r != null && /* @__PURE__ */ g("span", {
437
- className: "_15f5d9v5 vncd898o vncd89v83",
437
+ className: "txvbqb8o txvbqbv83",
438
438
  children: r
439
439
  }),
440
440
  /* @__PURE__ */ g(n, {
@@ -452,7 +452,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
452
452
  }
453
453
  }),
454
454
  N[e.id] != null && /* @__PURE__ */ g("span", {
455
- className: "_15f5d9v4 vncd898o vncd89v93",
455
+ className: "txvbqb8o txvbqbv93",
456
456
  children: N[e.id]
457
457
  })
458
458
  ] }, e.id);
@@ -462,7 +462,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
462
462
  return Array.isArray(n) && (i = n.filter((e) => typeof e == "string")), /* @__PURE__ */ _(f, { children: [
463
463
  /* @__PURE__ */ g(m, { children: t }),
464
464
  r != null && /* @__PURE__ */ g("span", {
465
- className: "_15f5d9v5 vncd898o vncd89v83",
465
+ className: "txvbqb8o txvbqbv83",
466
466
  children: r
467
467
  }),
468
468
  /* @__PURE__ */ g("div", {
@@ -477,7 +477,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
477
477
  }, t.value))
478
478
  }),
479
479
  N[e.id] != null && /* @__PURE__ */ g("span", {
480
- className: "_15f5d9v4 vncd898o vncd89v93",
480
+ className: "txvbqb8o txvbqbv93",
481
481
  children: N[e.id]
482
482
  })
483
483
  ] }, e.id);
@@ -486,7 +486,7 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
486
486
  }
487
487
  }) }),
488
488
  $ && /* @__PURE__ */ _("div", {
489
- className: "_15f5d9v3 vncd899io vncd89ai6 vncd89ao6",
489
+ className: "txvbqb9io txvbqbai6 txvbqbao6",
490
490
  children: [L != null && Z != null && /* @__PURE__ */ g(se, {
491
491
  badgeLabel: Z,
492
492
  copyCode: L,
@@ -510,4 +510,4 @@ var pe = "_15f5d9v0 vncd899io vncd89ai6 vncd89aof", me = "_15f5d9v1 vncd899io vn
510
510
  //#endregion
511
511
  export { S as BackofficeEntityActionFormDialog, S as default };
512
512
 
513
- //# sourceMappingURL=BackofficeEntityActionFormDialog-FHlW0vys.js.map
513
+ //# sourceMappingURL=BackofficeEntityActionFormDialog-BzKi1eyv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackofficeEntityActionFormDialog-BzKi1eyv.js","names":[],"sources":["../../src/components/backoffice/actions/backofficeEntityActionFormDialog.css.ts","../../src/components/backoffice/actions/BackofficeEntityActionFormDialog.tsx"],"sourcesContent":["import { sprinkles } from '@plumile/ui';\n\nexport const form = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n});\n\nexport const actions = sprinkles({\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 2,\n});\n\nexport const checkboxGroup = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n});\n\nexport const resultSection = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n});\n\nexport const fieldError = sprinkles({\n fontSize: 'xs',\n color: 'error',\n});\n\nexport const fieldDescription = sprinkles({\n fontSize: 'xs',\n color: 'secondary',\n});\n","import {\n type FormEvent,\n type JSX,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\nimport {\n type MutationPayloadBase,\n resolveMutationOutcome,\n} from '../../../relay/mutationResult.js';\nimport {\n BackofficeFormSection,\n Button,\n CheckboxField,\n Form,\n FormErrorBanner,\n FormGroup,\n HighlightCode,\n Input,\n Label,\n Modal,\n SimpleSelect,\n Textarea,\n useToast,\n} from '@plumile/ui';\nimport type {\n BackofficeEntityActionFormFieldSpec,\n BackofficeEntityFormMutationActionSpec,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../../../provider/BackofficeConfigContext.js';\nimport { EntityIdFilterField } from '../filters/EntityIdFilterField.js';\nimport { EntityIdPickerDialog } from '../pickers/EntityIdPickerDialog.js';\nimport {\n resolveToastSpec,\n resolveToastViewActions,\n} from './toastViewAction.js';\n\nconst { commitMutation, useRelayEnvironment } = ReactRelay;\nimport { RoutingContext } from '@plumile/router';\n\nimport * as styles from './backofficeEntityActionFormDialog.css.js';\n\nexport type BackofficeEntityActionFormDialogProps<Node> = {\n isOpen: boolean;\n action: BackofficeEntityFormMutationActionSpec<Node>;\n node: Node;\n onClose: () => void;\n onSuccess?: () => void;\n};\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value != null && !Array.isArray(value);\n};\n\nconst extractMutationPayload = (\n response: unknown,\n): MutationPayloadBase | null => {\n if (!isPlainObject(response)) {\n return null;\n }\n\n for (const value of Object.values(response)) {\n if (isPlainObject(value) && ('status' in value || 'result' in value)) {\n return value as MutationPayloadBase;\n }\n }\n\n return null;\n};\n\nconst buildDefaultValues = (\n fields: readonly BackofficeEntityActionFormFieldSpec[],\n): Record<string, unknown> => {\n const output: Record<string, unknown> = {};\n fields.forEach((field) => {\n if (field.kind === 'boolean') {\n output[field.id] = field.defaultValue ?? false;\n return;\n }\n if (field.kind === 'multiEnum') {\n output[field.id] = field.defaultValue ?? [];\n return;\n }\n if (field.defaultValue != null) {\n output[field.id] = field.defaultValue;\n return;\n }\n output[field.id] = '';\n });\n return output;\n};\n\nconst normalizeInitialValue = (\n field: BackofficeEntityActionFormFieldSpec,\n value: unknown,\n): unknown => {\n if (field.kind === 'number') {\n if (typeof value === 'number') {\n return String(value);\n }\n if (typeof value === 'string') {\n return value;\n }\n return '';\n }\n if (field.kind === 'multiEnum') {\n if (Array.isArray(value)) {\n return value.filter((entry): entry is string => {\n return typeof entry === 'string' && entry.trim() !== '';\n });\n }\n return [];\n }\n if (field.kind === 'boolean') {\n return value === true;\n }\n if (typeof value === 'string') {\n return value;\n }\n return value ?? '';\n};\n\nconst buildInitialValues = <Node,>(\n action: BackofficeEntityFormMutationActionSpec<Node>,\n node: Node,\n): Record<string, unknown> => {\n const defaults = buildDefaultValues(action.fields);\n if (action.getInitialValues == null) {\n return defaults;\n }\n const overrides = action.getInitialValues(node);\n const next: Record<string, unknown> = { ...defaults };\n action.fields.forEach((field) => {\n if (!(field.id in overrides)) {\n return;\n }\n next[field.id] = normalizeInitialValue(field, overrides[field.id]);\n });\n return next;\n};\n\nexport const BackofficeEntityActionFormDialog = <Node,>({\n isOpen,\n action,\n node,\n onClose,\n onSuccess,\n}: BackofficeEntityActionFormDialogProps<Node>): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities } = useBackofficeConfig();\n const routing = useContext(RoutingContext);\n const environment = useRelayEnvironment();\n const toast = useToast();\n\n const [values, setValues] = useState<Record<string, unknown>>({});\n const [formError, setFormError] = useState<string | null>(null);\n const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [resultValue, setResultValue] = useState<string | null>(null);\n const [resultResponse, setResultResponse] = useState<unknown>(null);\n const [activeEntityPicker, setActiveEntityPicker] = useState<{\n fieldId: string;\n entity: string;\n label: string;\n } | null>(null);\n\n useEffect(() => {\n if (!isOpen) {\n return;\n }\n setValues(buildInitialValues(action, node));\n setFormError(null);\n setFieldErrors({});\n setResultValue(null);\n setResultResponse(null);\n }, [action, isOpen, node]);\n\n const setFieldValue = useCallback((fieldId: string, value: unknown) => {\n setValues((current) => {\n return { ...current, [fieldId]: value };\n });\n setFieldErrors((current) => {\n if (current[fieldId] == null) {\n return current;\n }\n const { [fieldId]: removedValue, ...next } = current;\n return next;\n });\n }, []);\n\n const title = resolveLabel(action.label, tApp);\n\n const resolveRequiredError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.required', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidNumberError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidNumber', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJson', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonObjectError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJsonObject', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonArrayError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJsonArray', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const buildPayload = useCallback(():\n | { values: Record<string, unknown> }\n | { error: string; fieldId?: string } => {\n const output: Record<string, unknown> = {};\n\n for (const field of action.fields) {\n const fieldLabel = resolveLabel(field.label, tApp);\n const rawValue = values[field.id];\n\n switch (field.kind) {\n case 'text': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'number': {\n let valueString = '';\n if (typeof rawValue === 'string') {\n valueString = rawValue.trim();\n } else if (\n typeof rawValue === 'number' &&\n Number.isFinite(rawValue)\n ) {\n valueString = String(rawValue);\n }\n if (valueString === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n const parsed = Number(valueString);\n if (!Number.isFinite(parsed)) {\n return {\n error: resolveInvalidNumberError(fieldLabel),\n fieldId: field.id,\n };\n }\n output[field.id] = parsed;\n break;\n }\n case 'json': {\n let valueString = '';\n if (typeof rawValue === 'string') {\n valueString = rawValue.trim();\n }\n if (valueString === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(valueString);\n } catch {\n return {\n error: resolveInvalidJsonError(fieldLabel),\n fieldId: field.id,\n };\n }\n\n const jsonType = field.jsonType ?? 'object';\n if (jsonType === 'object' && !isPlainObject(parsed)) {\n return {\n error: resolveInvalidJsonObjectError(fieldLabel),\n fieldId: field.id,\n };\n }\n if (jsonType === 'array' && !Array.isArray(parsed)) {\n return {\n error: resolveInvalidJsonArrayError(fieldLabel),\n fieldId: field.id,\n };\n }\n\n output[field.id] = parsed;\n break;\n }\n case 'enum': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'boolean': {\n output[field.id] = rawValue === true;\n break;\n }\n case 'entityId': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'multiEnum': {\n let list: string[] = [];\n if (Array.isArray(rawValue)) {\n list = rawValue.filter((entry): entry is string => {\n return typeof entry === 'string' && entry.trim() !== '';\n });\n }\n if (list.length === 0) {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = list;\n break;\n }\n default: {\n break;\n }\n }\n }\n\n return { values: output };\n }, [\n action.fields,\n resolveInvalidJsonArrayError,\n resolveInvalidJsonError,\n resolveInvalidJsonObjectError,\n resolveInvalidNumberError,\n resolveRequiredError,\n tApp,\n values,\n ]);\n\n const handleSubmit = useCallback(() => {\n if (isSubmitting) {\n return;\n }\n\n setFormError(null);\n setFieldErrors({});\n\n const payload = buildPayload();\n if ('error' in payload) {\n setFormError(payload.error);\n if (payload.fieldId != null) {\n setFieldErrors({ [payload.fieldId]: payload.error });\n }\n return;\n }\n\n let variables: ReturnType<typeof action.getVariables>;\n try {\n variables = action.getVariables(node, payload.values);\n } catch (error) {\n let message = t('actions.form.errors.invalidPayload');\n if (error instanceof Error) {\n message = error.message;\n }\n setFormError(message);\n return;\n }\n\n setIsSubmitting(true);\n commitMutation(environment, {\n mutation: action.mutation,\n variables,\n updater: (store) => {\n action.updater?.(store, node);\n },\n onCompleted: (response) => {\n setIsSubmitting(false);\n const mutationPayload = extractMutationPayload(response);\n if (mutationPayload != null) {\n let defaultErrorMessage = t('actions.form.errors.invalidPayload');\n if (action.toasts?.error?.message != null) {\n defaultErrorMessage = resolveLabel(\n action.toasts.error.message,\n tApp,\n );\n } else if (action.toasts?.error?.title != null) {\n defaultErrorMessage = resolveLabel(action.toasts.error.title, tApp);\n }\n\n const outcome = resolveMutationOutcome(mutationPayload, {\n defaultErrorMessage,\n mapReason: (reason) => {\n const mapped = action.mapErrorReason?.(reason, node);\n if (mapped == null) {\n return null;\n }\n if (typeof mapped === 'function') {\n return resolveLabel(mapped, tApp);\n }\n return String(mapped);\n },\n });\n if (!outcome.ok) {\n const error = new Error(outcome.message);\n setFormError(outcome.message);\n action.onError?.(error, node);\n if (action.toasts?.error != null) {\n const toastTitle = resolveLabel(action.toasts.error.title, tApp);\n let toastMessage: string | undefined;\n if (action.toasts.error.message != null) {\n toastMessage = resolveLabel(action.toasts.error.message, tApp);\n }\n toast.error(toastTitle, toastMessage);\n }\n return;\n }\n }\n\n action.onCompleted?.(response, node);\n\n let hasCustomResult = false;\n if (action.result?.render != null) {\n const renderedResult = action.result.render(response, node);\n if (renderedResult != null) {\n hasCustomResult = true;\n setResultResponse(response);\n }\n }\n if (action.toasts?.success != null) {\n const toastSpec = resolveToastSpec(action.toasts.success, tApp);\n const toastActions = resolveToastViewActions({\n toast: action.toasts.success,\n response,\n node,\n tApp,\n entities,\n defaultLabel: t('actions.view'),\n navigateTo: (to) => {\n routing?.history.push({ pathname: to });\n },\n });\n toast.push({\n kind: 'info',\n title: toastSpec.title,\n message: toastSpec.message,\n actions: toastActions,\n });\n }\n\n if (action.result != null) {\n const nextValue = action.result.getValue(response, node);\n if (typeof nextValue === 'string' && nextValue.trim() !== '') {\n setResultValue(nextValue);\n onSuccess?.();\n return;\n }\n }\n\n if (hasCustomResult) {\n onSuccess?.();\n return;\n }\n\n onSuccess?.();\n onClose();\n },\n onError: (error) => {\n setIsSubmitting(false);\n action.onError?.(error, node);\n if (action.toasts?.error != null) {\n const toastTitle = resolveLabel(action.toasts.error.title, tApp);\n let toastMessage: string | undefined;\n if (action.toasts.error.message != null) {\n toastMessage = resolveLabel(action.toasts.error.message, tApp);\n }\n toast.error(toastTitle, toastMessage);\n }\n },\n });\n }, [\n action,\n buildPayload,\n entities,\n environment,\n isSubmitting,\n node,\n onClose,\n onSuccess,\n routing?.history,\n t,\n tApp,\n toast,\n ]);\n\n const handleFormSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n handleSubmit();\n },\n [handleSubmit],\n );\n\n const resultLabel = useMemo(() => {\n if (action.result == null) {\n return null;\n }\n return resolveLabel(action.result.label, tApp);\n }, [action.result, tApp]);\n\n const resultRender = useMemo(() => {\n if (action.result?.render == null || resultResponse == null) {\n return null;\n }\n return action.result.render(resultResponse as never, node);\n }, [action.result, node, resultResponse]);\n\n const showResult =\n (resultValue != null && resultLabel != null) || resultRender != null;\n\n const submitLabel = resolveLabel(action.label, tApp);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <>\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n title={title}\n footer={\n <div className={styles.actions}>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={onClose}\n >\n {t('actions.form.cancel')}\n </Button>\n {!showResult && (\n <Button\n type=\"submit\"\n variant=\"primary\"\n size=\"small\"\n disabled={isSubmitting}\n onClick={handleSubmit}\n >\n {submitLabel}\n </Button>\n )}\n </div>\n }\n >\n <Form onSubmit={handleFormSubmit} className={styles.form}>\n <FormErrorBanner message={formError} />\n <BackofficeFormSection>\n {action.fields.map((field) => {\n const fieldLabel = resolveLabel(field.label, tApp);\n let fieldDescription: string | null = null;\n if (field.description != null) {\n fieldDescription = resolveLabel(field.description, tApp);\n }\n\n switch (field.kind) {\n case 'text': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormGroup key={field.id}>\n <Label>{fieldLabel}</Label>\n {fieldDescription != null && (\n <span className={styles.fieldDescription}>\n {fieldDescription}\n </span>\n )}\n <Input\n type=\"text\"\n value={value}\n placeholder={placeholder}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n {fieldErrors[field.id] != null && (\n <span className={styles.fieldError}>\n {fieldErrors[field.id]}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'number': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormGroup key={field.id}>\n <Label>{fieldLabel}</Label>\n {fieldDescription != null && (\n <span className={styles.fieldDescription}>\n {fieldDescription}\n </span>\n )}\n <Input\n type=\"number\"\n value={value}\n placeholder={placeholder}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n {fieldErrors[field.id] != null && (\n <span className={styles.fieldError}>\n {fieldErrors[field.id]}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'json': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormGroup key={field.id}>\n <Label>{fieldLabel}</Label>\n {fieldDescription != null && (\n <span className={styles.fieldDescription}>\n {fieldDescription}\n </span>\n )}\n <Textarea\n value={value}\n placeholder={placeholder}\n rows={8}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n {fieldErrors[field.id] != null && (\n <span className={styles.fieldError}>\n {fieldErrors[field.id]}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'enum': {\n const rawValue = values[field.id];\n let selected = '';\n if (typeof rawValue === 'string') {\n selected = rawValue;\n }\n const options = field.options.map((option) => {\n return {\n id: option.value,\n value: option.value,\n label: resolveLabel(option.label, tApp),\n };\n });\n return (\n <FormGroup key={field.id}>\n <Label>{fieldLabel}</Label>\n {fieldDescription != null && (\n <span className={styles.fieldDescription}>\n {fieldDescription}\n </span>\n )}\n <SimpleSelect\n options={options}\n value={selected}\n placeholder={fieldLabel}\n onChange={(nextValue) => {\n setFieldValue(field.id, nextValue);\n }}\n />\n {fieldErrors[field.id] != null && (\n <span className={styles.fieldError}>\n {fieldErrors[field.id]}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'boolean': {\n const checked = values[field.id] === true;\n return (\n <FormGroup key={field.id}>\n {fieldDescription != null && (\n <span className={styles.fieldDescription}>\n {fieldDescription}\n </span>\n )}\n <CheckboxField\n label={fieldLabel}\n checked={checked}\n onChange={(event) => {\n setFieldValue(field.id, event.target.checked);\n }}\n />\n {fieldErrors[field.id] != null && (\n <span className={styles.fieldError}>\n {fieldErrors[field.id]}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'entityId': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n return (\n <FormGroup key={field.id}>\n <Label>{fieldLabel}</Label>\n {fieldDescription != null && (\n <span className={styles.fieldDescription}>\n {fieldDescription}\n </span>\n )}\n <EntityIdFilterField\n label={fieldLabel}\n value={value}\n onPick={() => {\n setActiveEntityPicker({\n fieldId: field.id,\n entity: field.entity,\n label: fieldLabel,\n });\n }}\n onClear={() => {\n setFieldValue(field.id, '');\n }}\n />\n {fieldErrors[field.id] != null && (\n <span className={styles.fieldError}>\n {fieldErrors[field.id]}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'multiEnum': {\n const rawValue = values[field.id];\n let selected: string[] = [];\n if (Array.isArray(rawValue)) {\n selected = rawValue.filter((entry): entry is string => {\n return typeof entry === 'string';\n });\n }\n return (\n <FormGroup key={field.id}>\n <Label>{fieldLabel}</Label>\n {fieldDescription != null && (\n <span className={styles.fieldDescription}>\n {fieldDescription}\n </span>\n )}\n <div className={styles.checkboxGroup}>\n {field.options.map((option) => {\n const optionLabel = resolveLabel(option.label, tApp);\n const isChecked = selected.includes(option.value);\n return (\n <CheckboxField\n key={option.value}\n label={optionLabel}\n checked={isChecked}\n onChange={(event) => {\n let nextList = selected;\n if (event.target.checked) {\n if (!selected.includes(option.value)) {\n nextList = [...selected, option.value];\n }\n } else {\n nextList = selected.filter((value) => {\n return value !== option.value;\n });\n }\n setFieldValue(field.id, nextList);\n }}\n />\n );\n })}\n </div>\n {fieldErrors[field.id] != null && (\n <span className={styles.fieldError}>\n {fieldErrors[field.id]}\n </span>\n )}\n </FormGroup>\n );\n }\n default: {\n return null;\n }\n }\n })}\n </BackofficeFormSection>\n\n {showResult && (\n <div className={styles.resultSection}>\n {resultValue != null && resultLabel != null && (\n <HighlightCode\n badgeLabel={resultLabel}\n copyCode={resultValue}\n fallbackCodeText={resultValue}\n />\n )}\n {resultRender}\n </div>\n )}\n </Form>\n </Modal>\n <EntityIdPickerDialog\n isOpen={activeEntityPicker != null}\n entity={activeEntityPicker?.entity ?? ''}\n title={activeEntityPicker?.label ?? ''}\n onClose={() => {\n setActiveEntityPicker(null);\n }}\n onSelectId={(id) => {\n if (activeEntityPicker == null) {\n return;\n }\n setFieldValue(activeEntityPicker.fieldId, id);\n setActiveEntityPicker(null);\n }}\n />\n </>\n );\n};\n\nexport default BackofficeEntityActionFormDialog;\n"],"mappings":"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"}