@plumile/backoffice-react 0.1.82 → 0.1.84

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 (51) hide show
  1. package/lib/esm/{AcceptInvitationScreen-DJkNNx49.js → AcceptInvitationScreen-5-0EtE15.js} +4 -4
  2. package/lib/esm/{AcceptInvitationScreen-DJkNNx49.js.map → AcceptInvitationScreen-5-0EtE15.js.map} +1 -1
  3. package/lib/esm/{AuthPanel-Co626p7A.js → AuthPanel-DiHejPoq.js} +2 -2
  4. package/lib/esm/{AuthPanel-Co626p7A.js.map → AuthPanel-DiHejPoq.js.map} +1 -1
  5. package/lib/esm/{BackofficeAcceptInvitationPage-BQfDMSux.js → BackofficeAcceptInvitationPage-FPbn31YK.js} +6 -6
  6. package/lib/esm/{BackofficeAcceptInvitationPage-BQfDMSux.js.map → BackofficeAcceptInvitationPage-FPbn31YK.js.map} +1 -1
  7. package/lib/esm/{BackofficeDashboardPage-B5_YC1ZL.js → BackofficeDashboardPage-C7lIVeA1.js} +3 -3
  8. package/lib/esm/{BackofficeDashboardPage-B5_YC1ZL.js.map → BackofficeDashboardPage-C7lIVeA1.js.map} +1 -1
  9. package/lib/esm/{BackofficeDetailPayload-CbsZKnw6.js → BackofficeDetailPayload-iVx66o_6.js} +4 -4
  10. package/lib/esm/{BackofficeDetailPayload-CbsZKnw6.js.map → BackofficeDetailPayload-iVx66o_6.js.map} +1 -1
  11. package/lib/esm/{BackofficeEntityActionFormDialog-BzKi1eyv.js → BackofficeEntityActionFormDialog-V4QXnvpy.js} +18 -18
  12. package/lib/esm/{BackofficeEntityActionFormDialog-BzKi1eyv.js.map → BackofficeEntityActionFormDialog-V4QXnvpy.js.map} +1 -1
  13. package/lib/esm/{BackofficeEntityDetailPage-CE4tl5ZJ.js → BackofficeEntityDetailPage-BljQmWsw.js} +10 -10
  14. package/lib/esm/{BackofficeEntityDetailPage-CE4tl5ZJ.js.map → BackofficeEntityDetailPage-BljQmWsw.js.map} +1 -1
  15. package/lib/esm/{BackofficeEntityListPage-CtLI15-L.js → BackofficeEntityListPage-BneDsGo-.js} +6 -6
  16. package/lib/esm/{BackofficeEntityListPage-CtLI15-L.js.map → BackofficeEntityListPage-BneDsGo-.js.map} +1 -1
  17. package/lib/esm/{BackofficeLayoutPage-DpvTzwtK.js → BackofficeLayoutPage-Da4y2B0i.js} +5 -5
  18. package/lib/esm/{BackofficeLayoutPage-DpvTzwtK.js.map → BackofficeLayoutPage-Da4y2B0i.js.map} +1 -1
  19. package/lib/esm/{BackofficeLoginPage-GKVdZndS.js → BackofficeLoginPage-Dc61SyMV.js} +6 -6
  20. package/lib/esm/{BackofficeLoginPage-GKVdZndS.js.map → BackofficeLoginPage-Dc61SyMV.js.map} +1 -1
  21. package/lib/esm/{BackofficePasswordResetCompletePage-CCQJYK9S.js → BackofficePasswordResetCompletePage-CvoHqhBS.js} +4 -4
  22. package/lib/esm/{BackofficePasswordResetCompletePage-CCQJYK9S.js.map → BackofficePasswordResetCompletePage-CvoHqhBS.js.map} +1 -1
  23. package/lib/esm/{BackofficePasswordResetRequestPage-Df8mcLkC.js → BackofficePasswordResetRequestPage-DDNcCf3_.js} +4 -4
  24. package/lib/esm/{BackofficePasswordResetRequestPage-Df8mcLkC.js.map → BackofficePasswordResetRequestPage-DDNcCf3_.js.map} +1 -1
  25. package/lib/esm/{BackofficeRightPageLayout-D7QRE8KZ.js → BackofficeRightPageLayout-F8ipegrl.js} +3 -3
  26. package/lib/esm/{BackofficeRightPageLayout-D7QRE8KZ.js.map → BackofficeRightPageLayout-F8ipegrl.js.map} +1 -1
  27. package/lib/esm/{BackofficeVerifyEmailPage-CtqLzXAD.js → BackofficeVerifyEmailPage-BSTtLXdx.js} +3 -3
  28. package/lib/esm/{BackofficeVerifyEmailPage-CtqLzXAD.js.map → BackofficeVerifyEmailPage-BSTtLXdx.js.map} +1 -1
  29. package/lib/esm/{EntityFilterValue-Bn9VGr2M.js → EntityFilterValue-B5ZGHO_u.js} +2 -2
  30. package/lib/esm/{EntityFilterValue-Bn9VGr2M.js.map → EntityFilterValue-B5ZGHO_u.js.map} +1 -1
  31. package/lib/esm/{EntityIdPickerDialog-D_qAlrU6.js → EntityIdPickerDialog-DbTnDU4v.js} +3 -3
  32. package/lib/esm/{EntityIdPickerDialog-D_qAlrU6.js.map → EntityIdPickerDialog-DbTnDU4v.js.map} +1 -1
  33. package/lib/esm/{LazyBackofficeEntityActionFormDialog-DndjG4kV.js → LazyBackofficeEntityActionFormDialog-BE3wVfU6.js} +5 -5
  34. package/lib/esm/{LazyBackofficeEntityActionFormDialog-DndjG4kV.js.map → LazyBackofficeEntityActionFormDialog-BE3wVfU6.js.map} +1 -1
  35. package/lib/esm/{PasswordResetCompleteScreen-DdJsdKMI.js → PasswordResetCompleteScreen-B0P_tZg2.js} +3 -3
  36. package/lib/esm/{PasswordResetCompleteScreen-DdJsdKMI.js.map → PasswordResetCompleteScreen-B0P_tZg2.js.map} +1 -1
  37. package/lib/esm/{PasswordResetRequestScreen-DBIHOmsl.js → PasswordResetRequestScreen-p9s0dblR.js} +3 -3
  38. package/lib/esm/{PasswordResetRequestScreen-DBIHOmsl.js.map → PasswordResetRequestScreen-p9s0dblR.js.map} +1 -1
  39. package/lib/esm/{VerifyEmailScreen-C9rfi3q8.js → VerifyEmailScreen--9lxOGlW.js} +2 -2
  40. package/lib/esm/{VerifyEmailScreen-C9rfi3q8.js.map → VerifyEmailScreen--9lxOGlW.js.map} +1 -1
  41. package/lib/esm/backoffice-react.js +20 -20
  42. package/lib/esm/loginPage.css-CBJ1Ozm5.js +12 -0
  43. package/lib/esm/{loginPage.css-4M4PrzUn.js.map → loginPage.css-CBJ1Ozm5.js.map} +1 -1
  44. package/lib/esm/{synchronizeAuthStatusQuery-Bb5wh5rF.js → synchronizeAuthStatusQuery-Dr6AEFhi.js} +4 -4
  45. package/lib/esm/{synchronizeAuthStatusQuery-Bb5wh5rF.js.map → synchronizeAuthStatusQuery-Dr6AEFhi.js.map} +1 -1
  46. package/lib/esm/{useAuth-tQWc1NnB.js → useAuth-CjdysxLB.js} +2 -2
  47. package/lib/esm/{useAuth-tQWc1NnB.js.map → useAuth-CjdysxLB.js.map} +1 -1
  48. package/lib/esm/{useBackofficeAuth-BUrTeBOK.js → useBackofficeAuth-BshabGXc.js} +2 -2
  49. package/lib/esm/{useBackofficeAuth-BUrTeBOK.js.map → useBackofficeAuth-BshabGXc.js.map} +1 -1
  50. package/package.json +5 -5
  51. package/lib/esm/loginPage.css-4M4PrzUn.js +0 -12
