@plumile/backoffice-react 0.1.125 → 0.1.131

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 (68) hide show
  1. package/lib/esm/auth/login/loginPage.css.js +1 -0
  2. package/lib/esm/auth/login/loginPage.css.js.map +1 -1
  3. package/lib/esm/components/backoffice/billing/BackofficeBillingUsageChart.js +37 -26
  4. package/lib/esm/components/backoffice/billing/BackofficeBillingUsageChart.js.map +1 -1
  5. package/lib/esm/components/backoffice/detail/BackofficeDetailBadgeRow.js +2 -1
  6. package/lib/esm/components/backoffice/detail/BackofficeDetailBadgeRow.js.map +1 -1
  7. package/lib/esm/components/backoffice/detail/BackofficeKpiStrip.js +23 -23
  8. package/lib/esm/components/backoffice/detail/BackofficeKpiStrip.js.map +1 -1
  9. package/lib/esm/components/backoffice/detail/backofficeDetailRelationLink.css.js +1 -0
  10. package/lib/esm/components/backoffice/detail/backofficeKpiStrip.css.js +14 -2
  11. package/lib/esm/components/backoffice/detail/backofficeKpiStrip.css.js.map +1 -1
  12. package/lib/esm/components/backoffice/filters/DeferredFilterSearchInput.js +64 -50
  13. package/lib/esm/components/backoffice/filters/DeferredFilterSearchInput.js.map +1 -1
  14. package/lib/esm/components/backoffice/filters/EntityIdFilterField.js +45 -50
  15. package/lib/esm/components/backoffice/filters/EntityIdFilterField.js.map +1 -1
  16. package/lib/esm/components/backoffice/filters/deferredFilterSearchInput.css.js +2 -2
  17. package/lib/esm/components/backoffice/filters/deferredFilterSearchInput.css.js.map +1 -1
  18. package/lib/esm/components/backoffice/filters/entityIdFilterField.css.js +1 -1
  19. package/lib/esm/components/backoffice/filters/entityIdFilterField.css.js.map +1 -1
  20. package/lib/esm/components/backoffice/hub/backofficeHubTemplate.css.js.map +1 -1
  21. package/lib/esm/components/backoffice/layout/backofficeSidebarActions.css.js +0 -1
  22. package/lib/esm/components/backoffice/pickers/entityIdPickerDialog.css.js.map +1 -1
  23. package/lib/esm/components/backoffice/refs/backofficeRelatedCountLink.css.js.map +1 -1
  24. package/lib/esm/components/backoffice/routing/backofficeRoutePendingBar.css.js.map +1 -1
  25. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js +1 -1
  26. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js.map +1 -1
  27. package/lib/esm/components/backoffice/shared/BackofficeFormattedCurrency.js +2 -1
  28. package/lib/esm/components/backoffice/shared/BackofficeFormattedCurrency.js.map +1 -1
  29. package/lib/esm/components/backoffice/tools/backofficeToolsDocPanel.css.js.map +1 -1
  30. package/lib/esm/i18n/locales/en/backofficeReact.js +3 -3
  31. package/lib/esm/i18n/locales/en/backofficeReact.js.map +1 -1
  32. package/lib/esm/i18n/locales/fr/backofficeReact.js +3 -3
  33. package/lib/esm/i18n/locales/fr/backofficeReact.js.map +1 -1
  34. package/lib/esm/i18n/useBackofficeFormats.js +28 -12
  35. package/lib/esm/i18n/useBackofficeFormats.js.map +1 -1
  36. package/lib/esm/pages/BackofficeEntityDetailPage.js +197 -196
  37. package/lib/esm/pages/BackofficeEntityDetailPage.js.map +1 -1
  38. package/lib/esm/pages/BackofficeEntityDetailPage.view-helpers.js +74 -70
  39. package/lib/esm/pages/BackofficeEntityDetailPage.view-helpers.js.map +1 -1
  40. package/lib/esm/pages/BackofficeEntityListPage.js +46 -53
  41. package/lib/esm/pages/BackofficeEntityListPage.js.map +1 -1
  42. package/lib/esm/pages/backofficeEntityListPage.css.js +1 -1
  43. package/lib/esm/pages/backofficeEntityListPage.css.js.map +1 -1
  44. package/lib/esm/pages/dashboard/dashboardPanel.css.js.map +1 -1
  45. package/lib/esm/provider/BackofficeProvider.js +1 -1
  46. package/lib/esm/provider/BackofficeProvider.js.map +1 -1
  47. package/lib/esm/style.css +1 -1
  48. package/lib/types/components/backoffice/billing/BackofficeBillingUsageChart.d.ts.map +1 -1
  49. package/lib/types/components/backoffice/detail/BackofficeDetailBadgeRow.d.ts.map +1 -1
  50. package/lib/types/components/backoffice/detail/BackofficeKpiStrip.d.ts.map +1 -1
  51. package/lib/types/components/backoffice/detail/backofficeKpiStrip.css.d.ts +24 -0
  52. package/lib/types/components/backoffice/detail/backofficeKpiStrip.css.d.ts.map +1 -1
  53. package/lib/types/components/backoffice/filters/DeferredFilterSearchInput.d.ts +1 -1
  54. package/lib/types/components/backoffice/filters/DeferredFilterSearchInput.d.ts.map +1 -1
  55. package/lib/types/components/backoffice/filters/EntityIdFilterField.d.ts.map +1 -1
  56. package/lib/types/components/backoffice/filters/deferredFilterSearchInput.css.d.ts +2 -0
  57. package/lib/types/components/backoffice/filters/deferredFilterSearchInput.css.d.ts.map +1 -1
  58. package/lib/types/components/backoffice/filters/entityIdFilterField.css.d.ts.map +1 -1
  59. package/lib/types/components/backoffice/shared/BackofficeFormattedCurrency.d.ts.map +1 -1
  60. package/lib/types/i18n/resources.d.ts +6 -6
  61. package/lib/types/i18n/useBackofficeFormats.d.ts +1 -0
  62. package/lib/types/i18n/useBackofficeFormats.d.ts.map +1 -1
  63. package/lib/types/pages/BackofficeEntityDetailPage.d.ts.map +1 -1
  64. package/lib/types/pages/BackofficeEntityDetailPage.view-helpers.d.ts +1 -0
  65. package/lib/types/pages/BackofficeEntityDetailPage.view-helpers.d.ts.map +1 -1
  66. package/lib/types/pages/BackofficeEntityListPage.d.ts.map +1 -1
  67. package/lib/types/pages/backofficeEntityListPage.css.d.ts.map +1 -1
  68. package/package.json +11 -11
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeEntityDetailPage.view-helpers.js","names":[],"sources":["../../../src/pages/BackofficeEntityDetailPage.view-helpers.ts"],"sourcesContent":["/* eslint-disable no-ternary */\nimport type {\n BackofficeBadgeItem,\n BackofficeDetailBlockSpec,\n BackofficeDetailFieldSpec,\n BackofficeDetailHeaderConfig,\n BackofficeDetailHeaderMetaSpec,\n BackofficeDetailHeaderStatusSpec,\n BackofficeFieldSize,\n BackofficeFlagVariant,\n BackofficeInlineValueSpec,\n BackofficeRuntimeRelationFilterSpec,\n BackofficeTone,\n} from '@plumile/backoffice-core/types.js';\nimport type { TFunction } from 'i18next';\nimport { Fragment, createElement, type ReactNode } from 'react';\n\nimport {\n isEmptyText,\n resolveLabel,\n resolveBadgeTone,\n resolveRelationValue,\n resolveValueLabel,\n} from './BackofficeEntityDetailPage.helpers.js';\n\nexport type ResolvedFieldItem = {\n id: string;\n label: string;\n size: BackofficeFieldSize;\n value: ReactNode;\n copyValue?: string;\n fullWidth?: boolean;\n};\n\nexport type ResolvedHeaderItem = {\n id: string;\n label: string;\n value: ReactNode;\n};\n\nexport type FlagIconName =\n | 'shield-lock'\n | 'shield-off'\n | 'settings-check'\n | 'settings-x'\n | 'x-badge'\n | 'chat-check'\n | 'key'\n | 'key-off'\n | 'lock'\n | 'lock-open'\n | 'robot-check'\n | 'robot-x'\n | 'rocket'\n | 'rocket-off';\n\nexport type ResolvedFlagTag = {\n tone: 'neutral' | 'info' | 'success' | 'warning' | 'danger';\n label: string;\n iconName?: FlagIconName;\n};\n\nexport const resolveFlagTag = (\n variant: BackofficeFlagVariant,\n value: boolean,\n t: TFunction,\n): ResolvedFlagTag => {\n switch (variant) {\n case 'yesNo':\n return value\n ? { tone: 'success', label: t('common.boolean.yes') }\n : { tone: 'neutral', label: t('common.boolean.no') };\n case 'capability':\n return value\n ? {\n tone: 'success',\n label: t('flags.capability.allowed'),\n iconName: 'shield-lock',\n }\n : {\n tone: 'neutral',\n label: t('flags.capability.denied'),\n iconName: 'shield-off',\n };\n case 'enabled':\n return value\n ? {\n tone: 'success',\n label: t('flags.enabled.enabled'),\n iconName: 'settings-check',\n }\n : {\n tone: 'neutral',\n label: t('flags.enabled.disabled'),\n iconName: 'settings-x',\n };\n case 'failure':\n return value\n ? {\n tone: 'danger',\n label: t('flags.failure.failed'),\n iconName: 'x-badge',\n }\n : {\n tone: 'success',\n label: t('flags.failure.ok'),\n iconName: 'chat-check',\n };\n case 'encrypted':\n return value\n ? {\n tone: 'info',\n label: t('flags.encrypted.encrypted'),\n iconName: 'key',\n }\n : {\n tone: 'neutral',\n label: t('flags.encrypted.notEncrypted'),\n iconName: 'key-off',\n };\n case 'locked':\n return value\n ? {\n tone: 'warning',\n label: t('flags.locked.locked'),\n iconName: 'lock',\n }\n : {\n tone: 'success',\n label: t('flags.locked.unlocked'),\n iconName: 'lock-open',\n };\n case 'default':\n return value\n ? { tone: 'info', label: t('flags.default.default') }\n : { tone: 'neutral', label: t('flags.default.notDefault') };\n case 'agentManaged':\n return value\n ? {\n tone: 'info',\n label: t('flags.agentManaged.agentManaged'),\n iconName: 'robot-check',\n }\n : {\n tone: 'neutral',\n label: t('flags.agentManaged.userManaged'),\n iconName: 'robot-x',\n };\n case 'deployedProduction':\n return value\n ? {\n tone: 'success',\n label: t('flags.deployedProduction.deployed'),\n iconName: 'rocket',\n }\n : {\n tone: 'neutral',\n label: t('flags.deployedProduction.notDeployed'),\n iconName: 'rocket-off',\n };\n case 'forced':\n return value\n ? { tone: 'warning', label: t('flags.forced.forced') }\n : { tone: 'neutral', label: t('flags.forced.normal') };\n default:\n throw new Error(`Unsupported flag variant: ${String(variant)}`);\n }\n};\n\nexport const resolveInlineValue = (\n value: BackofficeInlineValueSpec,\n options: {\n tApp: TFunction;\n t: TFunction;\n resolveEntityHref?: (entityId: string, refId: string) => string | null;\n renderLink: (href: string, label: ReactNode) => ReactNode;\n },\n): ReactNode => {\n const { tApp, t, resolveEntityHref, renderLink } = options;\n const fallback = t('common.notAvailable');\n\n if (value.type === 'text') {\n const resolved = resolveValueLabel(value.value, tApp);\n return isEmptyText(resolved) ? fallback : resolved;\n }\n\n if (value.type === 'entityRef') {\n const { id } = value;\n if (id == null || id.trim() === '') {\n return fallback;\n }\n const resolvedLabel = resolveValueLabel(value.label, tApp);\n const label =\n resolvedLabel != null && String(resolvedLabel).trim() !== ''\n ? resolvedLabel\n : null;\n if (label == null) {\n return fallback;\n }\n const href = resolveEntityHref?.(value.entity, id) ?? null;\n return href != null ? renderLink(href, label) : label;\n }\n\n const { href } = value;\n if (href == null || href.trim() === '') {\n return fallback;\n }\n const label = resolveValueLabel(value.label, tApp);\n if (isEmptyText(label)) {\n return fallback;\n }\n return renderLink(href, label);\n};\n\nexport const resolveHeaderMeta = <Node>(\n meta: BackofficeDetailHeaderMetaSpec<Node>,\n node: Node,\n options: {\n tApp: TFunction;\n t: TFunction;\n resolveEntityHref?: (entityId: string, refId: string) => string | null;\n renderDate: (\n value: string | number | null | undefined,\n fallback: string,\n ) => ReactNode;\n renderLink: (href: string, label: ReactNode) => ReactNode;\n },\n): ReactNode => {\n const { tApp, t, resolveEntityHref, renderDate, renderLink } = options;\n const fallback = t('common.notAvailable');\n\n if (meta.type === 'dateTime') {\n return renderDate(meta.value(node), fallback);\n }\n\n if (meta.type === 'entityRef') {\n const idValue = meta.id(node);\n if (idValue == null || idValue.trim() === '') {\n return fallback;\n }\n const labelValue = resolveValueLabel(meta.value?.(node), tApp);\n const label =\n labelValue != null && String(labelValue).trim() !== ''\n ? labelValue\n : null;\n if (label == null) {\n return fallback;\n }\n const href = resolveEntityHref?.(meta.entity, idValue) ?? null;\n return href != null ? renderLink(href, label) : label;\n }\n\n if (meta.type === 'link') {\n const href = meta.href(node);\n const labelValue = resolveValueLabel(meta.value(node), tApp);\n if (href == null || href.trim() === '' || isEmptyText(labelValue)) {\n return fallback;\n }\n return renderLink(href, labelValue);\n }\n\n const value = resolveValueLabel(meta.value(node), tApp);\n return isEmptyText(value) ? fallback : value;\n};\n\nexport const resolveHeaderStatus = <Node>(\n status: BackofficeDetailHeaderStatusSpec<Node>,\n node: Node,\n tApp: TFunction,\n renderers: {\n renderBadgeRow: (items: readonly BackofficeBadgeItem[]) => ReactNode;\n renderTag: (\n tone: ReturnType<typeof resolveBadgeTone<Node>>,\n label: string,\n ) => ReactNode;\n },\n): ReactNode | undefined => {\n if (status.type === 'badgeRow') {\n const items = status.items(node).map((item) => {\n const resolvedLabel = resolveValueLabel(item.label, tApp);\n const label = resolvedLabel == null ? '' : String(resolvedLabel);\n return { ...item, label };\n });\n if (items.length === 0) {\n return undefined;\n }\n return renderers.renderBadgeRow(items);\n }\n\n const value = resolveValueLabel(status.value(node), tApp);\n const label = value == null ? '' : String(value);\n if (label.trim() === '') {\n return undefined;\n }\n const tone = resolveBadgeTone(status.tone, node);\n return renderers.renderTag(tone, label);\n};\n\nexport const buildFieldItems = <Node, RelationItem>(\n fields: readonly BackofficeDetailFieldSpec<Node>[],\n node: Node,\n options: {\n tApp: TFunction;\n t: TFunction;\n resolveEntityHref?: (entityId: string, refId: string) => string | null;\n formatNumber: (value: number | null | undefined) => string;\n formatCurrency: (value: number | null | undefined) => string;\n formatPercent: (value: number | null | undefined) => string;\n relationEntityListRoutes: Record<string, string>;\n resolveRelationItem: (args: {\n id: string;\n label: string;\n count: number | null;\n relation: BackofficeRuntimeRelationFilterSpec;\n listRoute: string;\n value: string;\n where: Record<string, unknown>;\n }) => RelationItem;\n setWhereValue: (\n where: Record<string, unknown> | null,\n whereKey: string,\n value: string,\n path?: readonly string[],\n ) => Record<string, unknown> | null;\n renderTag: (\n tone: ReturnType<typeof resolveBadgeTone<Node>>,\n label: string,\n ) => ReactNode;\n renderBadgeRow: (items: readonly BackofficeBadgeItem[]) => ReactNode;\n renderDate: (\n value: string | number | null | undefined,\n fallback: string,\n ) => ReactNode;\n renderFlagTag: (tag: ResolvedFlagTag) => ReactNode;\n renderLink: (href: string, label: ReactNode) => ReactNode;\n renderTaggedValue: (tag: unknown, value: ReactNode) => ReactNode;\n wrapCustomNode: (id: string, node: ReactNode) => ReactNode;\n },\n): {\n items: ResolvedFieldItem[];\n relationItems: RelationItem[];\n customNodes: ReactNode[];\n} => {\n const {\n tApp,\n t,\n resolveEntityHref,\n formatNumber,\n formatCurrency,\n formatPercent,\n relationEntityListRoutes,\n resolveRelationItem,\n setWhereValue,\n renderTag,\n renderBadgeRow,\n renderDate,\n renderFlagTag,\n renderLink,\n renderTaggedValue,\n wrapCustomNode,\n } = options;\n const items: ResolvedFieldItem[] = [];\n const relationItems: RelationItem[] = [];\n const customNodes: ReactNode[] = [];\n const fallback = t('common.notAvailable');\n\n fields.forEach((field, index) => {\n const id = `${field.type}-${index}`;\n\n switch (field.type) {\n case 'text': {\n const value = resolveValueLabel(field.value(node), tApp);\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value,\n copyValue: field.copyValue?.(node) ?? undefined,\n fullWidth: field.fullWidth,\n });\n break;\n }\n case 'badge': {\n const value = resolveValueLabel(field.value(node), tApp);\n const label = value != null ? String(value) : '';\n const tone = resolveBadgeTone(field.tone, node);\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value: label.trim() !== '' ? renderTag(tone, label) : null,\n });\n break;\n }\n case 'badgeRow': {\n const badgeItems = field.items(node).map((item) => {\n const resolvedLabel = resolveValueLabel(item.label, tApp);\n const label = resolvedLabel == null ? '' : String(resolvedLabel);\n return { ...item, label };\n });\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value: badgeItems.length > 0 ? renderBadgeRow(badgeItems) : null,\n fullWidth: field.fullWidth,\n });\n break;\n }\n case 'dateTime': {\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value: renderDate(field.value(node), fallback),\n });\n break;\n }\n case 'number': {\n const value = field.value(node);\n let formatted: string | null = null;\n if (value != null) {\n if (field.format === 'currency') {\n formatted = formatCurrency(value);\n } else if (field.format === 'percent') {\n formatted = formatPercent(value);\n } else {\n formatted = formatNumber(value);\n }\n }\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value: formatted,\n });\n break;\n }\n case 'flag': {\n const value = field.value(node);\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value:\n value != null\n ? renderFlagTag(resolveFlagTag(field.variant, value, t))\n : null,\n });\n break;\n }\n case 'entityRef': {\n const idValue = field.id(node);\n let value: ReactNode | null = null;\n if (idValue != null && idValue.trim() !== '') {\n const labelValue = field.value?.(node);\n const label =\n labelValue != null && labelValue.trim() !== '' ? labelValue : null;\n const href = resolveEntityHref?.(field.entity, idValue) ?? null;\n if (label != null) {\n value = href != null ? renderLink(href, label) : label;\n }\n }\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value: value ?? fallback,\n });\n break;\n }\n case 'link': {\n const href = field.href(node);\n const labelValue = field.value(node);\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value:\n href != null && href.trim() !== '' && !isEmptyText(labelValue)\n ? renderLink(href, labelValue)\n : null,\n });\n break;\n }\n case 'taggedValue': {\n const tag = field.tag(node);\n const valueNode = resolveInlineValue(field.value(node), {\n tApp,\n t,\n resolveEntityHref,\n renderLink,\n });\n const resolvedTag =\n tag == null\n ? null\n : {\n ...tag,\n label: (() => {\n const labelValue = resolveValueLabel(tag.label, tApp);\n return labelValue == null ? '' : String(labelValue);\n })(),\n };\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value:\n resolvedTag != null || valueNode != null\n ? renderTaggedValue(resolvedTag, valueNode)\n : null,\n fullWidth: field.fullWidth,\n });\n break;\n }\n case 'relation': {\n const value = resolveRelationValue(field.value(node));\n if (value == null) {\n break;\n }\n const listRoute = relationEntityListRoutes[field.relation.target];\n if (listRoute == null) {\n break;\n }\n const where = setWhereValue(\n null,\n field.relation.whereKey,\n value,\n field.relation.path,\n );\n if (where == null) {\n break;\n }\n relationItems.push(\n resolveRelationItem({\n id,\n label: resolveLabel(field.label, tApp),\n count: field.count?.(node) ?? null,\n relation: field.relation,\n listRoute,\n value,\n where,\n }),\n );\n break;\n }\n case 'custom': {\n const custom = field.render(node) as ReactNode;\n if (custom == null) {\n break;\n }\n if (field.label != null) {\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value: custom,\n fullWidth: field.fullWidth,\n });\n break;\n }\n customNodes.push(wrapCustomNode(id, custom));\n break;\n }\n default:\n break;\n }\n });\n\n return { items, relationItems, customNodes };\n};\n\nexport const resolveHeaderItems = <Node>(\n header: BackofficeDetailHeaderConfig<Node>,\n node: Node,\n options: {\n tApp: TFunction;\n t: TFunction;\n resolveEntityHref?: (entityId: string, refId: string) => string | null;\n renderLink: (href: string, label: ReactNode) => ReactNode;\n renderDate: (\n value: string | number | null | undefined,\n fallback: string,\n ) => ReactNode;\n renderTag: (\n tone: ReturnType<typeof resolveBadgeTone<Node>>,\n label: string,\n ) => ReactNode;\n renderBadgeRow: (items: readonly BackofficeBadgeItem[]) => ReactNode;\n },\n): {\n title: string;\n subtitle?: ReactNode;\n badges?: ReactNode;\n status?: ReactNode;\n items?: readonly ResolvedHeaderItem[];\n} => {\n const {\n tApp,\n t,\n resolveEntityHref,\n renderLink,\n renderDate,\n renderTag,\n renderBadgeRow,\n } = options;\n const resolvedTitle =\n header.titleValue?.(node, tApp) ?? resolveLabel(header.title, tApp);\n const title =\n resolvedTitle.trim() === ''\n ? resolveLabel(header.title, tApp)\n : resolvedTitle;\n\n let subtitleNode: ReactNode | undefined;\n if (header.subtitleItems != null && header.subtitleItems.length > 0) {\n const { subtitleItems } = header;\n const separator = header.subtitleSeparator ?? ' / ';\n const parts: ReactNode[] = [];\n subtitleItems.forEach((item, index) => {\n parts.push(\n createElement(\n 'span',\n { key: item.id },\n resolveInlineValue(item.value(node), {\n tApp,\n t,\n resolveEntityHref,\n renderLink,\n }),\n ),\n );\n if (index < subtitleItems.length - 1) {\n parts.push(createElement('span', { key: `${item.id}-sep` }, separator));\n }\n });\n subtitleNode = createElement('span', null, ...parts);\n } else {\n const subtitleValue =\n header.subtitleValue?.(node, tApp) ??\n (header.subtitle != null ? resolveLabel(header.subtitle, tApp) : null);\n subtitleNode =\n subtitleValue != null && subtitleValue.trim() !== ''\n ? subtitleValue\n : undefined;\n }\n\n const badgeNodes: ReactNode[] = [];\n header.badges?.forEach((badge, index) => {\n const label = resolveLabel(badge.label, tApp);\n const resolvedValue = resolveValueLabel(badge.value(node), tApp);\n const value = resolvedValue == null ? '' : String(resolvedValue);\n if (value.trim() === '') {\n return;\n }\n badgeNodes.push(\n renderTag(resolveBadgeTone(badge.tone, node), `${label}: ${value}`),\n );\n if (typeof badgeNodes[badgeNodes.length - 1] === 'object') {\n badgeNodes[badgeNodes.length - 1] = createElement(\n Fragment,\n { key: `${label}-${index}` },\n badgeNodes[badgeNodes.length - 1],\n );\n }\n });\n\n const status =\n header.status != null\n ? resolveHeaderStatus(header.status, node, tApp, {\n renderBadgeRow,\n renderTag,\n })\n : undefined;\n\n const items = header.meta?.map((meta, index) => {\n const label = resolveLabel(meta.label, tApp);\n return {\n id: `${label}-${index}`,\n label,\n value: resolveHeaderMeta(meta, node, {\n tApp,\n t,\n resolveEntityHref,\n renderDate,\n renderLink,\n }),\n };\n });\n\n return {\n title,\n subtitle: subtitleNode,\n badges:\n badgeNodes.length > 0\n ? createElement(Fragment, null, ...badgeNodes)\n : undefined,\n status,\n items,\n };\n};\n\nexport const renderBlocks = <Node>(\n blocks: readonly BackofficeDetailBlockSpec<Node>[] | undefined,\n node: Node,\n options: {\n tApp: TFunction;\n t: TFunction;\n resolveEntityHref: (entityId: string, refId: string) => string | null;\n keyPrefix?: string;\n renderLink: (href: string, label: ReactNode) => ReactNode;\n renderDate: (\n value: string | number | Date | null | undefined,\n fallback: string,\n ) => ReactNode;\n renderTag: (tone: BackofficeTone, label: string) => ReactNode;\n renderMetricGroup: (args: {\n key: string;\n title: string;\n description?: string;\n density?: 'compact' | 'comfortable';\n items: readonly {\n id: string;\n label: string;\n value: ReactNode;\n hint?: ReactNode;\n tone?: BackofficeTone;\n copyValue?: string;\n }[];\n }) => ReactNode;\n renderTimeline: (args: {\n key: string;\n title: string;\n description?: string;\n events: readonly {\n id: string;\n label: string;\n timestamp?: ReactNode;\n description?: ReactNode;\n actor?: ReactNode;\n tone?: BackofficeTone;\n payload?: ReactNode;\n }[];\n }) => ReactNode;\n renderRelations: (args: {\n key: string;\n title: string;\n description?: string;\n items: readonly {\n id: string;\n label: string;\n count?: number | null;\n href?: string;\n description?: ReactNode;\n tone?: BackofficeTone;\n }[];\n }) => ReactNode;\n renderContextStack: (args: {\n key: string;\n title: string;\n items: readonly {\n id: string;\n label: string;\n value: ReactNode | null | undefined;\n }[];\n }) => ReactNode;\n renderCustomSection: (\n key: string,\n title: string,\n child: ReactNode,\n ) => ReactNode;\n wrapCustomNode: (key: string, node: ReactNode) => ReactNode;\n resolveTableColumns: (columns: readonly unknown[]) => unknown;\n renderTable: (args: {\n key: string;\n title: string;\n description?: string;\n columns: unknown;\n rows: readonly unknown[];\n }) => ReactNode;\n renderPayload: (args: {\n key: string;\n title: string;\n description?: string;\n content: unknown;\n format?: string;\n }) => ReactNode;\n renderKeyValueListSection: (args: {\n key: string;\n title: string;\n description?: string;\n items: readonly { id: string; label: string; value: ReactNode }[];\n }) => ReactNode;\n },\n): ReactNode[] => {\n const { tApp, t, keyPrefix } = options;\n if (blocks == null || blocks.length === 0) {\n return [];\n }\n\n return blocks.map((block, index): ReactNode => {\n const key =\n keyPrefix != null\n ? `${keyPrefix}-${block.kind}-${index}`\n : `${block.kind}-${index}`;\n\n if (block.kind === 'custom') {\n const custom = block.render(node) as ReactNode;\n if (custom == null) {\n return null;\n }\n if (block.label != null) {\n return options.renderCustomSection(\n key,\n resolveLabel(block.label, tApp),\n custom,\n );\n }\n return options.wrapCustomNode(key, custom);\n }\n\n const title =\n 'title' in block\n ? resolveLabel(block.title, tApp)\n : resolveLabel(block.label, tApp);\n const description =\n block.description != null\n ? resolveLabel(block.description, tApp)\n : undefined;\n\n if (block.kind === 'summary') {\n return options.renderKeyValueListSection({\n key,\n title,\n description,\n items: block.items.map((item) => {\n const value = resolveValueLabel(item.value(node), tApp);\n const href = item.href?.(node);\n const tone = item.tone?.(node);\n let valueNode: ReactNode = value ?? t('common.notAvailable');\n if (href != null && href.trim() !== '' && !isEmptyText(value)) {\n valueNode = options.renderLink(href, value);\n } else if (tone != null && !isEmptyText(value)) {\n valueNode = options.renderTag(tone, String(value));\n }\n return {\n id: item.id,\n label: resolveLabel(item.label, tApp),\n value: valueNode,\n };\n }),\n });\n }\n\n if (block.kind === 'metrics') {\n return options.renderMetricGroup({\n key,\n title,\n description,\n density: block.density,\n items: block.items.map((item) => {\n const formattedValue = item.formattedValue?.(node);\n const value = resolveValueLabel(item.value(node), tApp);\n return {\n id: item.id,\n label: resolveLabel(item.label, tApp),\n value: formattedValue ?? value ?? t('common.notAvailable'),\n hint: resolveValueLabel(item.hint?.(node), tApp),\n tone: item.tone?.(node),\n copyValue: item.copyValue?.(node) ?? undefined,\n };\n }),\n });\n }\n\n if (block.kind === 'states') {\n return options.renderKeyValueListSection({\n key,\n title,\n description,\n items: block.states.map((state) => {\n const display = state.getDisplay(state.value(node), node);\n return {\n id: state.id,\n label: resolveLabel(state.label, tApp),\n value: options.renderTag(\n display.tone,\n String(\n resolveValueLabel(display.label, tApp) ??\n t('common.notAvailable'),\n ),\n ),\n };\n }),\n });\n }\n\n if (block.kind === 'context') {\n return options.renderContextStack({\n key,\n title,\n items: block.items.map((item) => {\n const value = resolveValueLabel(item.value(node), tApp);\n const href = item.href?.(node);\n return {\n id: item.id,\n label: resolveLabel(item.label, tApp),\n value:\n href != null && href.trim() !== '' && !isEmptyText(value)\n ? options.renderLink(href, value)\n : value,\n };\n }),\n });\n }\n\n if (block.kind === 'relations') {\n return options.renderRelations({\n key,\n title,\n description,\n items: block.items.map((item) => {\n return {\n id: item.id,\n label: resolveLabel(item.label, tApp),\n count: item.count?.(node) ?? null,\n href: item.href?.(node) ?? undefined,\n description: resolveValueLabel(item.description?.(node), tApp),\n tone: item.tone?.(node),\n };\n }),\n });\n }\n\n if (block.kind === 'timeline') {\n return options.renderTimeline({\n key,\n title,\n description,\n events: block.events.map((event) => {\n const state = event.state?.(node);\n const stateLabel =\n state == null ? null : resolveValueLabel(state.label, tApp);\n const stateText = stateLabel == null ? null : String(stateLabel);\n return {\n id: event.id,\n label:\n stateText == null || stateText.trim() === ''\n ? resolveLabel(event.label, tApp)\n : `${resolveLabel(event.label, tApp)}: ${stateText}`,\n timestamp:\n event.timestamp == null\n ? undefined\n : options.renderDate(\n event.timestamp(node),\n t('common.notAvailable'),\n ),\n description: resolveValueLabel(event.description?.(node), tApp),\n actor: resolveValueLabel(event.actor?.(node), tApp),\n tone: state?.tone,\n };\n }),\n });\n }\n\n if (block.kind === 'audit') {\n return options.renderKeyValueListSection({\n key,\n title,\n description,\n items: block.items.flatMap((item) => {\n const values = [\n {\n id: `${item.id}-timestamp`,\n label: resolveLabel(item.label, tApp),\n value: options.renderDate(\n item.timestamp?.(node),\n t('common.notAvailable'),\n ),\n },\n ];\n const actor = resolveValueLabel(item.actor?.(node), tApp);\n if (!isEmptyText(actor)) {\n values.push({\n id: `${item.id}-actor`,\n label: t('detail.audit.actor'),\n value: actor,\n });\n }\n const source = resolveValueLabel(item.source?.(node), tApp);\n if (!isEmptyText(source)) {\n values.push({\n id: `${item.id}-source`,\n label: t('detail.audit.source'),\n value: source,\n });\n }\n return values;\n }),\n });\n }\n\n if (block.kind === 'references') {\n return options.renderKeyValueListSection({\n key,\n title,\n description,\n items: block.references.map((reference) => {\n const value = resolveValueLabel(reference.value(node), tApp);\n const href = reference.href?.(node);\n return {\n id: reference.id,\n label: resolveLabel(reference.label, tApp),\n value:\n href != null && href.trim() !== '' && !isEmptyText(value)\n ? options.renderLink(href, value)\n : (value ?? t('common.notAvailable')),\n };\n }),\n });\n }\n\n if (block.kind === 'actionResult') {\n const items: { id: string; label: string; value: ReactNode }[] = [];\n const status = block.status?.(node);\n if (status != null) {\n items.push({\n id: `${block.id}-status`,\n label: t('detail.actionResult.status'),\n value: options.renderTag(\n status.tone,\n String(\n resolveValueLabel(status.label, tApp) ?? t('common.notAvailable'),\n ),\n ),\n });\n }\n const message = resolveValueLabel(block.message?.(node), tApp);\n if (!isEmptyText(message)) {\n items.push({\n id: `${block.id}-message`,\n label: t('detail.actionResult.message'),\n value: message,\n });\n }\n block.references?.forEach((reference) => {\n items.push({\n id: reference.id,\n label: resolveLabel(reference.label, tApp),\n value:\n resolveValueLabel(reference.value(node), tApp) ??\n t('common.notAvailable'),\n });\n });\n return options.renderKeyValueListSection({\n key,\n title,\n description,\n items,\n });\n }\n\n if (block.kind === 'technicalFacts') {\n return options.renderKeyValueListSection({\n key,\n title,\n description,\n items: block.facts.map((fact) => {\n const value = resolveValueLabel(fact.value(node), tApp);\n const href = fact.href?.(node);\n return {\n id: fact.id,\n label: resolveLabel(fact.label, tApp),\n value:\n href != null && href.trim() !== '' && !isEmptyText(value)\n ? options.renderLink(href, value)\n : (value ?? t('common.notAvailable')),\n };\n }),\n });\n }\n\n if (block.kind === 'table') {\n return options.renderTable({\n key,\n title,\n description,\n columns: options.resolveTableColumns(\n block.columns as readonly unknown[],\n ),\n rows: block.rows(node) as readonly unknown[],\n });\n }\n\n return options.renderPayload({\n key,\n title,\n description,\n content: block.value(node),\n format: block.format,\n });\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"BackofficeEntityDetailPage.view-helpers.js","names":[],"sources":["../../../src/pages/BackofficeEntityDetailPage.view-helpers.ts"],"sourcesContent":["/* eslint-disable no-ternary */\nimport type {\n BackofficeBadgeItem,\n BackofficeDetailBlockSpec,\n BackofficeDetailFieldSpec,\n BackofficeDetailHeaderConfig,\n BackofficeDetailHeaderMetaSpec,\n BackofficeDetailHeaderStatusSpec,\n BackofficeFieldSize,\n BackofficeFlagVariant,\n BackofficeInlineValueSpec,\n BackofficeRuntimeRelationFilterSpec,\n BackofficeTone,\n} from '@plumile/backoffice-core/types.js';\nimport type { TFunction } from 'i18next';\nimport { Fragment, createElement, type ReactNode } from 'react';\n\nimport {\n isEmptyText,\n resolveLabel,\n resolveBadgeTone,\n resolveRelationValue,\n resolveValueLabel,\n} from './BackofficeEntityDetailPage.helpers.js';\n\nexport type ResolvedFieldItem = {\n id: string;\n label: string;\n size: BackofficeFieldSize;\n value: ReactNode;\n copyValue?: string;\n fullWidth?: boolean;\n};\n\nexport type ResolvedHeaderItem = {\n id: string;\n label: string;\n value: ReactNode;\n};\n\nexport type FlagIconName =\n | 'shield-lock'\n | 'shield-off'\n | 'settings-check'\n | 'settings-x'\n | 'x-badge'\n | 'chat-check'\n | 'key'\n | 'key-off'\n | 'lock'\n | 'lock-open'\n | 'robot-check'\n | 'robot-x'\n | 'rocket'\n | 'rocket-off';\n\nexport type ResolvedFlagTag = {\n tone: 'neutral' | 'info' | 'success' | 'warning' | 'danger';\n label: string;\n iconName?: FlagIconName;\n};\n\nexport const resolveFlagTag = (\n variant: BackofficeFlagVariant,\n value: boolean,\n t: TFunction,\n): ResolvedFlagTag => {\n switch (variant) {\n case 'yesNo':\n return value\n ? { tone: 'success', label: t('common.boolean.yes') }\n : { tone: 'neutral', label: t('common.boolean.no') };\n case 'capability':\n return value\n ? {\n tone: 'success',\n label: t('flags.capability.allowed'),\n iconName: 'shield-lock',\n }\n : {\n tone: 'neutral',\n label: t('flags.capability.denied'),\n iconName: 'shield-off',\n };\n case 'enabled':\n return value\n ? {\n tone: 'success',\n label: t('flags.enabled.enabled'),\n iconName: 'settings-check',\n }\n : {\n tone: 'neutral',\n label: t('flags.enabled.disabled'),\n iconName: 'settings-x',\n };\n case 'failure':\n return value\n ? {\n tone: 'danger',\n label: t('flags.failure.failed'),\n iconName: 'x-badge',\n }\n : {\n tone: 'success',\n label: t('flags.failure.ok'),\n iconName: 'chat-check',\n };\n case 'encrypted':\n return value\n ? {\n tone: 'info',\n label: t('flags.encrypted.encrypted'),\n iconName: 'key',\n }\n : {\n tone: 'neutral',\n label: t('flags.encrypted.notEncrypted'),\n iconName: 'key-off',\n };\n case 'locked':\n return value\n ? {\n tone: 'warning',\n label: t('flags.locked.locked'),\n iconName: 'lock',\n }\n : {\n tone: 'success',\n label: t('flags.locked.unlocked'),\n iconName: 'lock-open',\n };\n case 'default':\n return value\n ? { tone: 'info', label: t('flags.default.default') }\n : { tone: 'neutral', label: t('flags.default.notDefault') };\n case 'agentManaged':\n return value\n ? {\n tone: 'info',\n label: t('flags.agentManaged.agentManaged'),\n iconName: 'robot-check',\n }\n : {\n tone: 'neutral',\n label: t('flags.agentManaged.userManaged'),\n iconName: 'robot-x',\n };\n case 'deployedProduction':\n return value\n ? {\n tone: 'success',\n label: t('flags.deployedProduction.deployed'),\n iconName: 'rocket',\n }\n : {\n tone: 'neutral',\n label: t('flags.deployedProduction.notDeployed'),\n iconName: 'rocket-off',\n };\n case 'forced':\n return value\n ? { tone: 'warning', label: t('flags.forced.forced') }\n : { tone: 'neutral', label: t('flags.forced.normal') };\n default:\n throw new Error(`Unsupported flag variant: ${String(variant)}`);\n }\n};\n\nexport const resolveInlineValue = (\n value: BackofficeInlineValueSpec,\n options: {\n tApp: TFunction;\n t: TFunction;\n resolveEntityHref?: (entityId: string, refId: string) => string | null;\n renderLink: (href: string, label: ReactNode) => ReactNode;\n },\n): ReactNode => {\n const { tApp, t, resolveEntityHref, renderLink } = options;\n const fallback = t('common.notAvailable');\n\n if (value.type === 'text') {\n const resolved = resolveValueLabel(value.value, tApp);\n return isEmptyText(resolved) ? fallback : resolved;\n }\n\n if (value.type === 'entityRef') {\n const { id } = value;\n if (id == null || id.trim() === '') {\n return fallback;\n }\n const resolvedLabel = resolveValueLabel(value.label, tApp);\n const label =\n resolvedLabel != null && String(resolvedLabel).trim() !== ''\n ? resolvedLabel\n : null;\n if (label == null) {\n return fallback;\n }\n const href = resolveEntityHref?.(value.entity, id) ?? null;\n return href != null ? renderLink(href, label) : label;\n }\n\n const { href } = value;\n if (href == null || href.trim() === '') {\n return fallback;\n }\n const label = resolveValueLabel(value.label, tApp);\n if (isEmptyText(label)) {\n return fallback;\n }\n return renderLink(href, label);\n};\n\nexport const resolveHeaderMeta = <Node>(\n meta: BackofficeDetailHeaderMetaSpec<Node>,\n node: Node,\n options: {\n tApp: TFunction;\n t: TFunction;\n resolveEntityHref?: (entityId: string, refId: string) => string | null;\n renderDate: (\n value: string | number | null | undefined,\n fallback: string,\n ) => ReactNode;\n renderLink: (href: string, label: ReactNode) => ReactNode;\n },\n): ReactNode => {\n const { tApp, t, resolveEntityHref, renderDate, renderLink } = options;\n const fallback = t('common.notAvailable');\n\n if (meta.type === 'dateTime') {\n return renderDate(meta.value(node), fallback);\n }\n\n if (meta.type === 'entityRef') {\n const idValue = meta.id(node);\n if (idValue == null || idValue.trim() === '') {\n return fallback;\n }\n const labelValue = resolveValueLabel(meta.value?.(node), tApp);\n const label =\n labelValue != null && String(labelValue).trim() !== ''\n ? labelValue\n : null;\n if (label == null) {\n return fallback;\n }\n const href = resolveEntityHref?.(meta.entity, idValue) ?? null;\n return href != null ? renderLink(href, label) : label;\n }\n\n if (meta.type === 'link') {\n const href = meta.href(node);\n const labelValue = resolveValueLabel(meta.value(node), tApp);\n if (href == null || href.trim() === '' || isEmptyText(labelValue)) {\n return fallback;\n }\n return renderLink(href, labelValue);\n }\n\n const value = resolveValueLabel(meta.value(node), tApp);\n return isEmptyText(value) ? fallback : value;\n};\n\nexport const resolveHeaderStatus = <Node>(\n status: BackofficeDetailHeaderStatusSpec<Node>,\n node: Node,\n tApp: TFunction,\n renderers: {\n renderBadgeRow: (items: readonly BackofficeBadgeItem[]) => ReactNode;\n renderTag: (\n tone: ReturnType<typeof resolveBadgeTone<Node>>,\n label: string,\n ) => ReactNode;\n },\n): ReactNode | undefined => {\n if (status.type === 'badgeRow') {\n const items = status.items(node).map((item) => {\n const resolvedLabel = resolveValueLabel(item.label, tApp);\n const label = resolvedLabel == null ? '' : String(resolvedLabel);\n return { ...item, label };\n });\n if (items.length === 0) {\n return undefined;\n }\n return renderers.renderBadgeRow(items);\n }\n\n const value = resolveValueLabel(status.value(node), tApp);\n const label = value == null ? '' : String(value);\n if (label.trim() === '') {\n return undefined;\n }\n const tone = resolveBadgeTone(status.tone, node);\n return renderers.renderTag(tone, label);\n};\n\nexport const buildFieldItems = <Node, RelationItem>(\n fields: readonly BackofficeDetailFieldSpec<Node>[],\n node: Node,\n options: {\n tApp: TFunction;\n t: TFunction;\n resolveEntityHref?: (entityId: string, refId: string) => string | null;\n formatNumber: (value: number | null | undefined) => string;\n formatCurrency: (value: number | null | undefined) => string;\n formatCurrencyTitle?: (value: number | null | undefined) => string | null;\n formatPercent: (value: number | null | undefined) => string;\n relationEntityListRoutes: Record<string, string>;\n resolveRelationItem: (args: {\n id: string;\n label: string;\n count: number | null;\n relation: BackofficeRuntimeRelationFilterSpec;\n listRoute: string;\n value: string;\n where: Record<string, unknown>;\n }) => RelationItem;\n setWhereValue: (\n where: Record<string, unknown> | null,\n whereKey: string,\n value: string,\n path?: readonly string[],\n ) => Record<string, unknown> | null;\n renderTag: (\n tone: ReturnType<typeof resolveBadgeTone<Node>>,\n label: string,\n ) => ReactNode;\n renderBadgeRow: (items: readonly BackofficeBadgeItem[]) => ReactNode;\n renderDate: (\n value: string | number | null | undefined,\n fallback: string,\n ) => ReactNode;\n renderFlagTag: (tag: ResolvedFlagTag) => ReactNode;\n renderLink: (href: string, label: ReactNode) => ReactNode;\n renderTaggedValue: (tag: unknown, value: ReactNode) => ReactNode;\n wrapCustomNode: (id: string, node: ReactNode) => ReactNode;\n },\n): {\n items: ResolvedFieldItem[];\n relationItems: RelationItem[];\n customNodes: ReactNode[];\n} => {\n const {\n tApp,\n t,\n resolveEntityHref,\n formatNumber,\n formatCurrency,\n formatCurrencyTitle,\n formatPercent,\n relationEntityListRoutes,\n resolveRelationItem,\n setWhereValue,\n renderTag,\n renderBadgeRow,\n renderDate,\n renderFlagTag,\n renderLink,\n renderTaggedValue,\n wrapCustomNode,\n } = options;\n const items: ResolvedFieldItem[] = [];\n const relationItems: RelationItem[] = [];\n const customNodes: ReactNode[] = [];\n const fallback = t('common.notAvailable');\n\n fields.forEach((field, index) => {\n const id = `${field.type}-${index}`;\n\n switch (field.type) {\n case 'text': {\n const value = resolveValueLabel(field.value(node), tApp);\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value,\n copyValue: field.copyValue?.(node) ?? undefined,\n fullWidth: field.fullWidth,\n });\n break;\n }\n case 'badge': {\n const value = resolveValueLabel(field.value(node), tApp);\n const label = value != null ? String(value) : '';\n const tone = resolveBadgeTone(field.tone, node);\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value: label.trim() !== '' ? renderTag(tone, label) : null,\n });\n break;\n }\n case 'badgeRow': {\n const badgeItems = field.items(node).map((item) => {\n const resolvedLabel = resolveValueLabel(item.label, tApp);\n const label = resolvedLabel == null ? '' : String(resolvedLabel);\n return { ...item, label };\n });\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value: badgeItems.length > 0 ? renderBadgeRow(badgeItems) : null,\n fullWidth: field.fullWidth,\n });\n break;\n }\n case 'dateTime': {\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value: renderDate(field.value(node), fallback),\n });\n break;\n }\n case 'number': {\n const value = field.value(node);\n let formatted: ReactNode | null = null;\n if (value != null) {\n if (field.format === 'currency') {\n const label = formatCurrency(value);\n formatted = createElement(\n 'span',\n { title: formatCurrencyTitle?.(value) ?? undefined },\n label,\n );\n } else if (field.format === 'percent') {\n formatted = formatPercent(value);\n } else {\n formatted = formatNumber(value);\n }\n }\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value: formatted,\n });\n break;\n }\n case 'flag': {\n const value = field.value(node);\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value:\n value != null\n ? renderFlagTag(resolveFlagTag(field.variant, value, t))\n : null,\n });\n break;\n }\n case 'entityRef': {\n const idValue = field.id(node);\n let value: ReactNode | null = null;\n if (idValue != null && idValue.trim() !== '') {\n const labelValue = field.value?.(node);\n const label =\n labelValue != null && labelValue.trim() !== '' ? labelValue : null;\n const href = resolveEntityHref?.(field.entity, idValue) ?? null;\n if (label != null) {\n value = href != null ? renderLink(href, label) : label;\n }\n }\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value: value ?? fallback,\n });\n break;\n }\n case 'link': {\n const href = field.href(node);\n const labelValue = field.value(node);\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value:\n href != null && href.trim() !== '' && !isEmptyText(labelValue)\n ? renderLink(href, labelValue)\n : null,\n });\n break;\n }\n case 'taggedValue': {\n const tag = field.tag(node);\n const valueNode = resolveInlineValue(field.value(node), {\n tApp,\n t,\n resolveEntityHref,\n renderLink,\n });\n const resolvedTag =\n tag == null\n ? null\n : {\n ...tag,\n label: (() => {\n const labelValue = resolveValueLabel(tag.label, tApp);\n return labelValue == null ? '' : String(labelValue);\n })(),\n };\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value:\n resolvedTag != null || valueNode != null\n ? renderTaggedValue(resolvedTag, valueNode)\n : null,\n fullWidth: field.fullWidth,\n });\n break;\n }\n case 'relation': {\n const value = resolveRelationValue(field.value(node));\n if (value == null) {\n break;\n }\n const listRoute = relationEntityListRoutes[field.relation.target];\n if (listRoute == null) {\n break;\n }\n const where = setWhereValue(\n null,\n field.relation.whereKey,\n value,\n field.relation.path,\n );\n if (where == null) {\n break;\n }\n relationItems.push(\n resolveRelationItem({\n id,\n label: resolveLabel(field.label, tApp),\n count: field.count?.(node) ?? null,\n relation: field.relation,\n listRoute,\n value,\n where,\n }),\n );\n break;\n }\n case 'custom': {\n const custom = field.render(node) as ReactNode;\n if (custom == null) {\n break;\n }\n if (field.label != null) {\n items.push({\n id,\n label: resolveLabel(field.label, tApp),\n size: field.size,\n value: custom,\n fullWidth: field.fullWidth,\n });\n break;\n }\n customNodes.push(wrapCustomNode(id, custom));\n break;\n }\n default:\n break;\n }\n });\n\n return { items, relationItems, customNodes };\n};\n\nexport const resolveHeaderItems = <Node>(\n header: BackofficeDetailHeaderConfig<Node>,\n node: Node,\n options: {\n tApp: TFunction;\n t: TFunction;\n resolveEntityHref?: (entityId: string, refId: string) => string | null;\n renderLink: (href: string, label: ReactNode) => ReactNode;\n renderDate: (\n value: string | number | null | undefined,\n fallback: string,\n ) => ReactNode;\n renderTag: (\n tone: ReturnType<typeof resolveBadgeTone<Node>>,\n label: string,\n ) => ReactNode;\n renderBadgeRow: (items: readonly BackofficeBadgeItem[]) => ReactNode;\n },\n): {\n title: string;\n subtitle?: ReactNode;\n badges?: ReactNode;\n status?: ReactNode;\n items?: readonly ResolvedHeaderItem[];\n} => {\n const {\n tApp,\n t,\n resolveEntityHref,\n renderLink,\n renderDate,\n renderTag,\n renderBadgeRow,\n } = options;\n const resolvedTitle =\n header.titleValue?.(node, tApp) ?? resolveLabel(header.title, tApp);\n const title =\n resolvedTitle.trim() === ''\n ? resolveLabel(header.title, tApp)\n : resolvedTitle;\n\n let subtitleNode: ReactNode | undefined;\n if (header.subtitleItems != null && header.subtitleItems.length > 0) {\n const { subtitleItems } = header;\n const separator = header.subtitleSeparator ?? ' / ';\n const parts: ReactNode[] = [];\n subtitleItems.forEach((item, index) => {\n parts.push(\n createElement(\n 'span',\n { key: item.id },\n resolveInlineValue(item.value(node), {\n tApp,\n t,\n resolveEntityHref,\n renderLink,\n }),\n ),\n );\n if (index < subtitleItems.length - 1) {\n parts.push(createElement('span', { key: `${item.id}-sep` }, separator));\n }\n });\n subtitleNode = createElement('span', null, ...parts);\n } else {\n const subtitleValue =\n header.subtitleValue?.(node, tApp) ??\n (header.subtitle != null ? resolveLabel(header.subtitle, tApp) : null);\n subtitleNode =\n subtitleValue != null && subtitleValue.trim() !== ''\n ? subtitleValue\n : undefined;\n }\n\n const badgeNodes: ReactNode[] = [];\n header.badges?.forEach((badge, index) => {\n const label = resolveLabel(badge.label, tApp);\n const resolvedValue = resolveValueLabel(badge.value(node), tApp);\n const value = resolvedValue == null ? '' : String(resolvedValue);\n if (value.trim() === '') {\n return;\n }\n badgeNodes.push(\n renderTag(resolveBadgeTone(badge.tone, node), `${label}: ${value}`),\n );\n if (typeof badgeNodes[badgeNodes.length - 1] === 'object') {\n badgeNodes[badgeNodes.length - 1] = createElement(\n Fragment,\n { key: `${label}-${index}` },\n badgeNodes[badgeNodes.length - 1],\n );\n }\n });\n\n const status =\n header.status != null\n ? resolveHeaderStatus(header.status, node, tApp, {\n renderBadgeRow,\n renderTag,\n })\n : undefined;\n\n const items = header.meta?.map((meta, index) => {\n const label = resolveLabel(meta.label, tApp);\n return {\n id: `${label}-${index}`,\n label,\n value: resolveHeaderMeta(meta, node, {\n tApp,\n t,\n resolveEntityHref,\n renderDate,\n renderLink,\n }),\n };\n });\n\n return {\n title,\n subtitle: subtitleNode,\n badges:\n badgeNodes.length > 0\n ? createElement(Fragment, null, ...badgeNodes)\n : undefined,\n status,\n items,\n };\n};\n\nexport const renderBlocks = <Node>(\n blocks: readonly BackofficeDetailBlockSpec<Node>[] | undefined,\n node: Node,\n options: {\n tApp: TFunction;\n t: TFunction;\n resolveEntityHref: (entityId: string, refId: string) => string | null;\n keyPrefix?: string;\n renderLink: (href: string, label: ReactNode) => ReactNode;\n renderDate: (\n value: string | number | Date | null | undefined,\n fallback: string,\n ) => ReactNode;\n renderTag: (tone: BackofficeTone, label: string) => ReactNode;\n renderMetricGroup: (args: {\n key: string;\n title: string;\n description?: string;\n density?: 'compact' | 'comfortable';\n items: readonly {\n id: string;\n label: string;\n value: ReactNode;\n hint?: ReactNode;\n tone?: BackofficeTone;\n copyValue?: string;\n }[];\n }) => ReactNode;\n renderTimeline: (args: {\n key: string;\n title: string;\n description?: string;\n events: readonly {\n id: string;\n label: string;\n timestamp?: ReactNode;\n description?: ReactNode;\n actor?: ReactNode;\n tone?: BackofficeTone;\n payload?: ReactNode;\n }[];\n }) => ReactNode;\n renderRelations: (args: {\n key: string;\n title: string;\n description?: string;\n items: readonly {\n id: string;\n label: string;\n count?: number | null;\n href?: string;\n description?: ReactNode;\n tone?: BackofficeTone;\n }[];\n }) => ReactNode;\n renderContextStack: (args: {\n key: string;\n title: string;\n items: readonly {\n id: string;\n label: string;\n value: ReactNode | null | undefined;\n }[];\n }) => ReactNode;\n renderCustomSection: (\n key: string,\n title: string,\n child: ReactNode,\n ) => ReactNode;\n wrapCustomNode: (key: string, node: ReactNode) => ReactNode;\n resolveTableColumns: (columns: readonly unknown[]) => unknown;\n renderTable: (args: {\n key: string;\n title: string;\n description?: string;\n columns: unknown;\n rows: readonly unknown[];\n }) => ReactNode;\n renderPayload: (args: {\n key: string;\n title: string;\n description?: string;\n content: unknown;\n format?: string;\n }) => ReactNode;\n renderKeyValueListSection: (args: {\n key: string;\n title: string;\n description?: string;\n items: readonly { id: string; label: string; value: ReactNode }[];\n }) => ReactNode;\n },\n): ReactNode[] => {\n const { tApp, t, keyPrefix } = options;\n if (blocks == null || blocks.length === 0) {\n return [];\n }\n\n return blocks.map((block, index): ReactNode => {\n const key =\n keyPrefix != null\n ? `${keyPrefix}-${block.kind}-${index}`\n : `${block.kind}-${index}`;\n\n if (block.kind === 'custom') {\n const custom = block.render(node) as ReactNode;\n if (custom == null) {\n return null;\n }\n if (block.label != null) {\n return options.renderCustomSection(\n key,\n resolveLabel(block.label, tApp),\n custom,\n );\n }\n return options.wrapCustomNode(key, custom);\n }\n\n const title =\n 'title' in block\n ? resolveLabel(block.title, tApp)\n : resolveLabel(block.label, tApp);\n const description =\n block.description != null\n ? resolveLabel(block.description, tApp)\n : undefined;\n\n if (block.kind === 'summary') {\n return options.renderKeyValueListSection({\n key,\n title,\n description,\n items: block.items.map((item) => {\n const value = resolveValueLabel(item.value(node), tApp);\n const href = item.href?.(node);\n const tone = item.tone?.(node);\n let valueNode: ReactNode = value ?? t('common.notAvailable');\n if (href != null && href.trim() !== '' && !isEmptyText(value)) {\n valueNode = options.renderLink(href, value);\n } else if (tone != null && !isEmptyText(value)) {\n valueNode = options.renderTag(tone, String(value));\n }\n return {\n id: item.id,\n label: resolveLabel(item.label, tApp),\n value: valueNode,\n };\n }),\n });\n }\n\n if (block.kind === 'metrics') {\n return options.renderMetricGroup({\n key,\n title,\n description,\n density: block.density,\n items: block.items.map((item) => {\n const formattedValue = item.formattedValue?.(node);\n const value = resolveValueLabel(item.value(node), tApp);\n return {\n id: item.id,\n label: resolveLabel(item.label, tApp),\n value: formattedValue ?? value ?? t('common.notAvailable'),\n hint: resolveValueLabel(item.hint?.(node), tApp),\n tone: item.tone?.(node),\n copyValue: item.copyValue?.(node) ?? undefined,\n };\n }),\n });\n }\n\n if (block.kind === 'states') {\n return options.renderKeyValueListSection({\n key,\n title,\n description,\n items: block.states.map((state) => {\n const display = state.getDisplay(state.value(node), node);\n return {\n id: state.id,\n label: resolveLabel(state.label, tApp),\n value: options.renderTag(\n display.tone,\n String(\n resolveValueLabel(display.label, tApp) ??\n t('common.notAvailable'),\n ),\n ),\n };\n }),\n });\n }\n\n if (block.kind === 'context') {\n return options.renderContextStack({\n key,\n title,\n items: block.items.map((item) => {\n const value = resolveValueLabel(item.value(node), tApp);\n const href = item.href?.(node);\n return {\n id: item.id,\n label: resolveLabel(item.label, tApp),\n value:\n href != null && href.trim() !== '' && !isEmptyText(value)\n ? options.renderLink(href, value)\n : value,\n };\n }),\n });\n }\n\n if (block.kind === 'relations') {\n return options.renderRelations({\n key,\n title,\n description,\n items: block.items.map((item) => {\n return {\n id: item.id,\n label: resolveLabel(item.label, tApp),\n count: item.count?.(node) ?? null,\n href: item.href?.(node) ?? undefined,\n description: resolveValueLabel(item.description?.(node), tApp),\n tone: item.tone?.(node),\n };\n }),\n });\n }\n\n if (block.kind === 'timeline') {\n return options.renderTimeline({\n key,\n title,\n description,\n events: block.events.map((event) => {\n const state = event.state?.(node);\n const stateLabel =\n state == null ? null : resolveValueLabel(state.label, tApp);\n const stateText = stateLabel == null ? null : String(stateLabel);\n return {\n id: event.id,\n label:\n stateText == null || stateText.trim() === ''\n ? resolveLabel(event.label, tApp)\n : `${resolveLabel(event.label, tApp)}: ${stateText}`,\n timestamp:\n event.timestamp == null\n ? undefined\n : options.renderDate(\n event.timestamp(node),\n t('common.notAvailable'),\n ),\n description: resolveValueLabel(event.description?.(node), tApp),\n actor: resolveValueLabel(event.actor?.(node), tApp),\n tone: state?.tone,\n };\n }),\n });\n }\n\n if (block.kind === 'audit') {\n return options.renderKeyValueListSection({\n key,\n title,\n description,\n items: block.items.flatMap((item) => {\n const values = [\n {\n id: `${item.id}-timestamp`,\n label: resolveLabel(item.label, tApp),\n value: options.renderDate(\n item.timestamp?.(node),\n t('common.notAvailable'),\n ),\n },\n ];\n const actor = resolveValueLabel(item.actor?.(node), tApp);\n if (!isEmptyText(actor)) {\n values.push({\n id: `${item.id}-actor`,\n label: t('detail.audit.actor'),\n value: actor,\n });\n }\n const source = resolveValueLabel(item.source?.(node), tApp);\n if (!isEmptyText(source)) {\n values.push({\n id: `${item.id}-source`,\n label: t('detail.audit.source'),\n value: source,\n });\n }\n return values;\n }),\n });\n }\n\n if (block.kind === 'references') {\n return options.renderKeyValueListSection({\n key,\n title,\n description,\n items: block.references.map((reference) => {\n const value = resolveValueLabel(reference.value(node), tApp);\n const href = reference.href?.(node);\n return {\n id: reference.id,\n label: resolveLabel(reference.label, tApp),\n value:\n href != null && href.trim() !== '' && !isEmptyText(value)\n ? options.renderLink(href, value)\n : (value ?? t('common.notAvailable')),\n };\n }),\n });\n }\n\n if (block.kind === 'actionResult') {\n const items: { id: string; label: string; value: ReactNode }[] = [];\n const status = block.status?.(node);\n if (status != null) {\n items.push({\n id: `${block.id}-status`,\n label: t('detail.actionResult.status'),\n value: options.renderTag(\n status.tone,\n String(\n resolveValueLabel(status.label, tApp) ?? t('common.notAvailable'),\n ),\n ),\n });\n }\n const message = resolveValueLabel(block.message?.(node), tApp);\n if (!isEmptyText(message)) {\n items.push({\n id: `${block.id}-message`,\n label: t('detail.actionResult.message'),\n value: message,\n });\n }\n block.references?.forEach((reference) => {\n items.push({\n id: reference.id,\n label: resolveLabel(reference.label, tApp),\n value:\n resolveValueLabel(reference.value(node), tApp) ??\n t('common.notAvailable'),\n });\n });\n return options.renderKeyValueListSection({\n key,\n title,\n description,\n items,\n });\n }\n\n if (block.kind === 'technicalFacts') {\n return options.renderKeyValueListSection({\n key,\n title,\n description,\n items: block.facts.map((fact) => {\n const value = resolveValueLabel(fact.value(node), tApp);\n const href = fact.href?.(node);\n return {\n id: fact.id,\n label: resolveLabel(fact.label, tApp),\n value:\n href != null && href.trim() !== '' && !isEmptyText(value)\n ? options.renderLink(href, value)\n : (value ?? t('common.notAvailable')),\n };\n }),\n });\n }\n\n if (block.kind === 'table') {\n return options.renderTable({\n key,\n title,\n description,\n columns: options.resolveTableColumns(\n block.columns as readonly unknown[],\n ),\n rows: block.rows(node) as readonly unknown[],\n });\n }\n\n return options.renderPayload({\n key,\n title,\n description,\n content: block.value(node),\n format: block.format,\n });\n });\n};\n"],"mappings":"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"}
@@ -19,12 +19,13 @@ import { fetchQuery as D } from "relay-runtime";
19
19
  import { useFragment as O, usePaginationFragment as k, usePreloadedQuery as se, useRelayEnvironment as ce } from "react-relay";
20
20
  import { InlineBanner as A } from "@plumile/ui/backoffice/molecules/inline_banner/InlineBanner.js";
21
21
  import { BACKOFFICE_LIST_DEFAULTS as le, BACKOFFICE_LIST_REFETCH_POLICY as j } from "@plumile/backoffice-core/constants.js";
22
- import { stableListVariablesKey as ue } from "@plumile/backoffice-core/state/stableKey.js";
23
- import { LinkButton as M } from "@plumile/ui/atomic/atoms/button/LinkButton.js";
24
- import { TableCell as de } from "@plumile/ui/components/data-table/TableCell.js";
25
- import { EyeSvg as fe } from "@plumile/ui/icons/EyeSvg.js";
22
+ import ue from "@plumile/router/routing/Link.js";
23
+ import { stableListVariablesKey as M } from "@plumile/backoffice-core/state/stableKey.js";
24
+ import { LinkButton as de } from "@plumile/ui/atomic/atoms/button/LinkButton.js";
25
+ import { TableCell as fe } from "@plumile/ui/components/data-table/TableCell.js";
26
+ import { EyeSvg as pe } from "@plumile/ui/icons/EyeSvg.js";
26
27
  //#region src/pages/BackofficeEntityListPage.tsx
27
- var pe = "store-or-network", me = (e, t, n, r) => {
28
+ var me = "store-or-network", he = (e, t, n, r) => {
28
29
  let i = t != null && t.length > 0, a = e;
29
30
  if (i) {
30
31
  let n = [{
@@ -56,11 +57,11 @@ var pe = "store-or-network", me = (e, t, n, r) => {
56
57
  let { t: s } = T(), { t: c } = e(), [l, f] = C(null), p = ce(), m = i.list, g = i.listDefaults ?? m.defaultState ?? {
57
58
  where: null,
58
59
  sort: null
59
- }, v = se(m.query, o.query), k = O(m.fragment, v), j = x(() => m.getRows(k).map((e) => m.toRow(e)), [k, m]), N = x(() => m.getNextCursor?.(v) ?? null, [m, v]), [P, F] = C(j), [I, L] = C(N), [R, z] = C(!1), [B, V] = C(!1), [he, H] = C(!1);
60
+ }, v = se(m.query, o.query), k = O(m.fragment, v), j = x(() => m.getRows(k).map((e) => m.toRow(e)), [k, m]), N = x(() => m.getNextCursor?.(v) ?? null, [m, v]), [P, F] = C(j), [I, L] = C(N), [R, z] = C(!1), [B, V] = C(!1), [ge, H] = C(!1);
60
61
  b(() => {
61
62
  F(j), L(N);
62
63
  }, [N, j]);
63
- let { columns: U, gridTemplateColumns: ge } = x(() => {
64
+ let { columns: U, gridTemplateColumns: _e } = x(() => {
64
65
  let e = n(m.columns, {
65
66
  tApp: s,
66
67
  t: c
@@ -69,29 +70,25 @@ var pe = "store-or-network", me = (e, t, n, r) => {
69
70
  fallback: c("common.notAvailable"),
70
71
  className: re,
71
72
  resolveDetailHref: (e) => i.routes.detail(e),
72
- renderAction: ({ href: e, ariaLabel: t }) => /* @__PURE__ */ w(de.Actions, { children: /* @__PURE__ */ w("span", {
73
+ renderAction: ({ href: e, ariaLabel: t }) => /* @__PURE__ */ w(fe.Actions, { children: /* @__PURE__ */ w(ue, {
74
+ to: e,
73
75
  className: ne,
76
+ "aria-label": t,
74
77
  title: t,
75
- children: /* @__PURE__ */ w(M, {
76
- to: e,
77
- variant: "icon",
78
- size: "small",
79
- "aria-label": t,
80
- children: /* @__PURE__ */ w(fe, {
81
- width: 16,
82
- height: 16
83
- })
78
+ children: /* @__PURE__ */ w(pe, {
79
+ width: 16,
80
+ height: 16
84
81
  })
85
82
  }) })
86
83
  });
87
- return me([...e, t], m.rowFlags, 1, s);
84
+ return he([...e, t], m.rowFlags, 1, s);
88
85
  }, [
89
86
  i.routes,
90
87
  m.columns,
91
88
  m.rowFlags,
92
89
  c,
93
90
  s
94
- ]), W = y((e) => m.getRowId(e), [m]), { state: G, pushState: _e } = u(i), K = G.sort ?? g.sort, { pageSize: q } = le, ve = y((e) => m.buildQueryVariables(e), [m]), J = S(0), ye = S(ue({
91
+ ]), W = y((e) => m.getRowId(e), [m]), { state: G, pushState: ve } = u(i), K = G.sort ?? g.sort, { pageSize: q } = le, ye = y((e) => m.buildQueryVariables(e), [m]), J = S(0), be = S(M({
95
92
  where: g.where,
96
93
  sort: g.sort,
97
94
  count: q
@@ -99,12 +96,12 @@ var pe = "store-or-network", me = (e, t, n, r) => {
99
96
  let t = J.current + 1;
100
97
  J.current = t, e.mode === "append" ? z(!0) : V(!0), H(!1);
101
98
  try {
102
- let n = ve({
99
+ let n = ye({
103
100
  where: e.where,
104
101
  sort: e.sort,
105
102
  count: e.count,
106
103
  cursor: e.cursor
107
- }), r = await D(p, m.query, n, { fetchPolicy: pe }).toPromise();
104
+ }), r = await D(p, m.query, n, { fetchPolicy: me }).toPromise();
108
105
  if (r == null || J.current !== t) return;
109
106
  let i = m.getRows(r).map((e) => m.toRow(e));
110
107
  F((t) => e.mode === "append" ? [...t, ...i] : i), L(m.getNextCursor?.(r) ?? null);
@@ -114,17 +111,17 @@ var pe = "store-or-network", me = (e, t, n, r) => {
114
111
  e.mode === "append" ? z(!1) : V(!1);
115
112
  }
116
113
  }, [
117
- ve,
114
+ ye,
118
115
  p,
119
116
  m
120
117
  ]);
121
118
  b(() => {
122
- let e = ue({
119
+ let e = M({
123
120
  where: G.where,
124
121
  sort: K,
125
122
  count: q
126
123
  });
127
- ye.current !== e && (ye.current = e, Y({
124
+ be.current !== e && (be.current = e, Y({
128
125
  where: G.where,
129
126
  sort: K,
130
127
  count: q,
@@ -155,7 +152,7 @@ var pe = "store-or-network", me = (e, t, n, r) => {
155
152
  K,
156
153
  Y,
157
154
  G.where
158
- ]), be = r({
155
+ ]), xe = r({
159
156
  hasNext: I != null,
160
157
  isLoadingNext: R,
161
158
  loadNext: (e) => {
@@ -170,14 +167,14 @@ var pe = "store-or-network", me = (e, t, n, r) => {
170
167
  });
171
168
  },
172
169
  count: q
173
- }), Z = x(() => i.listActions ?? [], [i.listActions]), Q = x(() => Z.filter((e) => e.isVisible == null ? !0 : e.isVisible(null)), [Z]), xe = x(() => {
170
+ }), Z = x(() => i.listActions ?? [], [i.listActions]), Q = x(() => Z.filter((e) => e.isVisible == null ? !0 : e.isVisible(null)), [Z]), Se = x(() => {
174
171
  if (Q.length !== 0) return /* @__PURE__ */ w("div", {
175
172
  className: ie,
176
173
  children: Q.map((e, t) => {
177
174
  let { variant: n } = e, r = _(e.label, s), i = r;
178
175
  e.ariaLabel != null && (i = _(e.ariaLabel, s));
179
176
  let a = te(n, t), o = e.size ?? "small", c = e.isDisabled?.(null) === !0;
180
- return ee(e) ? /* @__PURE__ */ w(M, {
177
+ return ee(e) ? /* @__PURE__ */ w(de, {
181
178
  to: e.to(null),
182
179
  variant: a,
183
180
  size: o,
@@ -197,8 +194,8 @@ var pe = "store-or-network", me = (e, t, n, r) => {
197
194
  }, e.id) : null;
198
195
  })
199
196
  });
200
- }, [s, Q]), $ = Z.find((e) => e.id === l), Se = null;
201
- return he && (Se = /* @__PURE__ */ w(A, {
197
+ }, [s, Q]), $ = Z.find((e) => e.id === l), Ce = null;
198
+ return ge && (Ce = /* @__PURE__ */ w(A, {
202
199
  tone: "danger",
203
200
  title: c("list.errors.title"),
204
201
  actions: /* @__PURE__ */ w(E, {
@@ -215,19 +212,19 @@ var pe = "store-or-network", me = (e, t, n, r) => {
215
212
  })), /* @__PURE__ */ oe(ae, { children: [/* @__PURE__ */ w(a, {
216
213
  config: i,
217
214
  state: G,
218
- pushState: _e,
219
- headerActions: xe,
215
+ pushState: ve,
216
+ headerActions: Se,
220
217
  rows: P,
221
218
  columns: U,
222
- gridTemplateColumns: ge,
219
+ gridTemplateColumns: _e,
223
220
  getRowId: W,
224
221
  hasNextPage: I != null,
225
222
  isLoadingMore: R,
226
223
  isRefreshing: B,
227
- onLoadMore: be,
224
+ onLoadMore: xe,
228
225
  onRefresh: X,
229
226
  totalCount: null,
230
- statusBanner: Se
227
+ statusBanner: Ce
231
228
  }), $ != null && h($) && /* @__PURE__ */ w(t, {
232
229
  isOpen: !0,
233
230
  action: $,
@@ -238,7 +235,7 @@ var pe = "store-or-network", me = (e, t, n, r) => {
238
235
  onSuccess: X
239
236
  })] });
240
237
  }, P = ({ config: s, prepared: c, breadcrumb: l }) => {
241
- let f = s.list, { t: p } = T(), { t: m } = e(), [g, v] = C(null), b = se(f.query, c.query), { data: S, loadNext: ae, hasNext: D, isLoadingNext: O, refetch: ce } = k(f.fragment, b), A = f.getConnection(S), ue = x(() => A.edges.map((e) => f.toRow(e.node)), [A.edges, f]), { columns: pe, gridTemplateColumns: N } = x(() => {
238
+ let f = s.list, { t: p } = T(), { t: m } = e(), [g, v] = C(null), b = se(f.query, c.query), { data: S, loadNext: ae, hasNext: D, isLoadingNext: O, refetch: ce } = k(f.fragment, b), A = f.getConnection(S), M = x(() => A.edges.map((e) => f.toRow(e.node)), [A.edges, f]), { columns: me, gridTemplateColumns: N } = x(() => {
242
239
  let e = n(f.columns, {
243
240
  tApp: p,
244
241
  t: m
@@ -247,22 +244,18 @@ var pe = "store-or-network", me = (e, t, n, r) => {
247
244
  fallback: m("common.notAvailable"),
248
245
  className: re,
249
246
  resolveDetailHref: (e) => s.routes.detail(e),
250
- renderAction: ({ href: e, ariaLabel: t }) => /* @__PURE__ */ w(de.Actions, { children: /* @__PURE__ */ w("span", {
247
+ renderAction: ({ href: e, ariaLabel: t }) => /* @__PURE__ */ w(fe.Actions, { children: /* @__PURE__ */ w(ue, {
248
+ to: e,
251
249
  className: ne,
250
+ "aria-label": t,
252
251
  title: t,
253
- children: /* @__PURE__ */ w(M, {
254
- to: e,
255
- variant: "icon",
256
- size: "small",
257
- "aria-label": t,
258
- children: /* @__PURE__ */ w(fe, {
259
- width: 16,
260
- height: 16
261
- })
252
+ children: /* @__PURE__ */ w(pe, {
253
+ width: 16,
254
+ height: 16
262
255
  })
263
256
  }) })
264
257
  });
265
- return me([...e, t], f.rowFlags, 1, p);
258
+ return he([...e, t], f.rowFlags, 1, p);
266
259
  }, [
267
260
  s.routes,
268
261
  f.columns,
@@ -292,19 +285,19 @@ var pe = "store-or-network", me = (e, t, n, r) => {
292
285
  },
293
286
  fetchPolicy: j,
294
287
  buildQueryVariables: f.buildQueryVariables
295
- }), he = r({
288
+ }), ge = r({
296
289
  hasNext: D,
297
290
  isLoadingNext: O,
298
291
  loadNext: ae,
299
292
  count: z
300
- }), H = x(() => s.listActions ?? [], [s.listActions]), U = x(() => H.filter((e) => e.isVisible == null ? !0 : e.isVisible(null)), [H]), ge = x(() => {
293
+ }), H = x(() => s.listActions ?? [], [s.listActions]), U = x(() => H.filter((e) => e.isVisible == null ? !0 : e.isVisible(null)), [H]), _e = x(() => {
301
294
  if (U.length !== 0) return /* @__PURE__ */ w("div", {
302
295
  className: ie,
303
296
  children: U.map((e, t) => {
304
297
  let { variant: n } = e, r = _(e.label, p), i = r;
305
298
  e.ariaLabel != null && (i = _(e.ariaLabel, p));
306
299
  let a = te(n, t), o = e.size ?? "small", s = e.isDisabled?.(null) === !0;
307
- return ee(e) ? /* @__PURE__ */ w(M, {
300
+ return ee(e) ? /* @__PURE__ */ w(de, {
308
301
  to: e.to(null),
309
302
  variant: a,
310
303
  size: o,
@@ -331,15 +324,15 @@ var pe = "store-or-network", me = (e, t, n, r) => {
331
324
  config: s,
332
325
  state: F,
333
326
  pushState: I,
334
- headerActions: ge,
335
- rows: ue,
336
- columns: pe,
327
+ headerActions: _e,
328
+ rows: M,
329
+ columns: me,
337
330
  gridTemplateColumns: N,
338
331
  getRowId: P,
339
332
  hasNextPage: D,
340
333
  isLoadingMore: O,
341
334
  isRefreshing: B,
342
- onLoadMore: he,
335
+ onLoadMore: ge,
343
336
  onRefresh: V,
344
337
  totalCount: A.totalCount ?? null
345
338
  }), W != null && h(W) && /* @__PURE__ */ w(t, {
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeEntityListPage.js","names":[],"sources":["../../../src/pages/BackofficeEntityListPage.tsx"],"sourcesContent":["import {\n type JSX,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport {\n useFragment,\n usePaginationFragment,\n usePreloadedQuery,\n useRelayEnvironment,\n} from 'react-relay';\nimport { fetchQuery } from 'relay-runtime';\nimport {\n BACKOFFICE_LIST_DEFAULTS,\n BACKOFFICE_LIST_REFETCH_POLICY,\n} from '@plumile/backoffice-core/constants.js';\nimport { stableListVariablesKey } from '@plumile/backoffice-core/state/stableKey.js';\nimport type {\n BackofficeEntityManifestItem,\n BackofficePreparedListRoute,\n BackofficeRuntimeResolvedListFacetConfig,\n BackofficeRowFlagSpec,\n} from '@plumile/backoffice-core/types.js';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { LinkButton } from '@plumile/ui/atomic/atoms/button/LinkButton.js';\nimport { InlineBanner } from '@plumile/ui/backoffice/molecules/inline_banner/InlineBanner.js';\nimport {\n type DataTableColumn,\n type GetRowId,\n} from '@plumile/ui/components/data-table/DataTable.js';\nimport { TableCell } from '@plumile/ui/components/data-table/TableCell.js';\nimport { EyeSvg } from '@plumile/ui/icons/EyeSvg.js';\nimport { BackofficeEntityListScaffold } from '../components/backoffice/scaffolds/BackofficeEntityListScaffold.js';\nimport { LazyBackofficeEntityActionFormDialog } from '../components/backoffice/actions/LazyBackofficeEntityActionFormDialog.js';\nimport { buildDataTableColumns } from '../components/backoffice/columns/buildDataTableColumns.js';\nimport { RowFlagsCell } from '../components/backoffice/list/RowFlagsCell.js';\nimport { useBackofficeListUrlState } from '../hooks/useBackofficeListUrlState.js';\nimport { useBackofficeLoadMore } from '../hooks/useBackofficeLoadMore.js';\nimport { useBackofficeListRefetch } from '../hooks/useBackofficeListRefetch.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport * as pageStyles from './backofficeEntityListPage.css.js';\nimport { rowFlagsColumnCell } from '../components/backoffice/list/RowFlagsCell.css.js';\nimport { BackofficeRightPageLayout } from '../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport { buildEntityListBreadcrumb } from '../components/backoffice/layout/breadcrumb/buildBreadcrumbs.js';\nimport {\n buildActionsColumn,\n computeActionsColumnWidthPx,\n computeRowFlagsColumnWidthPx,\n isFormMutationAction,\n isConnectionListConfig,\n isRecordListConfig,\n isRouteAction,\n resolveLabel,\n resolveActionVariant,\n resolveTrackBySize,\n type ConnectionListConfig,\n type RecordListConfig,\n} from './BackofficeEntityListPage.helpers.js';\n\nexport type BackofficeEntityListPageProps = {\n entityManifest: BackofficeEntityManifestItem;\n config: BackofficeRuntimeResolvedListFacetConfig;\n prepared: BackofficePreparedListRoute;\n};\n\ntype RecordFetchMode = 'append' | 'reset';\ntype RecordFetchInput = {\n where: Record<string, unknown> | null;\n sort: string | null;\n count: number;\n cursor: string | null;\n mode: RecordFetchMode;\n};\n\nconst RECORD_FETCH_POLICY = 'store-or-network' as const;\n\nconst applyListEdgeColumns = <Row,>(\n inputColumns: readonly DataTableColumn<Row>[],\n rowFlags: readonly BackofficeRowFlagSpec<Row>[] | undefined,\n actionCount: number,\n tApp: TFunction,\n): {\n columns: readonly DataTableColumn<Row>[];\n gridTemplateColumns?: string;\n} => {\n const hasFlags = rowFlags != null && rowFlags.length > 0;\n\n let columns = inputColumns;\n if (hasFlags) {\n const flagsColumn: DataTableColumn<Row> = {\n id: '__rowFlags',\n header: '',\n className: rowFlagsColumnCell,\n mobileRole: 'badge',\n cell: (row) => {\n return <RowFlagsCell row={row} flags={rowFlags} tApp={tApp} />;\n },\n };\n\n // Ensure we never pick the flags column as \"primary\".\n const withFlags = [flagsColumn, ...inputColumns];\n const hasPrimary = withFlags.some((col) => {\n return col.isPrimary === true;\n });\n\n columns = withFlags;\n if (!hasPrimary) {\n columns = withFlags.map((col, index) => {\n if (index === 1) {\n return { ...col, isPrimary: true };\n }\n return col;\n });\n }\n }\n\n let flagCount = 0;\n if (hasFlags) {\n flagCount = rowFlags.length;\n }\n const flagsWidthPx = computeRowFlagsColumnWidthPx(flagCount);\n const actionsWidthPx = computeActionsColumnWidthPx(actionCount);\n\n // We always include the right-side \"actions\" column in list pages.\n let leftColumnCount = 0;\n if (hasFlags) {\n leftColumnCount = 1;\n }\n const middleCount = columns.length - leftColumnCount - 1;\n\n const middleTracks = columns\n .slice(leftColumnCount, leftColumnCount + Math.max(0, middleCount))\n .map((column) => {\n return resolveTrackBySize(column as DataTableColumn<unknown>, '1fr');\n })\n .join(' ');\n\n let gridTemplateColumns = '';\n if (hasFlags) {\n gridTemplateColumns = `${flagsWidthPx}px ${middleTracks} ${actionsWidthPx}px`;\n } else {\n gridTemplateColumns = `${middleTracks} ${actionsWidthPx}px`;\n }\n\n return { columns, gridTemplateColumns };\n};\n\nconst BackofficeEntityRecordListPage = ({\n config,\n prepared,\n}: Omit<BackofficeEntityListPageProps, 'config'> & {\n config: RecordListConfig;\n}): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const [activeFormActionId, setActiveFormActionId] = useState<string | null>(\n null,\n );\n const environment = useRelayEnvironment();\n\n const listConfig = config.list;\n const listDefaults = config.listDefaults ??\n listConfig.defaultState ?? { where: null, sort: null };\n const queryData = usePreloadedQuery(listConfig.query, prepared.query);\n const fragmentData = useFragment(listConfig.fragment, queryData as never);\n\n const initialRows = useMemo(() => {\n return listConfig.getRows(fragmentData).map((row) => {\n return listConfig.toRow(row);\n });\n }, [fragmentData, listConfig]);\n\n const initialCursor = useMemo(() => {\n return listConfig.getNextCursor?.(queryData) ?? null;\n }, [listConfig, queryData]);\n\n const [rows, setRows] = useState(initialRows);\n const [nextCursor, setNextCursor] = useState(initialCursor);\n const [isLoadingMore, setIsLoadingMore] = useState(false);\n const [isRefreshing, setIsRefreshing] = useState(false);\n const [fetchError, setFetchError] = useState(false);\n\n useEffect(() => {\n setRows(initialRows);\n setNextCursor(initialCursor);\n }, [initialCursor, initialRows]);\n\n const { columns, gridTemplateColumns } = useMemo((): {\n columns: readonly DataTableColumn<unknown>[];\n gridTemplateColumns?: string;\n } => {\n const baseColumns = buildDataTableColumns(listConfig.columns, {\n tApp,\n t,\n });\n const actionsColumn = buildActionsColumn({\n ariaLabel: t('actions.view'),\n fallback: t('common.notAvailable'),\n className: pageStyles.actionsColumnCell,\n resolveDetailHref: (id) => {\n return config.routes.detail(id);\n },\n renderAction: ({ href, ariaLabel }) => {\n return (\n <TableCell.Actions>\n <span className={pageStyles.actionTrigger} title={ariaLabel}>\n <LinkButton\n to={href}\n variant=\"icon\"\n size=\"small\"\n aria-label={ariaLabel}\n >\n <EyeSvg width={16} height={16} />\n </LinkButton>\n </span>\n </TableCell.Actions>\n );\n },\n });\n const allColumns = [...baseColumns, actionsColumn];\n return applyListEdgeColumns(allColumns, listConfig.rowFlags, 1, tApp);\n }, [config.routes, listConfig.columns, listConfig.rowFlags, t, tApp]);\n\n const getRowId = useCallback<GetRowId<unknown>>(\n (row) => {\n return listConfig.getRowId(row);\n },\n [listConfig],\n );\n\n const { state, pushState } = useBackofficeListUrlState(config);\n const resolvedSort = state.sort ?? listDefaults.sort;\n const { pageSize } = BACKOFFICE_LIST_DEFAULTS;\n\n const buildVariables = useCallback(\n (input: {\n where: Record<string, unknown> | null;\n sort: string | null;\n count: number;\n cursor: string | null;\n }) => {\n return listConfig.buildQueryVariables(input);\n },\n [listConfig],\n );\n\n const requestIdRef = useRef(0);\n const lastRefetchKeyRef = useRef(\n stableListVariablesKey({\n where: listDefaults.where,\n sort: listDefaults.sort,\n count: pageSize,\n }),\n );\n\n const runFetch = useCallback(\n async (input: RecordFetchInput) => {\n const requestId = requestIdRef.current + 1;\n requestIdRef.current = requestId;\n\n if (input.mode === 'append') {\n setIsLoadingMore(true);\n } else {\n setIsRefreshing(true);\n }\n setFetchError(false);\n\n try {\n const variables = buildVariables({\n where: input.where,\n sort: input.sort,\n count: input.count,\n cursor: input.cursor,\n });\n\n const response = await fetchQuery(\n environment,\n listConfig.query,\n variables as never,\n { fetchPolicy: RECORD_FETCH_POLICY },\n ).toPromise();\n\n if (response == null || requestIdRef.current !== requestId) {\n return;\n }\n\n const nextRows = listConfig.getRows(response as never).map((row) => {\n return listConfig.toRow(row);\n });\n setRows((prev) => {\n if (input.mode === 'append') {\n return [...prev, ...nextRows];\n }\n return nextRows;\n });\n const cursor = listConfig.getNextCursor?.(response) ?? null;\n setNextCursor(cursor);\n } catch {\n if (requestIdRef.current === requestId) {\n setFetchError(true);\n }\n } finally {\n if (input.mode === 'append') {\n setIsLoadingMore(false);\n } else {\n setIsRefreshing(false);\n }\n }\n },\n [buildVariables, environment, listConfig],\n );\n\n useEffect(() => {\n const key = stableListVariablesKey({\n where: state.where,\n sort: resolvedSort,\n count: pageSize,\n });\n if (lastRefetchKeyRef.current === key) {\n return;\n }\n lastRefetchKeyRef.current = key;\n runFetch({\n where: state.where,\n sort: resolvedSort,\n count: pageSize,\n cursor: null,\n mode: 'reset',\n }).catch(() => {\n setFetchError(true);\n });\n }, [pageSize, resolvedSort, runFetch, state.where]);\n\n const handleRefresh = useCallback(() => {\n if (isRefreshing) {\n return;\n }\n runFetch({\n where: state.where,\n sort: resolvedSort,\n count: pageSize,\n cursor: null,\n mode: 'reset',\n }).catch(() => {\n setFetchError(true);\n });\n }, [isRefreshing, pageSize, resolvedSort, runFetch, state.where]);\n\n const handleLoadMore = useBackofficeLoadMore({\n hasNext: nextCursor != null,\n isLoadingNext: isLoadingMore,\n loadNext: (count) => {\n if (nextCursor == null) {\n return;\n }\n runFetch({\n where: state.where,\n sort: resolvedSort,\n count,\n cursor: nextCursor,\n mode: 'append',\n }).catch(() => {\n setFetchError(true);\n });\n },\n count: pageSize,\n });\n\n const listActions = useMemo(() => {\n return config.listActions ?? [];\n }, [config.listActions]);\n const visibleActions = useMemo(() => {\n return listActions.filter((action) => {\n if (action.isVisible == null) {\n return true;\n }\n return action.isVisible(null);\n });\n }, [listActions]);\n\n const headerActions = useMemo(() => {\n if (visibleActions.length === 0) {\n return undefined;\n }\n return (\n <div className={pageStyles.headerActions}>\n {visibleActions.map((action, index) => {\n const { variant: actionVariant } = action;\n const label = resolveLabel(action.label, tApp);\n let ariaLabel = label;\n if (action.ariaLabel != null) {\n ariaLabel = resolveLabel(action.ariaLabel, tApp);\n }\n const variant = resolveActionVariant(actionVariant, index);\n const size = action.size ?? 'small';\n const isDisabled = action.isDisabled?.(null) === true;\n\n if (isRouteAction(action)) {\n const href = action.to(null);\n return (\n <LinkButton\n key={action.id}\n to={href}\n variant={variant}\n size={size}\n isDisabled={isDisabled}\n aria-label={ariaLabel}\n >\n {label}\n </LinkButton>\n );\n }\n\n if (isFormMutationAction(action)) {\n return (\n <Button\n key={action.id}\n type=\"button\"\n variant={variant}\n size={size}\n disabled={isDisabled}\n onClick={() => {\n setActiveFormActionId(action.id);\n }}\n aria-label={ariaLabel}\n >\n {label}\n </Button>\n );\n }\n\n return null;\n })}\n </div>\n );\n }, [tApp, visibleActions]);\n\n const activeFormAction = listActions.find((action) => {\n return action.id === activeFormActionId;\n });\n\n let statusBanner: JSX.Element | null = null;\n if (fetchError) {\n statusBanner = (\n <InlineBanner\n tone=\"danger\"\n title={t('list.errors.title')}\n actions={\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={handleRefresh}\n >\n {t('list.actions.retry')}\n </Button>\n }\n onDismiss={() => {\n setFetchError(false);\n }}\n >\n {t('list.errors.fetchFailed')}\n </InlineBanner>\n );\n }\n\n return (\n <>\n <BackofficeEntityListScaffold\n config={config}\n state={state}\n pushState={pushState}\n headerActions={headerActions}\n rows={rows}\n columns={columns}\n gridTemplateColumns={gridTemplateColumns}\n getRowId={getRowId}\n hasNextPage={nextCursor != null}\n isLoadingMore={isLoadingMore}\n isRefreshing={isRefreshing}\n onLoadMore={handleLoadMore}\n onRefresh={handleRefresh}\n totalCount={null}\n statusBanner={statusBanner}\n />\n {activeFormAction != null && isFormMutationAction(activeFormAction) && (\n <LazyBackofficeEntityActionFormDialog\n isOpen\n action={activeFormAction}\n node={null}\n onClose={() => {\n setActiveFormActionId(null);\n }}\n onSuccess={handleRefresh}\n />\n )}\n </>\n );\n};\n\nconst BackofficeEntityConnectionListPage = ({\n config,\n prepared,\n breadcrumb,\n}: Omit<BackofficeEntityListPageProps, 'config'> & {\n config: ConnectionListConfig;\n breadcrumb: ReturnType<typeof buildEntityListBreadcrumb>;\n}): JSX.Element | null => {\n const listConfig = config.list;\n\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const [activeFormActionId, setActiveFormActionId] = useState<string | null>(\n null,\n );\n\n const queryData = usePreloadedQuery(listConfig.query, prepared.query);\n const {\n data: fragmentData,\n loadNext,\n hasNext,\n isLoadingNext,\n refetch,\n } = usePaginationFragment(listConfig.fragment, queryData as never);\n\n const connection = listConfig.getConnection(fragmentData);\n\n const rows = useMemo(() => {\n return connection.edges.map((edge) => {\n return listConfig.toRow(edge.node);\n });\n }, [connection.edges, listConfig]);\n\n const { columns, gridTemplateColumns } = useMemo((): {\n columns: readonly DataTableColumn<unknown>[];\n gridTemplateColumns?: string;\n } => {\n const baseColumns = buildDataTableColumns(listConfig.columns, {\n tApp,\n t,\n });\n const actionsColumn = buildActionsColumn({\n ariaLabel: t('actions.view'),\n fallback: t('common.notAvailable'),\n className: pageStyles.actionsColumnCell,\n resolveDetailHref: (id) => {\n return config.routes.detail(id);\n },\n renderAction: ({ href, ariaLabel }) => {\n return (\n <TableCell.Actions>\n <span className={pageStyles.actionTrigger} title={ariaLabel}>\n <LinkButton\n to={href}\n variant=\"icon\"\n size=\"small\"\n aria-label={ariaLabel}\n >\n <EyeSvg width={16} height={16} />\n </LinkButton>\n </span>\n </TableCell.Actions>\n );\n },\n });\n const allColumns = [...baseColumns, actionsColumn];\n return applyListEdgeColumns(allColumns, listConfig.rowFlags, 1, tApp);\n }, [config.routes, listConfig.columns, listConfig.rowFlags, t, tApp]);\n\n const getRowId = useCallback<GetRowId<unknown>>(\n (row) => {\n return listConfig.getRowId(row);\n },\n [listConfig],\n );\n\n const { state, pushState } = useBackofficeListUrlState(config);\n const listDefaults = config.listDefaults ??\n listConfig.defaultState ?? { where: null, sort: null };\n const resolvedSort = state.sort ?? listDefaults.sort;\n const { pageSize } = BACKOFFICE_LIST_DEFAULTS;\n\n const baseVariables = useMemo(() => {\n return {\n where: state.where,\n sort: resolvedSort,\n count: pageSize,\n cursor: null,\n };\n }, [pageSize, resolvedSort, state.where]);\n\n const { isRefreshing, onRefresh } = useBackofficeListRefetch({\n refetch,\n variables: baseVariables,\n defaults: {\n where: listDefaults.where,\n sort: listDefaults.sort,\n count: pageSize,\n cursor: null,\n },\n fetchPolicy: BACKOFFICE_LIST_REFETCH_POLICY,\n buildQueryVariables: listConfig.buildQueryVariables,\n });\n\n const handleLoadMore = useBackofficeLoadMore({\n hasNext,\n isLoadingNext,\n loadNext,\n count: pageSize,\n });\n\n const listActions = useMemo(() => {\n return config.listActions ?? [];\n }, [config.listActions]);\n const visibleActions = useMemo(() => {\n return listActions.filter((action) => {\n if (action.isVisible == null) {\n return true;\n }\n return action.isVisible(null);\n });\n }, [listActions]);\n\n const headerActions = useMemo(() => {\n if (visibleActions.length === 0) {\n return undefined;\n }\n return (\n <div className={pageStyles.headerActions}>\n {visibleActions.map((action, index) => {\n const { variant: actionVariant } = action;\n const label = resolveLabel(action.label, tApp);\n let ariaLabel = label;\n if (action.ariaLabel != null) {\n ariaLabel = resolveLabel(action.ariaLabel, tApp);\n }\n const variant = resolveActionVariant(actionVariant, index);\n const size = action.size ?? 'small';\n const isDisabled = action.isDisabled?.(null) === true;\n\n if (isRouteAction(action)) {\n const href = action.to(null);\n return (\n <LinkButton\n key={action.id}\n to={href}\n variant={variant}\n size={size}\n isDisabled={isDisabled}\n aria-label={ariaLabel}\n >\n {label}\n </LinkButton>\n );\n }\n\n if (isFormMutationAction(action)) {\n return (\n <Button\n key={action.id}\n type=\"button\"\n variant={variant}\n size={size}\n disabled={isDisabled}\n onClick={() => {\n setActiveFormActionId(action.id);\n }}\n aria-label={ariaLabel}\n >\n {label}\n </Button>\n );\n }\n\n return null;\n })}\n </div>\n );\n }, [tApp, visibleActions]);\n\n const activeFormAction = listActions.find((action) => {\n return action.id === activeFormActionId;\n });\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <BackofficeEntityListScaffold\n config={config}\n state={state}\n pushState={pushState}\n headerActions={headerActions}\n rows={rows}\n columns={columns}\n gridTemplateColumns={gridTemplateColumns}\n getRowId={getRowId}\n hasNextPage={hasNext}\n isLoadingMore={isLoadingNext}\n isRefreshing={isRefreshing}\n onLoadMore={handleLoadMore}\n onRefresh={onRefresh}\n totalCount={connection.totalCount ?? null}\n />\n {activeFormAction != null && isFormMutationAction(activeFormAction) && (\n <LazyBackofficeEntityActionFormDialog\n isOpen\n action={activeFormAction}\n node={null}\n onClose={() => {\n setActiveFormActionId(null);\n }}\n onSuccess={onRefresh}\n />\n )}\n </BackofficeRightPageLayout>\n );\n};\n\nexport const BackofficeEntityListPage = ({\n entityManifest,\n config,\n prepared,\n}: BackofficeEntityListPageProps): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const breadcrumb = buildEntityListBreadcrumb(config, tApp);\n\n if (isRecordListConfig(config)) {\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <BackofficeEntityRecordListPage\n entityManifest={entityManifest}\n config={config}\n prepared={prepared}\n />\n </BackofficeRightPageLayout>\n );\n }\n if (!isConnectionListConfig(config)) {\n return null;\n }\n return (\n <BackofficeEntityConnectionListPage\n entityManifest={entityManifest}\n config={config}\n prepared={prepared}\n breadcrumb={breadcrumb}\n />\n );\n};\n\nexport default BackofficeEntityListPage;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA+EA,IAAM,KAAsB,oBAEtB,MACJ,GACA,GACA,GACA,MAIG;CACH,IAAM,IAAW,KAAY,QAAQ,EAAS,SAAS,GAEnD,IAAU;CACd,IAAI,GAAU;EAYZ,IAAM,IAAY,CAAC;GAVjB,IAAI;GACJ,QAAQ;GACR,WAAW;GACX,YAAY;GACZ,OAAO,MACE,kBAAC,GAAD;IAAmB;IAAK,OAAO;IAAgB;IAAQ,CAAA;GAK/C,EAAa,GAAG,EAAa,EAC1C,IAAa,EAAU,MAAM,MAC1B,EAAI,cAAc,GACzB;EAGF,AADA,IAAU,GACL,MACH,IAAU,EAAU,KAAK,GAAK,MACxB,MAAU,IACL;GAAE,GAAG;GAAK,WAAW;GAAM,GAE7B,EACP;;CAIN,IAAI,IAAY;CAChB,AAAI,MACF,IAAY,EAAS;CAEvB,IAAM,IAAe,EAA6B,EAAU,EACtD,IAAiB,EAA4B,EAAY,EAG3D,IAAkB;CACtB,AAAI,MACF,IAAkB;CAEpB,IAAM,IAAc,EAAQ,SAAS,IAAkB,GAEjD,IAAe,EAClB,MAAM,GAAiB,IAAkB,KAAK,IAAI,GAAG,EAAY,CAAC,CAClE,KAAK,MACG,EAAmB,GAAoC,MAAM,CACpE,CACD,KAAK,IAAI,EAER,IAAsB;CAO1B,OANA,AAGE,IAHE,IACoB,GAAG,EAAa,KAAK,EAAa,GAAG,EAAe,MAEpD,GAAG,EAAa,GAAG,EAAe,KAGnD;EAAE;EAAS;EAAqB;GAGnC,KAAkC,EACtC,WACA,kBAGwB;CACxB,IAAM,EAAE,GAAG,MAAS,GAAgB,EAC9B,EAAE,SAAM,GAA+B,EACvC,CAAC,GAAoB,KAAyB,EAClD,KACD,EACK,IAAc,IAAqB,EAEnC,IAAa,EAAO,MACpB,IAAe,EAAO,gBAC1B,EAAW,gBAAgB;EAAE,OAAO;EAAM,MAAM;EAAM,EAClD,IAAY,GAAkB,EAAW,OAAO,EAAS,MAAM,EAC/D,IAAe,EAAY,EAAW,UAAU,EAAmB,EAEnE,IAAc,QACX,EAAW,QAAQ,EAAa,CAAC,KAAK,MACpC,EAAW,MAAM,EAAI,CAC5B,EACD,CAAC,GAAc,EAAW,CAAC,EAExB,IAAgB,QACb,EAAW,gBAAgB,EAAU,IAAI,MAC/C,CAAC,GAAY,EAAU,CAAC,EAErB,CAAC,GAAM,KAAW,EAAS,EAAY,EACvC,CAAC,GAAY,KAAiB,EAAS,EAAc,EACrD,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,CAAC,GAAc,KAAmB,EAAS,GAAM,EACjD,CAAC,IAAY,KAAiB,EAAS,GAAM;CAEnD,QAAgB;EAEd,AADA,EAAQ,EAAY,EACpB,EAAc,EAAc;IAC3B,CAAC,GAAe,EAAY,CAAC;CAEhC,IAAM,EAAE,YAAS,4BAAwB,QAGpC;EACH,IAAM,IAAc,EAAsB,EAAW,SAAS;GAC5D;GACA;GACD,CAAC,EACI,IAAgB,EAAmB;GACvC,WAAW,EAAE,eAAe;GAC5B,UAAU,EAAE,sBAAsB;GAClC,WAAW;GACX,oBAAoB,MACX,EAAO,OAAO,OAAO,EAAG;GAEjC,eAAe,EAAE,SAAM,mBAEnB,kBAAC,GAAU,SAAX,EAAA,UACE,kBAAC,QAAD;IAAM,WAAW;IAA0B,OAAO;cAChD,kBAAC,GAAD;KACE,IAAI;KACJ,SAAQ;KACR,MAAK;KACL,cAAY;eAEZ,kBAAC,IAAD;MAAQ,OAAO;MAAI,QAAQ;MAAM,CAAA;KACtB,CAAA;IACR,CAAA,EACW,CAAA;GAGzB,CAAC;EAEF,OAAO,GAAqB,CADR,GAAG,GAAa,EACR,EAAY,EAAW,UAAU,GAAG,EAAK;IACpE;EAAC,EAAO;EAAQ,EAAW;EAAS,EAAW;EAAU;EAAG;EAAK,CAAC,EAE/D,IAAW,GACd,MACQ,EAAW,SAAS,EAAI,EAEjC,CAAC,EAAW,CACb,EAEK,EAAE,UAAO,kBAAc,EAA0B,EAAO,EACxD,IAAe,EAAM,QAAQ,EAAa,MAC1C,EAAE,gBAAa,IAEf,KAAiB,GACpB,MAMQ,EAAW,oBAAoB,EAAM,EAE9C,CAAC,EAAW,CACb,EAEK,IAAe,EAAO,EAAE,EACxB,KAAoB,EACxB,GAAuB;EACrB,OAAO,EAAa;EACpB,MAAM,EAAa;EACnB,OAAO;EACR,CAAC,CACH,EAEK,IAAW,EACf,OAAO,MAA4B;EACjC,IAAM,IAAY,EAAa,UAAU;EAQzC,AAPA,EAAa,UAAU,GAEnB,EAAM,SAAS,WACjB,EAAiB,GAAK,GAEtB,EAAgB,GAAK,EAEvB,EAAc,GAAM;EAEpB,IAAI;GACF,IAAM,IAAY,GAAe;IAC/B,OAAO,EAAM;IACb,MAAM,EAAM;IACZ,OAAO,EAAM;IACb,QAAQ,EAAM;IACf,CAAC,EAEI,IAAW,MAAM,EACrB,GACA,EAAW,OACX,GACA,EAAE,aAAa,IAAqB,CACrC,CAAC,WAAW;GAEb,IAAI,KAAY,QAAQ,EAAa,YAAY,GAC/C;GAGF,IAAM,IAAW,EAAW,QAAQ,EAAkB,CAAC,KAAK,MACnD,EAAW,MAAM,EAAI,CAC5B;GAQF,AAPA,GAAS,MACH,EAAM,SAAS,WACV,CAAC,GAAG,GAAM,GAAG,EAAS,GAExB,EACP,EAEF,EADe,EAAW,gBAAgB,EAAS,IAAI,KAClC;UACf;GACN,AAAI,EAAa,YAAY,KAC3B,EAAc,GAAK;YAEb;GACR,AAAI,EAAM,SAAS,WACjB,EAAiB,GAAM,GAEvB,EAAgB,GAAM;;IAI5B;EAAC;EAAgB;EAAa;EAAW,CAC1C;CAED,QAAgB;EACd,IAAM,IAAM,GAAuB;GACjC,OAAO,EAAM;GACb,MAAM;GACN,OAAO;GACR,CAAC;EACE,GAAkB,YAAY,MAGlC,GAAkB,UAAU,GAC5B,EAAS;GACP,OAAO,EAAM;GACb,MAAM;GACN,OAAO;GACP,QAAQ;GACR,MAAM;GACP,CAAC,CAAC,YAAY;GACb,EAAc,GAAK;IACnB;IACD;EAAC;EAAU;EAAc;EAAU,EAAM;EAAM,CAAC;CAEnD,IAAM,IAAgB,QAAkB;EAClC,KAGJ,EAAS;GACP,OAAO,EAAM;GACb,MAAM;GACN,OAAO;GACP,QAAQ;GACR,MAAM;GACP,CAAC,CAAC,YAAY;GACb,EAAc,GAAK;IACnB;IACD;EAAC;EAAc;EAAU;EAAc;EAAU,EAAM;EAAM,CAAC,EAE3D,KAAiB,EAAsB;EAC3C,SAAS,KAAc;EACvB,eAAe;EACf,WAAW,MAAU;GACf,KAAc,QAGlB,EAAS;IACP,OAAO,EAAM;IACb,MAAM;IACN;IACA,QAAQ;IACR,MAAM;IACP,CAAC,CAAC,YAAY;IACb,EAAc,GAAK;KACnB;;EAEJ,OAAO;EACR,CAAC,EAEI,IAAc,QACX,EAAO,eAAe,EAAE,EAC9B,CAAC,EAAO,YAAY,CAAC,EAClB,IAAiB,QACd,EAAY,QAAQ,MACrB,EAAO,aAAa,OACf,KAEF,EAAO,UAAU,KAAK,CAC7B,EACD,CAAC,EAAY,CAAC,EAEX,KAAgB,QAAc;EAC9B,MAAe,WAAW,GAG9B,OACE,kBAAC,OAAD;GAAK,WAAW;aACb,EAAe,KAAK,GAAQ,MAAU;IACrC,IAAM,EAAE,SAAS,MAAkB,GAC7B,IAAQ,EAAa,EAAO,OAAO,EAAK,EAC1C,IAAY;IAChB,AAAI,EAAO,aAAa,SACtB,IAAY,EAAa,EAAO,WAAW,EAAK;IAElD,IAAM,IAAU,GAAqB,GAAe,EAAM,EACpD,IAAO,EAAO,QAAQ,SACtB,IAAa,EAAO,aAAa,KAAK,KAAK;IAoCjD,OAlCI,GAAc,EAAO,GAGrB,kBAAC,GAAD;KAEE,IAJS,EAAO,GAAG,KAIf;KACK;KACH;KACM;KACZ,cAAY;eAEX;KACU,EARN,EAAO,GAQD,GAIb,EAAqB,EAAO,GAE5B,kBAAC,GAAD;KAEE,MAAK;KACI;KACH;KACN,UAAU;KACV,eAAe;MACb,EAAsB,EAAO,GAAG;;KAElC,cAAY;eAEX;KACM,EAXF,EAAO,GAWL,GAIN;KACP;GACE,CAAA;IAEP,CAAC,GAAM,EAAe,CAAC,EAEpB,IAAmB,EAAY,MAAM,MAClC,EAAO,OAAO,EACrB,EAEE,KAAmC;CAyBvC,OAxBI,OACF,KACE,kBAAC,GAAD;EACE,MAAK;EACL,OAAO,EAAE,oBAAoB;EAC7B,SACE,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,MAAK;GACL,SAAS;aAER,EAAE,qBAAqB;GACjB,CAAA;EAEX,iBAAiB;GACf,EAAc,GAAM;;YAGrB,EAAE,0BAA0B;EAChB,CAAA,GAKjB,mBAAA,IAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EACU;EACD;EACI;EACI,eAAA;EACT;EACG;EACY;EACX;EACV,aAAa,KAAc;EACZ;EACD;EACd,YAAY;EACZ,WAAW;EACX,YAAY;EACE;EACd,CAAA,EACD,KAAoB,QAAQ,EAAqB,EAAiB,IACjE,kBAAC,GAAD;EACE,QAAA;EACA,QAAQ;EACR,MAAM;EACN,eAAe;GACb,EAAsB,KAAK;;EAE7B,WAAW;EACX,CAAA,CAEH,EAAA,CAAA;GAID,KAAsC,EAC1C,WACA,aACA,oBAIwB;CACxB,IAAM,IAAa,EAAO,MAEpB,EAAE,GAAG,MAAS,GAAgB,EAC9B,EAAE,SAAM,GAA+B,EACvC,CAAC,GAAoB,KAAyB,EAClD,KACD,EAEK,IAAY,GAAkB,EAAW,OAAO,EAAS,MAAM,EAC/D,EACJ,MAAM,GACN,cACA,YACA,kBACA,gBACE,EAAsB,EAAW,UAAU,EAAmB,EAE5D,IAAa,EAAW,cAAc,EAAa,EAEnD,KAAO,QACJ,EAAW,MAAM,KAAK,MACpB,EAAW,MAAM,EAAK,KAAK,CAClC,EACD,CAAC,EAAW,OAAO,EAAW,CAAC,EAE5B,EAAE,aAAS,2BAAwB,QAGpC;EACH,IAAM,IAAc,EAAsB,EAAW,SAAS;GAC5D;GACA;GACD,CAAC,EACI,IAAgB,EAAmB;GACvC,WAAW,EAAE,eAAe;GAC5B,UAAU,EAAE,sBAAsB;GAClC,WAAW;GACX,oBAAoB,MACX,EAAO,OAAO,OAAO,EAAG;GAEjC,eAAe,EAAE,SAAM,mBAEnB,kBAAC,GAAU,SAAX,EAAA,UACE,kBAAC,QAAD;IAAM,WAAW;IAA0B,OAAO;cAChD,kBAAC,GAAD;KACE,IAAI;KACJ,SAAQ;KACR,MAAK;KACL,cAAY;eAEZ,kBAAC,IAAD;MAAQ,OAAO;MAAI,QAAQ;MAAM,CAAA;KACtB,CAAA;IACR,CAAA,EACW,CAAA;GAGzB,CAAC;EAEF,OAAO,GAAqB,CADR,GAAG,GAAa,EACR,EAAY,EAAW,UAAU,GAAG,EAAK;IACpE;EAAC,EAAO;EAAQ,EAAW;EAAS,EAAW;EAAU;EAAG;EAAK,CAAC,EAE/D,IAAW,GACd,MACQ,EAAW,SAAS,EAAI,EAEjC,CAAC,EAAW,CACb,EAEK,EAAE,UAAO,iBAAc,EAA0B,EAAO,EACxD,IAAe,EAAO,gBAC1B,EAAW,gBAAgB;EAAE,OAAO;EAAM,MAAM;EAAM,EAClD,IAAe,EAAM,QAAQ,EAAa,MAC1C,EAAE,gBAAa,IAWf,EAAE,iBAAc,iBAAc,EAAyB;EAC3D;EACA,WAXoB,SACb;GACL,OAAO,EAAM;GACb,MAAM;GACN,OAAO;GACP,QAAQ;GACT,GACA;GAAC;GAAU;GAAc,EAAM;GAAM,CAI3B;EACX,UAAU;GACR,OAAO,EAAa;GACpB,MAAM,EAAa;GACnB,OAAO;GACP,QAAQ;GACT;EACD,aAAa;EACb,qBAAqB,EAAW;EACjC,CAAC,EAEI,KAAiB,EAAsB;EAC3C;EACA;EACA;EACA,OAAO;EACR,CAAC,EAEI,IAAc,QACX,EAAO,eAAe,EAAE,EAC9B,CAAC,EAAO,YAAY,CAAC,EAClB,IAAiB,QACd,EAAY,QAAQ,MACrB,EAAO,aAAa,OACf,KAEF,EAAO,UAAU,KAAK,CAC7B,EACD,CAAC,EAAY,CAAC,EAEX,KAAgB,QAAc;EAC9B,MAAe,WAAW,GAG9B,OACE,kBAAC,OAAD;GAAK,WAAW;aACb,EAAe,KAAK,GAAQ,MAAU;IACrC,IAAM,EAAE,SAAS,MAAkB,GAC7B,IAAQ,EAAa,EAAO,OAAO,EAAK,EAC1C,IAAY;IAChB,AAAI,EAAO,aAAa,SACtB,IAAY,EAAa,EAAO,WAAW,EAAK;IAElD,IAAM,IAAU,GAAqB,GAAe,EAAM,EACpD,IAAO,EAAO,QAAQ,SACtB,IAAa,EAAO,aAAa,KAAK,KAAK;IAoCjD,OAlCI,GAAc,EAAO,GAGrB,kBAAC,GAAD;KAEE,IAJS,EAAO,GAAG,KAIf;KACK;KACH;KACM;KACZ,cAAY;eAEX;KACU,EARN,EAAO,GAQD,GAIb,EAAqB,EAAO,GAE5B,kBAAC,GAAD;KAEE,MAAK;KACI;KACH;KACN,UAAU;KACV,eAAe;MACb,EAAsB,EAAO,GAAG;;KAElC,cAAY;eAEX;KACM,EAXF,EAAO,GAWL,GAIN;KACP;GACE,CAAA;IAEP,CAAC,GAAM,EAAe,CAAC,EAEpB,IAAmB,EAAY,MAAM,MAClC,EAAO,OAAO,EACrB;CAEF,OACE,mBAAC,GAAD;EAAuC;YAAvC,CACE,kBAAC,GAAD;GACU;GACD;GACI;GACI,eAAA;GACT;GACG;GACY;GACX;GACV,aAAa;GACb,eAAe;GACD;GACd,YAAY;GACD;GACX,YAAY,EAAW,cAAc;GACrC,CAAA,EACD,KAAoB,QAAQ,EAAqB,EAAiB,IACjE,kBAAC,GAAD;GACE,QAAA;GACA,QAAQ;GACR,MAAM;GACN,eAAe;IACb,EAAsB,KAAK;;GAE7B,WAAW;GACX,CAAA,CAEsB;;GAInB,KAA4B,EACvC,mBACA,WACA,kBACuD;CACvD,IAAM,EAAE,GAAG,MAAS,GAAgB,EAC9B,IAAa,EAA0B,GAAQ,EAAK;CAgB1D,OAdI,EAAmB,EAAO,GAE1B,kBAAC,GAAD;EAAuC;YACrC,kBAAC,GAAD;GACkB;GACR;GACE;GACV,CAAA;EACwB,CAAA,GAG3B,EAAuB,EAAO,GAIjC,kBAAC,GAAD;EACkB;EACR;EACE;EACE;EACZ,CAAA,GARK"}
1
+ {"version":3,"file":"BackofficeEntityListPage.js","names":[],"sources":["../../../src/pages/BackofficeEntityListPage.tsx"],"sourcesContent":["import {\n type JSX,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport Link from '@plumile/router/routing/Link.js';\nimport {\n useFragment,\n usePaginationFragment,\n usePreloadedQuery,\n useRelayEnvironment,\n} from 'react-relay';\nimport { fetchQuery } from 'relay-runtime';\nimport {\n BACKOFFICE_LIST_DEFAULTS,\n BACKOFFICE_LIST_REFETCH_POLICY,\n} from '@plumile/backoffice-core/constants.js';\nimport { stableListVariablesKey } from '@plumile/backoffice-core/state/stableKey.js';\nimport type {\n BackofficeEntityManifestItem,\n BackofficePreparedListRoute,\n BackofficeRuntimeResolvedListFacetConfig,\n BackofficeRowFlagSpec,\n} from '@plumile/backoffice-core/types.js';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { LinkButton } from '@plumile/ui/atomic/atoms/button/LinkButton.js';\nimport { InlineBanner } from '@plumile/ui/backoffice/molecules/inline_banner/InlineBanner.js';\nimport {\n type DataTableColumn,\n type GetRowId,\n} from '@plumile/ui/components/data-table/DataTable.js';\nimport { TableCell } from '@plumile/ui/components/data-table/TableCell.js';\nimport { EyeSvg } from '@plumile/ui/icons/EyeSvg.js';\nimport { BackofficeEntityListScaffold } from '../components/backoffice/scaffolds/BackofficeEntityListScaffold.js';\nimport { LazyBackofficeEntityActionFormDialog } from '../components/backoffice/actions/LazyBackofficeEntityActionFormDialog.js';\nimport { buildDataTableColumns } from '../components/backoffice/columns/buildDataTableColumns.js';\nimport { RowFlagsCell } from '../components/backoffice/list/RowFlagsCell.js';\nimport { useBackofficeListUrlState } from '../hooks/useBackofficeListUrlState.js';\nimport { useBackofficeLoadMore } from '../hooks/useBackofficeLoadMore.js';\nimport { useBackofficeListRefetch } from '../hooks/useBackofficeListRefetch.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport * as pageStyles from './backofficeEntityListPage.css.js';\nimport { rowFlagsColumnCell } from '../components/backoffice/list/RowFlagsCell.css.js';\nimport { BackofficeRightPageLayout } from '../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport { buildEntityListBreadcrumb } from '../components/backoffice/layout/breadcrumb/buildBreadcrumbs.js';\nimport {\n buildActionsColumn,\n computeActionsColumnWidthPx,\n computeRowFlagsColumnWidthPx,\n isFormMutationAction,\n isConnectionListConfig,\n isRecordListConfig,\n isRouteAction,\n resolveLabel,\n resolveActionVariant,\n resolveTrackBySize,\n type ConnectionListConfig,\n type RecordListConfig,\n} from './BackofficeEntityListPage.helpers.js';\n\nexport type BackofficeEntityListPageProps = {\n entityManifest: BackofficeEntityManifestItem;\n config: BackofficeRuntimeResolvedListFacetConfig;\n prepared: BackofficePreparedListRoute;\n};\n\ntype RecordFetchMode = 'append' | 'reset';\ntype RecordFetchInput = {\n where: Record<string, unknown> | null;\n sort: string | null;\n count: number;\n cursor: string | null;\n mode: RecordFetchMode;\n};\n\nconst RECORD_FETCH_POLICY = 'store-or-network' as const;\n\nconst applyListEdgeColumns = <Row,>(\n inputColumns: readonly DataTableColumn<Row>[],\n rowFlags: readonly BackofficeRowFlagSpec<Row>[] | undefined,\n actionCount: number,\n tApp: TFunction,\n): {\n columns: readonly DataTableColumn<Row>[];\n gridTemplateColumns?: string;\n} => {\n const hasFlags = rowFlags != null && rowFlags.length > 0;\n\n let columns = inputColumns;\n if (hasFlags) {\n const flagsColumn: DataTableColumn<Row> = {\n id: '__rowFlags',\n header: '',\n className: rowFlagsColumnCell,\n mobileRole: 'badge',\n cell: (row) => {\n return <RowFlagsCell row={row} flags={rowFlags} tApp={tApp} />;\n },\n };\n\n // Ensure we never pick the flags column as \"primary\".\n const withFlags = [flagsColumn, ...inputColumns];\n const hasPrimary = withFlags.some((col) => {\n return col.isPrimary === true;\n });\n\n columns = withFlags;\n if (!hasPrimary) {\n columns = withFlags.map((col, index) => {\n if (index === 1) {\n return { ...col, isPrimary: true };\n }\n return col;\n });\n }\n }\n\n let flagCount = 0;\n if (hasFlags) {\n flagCount = rowFlags.length;\n }\n const flagsWidthPx = computeRowFlagsColumnWidthPx(flagCount);\n const actionsWidthPx = computeActionsColumnWidthPx(actionCount);\n\n // We always include the right-side \"actions\" column in list pages.\n let leftColumnCount = 0;\n if (hasFlags) {\n leftColumnCount = 1;\n }\n const middleCount = columns.length - leftColumnCount - 1;\n\n const middleTracks = columns\n .slice(leftColumnCount, leftColumnCount + Math.max(0, middleCount))\n .map((column) => {\n return resolveTrackBySize(column as DataTableColumn<unknown>, '1fr');\n })\n .join(' ');\n\n let gridTemplateColumns = '';\n if (hasFlags) {\n gridTemplateColumns = `${flagsWidthPx}px ${middleTracks} ${actionsWidthPx}px`;\n } else {\n gridTemplateColumns = `${middleTracks} ${actionsWidthPx}px`;\n }\n\n return { columns, gridTemplateColumns };\n};\n\nconst BackofficeEntityRecordListPage = ({\n config,\n prepared,\n}: Omit<BackofficeEntityListPageProps, 'config'> & {\n config: RecordListConfig;\n}): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const [activeFormActionId, setActiveFormActionId] = useState<string | null>(\n null,\n );\n const environment = useRelayEnvironment();\n\n const listConfig = config.list;\n const listDefaults = config.listDefaults ??\n listConfig.defaultState ?? { where: null, sort: null };\n const queryData = usePreloadedQuery(listConfig.query, prepared.query);\n const fragmentData = useFragment(listConfig.fragment, queryData as never);\n\n const initialRows = useMemo(() => {\n return listConfig.getRows(fragmentData).map((row) => {\n return listConfig.toRow(row);\n });\n }, [fragmentData, listConfig]);\n\n const initialCursor = useMemo(() => {\n return listConfig.getNextCursor?.(queryData) ?? null;\n }, [listConfig, queryData]);\n\n const [rows, setRows] = useState(initialRows);\n const [nextCursor, setNextCursor] = useState(initialCursor);\n const [isLoadingMore, setIsLoadingMore] = useState(false);\n const [isRefreshing, setIsRefreshing] = useState(false);\n const [fetchError, setFetchError] = useState(false);\n\n useEffect(() => {\n setRows(initialRows);\n setNextCursor(initialCursor);\n }, [initialCursor, initialRows]);\n\n const { columns, gridTemplateColumns } = useMemo((): {\n columns: readonly DataTableColumn<unknown>[];\n gridTemplateColumns?: string;\n } => {\n const baseColumns = buildDataTableColumns(listConfig.columns, {\n tApp,\n t,\n });\n const actionsColumn = buildActionsColumn({\n ariaLabel: t('actions.view'),\n fallback: t('common.notAvailable'),\n className: pageStyles.actionsColumnCell,\n resolveDetailHref: (id) => {\n return config.routes.detail(id);\n },\n renderAction: ({ href, ariaLabel }) => {\n return (\n <TableCell.Actions>\n <Link\n to={href}\n className={pageStyles.actionTrigger}\n aria-label={ariaLabel}\n title={ariaLabel}\n >\n <EyeSvg width={16} height={16} />\n </Link>\n </TableCell.Actions>\n );\n },\n });\n const allColumns = [...baseColumns, actionsColumn];\n return applyListEdgeColumns(allColumns, listConfig.rowFlags, 1, tApp);\n }, [config.routes, listConfig.columns, listConfig.rowFlags, t, tApp]);\n\n const getRowId = useCallback<GetRowId<unknown>>(\n (row) => {\n return listConfig.getRowId(row);\n },\n [listConfig],\n );\n\n const { state, pushState } = useBackofficeListUrlState(config);\n const resolvedSort = state.sort ?? listDefaults.sort;\n const { pageSize } = BACKOFFICE_LIST_DEFAULTS;\n\n const buildVariables = useCallback(\n (input: {\n where: Record<string, unknown> | null;\n sort: string | null;\n count: number;\n cursor: string | null;\n }) => {\n return listConfig.buildQueryVariables(input);\n },\n [listConfig],\n );\n\n const requestIdRef = useRef(0);\n const lastRefetchKeyRef = useRef(\n stableListVariablesKey({\n where: listDefaults.where,\n sort: listDefaults.sort,\n count: pageSize,\n }),\n );\n\n const runFetch = useCallback(\n async (input: RecordFetchInput) => {\n const requestId = requestIdRef.current + 1;\n requestIdRef.current = requestId;\n\n if (input.mode === 'append') {\n setIsLoadingMore(true);\n } else {\n setIsRefreshing(true);\n }\n setFetchError(false);\n\n try {\n const variables = buildVariables({\n where: input.where,\n sort: input.sort,\n count: input.count,\n cursor: input.cursor,\n });\n\n const response = await fetchQuery(\n environment,\n listConfig.query,\n variables as never,\n { fetchPolicy: RECORD_FETCH_POLICY },\n ).toPromise();\n\n if (response == null || requestIdRef.current !== requestId) {\n return;\n }\n\n const nextRows = listConfig.getRows(response as never).map((row) => {\n return listConfig.toRow(row);\n });\n setRows((prev) => {\n if (input.mode === 'append') {\n return [...prev, ...nextRows];\n }\n return nextRows;\n });\n const cursor = listConfig.getNextCursor?.(response) ?? null;\n setNextCursor(cursor);\n } catch {\n if (requestIdRef.current === requestId) {\n setFetchError(true);\n }\n } finally {\n if (input.mode === 'append') {\n setIsLoadingMore(false);\n } else {\n setIsRefreshing(false);\n }\n }\n },\n [buildVariables, environment, listConfig],\n );\n\n useEffect(() => {\n const key = stableListVariablesKey({\n where: state.where,\n sort: resolvedSort,\n count: pageSize,\n });\n if (lastRefetchKeyRef.current === key) {\n return;\n }\n lastRefetchKeyRef.current = key;\n runFetch({\n where: state.where,\n sort: resolvedSort,\n count: pageSize,\n cursor: null,\n mode: 'reset',\n }).catch(() => {\n setFetchError(true);\n });\n }, [pageSize, resolvedSort, runFetch, state.where]);\n\n const handleRefresh = useCallback(() => {\n if (isRefreshing) {\n return;\n }\n runFetch({\n where: state.where,\n sort: resolvedSort,\n count: pageSize,\n cursor: null,\n mode: 'reset',\n }).catch(() => {\n setFetchError(true);\n });\n }, [isRefreshing, pageSize, resolvedSort, runFetch, state.where]);\n\n const handleLoadMore = useBackofficeLoadMore({\n hasNext: nextCursor != null,\n isLoadingNext: isLoadingMore,\n loadNext: (count) => {\n if (nextCursor == null) {\n return;\n }\n runFetch({\n where: state.where,\n sort: resolvedSort,\n count,\n cursor: nextCursor,\n mode: 'append',\n }).catch(() => {\n setFetchError(true);\n });\n },\n count: pageSize,\n });\n\n const listActions = useMemo(() => {\n return config.listActions ?? [];\n }, [config.listActions]);\n const visibleActions = useMemo(() => {\n return listActions.filter((action) => {\n if (action.isVisible == null) {\n return true;\n }\n return action.isVisible(null);\n });\n }, [listActions]);\n\n const headerActions = useMemo(() => {\n if (visibleActions.length === 0) {\n return undefined;\n }\n return (\n <div className={pageStyles.headerActions}>\n {visibleActions.map((action, index) => {\n const { variant: actionVariant } = action;\n const label = resolveLabel(action.label, tApp);\n let ariaLabel = label;\n if (action.ariaLabel != null) {\n ariaLabel = resolveLabel(action.ariaLabel, tApp);\n }\n const variant = resolveActionVariant(actionVariant, index);\n const size = action.size ?? 'small';\n const isDisabled = action.isDisabled?.(null) === true;\n\n if (isRouteAction(action)) {\n const href = action.to(null);\n return (\n <LinkButton\n key={action.id}\n to={href}\n variant={variant}\n size={size}\n isDisabled={isDisabled}\n aria-label={ariaLabel}\n >\n {label}\n </LinkButton>\n );\n }\n\n if (isFormMutationAction(action)) {\n return (\n <Button\n key={action.id}\n type=\"button\"\n variant={variant}\n size={size}\n disabled={isDisabled}\n onClick={() => {\n setActiveFormActionId(action.id);\n }}\n aria-label={ariaLabel}\n >\n {label}\n </Button>\n );\n }\n\n return null;\n })}\n </div>\n );\n }, [tApp, visibleActions]);\n\n const activeFormAction = listActions.find((action) => {\n return action.id === activeFormActionId;\n });\n\n let statusBanner: JSX.Element | null = null;\n if (fetchError) {\n statusBanner = (\n <InlineBanner\n tone=\"danger\"\n title={t('list.errors.title')}\n actions={\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={handleRefresh}\n >\n {t('list.actions.retry')}\n </Button>\n }\n onDismiss={() => {\n setFetchError(false);\n }}\n >\n {t('list.errors.fetchFailed')}\n </InlineBanner>\n );\n }\n\n return (\n <>\n <BackofficeEntityListScaffold\n config={config}\n state={state}\n pushState={pushState}\n headerActions={headerActions}\n rows={rows}\n columns={columns}\n gridTemplateColumns={gridTemplateColumns}\n getRowId={getRowId}\n hasNextPage={nextCursor != null}\n isLoadingMore={isLoadingMore}\n isRefreshing={isRefreshing}\n onLoadMore={handleLoadMore}\n onRefresh={handleRefresh}\n totalCount={null}\n statusBanner={statusBanner}\n />\n {activeFormAction != null && isFormMutationAction(activeFormAction) && (\n <LazyBackofficeEntityActionFormDialog\n isOpen\n action={activeFormAction}\n node={null}\n onClose={() => {\n setActiveFormActionId(null);\n }}\n onSuccess={handleRefresh}\n />\n )}\n </>\n );\n};\n\nconst BackofficeEntityConnectionListPage = ({\n config,\n prepared,\n breadcrumb,\n}: Omit<BackofficeEntityListPageProps, 'config'> & {\n config: ConnectionListConfig;\n breadcrumb: ReturnType<typeof buildEntityListBreadcrumb>;\n}): JSX.Element | null => {\n const listConfig = config.list;\n\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const [activeFormActionId, setActiveFormActionId] = useState<string | null>(\n null,\n );\n\n const queryData = usePreloadedQuery(listConfig.query, prepared.query);\n const {\n data: fragmentData,\n loadNext,\n hasNext,\n isLoadingNext,\n refetch,\n } = usePaginationFragment(listConfig.fragment, queryData as never);\n\n const connection = listConfig.getConnection(fragmentData);\n\n const rows = useMemo(() => {\n return connection.edges.map((edge) => {\n return listConfig.toRow(edge.node);\n });\n }, [connection.edges, listConfig]);\n\n const { columns, gridTemplateColumns } = useMemo((): {\n columns: readonly DataTableColumn<unknown>[];\n gridTemplateColumns?: string;\n } => {\n const baseColumns = buildDataTableColumns(listConfig.columns, {\n tApp,\n t,\n });\n const actionsColumn = buildActionsColumn({\n ariaLabel: t('actions.view'),\n fallback: t('common.notAvailable'),\n className: pageStyles.actionsColumnCell,\n resolveDetailHref: (id) => {\n return config.routes.detail(id);\n },\n renderAction: ({ href, ariaLabel }) => {\n return (\n <TableCell.Actions>\n <Link\n to={href}\n className={pageStyles.actionTrigger}\n aria-label={ariaLabel}\n title={ariaLabel}\n >\n <EyeSvg width={16} height={16} />\n </Link>\n </TableCell.Actions>\n );\n },\n });\n const allColumns = [...baseColumns, actionsColumn];\n return applyListEdgeColumns(allColumns, listConfig.rowFlags, 1, tApp);\n }, [config.routes, listConfig.columns, listConfig.rowFlags, t, tApp]);\n\n const getRowId = useCallback<GetRowId<unknown>>(\n (row) => {\n return listConfig.getRowId(row);\n },\n [listConfig],\n );\n\n const { state, pushState } = useBackofficeListUrlState(config);\n const listDefaults = config.listDefaults ??\n listConfig.defaultState ?? { where: null, sort: null };\n const resolvedSort = state.sort ?? listDefaults.sort;\n const { pageSize } = BACKOFFICE_LIST_DEFAULTS;\n\n const baseVariables = useMemo(() => {\n return {\n where: state.where,\n sort: resolvedSort,\n count: pageSize,\n cursor: null,\n };\n }, [pageSize, resolvedSort, state.where]);\n\n const { isRefreshing, onRefresh } = useBackofficeListRefetch({\n refetch,\n variables: baseVariables,\n defaults: {\n where: listDefaults.where,\n sort: listDefaults.sort,\n count: pageSize,\n cursor: null,\n },\n fetchPolicy: BACKOFFICE_LIST_REFETCH_POLICY,\n buildQueryVariables: listConfig.buildQueryVariables,\n });\n\n const handleLoadMore = useBackofficeLoadMore({\n hasNext,\n isLoadingNext,\n loadNext,\n count: pageSize,\n });\n\n const listActions = useMemo(() => {\n return config.listActions ?? [];\n }, [config.listActions]);\n const visibleActions = useMemo(() => {\n return listActions.filter((action) => {\n if (action.isVisible == null) {\n return true;\n }\n return action.isVisible(null);\n });\n }, [listActions]);\n\n const headerActions = useMemo(() => {\n if (visibleActions.length === 0) {\n return undefined;\n }\n return (\n <div className={pageStyles.headerActions}>\n {visibleActions.map((action, index) => {\n const { variant: actionVariant } = action;\n const label = resolveLabel(action.label, tApp);\n let ariaLabel = label;\n if (action.ariaLabel != null) {\n ariaLabel = resolveLabel(action.ariaLabel, tApp);\n }\n const variant = resolveActionVariant(actionVariant, index);\n const size = action.size ?? 'small';\n const isDisabled = action.isDisabled?.(null) === true;\n\n if (isRouteAction(action)) {\n const href = action.to(null);\n return (\n <LinkButton\n key={action.id}\n to={href}\n variant={variant}\n size={size}\n isDisabled={isDisabled}\n aria-label={ariaLabel}\n >\n {label}\n </LinkButton>\n );\n }\n\n if (isFormMutationAction(action)) {\n return (\n <Button\n key={action.id}\n type=\"button\"\n variant={variant}\n size={size}\n disabled={isDisabled}\n onClick={() => {\n setActiveFormActionId(action.id);\n }}\n aria-label={ariaLabel}\n >\n {label}\n </Button>\n );\n }\n\n return null;\n })}\n </div>\n );\n }, [tApp, visibleActions]);\n\n const activeFormAction = listActions.find((action) => {\n return action.id === activeFormActionId;\n });\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <BackofficeEntityListScaffold\n config={config}\n state={state}\n pushState={pushState}\n headerActions={headerActions}\n rows={rows}\n columns={columns}\n gridTemplateColumns={gridTemplateColumns}\n getRowId={getRowId}\n hasNextPage={hasNext}\n isLoadingMore={isLoadingNext}\n isRefreshing={isRefreshing}\n onLoadMore={handleLoadMore}\n onRefresh={onRefresh}\n totalCount={connection.totalCount ?? null}\n />\n {activeFormAction != null && isFormMutationAction(activeFormAction) && (\n <LazyBackofficeEntityActionFormDialog\n isOpen\n action={activeFormAction}\n node={null}\n onClose={() => {\n setActiveFormActionId(null);\n }}\n onSuccess={onRefresh}\n />\n )}\n </BackofficeRightPageLayout>\n );\n};\n\nexport const BackofficeEntityListPage = ({\n entityManifest,\n config,\n prepared,\n}: BackofficeEntityListPageProps): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const breadcrumb = buildEntityListBreadcrumb(config, tApp);\n\n if (isRecordListConfig(config)) {\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <BackofficeEntityRecordListPage\n entityManifest={entityManifest}\n config={config}\n prepared={prepared}\n />\n </BackofficeRightPageLayout>\n );\n }\n if (!isConnectionListConfig(config)) {\n return null;\n }\n return (\n <BackofficeEntityConnectionListPage\n entityManifest={entityManifest}\n config={config}\n prepared={prepared}\n breadcrumb={breadcrumb}\n />\n );\n};\n\nexport default BackofficeEntityListPage;\n"],"mappings":"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"}