@plumile/backoffice-react 0.1.196 → 0.1.197

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +7 -0
  2. package/lib/esm/components/backoffice/filters/BackofficeFilterAction.js +23 -20
  3. package/lib/esm/components/backoffice/filters/BackofficeFilterAction.js.map +1 -1
  4. package/lib/esm/components/backoffice/layout/breadcrumb/buildBreadcrumbs.js.map +1 -1
  5. package/lib/esm/components/backoffice/links/BackofficeInlineLink.js +19 -9
  6. package/lib/esm/components/backoffice/links/BackofficeInlineLink.js.map +1 -1
  7. package/lib/esm/components/backoffice/links/BackofficeLink.js +12 -8
  8. package/lib/esm/components/backoffice/links/BackofficeLink.js.map +1 -1
  9. package/lib/esm/components/backoffice/links/resolveBackofficeLink.js +64 -45
  10. package/lib/esm/components/backoffice/links/resolveBackofficeLink.js.map +1 -1
  11. package/lib/esm/components/backoffice/refs/BackofficeRelatedCountLink.js +30 -61
  12. package/lib/esm/components/backoffice/refs/BackofficeRelatedCountLink.js.map +1 -1
  13. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js +1 -4
  14. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js.map +1 -1
  15. package/lib/esm/components/backoffice/scaffolds/BackofficeListFilterContext.js +18 -27
  16. package/lib/esm/components/backoffice/scaffolds/BackofficeListFilterContext.js.map +1 -1
  17. package/lib/esm/hooks/useBackofficeListUrlState.js +27 -24
  18. package/lib/esm/hooks/useBackofficeListUrlState.js.map +1 -1
  19. package/lib/esm/pages/BackofficeDashboardWidgetContent.js +194 -227
  20. package/lib/esm/pages/BackofficeDashboardWidgetContent.js.map +1 -1
  21. package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js +107 -120
  22. package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js.map +1 -1
  23. package/lib/esm/pages/BackofficeEntityListDataPage.js +2 -8
  24. package/lib/esm/pages/BackofficeEntityListDataPage.js.map +1 -1
  25. package/lib/esm/pages/resolveDashboardTargetDestination.js +17 -0
  26. package/lib/esm/pages/resolveDashboardTargetDestination.js.map +1 -0
  27. package/lib/esm/router/createBackofficeRoutes.js +88 -99
  28. package/lib/esm/router/createBackofficeRoutes.js.map +1 -1
  29. package/lib/types/components/backoffice/filters/BackofficeFilterAction.d.ts.map +1 -1
  30. package/lib/types/components/backoffice/layout/breadcrumb/buildBreadcrumbs.d.ts +3 -3
  31. package/lib/types/components/backoffice/layout/breadcrumb/buildBreadcrumbs.d.ts.map +1 -1
  32. package/lib/types/components/backoffice/links/BackofficeInlineLink.d.ts.map +1 -1
  33. package/lib/types/components/backoffice/links/BackofficeLink.d.ts.map +1 -1
  34. package/lib/types/components/backoffice/links/resolveBackofficeLink.d.ts.map +1 -1
  35. package/lib/types/components/backoffice/links/types.d.ts +19 -15
  36. package/lib/types/components/backoffice/links/types.d.ts.map +1 -1
  37. package/lib/types/components/backoffice/refs/BackofficeRelatedCountLink.d.ts.map +1 -1
  38. package/lib/types/components/backoffice/scaffolds/BackofficeEntityListScaffold.d.ts.map +1 -1
  39. package/lib/types/components/backoffice/scaffolds/BackofficeListFilterContext.d.ts +0 -4
  40. package/lib/types/components/backoffice/scaffolds/BackofficeListFilterContext.d.ts.map +1 -1
  41. package/lib/types/hooks/useBackofficeListUrlState.d.ts.map +1 -1
  42. package/lib/types/index.d.ts +1 -1
  43. package/lib/types/index.d.ts.map +1 -1
  44. package/lib/types/pages/BackofficeDashboardWidgetContent.d.ts.map +1 -1
  45. package/lib/types/pages/BackofficeEntityDetailLayoutPage.d.ts.map +1 -1
  46. package/lib/types/pages/BackofficeEntityListDataPage.d.ts.map +1 -1
  47. package/lib/types/pages/resolveDashboardTargetDestination.d.ts +5 -0
  48. package/lib/types/pages/resolveDashboardTargetDestination.d.ts.map +1 -0
  49. package/lib/types/router/createBackofficeRoutes.d.ts +0 -2
  50. package/lib/types/router/createBackofficeRoutes.d.ts.map +1 -1
  51. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeDashboardWidgetContent.js","names":[],"sources":["../../../src/pages/BackofficeDashboardWidgetContent.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport { useEffect, useMemo, useState, type JSX } from 'react';\nimport type {\n BackofficeColumnSpec,\n BackofficeDashboardBreakdownListResult,\n BackofficeDashboardContext,\n BackofficeDashboardEntitySpotlightResult,\n BackofficeDashboardHealthMatrixResult,\n BackofficeDashboardLinkTarget,\n BackofficeDashboardRiskQueueResult,\n BackofficeDashboardSlaGaugeResult,\n BackofficeDashboardTimelineChartResult,\n BackofficeDashboardTrendMetricResult,\n BackofficeDashboardWidget,\n BackofficeDashboardWindowPreset,\n BackofficeDashboardWindowState,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport {\n buildBackofficeFallbackListHref,\n buildBackofficeListHref,\n} from '@plumile/backoffice-core/state/buildListHref.js';\nimport { BackofficeEmptyState } from '@plumile/ui/backoffice/molecules/backoffice_empty_state/BackofficeEmptyState.js';\nimport { DashboardMetricGroup } from '@plumile/ui/components/dashboard/dashboard_metric_group/DashboardMetricGroup.js';\nimport { DashboardPanel } from '@plumile/ui/components/dashboard/dashboard_panel/DashboardPanel.js';\nimport { DashboardQuickActions } from '@plumile/ui/components/dashboard/dashboard_quick_actions/DashboardQuickActions.js';\nimport { DashboardStatusList } from '@plumile/ui/components/dashboard/dashboard_status_list/DashboardStatusList.js';\nimport { DashboardBreakdownList } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardBreakdownList.js';\nimport { DashboardEntitySpotlight } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardEntitySpotlight.js';\nimport { DashboardHealthMatrix } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardHealthMatrix.js';\nimport { DashboardRiskQueue } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardRiskQueue.js';\nimport { DashboardSlaGauge } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardSlaGauge.js';\nimport { DashboardTimelineChart } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardTimelineChart.js';\nimport { DashboardTrendMetric } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardTrendMetric.js';\nimport { DashboardWindowControl } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardWindowControl.js';\nimport { DataTable } from '@plumile/ui/components/data-table/DataTable.js';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\nimport type { OperationType } from 'relay-runtime';\n\nimport { BackofficeBillingUsageChart } from '../components/backoffice/billing/BackofficeBillingUsageChart.js';\nimport { buildDataTableColumns } from '../components/backoffice/columns/buildDataTableColumns.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { resolveLabel } from './BackofficeDashboardPage.helpers.js';\n\nimport * as styles from './backofficeDashboardPage.css.js';\n\nconst { useLazyLoadQuery } = ReactRelay;\n\nexport type BackofficeDashboardWidgetContentProps = {\n widget: BackofficeDashboardWidget;\n context?: BackofficeDashboardContext;\n windowPresets?: readonly BackofficeDashboardWindowPreset[];\n activeWindowPresetId?: string;\n onWindowPresetChange?: (presetId: string) => void;\n};\n\ntype WidgetContentBodyProps = BackofficeDashboardWidgetContentProps & {\n data?: OperationType['response'];\n};\n\ntype BackofficeDashboardQueryWidget = Extract<\n BackofficeDashboardWidget,\n { dataSource: 'query' }\n>;\n\nconst fallbackWindowLabel: I18nLabel = (t) => {\n return t('common.time.lastDay', '24 h');\n};\n\nconst fallbackDashboardWindowState: BackofficeDashboardWindowState = {\n id: '24h',\n label: fallbackWindowLabel,\n from: new Date(0).toISOString(),\n to: new Date(0).toISOString(),\n};\n\nconst fallbackDashboardContext: BackofficeDashboardContext = {\n window: fallbackDashboardWindowState,\n};\n\nconst resolveWidgetVariables = (\n widget: BackofficeDashboardQueryWidget,\n context: BackofficeDashboardContext,\n): OperationType['variables'] => {\n if (typeof widget.variables === 'function') {\n return widget.variables(context);\n }\n\n return widget.variables;\n};\n\nconst DashboardUnavailableState = (): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n\n return <BackofficeEmptyState title={t('common.notAvailable')} />;\n};\n\nconst serializeDashboardTarget = (\n target: BackofficeDashboardLinkTarget | undefined,\n): string => {\n if (target == null) {\n return '';\n }\n if (target.kind === 'href') {\n return `href:${target.href}`;\n }\n return `entity-list:${target.entityId}:${JSON.stringify(\n target.state ?? null,\n )}`;\n};\n\nconst useDashboardTargetHrefResolver = (\n targets: readonly (BackofficeDashboardLinkTarget | undefined)[],\n): ((\n target: BackofficeDashboardLinkTarget | undefined,\n fallbackHref: string | undefined,\n) => string | undefined) => {\n const { entities, entityRegistry } = useBackofficeConfig();\n const [, setVersion] = useState(0);\n const targetKey = targets.map(serializeDashboardTarget).join('|');\n\n useEffect(() => {\n const entityIds = new Set<string>();\n for (const target of targets) {\n if (\n target?.kind === 'entity-list' &&\n entities[target.entityId] != null &&\n entityRegistry.getLoadedListEntity(target.entityId) == null\n ) {\n entityIds.add(target.entityId);\n }\n }\n\n if (entityIds.size === 0) {\n return undefined;\n }\n\n let cancelled = false;\n Promise.all(\n Array.from(entityIds).map(async (entityId) => {\n try {\n await entityRegistry.loadListEntity(entityId);\n } catch {\n return null;\n }\n return entityId;\n }),\n ).then(\n () => {\n if (cancelled) {\n return;\n }\n setVersion((current) => {\n return current + 1;\n });\n },\n () => {\n return undefined;\n },\n );\n\n return () => {\n cancelled = true;\n };\n }, [entities, entityRegistry, targetKey, targets]);\n\n return useMemo(() => {\n return (\n target: BackofficeDashboardLinkTarget | undefined,\n fallbackHref: string | undefined,\n ): string | undefined => {\n if (target == null) {\n return fallbackHref;\n }\n if (target.kind === 'href') {\n return target.href;\n }\n\n const entity = entities[target.entityId];\n if (entity == null) {\n return fallbackHref;\n }\n\n const loadedEntity = entityRegistry.getLoadedListEntity(target.entityId);\n if (loadedEntity != null) {\n return buildBackofficeListHref(loadedEntity.config, {\n where: target.state?.where,\n sort: target.state?.sort,\n });\n }\n\n return buildBackofficeFallbackListHref(\n entity.routes.list,\n target.state?.where ?? null,\n target.state?.filters,\n );\n };\n }, [entities, entityRegistry]);\n};\n\ntype DashboardMetricResult = {\n id: string;\n label: I18nLabel;\n value: string | number | null;\n meta?: I18nLabel;\n href?: string;\n target?: BackofficeDashboardLinkTarget;\n};\n\nconst DashboardMetricGroupContent = ({\n metrics,\n}: {\n metrics: readonly DashboardMetricResult[];\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveHref = useDashboardTargetHrefResolver(\n metrics.map((metric) => {\n return metric.target;\n }),\n );\n\n return (\n <DashboardMetricGroup\n emptyState={<DashboardUnavailableState />}\n metrics={metrics.map((metric) => {\n return {\n id: metric.id,\n href: resolveHref(metric.target, metric.href),\n label: resolveLabel(metric.label, tApp),\n value: metric.value ?? t('common.notAvailable'),\n hint:\n metric.meta != null ? resolveLabel(metric.meta, tApp) : undefined,\n };\n })}\n />\n );\n};\n\ntype DashboardStatusResult = {\n id: string;\n label: I18nLabel;\n value: string | number | null;\n href?: string;\n target?: BackofficeDashboardLinkTarget;\n};\n\nconst DashboardStatusSummaryContent = ({\n items,\n}: {\n items: readonly DashboardStatusResult[];\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveHref = useDashboardTargetHrefResolver(\n items.map((item) => {\n return item.target;\n }),\n );\n\n return (\n <DashboardStatusList\n emptyState={<DashboardUnavailableState />}\n items={items.map((item) => {\n return {\n id: item.id,\n href: resolveHref(item.target, item.href),\n label: resolveLabel(item.label, tApp),\n value: item.value ?? t('common.notAvailable'),\n };\n })}\n />\n );\n};\n\ntype DashboardQuickActionResult = {\n id: string;\n label: I18nLabel | string;\n href?: string;\n target?: BackofficeDashboardLinkTarget;\n};\n\nconst DashboardQuickActionsContent = ({\n actions,\n layout,\n}: {\n actions: readonly DashboardQuickActionResult[];\n layout?: 'grid' | 'stack';\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const resolveHref = useDashboardTargetHrefResolver(\n actions.map((action) => {\n return action.target;\n }),\n );\n\n return (\n <DashboardQuickActions\n layout={layout}\n emptyState={<DashboardUnavailableState />}\n actions={actions.map((action) => {\n let label: string;\n if (typeof action.label === 'string') {\n label = action.label;\n } else {\n label = resolveLabel(action.label, tApp);\n }\n\n return {\n id: action.id,\n href: resolveHref(action.target, action.href) ?? '#',\n label,\n };\n })}\n />\n );\n};\n\nconst collectTargets = (\n values: readonly {\n target?: BackofficeDashboardLinkTarget;\n }[],\n): readonly (BackofficeDashboardLinkTarget | undefined)[] => {\n return values.map((value) => {\n return value.target;\n });\n};\n\nconst DashboardTrendMetricContent = ({\n metric,\n}: {\n metric: BackofficeDashboardTrendMetricResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveHref = useDashboardTargetHrefResolver([metric.target]);\n\n return (\n <DashboardTrendMetric\n label={resolveLabel(metric.label, tApp)}\n value={metric.value ?? t('common.notAvailable')}\n unit={metric.unit}\n href={resolveHref(metric.target, metric.href)}\n tone={metric.tone}\n delta={\n metric.delta != null\n ? {\n ...metric.delta,\n label:\n metric.delta.label != null\n ? resolveLabel(metric.delta.label, tApp)\n : undefined,\n }\n : undefined\n }\n sparkline={metric.sparkline}\n sparklineLabel={resolveLabel(metric.label, tApp)}\n />\n );\n};\n\nconst DashboardSlaGaugeContent = ({\n gauge,\n}: {\n gauge: BackofficeDashboardSlaGaugeResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveHref = useDashboardTargetHrefResolver([gauge.target]);\n\n if (gauge.value == null) {\n return <BackofficeEmptyState title={t('common.notAvailable')} />;\n }\n\n return (\n <DashboardSlaGauge\n label={resolveLabel(gauge.label, tApp)}\n value={gauge.value}\n max={gauge.max}\n threshold={gauge.threshold}\n unit={gauge.unit}\n tone={gauge.tone}\n href={resolveHref(gauge.target, gauge.href)}\n />\n );\n};\n\nconst DashboardBreakdownListContent = ({\n items,\n}: {\n items: BackofficeDashboardBreakdownListResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveHref = useDashboardTargetHrefResolver(collectTargets(items));\n\n return (\n <DashboardBreakdownList\n emptyState={<DashboardUnavailableState />}\n items={items.map((item) => {\n return {\n id: item.id,\n href: resolveHref(item.target, item.href),\n label: resolveLabel(item.label, tApp),\n meta: item.meta != null ? resolveLabel(item.meta, tApp) : undefined,\n tone: item.tone,\n value: item.value ?? t('common.notAvailable'),\n };\n })}\n />\n );\n};\n\nconst DashboardTimelineChartContent = ({\n ariaLabel,\n chart,\n result,\n}: {\n ariaLabel: I18nLabel;\n chart?: 'line' | 'bar';\n result: BackofficeDashboardTimelineChartResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n\n return (\n <DashboardTimelineChart\n ariaLabel={resolveLabel(ariaLabel, tApp)}\n chart={chart}\n emptyMessage={\n result.emptyLabel != null ? resolveLabel(result.emptyLabel, tApp) : ''\n }\n series={result.series.map((serie) => {\n return {\n ...serie,\n label: resolveLabel(serie.label, tApp),\n };\n })}\n />\n );\n};\n\nconst DashboardRiskQueueContent = ({\n items,\n}: {\n items: BackofficeDashboardRiskQueueResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveHref = useDashboardTargetHrefResolver(collectTargets(items));\n\n return (\n <DashboardRiskQueue\n emptyState={<DashboardUnavailableState />}\n items={items.map((item) => {\n return {\n id: item.id,\n href: resolveHref(item.target, item.href),\n label: resolveLabel(item.label, tApp),\n meta: item.meta != null ? resolveLabel(item.meta, tApp) : undefined,\n severity: item.severity,\n value: item.value ?? t('common.notAvailable'),\n };\n })}\n />\n );\n};\n\nconst DashboardEntitySpotlightContent = ({\n item,\n}: {\n item: BackofficeDashboardEntitySpotlightResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const resolveHref = useDashboardTargetHrefResolver([item?.target]);\n\n if (item == null) {\n return <DashboardUnavailableState />;\n }\n\n return (\n <DashboardEntitySpotlight\n href={resolveHref(item.target, item.href)}\n label={resolveLabel(item.label, tApp)}\n title={resolveLabel(item.title, tApp)}\n tone={item.tone}\n meta={item.meta?.map((meta) => {\n return {\n id: meta.id,\n label: resolveLabel(meta.label, tApp),\n value: meta.value,\n };\n })}\n />\n );\n};\n\nconst DashboardHealthMatrixContent = ({\n rows,\n}: {\n rows: BackofficeDashboardHealthMatrixResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveHref = useDashboardTargetHrefResolver(\n rows.flatMap((row) => {\n return row.cells.map((cell) => {\n return cell.target;\n });\n }),\n );\n\n return (\n <DashboardHealthMatrix\n emptyState={<DashboardUnavailableState />}\n rows={rows.map((row) => {\n return {\n id: row.id,\n label: resolveLabel(row.label, tApp),\n cells: row.cells.map((cell) => {\n return {\n id: cell.id,\n href: resolveHref(cell.target, cell.href),\n label: resolveLabel(cell.label, tApp),\n tone: cell.tone,\n value: cell.value ?? t('common.notAvailable'),\n };\n }),\n };\n })}\n />\n );\n};\n\nconst WidgetContentBody = ({\n activeWindowPresetId,\n context = fallbackDashboardContext,\n widget,\n data,\n onWindowPresetChange,\n windowPresets = [],\n}: WidgetContentBodyProps): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities } = useBackofficeConfig();\n const description =\n widget.description != null\n ? resolveLabel(widget.description, tApp)\n : undefined;\n\n const resolveData = (): unknown => {\n if (widget.dataSource === 'query' && data != null) {\n return widget.resolve(data, context);\n }\n return null;\n };\n\n if (widget.kind === 'textBlock') {\n const title = resolveLabel(widget.title, tApp);\n const body = resolveLabel(widget.body, tApp);\n return (\n <DashboardPanel title={title} subtitle={description}>\n <div className={styles.tileBody}>{body}</div>\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'shortcut') {\n const entity = entities[widget.entityId];\n const title = resolveLabel(widget.label, tApp);\n if (entity == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n if (entity.kind === 'tool') {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardQuickActions\n actions={[\n {\n id: entity.id,\n href: entity.routes.list,\n label: t('dashboard.actions.openTool'),\n },\n ]}\n />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardQuickActions\n actions={[\n {\n id: entity.id,\n href: entity.routes.list,\n label: t('dashboard.actions.openList'),\n },\n ]}\n />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'tablePreview') {\n const resolved = resolveData() as {\n columns: readonly BackofficeColumnSpec[];\n rows: readonly unknown[];\n } | null;\n if (resolved == null) {\n return (\n <DashboardPanel\n title={resolveLabel(widget.title, tApp)}\n subtitle={description}\n >\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n const columns = buildDataTableColumns(resolved.columns, {\n tApp,\n t,\n });\n const title = resolveLabel(widget.title, tApp);\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DataTable\n columns={columns}\n rows={resolved.rows}\n getRowId={(row, index) => {\n if (row != null && typeof row === 'object') {\n const record = row as Record<string, unknown>;\n const { id } = record;\n if (typeof id === 'string' && id.trim() !== '') {\n return id;\n }\n }\n return String(index);\n }}\n />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'metricGroup') {\n const resolved = resolveData() as readonly DashboardMetricResult[] | null;\n if (resolved == null) {\n return <DashboardUnavailableState />;\n }\n return <DashboardMetricGroupContent metrics={resolved} />;\n }\n\n if (widget.kind === 'trendMetric') {\n const resolved =\n resolveData() as BackofficeDashboardTrendMetricResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardTrendMetricContent metric={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'slaGauge') {\n const resolved = resolveData() as BackofficeDashboardSlaGaugeResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardSlaGaugeContent gauge={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'breakdownList') {\n const resolved =\n resolveData() as BackofficeDashboardBreakdownListResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardBreakdownListContent items={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'timelineChart') {\n const resolved =\n resolveData() as BackofficeDashboardTimelineChartResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardTimelineChartContent\n ariaLabel={widget.ariaLabel}\n chart={widget.chart}\n result={resolved}\n />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'riskQueue') {\n const resolved = resolveData() as BackofficeDashboardRiskQueueResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardRiskQueueContent items={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'entitySpotlight') {\n const resolved =\n resolveData() as BackofficeDashboardEntitySpotlightResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardEntitySpotlightContent item={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'healthMatrix') {\n const resolved =\n resolveData() as BackofficeDashboardHealthMatrixResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardHealthMatrixContent rows={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'billingUsageChart') {\n const resolved = resolveData() as {\n currency: string;\n totalAmount: number;\n from: string | null;\n to: string | null;\n buckets: readonly {\n day: string;\n category: string;\n value: number;\n }[];\n } | null;\n const title = resolveLabel(widget.title, tApp);\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n\n return (\n <DashboardPanel title={title} subtitle={description}>\n <BackofficeBillingUsageChart\n ariaLabel={resolveLabel(widget.ariaLabel, tApp)}\n buckets={resolved.buckets}\n categories={widget.categories.map((category) => {\n return {\n id: category.id,\n label: resolveLabel(category.label, tApp),\n color: category.color,\n };\n })}\n currency={resolved.currency}\n emptyLabel={resolveLabel(widget.emptyLabel, tApp)}\n from={resolved.from}\n rangePrefix={resolveLabel(widget.rangePrefix, tApp)}\n to={resolved.to}\n totalAmount={resolved.totalAmount}\n />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'quickActions') {\n const title =\n widget.title != null\n ? resolveLabel(widget.title, tApp)\n : t('dashboard.actions.openTool');\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardQuickActionsContent\n layout={widget.layout?.zone === 'aside' ? 'stack' : 'grid'}\n actions={widget.actions}\n />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'windowControl') {\n return (\n <DashboardPanel\n title={resolveLabel(widget.title, tApp)}\n subtitle={description}\n >\n <DashboardWindowControl\n activePresetId={activeWindowPresetId ?? context.window.id}\n onChange={(presetId) => {\n onWindowPresetChange?.(presetId);\n }}\n presets={windowPresets.map((preset) => {\n return {\n id: preset.id,\n label: resolveLabel(preset.label, tApp),\n };\n })}\n />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'statusSummary') {\n const resolved = resolveData() as readonly DashboardStatusResult[] | null;\n if (resolved == null) {\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardStatusSummaryContent items={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'recentItems') {\n const title =\n widget.title != null\n ? resolveLabel(widget.title, tApp)\n : t('dashboard.title');\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n\n const entityManifest = entities[widget.entityId];\n if (entityManifest?.kind !== 'list-detail') {\n return (\n <DashboardPanel\n title={resolveLabel(widget.label, tApp)}\n subtitle={description}\n >\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n const resolved = resolveData() as {\n count: number | null;\n href?: string;\n target?: BackofficeDashboardLinkTarget;\n } | null;\n let countLabel: number | string = t('common.notAvailable');\n if (typeof resolved?.count === 'number') {\n countLabel = resolved.count;\n }\n const title = resolveLabel(widget.label, tApp);\n return (\n <DashboardPanel title={title} subtitle={description}>\n <div className={styles.tileBody}>\n <div className={styles.tileCount}>{countLabel}</div>\n <DashboardQuickActionsContent\n actions={[\n {\n id: entityManifest.id,\n href: resolved?.href ?? entityManifest.routes.list,\n target: resolved?.target,\n label: t('dashboard.actions.openList'),\n },\n ]}\n />\n </div>\n </DashboardPanel>\n );\n};\n\nconst WidgetWithQuery = ({\n activeWindowPresetId,\n context = fallbackDashboardContext,\n onWindowPresetChange,\n widget,\n windowPresets,\n}: BackofficeDashboardWidgetContentProps & {\n widget: BackofficeDashboardQueryWidget;\n}): JSX.Element => {\n const data = useLazyLoadQuery<OperationType>(\n widget.query,\n resolveWidgetVariables(widget, context),\n {\n fetchPolicy: 'store-or-network',\n },\n );\n\n return (\n <WidgetContentBody\n activeWindowPresetId={activeWindowPresetId}\n context={context}\n data={data}\n onWindowPresetChange={onWindowPresetChange}\n widget={widget}\n windowPresets={windowPresets}\n />\n );\n};\n\nexport const BackofficeDashboardWidgetContent = (\n props: BackofficeDashboardWidgetContentProps,\n): JSX.Element | null => {\n const { widget } = props;\n if (widget.dataSource === 'query') {\n return <WidgetWithQuery {...props} widget={widget} />;\n }\n\n return <WidgetContentBody {...props} />;\n};\n\nexport default BackofficeDashboardWidgetContent;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BackofficeDashboardWidgetContent.js","names":[],"sources":["../../../src/pages/BackofficeDashboardWidgetContent.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport { type JSX } from 'react';\nimport type {\n BackofficeColumnSpec,\n BackofficeDashboardBreakdownListResult,\n BackofficeDashboardContext,\n BackofficeDashboardEntitySpotlightResult,\n BackofficeDashboardHealthMatrixResult,\n BackofficeDashboardLinkTarget,\n BackofficeDashboardRiskQueueResult,\n BackofficeDashboardSlaGaugeResult,\n BackofficeDashboardTimelineChartResult,\n BackofficeDashboardTrendMetricResult,\n BackofficeDashboardWidget,\n BackofficeDashboardWindowPreset,\n BackofficeDashboardWindowState,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport { BackofficeEmptyState } from '@plumile/ui/backoffice/molecules/backoffice_empty_state/BackofficeEmptyState.js';\nimport { DashboardMetricGroup } from '@plumile/ui/components/dashboard/dashboard_metric_group/DashboardMetricGroup.js';\nimport { DashboardPanel } from '@plumile/ui/components/dashboard/dashboard_panel/DashboardPanel.js';\nimport { DashboardQuickActions } from '@plumile/ui/components/dashboard/dashboard_quick_actions/DashboardQuickActions.js';\nimport { DashboardStatusList } from '@plumile/ui/components/dashboard/dashboard_status_list/DashboardStatusList.js';\nimport { DashboardBreakdownList } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardBreakdownList.js';\nimport { DashboardEntitySpotlight } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardEntitySpotlight.js';\nimport { DashboardHealthMatrix } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardHealthMatrix.js';\nimport { DashboardRiskQueue } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardRiskQueue.js';\nimport { DashboardSlaGauge } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardSlaGauge.js';\nimport { DashboardTimelineChart } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardTimelineChart.js';\nimport { DashboardTrendMetric } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardTrendMetric.js';\nimport { DashboardWindowControl } from '@plumile/ui/components/dashboard/dashboard_operational/DashboardWindowControl.js';\nimport { DataTable } from '@plumile/ui/components/data-table/DataTable.js';\nimport type { RouterDestination } from '@plumile/router/types.js';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\nimport type { OperationType } from 'relay-runtime';\n\nimport { BackofficeBillingUsageChart } from '../components/backoffice/billing/BackofficeBillingUsageChart.js';\nimport { buildDataTableColumns } from '../components/backoffice/columns/buildDataTableColumns.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { resolveLabel } from './BackofficeDashboardPage.helpers.js';\nimport { resolveDashboardTargetDestination } from './resolveDashboardTargetDestination.js';\n\nimport * as styles from './backofficeDashboardPage.css.js';\n\nconst { useLazyLoadQuery } = ReactRelay;\n\nexport type BackofficeDashboardWidgetContentProps = {\n widget: BackofficeDashboardWidget;\n context?: BackofficeDashboardContext;\n windowPresets?: readonly BackofficeDashboardWindowPreset[];\n activeWindowPresetId?: string;\n onWindowPresetChange?: (presetId: string) => void;\n};\n\ntype WidgetContentBodyProps = BackofficeDashboardWidgetContentProps & {\n data?: OperationType['response'];\n};\n\ntype BackofficeDashboardQueryWidget = Extract<\n BackofficeDashboardWidget,\n { dataSource: 'query' }\n>;\n\nconst fallbackWindowLabel: I18nLabel = (t) => {\n return t('common.time.lastDay', '24 h');\n};\n\nconst fallbackDashboardWindowState: BackofficeDashboardWindowState = {\n id: '24h',\n label: fallbackWindowLabel,\n from: new Date(0).toISOString(),\n to: new Date(0).toISOString(),\n};\n\nconst fallbackDashboardContext: BackofficeDashboardContext = {\n window: fallbackDashboardWindowState,\n};\n\nconst resolveWidgetVariables = (\n widget: BackofficeDashboardQueryWidget,\n context: BackofficeDashboardContext,\n): OperationType['variables'] => {\n if (typeof widget.variables === 'function') {\n return widget.variables(context);\n }\n\n return widget.variables;\n};\n\nconst DashboardUnavailableState = (): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n\n return <BackofficeEmptyState title={t('common.notAvailable')} />;\n};\n\nconst useDashboardTargetDestinationResolver = (): ((\n target: BackofficeDashboardLinkTarget | undefined,\n fallbackHref: string | undefined,\n) => RouterDestination | undefined) => {\n const { entities } = useBackofficeConfig();\n return (\n target: BackofficeDashboardLinkTarget | undefined,\n fallbackHref: string | undefined,\n ): RouterDestination | undefined => {\n return resolveDashboardTargetDestination(target, entities, fallbackHref);\n };\n};\n\ntype DashboardMetricResult = {\n id: string;\n label: I18nLabel;\n value: string | number | null;\n meta?: I18nLabel;\n href?: string;\n target?: BackofficeDashboardLinkTarget;\n};\n\nconst DashboardMetricGroupContent = ({\n metrics,\n}: {\n metrics: readonly DashboardMetricResult[];\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveDestination = useDashboardTargetDestinationResolver();\n\n return (\n <DashboardMetricGroup\n emptyState={<DashboardUnavailableState />}\n metrics={metrics.map((metric) => {\n return {\n id: metric.id,\n destination: resolveDestination(metric.target, metric.href),\n label: resolveLabel(metric.label, tApp),\n value: metric.value ?? t('common.notAvailable'),\n hint:\n metric.meta != null ? resolveLabel(metric.meta, tApp) : undefined,\n };\n })}\n />\n );\n};\n\ntype DashboardStatusResult = {\n id: string;\n label: I18nLabel;\n value: string | number | null;\n href?: string;\n target?: BackofficeDashboardLinkTarget;\n};\n\nconst DashboardStatusSummaryContent = ({\n items,\n}: {\n items: readonly DashboardStatusResult[];\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveDestination = useDashboardTargetDestinationResolver();\n\n return (\n <DashboardStatusList\n emptyState={<DashboardUnavailableState />}\n items={items.map((item) => {\n return {\n id: item.id,\n destination: resolveDestination(item.target, item.href),\n label: resolveLabel(item.label, tApp),\n value: item.value ?? t('common.notAvailable'),\n };\n })}\n />\n );\n};\n\ntype DashboardQuickActionResult = {\n id: string;\n label: I18nLabel | string;\n href?: string;\n target?: BackofficeDashboardLinkTarget;\n};\n\nconst DashboardQuickActionsContent = ({\n actions,\n layout,\n}: {\n actions: readonly DashboardQuickActionResult[];\n layout?: 'grid' | 'stack';\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const resolveDestination = useDashboardTargetDestinationResolver();\n\n return (\n <DashboardQuickActions\n layout={layout}\n emptyState={<DashboardUnavailableState />}\n actions={actions.map((action) => {\n let label: string;\n if (typeof action.label === 'string') {\n label = action.label;\n } else {\n label = resolveLabel(action.label, tApp);\n }\n\n return {\n id: action.id,\n destination: resolveDestination(action.target, action.href) ?? {\n pathname: '#',\n },\n label,\n };\n })}\n />\n );\n};\n\nconst DashboardTrendMetricContent = ({\n metric,\n}: {\n metric: BackofficeDashboardTrendMetricResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveDestination = useDashboardTargetDestinationResolver();\n\n return (\n <DashboardTrendMetric\n label={resolveLabel(metric.label, tApp)}\n value={metric.value ?? t('common.notAvailable')}\n unit={metric.unit}\n destination={resolveDestination(metric.target, metric.href)}\n tone={metric.tone}\n delta={\n metric.delta != null\n ? {\n ...metric.delta,\n label:\n metric.delta.label != null\n ? resolveLabel(metric.delta.label, tApp)\n : undefined,\n }\n : undefined\n }\n sparkline={metric.sparkline}\n sparklineLabel={resolveLabel(metric.label, tApp)}\n />\n );\n};\n\nconst DashboardSlaGaugeContent = ({\n gauge,\n}: {\n gauge: BackofficeDashboardSlaGaugeResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveDestination = useDashboardTargetDestinationResolver();\n\n if (gauge.value == null) {\n return <BackofficeEmptyState title={t('common.notAvailable')} />;\n }\n\n return (\n <DashboardSlaGauge\n label={resolveLabel(gauge.label, tApp)}\n value={gauge.value}\n max={gauge.max}\n threshold={gauge.threshold}\n unit={gauge.unit}\n tone={gauge.tone}\n destination={resolveDestination(gauge.target, gauge.href)}\n />\n );\n};\n\nconst DashboardBreakdownListContent = ({\n items,\n}: {\n items: BackofficeDashboardBreakdownListResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveDestination = useDashboardTargetDestinationResolver();\n\n return (\n <DashboardBreakdownList\n emptyState={<DashboardUnavailableState />}\n items={items.map((item) => {\n return {\n id: item.id,\n destination: resolveDestination(item.target, item.href),\n label: resolveLabel(item.label, tApp),\n meta: item.meta != null ? resolveLabel(item.meta, tApp) : undefined,\n tone: item.tone,\n value: item.value ?? t('common.notAvailable'),\n };\n })}\n />\n );\n};\n\nconst DashboardTimelineChartContent = ({\n ariaLabel,\n chart,\n result,\n}: {\n ariaLabel: I18nLabel;\n chart?: 'line' | 'bar';\n result: BackofficeDashboardTimelineChartResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n\n return (\n <DashboardTimelineChart\n ariaLabel={resolveLabel(ariaLabel, tApp)}\n chart={chart}\n emptyMessage={\n result.emptyLabel != null ? resolveLabel(result.emptyLabel, tApp) : ''\n }\n series={result.series.map((serie) => {\n return {\n ...serie,\n label: resolveLabel(serie.label, tApp),\n };\n })}\n />\n );\n};\n\nconst DashboardRiskQueueContent = ({\n items,\n}: {\n items: BackofficeDashboardRiskQueueResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveDestination = useDashboardTargetDestinationResolver();\n\n return (\n <DashboardRiskQueue\n emptyState={<DashboardUnavailableState />}\n items={items.map((item) => {\n return {\n id: item.id,\n destination: resolveDestination(item.target, item.href),\n label: resolveLabel(item.label, tApp),\n meta: item.meta != null ? resolveLabel(item.meta, tApp) : undefined,\n severity: item.severity,\n value: item.value ?? t('common.notAvailable'),\n };\n })}\n />\n );\n};\n\nconst DashboardEntitySpotlightContent = ({\n item,\n}: {\n item: BackofficeDashboardEntitySpotlightResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const resolveDestination = useDashboardTargetDestinationResolver();\n\n if (item == null) {\n return <DashboardUnavailableState />;\n }\n\n return (\n <DashboardEntitySpotlight\n destination={resolveDestination(item.target, item.href)}\n label={resolveLabel(item.label, tApp)}\n title={resolveLabel(item.title, tApp)}\n tone={item.tone}\n meta={item.meta?.map((meta) => {\n return {\n id: meta.id,\n label: resolveLabel(meta.label, tApp),\n value: meta.value,\n };\n })}\n />\n );\n};\n\nconst DashboardHealthMatrixContent = ({\n rows,\n}: {\n rows: BackofficeDashboardHealthMatrixResult;\n}): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const resolveDestination = useDashboardTargetDestinationResolver();\n\n return (\n <DashboardHealthMatrix\n emptyState={<DashboardUnavailableState />}\n rows={rows.map((row) => {\n return {\n id: row.id,\n label: resolveLabel(row.label, tApp),\n cells: row.cells.map((cell) => {\n return {\n id: cell.id,\n destination: resolveDestination(cell.target, cell.href),\n label: resolveLabel(cell.label, tApp),\n tone: cell.tone,\n value: cell.value ?? t('common.notAvailable'),\n };\n }),\n };\n })}\n />\n );\n};\n\nconst WidgetContentBody = ({\n activeWindowPresetId,\n context = fallbackDashboardContext,\n widget,\n data,\n onWindowPresetChange,\n windowPresets = [],\n}: WidgetContentBodyProps): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities } = useBackofficeConfig();\n const description =\n widget.description != null\n ? resolveLabel(widget.description, tApp)\n : undefined;\n\n const resolveData = (): unknown => {\n if (widget.dataSource === 'query' && data != null) {\n return widget.resolve(data, context);\n }\n return null;\n };\n\n if (widget.kind === 'textBlock') {\n const title = resolveLabel(widget.title, tApp);\n const body = resolveLabel(widget.body, tApp);\n return (\n <DashboardPanel title={title} subtitle={description}>\n <div className={styles.tileBody}>{body}</div>\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'shortcut') {\n const entity = entities[widget.entityId];\n const title = resolveLabel(widget.label, tApp);\n if (entity == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n if (entity.kind === 'tool') {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardQuickActions\n actions={[\n {\n id: entity.id,\n destination: { pathname: entity.routes.list },\n label: t('dashboard.actions.openTool'),\n },\n ]}\n />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardQuickActions\n actions={[\n {\n id: entity.id,\n destination: { pathname: entity.routes.list },\n label: t('dashboard.actions.openList'),\n },\n ]}\n />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'tablePreview') {\n const resolved = resolveData() as {\n columns: readonly BackofficeColumnSpec[];\n rows: readonly unknown[];\n } | null;\n if (resolved == null) {\n return (\n <DashboardPanel\n title={resolveLabel(widget.title, tApp)}\n subtitle={description}\n >\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n const columns = buildDataTableColumns(resolved.columns, {\n tApp,\n t,\n });\n const title = resolveLabel(widget.title, tApp);\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DataTable\n columns={columns}\n rows={resolved.rows}\n getRowId={(row, index) => {\n if (row != null && typeof row === 'object') {\n const record = row as Record<string, unknown>;\n const { id } = record;\n if (typeof id === 'string' && id.trim() !== '') {\n return id;\n }\n }\n return String(index);\n }}\n />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'metricGroup') {\n const resolved = resolveData() as readonly DashboardMetricResult[] | null;\n if (resolved == null) {\n return <DashboardUnavailableState />;\n }\n return <DashboardMetricGroupContent metrics={resolved} />;\n }\n\n if (widget.kind === 'trendMetric') {\n const resolved =\n resolveData() as BackofficeDashboardTrendMetricResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardTrendMetricContent metric={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'slaGauge') {\n const resolved = resolveData() as BackofficeDashboardSlaGaugeResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardSlaGaugeContent gauge={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'breakdownList') {\n const resolved =\n resolveData() as BackofficeDashboardBreakdownListResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardBreakdownListContent items={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'timelineChart') {\n const resolved =\n resolveData() as BackofficeDashboardTimelineChartResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardTimelineChartContent\n ariaLabel={widget.ariaLabel}\n chart={widget.chart}\n result={resolved}\n />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'riskQueue') {\n const resolved = resolveData() as BackofficeDashboardRiskQueueResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardRiskQueueContent items={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'entitySpotlight') {\n const resolved =\n resolveData() as BackofficeDashboardEntitySpotlightResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardEntitySpotlightContent item={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'healthMatrix') {\n const resolved =\n resolveData() as BackofficeDashboardHealthMatrixResult | null;\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardHealthMatrixContent rows={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'billingUsageChart') {\n const resolved = resolveData() as {\n currency: string;\n totalAmount: number;\n from: string | null;\n to: string | null;\n buckets: readonly {\n day: string;\n category: string;\n value: number;\n }[];\n } | null;\n const title = resolveLabel(widget.title, tApp);\n if (resolved == null) {\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n\n return (\n <DashboardPanel title={title} subtitle={description}>\n <BackofficeBillingUsageChart\n ariaLabel={resolveLabel(widget.ariaLabel, tApp)}\n buckets={resolved.buckets}\n categories={widget.categories.map((category) => {\n return {\n id: category.id,\n label: resolveLabel(category.label, tApp),\n color: category.color,\n };\n })}\n currency={resolved.currency}\n emptyLabel={resolveLabel(widget.emptyLabel, tApp)}\n from={resolved.from}\n rangePrefix={resolveLabel(widget.rangePrefix, tApp)}\n to={resolved.to}\n totalAmount={resolved.totalAmount}\n />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'quickActions') {\n const title =\n widget.title != null\n ? resolveLabel(widget.title, tApp)\n : t('dashboard.actions.openTool');\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardQuickActionsContent\n layout={widget.layout?.zone === 'aside' ? 'stack' : 'grid'}\n actions={widget.actions}\n />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'windowControl') {\n return (\n <DashboardPanel\n title={resolveLabel(widget.title, tApp)}\n subtitle={description}\n >\n <DashboardWindowControl\n activePresetId={activeWindowPresetId ?? context.window.id}\n onChange={(presetId) => {\n onWindowPresetChange?.(presetId);\n }}\n presets={windowPresets.map((preset) => {\n return {\n id: preset.id,\n label: resolveLabel(preset.label, tApp),\n };\n })}\n />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'statusSummary') {\n const resolved = resolveData() as readonly DashboardStatusResult[] | null;\n if (resolved == null) {\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n const title =\n widget.title != null ? resolveLabel(widget.title, tApp) : undefined;\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardStatusSummaryContent items={resolved} />\n </DashboardPanel>\n );\n }\n\n if (widget.kind === 'recentItems') {\n const title =\n widget.title != null\n ? resolveLabel(widget.title, tApp)\n : t('dashboard.title');\n return (\n <DashboardPanel title={title} subtitle={description}>\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n\n const entityManifest = entities[widget.entityId];\n if (entityManifest?.kind !== 'list-detail') {\n return (\n <DashboardPanel\n title={resolveLabel(widget.label, tApp)}\n subtitle={description}\n >\n <DashboardUnavailableState />\n </DashboardPanel>\n );\n }\n const resolved = resolveData() as {\n count: number | null;\n href?: string;\n target?: BackofficeDashboardLinkTarget;\n } | null;\n let countLabel: number | string = t('common.notAvailable');\n if (typeof resolved?.count === 'number') {\n countLabel = resolved.count;\n }\n const title = resolveLabel(widget.label, tApp);\n return (\n <DashboardPanel title={title} subtitle={description}>\n <div className={styles.tileBody}>\n <div className={styles.tileCount}>{countLabel}</div>\n <DashboardQuickActionsContent\n actions={[\n {\n id: entityManifest.id,\n href: resolved?.href ?? entityManifest.routes.list,\n target: resolved?.target,\n label: t('dashboard.actions.openList'),\n },\n ]}\n />\n </div>\n </DashboardPanel>\n );\n};\n\nconst WidgetWithQuery = ({\n activeWindowPresetId,\n context = fallbackDashboardContext,\n onWindowPresetChange,\n widget,\n windowPresets,\n}: BackofficeDashboardWidgetContentProps & {\n widget: BackofficeDashboardQueryWidget;\n}): JSX.Element => {\n const data = useLazyLoadQuery<OperationType>(\n widget.query,\n resolveWidgetVariables(widget, context),\n {\n fetchPolicy: 'store-or-network',\n },\n );\n\n return (\n <WidgetContentBody\n activeWindowPresetId={activeWindowPresetId}\n context={context}\n data={data}\n onWindowPresetChange={onWindowPresetChange}\n widget={widget}\n windowPresets={windowPresets}\n />\n );\n};\n\nexport const BackofficeDashboardWidgetContent = (\n props: BackofficeDashboardWidgetContentProps,\n): JSX.Element | null => {\n const { widget } = props;\n if (widget.dataSource === 'query') {\n return <WidgetWithQuery {...props} widget={widget} />;\n }\n\n return <WidgetContentBody {...props} />;\n};\n\nexport default BackofficeDashboardWidgetContent;\n"],"mappings":"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"}
@@ -7,178 +7,165 @@ import { buildEntityDetailBreadcrumb as a } from "../components/backoffice/layou
7
7
  import { BackofficeLazyEntityCount as o } from "../components/backoffice/refs/BackofficeLazyEntityCount.js";
8
8
  import { BackofficeEntityDetailNotFound as s } from "../components/backoffice/scaffolds/BackofficeEntityDetailNotFound.js";
9
9
  import { resolveVisibleDetailPages as c } from "./detail/pageResolution.js";
10
- import { headerBlock as l, headerMeta as u, headerMetaList as d, headerRelationGroup as ee, relationCountLoading as f } from "./backofficeEntityDetailPage.css.js";
11
- import { resolveLabel as p, resolveRelationValue as m } from "./BackofficeEntityDetailPage.helpers.js";
12
- import { resolveHeaderItems as h } from "./BackofficeEntityDetailPage.view-helpers.js";
13
- import { BackofficeEntityDetailLayoutContextProvider as g } from "./detail/BackofficeEntityDetailLayoutContext.js";
14
- import { buildTabsItems as te } from "./detail/buildTabsItems.js";
15
- import { BackofficeRedirect as _ } from "./BackofficeRedirect.js";
16
- import { Suspense as ne, useContext as re } from "react";
17
- import { jsx as v, jsxs as y } from "react/jsx-runtime";
18
- import { useTranslation as b } from "react-i18next";
19
- import * as x from "react-relay";
20
- import { Spinner as S } from "@plumile/ui/backoffice/atoms/spinner/Spinner.js";
21
- import C from "@plumile/router/routing/RoutingContext.js";
22
- import { FormattedDate as w } from "@plumile/ui/atomic/atoms/formatted-date/FormattedDate.js";
23
- import { BACKOFFICE_DATE_TIME_OPTIONS as T } from "@plumile/backoffice-core/constants.js";
24
- import ie from "@plumile/router/routing/Link.js";
25
- import { Tag as ae } from "@plumile/ui/backoffice/atoms/tag/Tag.js";
26
- import { buildBackofficeFallbackListHref as oe, buildBackofficeListHref as se, buildBackofficeListLink as ce } from "@plumile/backoffice-core/state/buildListHref.js";
27
- import { setWhereValue as le } from "@plumile/backoffice-core/filters/where.js";
28
- import E from "@plumile/router/routing/useLocation.js";
29
- import { BackofficePageHeader as D } from "@plumile/ui/backoffice/molecules/backoffice_page_header/BackofficePageHeader.js";
30
- import { Tabs as O } from "@plumile/ui/atomic/molecules/tabs/Tabs.js";
31
- import { DetailPageTemplate as k } from "@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js";
32
- import { BackofficeKeyValueList as A } from "@plumile/ui/backoffice/molecules/backoffice_key_value_list/BackofficeKeyValueList.js";
33
- import { BackofficeRelationsMenu as j } from "@plumile/ui/backoffice/molecules/backoffice_relations_menu/BackofficeRelationsMenu.js";
10
+ import { headerBlock as l, headerMeta as u, headerMetaList as d, headerRelationGroup as f, relationCountLoading as p } from "./backofficeEntityDetailPage.css.js";
11
+ import { resolveLabel as m, resolveRelationValue as h } from "./BackofficeEntityDetailPage.helpers.js";
12
+ import { resolveHeaderItems as g } from "./BackofficeEntityDetailPage.view-helpers.js";
13
+ import { BackofficeEntityDetailLayoutContextProvider as _ } from "./detail/BackofficeEntityDetailLayoutContext.js";
14
+ import { buildTabsItems as v } from "./detail/buildTabsItems.js";
15
+ import { BackofficeRedirect as y } from "./BackofficeRedirect.js";
16
+ import { Suspense as b } from "react";
17
+ import { jsx as x, jsxs as S } from "react/jsx-runtime";
18
+ import { useTranslation as C } from "react-i18next";
19
+ import * as w from "react-relay";
20
+ import { Spinner as T } from "@plumile/ui/backoffice/atoms/spinner/Spinner.js";
21
+ import { FormattedDate as E } from "@plumile/ui/atomic/atoms/formatted-date/FormattedDate.js";
22
+ import { BACKOFFICE_DATE_TIME_OPTIONS as D } from "@plumile/backoffice-core/constants.js";
23
+ import O from "@plumile/router/routing/Link.js";
24
+ import { Tag as k } from "@plumile/ui/backoffice/atoms/tag/Tag.js";
25
+ import { setWhereValue as ee } from "@plumile/backoffice-core/filters/where.js";
26
+ import te from "@plumile/router/routing/useLocation.js";
27
+ import { BackofficePageHeader as ne } from "@plumile/ui/backoffice/molecules/backoffice_page_header/BackofficePageHeader.js";
28
+ import { Tabs as re } from "@plumile/ui/atomic/molecules/tabs/Tabs.js";
29
+ import { DetailPageTemplate as A } from "@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js";
30
+ import { BackofficeKeyValueList as j } from "@plumile/ui/backoffice/molecules/backoffice_key_value_list/BackofficeKeyValueList.js";
31
+ import { BackofficeRelationsMenu as M } from "@plumile/ui/backoffice/molecules/backoffice_relations_menu/BackofficeRelationsMenu.js";
34
32
  //#region src/pages/BackofficeEntityDetailLayoutPage.tsx
35
- var { usePreloadedQuery: M } = x, N = (e) => e.trim().replace(/^\/+|\/+$/g, ""), P = (e, t, n) => [n.pages.mainPage, ...n.pages.subPages ?? []].find((r) => e === n.routes.detailPage(t, r.id))?.path ?? "", F = () => /* @__PURE__ */ v("span", {
36
- className: f,
37
- children: /* @__PURE__ */ v(S, { size: 12 })
38
- }), I = () => {
33
+ var { usePreloadedQuery: N } = w, P = (e) => e.trim().replace(/^\/+|\/+$/g, ""), F = (e, t, n) => [n.pages.mainPage, ...n.pages.subPages ?? []].find((r) => e === n.routes.detailPage(t, r.id))?.path ?? "", I = () => /* @__PURE__ */ x("span", {
34
+ className: p,
35
+ children: /* @__PURE__ */ x(T, { size: 12 })
36
+ }), L = () => {
39
37
  let { t } = e();
40
- return /* @__PURE__ */ v("div", {
38
+ return /* @__PURE__ */ x("div", {
41
39
  role: "status",
42
40
  "aria-live": "polite",
43
41
  "aria-busy": "true",
44
- children: /* @__PURE__ */ v(S, {
42
+ children: /* @__PURE__ */ x(T, {
45
43
  size: 20,
46
44
  ariaLabel: t("common.loading")
47
45
  })
48
46
  });
49
- }, L = ({ config: s, prepared: f, layoutNodeRef: x, children: S }) => {
50
- let { t: M } = b(), { t: L } = e(), { entities: R, entityRegistry: z } = t(), { pathname: B } = E(), V = re(C), H = n(s.layoutPage.fragment, x), U = s.layoutPage.toView(H), W = P(B, f.id, s), G = c({
47
+ }, R = ({ config: s, prepared: p, layoutNodeRef: w, children: T }) => {
48
+ let { t: N } = C(), { t: R } = e(), { entities: z } = t(), { pathname: B } = te(), V = n(s.layoutPage.fragment, w), H = s.layoutPage.toView(V), U = F(B, p.id, s), W = c({
51
49
  mainPage: s.pages.mainPage,
52
50
  subPages: s.pages.subPages,
53
- activePagePath: W,
54
- node: U
51
+ activePagePath: U,
52
+ node: H
55
53
  });
56
- if (!G.hasVisiblePages || G.activePage == null) return /* @__PURE__ */ v(_, { to: s.routes.list });
57
- let { activePage: K } = G;
58
- if (W !== "" && N(K.path) !== N(W)) return /* @__PURE__ */ v(_, { to: s.routes.detailPage(f.id, K.id) });
59
- let q = te({
60
- pages: G.pages,
61
- id: f.id,
62
- tApp: M,
54
+ if (!W.hasVisiblePages || W.activePage == null) return /* @__PURE__ */ x(y, { to: s.routes.list });
55
+ let { activePage: G } = W;
56
+ if (U !== "" && P(G.path) !== P(U)) return /* @__PURE__ */ x(y, { to: s.routes.detailPage(p.id, G.id) });
57
+ let K = v({
58
+ pages: W.pages,
59
+ id: p.id,
60
+ tApp: N,
63
61
  detailPageHref: s.routes.detailPage
64
- }), J = h(s.header, U, {
65
- tApp: M,
66
- t: L,
62
+ }), q = g(s.header, H, {
63
+ tApp: N,
64
+ t: R,
67
65
  resolveEntityHref: (e, t) => {
68
- let n = R[e];
66
+ let n = z[e];
69
67
  return n == null ? null : n.routes.detail(t);
70
68
  },
71
- renderLink: (e, t) => /* @__PURE__ */ v(ie, {
69
+ renderLink: (e, t) => /* @__PURE__ */ x(O, {
72
70
  to: e,
73
71
  preloadOnHover: "code-and-data",
74
72
  children: t
75
73
  }),
76
- renderDate: (e, t) => /* @__PURE__ */ v(w, {
74
+ renderDate: (e, t) => /* @__PURE__ */ x(E, {
77
75
  value: e,
78
- options: T,
76
+ options: D,
79
77
  fallback: t
80
78
  }),
81
- renderTag: (e, t) => /* @__PURE__ */ v(ae, {
79
+ renderTag: (e, t) => /* @__PURE__ */ x(k, {
82
80
  tone: e,
83
81
  children: t
84
82
  }),
85
- renderBadgeRow: (e) => /* @__PURE__ */ v(r, { items: e })
86
- }), Y = (s.relations ?? []).flatMap((e) => {
87
- let { filterId: t, path: n, target: r, whereKey: i } = e, a = m(e.value(U));
88
- if (a == null) return [];
89
- let s = R[r];
90
- if (s?.hasList !== !0) return [];
91
- let c = le(null, i, a, n);
92
- if (c == null) return [];
93
- let l = z.getLoadedListEntity(r), u = t;
94
- u ?? (u = i, n != null && (u = `${i}.${n.join(".")}`));
95
- let d;
96
- return d = l == null ? oe(s.routes.list, c, [{
97
- id: u,
98
- value: a
99
- }]) : se(l.config, { where: c }), [{
83
+ renderBadgeRow: (e) => /* @__PURE__ */ x(r, { items: e })
84
+ }), J = (s.relations ?? []).flatMap((e) => {
85
+ let { path: t, target: n, whereKey: r } = e, i = h(e.value(H));
86
+ if (i == null) return [];
87
+ let a = z[n];
88
+ if (a?.hasList !== !0) return [];
89
+ let s = ee(null, r, i, t);
90
+ if (s == null) return [];
91
+ let c = a.listNavigation.encode({ where: s });
92
+ return [{
100
93
  id: e.id,
101
- label: p(e.label, M),
102
- count: /* @__PURE__ */ v(o, {
103
- entity: r,
104
- loadingFallback: /* @__PURE__ */ v(F, {}),
105
- where: c
94
+ label: m(e.label, N),
95
+ count: /* @__PURE__ */ x(o, {
96
+ entity: n,
97
+ loadingFallback: /* @__PURE__ */ x(I, {}),
98
+ where: s
106
99
  }),
107
- href: d,
108
- onClick: async (e) => {
109
- if (V == null || e.defaultPrevented || e.button !== 0 || e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) return;
110
- e.preventDefault();
111
- let t = await z.loadListEntity(r), n = ce(t.config, { where: c }), i = "";
112
- n.search !== "" && (i = `?${n.search}`), V.history.push({
113
- pathname: n.pathname,
114
- search: i,
115
- hash: ""
116
- });
100
+ destination: {
101
+ pathname: a.routes.list,
102
+ filters: c.filters,
103
+ query: c.query
117
104
  }
118
105
  }];
119
- }), ue = a({
106
+ }), Y = a({
120
107
  config: s,
121
- tApp: M,
122
- entityId: f.id,
123
- layoutView: U,
124
- pageLabel: K.label(M),
125
- pageId: K.id
108
+ tApp: N,
109
+ entityId: p.id,
110
+ layoutView: H,
111
+ pageLabel: G.label(N),
112
+ pageId: G.id
126
113
  }), X;
127
- (J.status != null || J.badges != null) && (X = /* @__PURE__ */ y("div", {
114
+ (q.status != null || q.badges != null) && (X = /* @__PURE__ */ S("div", {
128
115
  className: u,
129
- children: [J.status, J.badges]
116
+ children: [q.status, q.badges]
130
117
  }));
131
118
  let Z = null;
132
- J.items != null && J.items.length > 0 && (Z = /* @__PURE__ */ v("div", {
119
+ q.items != null && q.items.length > 0 && (Z = /* @__PURE__ */ x("div", {
133
120
  className: d,
134
- children: /* @__PURE__ */ v(A, { items: J.items })
121
+ children: /* @__PURE__ */ x(j, { items: q.items })
135
122
  }));
136
123
  let Q;
137
- Y.length > 0 && (Q = /* @__PURE__ */ v("div", {
138
- className: ee,
139
- children: /* @__PURE__ */ v(j, {
140
- label: L("relations.menu.label"),
141
- items: Y
124
+ J.length > 0 && (Q = /* @__PURE__ */ x("div", {
125
+ className: f,
126
+ children: /* @__PURE__ */ x(M, {
127
+ label: R("relations.menu.label"),
128
+ items: J
142
129
  })
143
130
  }));
144
- let de = /* @__PURE__ */ y("div", {
131
+ let ie = /* @__PURE__ */ S("div", {
145
132
  className: l,
146
- children: [/* @__PURE__ */ v(D, {
147
- title: J.title,
148
- subtitle: J.subtitle,
133
+ children: [/* @__PURE__ */ x(ne, {
134
+ title: q.title,
135
+ subtitle: q.subtitle,
149
136
  meta: X,
150
137
  actions: Q
151
138
  }), Z]
152
139
  }), $ = null;
153
- return G.pages.length > 1 && ($ = /* @__PURE__ */ v(O, {
154
- items: q,
155
- activeId: K.id,
140
+ return W.pages.length > 1 && ($ = /* @__PURE__ */ x(re, {
141
+ items: K,
142
+ activeId: G.id,
156
143
  variant: "underline"
157
- })), /* @__PURE__ */ v(g, {
144
+ })), /* @__PURE__ */ x(_, {
158
145
  value: {
159
- activePage: K,
146
+ activePage: G,
160
147
  config: s,
161
- entityId: f.id,
162
- layoutView: U,
163
- tabsItems: q,
164
- visiblePages: G.pages
148
+ entityId: p.id,
149
+ layoutView: H,
150
+ tabsItems: K,
151
+ visiblePages: W.pages
165
152
  },
166
- children: /* @__PURE__ */ v(i, {
167
- breadcrumb: ue,
168
- children: /* @__PURE__ */ v(k, {
169
- headerNode: de,
153
+ children: /* @__PURE__ */ x(i, {
154
+ breadcrumb: Y,
155
+ children: /* @__PURE__ */ x(A, {
156
+ headerNode: ie,
170
157
  tabsNode: $,
171
158
  headerDensity: "compact",
172
- children: /* @__PURE__ */ v(ne, {
173
- fallback: /* @__PURE__ */ v(I, {}),
174
- children: S
159
+ children: /* @__PURE__ */ x(b, {
160
+ fallback: /* @__PURE__ */ x(L, {}),
161
+ children: T
175
162
  })
176
163
  })
177
164
  })
178
165
  });
179
- }, R = ({ config: t, prepared: n, children: r }) => {
180
- let { t: a } = b(), { t: o } = e(), c = M(t.layoutPage.query, n.layoutQuery), l = t.layoutPage.resolveNode(c, { id: n.id });
181
- return l == null ? /* @__PURE__ */ v(i, {
166
+ }, z = ({ config: t, prepared: n, children: r }) => {
167
+ let { t: a } = C(), { t: o } = e(), c = N(t.layoutPage.query, n.layoutQuery), l = t.layoutPage.resolveNode(c, { id: n.id });
168
+ return l == null ? /* @__PURE__ */ x(i, {
182
169
  breadcrumb: [{
183
170
  kind: "link",
184
171
  target: {
@@ -195,8 +182,8 @@ var { usePreloadedQuery: M } = x, N = (e) => e.trim().replace(/^\/+|\/+$/g, ""),
195
182
  },
196
183
  label: o("detail.notFound")
197
184
  }],
198
- children: /* @__PURE__ */ v(s, { listHref: t.routes.list })
199
- }) : /* @__PURE__ */ v(L, {
185
+ children: /* @__PURE__ */ x(s, { listHref: t.routes.list })
186
+ }) : /* @__PURE__ */ x(R, {
200
187
  config: t,
201
188
  prepared: n,
202
189
  layoutNodeRef: l,
@@ -204,6 +191,6 @@ var { usePreloadedQuery: M } = x, N = (e) => e.trim().replace(/^\/+|\/+$/g, ""),
204
191
  });
205
192
  };
206
193
  //#endregion
207
- export { R as BackofficeEntityDetailLayoutPage, R as default };
194
+ export { z as BackofficeEntityDetailLayoutPage, z as default };
208
195
 
209
196
  //# sourceMappingURL=BackofficeEntityDetailLayoutPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeEntityDetailLayoutPage.js","names":[],"sources":["../../../src/pages/BackofficeEntityDetailLayoutPage.tsx"],"sourcesContent":["import { Suspense, type JSX, type ReactNode, useContext } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\nimport Link from '@plumile/router/routing/Link.js';\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\nimport useLocation from '@plumile/router/routing/useLocation.js';\n\nimport { BACKOFFICE_DATE_TIME_OPTIONS } from '@plumile/backoffice-core/constants.js';\nimport { setWhereValue } from '@plumile/backoffice-core/filters/where.js';\nimport {\n buildBackofficeFallbackListHref,\n buildBackofficeListHref,\n buildBackofficeListLink,\n} from '@plumile/backoffice-core/state/buildListHref.js';\nimport type {\n BackofficeEntityManifestItem,\n BackofficePreparedDetailLayoutDataRoute,\n BackofficeResolvedDetailLayoutFacetConfig,\n} from '@plumile/backoffice-core/types.js';\nimport { FormattedDate } from '@plumile/ui/atomic/atoms/formatted-date/FormattedDate.js';\nimport { Tabs } from '@plumile/ui/atomic/molecules/tabs/Tabs.js';\nimport { Tag } from '@plumile/ui/backoffice/atoms/tag/Tag.js';\nimport { BackofficeKeyValueList } from '@plumile/ui/backoffice/molecules/backoffice_key_value_list/BackofficeKeyValueList.js';\nimport { BackofficePageHeader } from '@plumile/ui/backoffice/molecules/backoffice_page_header/BackofficePageHeader.js';\nimport {\n BackofficeRelationsMenu,\n type BackofficeRelationsMenuItem,\n} from '@plumile/ui/backoffice/molecules/backoffice_relations_menu/BackofficeRelationsMenu.js';\nimport { Spinner } from '@plumile/ui/backoffice/atoms/spinner/Spinner.js';\nimport { DetailPageTemplate } from '@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js';\n\nimport { BackofficeDetailBadgeRow } from '../components/backoffice/detail/BackofficeDetailBadgeRow.js';\nimport { BackofficeLazyEntityCount } from '../components/backoffice/refs/BackofficeLazyEntityCount.js';\nimport { BackofficeEntityDetailNotFound } from '../components/backoffice/scaffolds/BackofficeEntityDetailNotFound.js';\nimport { BackofficeRightPageLayout } from '../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport { buildEntityDetailBreadcrumb } from '../components/backoffice/layout/breadcrumb/buildBreadcrumbs.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeFragment } from '../relay/typedRelayHooks.js';\nimport * as pageStyles from './backofficeEntityDetailPage.css.js';\nimport {\n resolveLabel,\n resolveRelationValue,\n} from './BackofficeEntityDetailPage.helpers.js';\nimport { resolveHeaderItems } from './BackofficeEntityDetailPage.view-helpers.js';\nimport { BackofficeEntityDetailLayoutContextProvider } from './detail/BackofficeEntityDetailLayoutContext.js';\nimport { buildTabsItems } from './detail/buildTabsItems.js';\nimport { resolveVisibleDetailPages } from './detail/pageResolution.js';\nimport { BackofficeRedirect } from './BackofficeRedirect.js';\n\nconst { usePreloadedQuery } = ReactRelay;\n\nconst normalizePath = (value: string): string => {\n return value.trim().replace(/^\\/+|\\/+$/g, '');\n};\n\nconst resolveActivePagePath = (\n pathname: string,\n id: string,\n config: BackofficeResolvedDetailLayoutFacetConfig,\n): string => {\n const pages = [config.pages.mainPage, ...(config.pages.subPages ?? [])];\n const activePage = pages.find((page) => {\n return pathname === config.routes.detailPage(id, page.id);\n });\n return activePage?.path ?? '';\n};\n\nconst RelationCountLoading = (): JSX.Element => {\n return (\n <span className={pageStyles.relationCountLoading}>\n <Spinner size={12} />\n </span>\n );\n};\n\nconst DetailPageContentLoading = (): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n return (\n <div role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <Spinner size={20} ariaLabel={t('common.loading')} />\n </div>\n );\n};\n\nexport type BackofficeEntityDetailLayoutPageProps = {\n entityManifest: BackofficeEntityManifestItem;\n config: BackofficeResolvedDetailLayoutFacetConfig;\n prepared: BackofficePreparedDetailLayoutDataRoute;\n children?: ReactNode;\n};\n\ntype BackofficeEntityDetailLayoutPageContentProps = {\n config: BackofficeResolvedDetailLayoutFacetConfig;\n prepared: BackofficePreparedDetailLayoutDataRoute;\n layoutNodeRef: unknown;\n children?: ReactNode;\n};\n\nconst BackofficeEntityDetailLayoutPageContent = ({\n config,\n prepared,\n layoutNodeRef,\n children,\n}: BackofficeEntityDetailLayoutPageContentProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities, entityRegistry } = useBackofficeConfig();\n const { pathname } = useLocation();\n const routing = useContext(RoutingContext);\n const layoutNode = useBackofficeFragment<unknown, unknown>(\n config.layoutPage.fragment,\n layoutNodeRef,\n );\n\n const layoutView = config.layoutPage.toView(layoutNode);\n const activePagePath = resolveActivePagePath(pathname, prepared.id, config);\n const resolvedPages = resolveVisibleDetailPages({\n mainPage: config.pages.mainPage,\n subPages: config.pages.subPages,\n activePagePath,\n node: layoutView,\n });\n\n if (!resolvedPages.hasVisiblePages || resolvedPages.activePage == null) {\n return <BackofficeRedirect to={config.routes.list} />;\n }\n\n const { activePage } = resolvedPages;\n if (\n activePagePath !== '' &&\n normalizePath(activePage.path) !== normalizePath(activePagePath)\n ) {\n return (\n <BackofficeRedirect\n to={config.routes.detailPage(prepared.id, activePage.id)}\n />\n );\n }\n\n const tabsItems = buildTabsItems({\n pages: resolvedPages.pages,\n id: prepared.id,\n tApp,\n detailPageHref: config.routes.detailPage,\n });\n const resolveEntityHref = (entityId: string, refId: string) => {\n const entityConfig = entities[entityId];\n if (entityConfig == null) {\n return null;\n }\n return entityConfig.routes.detail(refId);\n };\n const header = resolveHeaderItems(config.header, layoutView, {\n tApp,\n t,\n resolveEntityHref,\n renderLink: (href, label) => {\n return (\n <Link to={href} preloadOnHover=\"code-and-data\">\n {label}\n </Link>\n );\n },\n renderDate: (value, fallback) => {\n return (\n <FormattedDate\n value={value}\n options={BACKOFFICE_DATE_TIME_OPTIONS}\n fallback={fallback}\n />\n );\n },\n renderTag: (tone, label) => {\n return <Tag tone={tone}>{label}</Tag>;\n },\n renderBadgeRow: (items) => {\n return <BackofficeDetailBadgeRow items={items} />;\n },\n });\n const relationMenuItems: BackofficeRelationsMenuItem[] = (\n config.relations ?? []\n ).flatMap((relation) => {\n const { filterId: configuredFilterId, path, target, whereKey } = relation;\n const value = resolveRelationValue(relation.value(layoutView));\n if (value == null) {\n return [];\n }\n\n const entityManifest = entities[target];\n if (entityManifest?.hasList !== true) {\n return [];\n }\n\n const where = setWhereValue(null, whereKey, value, path);\n if (where == null) {\n return [];\n }\n\n const loadedEntity = entityRegistry.getLoadedListEntity(target);\n let filterId = configuredFilterId;\n if (filterId == null) {\n filterId = whereKey;\n if (path != null) {\n filterId = `${whereKey}.${path.join('.')}`;\n }\n }\n\n let href: string;\n if (loadedEntity == null) {\n href = buildBackofficeFallbackListHref(\n entityManifest.routes.list,\n where,\n [\n {\n id: filterId,\n value,\n },\n ],\n );\n } else {\n href = buildBackofficeListHref(loadedEntity.config, { where });\n }\n\n return [\n {\n id: relation.id,\n label: resolveLabel(relation.label, tApp),\n count: (\n <BackofficeLazyEntityCount\n entity={target}\n loadingFallback={<RelationCountLoading />}\n where={where}\n />\n ),\n href,\n onClick: async (event) => {\n if (\n routing == null ||\n event.defaultPrevented ||\n event.button !== 0 ||\n event.metaKey ||\n event.altKey ||\n event.ctrlKey ||\n event.shiftKey\n ) {\n return;\n }\n\n event.preventDefault();\n\n const listEntity = await entityRegistry.loadListEntity(target);\n const next = buildBackofficeListLink(listEntity.config, { where });\n\n let search = '';\n if (next.search !== '') {\n search = `?${next.search}`;\n }\n\n routing.history.push({\n pathname: next.pathname,\n search,\n hash: '',\n });\n },\n },\n ];\n });\n const breadcrumb = buildEntityDetailBreadcrumb({\n config,\n tApp,\n entityId: prepared.id,\n layoutView,\n pageLabel: activePage.label(tApp),\n pageId: activePage.id,\n });\n let headerMetaNode: JSX.Element | undefined;\n if (header.status != null || header.badges != null) {\n headerMetaNode = (\n <div className={pageStyles.headerMeta}>\n {header.status}\n {header.badges}\n </div>\n );\n }\n let headerItemsNode: JSX.Element | null = null;\n if (header.items != null && header.items.length > 0) {\n headerItemsNode = (\n <div className={pageStyles.headerMetaList}>\n <BackofficeKeyValueList items={header.items} />\n </div>\n );\n }\n let headerActionsNode: JSX.Element | undefined;\n if (relationMenuItems.length > 0) {\n headerActionsNode = (\n <div className={pageStyles.headerRelationGroup}>\n <BackofficeRelationsMenu\n label={t('relations.menu.label')}\n items={relationMenuItems}\n />\n </div>\n );\n }\n\n const headerNode = (\n <div className={pageStyles.headerBlock}>\n <BackofficePageHeader\n title={header.title}\n subtitle={header.subtitle}\n meta={headerMetaNode}\n actions={headerActionsNode}\n />\n {headerItemsNode}\n </div>\n );\n let tabsNode: JSX.Element | null = null;\n if (resolvedPages.pages.length > 1) {\n tabsNode = (\n <Tabs items={tabsItems} activeId={activePage.id} variant=\"underline\" />\n );\n }\n\n return (\n <BackofficeEntityDetailLayoutContextProvider\n value={{\n activePage,\n config,\n entityId: prepared.id,\n layoutView,\n tabsItems,\n visiblePages: resolvedPages.pages,\n }}\n >\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DetailPageTemplate\n headerNode={headerNode}\n tabsNode={tabsNode}\n headerDensity=\"compact\"\n >\n <Suspense fallback={<DetailPageContentLoading />}>\n {children}\n </Suspense>\n </DetailPageTemplate>\n </BackofficeRightPageLayout>\n </BackofficeEntityDetailLayoutContextProvider>\n );\n};\n\nexport const BackofficeEntityDetailLayoutPage = ({\n config,\n prepared,\n children,\n}: BackofficeEntityDetailLayoutPageProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const layoutQueryData = usePreloadedQuery(\n config.layoutPage.query,\n prepared.layoutQuery,\n );\n const layoutNodeRef = config.layoutPage.resolveNode(layoutQueryData, {\n id: prepared.id,\n });\n\n if (layoutNodeRef == null) {\n return (\n <BackofficeRightPageLayout\n breadcrumb={[\n {\n kind: 'link',\n target: {\n kind: 'entity-list',\n entityId: config.id,\n },\n label: config.label(tApp),\n },\n {\n kind: 'current',\n target: {\n kind: 'entity-detail',\n entityId: config.id,\n id: prepared.id,\n },\n label: t('detail.notFound'),\n },\n ]}\n >\n <BackofficeEntityDetailNotFound listHref={config.routes.list} />\n </BackofficeRightPageLayout>\n );\n }\n\n return (\n <BackofficeEntityDetailLayoutPageContent\n config={config}\n prepared={prepared}\n layoutNodeRef={layoutNodeRef}\n >\n {children}\n </BackofficeEntityDetailLayoutPageContent>\n );\n};\n\nexport default BackofficeEntityDetailLayoutPage;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BackofficeEntityDetailLayoutPage.js","names":[],"sources":["../../../src/pages/BackofficeEntityDetailLayoutPage.tsx"],"sourcesContent":["import { Suspense, type JSX, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\nimport Link from '@plumile/router/routing/Link.js';\nimport useLocation from '@plumile/router/routing/useLocation.js';\n\nimport { BACKOFFICE_DATE_TIME_OPTIONS } from '@plumile/backoffice-core/constants.js';\nimport { setWhereValue } from '@plumile/backoffice-core/filters/where.js';\nimport type {\n BackofficeEntityManifestItem,\n BackofficePreparedDetailLayoutDataRoute,\n BackofficeResolvedDetailLayoutFacetConfig,\n} from '@plumile/backoffice-core/types.js';\nimport { FormattedDate } from '@plumile/ui/atomic/atoms/formatted-date/FormattedDate.js';\nimport { Tabs } from '@plumile/ui/atomic/molecules/tabs/Tabs.js';\nimport { Tag } from '@plumile/ui/backoffice/atoms/tag/Tag.js';\nimport { BackofficeKeyValueList } from '@plumile/ui/backoffice/molecules/backoffice_key_value_list/BackofficeKeyValueList.js';\nimport { BackofficePageHeader } from '@plumile/ui/backoffice/molecules/backoffice_page_header/BackofficePageHeader.js';\nimport {\n BackofficeRelationsMenu,\n type BackofficeRelationsMenuItem,\n} from '@plumile/ui/backoffice/molecules/backoffice_relations_menu/BackofficeRelationsMenu.js';\nimport { Spinner } from '@plumile/ui/backoffice/atoms/spinner/Spinner.js';\nimport { DetailPageTemplate } from '@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js';\n\nimport { BackofficeDetailBadgeRow } from '../components/backoffice/detail/BackofficeDetailBadgeRow.js';\nimport { BackofficeLazyEntityCount } from '../components/backoffice/refs/BackofficeLazyEntityCount.js';\nimport { BackofficeEntityDetailNotFound } from '../components/backoffice/scaffolds/BackofficeEntityDetailNotFound.js';\nimport { BackofficeRightPageLayout } from '../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport { buildEntityDetailBreadcrumb } from '../components/backoffice/layout/breadcrumb/buildBreadcrumbs.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeFragment } from '../relay/typedRelayHooks.js';\nimport * as pageStyles from './backofficeEntityDetailPage.css.js';\nimport {\n resolveLabel,\n resolveRelationValue,\n} from './BackofficeEntityDetailPage.helpers.js';\nimport { resolveHeaderItems } from './BackofficeEntityDetailPage.view-helpers.js';\nimport { BackofficeEntityDetailLayoutContextProvider } from './detail/BackofficeEntityDetailLayoutContext.js';\nimport { buildTabsItems } from './detail/buildTabsItems.js';\nimport { resolveVisibleDetailPages } from './detail/pageResolution.js';\nimport { BackofficeRedirect } from './BackofficeRedirect.js';\n\nconst { usePreloadedQuery } = ReactRelay;\n\nconst normalizePath = (value: string): string => {\n return value.trim().replace(/^\\/+|\\/+$/g, '');\n};\n\nconst resolveActivePagePath = (\n pathname: string,\n id: string,\n config: BackofficeResolvedDetailLayoutFacetConfig,\n): string => {\n const pages = [config.pages.mainPage, ...(config.pages.subPages ?? [])];\n const activePage = pages.find((page) => {\n return pathname === config.routes.detailPage(id, page.id);\n });\n return activePage?.path ?? '';\n};\n\nconst RelationCountLoading = (): JSX.Element => {\n return (\n <span className={pageStyles.relationCountLoading}>\n <Spinner size={12} />\n </span>\n );\n};\n\nconst DetailPageContentLoading = (): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n return (\n <div role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <Spinner size={20} ariaLabel={t('common.loading')} />\n </div>\n );\n};\n\nexport type BackofficeEntityDetailLayoutPageProps = {\n entityManifest: BackofficeEntityManifestItem;\n config: BackofficeResolvedDetailLayoutFacetConfig;\n prepared: BackofficePreparedDetailLayoutDataRoute;\n children?: ReactNode;\n};\n\ntype BackofficeEntityDetailLayoutPageContentProps = {\n config: BackofficeResolvedDetailLayoutFacetConfig;\n prepared: BackofficePreparedDetailLayoutDataRoute;\n layoutNodeRef: unknown;\n children?: ReactNode;\n};\n\nconst BackofficeEntityDetailLayoutPageContent = ({\n config,\n prepared,\n layoutNodeRef,\n children,\n}: BackofficeEntityDetailLayoutPageContentProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities } = useBackofficeConfig();\n const { pathname } = useLocation();\n const layoutNode = useBackofficeFragment<unknown, unknown>(\n config.layoutPage.fragment,\n layoutNodeRef,\n );\n\n const layoutView = config.layoutPage.toView(layoutNode);\n const activePagePath = resolveActivePagePath(pathname, prepared.id, config);\n const resolvedPages = resolveVisibleDetailPages({\n mainPage: config.pages.mainPage,\n subPages: config.pages.subPages,\n activePagePath,\n node: layoutView,\n });\n\n if (!resolvedPages.hasVisiblePages || resolvedPages.activePage == null) {\n return <BackofficeRedirect to={config.routes.list} />;\n }\n\n const { activePage } = resolvedPages;\n if (\n activePagePath !== '' &&\n normalizePath(activePage.path) !== normalizePath(activePagePath)\n ) {\n return (\n <BackofficeRedirect\n to={config.routes.detailPage(prepared.id, activePage.id)}\n />\n );\n }\n\n const tabsItems = buildTabsItems({\n pages: resolvedPages.pages,\n id: prepared.id,\n tApp,\n detailPageHref: config.routes.detailPage,\n });\n const resolveEntityHref = (entityId: string, refId: string) => {\n const entityConfig = entities[entityId];\n if (entityConfig == null) {\n return null;\n }\n return entityConfig.routes.detail(refId);\n };\n const header = resolveHeaderItems(config.header, layoutView, {\n tApp,\n t,\n resolveEntityHref,\n renderLink: (href, label) => {\n return (\n <Link to={href} preloadOnHover=\"code-and-data\">\n {label}\n </Link>\n );\n },\n renderDate: (value, fallback) => {\n return (\n <FormattedDate\n value={value}\n options={BACKOFFICE_DATE_TIME_OPTIONS}\n fallback={fallback}\n />\n );\n },\n renderTag: (tone, label) => {\n return <Tag tone={tone}>{label}</Tag>;\n },\n renderBadgeRow: (items) => {\n return <BackofficeDetailBadgeRow items={items} />;\n },\n });\n const relationMenuItems: BackofficeRelationsMenuItem[] = (\n config.relations ?? []\n ).flatMap((relation) => {\n const { path, target, whereKey } = relation;\n const value = resolveRelationValue(relation.value(layoutView));\n if (value == null) {\n return [];\n }\n\n const entityManifest = entities[target];\n if (entityManifest?.hasList !== true) {\n return [];\n }\n\n const where = setWhereValue(null, whereKey, value, path);\n if (where == null) {\n return [];\n }\n\n const encoded = entityManifest.listNavigation.encode({ where });\n\n return [\n {\n id: relation.id,\n label: resolveLabel(relation.label, tApp),\n count: (\n <BackofficeLazyEntityCount\n entity={target}\n loadingFallback={<RelationCountLoading />}\n where={where}\n />\n ),\n destination: {\n pathname: entityManifest.routes.list,\n filters: encoded.filters,\n query: encoded.query,\n },\n },\n ];\n });\n const breadcrumb = buildEntityDetailBreadcrumb({\n config,\n tApp,\n entityId: prepared.id,\n layoutView,\n pageLabel: activePage.label(tApp),\n pageId: activePage.id,\n });\n let headerMetaNode: JSX.Element | undefined;\n if (header.status != null || header.badges != null) {\n headerMetaNode = (\n <div className={pageStyles.headerMeta}>\n {header.status}\n {header.badges}\n </div>\n );\n }\n let headerItemsNode: JSX.Element | null = null;\n if (header.items != null && header.items.length > 0) {\n headerItemsNode = (\n <div className={pageStyles.headerMetaList}>\n <BackofficeKeyValueList items={header.items} />\n </div>\n );\n }\n let headerActionsNode: JSX.Element | undefined;\n if (relationMenuItems.length > 0) {\n headerActionsNode = (\n <div className={pageStyles.headerRelationGroup}>\n <BackofficeRelationsMenu\n label={t('relations.menu.label')}\n items={relationMenuItems}\n />\n </div>\n );\n }\n\n const headerNode = (\n <div className={pageStyles.headerBlock}>\n <BackofficePageHeader\n title={header.title}\n subtitle={header.subtitle}\n meta={headerMetaNode}\n actions={headerActionsNode}\n />\n {headerItemsNode}\n </div>\n );\n let tabsNode: JSX.Element | null = null;\n if (resolvedPages.pages.length > 1) {\n tabsNode = (\n <Tabs items={tabsItems} activeId={activePage.id} variant=\"underline\" />\n );\n }\n\n return (\n <BackofficeEntityDetailLayoutContextProvider\n value={{\n activePage,\n config,\n entityId: prepared.id,\n layoutView,\n tabsItems,\n visiblePages: resolvedPages.pages,\n }}\n >\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DetailPageTemplate\n headerNode={headerNode}\n tabsNode={tabsNode}\n headerDensity=\"compact\"\n >\n <Suspense fallback={<DetailPageContentLoading />}>\n {children}\n </Suspense>\n </DetailPageTemplate>\n </BackofficeRightPageLayout>\n </BackofficeEntityDetailLayoutContextProvider>\n );\n};\n\nexport const BackofficeEntityDetailLayoutPage = ({\n config,\n prepared,\n children,\n}: BackofficeEntityDetailLayoutPageProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const layoutQueryData = usePreloadedQuery(\n config.layoutPage.query,\n prepared.layoutQuery,\n );\n const layoutNodeRef = config.layoutPage.resolveNode(layoutQueryData, {\n id: prepared.id,\n });\n\n if (layoutNodeRef == null) {\n return (\n <BackofficeRightPageLayout\n breadcrumb={[\n {\n kind: 'link',\n target: {\n kind: 'entity-list',\n entityId: config.id,\n },\n label: config.label(tApp),\n },\n {\n kind: 'current',\n target: {\n kind: 'entity-detail',\n entityId: config.id,\n id: prepared.id,\n },\n label: t('detail.notFound'),\n },\n ]}\n >\n <BackofficeEntityDetailNotFound listHref={config.routes.list} />\n </BackofficeRightPageLayout>\n );\n }\n\n return (\n <BackofficeEntityDetailLayoutPageContent\n config={config}\n prepared={prepared}\n layoutNodeRef={layoutNodeRef}\n >\n {children}\n </BackofficeEntityDetailLayoutPageContent>\n );\n};\n\nexport default BackofficeEntityDetailLayoutPage;\n"],"mappings":"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"}
@@ -16,10 +16,7 @@ import { BACKOFFICE_LIST_DEFAULTS as y, BACKOFFICE_LIST_REFETCH_POLICY as b } fr
16
16
  import { stableListVariablesKey as x } from "@plumile/backoffice-core/state/stableKey.js";
17
17
  //#region src/pages/BackofficeEntityListDataPage.tsx
18
18
  function S({ queryRef: t }) {
19
- let { config: a, state: p, pushState: m, headerActions: g, columns: _, gridTemplateColumns: S, getRowId: C, countFetchKey: w, bumpCountFetchKey: T, filterDrawerState: E, registerRefresh: D } = c(), O = a.list, { t: k } = e(), A = v(O.query, t), { data: j, loadNext: M, hasNext: N, isLoadingNext: P, refetch: F } = n(O.fragment, A), I = O.getConnection(j), L = d(() => I.edges.map((e) => O.toRow(e.node)), [I.edges, O]), R = a.listDefaults ?? O.defaultState ?? {
20
- where: null,
21
- sort: null
22
- }, z = p.sort ?? R.sort, { pageSize: B } = y, V = d(() => ({
19
+ let { config: a, state: p, pushState: m, headerActions: g, columns: _, gridTemplateColumns: S, getRowId: C, countFetchKey: w, bumpCountFetchKey: T, filterDrawerState: E, registerRefresh: D } = c(), O = a.list, { t: k } = e(), A = v(O.query, t), { data: j, loadNext: M, hasNext: N, isLoadingNext: P, refetch: F } = n(O.fragment, A), I = O.getConnection(j), L = d(() => I.edges.map((e) => O.toRow(e.node)), [I.edges, O]), { listDefaults: R } = a, z = p.sort ?? R.sort, { pageSize: B } = y, V = d(() => ({
23
20
  where: p.where,
24
21
  sort: z,
25
22
  count: B,
@@ -95,10 +92,7 @@ var C = ({ prepared: n }) => {
95
92
  k();
96
93
  }, [k]);
97
94
  let A = l(() => {
98
- let e = r.list, t = r.listDefaults ?? e.defaultState ?? {
99
- where: null,
100
- sort: null
101
- }, { pageSize: n } = y, i = {
95
+ let e = r.list, { listDefaults: t } = r, { pageSize: n } = y, i = {
102
96
  where: o.where,
103
97
  sort: o.sort ?? t.sort,
104
98
  count: n,