@@ -71,7 +71,7 @@ var f = (e, t) => t == null ? /* @__PURE__ */ Error(`Invalid breadcrumb contract
71
71
  let { target: n } = e();
72
72
  if (n == null) throw Error("Backoffice topbar target is missing. Ensure BackofficeLayoutPage provides a topbar breadcrumb mount target before rendering right-side pages.");
73
73
  return c(t, n);
74
- }, h = "txvbqb9jf txvbqbco", g = "_80s44h0 txvbqb9jf txvbqbco txvbqbao6", _ = "txvbqb9jf txvbqbco txvbqbao6", v = "_80s44h1 txvbqbv8r txvbqb8x txvbqbfa6", y = "txvbqbv8p txvbqb8x txvbqbfa6 txvbqbamo", b = ({ items: e }) => /* @__PURE__ */ a("nav", {
74
+ }, h = "txvbqb9jg txvbqbcp", g = "_80s44h0 txvbqb9jg txvbqbcp txvbqbao7", _ = "txvbqb9jg txvbqbcp txvbqbao7", v = "_80s44h1 txvbqbva1 txvbqb8y txvbqbfb7", y = "txvbqbv9z txvbqb8y txvbqbfb7 txvbqbamp", b = ({ items: e }) => /* @__PURE__ */ a("nav", {
75
75
  className: h,
76
76
  "aria-label": "Breadcrumb",
77
77
  children: /* @__PURE__ */ a("ol", {
@@ -93,7 +93,7 @@ var f = (e, t) => t == null ? /* @__PURE__ */ Error(`Invalid breadcrumb contract
93
93
  return /* @__PURE__ */ o("li", {
94
94
  className: _,
95
95
  children: [!r && /* @__PURE__ */ a("span", {
96
- className: "txvbqbv8r txvbqb8x txvbqbfa6",
96
+ className: "txvbqbva1 txvbqb8y txvbqbfb7",
97
97
  "aria-hidden": "true",
98
98
  children: "/"
99
99
  }), l]
@@ -104,4 +104,4 @@ var f = (e, t) => t == null ? /* @__PURE__ */ Error(`Invalid breadcrumb contract
104
104
  //#endregion
105
105
  export { d as n, x as t };
106
106
 
107
- //# sourceMappingURL=BackofficeRightPageLayout-D7QRE8KZ.js.map
107
+ //# sourceMappingURL=BackofficeRightPageLayout-F8ipegrl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeRightPageLayout-D7QRE8KZ.js","names":[],"sources":["../../src/components/backoffice/columns/buildDataTableColumns.tsx","../../src/components/backoffice/layout/breadcrumb/assertValidBreadcrumb.ts","../../src/components/backoffice/layout/breadcrumb/BackofficeTopbarPortal.tsx","../../src/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.ts","../../src/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.tsx","../../src/components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.tsx"],"sourcesContent":["import { BACKOFFICE_DATE_TIME_OPTIONS } from '@plumile/backoffice-core/constants.js';\nimport type {\n BackofficeColumnSpec,\n BackofficeFieldSize,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type { TFunction } from 'i18next';\nimport { Link } from '@plumile/router';\nimport { FormattedDate, Tag, type DataTableColumn } from '@plumile/ui';\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 resolveEntityHref?: (entityId: string, refId: string) => string | null;\n};\n\nexport type BackofficeSizedDataTableColumn<Row> = DataTableColumn<Row> & {\n size: BackofficeFieldSize;\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, resolveEntityHref } = 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 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 <Link to={cell.to(row)}>{value}</Link>;\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 href = resolveEntityHref?.(cell.entity, id) ?? null;\n if (href != null) {\n return <Link to={href}>{t('actions.view')}</Link>;\n }\n return fallback;\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","import type {\n BackofficeTopbarBreadcrumbItem,\n BreadcrumbContractErrorCode,\n} from './types.js';\n\nconst formatContractError = (\n code: BreadcrumbContractErrorCode,\n details?: string,\n): Error => {\n if (details == null) {\n return new Error(`Invalid breadcrumb contract: ${code}`);\n }\n return new Error(`Invalid breadcrumb contract: ${code} (${details})`);\n};\n\nexport const assertValidBreadcrumb = (\n items: readonly BackofficeTopbarBreadcrumbItem[] | null | undefined,\n): readonly BackofficeTopbarBreadcrumbItem[] => {\n if (items == null) {\n throw formatContractError('MISSING_BREADCRUMB');\n }\n if (items.length === 0) {\n throw formatContractError('EMPTY_BREADCRUMB');\n }\n\n const seen = new Set<string>();\n items.forEach((item, index) => {\n if (typeof item.id !== 'string' || item.id.trim() === '') {\n throw formatContractError('INVALID_SEGMENT_ID', `index=${index}`);\n }\n\n if (seen.has(item.id)) {\n throw formatContractError(\n 'INVALID_SEGMENT_ID',\n `duplicate id=\"${item.id}\"`,\n );\n }\n seen.add(item.id);\n });\n\n const last = items[items.length - 1];\n if (last?.isCurrent !== true) {\n throw formatContractError('MISSING_CURRENT_SEGMENT');\n }\n\n return items;\n};\n","import { type JSX, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { useBackofficeTopbarPortalContext } from './BackofficeTopbarPortalContext.js';\n\nexport type BackofficeTopbarPortalProps = {\n children: ReactNode;\n};\n\nexport const BackofficeTopbarPortal = ({\n children,\n}: BackofficeTopbarPortalProps): JSX.Element | null => {\n const { target } = useBackofficeTopbarPortalContext();\n if (target == null) {\n throw new Error(\n 'Backoffice topbar target is missing. Ensure BackofficeLayoutPage provides a topbar breadcrumb mount target before rendering right-side pages.',\n );\n }\n return createPortal(children, target);\n};\n\nexport default BackofficeTopbarPortal;\n","import { sprinkles } from '@plumile/ui';\nimport { style } from '@vanilla-extract/css';\n\nconst INLINE_FLEX = 'inline-flex' as const;\n\nexport const nav = sprinkles({\n display: INLINE_FLEX,\n alignItems: 'center',\n});\n\nexport const list = style([\n sprinkles({\n display: INLINE_FLEX,\n alignItems: 'center',\n gap: 2,\n }),\n {\n margin: 0,\n padding: 0,\n listStyle: 'none',\n },\n]);\n\nexport const item = sprinkles({\n display: INLINE_FLEX,\n alignItems: 'center',\n gap: 2,\n});\n\nexport const separator = sprinkles({\n color: 'textSecondary',\n fontSize: 'sm',\n lineHeight: 'normal',\n});\n\nexport const link = style([\n sprinkles({\n color: 'textSecondary',\n fontSize: 'sm',\n lineHeight: 'normal',\n }),\n {\n textDecoration: 'none',\n selectors: {\n '&:hover': {\n textDecoration: 'underline',\n },\n },\n },\n]);\n\nexport const current = sprinkles({\n color: 'text',\n fontSize: 'sm',\n lineHeight: 'normal',\n fontWeight: 'semibold',\n});\n","import { type JSX } from 'react';\nimport { Link } from '@plumile/router';\n\nimport type { BackofficeTopbarBreadcrumbItem } from './types.js';\nimport * as styles from './backofficeTopbarBreadcrumb.css.js';\n\nexport type BackofficeTopbarBreadcrumbProps = {\n items: readonly BackofficeTopbarBreadcrumbItem[];\n};\n\nexport const BackofficeTopbarBreadcrumb = ({\n items,\n}: BackofficeTopbarBreadcrumbProps): JSX.Element => {\n return (\n <nav className={styles.nav} aria-label=\"Breadcrumb\">\n <ol className={styles.list}>\n {items.map((item, index) => {\n const isFirst = index === 0;\n const isCurrent = item.isCurrent === true;\n const key = `${item.id}-${index}`;\n const shouldRenderLink = item.to != null && !isCurrent;\n let content: JSX.Element;\n\n if (shouldRenderLink) {\n content = (\n <Link to={item.to} className={styles.link}>\n {item.label}\n </Link>\n );\n } else {\n let className = styles.link;\n if (isCurrent) {\n className = styles.current;\n }\n content = <span className={className}>{item.label}</span>;\n }\n\n return (\n <li key={key} className={styles.item}>\n {!isFirst && (\n <span className={styles.separator} aria-hidden=\"true\">\n /\n </span>\n )}\n {content}\n </li>\n );\n })}\n </ol>\n </nav>\n );\n};\n\nexport default BackofficeTopbarBreadcrumb;\n","import { type JSX, type ReactNode } from 'react';\n\nimport { assertValidBreadcrumb } from './assertValidBreadcrumb.js';\nimport { BackofficeTopbarPortal } from './BackofficeTopbarPortal.js';\nimport { BackofficeTopbarBreadcrumb } from './BackofficeTopbarBreadcrumb.js';\nimport type { BackofficeTopbarBreadcrumbItem } from './types.js';\n\nexport type BackofficeRightPageLayoutProps = {\n breadcrumb: readonly BackofficeTopbarBreadcrumbItem[];\n children: ReactNode;\n};\n\nexport const BackofficeRightPageLayout = ({\n breadcrumb,\n children,\n}: BackofficeRightPageLayoutProps): JSX.Element => {\n const items = assertValidBreadcrumb(breadcrumb);\n\n return (\n <>\n <BackofficeTopbarPortal>\n <BackofficeTopbarBreadcrumb items={items} />\n </BackofficeTopbarPortal>\n <>{children}</>\n </>\n );\n};\n\nexport default BackofficeRightPageLayout;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BackofficeRightPageLayout-F8ipegrl.js","names":[],"sources":["../../src/components/backoffice/columns/buildDataTableColumns.tsx","../../src/components/backoffice/layout/breadcrumb/assertValidBreadcrumb.ts","../../src/components/backoffice/layout/breadcrumb/BackofficeTopbarPortal.tsx","../../src/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.ts","../../src/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.tsx","../../src/components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.tsx"],"sourcesContent":["import { BACKOFFICE_DATE_TIME_OPTIONS } from '@plumile/backoffice-core/constants.js';\nimport type {\n BackofficeColumnSpec,\n BackofficeFieldSize,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type { TFunction } from 'i18next';\nimport { Link } from '@plumile/router';\nimport { FormattedDate, Tag, type DataTableColumn } from '@plumile/ui';\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 resolveEntityHref?: (entityId: string, refId: string) => string | null;\n};\n\nexport type BackofficeSizedDataTableColumn<Row> = DataTableColumn<Row> & {\n size: BackofficeFieldSize;\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, resolveEntityHref } = 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 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 <Link to={cell.to(row)}>{value}</Link>;\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 href = resolveEntityHref?.(cell.entity, id) ?? null;\n if (href != null) {\n return <Link to={href}>{t('actions.view')}</Link>;\n }\n return fallback;\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","import type {\n BackofficeTopbarBreadcrumbItem,\n BreadcrumbContractErrorCode,\n} from './types.js';\n\nconst formatContractError = (\n code: BreadcrumbContractErrorCode,\n details?: string,\n): Error => {\n if (details == null) {\n return new Error(`Invalid breadcrumb contract: ${code}`);\n }\n return new Error(`Invalid breadcrumb contract: ${code} (${details})`);\n};\n\nexport const assertValidBreadcrumb = (\n items: readonly BackofficeTopbarBreadcrumbItem[] | null | undefined,\n): readonly BackofficeTopbarBreadcrumbItem[] => {\n if (items == null) {\n throw formatContractError('MISSING_BREADCRUMB');\n }\n if (items.length === 0) {\n throw formatContractError('EMPTY_BREADCRUMB');\n }\n\n const seen = new Set<string>();\n items.forEach((item, index) => {\n if (typeof item.id !== 'string' || item.id.trim() === '') {\n throw formatContractError('INVALID_SEGMENT_ID', `index=${index}`);\n }\n\n if (seen.has(item.id)) {\n throw formatContractError(\n 'INVALID_SEGMENT_ID',\n `duplicate id=\"${item.id}\"`,\n );\n }\n seen.add(item.id);\n });\n\n const last = items[items.length - 1];\n if (last?.isCurrent !== true) {\n throw formatContractError('MISSING_CURRENT_SEGMENT');\n }\n\n return items;\n};\n","import { type JSX, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { useBackofficeTopbarPortalContext } from './BackofficeTopbarPortalContext.js';\n\nexport type BackofficeTopbarPortalProps = {\n children: ReactNode;\n};\n\nexport const BackofficeTopbarPortal = ({\n children,\n}: BackofficeTopbarPortalProps): JSX.Element | null => {\n const { target } = useBackofficeTopbarPortalContext();\n if (target == null) {\n throw new Error(\n 'Backoffice topbar target is missing. Ensure BackofficeLayoutPage provides a topbar breadcrumb mount target before rendering right-side pages.',\n );\n }\n return createPortal(children, target);\n};\n\nexport default BackofficeTopbarPortal;\n","import { sprinkles } from '@plumile/ui';\nimport { style } from '@vanilla-extract/css';\n\nconst INLINE_FLEX = 'inline-flex' as const;\n\nexport const nav = sprinkles({\n display: INLINE_FLEX,\n alignItems: 'center',\n});\n\nexport const list = style([\n sprinkles({\n display: INLINE_FLEX,\n alignItems: 'center',\n gap: 2,\n }),\n {\n margin: 0,\n padding: 0,\n listStyle: 'none',\n },\n]);\n\nexport const item = sprinkles({\n display: INLINE_FLEX,\n alignItems: 'center',\n gap: 2,\n});\n\nexport const separator = sprinkles({\n color: 'textSecondary',\n fontSize: 'sm',\n lineHeight: 'normal',\n});\n\nexport const link = style([\n sprinkles({\n color: 'textSecondary',\n fontSize: 'sm',\n lineHeight: 'normal',\n }),\n {\n textDecoration: 'none',\n selectors: {\n '&:hover': {\n textDecoration: 'underline',\n },\n },\n },\n]);\n\nexport const current = sprinkles({\n color: 'text',\n fontSize: 'sm',\n lineHeight: 'normal',\n fontWeight: 'semibold',\n});\n","import { type JSX } from 'react';\nimport { Link } from '@plumile/router';\n\nimport type { BackofficeTopbarBreadcrumbItem } from './types.js';\nimport * as styles from './backofficeTopbarBreadcrumb.css.js';\n\nexport type BackofficeTopbarBreadcrumbProps = {\n items: readonly BackofficeTopbarBreadcrumbItem[];\n};\n\nexport const BackofficeTopbarBreadcrumb = ({\n items,\n}: BackofficeTopbarBreadcrumbProps): JSX.Element => {\n return (\n <nav className={styles.nav} aria-label=\"Breadcrumb\">\n <ol className={styles.list}>\n {items.map((item, index) => {\n const isFirst = index === 0;\n const isCurrent = item.isCurrent === true;\n const key = `${item.id}-${index}`;\n const shouldRenderLink = item.to != null && !isCurrent;\n let content: JSX.Element;\n\n if (shouldRenderLink) {\n content = (\n <Link to={item.to} className={styles.link}>\n {item.label}\n </Link>\n );\n } else {\n let className = styles.link;\n if (isCurrent) {\n className = styles.current;\n }\n content = <span className={className}>{item.label}</span>;\n }\n\n return (\n <li key={key} className={styles.item}>\n {!isFirst && (\n <span className={styles.separator} aria-hidden=\"true\">\n /\n </span>\n )}\n {content}\n </li>\n );\n })}\n </ol>\n </nav>\n );\n};\n\nexport default BackofficeTopbarBreadcrumb;\n","import { type JSX, type ReactNode } from 'react';\n\nimport { assertValidBreadcrumb } from './assertValidBreadcrumb.js';\nimport { BackofficeTopbarPortal } from './BackofficeTopbarPortal.js';\nimport { BackofficeTopbarBreadcrumb } from './BackofficeTopbarBreadcrumb.js';\nimport type { BackofficeTopbarBreadcrumbItem } from './types.js';\n\nexport type BackofficeRightPageLayoutProps = {\n breadcrumb: readonly BackofficeTopbarBreadcrumbItem[];\n children: ReactNode;\n};\n\nexport const BackofficeRightPageLayout = ({\n breadcrumb,\n children,\n}: BackofficeRightPageLayoutProps): JSX.Element => {\n const items = assertValidBreadcrumb(breadcrumb);\n\n return (\n <>\n <BackofficeTopbarPortal>\n <BackofficeTopbarBreadcrumb items={items} />\n </BackofficeTopbarPortal>\n <>{children}</>\n </>\n );\n};\n\nexport default BackofficeRightPageLayout;\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { n as e } from "./BackofficeConfigContext-R0t1owTI.js";
2
- import { f as t } from "./loginPage.css-4M4PrzUn.js";
3
- import { t as n } from "./VerifyEmailScreen-C9rfi3q8.js";
2
+ import { f as t } from "./loginPage.css-CBJ1Ozm5.js";
3
+ import { t as n } from "./VerifyEmailScreen--9lxOGlW.js";
4
4
  import { i as r, t as i } from "./mutationResult-CcQMY13J.js";
5
5
  import { t as a } from "./backofficeAuthPaths-BiJvoI5Q.js";
6
6
  import { i as o } from "./useBackofficeLazyValue-Dnii1_dE.js";
@@ -56,4 +56,4 @@ var { useMutation: f } = u, p = () => {
56
56
  //#endregion
57
57
  export { p as BackofficeVerifyEmailPage, p as default };
58
58
 
59
- //# sourceMappingURL=BackofficeVerifyEmailPage-CtqLzXAD.js.map
59
+ //# sourceMappingURL=BackofficeVerifyEmailPage-BSTtLXdx.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeVerifyEmailPage-CtqLzXAD.js","names":[],"sources":["../../src/pages/BackofficeVerifyEmailPage.tsx"],"sourcesContent":["import { useCallback, useContext, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { MutationParameters } from 'relay-runtime';\nimport { RoutingContext } from '@plumile/router';\n\nimport { VerifyEmailScreen } from '../auth/pages/VerifyEmailScreen.js';\nimport {\n type MutationPayloadBase,\n requireField,\n resolveMutationOutcome,\n} from '../relay/mutationResult.js';\nimport { useSharedTranslation } from '../i18n/useSharedTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeAuthVerifyEmailConfig } from '../provider/useBackofficeLazyValue.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\n\nconst { useMutation } = ReactRelay;\n\ntype VerifyEmailErrorReason =\n | 'INVALID_TOKEN'\n | 'TOKEN_EXPIRED'\n | 'ALREADY_VERIFIED'\n | 'INTERNAL_ERROR';\n\ntype VerifyEmailMutationPayload =\n MutationPayloadBase<VerifyEmailErrorReason> & {\n success?: boolean | null;\n };\n\nexport const BackofficeVerifyEmailPage = (): JSX.Element => {\n const routerContext = useContext(RoutingContext);\n const { basePath } = useBackofficeConfig();\n const auth = useBackofficeAuthVerifyEmailConfig();\n const { t } = useSharedTranslation();\n type VerifyEmailMutation = MutationParameters & {\n response: { verifyEmail?: VerifyEmailMutationPayload | null };\n variables: { input: { token: string } };\n };\n const [commitVerify] = useMutation<VerifyEmailMutation>(\n auth.verifyEmailMutation,\n );\n\n const handleBackToLogin = useCallback(() => {\n routerContext?.history.push({ pathname: getBackofficeLoginPath(basePath) });\n }, [basePath, routerContext?.history]);\n\n const handleVerifyEmail = useCallback(\n async (input: { token: string }): Promise<boolean> => {\n const invalidMessage = t('auth.verifyEmail.errors.invalid');\n const defaultErrorMessage = invalidMessage;\n\n return new Promise((resolve, reject) => {\n commitVerify({\n variables: {\n input,\n },\n onCompleted: (response) => {\n const outcome = resolveMutationOutcome(\n response.verifyEmail ?? null,\n {\n defaultErrorMessage,\n mapReason: (reason) => {\n switch (reason) {\n case 'INVALID_TOKEN':\n return invalidMessage;\n case 'TOKEN_EXPIRED':\n return t('auth.verifyEmail.errors.expired');\n case 'ALREADY_VERIFIED':\n return t('auth.verifyEmail.errors.alreadyVerified');\n case 'INTERNAL_ERROR':\n return invalidMessage;\n default:\n return null;\n }\n },\n },\n );\n if (!outcome.ok) {\n reject(new Error(outcome.message));\n return;\n }\n\n const successResult = requireField(\n outcome.payload.success ?? null,\n defaultErrorMessage,\n );\n if (!successResult.ok) {\n reject(new Error(successResult.message));\n return;\n }\n resolve(successResult.value);\n },\n onError: (mutationError) => {\n let error = new Error(defaultErrorMessage);\n if (mutationError instanceof Error) {\n error = mutationError;\n }\n reject(error);\n },\n });\n });\n },\n [commitVerify, t],\n );\n\n return (\n <VerifyEmailScreen\n onBackToLogin={handleBackToLogin}\n onVerifyEmail={handleVerifyEmail}\n />\n );\n};\n\nexport default BackofficeVerifyEmailPage;\n"],"mappings":";;;;;;;;;;;AAgBA,IAAM,EAAE,mBAAgB,GAaX,UAA+C;CAC1D,IAAM,IAAgB,EAAW,EAAe,EAC1C,EAAE,gBAAa,GAAqB,EACpC,IAAO,GAAoC,EAC3C,EAAE,SAAM,GAAsB,EAK9B,CAAC,KAAgB,EACrB,EAAK,oBACN;AAiED,QACE,kBAAC,GAAD;EACE,eAjEsB,QAAkB;AAC1C,MAAe,QAAQ,KAAK,EAAE,UAAU,EAAuB,EAAS,EAAE,CAAC;KAC1E,CAAC,GAAU,GAAe,QAAQ,CAAC;EAgElC,eA9DsB,EACxB,OAAO,MAA+C;GACpD,IAAM,IAAiB,EAAE,kCAAkC,EACrD,IAAsB;AAE5B,UAAO,IAAI,SAAS,GAAS,MAAW;AACtC,MAAa;KACX,WAAW,EACT,UACD;KACD,cAAc,MAAa;MACzB,IAAM,IAAU,EACd,EAAS,eAAe,MACxB;OACE;OACA,YAAY,MAAW;AACrB,gBAAQ,GAAR;SACE,KAAK,gBACH,QAAO;SACT,KAAK,gBACH,QAAO,EAAE,kCAAkC;SAC7C,KAAK,mBACH,QAAO,EAAE,0CAA0C;SACrD,KAAK,iBACH,QAAO;SACT,QACE,QAAO;;;OAGd,CACF;AACD,UAAI,CAAC,EAAQ,IAAI;AACf,SAAW,MAAM,EAAQ,QAAQ,CAAC;AAClC;;MAGF,IAAM,IAAgB,EACpB,EAAQ,QAAQ,WAAW,MAC3B,EACD;AACD,UAAI,CAAC,EAAc,IAAI;AACrB,SAAW,MAAM,EAAc,QAAQ,CAAC;AACxC;;AAEF,QAAQ,EAAc,MAAM;;KAE9B,UAAU,MAAkB;MAC1B,IAAI,IAAY,MAAM,EAAoB;AAI1C,MAHI,aAAyB,UAC3B,IAAQ,IAEV,EAAO,EAAM;;KAEhB,CAAC;KACF;KAEJ,CAAC,GAAc,EAAE,CAClB;EAMG,CAAA"}
1
+ {"version":3,"file":"BackofficeVerifyEmailPage-BSTtLXdx.js","names":[],"sources":["../../src/pages/BackofficeVerifyEmailPage.tsx"],"sourcesContent":["import { useCallback, useContext, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { MutationParameters } from 'relay-runtime';\nimport { RoutingContext } from '@plumile/router';\n\nimport { VerifyEmailScreen } from '../auth/pages/VerifyEmailScreen.js';\nimport {\n type MutationPayloadBase,\n requireField,\n resolveMutationOutcome,\n} from '../relay/mutationResult.js';\nimport { useSharedTranslation } from '../i18n/useSharedTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeAuthVerifyEmailConfig } from '../provider/useBackofficeLazyValue.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\n\nconst { useMutation } = ReactRelay;\n\ntype VerifyEmailErrorReason =\n | 'INVALID_TOKEN'\n | 'TOKEN_EXPIRED'\n | 'ALREADY_VERIFIED'\n | 'INTERNAL_ERROR';\n\ntype VerifyEmailMutationPayload =\n MutationPayloadBase<VerifyEmailErrorReason> & {\n success?: boolean | null;\n };\n\nexport const BackofficeVerifyEmailPage = (): JSX.Element => {\n const routerContext = useContext(RoutingContext);\n const { basePath } = useBackofficeConfig();\n const auth = useBackofficeAuthVerifyEmailConfig();\n const { t } = useSharedTranslation();\n type VerifyEmailMutation = MutationParameters & {\n response: { verifyEmail?: VerifyEmailMutationPayload | null };\n variables: { input: { token: string } };\n };\n const [commitVerify] = useMutation<VerifyEmailMutation>(\n auth.verifyEmailMutation,\n );\n\n const handleBackToLogin = useCallback(() => {\n routerContext?.history.push({ pathname: getBackofficeLoginPath(basePath) });\n }, [basePath, routerContext?.history]);\n\n const handleVerifyEmail = useCallback(\n async (input: { token: string }): Promise<boolean> => {\n const invalidMessage = t('auth.verifyEmail.errors.invalid');\n const defaultErrorMessage = invalidMessage;\n\n return new Promise((resolve, reject) => {\n commitVerify({\n variables: {\n input,\n },\n onCompleted: (response) => {\n const outcome = resolveMutationOutcome(\n response.verifyEmail ?? null,\n {\n defaultErrorMessage,\n mapReason: (reason) => {\n switch (reason) {\n case 'INVALID_TOKEN':\n return invalidMessage;\n case 'TOKEN_EXPIRED':\n return t('auth.verifyEmail.errors.expired');\n case 'ALREADY_VERIFIED':\n return t('auth.verifyEmail.errors.alreadyVerified');\n case 'INTERNAL_ERROR':\n return invalidMessage;\n default:\n return null;\n }\n },\n },\n );\n if (!outcome.ok) {\n reject(new Error(outcome.message));\n return;\n }\n\n const successResult = requireField(\n outcome.payload.success ?? null,\n defaultErrorMessage,\n );\n if (!successResult.ok) {\n reject(new Error(successResult.message));\n return;\n }\n resolve(successResult.value);\n },\n onError: (mutationError) => {\n let error = new Error(defaultErrorMessage);\n if (mutationError instanceof Error) {\n error = mutationError;\n }\n reject(error);\n },\n });\n });\n },\n [commitVerify, t],\n );\n\n return (\n <VerifyEmailScreen\n onBackToLogin={handleBackToLogin}\n onVerifyEmail={handleVerifyEmail}\n />\n );\n};\n\nexport default BackofficeVerifyEmailPage;\n"],"mappings":";;;;;;;;;;;AAgBA,IAAM,EAAE,mBAAgB,GAaX,UAA+C;CAC1D,IAAM,IAAgB,EAAW,EAAe,EAC1C,EAAE,gBAAa,GAAqB,EACpC,IAAO,GAAoC,EAC3C,EAAE,SAAM,GAAsB,EAK9B,CAAC,KAAgB,EACrB,EAAK,oBACN;AAiED,QACE,kBAAC,GAAD;EACE,eAjEsB,QAAkB;AAC1C,MAAe,QAAQ,KAAK,EAAE,UAAU,EAAuB,EAAS,EAAE,CAAC;KAC1E,CAAC,GAAU,GAAe,QAAQ,CAAC;EAgElC,eA9DsB,EACxB,OAAO,MAA+C;GACpD,IAAM,IAAiB,EAAE,kCAAkC,EACrD,IAAsB;AAE5B,UAAO,IAAI,SAAS,GAAS,MAAW;AACtC,MAAa;KACX,WAAW,EACT,UACD;KACD,cAAc,MAAa;MACzB,IAAM,IAAU,EACd,EAAS,eAAe,MACxB;OACE;OACA,YAAY,MAAW;AACrB,gBAAQ,GAAR;SACE,KAAK,gBACH,QAAO;SACT,KAAK,gBACH,QAAO,EAAE,kCAAkC;SAC7C,KAAK,mBACH,QAAO,EAAE,0CAA0C;SACrD,KAAK,iBACH,QAAO;SACT,QACE,QAAO;;;OAGd,CACF;AACD,UAAI,CAAC,EAAQ,IAAI;AACf,SAAW,MAAM,EAAQ,QAAQ,CAAC;AAClC;;MAGF,IAAM,IAAgB,EACpB,EAAQ,QAAQ,WAAW,MAC3B,EACD;AACD,UAAI,CAAC,EAAc,IAAI;AACrB,SAAW,MAAM,EAAc,QAAQ,CAAC;AACxC;;AAEF,QAAQ,EAAc,MAAM;;KAE9B,UAAU,MAAkB;MAC1B,IAAI,IAAY,MAAM,EAAoB;AAI1C,MAHI,aAAyB,UAC3B,IAAQ,IAEV,EAAO,EAAM;;KAEhB,CAAC;KACF;KAEJ,CAAC,GAAc,EAAE,CAClB;EAMG,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { n as e, t } from "./useBackofficeReactTranslation-WfXU8kCf.js";
2
- import { r as n } from "./EntityIdPickerDialog-D_qAlrU6.js";
2
+ import { r as n } from "./EntityIdPickerDialog-DbTnDU4v.js";
3
3
  import { Suspense as r, createContext as i, useCallback as a, useContext as o, useMemo as s } from "react";
4
4
  import * as c from "react-relay";
5
5
  import { jsx as l } from "react/jsx-runtime";
@@ -74,4 +74,4 @@ var f = i(null), p = (e) => {
74
74
  //#endregion
75
75
  export { m as i, v as n, p as r, y as t };
76
76
 
77
- //# sourceMappingURL=EntityFilterValue-Bn9VGr2M.js.map
77
+ //# sourceMappingURL=EntityFilterValue-B5ZGHO_u.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EntityFilterValue-Bn9VGr2M.js","names":[],"sources":["../../src/components/backoffice/scaffolds/BackofficeListFilterContext.tsx","../../src/components/backoffice/filters/EntityFilterValue.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useMemo,\n type JSX,\n type ReactNode,\n} from 'react';\n\nimport type {\n BackofficeListState,\n BackofficeResolvedListFacetConfig,\n} from '@plumile/backoffice-core/types.js';\nimport { buildBackofficeListLink } from '@plumile/backoffice-core/state/buildListHref.js';\nimport { setWhereValue } from '@plumile/backoffice-core/filters/where.js';\n\nexport type BackofficeListFilterContextValue = {\n config: BackofficeResolvedListFacetConfig;\n state: BackofficeListState<Record<string, unknown>, string>;\n pushState: (\n next: BackofficeListState<Record<string, unknown>, string>,\n ) => void;\n applyFilter: (\n whereKey: string,\n value: unknown,\n path?: readonly string[],\n ) => void;\n buildFilterLink: (\n whereKey: string,\n value: unknown,\n path?: readonly string[],\n ) => { pathname: string; search: string };\n};\n\nconst BackofficeListFilterContext =\n createContext<BackofficeListFilterContextValue | null>(null);\n\ntype ProviderProps<\n Where extends Record<string, unknown>,\n Sort extends string,\n> = {\n config: BackofficeResolvedListFacetConfig<Where, Sort>;\n state: BackofficeListState<Where, Sort>;\n pushState: (next: BackofficeListState<Where, Sort>) => void;\n children: ReactNode;\n};\n\nexport const BackofficeListFilterProvider = <\n Where extends Record<string, unknown>,\n Sort extends string,\n>(\n props: ProviderProps<Where, Sort>,\n): JSX.Element => {\n const { config, state, pushState, children } = props;\n\n const applyFilter = useCallback(\n (whereKey: string, value: unknown, path?: readonly string[]) => {\n const nextWhere = setWhereValue(\n state.where,\n whereKey as keyof Where,\n value,\n path,\n );\n pushState({ ...state, where: nextWhere });\n },\n [pushState, state],\n );\n\n const buildFilterLink = useCallback(\n (whereKey: string, value: unknown, path?: readonly string[]) => {\n const nextWhere = setWhereValue(\n state.where,\n whereKey as keyof Where,\n value,\n path,\n );\n return buildBackofficeListLink(config, { ...state, where: nextWhere });\n },\n [config, state],\n );\n\n const contextValue = useMemo<BackofficeListFilterContextValue>(() => {\n return {\n config: config as BackofficeResolvedListFacetConfig,\n state: state as unknown as BackofficeListState<\n Record<string, unknown>,\n string\n >,\n pushState: pushState as BackofficeListFilterContextValue['pushState'],\n applyFilter,\n buildFilterLink,\n };\n }, [applyFilter, buildFilterLink, config, pushState, state]);\n\n return (\n <BackofficeListFilterContext.Provider value={contextValue}>\n {children}\n </BackofficeListFilterContext.Provider>\n );\n};\n\nexport const useBackofficeListFilterContext =\n (): BackofficeListFilterContextValue | null => {\n return useContext(BackofficeListFilterContext);\n };\n\nexport default BackofficeListFilterContext;\n","import { Suspense, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { OperationType } from 'relay-runtime';\n\nimport type { BackofficePickerValueConfig } from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficePickerEntityLoader } from '../../../provider/useBackofficeEntityLoader.js';\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\n\nconst { useLazyLoadQuery } = ReactRelay;\n\ntype EntityFilterValueContentProps<RowRef, RowView> = {\n valueConfig: BackofficePickerValueConfig<RowRef, RowView>;\n id: string;\n children: (label: string | null) => JSX.Element;\n};\n\nconst resolveTitle = (value: unknown): string | null => {\n if (value == null || typeof value !== 'object') {\n return null;\n }\n const { title } = value as { title?: unknown };\n if (typeof title !== 'string') {\n return null;\n }\n const trimmed = title.trim();\n if (trimmed === '') {\n return null;\n }\n return trimmed;\n};\n\nconst EntityFilterValueContent = <RowRef, RowView>({\n valueConfig,\n id,\n children,\n}: EntityFilterValueContentProps<RowRef, RowView>): JSX.Element => {\n const data = useLazyLoadQuery<OperationType>(valueConfig.query, { id });\n const rowRef = valueConfig.resolveRow(data);\n let row: RowView | null = null;\n if (rowRef != null) {\n row = valueConfig.toRow(rowRef);\n }\n const title = resolveTitle(row);\n\n return children(title);\n};\n\nexport type EntityFilterValueTextProps = {\n entityId: string;\n id: string;\n children: (label: string | null) => JSX.Element;\n};\n\nexport const EntityFilterValueText = ({\n entityId,\n id,\n children,\n}: EntityFilterValueTextProps): JSX.Element => {\n const resolvedId = id.trim();\n const pickerEntityState = useBackofficePickerEntityLoader(entityId, {\n enabled: resolvedId !== '',\n });\n let valueConfig: BackofficePickerValueConfig<unknown, unknown> | null = null;\n if (pickerEntityState.status === 'loaded') {\n valueConfig = pickerEntityState.module.config.picker.value ?? null;\n }\n\n const fallback = children(null);\n if (valueConfig == null) {\n return fallback;\n }\n\n return (\n <BackofficeErrorBoundary\n fallback={() => {\n return fallback;\n }}\n >\n <Suspense fallback={fallback}>\n <EntityFilterValueContent valueConfig={valueConfig} id={id}>\n {children}\n </EntityFilterValueContent>\n </Suspense>\n </BackofficeErrorBoundary>\n );\n};\n\nexport type EntityFilterValueProps = {\n entityId: string;\n id: string;\n};\n\nexport const EntityFilterValue = ({\n entityId,\n id,\n}: EntityFilterValueProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const resolvedId = id.trim();\n\n return (\n <EntityFilterValueText entityId={entityId} id={id}>\n {(label) => {\n let fallbackLabel = resolvedId;\n if (resolvedId === '') {\n fallbackLabel = t('filters.placeholders.unresolved');\n }\n return <span>{label ?? fallbackLabel}</span>;\n }}\n </EntityFilterValueText>\n );\n};\n\nexport default EntityFilterValue;\n"],"mappings":";;;;;;;;AAkCA,IAAM,IACJ,EAAuD,KAAK,EAYjD,KAIX,MACgB;CAChB,IAAM,EAAE,WAAQ,UAAO,cAAW,gBAAa,GAEzC,IAAc,GACjB,GAAkB,GAAgB,MAA6B;EAC9D,IAAM,IAAY,EAChB,EAAM,OACN,GACA,GACA,EACD;AACD,IAAU;GAAE,GAAG;GAAO,OAAO;GAAW,CAAC;IAE3C,CAAC,GAAW,EAAM,CACnB,EAEK,IAAkB,GACrB,GAAkB,GAAgB,MAA6B;EAC9D,IAAM,IAAY,EAChB,EAAM,OACN,GACA,GACA,EACD;AACD,SAAO,EAAwB,GAAQ;GAAE,GAAG;GAAO,OAAO;GAAW,CAAC;IAExE,CAAC,GAAQ,EAAM,CAChB,EAEK,IAAe,SACZ;EACG;EACD;EAII;EACX;EACA;EACD,GACA;EAAC;EAAa;EAAiB;EAAQ;EAAW;EAAM,CAAC;AAE5D,QACE,kBAAC,EAA4B,UAA7B;EAAsC,OAAO;EAC1C;EACoC,CAAA;GAI9B,UAEF,EAAW,EAA4B,EC7F5C,EAAE,wBAAqB,GAQvB,KAAgB,MAAkC;AACtD,KAAqB,OAAO,KAAU,aAAlC,EACF,QAAO;CAET,IAAM,EAAE,aAAU;AAClB,KAAI,OAAO,KAAU,SACnB,QAAO;CAET,IAAM,IAAU,EAAM,MAAM;AAI5B,QAHI,MAAY,KACP,OAEF;GAGH,KAA6C,EACjD,gBACA,OACA,kBACiE;CACjE,IAAM,IAAO,EAAgC,EAAY,OAAO,EAAE,OAAI,CAAC,EACjE,IAAS,EAAY,WAAW,EAAK,EACvC,IAAsB;AAM1B,QALI,KAAU,SACZ,IAAM,EAAY,MAAM,EAAO,GAI1B,EAFO,EAAa,EAAI,CAET;GASX,KAAyB,EACpC,aACA,OACA,kBAC6C;CAE7C,IAAM,IAAoB,EAAgC,GAAU,EAClE,SAFiB,EAAG,MAAM,KAEF,IACzB,CAAC,EACE,IAAoE;AACxE,CAAI,EAAkB,WAAW,aAC/B,IAAc,EAAkB,OAAO,OAAO,OAAO,SAAS;CAGhE,IAAM,IAAW,EAAS,KAAK;AAK/B,QAJI,KAAe,OACV,IAIP,kBAAC,GAAD;EACE,gBACS;YAGT,kBAAC,GAAD;GAAoB;aAClB,kBAAC,GAAD;IAAuC;IAAiB;IACrD;IACwB,CAAA;GAClB,CAAA;EACa,CAAA;GASjB,KAAqB,EAChC,aACA,YACyC;CACzC,IAAM,EAAE,SAAM,GAA+B,EACvC,IAAa,EAAG,MAAM;AAE5B,QACE,kBAAC,GAAD;EAAiC;EAAc;aAC3C,MAAU;GACV,IAAI,IAAgB;AAIpB,UAHI,MAAe,OACjB,IAAgB,EAAE,kCAAkC,GAE/C,kBAAC,QAAD,EAAA,UAAO,KAAS,GAAqB,CAAA;;EAExB,CAAA"}
1
+ {"version":3,"file":"EntityFilterValue-B5ZGHO_u.js","names":[],"sources":["../../src/components/backoffice/scaffolds/BackofficeListFilterContext.tsx","../../src/components/backoffice/filters/EntityFilterValue.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useMemo,\n type JSX,\n type ReactNode,\n} from 'react';\n\nimport type {\n BackofficeListState,\n BackofficeResolvedListFacetConfig,\n} from '@plumile/backoffice-core/types.js';\nimport { buildBackofficeListLink } from '@plumile/backoffice-core/state/buildListHref.js';\nimport { setWhereValue } from '@plumile/backoffice-core/filters/where.js';\n\nexport type BackofficeListFilterContextValue = {\n config: BackofficeResolvedListFacetConfig;\n state: BackofficeListState<Record<string, unknown>, string>;\n pushState: (\n next: BackofficeListState<Record<string, unknown>, string>,\n ) => void;\n applyFilter: (\n whereKey: string,\n value: unknown,\n path?: readonly string[],\n ) => void;\n buildFilterLink: (\n whereKey: string,\n value: unknown,\n path?: readonly string[],\n ) => { pathname: string; search: string };\n};\n\nconst BackofficeListFilterContext =\n createContext<BackofficeListFilterContextValue | null>(null);\n\ntype ProviderProps<\n Where extends Record<string, unknown>,\n Sort extends string,\n> = {\n config: BackofficeResolvedListFacetConfig<Where, Sort>;\n state: BackofficeListState<Where, Sort>;\n pushState: (next: BackofficeListState<Where, Sort>) => void;\n children: ReactNode;\n};\n\nexport const BackofficeListFilterProvider = <\n Where extends Record<string, unknown>,\n Sort extends string,\n>(\n props: ProviderProps<Where, Sort>,\n): JSX.Element => {\n const { config, state, pushState, children } = props;\n\n const applyFilter = useCallback(\n (whereKey: string, value: unknown, path?: readonly string[]) => {\n const nextWhere = setWhereValue(\n state.where,\n whereKey as keyof Where,\n value,\n path,\n );\n pushState({ ...state, where: nextWhere });\n },\n [pushState, state],\n );\n\n const buildFilterLink = useCallback(\n (whereKey: string, value: unknown, path?: readonly string[]) => {\n const nextWhere = setWhereValue(\n state.where,\n whereKey as keyof Where,\n value,\n path,\n );\n return buildBackofficeListLink(config, { ...state, where: nextWhere });\n },\n [config, state],\n );\n\n const contextValue = useMemo<BackofficeListFilterContextValue>(() => {\n return {\n config: config as BackofficeResolvedListFacetConfig,\n state: state as unknown as BackofficeListState<\n Record<string, unknown>,\n string\n >,\n pushState: pushState as BackofficeListFilterContextValue['pushState'],\n applyFilter,\n buildFilterLink,\n };\n }, [applyFilter, buildFilterLink, config, pushState, state]);\n\n return (\n <BackofficeListFilterContext.Provider value={contextValue}>\n {children}\n </BackofficeListFilterContext.Provider>\n );\n};\n\nexport const useBackofficeListFilterContext =\n (): BackofficeListFilterContextValue | null => {\n return useContext(BackofficeListFilterContext);\n };\n\nexport default BackofficeListFilterContext;\n","import { Suspense, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { OperationType } from 'relay-runtime';\n\nimport type { BackofficePickerValueConfig } from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficePickerEntityLoader } from '../../../provider/useBackofficeEntityLoader.js';\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\n\nconst { useLazyLoadQuery } = ReactRelay;\n\ntype EntityFilterValueContentProps<RowRef, RowView> = {\n valueConfig: BackofficePickerValueConfig<RowRef, RowView>;\n id: string;\n children: (label: string | null) => JSX.Element;\n};\n\nconst resolveTitle = (value: unknown): string | null => {\n if (value == null || typeof value !== 'object') {\n return null;\n }\n const { title } = value as { title?: unknown };\n if (typeof title !== 'string') {\n return null;\n }\n const trimmed = title.trim();\n if (trimmed === '') {\n return null;\n }\n return trimmed;\n};\n\nconst EntityFilterValueContent = <RowRef, RowView>({\n valueConfig,\n id,\n children,\n}: EntityFilterValueContentProps<RowRef, RowView>): JSX.Element => {\n const data = useLazyLoadQuery<OperationType>(valueConfig.query, { id });\n const rowRef = valueConfig.resolveRow(data);\n let row: RowView | null = null;\n if (rowRef != null) {\n row = valueConfig.toRow(rowRef);\n }\n const title = resolveTitle(row);\n\n return children(title);\n};\n\nexport type EntityFilterValueTextProps = {\n entityId: string;\n id: string;\n children: (label: string | null) => JSX.Element;\n};\n\nexport const EntityFilterValueText = ({\n entityId,\n id,\n children,\n}: EntityFilterValueTextProps): JSX.Element => {\n const resolvedId = id.trim();\n const pickerEntityState = useBackofficePickerEntityLoader(entityId, {\n enabled: resolvedId !== '',\n });\n let valueConfig: BackofficePickerValueConfig<unknown, unknown> | null = null;\n if (pickerEntityState.status === 'loaded') {\n valueConfig = pickerEntityState.module.config.picker.value ?? null;\n }\n\n const fallback = children(null);\n if (valueConfig == null) {\n return fallback;\n }\n\n return (\n <BackofficeErrorBoundary\n fallback={() => {\n return fallback;\n }}\n >\n <Suspense fallback={fallback}>\n <EntityFilterValueContent valueConfig={valueConfig} id={id}>\n {children}\n </EntityFilterValueContent>\n </Suspense>\n </BackofficeErrorBoundary>\n );\n};\n\nexport type EntityFilterValueProps = {\n entityId: string;\n id: string;\n};\n\nexport const EntityFilterValue = ({\n entityId,\n id,\n}: EntityFilterValueProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const resolvedId = id.trim();\n\n return (\n <EntityFilterValueText entityId={entityId} id={id}>\n {(label) => {\n let fallbackLabel = resolvedId;\n if (resolvedId === '') {\n fallbackLabel = t('filters.placeholders.unresolved');\n }\n return <span>{label ?? fallbackLabel}</span>;\n }}\n </EntityFilterValueText>\n );\n};\n\nexport default EntityFilterValue;\n"],"mappings":";;;;;;;;AAkCA,IAAM,IACJ,EAAuD,KAAK,EAYjD,KAIX,MACgB;CAChB,IAAM,EAAE,WAAQ,UAAO,cAAW,gBAAa,GAEzC,IAAc,GACjB,GAAkB,GAAgB,MAA6B;EAC9D,IAAM,IAAY,EAChB,EAAM,OACN,GACA,GACA,EACD;AACD,IAAU;GAAE,GAAG;GAAO,OAAO;GAAW,CAAC;IAE3C,CAAC,GAAW,EAAM,CACnB,EAEK,IAAkB,GACrB,GAAkB,GAAgB,MAA6B;EAC9D,IAAM,IAAY,EAChB,EAAM,OACN,GACA,GACA,EACD;AACD,SAAO,EAAwB,GAAQ;GAAE,GAAG;GAAO,OAAO;GAAW,CAAC;IAExE,CAAC,GAAQ,EAAM,CAChB,EAEK,IAAe,SACZ;EACG;EACD;EAII;EACX;EACA;EACD,GACA;EAAC;EAAa;EAAiB;EAAQ;EAAW;EAAM,CAAC;AAE5D,QACE,kBAAC,EAA4B,UAA7B;EAAsC,OAAO;EAC1C;EACoC,CAAA;GAI9B,UAEF,EAAW,EAA4B,EC7F5C,EAAE,wBAAqB,GAQvB,KAAgB,MAAkC;AACtD,KAAqB,OAAO,KAAU,aAAlC,EACF,QAAO;CAET,IAAM,EAAE,aAAU;AAClB,KAAI,OAAO,KAAU,SACnB,QAAO;CAET,IAAM,IAAU,EAAM,MAAM;AAI5B,QAHI,MAAY,KACP,OAEF;GAGH,KAA6C,EACjD,gBACA,OACA,kBACiE;CACjE,IAAM,IAAO,EAAgC,EAAY,OAAO,EAAE,OAAI,CAAC,EACjE,IAAS,EAAY,WAAW,EAAK,EACvC,IAAsB;AAM1B,QALI,KAAU,SACZ,IAAM,EAAY,MAAM,EAAO,GAI1B,EAFO,EAAa,EAAI,CAET;GASX,KAAyB,EACpC,aACA,OACA,kBAC6C;CAE7C,IAAM,IAAoB,EAAgC,GAAU,EAClE,SAFiB,EAAG,MAAM,KAEF,IACzB,CAAC,EACE,IAAoE;AACxE,CAAI,EAAkB,WAAW,aAC/B,IAAc,EAAkB,OAAO,OAAO,OAAO,SAAS;CAGhE,IAAM,IAAW,EAAS,KAAK;AAK/B,QAJI,KAAe,OACV,IAIP,kBAAC,GAAD;EACE,gBACS;YAGT,kBAAC,GAAD;GAAoB;aAClB,kBAAC,GAAD;IAAuC;IAAiB;IACrD;IACwB,CAAA;GAClB,CAAA;EACa,CAAA;GASjB,KAAqB,EAChC,aACA,YACyC;CACzC,IAAM,EAAE,SAAM,GAA+B,EACvC,IAAa,EAAG,MAAM;AAE5B,QACE,kBAAC,GAAD;EAAiC;EAAc;aAC3C,MAAU;GACV,IAAI,IAAgB;AAIpB,UAHI,MAAe,OACjB,IAAgB,EAAE,kCAAkC,GAE/C,kBAAC,QAAD,EAAA,UAAO,KAAS,GAAqB,CAAA;;EAExB,CAAA"}
@@ -6,7 +6,7 @@ import { BackofficeEmptyState as l, Button as u, Input as d, Modal as f, Spinner
6
6
  import * as m from "react-relay";
7
7
  import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
8
8
  //#region src/components/backoffice/filters/entityIdFilterField.css.ts
9
- var v = "txvbqb9io txvbqbco txvbqbao6 txvbqbu3f txvbqbjdo", y = "txvbqb9mx txvbqbk4x txvbqb9io txvbqbco txvbqbl6f", b = "txvbqb9i6 txvbqbl6f txvbqbt6f txvbqbuw6", x = "txvbqbv8t", S = "txvbqb9io txvbqbco txvbqbanx", C = (e) => {
9
+ var v = "txvbqb9ip txvbqbcp txvbqbao7 txvbqbu4g txvbqbjep", y = "txvbqb9my txvbqbk5y txvbqb9ip txvbqbcp txvbqbl7g", b = "txvbqb9i7 txvbqbl7g txvbqbt7g txvbqbuxg", x = "txvbqbva3", S = "txvbqb9ip txvbqbcp txvbqbany", C = (e) => {
10
10
  let { label: t, value: r, displayValue: i, placeholder: a, onPick: o, onClear: s } = e, { t: c } = n(), l = r?.trim() ?? "", d = i?.trim() ?? "", f = l !== "", p = d !== "", m = a ?? c("filters.placeholders.search", { label: t }), h = c("filters.placeholders.unresolved"), C;
11
11
  C = p ? /* @__PURE__ */ g("span", {
12
12
  className: b,
@@ -170,7 +170,7 @@ var v = "txvbqb9io txvbqbco txvbqbao6 txvbqbu3f txvbqbjdo", y = "txvbqb9mx txvbq
170
170
  n,
171
171
  r
172
172
  ]), c;
173
- }, I = "txvbqb9io txvbqbai6 txvbqbaof", L = "txvbqbnuf txvbqboho txvbqbp5o txvbqblxf txvbqbv8r txvbqb8x txvbqbt5x", R = "txvbqb9io txvbqbao6 txvbqbco", z = "txvbqb9mx txvbqbk4x txvbqb9io txvbqbai6 txvbqbt5o", B = "txvbqbv8p txvbqbamf txvbqb96 txvbqbf3x", V = "txvbqbv8r txvbqb8x txvbqbf3x", H = ({ search: e, onSearchChange: t, searchPlaceholder: r, searchEnabled: i = !0, children: a }) => {
173
+ }, I = "txvbqb9ip txvbqbai7 txvbqbaog", L = "txvbqbnvg txvbqboip txvbqbp6p txvbqblyg txvbqbva1 txvbqb8y txvbqbt6y", R = "txvbqb9ip txvbqbao7 txvbqbcp", z = "txvbqb9my txvbqbk5y txvbqb9ip txvbqbai7 txvbqbt6p", B = "txvbqbv9z txvbqbamg txvbqb97 txvbqbf4y", V = "txvbqbva1 txvbqb8y txvbqbf4y", H = ({ search: e, onSearchChange: t, searchPlaceholder: r, searchEnabled: i = !0, children: a }) => {
174
174
  let { t: o } = n(), s = r ?? o("picker.searchPlaceholder.default"), c = null;
175
175
  return i && (c = /* @__PURE__ */ g(d, {
176
176
  value: e,
@@ -305,4 +305,4 @@ var v = "txvbqb9io txvbqbco txvbqbao6 txvbqbu3f txvbqbjdo", y = "txvbqb9mx txvbq
305
305
  //#endregion
306
306
  export { C as i, F as n, P as r, Q as t };
307
307
 
308
- //# sourceMappingURL=EntityIdPickerDialog-D_qAlrU6.js.map
308
+ //# sourceMappingURL=EntityIdPickerDialog-DbTnDU4v.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EntityIdPickerDialog-D_qAlrU6.js","names":[],"sources":["../../src/components/backoffice/filters/entityIdFilterField.css.ts","../../src/components/backoffice/filters/EntityIdFilterField.tsx","../../src/provider/useBackofficeEntityLoader.ts","../../src/components/backoffice/pickers/entityIdPickerDialog.css.ts","../../src/components/backoffice/pickers/shared/EntityPickerShell.tsx","../../src/components/backoffice/pickers/shared/EntityPickerRowBase.tsx","../../src/components/backoffice/pickers/shared/EntityPickerList.tsx","../../src/components/backoffice/pickers/EntityIdPickerDialog.tsx"],"sourcesContent":["import { sprinkles } from '@plumile/ui';\n\nexport const container = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n width: 72,\n maxWidth: 'full',\n});\n\nexport const valueBox = sprinkles({\n flex: 1,\n minWidth: 0,\n display: 'flex',\n alignItems: 'center',\n overflow: 'hidden',\n});\n\nexport const valueText = sprinkles({\n display: 'block',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\nexport const placeholder = sprinkles({\n color: 'textMuted',\n});\n\nexport const actions = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n});\n","import { type JSX } from 'react';\n\nimport { Button } from '@plumile/ui';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\n\nimport * as styles from './entityIdFilterField.css.js';\n\nexport type EntityIdFilterFieldProps = {\n label: string;\n value: string | null;\n displayValue?: string | null;\n placeholder?: string;\n onPick?: () => void;\n onClear?: () => void;\n};\n\nexport const EntityIdFilterField = (\n props: EntityIdFilterFieldProps,\n): JSX.Element => {\n const { label, value, displayValue, placeholder, onPick, onClear } = props;\n const { t } = useBackofficeReactTranslation();\n const normalizedValue = value?.trim() ?? '';\n const normalizedDisplayValue = displayValue?.trim() ?? '';\n const hasValue = normalizedValue !== '';\n const hasDisplayValue = normalizedDisplayValue !== '';\n\n const resolvedPlaceholder =\n placeholder ?? t('filters.placeholders.search', { label });\n const unresolvedPlaceholder = t('filters.placeholders.unresolved');\n\n let displayNode: JSX.Element;\n if (hasDisplayValue) {\n displayNode = (\n <span className={styles.valueText}>{normalizedDisplayValue}</span>\n );\n } else if (hasValue) {\n displayNode = (\n <span className={styles.placeholder}>{unresolvedPlaceholder}</span>\n );\n } else {\n displayNode = (\n <span className={styles.placeholder}>{resolvedPlaceholder}</span>\n );\n }\n\n let pickLabel = t('common.actions.pick');\n if (hasValue) {\n pickLabel = t('common.actions.change');\n }\n\n let clearNode: JSX.Element | null = null;\n if (hasValue && onClear != null) {\n clearNode = (\n <Button\n type=\"button\"\n variant=\"text\"\n size=\"small\"\n aria-label={t('common.actions.clear')}\n onClick={onClear}\n >\n {t('common.actions.clear')}\n </Button>\n );\n }\n\n let pickerNode: JSX.Element | null = null;\n if (onPick != null) {\n pickerNode = (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n aria-label={t('common.actions.pick')}\n onClick={onPick}\n >\n {pickLabel}\n </Button>\n );\n }\n\n return (\n <div className={styles.container}>\n <div className={styles.valueBox}>{displayNode}</div>\n <div className={styles.actions}>\n {pickerNode}\n {clearNode}\n </div>\n </div>\n );\n};\n\nexport default EntityIdFilterField;\n","import { useEffect, useMemo, useState } from 'react';\n\nimport type {\n BackofficeResolvedListFacetModule,\n BackofficeResolvedPickerFacetModule,\n BackofficeResolvedToolFacetModule,\n} from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeConfig } from './BackofficeConfigContext.js';\n\ntype LoadState<TModule> =\n | {\n status: 'loading';\n module: null;\n error: null;\n }\n | {\n status: 'loaded';\n module: TModule;\n error: null;\n }\n | {\n status: 'error';\n module: null;\n error: Error;\n };\n\ntype MultiLoadState<TModule> =\n | {\n status: 'loading';\n modules: Record<string, TModule>;\n error: null;\n }\n | {\n status: 'loaded';\n modules: Record<string, TModule>;\n error: null;\n }\n | {\n status: 'error';\n modules: Record<string, TModule>;\n error: Error;\n };\n\nconst toError = (error: unknown): Error => {\n if (error instanceof Error) {\n return error;\n }\n return new Error(String(error));\n};\n\nconst buildSortedEntityIds = (\n entityIds: readonly string[],\n): readonly string[] => {\n return [...new Set(entityIds)].sort();\n};\n\nconst createMultiLoadState = <TModule>(\n status: 'loading' | 'loaded',\n modules: Record<string, TModule>,\n): MultiLoadState<TModule> => {\n return {\n status,\n modules,\n error: null,\n };\n};\n\nconst areErrorsEqual = (left: Error | null, right: Error | null): boolean => {\n if (left === right) {\n return true;\n }\n if (left == null || right == null) {\n return false;\n }\n return left.name === right.name && left.message === right.message;\n};\n\nconst areModuleMapsEqual = <TModule>(\n left: Record<string, TModule>,\n right: Record<string, TModule>,\n): boolean => {\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n\n if (leftKeys.length !== rightKeys.length) {\n return false;\n }\n\n for (const key of leftKeys) {\n if (!(key in right) || left[key] !== right[key]) {\n return false;\n }\n }\n\n return true;\n};\n\nconst areLoadStatesEqual = <TModule>(\n left: LoadState<TModule>,\n right: LoadState<TModule>,\n): boolean => {\n if (left.status !== right.status) {\n return false;\n }\n\n if (left.module !== right.module) {\n return false;\n }\n\n return areErrorsEqual(left.error, right.error);\n};\n\nconst areMultiLoadStatesEqual = <TModule>(\n left: MultiLoadState<TModule>,\n right: MultiLoadState<TModule>,\n): boolean => {\n if (left.status !== right.status) {\n return false;\n }\n\n if (!areModuleMapsEqual(left.modules, right.modules)) {\n return false;\n }\n\n return areErrorsEqual(left.error, right.error);\n};\n\nconst selectLoadState = <TModule>(\n currentState: LoadState<TModule>,\n nextState: LoadState<TModule>,\n): LoadState<TModule> => {\n if (areLoadStatesEqual(currentState, nextState)) {\n return currentState;\n }\n return nextState;\n};\n\nconst selectMultiLoadState = <TModule>(\n currentState: MultiLoadState<TModule>,\n nextState: MultiLoadState<TModule>,\n): MultiLoadState<TModule> => {\n if (areMultiLoadStatesEqual(currentState, nextState)) {\n return currentState;\n }\n return nextState;\n};\n\nconst useFacetLoader = <TModule>(\n entityId: string,\n getLoaded: (entityId: string) => TModule | null,\n load: (entityId: string) => Promise<TModule>,\n enabled = true,\n): LoadState<TModule> => {\n const initialModule = getLoaded(entityId);\n const [state, setState] = useState<LoadState<TModule>>(() => {\n if (initialModule != null) {\n return {\n status: 'loaded',\n module: initialModule,\n error: null,\n };\n }\n return {\n status: 'loading',\n module: null,\n error: null,\n };\n });\n\n useEffect(() => {\n if (!enabled) {\n const loadedModule = getLoaded(entityId);\n setState((currentState) => {\n let nextState: LoadState<TModule>;\n\n if (loadedModule != null) {\n nextState = {\n status: 'loaded',\n module: loadedModule,\n error: null,\n };\n } else {\n nextState = {\n status: 'loading',\n module: null,\n error: null,\n };\n }\n\n return selectLoadState(currentState, nextState);\n });\n return undefined;\n }\n\n const loadedModule = getLoaded(entityId);\n if (loadedModule != null) {\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'loaded',\n module: loadedModule,\n error: null,\n };\n return selectLoadState(currentState, nextState);\n });\n return undefined;\n }\n\n let cancelled = false;\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'loading',\n module: null,\n error: null,\n };\n return selectLoadState(currentState, nextState);\n });\n\n load(entityId)\n .then((module) => {\n if (cancelled) {\n return;\n }\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'loaded',\n module,\n error: null,\n };\n return selectLoadState(currentState, nextState);\n });\n })\n .catch((error: unknown) => {\n if (cancelled) {\n return;\n }\n const nextError = toError(error);\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'error',\n module: null,\n error: nextError,\n };\n return selectLoadState(currentState, nextState);\n });\n });\n\n return () => {\n cancelled = true;\n };\n }, [enabled, entityId, getLoaded, load]);\n\n return state;\n};\n\nexport const useBackofficeListEntityLoader = (\n entityId: string,\n options?: { enabled?: boolean },\n): LoadState<BackofficeResolvedListFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n return useFacetLoader(\n entityId,\n entityRegistry.getLoadedListEntity,\n entityRegistry.loadListEntity,\n options?.enabled,\n );\n};\n\nexport const useBackofficePickerEntityLoader = (\n entityId: string,\n options?: { enabled?: boolean },\n): LoadState<BackofficeResolvedPickerFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n return useFacetLoader(\n entityId,\n entityRegistry.getLoadedPickerEntity,\n entityRegistry.loadPickerEntity,\n options?.enabled,\n );\n};\n\nexport const useBackofficeToolEntityLoader = (\n entityId: string,\n options?: { enabled?: boolean },\n): LoadState<BackofficeResolvedToolFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n return useFacetLoader(\n entityId,\n entityRegistry.getLoadedToolEntity,\n entityRegistry.loadToolEntity,\n options?.enabled,\n );\n};\n\nexport const useBackofficeListEntitiesLoader = (\n entityIds: readonly string[],\n): MultiLoadState<BackofficeResolvedListFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n const normalizedEntityIds = useMemo(() => {\n return buildSortedEntityIds(entityIds);\n }, [entityIds]);\n const entityIdsKey = normalizedEntityIds.join('|');\n const [state, setState] = useState<\n MultiLoadState<BackofficeResolvedListFacetModule>\n >(() => {\n const modules: Record<string, BackofficeResolvedListFacetModule> = {};\n let isComplete = true;\n\n for (const entityId of normalizedEntityIds) {\n const module = entityRegistry.getLoadedListEntity(entityId);\n if (module == null) {\n isComplete = false;\n } else {\n modules[entityId] = module;\n }\n }\n\n if (isComplete) {\n return createMultiLoadState('loaded', modules);\n }\n return createMultiLoadState('loading', modules);\n });\n\n useEffect(() => {\n const modules: Record<string, BackofficeResolvedListFacetModule> = {};\n let isComplete = true;\n\n for (const entityId of normalizedEntityIds) {\n const module = entityRegistry.getLoadedListEntity(entityId);\n if (module == null) {\n isComplete = false;\n } else {\n modules[entityId] = module;\n }\n }\n\n if (isComplete) {\n const nextState = createMultiLoadState('loaded', modules);\n setState((currentState) => {\n return selectMultiLoadState(currentState, nextState);\n });\n return undefined;\n }\n\n let cancelled = false;\n setState((currentState) => {\n const nextState: MultiLoadState<BackofficeResolvedListFacetModule> = {\n status: 'loading',\n modules,\n error: null,\n };\n return selectMultiLoadState(currentState, nextState);\n });\n\n Promise.all(\n normalizedEntityIds.map(async (entityId) => {\n const module = await entityRegistry.loadListEntity(entityId);\n return [entityId, module] as const;\n }),\n )\n .then((entries) => {\n if (cancelled) {\n return;\n }\n setState((currentState) => {\n const nextState: MultiLoadState<BackofficeResolvedListFacetModule> = {\n status: 'loaded',\n modules: Object.fromEntries(entries),\n error: null,\n };\n return selectMultiLoadState(currentState, nextState);\n });\n })\n .catch((error: unknown) => {\n if (cancelled) {\n return;\n }\n const nextError = toError(error);\n setState((currentState) => {\n const nextState: MultiLoadState<BackofficeResolvedListFacetModule> = {\n status: 'error',\n modules,\n error: nextError,\n };\n return selectMultiLoadState(currentState, nextState);\n });\n });\n\n return () => {\n cancelled = true;\n };\n }, [entityIdsKey, entityRegistry, normalizedEntityIds]);\n\n return state;\n};\n","import { sprinkles } from '@plumile/ui';\n\nexport const layout = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n});\n\nexport const searchRequiredMessage = sprinkles({\n color: 'textSecondary',\n fontSize: 'sm',\n textAlign: 'center',\n paddingY: 3,\n paddingX: 0,\n});\n\nexport const row = sprinkles({\n display: 'flex',\n gap: 2,\n alignItems: 'center',\n});\n\nexport const rowText = sprinkles({\n flex: 1,\n minWidth: 0,\n display: 'flex',\n flexDirection: 'column',\n textAlign: 'left',\n});\n\nexport const rowTitle = sprinkles({\n color: 'text',\n fontWeight: 'medium',\n fontSize: 'base',\n lineHeight: 1.2,\n});\n\nexport const rowSubtitle = sprinkles({\n color: 'textSecondary',\n fontSize: 'sm',\n lineHeight: 1.2,\n});\n\nexport const rowMeta = sprinkles({\n color: 'textMuted',\n fontSize: 'xs',\n lineHeight: 1.2,\n whiteSpace: 'nowrap',\n});\n","import { type JSX, type ReactNode } from 'react';\n\nimport { Input } from '@plumile/ui';\n\nimport { useBackofficeReactTranslation } from '../../../../i18n/useBackofficeReactTranslation.js';\n\nimport * as styles from '../entityIdPickerDialog.css.js';\n\nexport type EntityPickerShellProps = {\n search: string;\n onSearchChange: (next: string) => void;\n searchPlaceholder?: string;\n searchEnabled?: boolean;\n children: ReactNode;\n};\n\nexport const EntityPickerShell = ({\n search,\n onSearchChange,\n searchPlaceholder,\n searchEnabled = true,\n children,\n}: EntityPickerShellProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const resolvedPlaceholder =\n searchPlaceholder ?? t('picker.searchPlaceholder.default');\n let searchNode: JSX.Element | null = null;\n if (searchEnabled) {\n searchNode = (\n <Input\n value={search}\n onChange={(event) => {\n onSearchChange(event.target.value);\n }}\n placeholder={resolvedPlaceholder}\n size=\"small\"\n fullWidth\n />\n );\n }\n\n return (\n <div className={styles.layout}>\n {searchNode}\n {children}\n </div>\n );\n};\n\nexport default EntityPickerShell;\n","import { type JSX, type ReactNode } from 'react';\n\nimport * as styles from '../entityIdPickerDialog.css.js';\n\nexport type EntityPickerRowBaseProps = {\n title: ReactNode;\n subtitle?: ReactNode;\n};\n\nexport const EntityPickerRowBase = ({\n title,\n subtitle,\n}: EntityPickerRowBaseProps): JSX.Element => {\n let subtitleNode: ReactNode | null = null;\n if (subtitle != null) {\n subtitleNode = <div className={styles.rowSubtitle}>{subtitle}</div>;\n }\n\n return (\n <div className={styles.row}>\n <div className={styles.rowText}>\n <div className={styles.rowTitle}>{title}</div>\n {subtitleNode}\n </div>\n </div>\n );\n};\n\nexport default EntityPickerRowBase;\n","import { type JSX } from 'react';\n\nimport { BackofficeEmptyState, Button } from '@plumile/ui';\n\nimport { EntityPickerRowBase } from './EntityPickerRowBase.js';\nimport type { EntityPickerRowViewModel } from '../types.js';\n\nexport type EntityPickerListProps = {\n items: readonly EntityPickerRowViewModel[];\n onSelectId: (id: string) => void;\n emptyState?: JSX.Element;\n};\n\nexport const EntityPickerList = ({\n items,\n onSelectId,\n emptyState,\n}: EntityPickerListProps): JSX.Element => {\n if (items.length === 0) {\n return (\n emptyState ?? (\n <BackofficeEmptyState\n title=\"No result\"\n description=\"Try another search term.\"\n />\n )\n );\n }\n\n return (\n <div>\n {items.map((item) => {\n return (\n <Button\n key={item.id}\n type=\"button\"\n variant=\"text\"\n onClick={() => {\n onSelectId(item.id);\n }}\n width=\"full\"\n >\n <EntityPickerRowBase title={item.title} subtitle={item.subtitle} />\n </Button>\n );\n })}\n </div>\n );\n};\n\nexport default EntityPickerList;\n","import {\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n type JSX,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\n\nimport { Button, Modal, Spinner } from '@plumile/ui';\nimport type {\n BackofficeEntityPickerConfig,\n BackofficePickerScope,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficePickerEntityLoader } from '../../../provider/useBackofficeEntityLoader.js';\n\nimport { EntityPickerShell } from './shared/EntityPickerShell.js';\nimport { EntityPickerList } from './shared/EntityPickerList.js';\nimport type { EntityPickerRowViewModel } from './types.js';\nimport * as styles from './entityIdPickerDialog.css.js';\n\nconst { useFragment, useLazyLoadQuery } = ReactRelay;\n\nexport type EntityIdPickerDialogProps = {\n isOpen: boolean;\n entity: string;\n title: string;\n scope?: BackofficePickerScope;\n onClose: () => void;\n onSelectId: (id: string) => void;\n};\n\nconst PICKER_FETCH_POLICY = 'store-and-network' as const;\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\ntype PickerBodyProps<RowRef, RowView extends EntityPickerRowViewModel> = {\n config: BackofficeEntityPickerConfig<RowRef, RowView>;\n search: string;\n scope?: BackofficePickerScope;\n fetchKey: number;\n onSelectId: (id: string) => void;\n};\n\nconst PickerBody = <RowRef, RowView extends EntityPickerRowViewModel>({\n config,\n search,\n scope,\n fetchKey,\n onSelectId,\n}: PickerBodyProps<RowRef, RowView>): JSX.Element => {\n const variables = useMemo(() => {\n const trimmed = search.trim();\n if (config.buildVariables != null) {\n return config.buildVariables({ search: trimmed, scope });\n }\n let searchValue: string | null = trimmed;\n if (trimmed === '') {\n searchValue = null;\n }\n return {\n search: searchValue,\n scope,\n } as Record<string, unknown>;\n }, [config, scope, search]);\n\n const queryData = useLazyLoadQuery(config.query, variables, {\n fetchPolicy: PICKER_FETCH_POLICY,\n fetchKey,\n });\n\n const fragmentData = useFragment(\n config.fragment,\n queryData as never,\n ) as unknown;\n\n const connection = config.getConnection(fragmentData as never);\n\n const items = useMemo<readonly EntityPickerRowViewModel[]>(() => {\n return connection.edges.map((edge) => {\n const row = config.toRow(edge.node);\n const id = config.getRowId(row);\n return {\n id,\n title: row.title,\n subtitle: row.subtitle,\n };\n });\n }, [config, connection.edges]);\n\n return <EntityPickerList items={items} onSelectId={onSelectId} />;\n};\n\nconst buildFooter = (onClose: () => void, closeLabel: string): JSX.Element => {\n return (\n <>\n <Button type=\"button\" variant=\"secondary\" onClick={onClose}>\n {closeLabel}\n </Button>\n </>\n );\n};\n\nconst PickerUnavailable = ({ message }: { message: string }) => {\n return <div>{message}</div>;\n};\n\nexport const EntityIdPickerDialog = ({\n isOpen,\n entity,\n title,\n scope,\n onClose,\n onSelectId,\n}: EntityIdPickerDialogProps): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const [search, setSearch] = useState('');\n const [fetchKey, setFetchKey] = useState(0);\n const entityState = useBackofficePickerEntityLoader(entity, {\n enabled: isOpen,\n });\n\n let pickerConfig:\n | BackofficeEntityPickerConfig<unknown, EntityPickerRowViewModel>\n | undefined;\n if (entityState.status === 'loaded') {\n pickerConfig = entityState.module.config.picker as\n | BackofficeEntityPickerConfig<unknown, EntityPickerRowViewModel>\n | undefined;\n }\n\n useEffect(() => {\n if (isOpen) {\n setSearch('');\n setFetchKey((value) => {\n return value + 1;\n });\n }\n }, [isOpen]);\n\n const footer = useMemo(() => {\n return buildFooter(onClose, t('common.actions.close'));\n }, [onClose, t]);\n\n const handleSearchChange = useCallback((next: string) => {\n setSearch(next);\n setFetchKey((value) => {\n return value + 1;\n });\n }, []);\n\n const handleSelectId = useCallback(\n (id: string) => {\n onSelectId(id);\n onClose();\n },\n [onClose, onSelectId],\n );\n\n if (!isOpen) {\n return null;\n }\n\n let resolvedSearchPlaceholder: string | undefined;\n if (pickerConfig?.searchPlaceholder != null) {\n resolvedSearchPlaceholder = resolveLabel(\n pickerConfig.searchPlaceholder,\n tApp,\n );\n }\n\n const trimmedSearch = search.trim();\n const isSearchRequired = pickerConfig?.searchRequired === true;\n\n let pickerNode: JSX.Element;\n if (entityState.status === 'loading') {\n pickerNode = <Spinner />;\n } else if (pickerConfig != null) {\n if (isSearchRequired && trimmedSearch === '') {\n pickerNode = (\n <div className={styles.searchRequiredMessage}>\n {t('picker.searchRequired')}\n </div>\n );\n } else {\n pickerNode = (\n <PickerBody\n config={pickerConfig}\n search={search}\n scope={scope}\n fetchKey={fetchKey}\n onSelectId={handleSelectId}\n />\n );\n }\n } else {\n pickerNode = (\n <PickerUnavailable message={t('picker.unavailable', { entity })} />\n );\n }\n\n return (\n <Modal isOpen={isOpen} onClose={onClose} title={title} footer={footer}>\n <EntityPickerShell\n search={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={resolvedSearchPlaceholder}\n searchEnabled={pickerConfig?.searchEnabled ?? true}\n >\n <BackofficeErrorBoundary\n fallback={(args: { error: unknown; reset: () => void }) => {\n const { reset } = args;\n return (\n <div>\n <div>{t('picker.errors.loadFailed')}</div>\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n reset();\n setFetchKey((value) => {\n return value + 1;\n });\n }}\n >\n {t('common.actions.retry')}\n </Button>\n </div>\n );\n }}\n >\n <Suspense fallback={<Spinner />}>{pickerNode}</Suspense>\n </BackofficeErrorBoundary>\n </EntityPickerShell>\n </Modal>\n );\n};\n\nexport type { BackofficePickerScope } from '@plumile/backoffice-core/types.js';\n\nexport default EntityIdPickerDialog;\n"],"mappings":"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"}
1
+ {"version":3,"file":"EntityIdPickerDialog-DbTnDU4v.js","names":[],"sources":["../../src/components/backoffice/filters/entityIdFilterField.css.ts","../../src/components/backoffice/filters/EntityIdFilterField.tsx","../../src/provider/useBackofficeEntityLoader.ts","../../src/components/backoffice/pickers/entityIdPickerDialog.css.ts","../../src/components/backoffice/pickers/shared/EntityPickerShell.tsx","../../src/components/backoffice/pickers/shared/EntityPickerRowBase.tsx","../../src/components/backoffice/pickers/shared/EntityPickerList.tsx","../../src/components/backoffice/pickers/EntityIdPickerDialog.tsx"],"sourcesContent":["import { sprinkles } from '@plumile/ui';\n\nexport const container = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 2,\n width: 72,\n maxWidth: 'full',\n});\n\nexport const valueBox = sprinkles({\n flex: 1,\n minWidth: 0,\n display: 'flex',\n alignItems: 'center',\n overflow: 'hidden',\n});\n\nexport const valueText = sprinkles({\n display: 'block',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\nexport const placeholder = sprinkles({\n color: 'textMuted',\n});\n\nexport const actions = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n});\n","import { type JSX } from 'react';\n\nimport { Button } from '@plumile/ui';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\n\nimport * as styles from './entityIdFilterField.css.js';\n\nexport type EntityIdFilterFieldProps = {\n label: string;\n value: string | null;\n displayValue?: string | null;\n placeholder?: string;\n onPick?: () => void;\n onClear?: () => void;\n};\n\nexport const EntityIdFilterField = (\n props: EntityIdFilterFieldProps,\n): JSX.Element => {\n const { label, value, displayValue, placeholder, onPick, onClear } = props;\n const { t } = useBackofficeReactTranslation();\n const normalizedValue = value?.trim() ?? '';\n const normalizedDisplayValue = displayValue?.trim() ?? '';\n const hasValue = normalizedValue !== '';\n const hasDisplayValue = normalizedDisplayValue !== '';\n\n const resolvedPlaceholder =\n placeholder ?? t('filters.placeholders.search', { label });\n const unresolvedPlaceholder = t('filters.placeholders.unresolved');\n\n let displayNode: JSX.Element;\n if (hasDisplayValue) {\n displayNode = (\n <span className={styles.valueText}>{normalizedDisplayValue}</span>\n );\n } else if (hasValue) {\n displayNode = (\n <span className={styles.placeholder}>{unresolvedPlaceholder}</span>\n );\n } else {\n displayNode = (\n <span className={styles.placeholder}>{resolvedPlaceholder}</span>\n );\n }\n\n let pickLabel = t('common.actions.pick');\n if (hasValue) {\n pickLabel = t('common.actions.change');\n }\n\n let clearNode: JSX.Element | null = null;\n if (hasValue && onClear != null) {\n clearNode = (\n <Button\n type=\"button\"\n variant=\"text\"\n size=\"small\"\n aria-label={t('common.actions.clear')}\n onClick={onClear}\n >\n {t('common.actions.clear')}\n </Button>\n );\n }\n\n let pickerNode: JSX.Element | null = null;\n if (onPick != null) {\n pickerNode = (\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n aria-label={t('common.actions.pick')}\n onClick={onPick}\n >\n {pickLabel}\n </Button>\n );\n }\n\n return (\n <div className={styles.container}>\n <div className={styles.valueBox}>{displayNode}</div>\n <div className={styles.actions}>\n {pickerNode}\n {clearNode}\n </div>\n </div>\n );\n};\n\nexport default EntityIdFilterField;\n","import { useEffect, useMemo, useState } from 'react';\n\nimport type {\n BackofficeResolvedListFacetModule,\n BackofficeResolvedPickerFacetModule,\n BackofficeResolvedToolFacetModule,\n} from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeConfig } from './BackofficeConfigContext.js';\n\ntype LoadState<TModule> =\n | {\n status: 'loading';\n module: null;\n error: null;\n }\n | {\n status: 'loaded';\n module: TModule;\n error: null;\n }\n | {\n status: 'error';\n module: null;\n error: Error;\n };\n\ntype MultiLoadState<TModule> =\n | {\n status: 'loading';\n modules: Record<string, TModule>;\n error: null;\n }\n | {\n status: 'loaded';\n modules: Record<string, TModule>;\n error: null;\n }\n | {\n status: 'error';\n modules: Record<string, TModule>;\n error: Error;\n };\n\nconst toError = (error: unknown): Error => {\n if (error instanceof Error) {\n return error;\n }\n return new Error(String(error));\n};\n\nconst buildSortedEntityIds = (\n entityIds: readonly string[],\n): readonly string[] => {\n return [...new Set(entityIds)].sort();\n};\n\nconst createMultiLoadState = <TModule>(\n status: 'loading' | 'loaded',\n modules: Record<string, TModule>,\n): MultiLoadState<TModule> => {\n return {\n status,\n modules,\n error: null,\n };\n};\n\nconst areErrorsEqual = (left: Error | null, right: Error | null): boolean => {\n if (left === right) {\n return true;\n }\n if (left == null || right == null) {\n return false;\n }\n return left.name === right.name && left.message === right.message;\n};\n\nconst areModuleMapsEqual = <TModule>(\n left: Record<string, TModule>,\n right: Record<string, TModule>,\n): boolean => {\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n\n if (leftKeys.length !== rightKeys.length) {\n return false;\n }\n\n for (const key of leftKeys) {\n if (!(key in right) || left[key] !== right[key]) {\n return false;\n }\n }\n\n return true;\n};\n\nconst areLoadStatesEqual = <TModule>(\n left: LoadState<TModule>,\n right: LoadState<TModule>,\n): boolean => {\n if (left.status !== right.status) {\n return false;\n }\n\n if (left.module !== right.module) {\n return false;\n }\n\n return areErrorsEqual(left.error, right.error);\n};\n\nconst areMultiLoadStatesEqual = <TModule>(\n left: MultiLoadState<TModule>,\n right: MultiLoadState<TModule>,\n): boolean => {\n if (left.status !== right.status) {\n return false;\n }\n\n if (!areModuleMapsEqual(left.modules, right.modules)) {\n return false;\n }\n\n return areErrorsEqual(left.error, right.error);\n};\n\nconst selectLoadState = <TModule>(\n currentState: LoadState<TModule>,\n nextState: LoadState<TModule>,\n): LoadState<TModule> => {\n if (areLoadStatesEqual(currentState, nextState)) {\n return currentState;\n }\n return nextState;\n};\n\nconst selectMultiLoadState = <TModule>(\n currentState: MultiLoadState<TModule>,\n nextState: MultiLoadState<TModule>,\n): MultiLoadState<TModule> => {\n if (areMultiLoadStatesEqual(currentState, nextState)) {\n return currentState;\n }\n return nextState;\n};\n\nconst useFacetLoader = <TModule>(\n entityId: string,\n getLoaded: (entityId: string) => TModule | null,\n load: (entityId: string) => Promise<TModule>,\n enabled = true,\n): LoadState<TModule> => {\n const initialModule = getLoaded(entityId);\n const [state, setState] = useState<LoadState<TModule>>(() => {\n if (initialModule != null) {\n return {\n status: 'loaded',\n module: initialModule,\n error: null,\n };\n }\n return {\n status: 'loading',\n module: null,\n error: null,\n };\n });\n\n useEffect(() => {\n if (!enabled) {\n const loadedModule = getLoaded(entityId);\n setState((currentState) => {\n let nextState: LoadState<TModule>;\n\n if (loadedModule != null) {\n nextState = {\n status: 'loaded',\n module: loadedModule,\n error: null,\n };\n } else {\n nextState = {\n status: 'loading',\n module: null,\n error: null,\n };\n }\n\n return selectLoadState(currentState, nextState);\n });\n return undefined;\n }\n\n const loadedModule = getLoaded(entityId);\n if (loadedModule != null) {\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'loaded',\n module: loadedModule,\n error: null,\n };\n return selectLoadState(currentState, nextState);\n });\n return undefined;\n }\n\n let cancelled = false;\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'loading',\n module: null,\n error: null,\n };\n return selectLoadState(currentState, nextState);\n });\n\n load(entityId)\n .then((module) => {\n if (cancelled) {\n return;\n }\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'loaded',\n module,\n error: null,\n };\n return selectLoadState(currentState, nextState);\n });\n })\n .catch((error: unknown) => {\n if (cancelled) {\n return;\n }\n const nextError = toError(error);\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'error',\n module: null,\n error: nextError,\n };\n return selectLoadState(currentState, nextState);\n });\n });\n\n return () => {\n cancelled = true;\n };\n }, [enabled, entityId, getLoaded, load]);\n\n return state;\n};\n\nexport const useBackofficeListEntityLoader = (\n entityId: string,\n options?: { enabled?: boolean },\n): LoadState<BackofficeResolvedListFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n return useFacetLoader(\n entityId,\n entityRegistry.getLoadedListEntity,\n entityRegistry.loadListEntity,\n options?.enabled,\n );\n};\n\nexport const useBackofficePickerEntityLoader = (\n entityId: string,\n options?: { enabled?: boolean },\n): LoadState<BackofficeResolvedPickerFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n return useFacetLoader(\n entityId,\n entityRegistry.getLoadedPickerEntity,\n entityRegistry.loadPickerEntity,\n options?.enabled,\n );\n};\n\nexport const useBackofficeToolEntityLoader = (\n entityId: string,\n options?: { enabled?: boolean },\n): LoadState<BackofficeResolvedToolFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n return useFacetLoader(\n entityId,\n entityRegistry.getLoadedToolEntity,\n entityRegistry.loadToolEntity,\n options?.enabled,\n );\n};\n\nexport const useBackofficeListEntitiesLoader = (\n entityIds: readonly string[],\n): MultiLoadState<BackofficeResolvedListFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n const normalizedEntityIds = useMemo(() => {\n return buildSortedEntityIds(entityIds);\n }, [entityIds]);\n const entityIdsKey = normalizedEntityIds.join('|');\n const [state, setState] = useState<\n MultiLoadState<BackofficeResolvedListFacetModule>\n >(() => {\n const modules: Record<string, BackofficeResolvedListFacetModule> = {};\n let isComplete = true;\n\n for (const entityId of normalizedEntityIds) {\n const module = entityRegistry.getLoadedListEntity(entityId);\n if (module == null) {\n isComplete = false;\n } else {\n modules[entityId] = module;\n }\n }\n\n if (isComplete) {\n return createMultiLoadState('loaded', modules);\n }\n return createMultiLoadState('loading', modules);\n });\n\n useEffect(() => {\n const modules: Record<string, BackofficeResolvedListFacetModule> = {};\n let isComplete = true;\n\n for (const entityId of normalizedEntityIds) {\n const module = entityRegistry.getLoadedListEntity(entityId);\n if (module == null) {\n isComplete = false;\n } else {\n modules[entityId] = module;\n }\n }\n\n if (isComplete) {\n const nextState = createMultiLoadState('loaded', modules);\n setState((currentState) => {\n return selectMultiLoadState(currentState, nextState);\n });\n return undefined;\n }\n\n let cancelled = false;\n setState((currentState) => {\n const nextState: MultiLoadState<BackofficeResolvedListFacetModule> = {\n status: 'loading',\n modules,\n error: null,\n };\n return selectMultiLoadState(currentState, nextState);\n });\n\n Promise.all(\n normalizedEntityIds.map(async (entityId) => {\n const module = await entityRegistry.loadListEntity(entityId);\n return [entityId, module] as const;\n }),\n )\n .then((entries) => {\n if (cancelled) {\n return;\n }\n setState((currentState) => {\n const nextState: MultiLoadState<BackofficeResolvedListFacetModule> = {\n status: 'loaded',\n modules: Object.fromEntries(entries),\n error: null,\n };\n return selectMultiLoadState(currentState, nextState);\n });\n })\n .catch((error: unknown) => {\n if (cancelled) {\n return;\n }\n const nextError = toError(error);\n setState((currentState) => {\n const nextState: MultiLoadState<BackofficeResolvedListFacetModule> = {\n status: 'error',\n modules,\n error: nextError,\n };\n return selectMultiLoadState(currentState, nextState);\n });\n });\n\n return () => {\n cancelled = true;\n };\n }, [entityIdsKey, entityRegistry, normalizedEntityIds]);\n\n return state;\n};\n","import { sprinkles } from '@plumile/ui';\n\nexport const layout = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n});\n\nexport const searchRequiredMessage = sprinkles({\n color: 'textSecondary',\n fontSize: 'sm',\n textAlign: 'center',\n paddingY: 3,\n paddingX: 0,\n});\n\nexport const row = sprinkles({\n display: 'flex',\n gap: 2,\n alignItems: 'center',\n});\n\nexport const rowText = sprinkles({\n flex: 1,\n minWidth: 0,\n display: 'flex',\n flexDirection: 'column',\n textAlign: 'left',\n});\n\nexport const rowTitle = sprinkles({\n color: 'text',\n fontWeight: 'medium',\n fontSize: 'base',\n lineHeight: 1.2,\n});\n\nexport const rowSubtitle = sprinkles({\n color: 'textSecondary',\n fontSize: 'sm',\n lineHeight: 1.2,\n});\n\nexport const rowMeta = sprinkles({\n color: 'textMuted',\n fontSize: 'xs',\n lineHeight: 1.2,\n whiteSpace: 'nowrap',\n});\n","import { type JSX, type ReactNode } from 'react';\n\nimport { Input } from '@plumile/ui';\n\nimport { useBackofficeReactTranslation } from '../../../../i18n/useBackofficeReactTranslation.js';\n\nimport * as styles from '../entityIdPickerDialog.css.js';\n\nexport type EntityPickerShellProps = {\n search: string;\n onSearchChange: (next: string) => void;\n searchPlaceholder?: string;\n searchEnabled?: boolean;\n children: ReactNode;\n};\n\nexport const EntityPickerShell = ({\n search,\n onSearchChange,\n searchPlaceholder,\n searchEnabled = true,\n children,\n}: EntityPickerShellProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const resolvedPlaceholder =\n searchPlaceholder ?? t('picker.searchPlaceholder.default');\n let searchNode: JSX.Element | null = null;\n if (searchEnabled) {\n searchNode = (\n <Input\n value={search}\n onChange={(event) => {\n onSearchChange(event.target.value);\n }}\n placeholder={resolvedPlaceholder}\n size=\"small\"\n fullWidth\n />\n );\n }\n\n return (\n <div className={styles.layout}>\n {searchNode}\n {children}\n </div>\n );\n};\n\nexport default EntityPickerShell;\n","import { type JSX, type ReactNode } from 'react';\n\nimport * as styles from '../entityIdPickerDialog.css.js';\n\nexport type EntityPickerRowBaseProps = {\n title: ReactNode;\n subtitle?: ReactNode;\n};\n\nexport const EntityPickerRowBase = ({\n title,\n subtitle,\n}: EntityPickerRowBaseProps): JSX.Element => {\n let subtitleNode: ReactNode | null = null;\n if (subtitle != null) {\n subtitleNode = <div className={styles.rowSubtitle}>{subtitle}</div>;\n }\n\n return (\n <div className={styles.row}>\n <div className={styles.rowText}>\n <div className={styles.rowTitle}>{title}</div>\n {subtitleNode}\n </div>\n </div>\n );\n};\n\nexport default EntityPickerRowBase;\n","import { type JSX } from 'react';\n\nimport { BackofficeEmptyState, Button } from '@plumile/ui';\n\nimport { EntityPickerRowBase } from './EntityPickerRowBase.js';\nimport type { EntityPickerRowViewModel } from '../types.js';\n\nexport type EntityPickerListProps = {\n items: readonly EntityPickerRowViewModel[];\n onSelectId: (id: string) => void;\n emptyState?: JSX.Element;\n};\n\nexport const EntityPickerList = ({\n items,\n onSelectId,\n emptyState,\n}: EntityPickerListProps): JSX.Element => {\n if (items.length === 0) {\n return (\n emptyState ?? (\n <BackofficeEmptyState\n title=\"No result\"\n description=\"Try another search term.\"\n />\n )\n );\n }\n\n return (\n <div>\n {items.map((item) => {\n return (\n <Button\n key={item.id}\n type=\"button\"\n variant=\"text\"\n onClick={() => {\n onSelectId(item.id);\n }}\n width=\"full\"\n >\n <EntityPickerRowBase title={item.title} subtitle={item.subtitle} />\n </Button>\n );\n })}\n </div>\n );\n};\n\nexport default EntityPickerList;\n","import {\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n type JSX,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\n\nimport { Button, Modal, Spinner } from '@plumile/ui';\nimport type {\n BackofficeEntityPickerConfig,\n BackofficePickerScope,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficePickerEntityLoader } from '../../../provider/useBackofficeEntityLoader.js';\n\nimport { EntityPickerShell } from './shared/EntityPickerShell.js';\nimport { EntityPickerList } from './shared/EntityPickerList.js';\nimport type { EntityPickerRowViewModel } from './types.js';\nimport * as styles from './entityIdPickerDialog.css.js';\n\nconst { useFragment, useLazyLoadQuery } = ReactRelay;\n\nexport type EntityIdPickerDialogProps = {\n isOpen: boolean;\n entity: string;\n title: string;\n scope?: BackofficePickerScope;\n onClose: () => void;\n onSelectId: (id: string) => void;\n};\n\nconst PICKER_FETCH_POLICY = 'store-and-network' as const;\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\ntype PickerBodyProps<RowRef, RowView extends EntityPickerRowViewModel> = {\n config: BackofficeEntityPickerConfig<RowRef, RowView>;\n search: string;\n scope?: BackofficePickerScope;\n fetchKey: number;\n onSelectId: (id: string) => void;\n};\n\nconst PickerBody = <RowRef, RowView extends EntityPickerRowViewModel>({\n config,\n search,\n scope,\n fetchKey,\n onSelectId,\n}: PickerBodyProps<RowRef, RowView>): JSX.Element => {\n const variables = useMemo(() => {\n const trimmed = search.trim();\n if (config.buildVariables != null) {\n return config.buildVariables({ search: trimmed, scope });\n }\n let searchValue: string | null = trimmed;\n if (trimmed === '') {\n searchValue = null;\n }\n return {\n search: searchValue,\n scope,\n } as Record<string, unknown>;\n }, [config, scope, search]);\n\n const queryData = useLazyLoadQuery(config.query, variables, {\n fetchPolicy: PICKER_FETCH_POLICY,\n fetchKey,\n });\n\n const fragmentData = useFragment(\n config.fragment,\n queryData as never,\n ) as unknown;\n\n const connection = config.getConnection(fragmentData as never);\n\n const items = useMemo<readonly EntityPickerRowViewModel[]>(() => {\n return connection.edges.map((edge) => {\n const row = config.toRow(edge.node);\n const id = config.getRowId(row);\n return {\n id,\n title: row.title,\n subtitle: row.subtitle,\n };\n });\n }, [config, connection.edges]);\n\n return <EntityPickerList items={items} onSelectId={onSelectId} />;\n};\n\nconst buildFooter = (onClose: () => void, closeLabel: string): JSX.Element => {\n return (\n <>\n <Button type=\"button\" variant=\"secondary\" onClick={onClose}>\n {closeLabel}\n </Button>\n </>\n );\n};\n\nconst PickerUnavailable = ({ message }: { message: string }) => {\n return <div>{message}</div>;\n};\n\nexport const EntityIdPickerDialog = ({\n isOpen,\n entity,\n title,\n scope,\n onClose,\n onSelectId,\n}: EntityIdPickerDialogProps): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const [search, setSearch] = useState('');\n const [fetchKey, setFetchKey] = useState(0);\n const entityState = useBackofficePickerEntityLoader(entity, {\n enabled: isOpen,\n });\n\n let pickerConfig:\n | BackofficeEntityPickerConfig<unknown, EntityPickerRowViewModel>\n | undefined;\n if (entityState.status === 'loaded') {\n pickerConfig = entityState.module.config.picker as\n | BackofficeEntityPickerConfig<unknown, EntityPickerRowViewModel>\n | undefined;\n }\n\n useEffect(() => {\n if (isOpen) {\n setSearch('');\n setFetchKey((value) => {\n return value + 1;\n });\n }\n }, [isOpen]);\n\n const footer = useMemo(() => {\n return buildFooter(onClose, t('common.actions.close'));\n }, [onClose, t]);\n\n const handleSearchChange = useCallback((next: string) => {\n setSearch(next);\n setFetchKey((value) => {\n return value + 1;\n });\n }, []);\n\n const handleSelectId = useCallback(\n (id: string) => {\n onSelectId(id);\n onClose();\n },\n [onClose, onSelectId],\n );\n\n if (!isOpen) {\n return null;\n }\n\n let resolvedSearchPlaceholder: string | undefined;\n if (pickerConfig?.searchPlaceholder != null) {\n resolvedSearchPlaceholder = resolveLabel(\n pickerConfig.searchPlaceholder,\n tApp,\n );\n }\n\n const trimmedSearch = search.trim();\n const isSearchRequired = pickerConfig?.searchRequired === true;\n\n let pickerNode: JSX.Element;\n if (entityState.status === 'loading') {\n pickerNode = <Spinner />;\n } else if (pickerConfig != null) {\n if (isSearchRequired && trimmedSearch === '') {\n pickerNode = (\n <div className={styles.searchRequiredMessage}>\n {t('picker.searchRequired')}\n </div>\n );\n } else {\n pickerNode = (\n <PickerBody\n config={pickerConfig}\n search={search}\n scope={scope}\n fetchKey={fetchKey}\n onSelectId={handleSelectId}\n />\n );\n }\n } else {\n pickerNode = (\n <PickerUnavailable message={t('picker.unavailable', { entity })} />\n );\n }\n\n return (\n <Modal isOpen={isOpen} onClose={onClose} title={title} footer={footer}>\n <EntityPickerShell\n search={search}\n onSearchChange={handleSearchChange}\n searchPlaceholder={resolvedSearchPlaceholder}\n searchEnabled={pickerConfig?.searchEnabled ?? true}\n >\n <BackofficeErrorBoundary\n fallback={(args: { error: unknown; reset: () => void }) => {\n const { reset } = args;\n return (\n <div>\n <div>{t('picker.errors.loadFailed')}</div>\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n reset();\n setFetchKey((value) => {\n return value + 1;\n });\n }}\n >\n {t('common.actions.retry')}\n </Button>\n </div>\n );\n }}\n >\n <Suspense fallback={<Spinner />}>{pickerNode}</Suspense>\n </BackofficeErrorBoundary>\n </EntityPickerShell>\n </Modal>\n );\n};\n\nexport type { BackofficePickerScope } from '@plumile/backoffice-core/types.js';\n\nexport default EntityIdPickerDialog;\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { n as e, t } from "./useBackofficeReactTranslation-WfXU8kCf.js";
2
- import { n, r, t as i } from "./EntityFilterValue-Bn9VGr2M.js";
3
- import { i as a, t as o } from "./EntityIdPickerDialog-D_qAlrU6.js";
2
+ import { n, r, t as i } from "./EntityFilterValue-B5ZGHO_u.js";
3
+ import { i as a, t as o } from "./EntityIdPickerDialog-DbTnDU4v.js";
4
4
  import { Suspense as s, lazy as c, startTransition as l, useCallback as u, useEffect as d, useMemo as f, useRef as p, useState as m } from "react";
5
5
  import { useTranslation as ee } from "react-i18next";
6
6
  import { BackofficeEmptyState as h, BackofficeFilterDrawer as te, BackofficeFilterField as ne, BackofficeLoadMore as re, BackofficePageHeader as ie, BackofficeTableSkeleton as ae, BackofficeTableToolbar as oe, BackofficeVirtualizedConnectionTable as se, Button as g, FilterChipRow as ce, GlobalSearchInput as le, InlineBanner as ue, ListPageTemplate as de, SimpleSelect as _, denseTableClass as fe } from "@plumile/ui";
@@ -57,7 +57,7 @@ function pe({ refetch: e, variables: t, defaults: n, fetchPolicy: r, buildVariab
57
57
  }
58
58
  //#endregion
59
59
  //#region src/components/backoffice/scaffolds/backofficeEntityListScaffold.css.ts
60
- var me = "txvbqb9io txvbqbajx txvbqbco txvbqbao6", he = "txvbqbu3f txvbqbjdo", ge = "txvbqb9io txvbqbai6 txvbqbaof", _e = "txvbqb96 txvbqbamo txvbqbv8p", T = (e, t) => e(t), E = (e, t) => e.fromGraphQL != null && t != null ? e.fromGraphQL(t) : x(t, e.whereKey ?? e.id, e.path), ve = (e, t, n) => {
60
+ var me = "txvbqb9ip txvbqbajy txvbqbcp txvbqbao7", he = "txvbqbu4g txvbqbjep", ge = "txvbqb9ip txvbqbai7 txvbqbaog", _e = "txvbqb97 txvbqbamp txvbqbv9z", T = (e, t) => e(t), E = (e, t) => e.fromGraphQL != null && t != null ? e.fromGraphQL(t) : x(t, e.whereKey ?? e.id, e.path), ve = (e, t, n) => {
61
61
  if (t == null) return null;
62
62
  if (Array.isArray(t)) {
63
63
  let e = t.map((e) => {
@@ -476,11 +476,11 @@ var me = "txvbqb9io txvbqbajx txvbqbco txvbqbao6", he = "txvbqbu3f txvbqbjdo", g
476
476
  tableFooterNode: $
477
477
  })
478
478
  });
479
- }, O = c(async () => ({ default: (await import("./BackofficeEntityActionFormDialog-BzKi1eyv.js")).BackofficeEntityActionFormDialog })), k = (e) => /* @__PURE__ */ y(s, {
479
+ }, O = c(async () => ({ default: (await import("./BackofficeEntityActionFormDialog-V4QXnvpy.js")).BackofficeEntityActionFormDialog })), k = (e) => /* @__PURE__ */ y(s, {
480
480
  fallback: null,
481
481
  children: /* @__PURE__ */ y(O, { ...e })
482
482
  });
483
483
  //#endregion
484
484
  export { w as i, D as n, pe as r, k as t };
485
485
 
486
- //# sourceMappingURL=LazyBackofficeEntityActionFormDialog-DndjG4kV.js.map
486
+ //# sourceMappingURL=LazyBackofficeEntityActionFormDialog-BE3wVfU6.js.map