@open-mercato/ui 0.5.1-develop.2800.bfe2178a4f → 0.5.1-develop.2802.9223828f7f
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.
|
@@ -603,6 +603,7 @@ function DataTable({
|
|
|
603
603
|
rowClickActionIds,
|
|
604
604
|
disableRowClick = false,
|
|
605
605
|
bulkActions: bulkActionsProp,
|
|
606
|
+
selectionScopeKey,
|
|
606
607
|
searchValue,
|
|
607
608
|
onSearchChange,
|
|
608
609
|
searchPlaceholder,
|
|
@@ -986,6 +987,7 @@ function DataTable({
|
|
|
986
987
|
const hasPropBulkActions = Array.isArray(bulkActionsProp) && bulkActionsProp.length > 0;
|
|
987
988
|
const hasInjectedBulkActions = injectedBulkActions.length > 0 || hasPropBulkActions;
|
|
988
989
|
const [rowSelection, setRowSelection] = React.useState({});
|
|
990
|
+
const selectionScopeKeyRef = React.useRef(selectionScopeKey);
|
|
989
991
|
const table = useReactTable({
|
|
990
992
|
data: clientFilteredData,
|
|
991
993
|
columns: mergedColumns,
|
|
@@ -1012,6 +1014,19 @@ function DataTable({
|
|
|
1012
1014
|
React.useEffect(() => {
|
|
1013
1015
|
if (sortingProp) setSorting(sortingProp);
|
|
1014
1016
|
}, [sortingProp]);
|
|
1017
|
+
React.useEffect(() => {
|
|
1018
|
+
if (selectionScopeKey === void 0) {
|
|
1019
|
+
selectionScopeKeyRef.current = void 0;
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
if (selectionScopeKeyRef.current === void 0) {
|
|
1023
|
+
selectionScopeKeyRef.current = selectionScopeKey;
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
if (selectionScopeKeyRef.current === selectionScopeKey) return;
|
|
1027
|
+
selectionScopeKeyRef.current = selectionScopeKey;
|
|
1028
|
+
setRowSelection({});
|
|
1029
|
+
}, [selectionScopeKey]);
|
|
1015
1030
|
React.useEffect(() => {
|
|
1016
1031
|
if (hasInjectedBulkActions) return;
|
|
1017
1032
|
if (Object.keys(rowSelection).length === 0) return;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/backend/DataTable.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport { useReactTable, getCoreRowModel, getSortedRowModel, flexRender, type ColumnDef, type SortingState, type Column as TableColumn, type VisibilityState, type RowSelectionState } from '@tanstack/react-table'\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { RefreshCw, Loader2, SlidersHorizontal, MoreHorizontal, Circle, Filter, ChevronDown, Check } from 'lucide-react'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../primitives/table'\nimport { Button } from '../primitives/button'\nimport { Checkbox } from '../primitives/checkbox'\nimport { Spinner } from '../primitives/spinner'\nimport { TooltipProvider } from '../primitives/tooltip'\nimport { TruncatedCell } from './TruncatedCell'\nimport { FilterBar, type FilterDef, type FilterValues } from './FilterBar'\nimport { useCustomFieldFilterDefs } from './utils/customFieldFilters'\nimport { fetchCustomFieldDefinitionsPayload, type CustomFieldsetDto } from './utils/customFieldDefs'\nimport { RowActions, type RowActionItem } from './RowActions'\nimport { subscribeOrganizationScopeChanged, type OrganizationScopeChangedDetail } from '@open-mercato/shared/lib/frontend/organizationEvents'\nimport { InjectionSpot } from './injection/InjectionSpot'\nimport { useAppEvent } from './injection/useAppEvent'\nimport { useInjectionDataWidgets } from './injection/useInjectionDataWidgets'\nimport { resolveInjectedIcon } from './injection/resolveInjectedIcon'\nimport { serializeExport, defaultExportFilename, type PreparedExport } from '@open-mercato/shared/lib/crud/exporters'\nimport { apiCall } from './utils/apiCall'\nimport { raiseCrudError } from './utils/serverErrors'\nimport { PerspectiveSidebar } from './PerspectiveSidebar'\nimport { Popover, PopoverTrigger, PopoverContent } from '../primitives/popover'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { flash } from './FlashMessages'\nimport { useConfirmDialog } from './confirm-dialog'\nimport type {\n PerspectiveDto,\n RolePerspectiveDto,\n PerspectivesIndexResponse,\n PerspectiveSettings,\n PerspectiveSaveResponse,\n} from '@open-mercato/shared/modules/perspectives/types'\nimport type {\n InjectionColumnDefinition,\n InjectionBulkActionDefinition,\n InjectionFilterDefinition,\n InjectionRowActionDefinition,\n} from '@open-mercato/shared/modules/widgets/injection'\nimport { ComponentReplacementHandles } from '@open-mercato/shared/modules/widgets/component-registry'\nimport { insertByInjectionPlacement } from '@open-mercato/shared/modules/widgets/injection-position'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport type { AdvancedFilterState, FilterFieldDef as AdvancedFilterFieldDef } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { createEmptyCondition, getDefaultOperator } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { AdvancedFilterBuilder } from './filters/AdvancedFilterBuilder'\nimport { type ColumnChooserField } from './columns/ColumnChooserPanel'\nimport { useAutoDiscoveredFields } from './utils/useAutoDiscoveredFields'\nimport { useCustomFieldDefs } from './utils/customFieldDefs'\nimport {\n DndContext,\n closestCenter,\n PointerSensor,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from '@dnd-kit/core'\nimport {\n SortableContext,\n horizontalListSortingStrategy,\n useSortable,\n} from '@dnd-kit/sortable'\nimport { CSS } from '@dnd-kit/utilities'\n\nlet refreshScheduled = false\n\nfunction scheduleRouterRefresh(router: ReturnType<typeof useRouter>) {\n if (refreshScheduled) return\n refreshScheduled = true\n if (typeof window === 'undefined') {\n refreshScheduled = false\n return\n }\n window.requestAnimationFrame(() => {\n refreshScheduled = false\n try { router.refresh() } catch {}\n })\n}\n\nexport type PaginationProps = {\n page: number\n pageSize: number\n total: number\n totalPages: number\n onPageChange: (page: number) => void\n durationMs?: number | null\n cacheStatus?: 'hit' | 'miss' | null\n pageSizeOptions?: number[]\n onPageSizeChange?: (pageSize: number) => void\n}\n\nexport type DataTableRefreshButton = {\n onRefresh: () => void\n label: string\n isRefreshing?: boolean\n disabled?: boolean\n}\n\nconst DEFAULT_ROW_CLICK_ACTION_IDS = ['edit', 'open']\n\nexport function withDataTableNamespaces<T extends Record<string, unknown>>(\n mappedRow: T,\n sourceItem: Record<string, unknown>,\n): T & Record<string, unknown> {\n const namespaced: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(sourceItem)) {\n if (!key.startsWith('_')) continue\n namespaced[key] = value\n }\n return {\n ...mappedRow,\n ...namespaced,\n }\n}\n\nfunction resolveDataTableRowId<T>(row: T, index: number): string {\n if (row && typeof row === 'object') {\n const candidate = (row as Record<string, unknown>).id\n if (typeof candidate === 'string' && candidate.trim().length > 0) {\n return candidate\n }\n }\n return String(index)\n}\n\nfunction resolveDefaultRowAction(items: RowActionItem[], preferredIds: string[]): RowActionItem | null {\n for (const preferredId of preferredIds) {\n const match = items.find((item) => item.id === preferredId && (item.href || item.onSelect))\n if (match) return match\n }\n for (const preferredId of preferredIds) {\n const match = items.find((item) => item.label.toLowerCase() === preferredId && (item.href || item.onSelect))\n if (match) return match\n }\n return null\n}\n\nfunction pickDefaultRowAction(node: React.ReactNode, preferredIds: string[]): RowActionItem | null {\n if (!React.isValidElement(node)) return null\n const items = (node.props as { items?: RowActionItem[] }).items\n if (!Array.isArray(items)) return null\n return resolveDefaultRowAction(items, preferredIds)\n}\n\nexport type DataTableExportFormat = 'csv' | 'json' | 'xml' | 'markdown'\n\nexport type DataTableExportSectionConfig = {\n title?: string\n description?: string\n getUrl?: (format: DataTableExportFormat) => string\n prepare?: (format: DataTableExportFormat) => Promise<PreparedExport | { prepared: PreparedExport; filename?: string } | null> | PreparedExport | { prepared: PreparedExport; filename?: string } | null\n formats?: DataTableExportFormat[]\n disabled?: boolean\n filename?: (format: DataTableExportFormat) => string\n}\n\nexport type DataTableExportConfig = {\n label?: string\n disabled?: boolean\n formats?: DataTableExportFormat[]\n getUrl?: (format: DataTableExportFormat) => string\n sections?: DataTableExportSectionConfig[]\n view?: DataTableExportSectionConfig\n full?: DataTableExportSectionConfig\n filename?: (format: DataTableExportFormat) => string\n}\n\nexport type DataTablePerspectiveConfig = {\n tableId: string\n initialState?: {\n response?: PerspectivesIndexResponse\n activePerspectiveId?: string | null\n initialSettings?: PerspectiveSettings | null\n }\n}\n\nexport type BulkAction<T = Record<string, unknown>> = {\n id: string\n label: string\n icon?: React.ComponentType<{ className?: string }>\n destructive?: boolean\n onExecute: (selectedRows: T[]) => Promise<void | boolean | BulkActionExecuteResult> | void | boolean | BulkActionExecuteResult\n}\n\nexport type DataTableProps<T> = {\n columns: ColumnDef<T, any>[]\n data: T[]\n toolbar?: React.ReactNode\n title?: React.ReactNode\n actions?: React.ReactNode\n refreshButton?: DataTableRefreshButton\n sortable?: boolean\n sorting?: SortingState\n onSortingChange?: (s: SortingState) => void\n pagination?: PaginationProps\n isLoading?: boolean\n emptyState?: React.ReactNode\n error?: React.ReactNode | string | null\n rowActions?: (row: T) => React.ReactNode\n onRowClick?: (row: T) => void\n rowClickActionIds?: string[]\n disableRowClick?: boolean\n bulkActions?: BulkAction<T>[]\n\n // Auto FilterBar options (rendered as toolbar when provided and no custom toolbar passed)\n searchValue?: string\n onSearchChange?: (v: string) => void\n searchPlaceholder?: string\n searchAlign?: 'left' | 'right'\n filters?: FilterDef[]\n filterValues?: FilterValues\n onFiltersApply?: (values: FilterValues) => void\n onFiltersClear?: () => void\n entityId?: string\n entityIds?: string[]\n exporter?: DataTableExportConfig | false\n perspective?: DataTablePerspectiveConfig\n embedded?: boolean\n onCustomFieldFilterFieldsetChange?: (fieldset: string | null, entityId?: string) => void\n customFieldFilterKeyExtras?: Array<string | number | boolean | null | undefined>\n injectionSpotId?: string\n injectionContext?: Record<string, unknown>\n replacementHandle?: string\n stickyFirstColumn?: boolean\n stickyActionsColumn?: boolean\n virtualized?: boolean\n virtualizedMaxHeight?: number | string\n virtualizedOverscan?: number\n advancedFilter?: {\n fields?: AdvancedFilterFieldDef[]\n auto?: boolean\n value: AdvancedFilterState\n onChange: (state: AdvancedFilterState) => void\n onApply: () => void\n onClear: () => void\n }\n columnChooser?: {\n availableColumns?: ColumnChooserField[]\n auto?: boolean\n }\n}\n\nconst DEFAULT_EXPORT_FORMATS: DataTableExportFormat[] = ['csv', 'json', 'xml', 'markdown']\nconst EXPORT_LABELS: Record<DataTableExportFormat, string> = {\n csv: 'CSV',\n json: 'JSON',\n xml: 'XML',\n markdown: 'Markdown',\n}\nconst EMPTY_FILTER_DEFS: FilterDef[] = []\nconst EMPTY_FILTER_VALUES: FilterValues = Object.freeze({}) as FilterValues\n\ntype BulkActionExecuteResult = {\n ok: boolean\n message?: string\n affectedCount?: number\n progressJobId?: string | null\n}\n\nfunction collectUniqueById<T extends { id: string }>(\n entries: T[],\n warningScope: string,\n): T[] {\n const byId = new Map<string, T>()\n for (const entry of entries) {\n if (!entry.id) continue\n if (byId.has(entry.id)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`[UMES] Duplicate injected ${warningScope} id \"${entry.id}\" detected. Keeping the first entry.`)\n }\n continue\n }\n byId.set(entry.id, entry)\n }\n return Array.from(byId.values())\n}\n\ntype ResolvedExportSection = {\n key: string\n title: string\n description?: string\n formats: DataTableExportFormat[]\n getUrl?: (format: DataTableExportFormat) => string\n prepare?: (format: DataTableExportFormat) => Promise<{ prepared: PreparedExport; filename?: string } | null> | { prepared: PreparedExport; filename?: string } | null\n filename?: (format: DataTableExportFormat) => string\n disabled: boolean\n}\n\nfunction resolveExportSections(config: DataTableExportConfig | null | undefined): ResolvedExportSection[] {\n if (!config) return []\n const sections: ResolvedExportSection[] = []\n const baseFormats = config.formats && config.formats.length > 0 ? config.formats : DEFAULT_EXPORT_FORMATS\n const addSection = (key: string, section: DataTableExportSectionConfig | undefined | null, fallbackTitle: string) => {\n if (!section || (!section.getUrl && !section.prepare)) return\n const title = section.title?.trim().length ? section.title!.trim() : fallbackTitle\n const seen = new Set<DataTableExportFormat>()\n const formatsSource = section.formats && section.formats.length > 0 ? section.formats : baseFormats\n const formats = formatsSource.filter((format) => {\n if (seen.has(format)) return false\n seen.add(format)\n return true\n })\n if (formats.length === 0) return\n sections.push({\n key,\n title,\n description: section.description,\n formats,\n getUrl: section.getUrl,\n prepare: section.prepare\n ? async (format: DataTableExportFormat) => {\n const result = await section.prepare!(format)\n if (!result) return null\n if ('prepared' in result) return result\n return { prepared: result }\n }\n : undefined,\n filename: section.filename,\n disabled: Boolean(config.disabled || section.disabled),\n })\n }\n\n // Allow legacy config (getUrl without sections/view)\n const hasExplicitSections = Array.isArray(config.sections) && config.sections.length > 0\n if (!config.view && !config.full && !hasExplicitSections && config.getUrl) {\n addSection('view', { getUrl: config.getUrl, formats: config.formats }, 'Export what you view')\n } else {\n addSection('view', config.view, 'Export what you view')\n }\n\n if (hasExplicitSections) {\n config.sections!.forEach((section, idx) => {\n addSection(`section-${idx}`, section, section.title?.trim().length ? section.title! : `Export ${idx + 1}`)\n })\n }\n\n addSection('full', config.full, 'Full data export')\n return sections\n}\n\nconst PERSPECTIVE_COOKIE_PREFIX = 'om_table_perspective'\nconst PERSPECTIVE_STORAGE_PREFIX = 'om_table_perspective_snapshot'\n\nfunction formatDurationLabel(durationMs?: number | null): string {\n if (durationMs == null) return ''\n if (!Number.isFinite(durationMs)) return ''\n if (durationMs < 0) return ''\n if (durationMs < 1000) return `${Math.round(durationMs)}ms`\n if (durationMs < 10_000) return `${(durationMs / 1000).toFixed(1)}s`\n if (durationMs < 60_000) return `${Math.round(durationMs / 1000)}s`\n if (durationMs < 3_600_000) return `${(durationMs / 60_000).toFixed(durationMs < 600_000 ? 1 : 0)}m`\n return `${(durationMs / 3_600_000).toFixed(durationMs < 7_200_000 ? 1 : 0)}h`\n}\n\ntype PerspectiveSnapshot = {\n perspectiveId: string | null\n settings: PerspectiveSettings\n updatedAt: number\n}\n\nfunction readPerspectiveCookie(tableId: string): string | null {\n if (typeof document === 'undefined') return null\n const key = `${PERSPECTIVE_COOKIE_PREFIX}:${tableId}`\n const pattern = new RegExp(`(?:^|;\\\\s*)${key}=([^;]+)`)\n const match = document.cookie.match(pattern)\n return match ? decodeURIComponent(match[1]) : null\n}\n\nfunction writePerspectiveCookie(tableId: string, perspectiveId: string | null): void {\n if (typeof document === 'undefined') return\n const key = `${PERSPECTIVE_COOKIE_PREFIX}:${tableId}`\n const expires = perspectiveId ? 'Max-Age=31536000' : 'Max-Age=0'\n const value = perspectiveId ? encodeURIComponent(perspectiveId) : ''\n document.cookie = `${key}=${value}; Path=/; ${expires}; SameSite=Lax`\n}\n\nfunction readPerspectiveSnapshot(tableId: string): PerspectiveSnapshot | null {\n if (typeof window === 'undefined') return null\n try {\n const raw = window.localStorage.getItem(`${PERSPECTIVE_STORAGE_PREFIX}:${tableId}`)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n if (!parsed || typeof parsed !== 'object') return null\n const perspectiveId =\n typeof parsed.perspectiveId === 'string' && parsed.perspectiveId.trim().length > 0\n ? parsed.perspectiveId\n : null\n const settings = typeof parsed.settings === 'object' && parsed.settings !== null\n ? parsed.settings as PerspectiveSettings\n : null\n const updatedAt = typeof parsed.updatedAt === 'number' ? parsed.updatedAt : Date.now()\n if (!settings) return null\n return { perspectiveId, settings, updatedAt }\n } catch {\n return null\n }\n}\n\nfunction writePerspectiveSnapshot(tableId: string, snapshot: PerspectiveSnapshot | null) {\n if (typeof window === 'undefined') return\n const key = `${PERSPECTIVE_STORAGE_PREFIX}:${tableId}`\n try {\n if (!snapshot) {\n window.localStorage.removeItem(key)\n return\n }\n window.localStorage.setItem(key, JSON.stringify(snapshot))\n } catch {\n // ignore storage errors\n }\n}\n\nfunction sanitizePerspectiveSettings(source?: PerspectiveSettings | null): PerspectiveSettings | null {\n if (!source || typeof source !== 'object') return null\n const forbidden = new Set(['__proto__', 'prototype', 'constructor'])\n const result: PerspectiveSettings = {}\n\n if (Array.isArray(source.columnOrder)) {\n const seen = new Set<string>()\n const order = source.columnOrder\n .map((id) => (typeof id === 'string' ? id.trim() : ''))\n .filter((id) => id.length > 0 && !seen.has(id) && (seen.add(id), true))\n if (order.length) result.columnOrder = order\n }\n\n if (source.columnVisibility && typeof source.columnVisibility === 'object') {\n const entries = Object.entries(source.columnVisibility)\n .filter(([key, value]) => typeof key === 'string' && key.trim().length > 0 && !forbidden.has(key) && typeof value === 'boolean')\n if (entries.length) {\n const visibility: Record<string, boolean> = {}\n entries.forEach(([key, value]) => { visibility[key] = value })\n result.columnVisibility = visibility\n }\n }\n\n if (Array.isArray(source.sorting)) {\n const sorting = source.sorting\n .map((item) => {\n const id = typeof item?.id === 'string' ? item.id.trim() : ''\n if (!id || forbidden.has(id)) return null\n return { id, desc: Boolean(item?.desc) }\n })\n .filter((item): item is { id: string; desc: boolean } => item !== null)\n if (sorting.length) result.sorting = sorting\n }\n\n if (typeof source.pageSize === 'number' && Number.isFinite(source.pageSize)) {\n const pageSize = Math.max(1, Math.min(500, Math.floor(source.pageSize)))\n result.pageSize = pageSize\n }\n\n if (typeof source.searchValue === 'string' && source.searchValue.trim().length > 0) {\n result.searchValue = source.searchValue.trim().slice(0, 200)\n }\n\n if (source.filters && typeof source.filters === 'object') {\n const filters: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(source.filters)) {\n if (typeof key === 'string') {\n const trimmed = key.trim()\n if (trimmed.length > 0 && !forbidden.has(trimmed)) filters[trimmed] = value\n }\n }\n if (Object.keys(filters).length) result.filters = filters\n }\n\n return Object.keys(result).length ? result : null\n}\n\nfunction normalizeLabel(input: string): string {\n if (!input) return ''\n return input\n .replace(/^cf[_:]/, '')\n .replace(/[_:\\-]+/g, ' ')\n .replace(/\\b\\w/g, (ch) => ch.toUpperCase())\n}\n\n// Column width configuration based on column type\ntype ColumnTruncateConfig = {\n maxWidth: string\n truncate: boolean\n}\n\ntype ColumnTruncateMeta = {\n truncate?: boolean\n maxWidth?: string\n}\n\nfunction getColumnTruncateConfig(columnId: string, accessorKey?: string, columnMeta?: ColumnTruncateMeta): ColumnTruncateConfig {\n const key = accessorKey || columnId\n const metaMaxWidth = typeof columnMeta?.maxWidth === 'string' ? columnMeta.maxWidth.trim() : ''\n\n // Custom fields get narrower width\n if (key.startsWith('cf_') || key.startsWith('cf:')) {\n return {\n maxWidth: metaMaxWidth || '120px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n }\n\n // Core informative columns get wider width\n const wideColumns = ['title', 'name', 'description', 'source', 'companies', 'people']\n if (wideColumns.includes(key)) {\n return {\n maxWidth: metaMaxWidth || '250px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n }\n\n // Medium width for status-like columns\n const mediumColumns = ['status', 'pipelineStage', 'pipeline_stage', 'type', 'category']\n if (mediumColumns.includes(key)) {\n return {\n maxWidth: metaMaxWidth || '180px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n }\n\n // Date columns\n if (key.endsWith('_at') || key.endsWith('At') || key.includes('date') || key.includes('Date')) {\n return {\n maxWidth: metaMaxWidth || '120px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n }\n\n // Default for other columns\n return {\n maxWidth: metaMaxWidth || '150px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n}\n\nfunction readInjectedColumnValue(row: unknown, accessorKey: string): unknown {\n if (!row || typeof row !== 'object' || !accessorKey) return undefined\n const segments = accessorKey.split('.').filter((segment) => segment.length > 0)\n if (segments.length === 0) return undefined\n let current: unknown = row\n for (const segment of segments) {\n if (!current || typeof current !== 'object') return undefined\n current = (current as Record<string, unknown>)[segment]\n }\n return current\n}\n\n// Check if a column should skip truncation (e.g., actions column)\nfunction shouldSkipTruncation(columnId: string): boolean {\n const skipColumns = ['actions', 'select', 'checkbox', 'expand']\n return skipColumns.includes(columnId.toLowerCase())\n}\n\nfunction ExportMenu({ config, sections }: { config: DataTableExportConfig; sections: ResolvedExportSection[] }) {\n const t = useT()\n const { label } = config\n const defaultLabel = label ?? t('ui.dataTable.export.label', 'Export')\n const disabled = Boolean(config.disabled)\n const hasSections = sections.length > 0\n const [open, setOpen] = React.useState(false)\n const buttonRef = React.useRef<HTMLButtonElement>(null)\n const menuRef = React.useRef<HTMLDivElement>(null)\n\n React.useEffect(() => {\n if (!open || !hasSections) return\n const onDocClick = (event: MouseEvent) => {\n const target = event.target as Node\n if (menuRef.current && !menuRef.current.contains(target) && buttonRef.current && !buttonRef.current.contains(target)) {\n setOpen(false)\n }\n }\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setOpen(false)\n buttonRef.current?.focus()\n }\n }\n document.addEventListener('mousedown', onDocClick)\n document.addEventListener('keydown', onKeyDown)\n return () => {\n document.removeEventListener('mousedown', onDocClick)\n document.removeEventListener('keydown', onKeyDown)\n }\n }, [hasSections, open])\n\n if (!hasSections) return null\n\n const handleSelect = async (section: ResolvedExportSection, format: DataTableExportFormat) => {\n try {\n if (section.prepare) {\n const preparedResult = await section.prepare(format)\n if (!preparedResult) return\n const prepared = preparedResult.prepared\n const serialized = serializeExport(prepared, format)\n const filename =\n preparedResult.filename\n ?? section.filename?.(format)\n ?? config.filename?.(format)\n ?? defaultExportFilename(section.title, format)\n if (typeof window !== 'undefined') {\n const blob = new Blob([serialized.body], { type: serialized.contentType })\n const href = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = href\n a.download = filename\n document.body.appendChild(a)\n a.click()\n document.body.removeChild(a)\n URL.revokeObjectURL(href)\n }\n } else if (section.getUrl) {\n const url = section.getUrl(format)\n if (url && typeof window !== 'undefined') {\n window.open(url, '_blank', 'noopener,noreferrer')\n }\n }\n } catch {\n // ignore export errors\n } finally {\n setOpen(false)\n }\n }\n\n return (\n <div className=\"relative inline-block\">\n <Button\n ref={buttonRef}\n variant=\"outline\"\n size=\"sm\"\n type=\"button\"\n onClick={() => {\n if (disabled) return\n setOpen((prev) => !prev)\n }}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n disabled={disabled}\n >\n {defaultLabel}\n </Button>\n {open ? (\n <div\n ref={menuRef}\n role=\"menu\"\n className=\"absolute right-0 mt-2 w-60 rounded-md border bg-background py-2 shadow z-20\"\n >\n {sections.map((section, idx) => (\n <div key={section.key} className={idx > 0 ? 'mt-2 border-t pt-3' : ''}>\n <div className=\"px-3\">\n <div className=\"text-xs font-semibold uppercase text-muted-foreground\">{section.title}</div>\n {section.description ? (\n <p className=\"mt-1 text-xs text-muted-foreground leading-snug\">{section.description}</p>\n ) : null}\n </div>\n <div className=\"mt-2 space-y-1 px-2 pb-1\">\n {section.formats.map((format) => (\n <Button\n key={`${section.key}-${format}`}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"w-full justify-start font-normal\"\n onClick={() => void handleSelect(section, format)}\n disabled={section.disabled}\n >\n {EXPORT_LABELS[format]}\n </Button>\n ))}\n </div>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\nfunction sanitizeDndContextId(value: string): string {\n const trimmed = value.trim().toLowerCase()\n let normalized = ''\n let previousWasDash = false\n\n for (const character of trimmed) {\n const isLowercaseLetter = character >= 'a' && character <= 'z'\n const isDigit = character >= '0' && character <= '9'\n\n if (isLowercaseLetter || isDigit || character === '_') {\n normalized += character\n previousWasDash = false\n continue\n }\n\n if (!previousWasDash) {\n normalized += '-'\n previousWasDash = true\n }\n }\n\n while (normalized.startsWith('-')) {\n normalized = normalized.slice(1)\n }\n\n while (normalized.endsWith('-')) {\n normalized = normalized.slice(0, -1)\n }\n\n return normalized.length > 0 ? normalized : 'data-table'\n}\n\nfunction HeaderDndWrapper({ enabled, contextId, sensors, columnIds, onDragEnd, children }: {\n enabled: boolean\n contextId: string\n sensors: ReturnType<typeof useSensors>\n columnIds: string[]\n onDragEnd: (event: DragEndEvent) => void\n children: React.ReactNode\n}) {\n if (!enabled) return <>{children}</>\n return (\n <DndContext id={contextId} sensors={sensors} collisionDetection={closestCenter} onDragEnd={onDragEnd}>\n <SortableContext items={columnIds} strategy={horizontalListSortingStrategy}>\n {children}\n </SortableContext>\n </DndContext>\n )\n}\n\nfunction SortableHeaderCell({ id, children, className }: { id: string; children: React.ReactNode; className?: string }) {\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id })\n const isSticky = typeof className === 'string' && className.includes('sticky')\n const style: React.CSSProperties = {\n transform: CSS.Transform.toString(transform),\n transition,\n opacity: isDragging ? 0.5 : 1,\n cursor: 'grab',\n position: isSticky ? 'sticky' : 'relative',\n }\n return (\n <TableHead ref={setNodeRef} style={style} className={className} {...attributes} {...listeners}>\n {children}\n </TableHead>\n )\n}\n\nfunction ViewSwitcherDropdown({\n activePerspectiveId,\n perspectives,\n rolePerspectives,\n onClear,\n onActivate,\n onOpenSidebar,\n t,\n}: {\n activePerspectiveId: string | null\n perspectives: PerspectiveDto[]\n rolePerspectives: RolePerspectiveDto[]\n onClear: () => void\n onActivate: (item: PerspectiveDto | RolePerspectiveDto, source: 'personal' | 'role') => void\n onOpenSidebar: () => void\n t: (key: string, fallback: string) => string\n}) {\n const [open, setOpen] = React.useState(false)\n const allViews = [...perspectives, ...rolePerspectives]\n const activeName = allViews.find((v) => v.id === activePerspectiveId)?.name.trim() || ''\n const activeLabel = activeName || t('ui.dataTable.perspectives.allViews', 'All views')\n return (\n <div className=\"inline-flex h-9 items-center rounded-md border border-input text-sm\">\n <Button\n data-testid=\"data-table-open-views-sidebar\"\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={onOpenSidebar}\n className=\"h-full rounded-none rounded-l-md px-3 font-medium\"\n >\n <SlidersHorizontal className=\"size-4 mr-1.5\" />\n {t('ui.dataTable.perspectives.button', 'Views')}\n </Button>\n <div className=\"h-5 w-px bg-border\" />\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-full max-w-[200px] rounded-none rounded-r-md px-3 font-normal text-muted-foreground\"\n >\n <span className=\"truncate\">{activeLabel}</span>\n <ChevronDown className=\"size-3.5 shrink-0 ml-1.5\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-[220px] p-1\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className={cn(\n 'w-full justify-start h-auto px-2 py-1.5 text-sm font-normal',\n !activePerspectiveId && 'bg-accent text-accent-foreground'\n )}\n onClick={() => { onClear(); setOpen(false) }}\n >\n <Check className={cn('size-4 shrink-0 mr-2', activePerspectiveId ? 'invisible' : '')} />\n {t('ui.dataTable.perspectives.noView', '\u2014 No view \u2014')}\n </Button>\n {perspectives.map((p) => (\n <Button\n key={p.id}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className={cn(\n 'w-full justify-start h-auto px-2 py-1.5 text-sm font-normal',\n activePerspectiveId === p.id && 'bg-accent text-accent-foreground'\n )}\n onClick={() => { onActivate(p, 'personal'); setOpen(false) }}\n >\n <Check className={cn('size-4 shrink-0 mr-2', activePerspectiveId !== p.id ? 'invisible' : '')} />\n <span className=\"truncate\">{p.name.trim() || t('ui.perspectives.untitled', 'Untitled view')}</span>\n </Button>\n ))}\n {rolePerspectives.map((p) => (\n <Button\n key={p.id}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className={cn(\n 'w-full justify-start h-auto px-2 py-1.5 text-sm font-normal',\n activePerspectiveId === p.id && 'bg-accent text-accent-foreground'\n )}\n onClick={() => { onActivate(p, 'role'); setOpen(false) }}\n >\n <Check className={cn('size-4 shrink-0 mr-2', activePerspectiveId !== p.id ? 'invisible' : '')} />\n <span className=\"truncate\">{p.name.trim() || t('ui.perspectives.untitled', 'Untitled view')}</span>\n </Button>\n ))}\n </PopoverContent>\n </Popover>\n </div>\n )\n}\n\nexport function DataTable<T>({\n columns,\n data,\n toolbar,\n title,\n actions,\n refreshButton,\n sortable,\n sorting: sortingProp,\n onSortingChange,\n pagination,\n isLoading,\n emptyState,\n error,\n rowActions,\n onRowClick,\n rowClickActionIds,\n disableRowClick = false,\n bulkActions: bulkActionsProp,\n searchValue,\n onSearchChange,\n searchPlaceholder,\n searchAlign = 'left',\n filters: baseFilters = EMPTY_FILTER_DEFS,\n filterValues = EMPTY_FILTER_VALUES,\n onFiltersApply,\n onFiltersClear,\n entityId,\n entityIds,\n exporter,\n perspective,\n embedded = false,\n onCustomFieldFilterFieldsetChange,\n customFieldFilterKeyExtras,\n injectionSpotId,\n injectionContext,\n replacementHandle,\n stickyFirstColumn = false,\n stickyActionsColumn = false,\n virtualized = false,\n virtualizedMaxHeight,\n virtualizedOverscan = 10,\n advancedFilter,\n columnChooser,\n}: DataTableProps<T>) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const router = useRouter()\n const resolvedRowClickActionIds = rowClickActionIds ?? DEFAULT_ROW_CLICK_ACTION_IDS\n const containerRef = React.useRef<HTMLDivElement>(null)\n const lastScopeRef = React.useRef<OrganizationScopeChangedDetail | null>(null)\n const hasInitializedScopeRef = React.useRef(false)\n React.useEffect(() => {\n return subscribeOrganizationScopeChanged((detail) => {\n const prev = lastScopeRef.current\n lastScopeRef.current = detail\n if (!hasInitializedScopeRef.current) {\n hasInitializedScopeRef.current = true\n return\n }\n if (\n prev &&\n prev.organizationId === detail.organizationId &&\n prev.tenantId === detail.tenantId\n ) {\n return\n }\n scheduleRouterRefresh(router)\n })\n }, [router])\n const queryClient = useQueryClient()\n const perspectiveConfig = perspective ?? null\n const perspectiveTableId = perspectiveConfig?.tableId ?? null\n const perspectiveEnabled = Boolean(perspectiveTableId)\n // Snapshot from localStorage is read post-mount via useLayoutEffect to avoid SSR/CSR\n // hydration mismatch. Initial render uses only props-derived state (identical on both sides).\n const initialSnapshotRef = React.useRef<PerspectiveSnapshot | null>(null)\n const snapshotHydratedTableRef = React.useRef<string | null>(null)\n const initialSettingsFromConfig = sanitizePerspectiveSettings(perspectiveConfig?.initialState?.initialSettings ?? null)\n const mergedInitialSettings = initialSettingsFromConfig\n const initialActiveId = perspectiveConfig?.initialState?.activePerspectiveId ?? null\n const [isPerspectiveOpen, setPerspectiveOpen] = React.useState(false)\n const [isAdvancedFilterOpen, setAdvancedFilterOpen] = React.useState(false)\n const [activePerspectiveId, setActivePerspectiveId] = React.useState<string | null>(initialActiveId)\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>(() => mergedInitialSettings?.columnVisibility ?? {})\n const [columnOrder, setColumnOrder] = React.useState<string[]>(() => mergedInitialSettings?.columnOrder ?? [])\n const [deletingIds, setDeletingIds] = React.useState<string[]>([])\n const [roleClearingIds, setRoleClearingIds] = React.useState<string[]>([])\n const [perspectiveApiMissing, setPerspectiveApiMissing] = React.useState(false)\n\n const perspectiveFeatureQuery = useQuery<{ use: boolean; roleDefaults: boolean }>({\n queryKey: ['feature-check', 'perspectives'],\n enabled: perspectiveEnabled,\n staleTime: 5 * 60 * 1000,\n queryFn: async () => {\n try {\n const call = await apiCall<{ granted?: unknown[] }>(\n '/api/auth/feature-check',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ features: ['perspectives.use', 'perspectives.role_defaults'] }),\n },\n )\n if (!call.ok) throw new Error(`feature-check failed (${call.status})`)\n const data = call.result ?? {}\n const granted = Array.isArray(data?.granted) ? data.granted.map((f: any) => String(f)) : []\n const has = (feature: string) => granted.some((grantedFeature: string) => {\n if (grantedFeature === '*') return true\n if (grantedFeature === feature) return true\n if (grantedFeature.endsWith('.*')) {\n const prefix = grantedFeature.slice(0, -2)\n return feature === prefix || feature.startsWith(`${prefix}.`)\n }\n return false\n })\n return {\n use: has('perspectives.use'),\n roleDefaults: has('perspectives.role_defaults'),\n }\n } catch {\n return {\n use: true,\n roleDefaults: true,\n }\n }\n },\n })\n const perspectivePermissions = perspectiveFeatureQuery.data\n const canUsePerspectives = perspectiveEnabled && Boolean(perspectivePermissions?.use)\n const canUseRoleDefaultsFeature = Boolean(perspectivePermissions?.roleDefaults)\n\n React.useEffect(() => {\n if (!canUsePerspectives && isPerspectiveOpen) {\n setPerspectiveOpen(false)\n }\n }, [canUsePerspectives, isPerspectiveOpen])\n\n React.useEffect(() => {\n if (!perspectiveTableId) return\n if (!mergedInitialSettings) return\n const snapshot: PerspectiveSnapshot = {\n perspectiveId: initialActiveId,\n settings: mergedInitialSettings,\n updatedAt: Date.now(),\n }\n writePerspectiveSnapshot(perspectiveTableId, snapshot)\n initialSnapshotRef.current = snapshot\n }, [perspectiveTableId, mergedInitialSettings, initialActiveId])\n\n const perspectiveQuery = useQuery<PerspectivesIndexResponse>({\n queryKey: ['table-perspectives', perspectiveTableId],\n queryFn: async () => {\n if (!perspectiveTableId) throw new Error('Missing table id')\n const call = await apiCall<PerspectivesIndexResponse>(`/api/perspectives/${encodeURIComponent(perspectiveTableId)}`)\n if (call.status === 404) {\n setPerspectiveApiMissing(true)\n return {\n tableId: perspectiveTableId,\n perspectives: [],\n defaultPerspectiveId: null,\n rolePerspectives: [],\n roles: [],\n canApplyToRoles: false,\n }\n }\n if (!call.ok) {\n await raiseCrudError(call.response, t('ui.dataTable.perspectives.error.load', 'Failed to load perspectives'))\n }\n setPerspectiveApiMissing(false)\n const payload = call.result\n if (!payload) throw new Error(t('ui.dataTable.perspectives.error.load', 'Failed to load perspectives'))\n return payload\n },\n enabled: canUsePerspectives,\n initialData: perspectiveConfig?.initialState?.response,\n staleTime: 5 * 60 * 1000,\n gcTime: 10 * 60 * 1000,\n })\n const perspectiveData = perspectiveQuery.data\n const initialPerspectiveAppliedRef = React.useRef(Boolean(mergedInitialSettings))\n\n const extensionTableId = React.useMemo(() => {\n if (perspective?.tableId) return perspective.tableId\n if (injectionSpotId?.startsWith('data-table:')) return injectionSpotId.slice('data-table:'.length)\n return null\n }, [injectionSpotId, perspective?.tableId])\n const resolvedInjectionSpotId = injectionSpotId ?? (perspective?.tableId ? `data-table:${perspective.tableId}` : null)\n const resolvedReplacementHandle = replacementHandle ?? ComponentReplacementHandles.dataTable(extensionTableId ?? 'unknown')\n const resolvedInjectionContext = React.useMemo(\n () => injectionContext ?? { tableId: perspective?.tableId ?? null, title: typeof title === 'string' ? title : undefined },\n [injectionContext, perspective?.tableId, title]\n )\n const headerInjectionSpotId = React.useMemo(\n () => (resolvedInjectionSpotId ? `${resolvedInjectionSpotId}:header` : null),\n [resolvedInjectionSpotId]\n )\n const toolbarInjectionSpotId = React.useMemo(\n () => (resolvedInjectionSpotId ? `${resolvedInjectionSpotId}:toolbar` : null),\n [resolvedInjectionSpotId]\n )\n const footerInjectionSpotId = React.useMemo(\n () => (resolvedInjectionSpotId ? `${resolvedInjectionSpotId}:footer` : null),\n [resolvedInjectionSpotId]\n )\n const { widgets: columnWidgets } = useInjectionDataWidgets(\n extensionTableId ? `data-table:${extensionTableId}:columns` : '__disabled__:columns',\n )\n const { widgets: rowActionWidgets } = useInjectionDataWidgets(\n extensionTableId ? `data-table:${extensionTableId}:row-actions` : '__disabled__:row-actions',\n )\n const { widgets: bulkActionWidgets } = useInjectionDataWidgets(\n extensionTableId ? `data-table:${extensionTableId}:bulk-actions` : '__disabled__:bulk-actions',\n )\n const { widgets: filterWidgets } = useInjectionDataWidgets(\n extensionTableId ? `data-table:${extensionTableId}:filters` : '__disabled__:filters',\n )\n const injectedColumnDefs = React.useMemo<{ def: ColumnDef<T, unknown>; placement: InjectionColumnDefinition['placement'] }[]>(() => {\n const entries: InjectionColumnDefinition[] = []\n for (const widget of columnWidgets) {\n if (!('columns' in widget)) continue\n for (const definition of widget.columns ?? []) {\n entries.push(definition)\n }\n }\n return collectUniqueById(entries, 'column').map((definition) => ({\n def: {\n id: definition.id,\n accessorFn: (row: T) => readInjectedColumnValue(row, definition.accessorKey),\n header: t(definition.header, definition.header),\n cell: definition.cell as ColumnDef<T, unknown>['cell'],\n size: definition.size,\n enableSorting: definition.sortable === true,\n },\n placement: definition.placement,\n }))\n }, [columnWidgets, t])\n const injectedRowActions = React.useMemo<InjectionRowActionDefinition[]>(() => {\n const entries: InjectionRowActionDefinition[] = []\n for (const widget of rowActionWidgets) {\n if (!('rowActions' in widget)) continue\n for (const definition of widget.rowActions ?? []) {\n entries.push(definition)\n }\n }\n return collectUniqueById(entries, 'row action')\n }, [rowActionWidgets])\n const injectedBulkActions = React.useMemo<InjectionBulkActionDefinition[]>(() => {\n const entries: InjectionBulkActionDefinition[] = []\n for (const widget of bulkActionWidgets) {\n if (!('bulkActions' in widget)) continue\n for (const definition of widget.bulkActions ?? []) {\n entries.push(definition)\n }\n }\n return collectUniqueById(entries, 'bulk action')\n }, [bulkActionWidgets])\n const { serverFilters: injectedFilters, clientFilters: injectedClientFilters } = React.useMemo<{\n serverFilters: FilterDef[]\n clientFilters: { id: string; filterFn: (row: unknown, value: unknown) => boolean }[]\n }>(() => {\n const byId = new Map<string, FilterDef>()\n const clientEntries: { id: string; filterFn: (row: unknown, value: unknown) => boolean }[] = []\n for (const widget of filterWidgets) {\n if (!('filters' in widget)) continue\n for (const definition of widget.filters ?? []) {\n const filter = definition as InjectionFilterDefinition\n const mappedType: FilterDef['type'] =\n filter.type === 'date-range'\n ? 'dateRange'\n : filter.type === 'boolean'\n ? 'checkbox'\n : filter.type === 'select'\n ? 'select'\n : 'text'\n const id = filter.queryParam ?? filter.id\n if (filter.strategy === 'client' && filter.filterFn) {\n clientEntries.push({ id, filterFn: filter.filterFn })\n }\n if (!byId.has(id)) {\n const translatedOptions = Array.isArray(filter.options)\n ? filter.options.map((option) => ({\n ...option,\n label: t(option.label, option.label),\n }))\n : filter.options\n byId.set(id, {\n id,\n label: t(filter.label, filter.label),\n type: mappedType,\n options: translatedOptions,\n })\n }\n }\n }\n return { serverFilters: Array.from(byId.values()), clientFilters: clientEntries }\n }, [filterWidgets, t])\n const mergedColumns = React.useMemo<ColumnDef<T, unknown>[]>(() => {\n if (!injectedColumnDefs.length) return columns\n let result = [...columns]\n for (const { def, placement } of injectedColumnDefs) {\n result = insertByInjectionPlacement(\n result,\n def,\n placement,\n (col) => (col as { id?: string }).id ?? '',\n )\n }\n return result\n }, [columns, injectedColumnDefs])\n const resolvedRowActions = React.useCallback((row: T) => {\n const injectedItems: (RowActionItem & { placement?: InjectionRowActionDefinition['placement'] })[] = injectedRowActions.map((action) => ({\n id: action.id,\n label: t(action.label, action.label),\n onSelect: () => action.onSelect(row, { navigate: (href: string) => router.push(href) }),\n placement: action.placement,\n }))\n const baseNode = rowActions ? rowActions(row) : null\n if (!injectedItems.length) return baseNode\n if (React.isValidElement(baseNode)) {\n const baseItems = (baseNode.props as { items?: RowActionItem[] }).items\n if (Array.isArray(baseItems)) {\n let merged = [...baseItems]\n const existingIds = new Set(\n baseItems.map((item) => item.id).filter((id): id is string => typeof id === 'string' && id.length > 0)\n )\n for (const item of injectedItems) {\n if (item.id && existingIds.has(item.id)) continue\n merged = insertByInjectionPlacement(\n merged,\n item,\n item.placement,\n (entry) => entry.id ?? '',\n )\n }\n return <RowActions items={merged} />\n }\n }\n return <RowActions items={injectedItems} />\n }, [injectedRowActions, rowActions, router, t])\n\n // Date formatting setup\n const DATE_FORMAT = (process.env.NEXT_PUBLIC_DATE_FORMAT || 'YYYY-MM-DD HH:mm') as string\n\n const pad2 = (n: number) => (n < 10 ? `0${n}` : String(n))\n const simpleFormat = (d: Date, fmt: string) => {\n // Supports tokens: YYYY, MM, DD, HH, mm, ss\n const YYYY = String(d.getFullYear())\n const MM = pad2(d.getMonth() + 1)\n const DD = pad2(d.getDate())\n const HH = pad2(d.getHours())\n const mm = pad2(d.getMinutes())\n const ss = pad2(d.getSeconds())\n return fmt\n .replace(/YYYY/g, YYYY)\n .replace(/MM/g, MM)\n .replace(/DD/g, DD)\n .replace(/HH/g, HH)\n .replace(/mm/g, mm)\n .replace(/ss/g, ss)\n }\n\n const tryParseDate = (v: unknown): Date | null => {\n if (v == null) return null\n if (v instanceof Date) return isNaN(v.getTime()) ? null : v\n if (typeof v === 'number') {\n const d = new Date(v)\n return isNaN(d.getTime()) ? null : d\n }\n if (typeof v === 'string') {\n const s = v.trim()\n if (!s) return null\n // ISO-like detection (YYYY-MM-DD ...)\n if (/^\\d{4}-\\d{2}-\\d{2}(?:[ T]\\d{2}:\\d{2}(?::\\d{2})?(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?)?$/.test(s)) {\n const d = new Date(s)\n return isNaN(d.getTime()) ? null : d\n }\n // Fallback: Date.parse\n const d = new Date(s)\n return isNaN(d.getTime()) ? null : d\n }\n return null\n }\n\n // Guess date columns once using first non-empty row\n const [dateColumnIds, setDateColumnIds] = React.useState<Set<string> | null>(null)\n React.useEffect(() => {\n if (dateColumnIds) return\n if (!data || data.length === 0) return\n // Build a cheap row accessor using column defs\n const accessors = mergedColumns.map((c) => {\n const key = (c as any).accessorKey as string | undefined\n const id = (c as any).id as string | undefined\n return { id: id || key || '', key }\n })\n const guessed = new Set<string>()\n accessors.forEach((a) => {\n if (!a.id) return\n const name = a.id\n // Name-based guess: snake_case '_at' suffix\n if (name.endsWith('_at')) {\n guessed.add(name)\n return\n }\n })\n setDateColumnIds(guessed)\n }, [dateColumnIds, data, mergedColumns])\n // Column visibility: only hide columns explicitly marked as hidden.\n // All other columns are always rendered; horizontal scroll (min-w + overflow-auto)\n // handles narrow viewports so users can swipe to reach every column.\n const responsiveClass = (_priority?: number, hidden?: boolean) => {\n if (hidden) return ''\n return ''\n }\n\n const resolvePriority = React.useCallback((column: TableColumn<T, unknown>) => {\n const meta = (column.columnDef as any)?.meta\n const rawPriority = typeof meta?.priority === 'number' ? meta.priority : undefined\n if (rawPriority && rawPriority > 0) return rawPriority\n const index = column.getIndex()\n return index <= 1 ? 1 : 2\n }, [])\n\n const initialSorting = React.useMemo<SortingState>(() => {\n if (mergedInitialSettings?.sorting) {\n return mergedInitialSettings.sorting.map((item) => ({ id: item.id, desc: Boolean(item.desc) }))\n }\n return []\n }, [mergedInitialSettings])\n const [sorting, setSorting] = React.useState<SortingState>(() => {\n if (sortingProp && sortingProp.length) return sortingProp\n if (initialSorting.length) return initialSorting\n return []\n })\n const clientFilteredData = React.useMemo(() => {\n if (!injectedClientFilters.length || !filterValues) return data\n const activeClientFilters = injectedClientFilters.filter(\n (cf) => filterValues[cf.id] !== undefined && filterValues[cf.id] !== '' && filterValues[cf.id] !== null,\n )\n if (!activeClientFilters.length) return data\n return data.filter((row) =>\n activeClientFilters.every((cf) => cf.filterFn(row, filterValues[cf.id])),\n )\n }, [data, injectedClientFilters, filterValues])\n const hasPropBulkActions = Array.isArray(bulkActionsProp) && bulkActionsProp.length > 0\n const hasInjectedBulkActions = injectedBulkActions.length > 0 || hasPropBulkActions\n const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({})\n const table = useReactTable<T>({\n data: clientFilteredData,\n columns: mergedColumns,\n getCoreRowModel: getCoreRowModel(),\n ...(sortable ? { getSortedRowModel: getSortedRowModel() } : {}),\n getRowId: resolveDataTableRowId,\n state: { sorting, columnVisibility, columnOrder, rowSelection },\n enableRowSelection: hasInjectedBulkActions,\n onSortingChange: (updater) => {\n const next = typeof updater === 'function' ? updater(sorting) : updater\n setSorting(next)\n onSortingChange?.(next)\n },\n onColumnVisibilityChange: (updater) => {\n const next = typeof updater === 'function' ? updater(columnVisibility) : updater\n setColumnVisibility(next)\n },\n onColumnOrderChange: (updater) => {\n const next = typeof updater === 'function' ? updater(columnOrder) : updater\n setColumnOrder(next)\n },\n onRowSelectionChange: setRowSelection,\n })\n React.useEffect(() => { if (sortingProp) setSorting(sortingProp) }, [sortingProp])\n React.useEffect(() => {\n if (hasInjectedBulkActions) return\n if (Object.keys(rowSelection).length === 0) return\n setRowSelection({})\n }, [hasInjectedBulkActions, rowSelection])\n React.useEffect(() => {\n const ids = table.getAllLeafColumns().map((column) => column.id)\n if (!ids.length) return\n setColumnOrder((prev) => {\n if (!prev.length) return ids\n const allowed = ids\n const filtered = prev.filter((id) => allowed.includes(id))\n const seen = new Set(filtered)\n for (const id of allowed) {\n if (!seen.has(id)) {\n filtered.push(id)\n seen.add(id)\n }\n }\n const changed = filtered.length !== prev.length || filtered.some((id, index) => id !== prev[index])\n return changed ? filtered : prev\n })\n }, [table, mergedColumns])\n\n const initialVisibilityApplied = React.useRef(Boolean(mergedInitialSettings?.columnVisibility))\n React.useEffect(() => {\n if (initialVisibilityApplied.current) return\n const hidden: VisibilityState = {}\n table.getAllLeafColumns().forEach((column) => {\n const hiddenMeta = (column.columnDef as any)?.meta?.hidden\n if (hiddenMeta) hidden[column.id] = false\n })\n if (Object.keys(hidden).length) {\n setColumnVisibility((prev) => ({ ...hidden, ...prev }))\n }\n initialVisibilityApplied.current = true\n }, [table, mergedColumns])\n\n const getCurrentSettings = React.useCallback((): PerspectiveSettings => {\n const visibility: Record<string, boolean> = {}\n for (const [key, value] of Object.entries(columnVisibility)) {\n if (typeof key === 'string' && typeof value === 'boolean') {\n visibility[key] = value\n }\n }\n const filtersRecord: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(filterValues ?? {})) {\n if (typeof key === 'string') filtersRecord[key] = value\n }\n const candidate: PerspectiveSettings = {\n columnOrder,\n columnVisibility: visibility,\n sorting,\n filters: filtersRecord,\n searchValue,\n }\n return sanitizePerspectiveSettings(candidate) ?? {}\n }, [columnOrder, columnVisibility, sorting, filterValues, searchValue])\n\n const applyPerspectiveSettings = React.useCallback((settings: PerspectiveSettings, nextId: string | null) => {\n const normalized = sanitizePerspectiveSettings(settings) ?? {}\n if (normalized.columnOrder && normalized.columnOrder.length) {\n setColumnOrder(normalized.columnOrder)\n } else {\n const ids = table.getAllLeafColumns().map((column) => column.id)\n if (ids.length) setColumnOrder(ids)\n }\n if (normalized.columnVisibility) setColumnVisibility(normalized.columnVisibility)\n else setColumnVisibility({})\n if (normalized.sorting) {\n const sortingState: SortingState = normalized.sorting.map((item) => ({\n id: item.id,\n desc: item.desc === true,\n }))\n setSorting(sortingState)\n onSortingChange?.(sortingState)\n } else {\n setSorting([])\n onSortingChange?.([])\n }\n if (onFiltersApply) {\n onFiltersApply((normalized.filters ?? {}) as FilterValues)\n }\n if (onSearchChange) {\n onSearchChange(normalized.searchValue ?? '')\n }\n setActivePerspectiveId(nextId)\n if (perspectiveTableId) {\n writePerspectiveCookie(perspectiveTableId, nextId)\n if (nextId) {\n const snapshot: PerspectiveSnapshot = { perspectiveId: nextId, settings: normalized, updatedAt: Date.now() }\n writePerspectiveSnapshot(perspectiveTableId, snapshot)\n initialSnapshotRef.current = snapshot\n } else {\n writePerspectiveSnapshot(perspectiveTableId, null)\n initialSnapshotRef.current = null\n }\n }\n }, [onFiltersApply, onSearchChange, onSortingChange, perspectiveTableId, table])\n\n React.useLayoutEffect(() => {\n if (!perspectiveTableId) return\n if (snapshotHydratedTableRef.current === perspectiveTableId) return\n snapshotHydratedTableRef.current = perspectiveTableId\n const snapshot = readPerspectiveSnapshot(perspectiveTableId)\n if (!snapshot) return\n initialSnapshotRef.current = snapshot\n applyPerspectiveSettings(snapshot.settings, snapshot.perspectiveId ?? null)\n initialPerspectiveAppliedRef.current = true\n }, [perspectiveTableId, applyPerspectiveSettings])\n\n type SavePerspectivePayload = {\n name: string\n isDefault: boolean\n applyToRoles: string[]\n setRoleDefault: boolean\n perspectiveId?: string | null\n settings?: PerspectiveSettings\n }\n\n const perspectiveQueryKey: [string, string | null] = ['table-perspectives', perspectiveTableId]\n const savePerspectiveMutation = useMutation<PerspectiveSaveResponse, Error, SavePerspectivePayload>({\n mutationFn: async (input) => {\n if (!perspectiveTableId) throw new Error('Missing table id')\n const payload = {\n perspectiveId: input.perspectiveId ?? undefined,\n name: input.name,\n settings: input.settings ?? getCurrentSettings(),\n isDefault: input.isDefault,\n applyToRoles: input.applyToRoles,\n setRoleDefault: input.setRoleDefault,\n }\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.debug('[DataTable] perspective payload', payload)\n }\n const call = await apiCall<PerspectiveSaveResponse>(\n `/api/perspectives/${encodeURIComponent(perspectiveTableId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n )\n if (call.status === 404) {\n throw new Error(t('ui.dataTable.perspectives.error.apiUnavailable', 'Perspectives API is not available. Run `yarn generate` to regenerate module routes and restart the dev server.'))\n }\n if (!call.ok) {\n await raiseCrudError(call.response, t('ui.dataTable.perspectives.error.save', 'Failed to save perspective'))\n }\n const result = call.result\n if (!result) throw new Error(t('ui.dataTable.perspectives.error.save', 'Failed to save perspective'))\n return result\n },\n onSuccess: (data) => {\n if (perspectiveTableId) {\n void queryClient.invalidateQueries({ queryKey: perspectiveQueryKey })\n }\n if (data.perspective) {\n applyPerspectiveSettings(data.perspective.settings, data.perspective.id)\n }\n },\n })\n\n const resolveColumnLabel = React.useCallback((column: TableColumn<T, unknown>): string => {\n const meta = (column.columnDef as any)?.meta\n if (typeof meta?.label === 'string' && meta.label.trim().length > 0) return meta.label.trim()\n if (typeof meta?.title === 'string' && meta.title.trim().length > 0) return meta.title.trim()\n const header = column.columnDef.header\n if (typeof header === 'string') return header\n if (typeof header === 'function') return normalizeLabel(column.id)\n return normalizeLabel(column.id)\n }, [])\n\n const activePersonalPerspectiveId = React.useMemo(() => {\n if (!perspectiveData || !activePerspectiveId) return null\n const found = perspectiveData.perspectives.find((p) => p.id === activePerspectiveId)\n return found ? found.id : null\n }, [perspectiveData, activePerspectiveId])\n\n\n const deletePerspectiveMutation = useMutation<void, Error, { perspectiveId: string }>({\n mutationFn: async ({ perspectiveId }) => {\n if (!perspectiveTableId) throw new Error('Missing table id')\n const call = await apiCall(\n `/api/perspectives/${encodeURIComponent(perspectiveTableId)}/${encodeURIComponent(perspectiveId)}`,\n { method: 'DELETE' },\n )\n if (call.status === 404) throw new Error(t('ui.dataTable.perspectives.error.apiUnavailable', 'Perspectives API is not available. Run `yarn generate` and restart the dev server.'))\n if (!call.ok) {\n await raiseCrudError(call.response, t('ui.dataTable.perspectives.error.delete', 'Failed to delete perspective'))\n }\n },\n onMutate: ({ perspectiveId }) => {\n setDeletingIds((prev) => prev.includes(perspectiveId) ? prev : [...prev, perspectiveId])\n },\n onSettled: (_data, _error, variables) => {\n setDeletingIds((prev) => prev.filter((id) => id !== variables.perspectiveId))\n },\n onSuccess: (_data, variables) => {\n const removedActive = activePerspectiveId === variables.perspectiveId\n if (perspectiveTableId) {\n void queryClient.invalidateQueries({ queryKey: perspectiveQueryKey })\n if (removedActive) {\n setActivePerspectiveId(null)\n writePerspectiveCookie(perspectiveTableId, null)\n writePerspectiveSnapshot(perspectiveTableId, null)\n initialSnapshotRef.current = null\n initialPerspectiveAppliedRef.current = false\n }\n } else if (removedActive) {\n setActivePerspectiveId(null)\n initialPerspectiveAppliedRef.current = false\n }\n },\n })\n\n const clearRoleMutation = useMutation<void, Error, { roleId: string }>({\n mutationFn: async ({ roleId }) => {\n if (!perspectiveTableId) throw new Error('Missing table id')\n const call = await apiCall(\n `/api/perspectives/${encodeURIComponent(perspectiveTableId)}/roles/${encodeURIComponent(roleId)}`,\n { method: 'DELETE' },\n )\n if (call.status === 404) throw new Error(t('ui.dataTable.perspectives.error.apiUnavailable', 'Perspectives API is not available. Run `yarn generate` and restart the dev server.'))\n if (!call.ok) {\n await raiseCrudError(call.response, t('ui.dataTable.perspectives.error.clearRoles', 'Failed to clear role perspectives'))\n }\n },\n onMutate: ({ roleId }) => {\n setRoleClearingIds((prev) => prev.includes(roleId) ? prev : [...prev, roleId])\n },\n onSettled: (_data, _error, variables) => {\n setRoleClearingIds((prev) => prev.filter((id) => id !== variables.roleId))\n },\n onSuccess: (_data, variables) => {\n if (perspectiveTableId) {\n void queryClient.invalidateQueries({ queryKey: perspectiveQueryKey })\n }\n if (activePerspectiveId) {\n const current = queryClient.getQueryData<PerspectivesIndexResponse>(perspectiveQueryKey)\n const match = current?.rolePerspectives.find((rp) => rp.id === activePerspectiveId)\n if (match && match.roleId === variables.roleId) {\n setActivePerspectiveId(null)\n if (perspectiveTableId) writePerspectiveCookie(perspectiveTableId, null)\n if (perspectiveTableId) writePerspectiveSnapshot(perspectiveTableId, null)\n initialSnapshotRef.current = null\n initialPerspectiveAppliedRef.current = false\n }\n }\n },\n })\n\n const handlePerspectiveActivate = React.useCallback((item: PerspectiveDto | RolePerspectiveDto, _source?: 'personal' | 'role') => {\n applyPerspectiveSettings(item.settings, item.id)\n }, [applyPerspectiveSettings])\n\n const handlePerspectiveSave = React.useCallback(async (input: { name: string; isDefault: boolean; applyToRoles: string[]; setRoleDefault: boolean; perspectiveId?: string | null; settings?: PerspectiveSettings }) => {\n const normalizedRoles = Array.from(new Set(input.applyToRoles))\n await savePerspectiveMutation.mutateAsync({\n name: input.name.trim(),\n isDefault: input.isDefault,\n applyToRoles: normalizedRoles,\n setRoleDefault: normalizedRoles.length > 0 ? input.setRoleDefault : false,\n perspectiveId: input.perspectiveId !== undefined ? input.perspectiveId : activePersonalPerspectiveId,\n settings: input.settings,\n })\n }, [savePerspectiveMutation, activePersonalPerspectiveId])\n\n const handlePerspectiveDelete = React.useCallback(async (perspectiveId: string) => {\n await deletePerspectiveMutation.mutateAsync({ perspectiveId })\n }, [deletePerspectiveMutation])\n\n const handleClearRole = React.useCallback(async (roleId: string) => {\n await clearRoleMutation.mutateAsync({ roleId })\n }, [clearRoleMutation])\n\n const handleColumnChooserToggle = React.useCallback((key: string) => {\n const column = table.getColumn(key)\n if (!column) return\n const nextVisible = !column.getIsVisible()\n if (nextVisible) {\n setColumnOrder((prev) => (prev.includes(key) ? prev : [...prev, key]))\n }\n setColumnVisibility((prev) => {\n const next = { ...prev }\n if (nextVisible) delete next[key]\n else next[key] = false\n return next\n })\n column.toggleVisibility(nextVisible)\n }, [table])\n\n const handleColumnChooserReorder = React.useCallback((newOrder: string[]) => {\n setColumnOrder(newOrder)\n table.setColumnOrder(newOrder)\n }, [table])\n\n const dndSensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 5 } }))\n const enableHeaderDnd = Boolean(columnChooser)\n const stableDndContextId = React.useMemo(\n () => sanitizeDndContextId(\n extensionTableId\n ?? perspectiveTableId\n ?? resolvedReplacementHandle\n ?? (typeof title === 'string' && title.trim().length > 0 ? title : 'data-table'),\n ),\n [extensionTableId, perspectiveTableId, resolvedReplacementHandle, title],\n )\n const headerColumnIds = React.useMemo(() => {\n if (!enableHeaderDnd) return []\n return table.getHeaderGroups().flatMap((hg) => hg.headers.map((h) => h.id))\n }, [enableHeaderDnd, table, columnOrder])\n\n const handleHeaderDragEnd = React.useCallback((event: DragEndEvent) => {\n const { active, over } = event\n if (!over || active.id === over.id) return\n const currentIds = columnOrder.length ? columnOrder : table.getAllLeafColumns().map((c) => c.id)\n const oldIdx = currentIds.indexOf(String(active.id))\n const newIdx = currentIds.indexOf(String(over.id))\n if (oldIdx === -1 || newIdx === -1) return\n const next = [...currentIds]\n const [moved] = next.splice(oldIdx, 1)\n next.splice(newIdx, 0, moved)\n setColumnOrder(next)\n table.setColumnOrder(next)\n }, [columnOrder, table])\n\n const perspectiveApiWarning = perspectiveApiMissing && canUsePerspectives\n ? t('ui.dataTable.perspectives.warning.apiUnavailable', 'Perspectives API is not available yet. Run `yarn generate` to regenerate module routes, then restart the server.')\n : null\n\n const loadStartRef = React.useRef<number | null>(null)\n const [measuredDurationMs, setMeasuredDurationMs] = React.useState<number | null>(null)\n\n React.useEffect(() => {\n if (typeof isLoading !== 'boolean') return\n if (isLoading) {\n if (loadStartRef.current === null) {\n const now = typeof performance !== 'undefined' && typeof performance.now === 'function'\n ? performance.now()\n : Date.now()\n loadStartRef.current = now\n }\n return\n }\n if (loadStartRef.current !== null) {\n const now = typeof performance !== 'undefined' && typeof performance.now === 'function'\n ? performance.now()\n : Date.now()\n setMeasuredDurationMs(now - loadStartRef.current)\n loadStartRef.current = null\n }\n }, [isLoading])\n\n React.useLayoutEffect(() => {\n if (!canUsePerspectives) return\n if (!perspectiveTableId) return\n if (initialSnapshotRef.current) return\n if (initialPerspectiveAppliedRef.current && activePerspectiveId != null) return\n\n const source = perspectiveData ?? perspectiveConfig?.initialState?.response\n if (!source) return\n\n const tryResolve = (id: string | null | undefined): PerspectiveDto | RolePerspectiveDto | undefined => {\n if (!id) return undefined\n return source.perspectives.find((p) => p.id === id)\n ?? source.rolePerspectives.find((p) => p.id === id)\n }\n\n let target: PerspectiveDto | RolePerspectiveDto | undefined\n if (activePerspectiveId) {\n target = tryResolve(activePerspectiveId)\n }\n const cookieId = readPerspectiveCookie(perspectiveTableId)\n if (!target && cookieId) target = tryResolve(cookieId)\n if (!target && source.defaultPerspectiveId) {\n target = tryResolve(source.defaultPerspectiveId)\n }\n if (!target) {\n target = source.rolePerspectives.find((p) => p.isDefault)\n }\n if (!target) {\n target = source.perspectives[0]\n }\n if (target) {\n applyPerspectiveSettings(target.settings, target.id)\n }\n initialPerspectiveAppliedRef.current = true\n }, [canUsePerspectives, perspectiveData, perspectiveTableId, perspectiveConfig, applyPerspectiveSettings, activePerspectiveId])\n\n const scrollTableIntoView = React.useCallback(() => {\n const rect = containerRef.current?.getBoundingClientRect()\n if (!rect || rect.top >= 0) return\n const behavior = window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'instant' : 'smooth'\n containerRef.current?.scrollIntoView({ behavior, block: 'start' })\n }, [])\n\n const paginationNode = React.useMemo(() => {\n if (!pagination || pagination.total === 0) return null\n\n const { page, totalPages, onPageChange, durationMs, cacheStatus } = pagination\n const startItem = (page - 1) * pagination.pageSize + 1\n const endItem = Math.min(page * pagination.pageSize, pagination.total)\n const effectiveDuration = (typeof durationMs === 'number' && Number.isFinite(durationMs) && durationMs >= 0)\n ? durationMs\n : measuredDurationMs ?? undefined\n const durationLabel = formatDurationLabel(effectiveDuration)\n const normalizedCacheStatus = cacheStatus === 'hit' || cacheStatus === 'miss' ? cacheStatus : null\n const cacheBadge = normalizedCacheStatus ? (\n <span\n className=\"inline-flex items-center justify-center\"\n aria-label={t('ui.dataTable.pagination.cache.ariaLabel', 'Cache {status}', { status: normalizedCacheStatus.toUpperCase() })}\n title={t('ui.dataTable.pagination.cache.title', 'Cache {status}', { status: normalizedCacheStatus.toUpperCase() })}\n >\n <Circle\n className={`h-3.5 w-3.5 ${normalizedCacheStatus === 'hit' ? 'text-emerald-500' : 'text-amber-500'}`}\n strokeWidth={3}\n />\n <span className=\"sr-only\">{t('ui.dataTable.pagination.cache.srOnly', 'Cache {status}', { status: normalizedCacheStatus.toUpperCase() })}</span>\n </span>\n ) : null\n\n const pageSizeOptions = Array.isArray(pagination.pageSizeOptions)\n ? Array.from(new Set(\n [pagination.pageSize, ...pagination.pageSizeOptions]\n .filter((size): size is number => typeof size === 'number' && Number.isFinite(size) && size > 0)\n .map((size) => Math.max(1, Math.floor(size))),\n )).sort((left, right) => left - right)\n : []\n const pageSizeSelect = pageSizeOptions.length > 0 && pagination.onPageSizeChange ? (\n <span className=\"inline-flex items-center gap-1.5\">\n <select\n className=\"rounded border bg-background pl-2 pr-7 py-0.5 text-sm min-w-[3.5rem]\"\n value={pagination.pageSize}\n onChange={(event) => {\n pagination.onPageSizeChange!(Number(event.target.value))\n scrollTableIntoView()\n }}\n aria-label={t('ui.dataTable.pagination.rowsPerPage', 'Rows per page')}\n >\n {pageSizeOptions.map((size) => (\n <option key={size} value={size}>{size}</option>\n ))}\n </select>\n <span className=\"text-muted-foreground\">{t('ui.dataTable.pagination.perPage', 'per page')}</span>\n </span>\n ) : null\n\n return (\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 px-4 py-3 border-t\">\n <div className=\"text-sm text-muted-foreground flex items-center justify-center sm:justify-start gap-2 flex-wrap\">\n <span>\n {durationLabel\n ? t('ui.dataTable.pagination.resultsWithDuration', 'Showing {start} to {end} of {total} results in {duration}', { start: startItem, end: endItem, total: pagination.total, duration: durationLabel })\n : t('ui.dataTable.pagination.results', 'Showing {start} to {end} of {total} results', { start: startItem, end: endItem, total: pagination.total })\n }\n </span>\n {cacheBadge}\n {pageSizeSelect}\n </div>\n <div className=\"flex items-center justify-center sm:justify-end gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => { onPageChange(page - 1); scrollTableIntoView() }}\n disabled={page <= 1}\n >\n {t('ui.dataTable.pagination.previous', 'Previous')}\n </Button>\n <span className=\"text-sm whitespace-nowrap\">\n {t('ui.dataTable.pagination.pageInfo', 'Page {page} of {totalPages}', { page, totalPages })}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => { onPageChange(page + 1); scrollTableIntoView() }}\n disabled={page >= totalPages}\n >\n {t('ui.dataTable.pagination.next', 'Next')}\n </Button>\n </div>\n </div>\n )\n }, [pagination, measuredDurationMs, scrollTableIntoView, t])\n\n // Auto filters: fetch custom field defs when requested\n const resolvedEntityIds = React.useMemo(() => {\n if (Array.isArray(entityIds) && entityIds.length) {\n const dedup = new Set<string>()\n const list: string[] = []\n entityIds.forEach((id) => {\n const trimmed = typeof id === 'string' ? id.trim() : ''\n if (!trimmed || dedup.has(trimmed)) return\n dedup.add(trimmed)\n list.push(trimmed)\n })\n return list\n }\n if (typeof entityId === 'string' && entityId.trim().length > 0) {\n return [entityId.trim()]\n }\n return []\n }, [entityId, entityIds])\n const entityKey = React.useMemo(() => (resolvedEntityIds.length ? resolvedEntityIds.join('|') : null), [resolvedEntityIds])\n const customFieldFilterExtrasSignature = React.useMemo(\n () => JSON.stringify(customFieldFilterKeyExtras ?? []),\n [customFieldFilterKeyExtras]\n )\n\n const [cfFilterFieldsetsByEntity, setCfFilterFieldsetsByEntity] = React.useState<Record<string, CustomFieldsetDto[]>>({})\n const [cfFilterFieldsetSelection, setCfFilterFieldsetSelection] = React.useState<Record<string, string | null>>({})\n\n React.useEffect(() => {\n if (!entityKey) {\n setCfFilterFieldsetsByEntity({})\n setCfFilterFieldsetSelection({})\n return\n }\n let cancelled = false\n const loadFieldsets = async () => {\n try {\n const payload = await fetchCustomFieldDefinitionsPayload(resolvedEntityIds)\n if (cancelled) return\n const fieldsets = payload.fieldsetsByEntity ?? {}\n setCfFilterFieldsetsByEntity(fieldsets)\n const selectionChanges: Array<[string, string | null]> = []\n let shouldNotify = false\n setCfFilterFieldsetSelection((prev) => {\n const next: Record<string, string | null> = {}\n let changed = false\n resolvedEntityIds.forEach((entityId) => {\n const list = fieldsets[entityId] ?? []\n if (!list.length) {\n if (prev[entityId] !== undefined) changed = true\n return\n }\n const existing = prev[entityId]\n const fallback = list[0]?.code ?? null\n const isValidExisting = existing ? list.some((entry) => entry.code === existing) : false\n const value = isValidExisting ? existing : fallback ?? null\n next[entityId] = value\n if (value !== existing) {\n changed = true\n selectionChanges.push([entityId, value])\n }\n })\n if (Object.keys(prev).length !== Object.keys(next).length) changed = true\n if (changed) {\n shouldNotify = true\n return next\n }\n return prev\n })\n if (shouldNotify && selectionChanges.length && onCustomFieldFilterFieldsetChange) {\n selectionChanges.forEach(([entityId, value]) => onCustomFieldFilterFieldsetChange(value, entityId))\n }\n } catch {\n if (!cancelled) {\n setCfFilterFieldsetsByEntity({})\n setCfFilterFieldsetSelection({})\n }\n }\n }\n loadFieldsets()\n return () => {\n cancelled = true\n }\n }, [customFieldFilterExtrasSignature, entityKey, onCustomFieldFilterFieldsetChange, resolvedEntityIds])\n\n const supportsCustomFieldFilterFieldsets =\n resolvedEntityIds.length === 1 &&\n (cfFilterFieldsetsByEntity[resolvedEntityIds[0]]?.length ?? 0) > 0\n const activeCustomFieldFilterFieldset = supportsCustomFieldFilterFieldsets\n ? cfFilterFieldsetSelection[resolvedEntityIds[0]] ?? cfFilterFieldsetsByEntity[resolvedEntityIds[0]]?.[0]?.code ?? null\n : null\n\n const handleCustomFieldFilterFieldsetChange = React.useCallback(\n (value: string) => {\n if (!supportsCustomFieldFilterFieldsets) return\n const entityId = resolvedEntityIds[0]\n const nextValue = value || null\n setCfFilterFieldsetSelection((prev) => {\n if (prev[entityId] === nextValue) return prev\n return { ...prev, [entityId]: nextValue }\n })\n if (onCustomFieldFilterFieldsetChange) {\n onCustomFieldFilterFieldsetChange(nextValue, entityId)\n }\n },\n [onCustomFieldFilterFieldsetChange, resolvedEntityIds, supportsCustomFieldFilterFieldsets],\n )\n\n const { data: cfFilters = [] } = useCustomFieldFilterDefs(entityKey ? resolvedEntityIds : [], {\n enabled: !!entityKey,\n fieldset: supportsCustomFieldFilterFieldsets ? activeCustomFieldFilterFieldset ?? undefined : undefined,\n keyExtras: customFieldFilterKeyExtras,\n })\n\n const isAutoAdvancedFilter = Boolean(advancedFilter?.auto)\n const isAutoColumnChooser = Boolean(columnChooser?.auto)\n const needsAutoDiscovery = isAutoAdvancedFilter || isAutoColumnChooser\n const { data: autoDiscoveryDefs = [] } = useCustomFieldDefs(\n needsAutoDiscovery && entityKey ? resolvedEntityIds : [],\n { enabled: needsAutoDiscovery && !!entityKey },\n )\n const autoDiscovered = useAutoDiscoveredFields({\n columns: needsAutoDiscovery ? mergedColumns : [],\n customFieldDefs: needsAutoDiscovery ? autoDiscoveryDefs : [],\n })\n const resolvedAdvancedFilterFields = isAutoAdvancedFilter\n ? autoDiscovered.advancedFilterFields\n : advancedFilter?.fields ?? []\n const resolvedColumnChooserFields = isAutoColumnChooser\n ? autoDiscovered.columnChooserFields\n : columnChooser?.availableColumns ?? []\n\n const effectiveColumnChooserFields = React.useMemo<ColumnChooserField[]>(() => {\n if (resolvedColumnChooserFields.length > 0) return resolvedColumnChooserFields\n return table.getAllLeafColumns().map((col) => ({\n key: col.id,\n label: resolveColumnLabel(col),\n group: 'Columns',\n alwaysVisible: !col.getCanHide(),\n }))\n }, [resolvedColumnChooserFields, table, resolveColumnLabel, columns])\n\n const visibleColumnKeys = React.useMemo(\n () => table.getAllLeafColumns().filter((c) => c.getIsVisible()).map((c) => c.id),\n [table, columnVisibility, columns],\n )\n\n const selectedRows = React.useMemo<T[]>(() => {\n if (!hasInjectedBulkActions) return []\n return table.getSelectedRowModel().rows.map((row) => row.original as T)\n }, [hasInjectedBulkActions, table, rowSelection])\n const trackedBulkProgressJobIdsRef = React.useRef(new Set<string>())\n\n const clearTrackedBulkProgressJob = React.useCallback((jobId: string | null): boolean => {\n if (!jobId) return false\n return trackedBulkProgressJobIdsRef.current.delete(jobId)\n }, [])\n\n const refreshAfterBulkProgressCompletion = React.useCallback(() => {\n if (refreshButton?.onRefresh) {\n refreshButton.onRefresh()\n return\n }\n scheduleRouterRefresh(router)\n }, [refreshButton, router])\n\n useAppEvent(\n 'progress.job.completed',\n (event) => {\n const payload = event.payload as { jobId?: unknown } | null | undefined\n const jobId = typeof payload?.jobId === 'string' ? payload.jobId : null\n if (!clearTrackedBulkProgressJob(jobId)) return\n refreshAfterBulkProgressCompletion()\n },\n [clearTrackedBulkProgressJob, refreshAfterBulkProgressCompletion],\n )\n\n useAppEvent(\n 'progress.job.failed',\n (event) => {\n const payload = event.payload as { jobId?: unknown } | null | undefined\n const jobId = typeof payload?.jobId === 'string' ? payload.jobId : null\n clearTrackedBulkProgressJob(jobId)\n },\n [clearTrackedBulkProgressJob],\n )\n\n useAppEvent(\n 'progress.job.cancelled',\n (event) => {\n const payload = event.payload as { jobId?: unknown } | null | undefined\n const jobId = typeof payload?.jobId === 'string' ? payload.jobId : null\n clearTrackedBulkProgressJob(jobId)\n },\n [clearTrackedBulkProgressJob],\n )\n\n const runBulkAction = React.useCallback(\n async (action: InjectionBulkActionDefinition) => {\n if (action.requiresSelection !== false && !selectedRows.length) return\n try {\n const result = await action.onExecute(selectedRows, {\n tableId: extensionTableId,\n navigate: (href: string) => router.push(href),\n confirm,\n refresh: refreshButton?.onRefresh,\n injectionContext: resolvedInjectionContext,\n translate: t,\n })\n const normalized = result as BulkActionExecuteResult | void\n if (normalized && normalized.ok === false) {\n if (normalized.message === undefined) return\n flash(\n normalized.message\n ?? t('ui.dataTable.bulkAction.error', 'Bulk action failed.'),\n 'error',\n )\n return\n }\n if (normalized?.progressJobId) {\n trackedBulkProgressJobIdsRef.current.add(normalized.progressJobId)\n setRowSelection({})\n flash(\n normalized.message\n ?? t('ui.dataTable.bulkAction.started', 'Bulk action started. Track progress in the top bar.'),\n 'success',\n )\n return\n }\n flash(\n normalized?.message\n ?? t('ui.dataTable.bulkAction.success', 'Bulk action completed.'),\n 'success',\n )\n setRowSelection({})\n if (refreshButton?.onRefresh) {\n refreshButton.onRefresh()\n } else {\n scheduleRouterRefresh(router)\n }\n } catch (error) {\n flash(\n error instanceof Error\n ? error.message\n : t('ui.dataTable.bulkAction.error', 'Bulk action failed.'),\n 'error',\n )\n }\n },\n [confirm, extensionTableId, refreshButton, resolvedInjectionContext, router, selectedRows, t],\n )\n\n const runPropBulkAction = React.useCallback(\n async (action: BulkAction<T>) => {\n const result = await action.onExecute(selectedRows)\n if (result !== false) {\n setRowSelection({})\n }\n },\n [selectedRows],\n )\n\n const builtToolbar = React.useMemo(() => {\n if (toolbar) return toolbar\n const anySearch = onSearchChange != null\n const anyFilters = (baseFilters && baseFilters.length > 0) || (cfFilters && cfFilters.length > 0) || injectedFilters.length > 0\n const hasBulkButtons = hasInjectedBulkActions || hasPropBulkActions\n if (!anySearch && !anyFilters && !hasBulkButtons) return null\n // Merge base filters with CF filters, preferring base definitions when ids collide\n const baseList = baseFilters || []\n const existing = new Set(baseList.map((f) => f.id))\n const cfOnly = (cfFilters || []).filter((f) => !existing.has(f.id))\n const injectedOnly = injectedFilters.filter((f) => !existing.has(f.id) && !cfOnly.some((cf) => cf.id === f.id))\n const combined: FilterDef[] = [...baseList, ...cfOnly, ...injectedOnly]\n const perspectiveButton = canUsePerspectives ? (\n <ViewSwitcherDropdown\n activePerspectiveId={activePerspectiveId}\n perspectives={perspectiveData?.perspectives ?? []}\n rolePerspectives={perspectiveData?.rolePerspectives ?? []}\n onClear={() => applyPerspectiveSettings({}, null)}\n onActivate={handlePerspectiveActivate}\n onOpenSidebar={() => setPerspectiveOpen(true)}\n t={t}\n />\n ) : null\n const fieldsetSelector =\n supportsCustomFieldFilterFieldsets && resolvedEntityIds.length === 1\n ? (\n <div className=\"space-y-1\">\n <div className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {t('ui.dataTable.fieldset.label', 'Fieldset')}\n </div>\n <select\n className=\"w-full rounded border bg-background px-2 py-2 text-sm\"\n value={activeCustomFieldFilterFieldset ?? ''}\n onChange={(event) => handleCustomFieldFilterFieldsetChange(event.target.value)}\n >\n {(cfFilterFieldsetsByEntity[resolvedEntityIds[0]] ?? []).map((fieldset) => (\n <option key={fieldset.code} value={fieldset.code}>\n {fieldset.label}\n </option>\n ))}\n </select>\n </div>\n )\n : null\n const leadingItems = perspectiveButton ? <div className=\"flex items-center gap-2\">{perspectiveButton}</div> : null\n const trailingItems = hasBulkButtons ? (\n <div className=\"flex flex-wrap items-center gap-2\">\n {selectedRows.length > 0 ? (\n <span className=\"text-sm text-muted-foreground\">\n {t('ui.dataTable.bulkAction.selectedCount', '{count} selected', { count: selectedRows.length })}\n </span>\n ) : null}\n {injectedBulkActions.map((action) => {\n const label = t(action.label, action.label)\n const iconNode = resolveInjectedIcon(action.icon, 'h-4 w-4 shrink-0')\n return (\n <Button\n key={action.id}\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n title={label}\n aria-label={label}\n className={iconNode ? 'px-2 sm:px-3' : undefined}\n disabled={action.requiresSelection !== false && selectedRows.length === 0}\n onClick={() => void runBulkAction(action)}\n >\n {iconNode}\n <span className={iconNode ? 'hidden sm:inline' : undefined}>{label}</span>\n </Button>\n )\n })}\n {selectedRows.length > 0 ? (bulkActionsProp ?? []).map((action) => {\n const ActionIcon = action.icon\n return (\n <Button\n key={action.id}\n type=\"button\"\n size=\"sm\"\n variant={action.destructive ? 'destructive' : 'outline'}\n onClick={() => void runPropBulkAction(action)}\n >\n {ActionIcon ? <ActionIcon className=\"h-4 w-4 shrink-0\" /> : null}\n <span>{action.label}</span>\n </Button>\n )\n }) : null}\n </div>\n ) : null\n return (\n <FilterBar\n searchValue={searchValue}\n onSearchChange={onSearchChange}\n searchPlaceholder={searchPlaceholder}\n searchAlign={searchAlign}\n filters={combined}\n values={filterValues}\n onApply={onFiltersApply}\n onClear={onFiltersClear}\n leadingItems={leadingItems}\n trailingItems={trailingItems}\n filtersExtraContent={fieldsetSelector}\n layout={embedded ? 'inline' : 'stacked'}\n className={embedded ? 'min-h-[2.25rem]' : undefined}\n />\n )\n }, [\n toolbar,\n searchValue,\n onSearchChange,\n searchPlaceholder,\n searchAlign,\n baseFilters,\n cfFilters,\n injectedFilters,\n filterValues,\n onFiltersApply,\n onFiltersClear,\n canUsePerspectives,\n embedded,\n supportsCustomFieldFilterFieldsets,\n resolvedEntityIds,\n activeCustomFieldFilterFieldset,\n handleCustomFieldFilterFieldsetChange,\n cfFilterFieldsetsByEntity,\n hasInjectedBulkActions,\n hasPropBulkActions,\n injectedBulkActions,\n bulkActionsProp,\n selectedRows.length,\n selectedRows,\n runBulkAction,\n runPropBulkAction,\n ])\n\n const hasTitle = title != null\n const hasActions = actions !== undefined && actions !== null && actions !== false\n const shouldReserveActionsSpace = actions === null || actions === false\n const exportConfig = exporter === false ? null : exporter || null\n const resolvedExportSections = React.useMemo(() => resolveExportSections(exportConfig), [exportConfig])\n const hasExport = resolvedExportSections.length > 0\n const refreshButtonConfig = refreshButton\n const hasRefreshButton = Boolean(refreshButtonConfig)\n const hasToolbar = builtToolbar != null\n const hasToolbarInjection = Boolean(toolbarInjectionSpotId)\n const shouldRenderActionsWrapper = hasActions || hasRefreshButton || shouldReserveActionsSpace || hasExport || hasToolbarInjection || Boolean(advancedFilter)\n const renderToolbarInline = embedded && hasToolbar\n const shouldRenderToolbarBelow = hasToolbar && !renderToolbarInline\n const shouldRenderHeader = hasTitle || renderToolbarInline || shouldRenderActionsWrapper || shouldRenderToolbarBelow\n const containerClassName = embedded ? '' : 'rounded-lg border bg-card mx-1 sm:mx-2'\n const headerWrapperClassName = embedded ? 'pb-3' : 'px-4 py-3 border-b'\n const headerContentClassName = 'flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between'\n const toolbarWrapperClassName = embedded ? 'mt-2' : 'mt-3 pt-3 border-t'\n const tableScrollWrapperClassName = embedded ? '' : 'overflow-auto'\n\n const virtualScrollRef = React.useRef<HTMLDivElement>(null)\n const allRows = table.getRowModel().rows\n const rowVirtualizer = virtualized\n ? useVirtualizer({\n count: allRows.length,\n getScrollElement: () => virtualScrollRef.current,\n estimateSize: () => 48,\n overscan: virtualizedOverscan,\n })\n : null\n const virtualMaxHeightStyle: React.CSSProperties | undefined = virtualized\n ? {\n maxHeight: typeof virtualizedMaxHeight === 'number'\n ? `${virtualizedMaxHeight}px`\n : virtualizedMaxHeight ?? 'calc(100vh - 300px)',\n overflow: 'auto',\n }\n : undefined\n\n const titleContent = hasTitle ? (\n <div className=\"text-base font-semibold leading-tight min-h-[2.25rem] flex items-center\">\n {typeof title === 'string' ? <h2 className=\"text-base font-semibold\">{title}</h2> : title}\n </div>\n ) : <div className=\"min-h-[2.25rem]\" />\n\n return (\n <TooltipProvider delayDuration={300}>\n <div ref={containerRef} className={containerClassName} data-component-handle={resolvedReplacementHandle}>\n {shouldRenderHeader && (\n <div className={headerWrapperClassName}>\n {(hasTitle || shouldRenderActionsWrapper || renderToolbarInline) && (\n <div className={headerContentClassName}>\n <div className=\"flex-1 min-w-0\">\n {renderToolbarInline ? builtToolbar : titleContent}\n </div>\n {shouldRenderActionsWrapper ? (\n <div className=\"flex flex-wrap items-center gap-2 min-h-[2.25rem]\">\n {refreshButtonConfig ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={refreshButtonConfig.onRefresh}\n aria-label={refreshButtonConfig.label}\n title={refreshButtonConfig.label}\n disabled={refreshButtonConfig.disabled || refreshButtonConfig.isRefreshing}\n >\n {refreshButtonConfig.isRefreshing ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <RefreshCw className=\"h-4 w-4\" />\n )}\n <span className=\"sr-only\">{refreshButtonConfig.label}</span>\n </Button>\n ) : null}\n {advancedFilter ? (\n <Button\n type=\"button\"\n variant={advancedFilter.value.conditions.length > 0 ? 'secondary' : 'ghost'}\n size=\"icon\"\n onClick={() => {\n const opening = !isAdvancedFilterOpen\n if (opening && advancedFilter.value.conditions.length === 0) {\n const newCondition = createEmptyCondition()\n if (resolvedAdvancedFilterFields.length > 0) {\n newCondition.field = resolvedAdvancedFilterFields[0].key\n newCondition.operator = getDefaultOperator(resolvedAdvancedFilterFields[0].type)\n }\n advancedFilter.onChange({ ...advancedFilter.value, conditions: [newCondition] })\n }\n setAdvancedFilterOpen(opening)\n }}\n aria-label={t('ui.advancedFilter.toggle', 'Advanced filters')}\n title={t('ui.advancedFilter.toggle', 'Advanced filters')}\n >\n <Filter className=\"h-4 w-4\" />\n {advancedFilter.value.conditions.length > 0 ? (\n <span className=\"absolute -top-1 -right-1 flex h-4 w-4 items-center justify-center rounded-full bg-primary text-[10px] text-primary-foreground\">\n {advancedFilter.value.conditions.length}\n </span>\n ) : null}\n </Button>\n ) : null}\n {canUsePerspectives ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setPerspectiveOpen(true)}\n aria-label={t('ui.dataTable.customizeColumns.ariaLabel', 'Customize columns')}\n title={t('ui.dataTable.customizeColumns.title', 'Customize columns')}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">{t('ui.dataTable.customizeColumns.srOnly', 'Customize columns')}</span>\n </Button>\n ) : null}\n {exportConfig && hasExport ? <ExportMenu config={exportConfig} sections={resolvedExportSections} /> : null}\n {toolbarInjectionSpotId ? (\n <InjectionSpot spotId={toolbarInjectionSpotId} context={resolvedInjectionContext} />\n ) : null}\n {hasActions ? actions : null}\n </div>\n ) : null}\n </div>\n )}\n {shouldRenderToolbarBelow ? <div className={toolbarWrapperClassName}>{builtToolbar}</div> : null}\n {headerInjectionSpotId ? (\n <div className={embedded ? 'mt-2' : 'mt-3'}>\n <InjectionSpot spotId={headerInjectionSpotId} context={resolvedInjectionContext} />\n </div>\n ) : null}\n </div>\n )}\n {advancedFilter && isAdvancedFilterOpen ? (\n <div className=\"border-b\">\n <AdvancedFilterBuilder\n fields={resolvedAdvancedFilterFields}\n value={advancedFilter.value}\n onChange={advancedFilter.onChange}\n onApply={() => { advancedFilter.onApply(); setAdvancedFilterOpen(false) }}\n onClear={() => { advancedFilter.onClear(); setAdvancedFilterOpen(false) }}\n />\n </div>\n ) : null}\n {advancedFilter && advancedFilter.value.conditions.length > 0 && !isAdvancedFilterOpen ? (\n <div className=\"flex items-center gap-2 flex-wrap px-4 py-2 border-b text-sm\">\n <span className=\"text-muted-foreground\">\n {t('ui.advancedFilter.activeCount', '{count} active filters', { count: advancedFilter.value.conditions.length })}\n </span>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"h-auto px-1 py-0.5 text-xs\" onClick={() => setAdvancedFilterOpen(true)}>\n {t('ui.advancedFilter.edit', 'Edit')}\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"h-auto px-1 py-0.5 text-xs text-muted-foreground\" onClick={advancedFilter.onClear}>\n {t('ui.advancedFilter.clearAll', 'Clear all')}\n </Button>\n </div>\n ) : null}\n <HeaderDndWrapper\n enabled={enableHeaderDnd}\n contextId={`${stableDndContextId}-headers`}\n sensors={dndSensors}\n columnIds={headerColumnIds}\n onDragEnd={handleHeaderDragEnd}\n >\n <div ref={virtualized ? virtualScrollRef : undefined} className={tableScrollWrapperClassName} style={virtualMaxHeightStyle}>\n <Table className=\"min-w-[640px] md:min-w-0\">\n <TableHeader>\n {table.getHeaderGroups().map((hg) => (\n <TableRow key={hg.id}>\n {hasInjectedBulkActions ? (\n <TableHead className=\"w-8\">\n <Checkbox\n checked={table.getIsAllPageRowsSelected()}\n onCheckedChange={(checked) => {\n table.toggleAllPageRowsSelected(Boolean(checked))\n }}\n aria-label={t('ui.dataTable.bulkAction.selectAll', 'Select all rows')}\n />\n </TableHead>\n ) : null}\n {hg.headers.map((header, headerIndex) => {\n const columnMeta = (header.column.columnDef as any)?.meta\n const priority = resolvePriority(header.column)\n const isFirstDataColumn = headerIndex === 0\n const stickyClass = stickyFirstColumn && isFirstDataColumn ? ' sticky left-0 z-10 bg-background' : ''\n const headerCellContent = header.isPlaceholder ? null : (\n <Button\n variant=\"ghost\"\n type=\"button\"\n className={`h-auto p-0 font-medium ${sortable && header.column.getCanSort?.() ? 'cursor-pointer select-none' : ''}`}\n onClick={() => sortable && header.column.toggleSorting?.(header.column.getIsSorted() === 'asc')}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {sortable && header.column.getCanSort?.() ? (\n <span className=\"ml-1 inline-flex flex-col text-[10px] leading-none gap-px\">\n <span className={header.column.getIsSorted() === 'asc' ? 'text-foreground' : 'text-muted-foreground/40'}>\u25B2</span>\n <span className={header.column.getIsSorted() === 'desc' ? 'text-foreground' : 'text-muted-foreground/40'}>\u25BC</span>\n </span>\n ) : null}\n </Button>\n )\n return enableHeaderDnd ? (\n <SortableHeaderCell key={header.id} id={header.id} className={responsiveClass(priority, columnMeta?.hidden) + stickyClass}>\n {headerCellContent}\n </SortableHeaderCell>\n ) : (\n <TableHead key={header.id} className={responsiveClass(priority, columnMeta?.hidden) + stickyClass}>\n {headerCellContent}\n </TableHead>\n )\n })}\n {rowActions || injectedRowActions.length > 0 ? (\n <TableHead\n className={cn(\n 'w-0 text-right',\n stickyActionsColumn && 'sticky right-0 z-20 bg-background',\n )}\n >\n {t('ui.dataTable.actionsColumn', 'Actions')}\n </TableHead>\n ) : null}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {isLoading ? (\n <TableRow>\n <TableCell colSpan={mergedColumns.length + (rowActions || injectedRowActions.length > 0 ? 1 : 0) + (hasInjectedBulkActions ? 1 : 0)} className=\"h-24 text-center\">\n <div className=\"flex items-center justify-center gap-2\">\n <Spinner size=\"md\" />\n <span className=\"text-muted-foreground\">{t('ui.dataTable.loading', 'Loading data...')}</span>\n </div>\n </TableCell>\n </TableRow>\n ) : error ? (\n <TableRow>\n <TableCell colSpan={mergedColumns.length + (rowActions || injectedRowActions.length > 0 ? 1 : 0) + (hasInjectedBulkActions ? 1 : 0)} className=\"h-24 text-center text-destructive\">\n {error}\n </TableCell>\n </TableRow>\n ) : allRows.length ? (\n <>\n {virtualized && rowVirtualizer ? (\n <>\n {rowVirtualizer.getVirtualItems()[0]?.start > 0 ? (\n <tr style={{ height: `${rowVirtualizer.getVirtualItems()[0].start}px` }} />\n ) : null}\n </>\n ) : null}\n {(virtualized && rowVirtualizer\n ? rowVirtualizer.getVirtualItems().map((vi) => allRows[vi.index])\n : allRows\n ).map((row) => {\n const rowActionsElement = resolvedRowActions(row.original as T)\n const defaultRowAction = onRowClick ? null : pickDefaultRowAction(rowActionsElement, resolvedRowClickActionIds)\n const isClickable = !disableRowClick && (onRowClick || defaultRowAction)\n \n return (\n <TableRow \n key={row.id} \n data-state={row.getIsSelected() && 'selected'}\n className={isClickable ? 'cursor-pointer hover:bg-muted/50 transition-colors' : ''}\n onClick={isClickable ? (e) => {\n // Don't trigger row click if clicking on actions cell\n if ((e.target as HTMLElement).closest('[data-actions-cell]')) {\n return\n }\n \n if (onRowClick) {\n onRowClick(row.original as T)\n } else if (defaultRowAction) {\n if (defaultRowAction.href) {\n router.push(defaultRowAction.href)\n } else if (defaultRowAction.onSelect) {\n defaultRowAction.onSelect()\n }\n }\n } : undefined}\n >\n {hasInjectedBulkActions ? (\n <TableCell className=\"w-8\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(checked) => row.toggleSelected(Boolean(checked))}\n aria-label={t('ui.dataTable.bulkAction.selectRow', 'Select row')}\n onClick={(event) => event.stopPropagation()}\n />\n </TableCell>\n ) : null}\n {row.getVisibleCells().map((cell, cellIndex) => {\n const columnMeta = (cell.column.columnDef as any)?.meta\n const priority = resolvePriority(cell.column)\n const isStickyCell = stickyFirstColumn && cellIndex === 0\n const hasCustomCell = Boolean(cell.column.columnDef.cell)\n const columnId = String((cell.column as any).id || '')\n const accessorKey = String((cell.column.columnDef as any)?.accessorKey || '')\n const isDateCol = dateColumnIds ? dateColumnIds.has(columnId) : false\n\n let content: React.ReactNode\n if (isDateCol) {\n const raw = cell.getValue() as any\n const d = tryParseDate(raw)\n content = d ? simpleFormat(d, DATE_FORMAT) : (raw as any)\n } else {\n content = flexRender(cell.column.columnDef.cell, cell.getContext())\n }\n\n // Get truncation configuration for this column\n const skipTruncation = shouldSkipTruncation(columnId)\n // Get truncation configuration for this column\n const truncateConfig = getColumnTruncateConfig(columnId, accessorKey, columnMeta)\n const shouldTruncate = truncateConfig.truncate && !skipTruncation\n const maxWidth = truncateConfig.maxWidth\n\n // Wrap content with TruncatedCell if truncation is enabled\n // Get raw cell value for tooltip - flexRender returns React elements\n // that cannot have their text extracted, so we pass the raw value directly\n // Check for custom tooltip content function in column meta for complex cells\n const cellValue = cell.getValue()\n const metaTooltipContent = columnMeta?.tooltipContent as ((row: unknown) => string | undefined) | undefined\n let tooltipText: string | undefined\n if (metaTooltipContent) {\n tooltipText = metaTooltipContent(row.original)\n } else if (isDateCol && cellValue != null) {\n const parsedDate = tryParseDate(cellValue)\n tooltipText = parsedDate ? simpleFormat(parsedDate, DATE_FORMAT) : String(cellValue)\n } else {\n tooltipText = cellValue != null ? String(cellValue) : undefined\n }\n\n const wrappedContent = shouldTruncate ? (\n <TruncatedCell maxWidth={maxWidth} tooltipContent={tooltipText}>\n {content}\n </TruncatedCell>\n ) : content\n\n return (\n <TableCell key={cell.id} className={responsiveClass(priority, columnMeta?.hidden) + (isStickyCell ? ' sticky left-0 z-10 bg-background' : '')}>\n {wrappedContent}\n </TableCell>\n )\n })}\n {rowActions || injectedRowActions.length > 0 ? (\n <TableCell\n className={cn(\n 'text-right whitespace-nowrap',\n stickyActionsColumn && 'sticky right-0 z-10 bg-background',\n )}\n data-actions-cell\n >\n {rowActionsElement}\n </TableCell>\n ) : null}\n </TableRow>\n )\n })}\n {virtualized && rowVirtualizer ? (() => {\n const virtualItems = rowVirtualizer.getVirtualItems()\n const lastItem = virtualItems[virtualItems.length - 1]\n const bottomPadding = lastItem ? rowVirtualizer.getTotalSize() - lastItem.end : 0\n return bottomPadding > 0 ? <tr style={{ height: `${bottomPadding}px` }} /> : null\n })() : null}\n </>\n ) : (\n <TableRow>\n <TableCell colSpan={mergedColumns.length + (rowActions || injectedRowActions.length > 0 ? 1 : 0) + (hasInjectedBulkActions ? 1 : 0)} className=\"h-24 text-center text-muted-foreground\">\n {emptyState ?? t('ui.dataTable.emptyState.default', 'No results.')}\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n </HeaderDndWrapper>\n {footerInjectionSpotId ? (\n <div className={embedded ? 'mt-3' : 'px-4 py-3 border-t'}>\n <InjectionSpot spotId={footerInjectionSpotId} context={resolvedInjectionContext} />\n </div>\n ) : null}\n {paginationNode}\n {ConfirmDialogElement}\n {canUsePerspectives ? (\n <PerspectiveSidebar\n open={isPerspectiveOpen}\n onOpenChange={setPerspectiveOpen}\n loading={perspectiveQuery.isFetching && !perspectiveQuery.data}\n perspectives={perspectiveData?.perspectives ?? []}\n rolePerspectives={perspectiveData?.rolePerspectives ?? []}\n roles={perspectiveData?.roles ?? []}\n activePerspectiveId={activePerspectiveId}\n onActivatePerspective={handlePerspectiveActivate}\n onDeletePerspective={handlePerspectiveDelete}\n onClearRole={handleClearRole}\n onSave={handlePerspectiveSave}\n canApplyToRoles={Boolean(perspectiveData?.canApplyToRoles && canUseRoleDefaultsFeature)}\n availableColumns={effectiveColumnChooserFields}\n visibleColumnKeys={visibleColumnKeys}\n columnOrder={columnOrder}\n onToggleColumn={handleColumnChooserToggle}\n onReorderColumns={handleColumnChooserReorder}\n saving={savePerspectiveMutation.isPending}\n deletingIds={deletingIds}\n roleClearingIds={roleClearingIds}\n apiWarning={perspectiveApiWarning}\n />\n ) : null}\n </div>\n </TooltipProvider>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport { useReactTable, getCoreRowModel, getSortedRowModel, flexRender, type ColumnDef, type SortingState, type Column as TableColumn, type VisibilityState, type RowSelectionState } from '@tanstack/react-table'\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { RefreshCw, Loader2, SlidersHorizontal, MoreHorizontal, Circle, Filter, ChevronDown, Check } from 'lucide-react'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../primitives/table'\nimport { Button } from '../primitives/button'\nimport { Checkbox } from '../primitives/checkbox'\nimport { Spinner } from '../primitives/spinner'\nimport { TooltipProvider } from '../primitives/tooltip'\nimport { TruncatedCell } from './TruncatedCell'\nimport { FilterBar, type FilterDef, type FilterValues } from './FilterBar'\nimport { useCustomFieldFilterDefs } from './utils/customFieldFilters'\nimport { fetchCustomFieldDefinitionsPayload, type CustomFieldsetDto } from './utils/customFieldDefs'\nimport { RowActions, type RowActionItem } from './RowActions'\nimport { subscribeOrganizationScopeChanged, type OrganizationScopeChangedDetail } from '@open-mercato/shared/lib/frontend/organizationEvents'\nimport { InjectionSpot } from './injection/InjectionSpot'\nimport { useAppEvent } from './injection/useAppEvent'\nimport { useInjectionDataWidgets } from './injection/useInjectionDataWidgets'\nimport { resolveInjectedIcon } from './injection/resolveInjectedIcon'\nimport { serializeExport, defaultExportFilename, type PreparedExport } from '@open-mercato/shared/lib/crud/exporters'\nimport { apiCall } from './utils/apiCall'\nimport { raiseCrudError } from './utils/serverErrors'\nimport { PerspectiveSidebar } from './PerspectiveSidebar'\nimport { Popover, PopoverTrigger, PopoverContent } from '../primitives/popover'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { flash } from './FlashMessages'\nimport { useConfirmDialog } from './confirm-dialog'\nimport type {\n PerspectiveDto,\n RolePerspectiveDto,\n PerspectivesIndexResponse,\n PerspectiveSettings,\n PerspectiveSaveResponse,\n} from '@open-mercato/shared/modules/perspectives/types'\nimport type {\n InjectionColumnDefinition,\n InjectionBulkActionDefinition,\n InjectionFilterDefinition,\n InjectionRowActionDefinition,\n} from '@open-mercato/shared/modules/widgets/injection'\nimport { ComponentReplacementHandles } from '@open-mercato/shared/modules/widgets/component-registry'\nimport { insertByInjectionPlacement } from '@open-mercato/shared/modules/widgets/injection-position'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport type { AdvancedFilterState, FilterFieldDef as AdvancedFilterFieldDef } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { createEmptyCondition, getDefaultOperator } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { AdvancedFilterBuilder } from './filters/AdvancedFilterBuilder'\nimport { type ColumnChooserField } from './columns/ColumnChooserPanel'\nimport { useAutoDiscoveredFields } from './utils/useAutoDiscoveredFields'\nimport { useCustomFieldDefs } from './utils/customFieldDefs'\nimport {\n DndContext,\n closestCenter,\n PointerSensor,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from '@dnd-kit/core'\nimport {\n SortableContext,\n horizontalListSortingStrategy,\n useSortable,\n} from '@dnd-kit/sortable'\nimport { CSS } from '@dnd-kit/utilities'\n\nlet refreshScheduled = false\n\nfunction scheduleRouterRefresh(router: ReturnType<typeof useRouter>) {\n if (refreshScheduled) return\n refreshScheduled = true\n if (typeof window === 'undefined') {\n refreshScheduled = false\n return\n }\n window.requestAnimationFrame(() => {\n refreshScheduled = false\n try { router.refresh() } catch {}\n })\n}\n\nexport type PaginationProps = {\n page: number\n pageSize: number\n total: number\n totalPages: number\n onPageChange: (page: number) => void\n durationMs?: number | null\n cacheStatus?: 'hit' | 'miss' | null\n pageSizeOptions?: number[]\n onPageSizeChange?: (pageSize: number) => void\n}\n\nexport type DataTableRefreshButton = {\n onRefresh: () => void\n label: string\n isRefreshing?: boolean\n disabled?: boolean\n}\n\nconst DEFAULT_ROW_CLICK_ACTION_IDS = ['edit', 'open']\n\nexport function withDataTableNamespaces<T extends Record<string, unknown>>(\n mappedRow: T,\n sourceItem: Record<string, unknown>,\n): T & Record<string, unknown> {\n const namespaced: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(sourceItem)) {\n if (!key.startsWith('_')) continue\n namespaced[key] = value\n }\n return {\n ...mappedRow,\n ...namespaced,\n }\n}\n\nfunction resolveDataTableRowId<T>(row: T, index: number): string {\n if (row && typeof row === 'object') {\n const candidate = (row as Record<string, unknown>).id\n if (typeof candidate === 'string' && candidate.trim().length > 0) {\n return candidate\n }\n }\n return String(index)\n}\n\nfunction resolveDefaultRowAction(items: RowActionItem[], preferredIds: string[]): RowActionItem | null {\n for (const preferredId of preferredIds) {\n const match = items.find((item) => item.id === preferredId && (item.href || item.onSelect))\n if (match) return match\n }\n for (const preferredId of preferredIds) {\n const match = items.find((item) => item.label.toLowerCase() === preferredId && (item.href || item.onSelect))\n if (match) return match\n }\n return null\n}\n\nfunction pickDefaultRowAction(node: React.ReactNode, preferredIds: string[]): RowActionItem | null {\n if (!React.isValidElement(node)) return null\n const items = (node.props as { items?: RowActionItem[] }).items\n if (!Array.isArray(items)) return null\n return resolveDefaultRowAction(items, preferredIds)\n}\n\nexport type DataTableExportFormat = 'csv' | 'json' | 'xml' | 'markdown'\n\nexport type DataTableExportSectionConfig = {\n title?: string\n description?: string\n getUrl?: (format: DataTableExportFormat) => string\n prepare?: (format: DataTableExportFormat) => Promise<PreparedExport | { prepared: PreparedExport; filename?: string } | null> | PreparedExport | { prepared: PreparedExport; filename?: string } | null\n formats?: DataTableExportFormat[]\n disabled?: boolean\n filename?: (format: DataTableExportFormat) => string\n}\n\nexport type DataTableExportConfig = {\n label?: string\n disabled?: boolean\n formats?: DataTableExportFormat[]\n getUrl?: (format: DataTableExportFormat) => string\n sections?: DataTableExportSectionConfig[]\n view?: DataTableExportSectionConfig\n full?: DataTableExportSectionConfig\n filename?: (format: DataTableExportFormat) => string\n}\n\nexport type DataTablePerspectiveConfig = {\n tableId: string\n initialState?: {\n response?: PerspectivesIndexResponse\n activePerspectiveId?: string | null\n initialSettings?: PerspectiveSettings | null\n }\n}\n\nexport type BulkAction<T = Record<string, unknown>> = {\n id: string\n label: string\n icon?: React.ComponentType<{ className?: string }>\n destructive?: boolean\n onExecute: (selectedRows: T[]) => Promise<void | boolean | BulkActionExecuteResult> | void | boolean | BulkActionExecuteResult\n}\n\nexport type DataTableProps<T> = {\n columns: ColumnDef<T, any>[]\n data: T[]\n toolbar?: React.ReactNode\n title?: React.ReactNode\n actions?: React.ReactNode\n refreshButton?: DataTableRefreshButton\n sortable?: boolean\n sorting?: SortingState\n onSortingChange?: (s: SortingState) => void\n pagination?: PaginationProps\n isLoading?: boolean\n emptyState?: React.ReactNode\n error?: React.ReactNode | string | null\n rowActions?: (row: T) => React.ReactNode\n onRowClick?: (row: T) => void\n rowClickActionIds?: string[]\n disableRowClick?: boolean\n bulkActions?: BulkAction<T>[]\n selectionScopeKey?: string\n\n // Auto FilterBar options (rendered as toolbar when provided and no custom toolbar passed)\n searchValue?: string\n onSearchChange?: (v: string) => void\n searchPlaceholder?: string\n searchAlign?: 'left' | 'right'\n filters?: FilterDef[]\n filterValues?: FilterValues\n onFiltersApply?: (values: FilterValues) => void\n onFiltersClear?: () => void\n entityId?: string\n entityIds?: string[]\n exporter?: DataTableExportConfig | false\n perspective?: DataTablePerspectiveConfig\n embedded?: boolean\n onCustomFieldFilterFieldsetChange?: (fieldset: string | null, entityId?: string) => void\n customFieldFilterKeyExtras?: Array<string | number | boolean | null | undefined>\n injectionSpotId?: string\n injectionContext?: Record<string, unknown>\n replacementHandle?: string\n stickyFirstColumn?: boolean\n stickyActionsColumn?: boolean\n virtualized?: boolean\n virtualizedMaxHeight?: number | string\n virtualizedOverscan?: number\n advancedFilter?: {\n fields?: AdvancedFilterFieldDef[]\n auto?: boolean\n value: AdvancedFilterState\n onChange: (state: AdvancedFilterState) => void\n onApply: () => void\n onClear: () => void\n }\n columnChooser?: {\n availableColumns?: ColumnChooserField[]\n auto?: boolean\n }\n}\n\nconst DEFAULT_EXPORT_FORMATS: DataTableExportFormat[] = ['csv', 'json', 'xml', 'markdown']\nconst EXPORT_LABELS: Record<DataTableExportFormat, string> = {\n csv: 'CSV',\n json: 'JSON',\n xml: 'XML',\n markdown: 'Markdown',\n}\nconst EMPTY_FILTER_DEFS: FilterDef[] = []\nconst EMPTY_FILTER_VALUES: FilterValues = Object.freeze({}) as FilterValues\n\ntype BulkActionExecuteResult = {\n ok: boolean\n message?: string\n affectedCount?: number\n progressJobId?: string | null\n}\n\nfunction collectUniqueById<T extends { id: string }>(\n entries: T[],\n warningScope: string,\n): T[] {\n const byId = new Map<string, T>()\n for (const entry of entries) {\n if (!entry.id) continue\n if (byId.has(entry.id)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`[UMES] Duplicate injected ${warningScope} id \"${entry.id}\" detected. Keeping the first entry.`)\n }\n continue\n }\n byId.set(entry.id, entry)\n }\n return Array.from(byId.values())\n}\n\ntype ResolvedExportSection = {\n key: string\n title: string\n description?: string\n formats: DataTableExportFormat[]\n getUrl?: (format: DataTableExportFormat) => string\n prepare?: (format: DataTableExportFormat) => Promise<{ prepared: PreparedExport; filename?: string } | null> | { prepared: PreparedExport; filename?: string } | null\n filename?: (format: DataTableExportFormat) => string\n disabled: boolean\n}\n\nfunction resolveExportSections(config: DataTableExportConfig | null | undefined): ResolvedExportSection[] {\n if (!config) return []\n const sections: ResolvedExportSection[] = []\n const baseFormats = config.formats && config.formats.length > 0 ? config.formats : DEFAULT_EXPORT_FORMATS\n const addSection = (key: string, section: DataTableExportSectionConfig | undefined | null, fallbackTitle: string) => {\n if (!section || (!section.getUrl && !section.prepare)) return\n const title = section.title?.trim().length ? section.title!.trim() : fallbackTitle\n const seen = new Set<DataTableExportFormat>()\n const formatsSource = section.formats && section.formats.length > 0 ? section.formats : baseFormats\n const formats = formatsSource.filter((format) => {\n if (seen.has(format)) return false\n seen.add(format)\n return true\n })\n if (formats.length === 0) return\n sections.push({\n key,\n title,\n description: section.description,\n formats,\n getUrl: section.getUrl,\n prepare: section.prepare\n ? async (format: DataTableExportFormat) => {\n const result = await section.prepare!(format)\n if (!result) return null\n if ('prepared' in result) return result\n return { prepared: result }\n }\n : undefined,\n filename: section.filename,\n disabled: Boolean(config.disabled || section.disabled),\n })\n }\n\n // Allow legacy config (getUrl without sections/view)\n const hasExplicitSections = Array.isArray(config.sections) && config.sections.length > 0\n if (!config.view && !config.full && !hasExplicitSections && config.getUrl) {\n addSection('view', { getUrl: config.getUrl, formats: config.formats }, 'Export what you view')\n } else {\n addSection('view', config.view, 'Export what you view')\n }\n\n if (hasExplicitSections) {\n config.sections!.forEach((section, idx) => {\n addSection(`section-${idx}`, section, section.title?.trim().length ? section.title! : `Export ${idx + 1}`)\n })\n }\n\n addSection('full', config.full, 'Full data export')\n return sections\n}\n\nconst PERSPECTIVE_COOKIE_PREFIX = 'om_table_perspective'\nconst PERSPECTIVE_STORAGE_PREFIX = 'om_table_perspective_snapshot'\n\nfunction formatDurationLabel(durationMs?: number | null): string {\n if (durationMs == null) return ''\n if (!Number.isFinite(durationMs)) return ''\n if (durationMs < 0) return ''\n if (durationMs < 1000) return `${Math.round(durationMs)}ms`\n if (durationMs < 10_000) return `${(durationMs / 1000).toFixed(1)}s`\n if (durationMs < 60_000) return `${Math.round(durationMs / 1000)}s`\n if (durationMs < 3_600_000) return `${(durationMs / 60_000).toFixed(durationMs < 600_000 ? 1 : 0)}m`\n return `${(durationMs / 3_600_000).toFixed(durationMs < 7_200_000 ? 1 : 0)}h`\n}\n\ntype PerspectiveSnapshot = {\n perspectiveId: string | null\n settings: PerspectiveSettings\n updatedAt: number\n}\n\nfunction readPerspectiveCookie(tableId: string): string | null {\n if (typeof document === 'undefined') return null\n const key = `${PERSPECTIVE_COOKIE_PREFIX}:${tableId}`\n const pattern = new RegExp(`(?:^|;\\\\s*)${key}=([^;]+)`)\n const match = document.cookie.match(pattern)\n return match ? decodeURIComponent(match[1]) : null\n}\n\nfunction writePerspectiveCookie(tableId: string, perspectiveId: string | null): void {\n if (typeof document === 'undefined') return\n const key = `${PERSPECTIVE_COOKIE_PREFIX}:${tableId}`\n const expires = perspectiveId ? 'Max-Age=31536000' : 'Max-Age=0'\n const value = perspectiveId ? encodeURIComponent(perspectiveId) : ''\n document.cookie = `${key}=${value}; Path=/; ${expires}; SameSite=Lax`\n}\n\nfunction readPerspectiveSnapshot(tableId: string): PerspectiveSnapshot | null {\n if (typeof window === 'undefined') return null\n try {\n const raw = window.localStorage.getItem(`${PERSPECTIVE_STORAGE_PREFIX}:${tableId}`)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n if (!parsed || typeof parsed !== 'object') return null\n const perspectiveId =\n typeof parsed.perspectiveId === 'string' && parsed.perspectiveId.trim().length > 0\n ? parsed.perspectiveId\n : null\n const settings = typeof parsed.settings === 'object' && parsed.settings !== null\n ? parsed.settings as PerspectiveSettings\n : null\n const updatedAt = typeof parsed.updatedAt === 'number' ? parsed.updatedAt : Date.now()\n if (!settings) return null\n return { perspectiveId, settings, updatedAt }\n } catch {\n return null\n }\n}\n\nfunction writePerspectiveSnapshot(tableId: string, snapshot: PerspectiveSnapshot | null) {\n if (typeof window === 'undefined') return\n const key = `${PERSPECTIVE_STORAGE_PREFIX}:${tableId}`\n try {\n if (!snapshot) {\n window.localStorage.removeItem(key)\n return\n }\n window.localStorage.setItem(key, JSON.stringify(snapshot))\n } catch {\n // ignore storage errors\n }\n}\n\nfunction sanitizePerspectiveSettings(source?: PerspectiveSettings | null): PerspectiveSettings | null {\n if (!source || typeof source !== 'object') return null\n const forbidden = new Set(['__proto__', 'prototype', 'constructor'])\n const result: PerspectiveSettings = {}\n\n if (Array.isArray(source.columnOrder)) {\n const seen = new Set<string>()\n const order = source.columnOrder\n .map((id) => (typeof id === 'string' ? id.trim() : ''))\n .filter((id) => id.length > 0 && !seen.has(id) && (seen.add(id), true))\n if (order.length) result.columnOrder = order\n }\n\n if (source.columnVisibility && typeof source.columnVisibility === 'object') {\n const entries = Object.entries(source.columnVisibility)\n .filter(([key, value]) => typeof key === 'string' && key.trim().length > 0 && !forbidden.has(key) && typeof value === 'boolean')\n if (entries.length) {\n const visibility: Record<string, boolean> = {}\n entries.forEach(([key, value]) => { visibility[key] = value })\n result.columnVisibility = visibility\n }\n }\n\n if (Array.isArray(source.sorting)) {\n const sorting = source.sorting\n .map((item) => {\n const id = typeof item?.id === 'string' ? item.id.trim() : ''\n if (!id || forbidden.has(id)) return null\n return { id, desc: Boolean(item?.desc) }\n })\n .filter((item): item is { id: string; desc: boolean } => item !== null)\n if (sorting.length) result.sorting = sorting\n }\n\n if (typeof source.pageSize === 'number' && Number.isFinite(source.pageSize)) {\n const pageSize = Math.max(1, Math.min(500, Math.floor(source.pageSize)))\n result.pageSize = pageSize\n }\n\n if (typeof source.searchValue === 'string' && source.searchValue.trim().length > 0) {\n result.searchValue = source.searchValue.trim().slice(0, 200)\n }\n\n if (source.filters && typeof source.filters === 'object') {\n const filters: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(source.filters)) {\n if (typeof key === 'string') {\n const trimmed = key.trim()\n if (trimmed.length > 0 && !forbidden.has(trimmed)) filters[trimmed] = value\n }\n }\n if (Object.keys(filters).length) result.filters = filters\n }\n\n return Object.keys(result).length ? result : null\n}\n\nfunction normalizeLabel(input: string): string {\n if (!input) return ''\n return input\n .replace(/^cf[_:]/, '')\n .replace(/[_:\\-]+/g, ' ')\n .replace(/\\b\\w/g, (ch) => ch.toUpperCase())\n}\n\n// Column width configuration based on column type\ntype ColumnTruncateConfig = {\n maxWidth: string\n truncate: boolean\n}\n\ntype ColumnTruncateMeta = {\n truncate?: boolean\n maxWidth?: string\n}\n\nfunction getColumnTruncateConfig(columnId: string, accessorKey?: string, columnMeta?: ColumnTruncateMeta): ColumnTruncateConfig {\n const key = accessorKey || columnId\n const metaMaxWidth = typeof columnMeta?.maxWidth === 'string' ? columnMeta.maxWidth.trim() : ''\n\n // Custom fields get narrower width\n if (key.startsWith('cf_') || key.startsWith('cf:')) {\n return {\n maxWidth: metaMaxWidth || '120px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n }\n\n // Core informative columns get wider width\n const wideColumns = ['title', 'name', 'description', 'source', 'companies', 'people']\n if (wideColumns.includes(key)) {\n return {\n maxWidth: metaMaxWidth || '250px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n }\n\n // Medium width for status-like columns\n const mediumColumns = ['status', 'pipelineStage', 'pipeline_stage', 'type', 'category']\n if (mediumColumns.includes(key)) {\n return {\n maxWidth: metaMaxWidth || '180px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n }\n\n // Date columns\n if (key.endsWith('_at') || key.endsWith('At') || key.includes('date') || key.includes('Date')) {\n return {\n maxWidth: metaMaxWidth || '120px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n }\n\n // Default for other columns\n return {\n maxWidth: metaMaxWidth || '150px',\n truncate: typeof columnMeta?.truncate === 'boolean' ? columnMeta.truncate : true,\n }\n}\n\nfunction readInjectedColumnValue(row: unknown, accessorKey: string): unknown {\n if (!row || typeof row !== 'object' || !accessorKey) return undefined\n const segments = accessorKey.split('.').filter((segment) => segment.length > 0)\n if (segments.length === 0) return undefined\n let current: unknown = row\n for (const segment of segments) {\n if (!current || typeof current !== 'object') return undefined\n current = (current as Record<string, unknown>)[segment]\n }\n return current\n}\n\n// Check if a column should skip truncation (e.g., actions column)\nfunction shouldSkipTruncation(columnId: string): boolean {\n const skipColumns = ['actions', 'select', 'checkbox', 'expand']\n return skipColumns.includes(columnId.toLowerCase())\n}\n\nfunction ExportMenu({ config, sections }: { config: DataTableExportConfig; sections: ResolvedExportSection[] }) {\n const t = useT()\n const { label } = config\n const defaultLabel = label ?? t('ui.dataTable.export.label', 'Export')\n const disabled = Boolean(config.disabled)\n const hasSections = sections.length > 0\n const [open, setOpen] = React.useState(false)\n const buttonRef = React.useRef<HTMLButtonElement>(null)\n const menuRef = React.useRef<HTMLDivElement>(null)\n\n React.useEffect(() => {\n if (!open || !hasSections) return\n const onDocClick = (event: MouseEvent) => {\n const target = event.target as Node\n if (menuRef.current && !menuRef.current.contains(target) && buttonRef.current && !buttonRef.current.contains(target)) {\n setOpen(false)\n }\n }\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setOpen(false)\n buttonRef.current?.focus()\n }\n }\n document.addEventListener('mousedown', onDocClick)\n document.addEventListener('keydown', onKeyDown)\n return () => {\n document.removeEventListener('mousedown', onDocClick)\n document.removeEventListener('keydown', onKeyDown)\n }\n }, [hasSections, open])\n\n if (!hasSections) return null\n\n const handleSelect = async (section: ResolvedExportSection, format: DataTableExportFormat) => {\n try {\n if (section.prepare) {\n const preparedResult = await section.prepare(format)\n if (!preparedResult) return\n const prepared = preparedResult.prepared\n const serialized = serializeExport(prepared, format)\n const filename =\n preparedResult.filename\n ?? section.filename?.(format)\n ?? config.filename?.(format)\n ?? defaultExportFilename(section.title, format)\n if (typeof window !== 'undefined') {\n const blob = new Blob([serialized.body], { type: serialized.contentType })\n const href = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = href\n a.download = filename\n document.body.appendChild(a)\n a.click()\n document.body.removeChild(a)\n URL.revokeObjectURL(href)\n }\n } else if (section.getUrl) {\n const url = section.getUrl(format)\n if (url && typeof window !== 'undefined') {\n window.open(url, '_blank', 'noopener,noreferrer')\n }\n }\n } catch {\n // ignore export errors\n } finally {\n setOpen(false)\n }\n }\n\n return (\n <div className=\"relative inline-block\">\n <Button\n ref={buttonRef}\n variant=\"outline\"\n size=\"sm\"\n type=\"button\"\n onClick={() => {\n if (disabled) return\n setOpen((prev) => !prev)\n }}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n disabled={disabled}\n >\n {defaultLabel}\n </Button>\n {open ? (\n <div\n ref={menuRef}\n role=\"menu\"\n className=\"absolute right-0 mt-2 w-60 rounded-md border bg-background py-2 shadow z-20\"\n >\n {sections.map((section, idx) => (\n <div key={section.key} className={idx > 0 ? 'mt-2 border-t pt-3' : ''}>\n <div className=\"px-3\">\n <div className=\"text-xs font-semibold uppercase text-muted-foreground\">{section.title}</div>\n {section.description ? (\n <p className=\"mt-1 text-xs text-muted-foreground leading-snug\">{section.description}</p>\n ) : null}\n </div>\n <div className=\"mt-2 space-y-1 px-2 pb-1\">\n {section.formats.map((format) => (\n <Button\n key={`${section.key}-${format}`}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"w-full justify-start font-normal\"\n onClick={() => void handleSelect(section, format)}\n disabled={section.disabled}\n >\n {EXPORT_LABELS[format]}\n </Button>\n ))}\n </div>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\nfunction sanitizeDndContextId(value: string): string {\n const trimmed = value.trim().toLowerCase()\n let normalized = ''\n let previousWasDash = false\n\n for (const character of trimmed) {\n const isLowercaseLetter = character >= 'a' && character <= 'z'\n const isDigit = character >= '0' && character <= '9'\n\n if (isLowercaseLetter || isDigit || character === '_') {\n normalized += character\n previousWasDash = false\n continue\n }\n\n if (!previousWasDash) {\n normalized += '-'\n previousWasDash = true\n }\n }\n\n while (normalized.startsWith('-')) {\n normalized = normalized.slice(1)\n }\n\n while (normalized.endsWith('-')) {\n normalized = normalized.slice(0, -1)\n }\n\n return normalized.length > 0 ? normalized : 'data-table'\n}\n\nfunction HeaderDndWrapper({ enabled, contextId, sensors, columnIds, onDragEnd, children }: {\n enabled: boolean\n contextId: string\n sensors: ReturnType<typeof useSensors>\n columnIds: string[]\n onDragEnd: (event: DragEndEvent) => void\n children: React.ReactNode\n}) {\n if (!enabled) return <>{children}</>\n return (\n <DndContext id={contextId} sensors={sensors} collisionDetection={closestCenter} onDragEnd={onDragEnd}>\n <SortableContext items={columnIds} strategy={horizontalListSortingStrategy}>\n {children}\n </SortableContext>\n </DndContext>\n )\n}\n\nfunction SortableHeaderCell({ id, children, className }: { id: string; children: React.ReactNode; className?: string }) {\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id })\n const isSticky = typeof className === 'string' && className.includes('sticky')\n const style: React.CSSProperties = {\n transform: CSS.Transform.toString(transform),\n transition,\n opacity: isDragging ? 0.5 : 1,\n cursor: 'grab',\n position: isSticky ? 'sticky' : 'relative',\n }\n return (\n <TableHead ref={setNodeRef} style={style} className={className} {...attributes} {...listeners}>\n {children}\n </TableHead>\n )\n}\n\nfunction ViewSwitcherDropdown({\n activePerspectiveId,\n perspectives,\n rolePerspectives,\n onClear,\n onActivate,\n onOpenSidebar,\n t,\n}: {\n activePerspectiveId: string | null\n perspectives: PerspectiveDto[]\n rolePerspectives: RolePerspectiveDto[]\n onClear: () => void\n onActivate: (item: PerspectiveDto | RolePerspectiveDto, source: 'personal' | 'role') => void\n onOpenSidebar: () => void\n t: (key: string, fallback: string) => string\n}) {\n const [open, setOpen] = React.useState(false)\n const allViews = [...perspectives, ...rolePerspectives]\n const activeName = allViews.find((v) => v.id === activePerspectiveId)?.name.trim() || ''\n const activeLabel = activeName || t('ui.dataTable.perspectives.allViews', 'All views')\n return (\n <div className=\"inline-flex h-9 items-center rounded-md border border-input text-sm\">\n <Button\n data-testid=\"data-table-open-views-sidebar\"\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={onOpenSidebar}\n className=\"h-full rounded-none rounded-l-md px-3 font-medium\"\n >\n <SlidersHorizontal className=\"size-4 mr-1.5\" />\n {t('ui.dataTable.perspectives.button', 'Views')}\n </Button>\n <div className=\"h-5 w-px bg-border\" />\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-full max-w-[200px] rounded-none rounded-r-md px-3 font-normal text-muted-foreground\"\n >\n <span className=\"truncate\">{activeLabel}</span>\n <ChevronDown className=\"size-3.5 shrink-0 ml-1.5\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-[220px] p-1\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className={cn(\n 'w-full justify-start h-auto px-2 py-1.5 text-sm font-normal',\n !activePerspectiveId && 'bg-accent text-accent-foreground'\n )}\n onClick={() => { onClear(); setOpen(false) }}\n >\n <Check className={cn('size-4 shrink-0 mr-2', activePerspectiveId ? 'invisible' : '')} />\n {t('ui.dataTable.perspectives.noView', '\u2014 No view \u2014')}\n </Button>\n {perspectives.map((p) => (\n <Button\n key={p.id}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className={cn(\n 'w-full justify-start h-auto px-2 py-1.5 text-sm font-normal',\n activePerspectiveId === p.id && 'bg-accent text-accent-foreground'\n )}\n onClick={() => { onActivate(p, 'personal'); setOpen(false) }}\n >\n <Check className={cn('size-4 shrink-0 mr-2', activePerspectiveId !== p.id ? 'invisible' : '')} />\n <span className=\"truncate\">{p.name.trim() || t('ui.perspectives.untitled', 'Untitled view')}</span>\n </Button>\n ))}\n {rolePerspectives.map((p) => (\n <Button\n key={p.id}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className={cn(\n 'w-full justify-start h-auto px-2 py-1.5 text-sm font-normal',\n activePerspectiveId === p.id && 'bg-accent text-accent-foreground'\n )}\n onClick={() => { onActivate(p, 'role'); setOpen(false) }}\n >\n <Check className={cn('size-4 shrink-0 mr-2', activePerspectiveId !== p.id ? 'invisible' : '')} />\n <span className=\"truncate\">{p.name.trim() || t('ui.perspectives.untitled', 'Untitled view')}</span>\n </Button>\n ))}\n </PopoverContent>\n </Popover>\n </div>\n )\n}\n\nexport function DataTable<T>({\n columns,\n data,\n toolbar,\n title,\n actions,\n refreshButton,\n sortable,\n sorting: sortingProp,\n onSortingChange,\n pagination,\n isLoading,\n emptyState,\n error,\n rowActions,\n onRowClick,\n rowClickActionIds,\n disableRowClick = false,\n bulkActions: bulkActionsProp,\n selectionScopeKey,\n searchValue,\n onSearchChange,\n searchPlaceholder,\n searchAlign = 'left',\n filters: baseFilters = EMPTY_FILTER_DEFS,\n filterValues = EMPTY_FILTER_VALUES,\n onFiltersApply,\n onFiltersClear,\n entityId,\n entityIds,\n exporter,\n perspective,\n embedded = false,\n onCustomFieldFilterFieldsetChange,\n customFieldFilterKeyExtras,\n injectionSpotId,\n injectionContext,\n replacementHandle,\n stickyFirstColumn = false,\n stickyActionsColumn = false,\n virtualized = false,\n virtualizedMaxHeight,\n virtualizedOverscan = 10,\n advancedFilter,\n columnChooser,\n}: DataTableProps<T>) {\n const t = useT()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const router = useRouter()\n const resolvedRowClickActionIds = rowClickActionIds ?? DEFAULT_ROW_CLICK_ACTION_IDS\n const containerRef = React.useRef<HTMLDivElement>(null)\n const lastScopeRef = React.useRef<OrganizationScopeChangedDetail | null>(null)\n const hasInitializedScopeRef = React.useRef(false)\n React.useEffect(() => {\n return subscribeOrganizationScopeChanged((detail) => {\n const prev = lastScopeRef.current\n lastScopeRef.current = detail\n if (!hasInitializedScopeRef.current) {\n hasInitializedScopeRef.current = true\n return\n }\n if (\n prev &&\n prev.organizationId === detail.organizationId &&\n prev.tenantId === detail.tenantId\n ) {\n return\n }\n scheduleRouterRefresh(router)\n })\n }, [router])\n const queryClient = useQueryClient()\n const perspectiveConfig = perspective ?? null\n const perspectiveTableId = perspectiveConfig?.tableId ?? null\n const perspectiveEnabled = Boolean(perspectiveTableId)\n // Snapshot from localStorage is read post-mount via useLayoutEffect to avoid SSR/CSR\n // hydration mismatch. Initial render uses only props-derived state (identical on both sides).\n const initialSnapshotRef = React.useRef<PerspectiveSnapshot | null>(null)\n const snapshotHydratedTableRef = React.useRef<string | null>(null)\n const initialSettingsFromConfig = sanitizePerspectiveSettings(perspectiveConfig?.initialState?.initialSettings ?? null)\n const mergedInitialSettings = initialSettingsFromConfig\n const initialActiveId = perspectiveConfig?.initialState?.activePerspectiveId ?? null\n const [isPerspectiveOpen, setPerspectiveOpen] = React.useState(false)\n const [isAdvancedFilterOpen, setAdvancedFilterOpen] = React.useState(false)\n const [activePerspectiveId, setActivePerspectiveId] = React.useState<string | null>(initialActiveId)\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>(() => mergedInitialSettings?.columnVisibility ?? {})\n const [columnOrder, setColumnOrder] = React.useState<string[]>(() => mergedInitialSettings?.columnOrder ?? [])\n const [deletingIds, setDeletingIds] = React.useState<string[]>([])\n const [roleClearingIds, setRoleClearingIds] = React.useState<string[]>([])\n const [perspectiveApiMissing, setPerspectiveApiMissing] = React.useState(false)\n\n const perspectiveFeatureQuery = useQuery<{ use: boolean; roleDefaults: boolean }>({\n queryKey: ['feature-check', 'perspectives'],\n enabled: perspectiveEnabled,\n staleTime: 5 * 60 * 1000,\n queryFn: async () => {\n try {\n const call = await apiCall<{ granted?: unknown[] }>(\n '/api/auth/feature-check',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ features: ['perspectives.use', 'perspectives.role_defaults'] }),\n },\n )\n if (!call.ok) throw new Error(`feature-check failed (${call.status})`)\n const data = call.result ?? {}\n const granted = Array.isArray(data?.granted) ? data.granted.map((f: any) => String(f)) : []\n const has = (feature: string) => granted.some((grantedFeature: string) => {\n if (grantedFeature === '*') return true\n if (grantedFeature === feature) return true\n if (grantedFeature.endsWith('.*')) {\n const prefix = grantedFeature.slice(0, -2)\n return feature === prefix || feature.startsWith(`${prefix}.`)\n }\n return false\n })\n return {\n use: has('perspectives.use'),\n roleDefaults: has('perspectives.role_defaults'),\n }\n } catch {\n return {\n use: true,\n roleDefaults: true,\n }\n }\n },\n })\n const perspectivePermissions = perspectiveFeatureQuery.data\n const canUsePerspectives = perspectiveEnabled && Boolean(perspectivePermissions?.use)\n const canUseRoleDefaultsFeature = Boolean(perspectivePermissions?.roleDefaults)\n\n React.useEffect(() => {\n if (!canUsePerspectives && isPerspectiveOpen) {\n setPerspectiveOpen(false)\n }\n }, [canUsePerspectives, isPerspectiveOpen])\n\n React.useEffect(() => {\n if (!perspectiveTableId) return\n if (!mergedInitialSettings) return\n const snapshot: PerspectiveSnapshot = {\n perspectiveId: initialActiveId,\n settings: mergedInitialSettings,\n updatedAt: Date.now(),\n }\n writePerspectiveSnapshot(perspectiveTableId, snapshot)\n initialSnapshotRef.current = snapshot\n }, [perspectiveTableId, mergedInitialSettings, initialActiveId])\n\n const perspectiveQuery = useQuery<PerspectivesIndexResponse>({\n queryKey: ['table-perspectives', perspectiveTableId],\n queryFn: async () => {\n if (!perspectiveTableId) throw new Error('Missing table id')\n const call = await apiCall<PerspectivesIndexResponse>(`/api/perspectives/${encodeURIComponent(perspectiveTableId)}`)\n if (call.status === 404) {\n setPerspectiveApiMissing(true)\n return {\n tableId: perspectiveTableId,\n perspectives: [],\n defaultPerspectiveId: null,\n rolePerspectives: [],\n roles: [],\n canApplyToRoles: false,\n }\n }\n if (!call.ok) {\n await raiseCrudError(call.response, t('ui.dataTable.perspectives.error.load', 'Failed to load perspectives'))\n }\n setPerspectiveApiMissing(false)\n const payload = call.result\n if (!payload) throw new Error(t('ui.dataTable.perspectives.error.load', 'Failed to load perspectives'))\n return payload\n },\n enabled: canUsePerspectives,\n initialData: perspectiveConfig?.initialState?.response,\n staleTime: 5 * 60 * 1000,\n gcTime: 10 * 60 * 1000,\n })\n const perspectiveData = perspectiveQuery.data\n const initialPerspectiveAppliedRef = React.useRef(Boolean(mergedInitialSettings))\n\n const extensionTableId = React.useMemo(() => {\n if (perspective?.tableId) return perspective.tableId\n if (injectionSpotId?.startsWith('data-table:')) return injectionSpotId.slice('data-table:'.length)\n return null\n }, [injectionSpotId, perspective?.tableId])\n const resolvedInjectionSpotId = injectionSpotId ?? (perspective?.tableId ? `data-table:${perspective.tableId}` : null)\n const resolvedReplacementHandle = replacementHandle ?? ComponentReplacementHandles.dataTable(extensionTableId ?? 'unknown')\n const resolvedInjectionContext = React.useMemo(\n () => injectionContext ?? { tableId: perspective?.tableId ?? null, title: typeof title === 'string' ? title : undefined },\n [injectionContext, perspective?.tableId, title]\n )\n const headerInjectionSpotId = React.useMemo(\n () => (resolvedInjectionSpotId ? `${resolvedInjectionSpotId}:header` : null),\n [resolvedInjectionSpotId]\n )\n const toolbarInjectionSpotId = React.useMemo(\n () => (resolvedInjectionSpotId ? `${resolvedInjectionSpotId}:toolbar` : null),\n [resolvedInjectionSpotId]\n )\n const footerInjectionSpotId = React.useMemo(\n () => (resolvedInjectionSpotId ? `${resolvedInjectionSpotId}:footer` : null),\n [resolvedInjectionSpotId]\n )\n const { widgets: columnWidgets } = useInjectionDataWidgets(\n extensionTableId ? `data-table:${extensionTableId}:columns` : '__disabled__:columns',\n )\n const { widgets: rowActionWidgets } = useInjectionDataWidgets(\n extensionTableId ? `data-table:${extensionTableId}:row-actions` : '__disabled__:row-actions',\n )\n const { widgets: bulkActionWidgets } = useInjectionDataWidgets(\n extensionTableId ? `data-table:${extensionTableId}:bulk-actions` : '__disabled__:bulk-actions',\n )\n const { widgets: filterWidgets } = useInjectionDataWidgets(\n extensionTableId ? `data-table:${extensionTableId}:filters` : '__disabled__:filters',\n )\n const injectedColumnDefs = React.useMemo<{ def: ColumnDef<T, unknown>; placement: InjectionColumnDefinition['placement'] }[]>(() => {\n const entries: InjectionColumnDefinition[] = []\n for (const widget of columnWidgets) {\n if (!('columns' in widget)) continue\n for (const definition of widget.columns ?? []) {\n entries.push(definition)\n }\n }\n return collectUniqueById(entries, 'column').map((definition) => ({\n def: {\n id: definition.id,\n accessorFn: (row: T) => readInjectedColumnValue(row, definition.accessorKey),\n header: t(definition.header, definition.header),\n cell: definition.cell as ColumnDef<T, unknown>['cell'],\n size: definition.size,\n enableSorting: definition.sortable === true,\n },\n placement: definition.placement,\n }))\n }, [columnWidgets, t])\n const injectedRowActions = React.useMemo<InjectionRowActionDefinition[]>(() => {\n const entries: InjectionRowActionDefinition[] = []\n for (const widget of rowActionWidgets) {\n if (!('rowActions' in widget)) continue\n for (const definition of widget.rowActions ?? []) {\n entries.push(definition)\n }\n }\n return collectUniqueById(entries, 'row action')\n }, [rowActionWidgets])\n const injectedBulkActions = React.useMemo<InjectionBulkActionDefinition[]>(() => {\n const entries: InjectionBulkActionDefinition[] = []\n for (const widget of bulkActionWidgets) {\n if (!('bulkActions' in widget)) continue\n for (const definition of widget.bulkActions ?? []) {\n entries.push(definition)\n }\n }\n return collectUniqueById(entries, 'bulk action')\n }, [bulkActionWidgets])\n const { serverFilters: injectedFilters, clientFilters: injectedClientFilters } = React.useMemo<{\n serverFilters: FilterDef[]\n clientFilters: { id: string; filterFn: (row: unknown, value: unknown) => boolean }[]\n }>(() => {\n const byId = new Map<string, FilterDef>()\n const clientEntries: { id: string; filterFn: (row: unknown, value: unknown) => boolean }[] = []\n for (const widget of filterWidgets) {\n if (!('filters' in widget)) continue\n for (const definition of widget.filters ?? []) {\n const filter = definition as InjectionFilterDefinition\n const mappedType: FilterDef['type'] =\n filter.type === 'date-range'\n ? 'dateRange'\n : filter.type === 'boolean'\n ? 'checkbox'\n : filter.type === 'select'\n ? 'select'\n : 'text'\n const id = filter.queryParam ?? filter.id\n if (filter.strategy === 'client' && filter.filterFn) {\n clientEntries.push({ id, filterFn: filter.filterFn })\n }\n if (!byId.has(id)) {\n const translatedOptions = Array.isArray(filter.options)\n ? filter.options.map((option) => ({\n ...option,\n label: t(option.label, option.label),\n }))\n : filter.options\n byId.set(id, {\n id,\n label: t(filter.label, filter.label),\n type: mappedType,\n options: translatedOptions,\n })\n }\n }\n }\n return { serverFilters: Array.from(byId.values()), clientFilters: clientEntries }\n }, [filterWidgets, t])\n const mergedColumns = React.useMemo<ColumnDef<T, unknown>[]>(() => {\n if (!injectedColumnDefs.length) return columns\n let result = [...columns]\n for (const { def, placement } of injectedColumnDefs) {\n result = insertByInjectionPlacement(\n result,\n def,\n placement,\n (col) => (col as { id?: string }).id ?? '',\n )\n }\n return result\n }, [columns, injectedColumnDefs])\n const resolvedRowActions = React.useCallback((row: T) => {\n const injectedItems: (RowActionItem & { placement?: InjectionRowActionDefinition['placement'] })[] = injectedRowActions.map((action) => ({\n id: action.id,\n label: t(action.label, action.label),\n onSelect: () => action.onSelect(row, { navigate: (href: string) => router.push(href) }),\n placement: action.placement,\n }))\n const baseNode = rowActions ? rowActions(row) : null\n if (!injectedItems.length) return baseNode\n if (React.isValidElement(baseNode)) {\n const baseItems = (baseNode.props as { items?: RowActionItem[] }).items\n if (Array.isArray(baseItems)) {\n let merged = [...baseItems]\n const existingIds = new Set(\n baseItems.map((item) => item.id).filter((id): id is string => typeof id === 'string' && id.length > 0)\n )\n for (const item of injectedItems) {\n if (item.id && existingIds.has(item.id)) continue\n merged = insertByInjectionPlacement(\n merged,\n item,\n item.placement,\n (entry) => entry.id ?? '',\n )\n }\n return <RowActions items={merged} />\n }\n }\n return <RowActions items={injectedItems} />\n }, [injectedRowActions, rowActions, router, t])\n\n // Date formatting setup\n const DATE_FORMAT = (process.env.NEXT_PUBLIC_DATE_FORMAT || 'YYYY-MM-DD HH:mm') as string\n\n const pad2 = (n: number) => (n < 10 ? `0${n}` : String(n))\n const simpleFormat = (d: Date, fmt: string) => {\n // Supports tokens: YYYY, MM, DD, HH, mm, ss\n const YYYY = String(d.getFullYear())\n const MM = pad2(d.getMonth() + 1)\n const DD = pad2(d.getDate())\n const HH = pad2(d.getHours())\n const mm = pad2(d.getMinutes())\n const ss = pad2(d.getSeconds())\n return fmt\n .replace(/YYYY/g, YYYY)\n .replace(/MM/g, MM)\n .replace(/DD/g, DD)\n .replace(/HH/g, HH)\n .replace(/mm/g, mm)\n .replace(/ss/g, ss)\n }\n\n const tryParseDate = (v: unknown): Date | null => {\n if (v == null) return null\n if (v instanceof Date) return isNaN(v.getTime()) ? null : v\n if (typeof v === 'number') {\n const d = new Date(v)\n return isNaN(d.getTime()) ? null : d\n }\n if (typeof v === 'string') {\n const s = v.trim()\n if (!s) return null\n // ISO-like detection (YYYY-MM-DD ...)\n if (/^\\d{4}-\\d{2}-\\d{2}(?:[ T]\\d{2}:\\d{2}(?::\\d{2})?(?:\\.\\d+)?(?:Z|[+-]\\d{2}:?\\d{2})?)?$/.test(s)) {\n const d = new Date(s)\n return isNaN(d.getTime()) ? null : d\n }\n // Fallback: Date.parse\n const d = new Date(s)\n return isNaN(d.getTime()) ? null : d\n }\n return null\n }\n\n // Guess date columns once using first non-empty row\n const [dateColumnIds, setDateColumnIds] = React.useState<Set<string> | null>(null)\n React.useEffect(() => {\n if (dateColumnIds) return\n if (!data || data.length === 0) return\n // Build a cheap row accessor using column defs\n const accessors = mergedColumns.map((c) => {\n const key = (c as any).accessorKey as string | undefined\n const id = (c as any).id as string | undefined\n return { id: id || key || '', key }\n })\n const guessed = new Set<string>()\n accessors.forEach((a) => {\n if (!a.id) return\n const name = a.id\n // Name-based guess: snake_case '_at' suffix\n if (name.endsWith('_at')) {\n guessed.add(name)\n return\n }\n })\n setDateColumnIds(guessed)\n }, [dateColumnIds, data, mergedColumns])\n // Column visibility: only hide columns explicitly marked as hidden.\n // All other columns are always rendered; horizontal scroll (min-w + overflow-auto)\n // handles narrow viewports so users can swipe to reach every column.\n const responsiveClass = (_priority?: number, hidden?: boolean) => {\n if (hidden) return ''\n return ''\n }\n\n const resolvePriority = React.useCallback((column: TableColumn<T, unknown>) => {\n const meta = (column.columnDef as any)?.meta\n const rawPriority = typeof meta?.priority === 'number' ? meta.priority : undefined\n if (rawPriority && rawPriority > 0) return rawPriority\n const index = column.getIndex()\n return index <= 1 ? 1 : 2\n }, [])\n\n const initialSorting = React.useMemo<SortingState>(() => {\n if (mergedInitialSettings?.sorting) {\n return mergedInitialSettings.sorting.map((item) => ({ id: item.id, desc: Boolean(item.desc) }))\n }\n return []\n }, [mergedInitialSettings])\n const [sorting, setSorting] = React.useState<SortingState>(() => {\n if (sortingProp && sortingProp.length) return sortingProp\n if (initialSorting.length) return initialSorting\n return []\n })\n const clientFilteredData = React.useMemo(() => {\n if (!injectedClientFilters.length || !filterValues) return data\n const activeClientFilters = injectedClientFilters.filter(\n (cf) => filterValues[cf.id] !== undefined && filterValues[cf.id] !== '' && filterValues[cf.id] !== null,\n )\n if (!activeClientFilters.length) return data\n return data.filter((row) =>\n activeClientFilters.every((cf) => cf.filterFn(row, filterValues[cf.id])),\n )\n }, [data, injectedClientFilters, filterValues])\n const hasPropBulkActions = Array.isArray(bulkActionsProp) && bulkActionsProp.length > 0\n const hasInjectedBulkActions = injectedBulkActions.length > 0 || hasPropBulkActions\n const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({})\n const selectionScopeKeyRef = React.useRef<string | undefined>(selectionScopeKey)\n const table = useReactTable<T>({\n data: clientFilteredData,\n columns: mergedColumns,\n getCoreRowModel: getCoreRowModel(),\n ...(sortable ? { getSortedRowModel: getSortedRowModel() } : {}),\n getRowId: resolveDataTableRowId,\n state: { sorting, columnVisibility, columnOrder, rowSelection },\n enableRowSelection: hasInjectedBulkActions,\n onSortingChange: (updater) => {\n const next = typeof updater === 'function' ? updater(sorting) : updater\n setSorting(next)\n onSortingChange?.(next)\n },\n onColumnVisibilityChange: (updater) => {\n const next = typeof updater === 'function' ? updater(columnVisibility) : updater\n setColumnVisibility(next)\n },\n onColumnOrderChange: (updater) => {\n const next = typeof updater === 'function' ? updater(columnOrder) : updater\n setColumnOrder(next)\n },\n onRowSelectionChange: setRowSelection,\n })\n React.useEffect(() => { if (sortingProp) setSorting(sortingProp) }, [sortingProp])\n React.useEffect(() => {\n if (selectionScopeKey === undefined) {\n selectionScopeKeyRef.current = undefined\n return\n }\n if (selectionScopeKeyRef.current === undefined) {\n selectionScopeKeyRef.current = selectionScopeKey\n return\n }\n if (selectionScopeKeyRef.current === selectionScopeKey) return\n selectionScopeKeyRef.current = selectionScopeKey\n setRowSelection({})\n }, [selectionScopeKey])\n React.useEffect(() => {\n if (hasInjectedBulkActions) return\n if (Object.keys(rowSelection).length === 0) return\n setRowSelection({})\n }, [hasInjectedBulkActions, rowSelection])\n React.useEffect(() => {\n const ids = table.getAllLeafColumns().map((column) => column.id)\n if (!ids.length) return\n setColumnOrder((prev) => {\n if (!prev.length) return ids\n const allowed = ids\n const filtered = prev.filter((id) => allowed.includes(id))\n const seen = new Set(filtered)\n for (const id of allowed) {\n if (!seen.has(id)) {\n filtered.push(id)\n seen.add(id)\n }\n }\n const changed = filtered.length !== prev.length || filtered.some((id, index) => id !== prev[index])\n return changed ? filtered : prev\n })\n }, [table, mergedColumns])\n\n const initialVisibilityApplied = React.useRef(Boolean(mergedInitialSettings?.columnVisibility))\n React.useEffect(() => {\n if (initialVisibilityApplied.current) return\n const hidden: VisibilityState = {}\n table.getAllLeafColumns().forEach((column) => {\n const hiddenMeta = (column.columnDef as any)?.meta?.hidden\n if (hiddenMeta) hidden[column.id] = false\n })\n if (Object.keys(hidden).length) {\n setColumnVisibility((prev) => ({ ...hidden, ...prev }))\n }\n initialVisibilityApplied.current = true\n }, [table, mergedColumns])\n\n const getCurrentSettings = React.useCallback((): PerspectiveSettings => {\n const visibility: Record<string, boolean> = {}\n for (const [key, value] of Object.entries(columnVisibility)) {\n if (typeof key === 'string' && typeof value === 'boolean') {\n visibility[key] = value\n }\n }\n const filtersRecord: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(filterValues ?? {})) {\n if (typeof key === 'string') filtersRecord[key] = value\n }\n const candidate: PerspectiveSettings = {\n columnOrder,\n columnVisibility: visibility,\n sorting,\n filters: filtersRecord,\n searchValue,\n }\n return sanitizePerspectiveSettings(candidate) ?? {}\n }, [columnOrder, columnVisibility, sorting, filterValues, searchValue])\n\n const applyPerspectiveSettings = React.useCallback((settings: PerspectiveSettings, nextId: string | null) => {\n const normalized = sanitizePerspectiveSettings(settings) ?? {}\n if (normalized.columnOrder && normalized.columnOrder.length) {\n setColumnOrder(normalized.columnOrder)\n } else {\n const ids = table.getAllLeafColumns().map((column) => column.id)\n if (ids.length) setColumnOrder(ids)\n }\n if (normalized.columnVisibility) setColumnVisibility(normalized.columnVisibility)\n else setColumnVisibility({})\n if (normalized.sorting) {\n const sortingState: SortingState = normalized.sorting.map((item) => ({\n id: item.id,\n desc: item.desc === true,\n }))\n setSorting(sortingState)\n onSortingChange?.(sortingState)\n } else {\n setSorting([])\n onSortingChange?.([])\n }\n if (onFiltersApply) {\n onFiltersApply((normalized.filters ?? {}) as FilterValues)\n }\n if (onSearchChange) {\n onSearchChange(normalized.searchValue ?? '')\n }\n setActivePerspectiveId(nextId)\n if (perspectiveTableId) {\n writePerspectiveCookie(perspectiveTableId, nextId)\n if (nextId) {\n const snapshot: PerspectiveSnapshot = { perspectiveId: nextId, settings: normalized, updatedAt: Date.now() }\n writePerspectiveSnapshot(perspectiveTableId, snapshot)\n initialSnapshotRef.current = snapshot\n } else {\n writePerspectiveSnapshot(perspectiveTableId, null)\n initialSnapshotRef.current = null\n }\n }\n }, [onFiltersApply, onSearchChange, onSortingChange, perspectiveTableId, table])\n\n React.useLayoutEffect(() => {\n if (!perspectiveTableId) return\n if (snapshotHydratedTableRef.current === perspectiveTableId) return\n snapshotHydratedTableRef.current = perspectiveTableId\n const snapshot = readPerspectiveSnapshot(perspectiveTableId)\n if (!snapshot) return\n initialSnapshotRef.current = snapshot\n applyPerspectiveSettings(snapshot.settings, snapshot.perspectiveId ?? null)\n initialPerspectiveAppliedRef.current = true\n }, [perspectiveTableId, applyPerspectiveSettings])\n\n type SavePerspectivePayload = {\n name: string\n isDefault: boolean\n applyToRoles: string[]\n setRoleDefault: boolean\n perspectiveId?: string | null\n settings?: PerspectiveSettings\n }\n\n const perspectiveQueryKey: [string, string | null] = ['table-perspectives', perspectiveTableId]\n const savePerspectiveMutation = useMutation<PerspectiveSaveResponse, Error, SavePerspectivePayload>({\n mutationFn: async (input) => {\n if (!perspectiveTableId) throw new Error('Missing table id')\n const payload = {\n perspectiveId: input.perspectiveId ?? undefined,\n name: input.name,\n settings: input.settings ?? getCurrentSettings(),\n isDefault: input.isDefault,\n applyToRoles: input.applyToRoles,\n setRoleDefault: input.setRoleDefault,\n }\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.debug('[DataTable] perspective payload', payload)\n }\n const call = await apiCall<PerspectiveSaveResponse>(\n `/api/perspectives/${encodeURIComponent(perspectiveTableId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n },\n )\n if (call.status === 404) {\n throw new Error(t('ui.dataTable.perspectives.error.apiUnavailable', 'Perspectives API is not available. Run `yarn generate` to regenerate module routes and restart the dev server.'))\n }\n if (!call.ok) {\n await raiseCrudError(call.response, t('ui.dataTable.perspectives.error.save', 'Failed to save perspective'))\n }\n const result = call.result\n if (!result) throw new Error(t('ui.dataTable.perspectives.error.save', 'Failed to save perspective'))\n return result\n },\n onSuccess: (data) => {\n if (perspectiveTableId) {\n void queryClient.invalidateQueries({ queryKey: perspectiveQueryKey })\n }\n if (data.perspective) {\n applyPerspectiveSettings(data.perspective.settings, data.perspective.id)\n }\n },\n })\n\n const resolveColumnLabel = React.useCallback((column: TableColumn<T, unknown>): string => {\n const meta = (column.columnDef as any)?.meta\n if (typeof meta?.label === 'string' && meta.label.trim().length > 0) return meta.label.trim()\n if (typeof meta?.title === 'string' && meta.title.trim().length > 0) return meta.title.trim()\n const header = column.columnDef.header\n if (typeof header === 'string') return header\n if (typeof header === 'function') return normalizeLabel(column.id)\n return normalizeLabel(column.id)\n }, [])\n\n const activePersonalPerspectiveId = React.useMemo(() => {\n if (!perspectiveData || !activePerspectiveId) return null\n const found = perspectiveData.perspectives.find((p) => p.id === activePerspectiveId)\n return found ? found.id : null\n }, [perspectiveData, activePerspectiveId])\n\n\n const deletePerspectiveMutation = useMutation<void, Error, { perspectiveId: string }>({\n mutationFn: async ({ perspectiveId }) => {\n if (!perspectiveTableId) throw new Error('Missing table id')\n const call = await apiCall(\n `/api/perspectives/${encodeURIComponent(perspectiveTableId)}/${encodeURIComponent(perspectiveId)}`,\n { method: 'DELETE' },\n )\n if (call.status === 404) throw new Error(t('ui.dataTable.perspectives.error.apiUnavailable', 'Perspectives API is not available. Run `yarn generate` and restart the dev server.'))\n if (!call.ok) {\n await raiseCrudError(call.response, t('ui.dataTable.perspectives.error.delete', 'Failed to delete perspective'))\n }\n },\n onMutate: ({ perspectiveId }) => {\n setDeletingIds((prev) => prev.includes(perspectiveId) ? prev : [...prev, perspectiveId])\n },\n onSettled: (_data, _error, variables) => {\n setDeletingIds((prev) => prev.filter((id) => id !== variables.perspectiveId))\n },\n onSuccess: (_data, variables) => {\n const removedActive = activePerspectiveId === variables.perspectiveId\n if (perspectiveTableId) {\n void queryClient.invalidateQueries({ queryKey: perspectiveQueryKey })\n if (removedActive) {\n setActivePerspectiveId(null)\n writePerspectiveCookie(perspectiveTableId, null)\n writePerspectiveSnapshot(perspectiveTableId, null)\n initialSnapshotRef.current = null\n initialPerspectiveAppliedRef.current = false\n }\n } else if (removedActive) {\n setActivePerspectiveId(null)\n initialPerspectiveAppliedRef.current = false\n }\n },\n })\n\n const clearRoleMutation = useMutation<void, Error, { roleId: string }>({\n mutationFn: async ({ roleId }) => {\n if (!perspectiveTableId) throw new Error('Missing table id')\n const call = await apiCall(\n `/api/perspectives/${encodeURIComponent(perspectiveTableId)}/roles/${encodeURIComponent(roleId)}`,\n { method: 'DELETE' },\n )\n if (call.status === 404) throw new Error(t('ui.dataTable.perspectives.error.apiUnavailable', 'Perspectives API is not available. Run `yarn generate` and restart the dev server.'))\n if (!call.ok) {\n await raiseCrudError(call.response, t('ui.dataTable.perspectives.error.clearRoles', 'Failed to clear role perspectives'))\n }\n },\n onMutate: ({ roleId }) => {\n setRoleClearingIds((prev) => prev.includes(roleId) ? prev : [...prev, roleId])\n },\n onSettled: (_data, _error, variables) => {\n setRoleClearingIds((prev) => prev.filter((id) => id !== variables.roleId))\n },\n onSuccess: (_data, variables) => {\n if (perspectiveTableId) {\n void queryClient.invalidateQueries({ queryKey: perspectiveQueryKey })\n }\n if (activePerspectiveId) {\n const current = queryClient.getQueryData<PerspectivesIndexResponse>(perspectiveQueryKey)\n const match = current?.rolePerspectives.find((rp) => rp.id === activePerspectiveId)\n if (match && match.roleId === variables.roleId) {\n setActivePerspectiveId(null)\n if (perspectiveTableId) writePerspectiveCookie(perspectiveTableId, null)\n if (perspectiveTableId) writePerspectiveSnapshot(perspectiveTableId, null)\n initialSnapshotRef.current = null\n initialPerspectiveAppliedRef.current = false\n }\n }\n },\n })\n\n const handlePerspectiveActivate = React.useCallback((item: PerspectiveDto | RolePerspectiveDto, _source?: 'personal' | 'role') => {\n applyPerspectiveSettings(item.settings, item.id)\n }, [applyPerspectiveSettings])\n\n const handlePerspectiveSave = React.useCallback(async (input: { name: string; isDefault: boolean; applyToRoles: string[]; setRoleDefault: boolean; perspectiveId?: string | null; settings?: PerspectiveSettings }) => {\n const normalizedRoles = Array.from(new Set(input.applyToRoles))\n await savePerspectiveMutation.mutateAsync({\n name: input.name.trim(),\n isDefault: input.isDefault,\n applyToRoles: normalizedRoles,\n setRoleDefault: normalizedRoles.length > 0 ? input.setRoleDefault : false,\n perspectiveId: input.perspectiveId !== undefined ? input.perspectiveId : activePersonalPerspectiveId,\n settings: input.settings,\n })\n }, [savePerspectiveMutation, activePersonalPerspectiveId])\n\n const handlePerspectiveDelete = React.useCallback(async (perspectiveId: string) => {\n await deletePerspectiveMutation.mutateAsync({ perspectiveId })\n }, [deletePerspectiveMutation])\n\n const handleClearRole = React.useCallback(async (roleId: string) => {\n await clearRoleMutation.mutateAsync({ roleId })\n }, [clearRoleMutation])\n\n const handleColumnChooserToggle = React.useCallback((key: string) => {\n const column = table.getColumn(key)\n if (!column) return\n const nextVisible = !column.getIsVisible()\n if (nextVisible) {\n setColumnOrder((prev) => (prev.includes(key) ? prev : [...prev, key]))\n }\n setColumnVisibility((prev) => {\n const next = { ...prev }\n if (nextVisible) delete next[key]\n else next[key] = false\n return next\n })\n column.toggleVisibility(nextVisible)\n }, [table])\n\n const handleColumnChooserReorder = React.useCallback((newOrder: string[]) => {\n setColumnOrder(newOrder)\n table.setColumnOrder(newOrder)\n }, [table])\n\n const dndSensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 5 } }))\n const enableHeaderDnd = Boolean(columnChooser)\n const stableDndContextId = React.useMemo(\n () => sanitizeDndContextId(\n extensionTableId\n ?? perspectiveTableId\n ?? resolvedReplacementHandle\n ?? (typeof title === 'string' && title.trim().length > 0 ? title : 'data-table'),\n ),\n [extensionTableId, perspectiveTableId, resolvedReplacementHandle, title],\n )\n const headerColumnIds = React.useMemo(() => {\n if (!enableHeaderDnd) return []\n return table.getHeaderGroups().flatMap((hg) => hg.headers.map((h) => h.id))\n }, [enableHeaderDnd, table, columnOrder])\n\n const handleHeaderDragEnd = React.useCallback((event: DragEndEvent) => {\n const { active, over } = event\n if (!over || active.id === over.id) return\n const currentIds = columnOrder.length ? columnOrder : table.getAllLeafColumns().map((c) => c.id)\n const oldIdx = currentIds.indexOf(String(active.id))\n const newIdx = currentIds.indexOf(String(over.id))\n if (oldIdx === -1 || newIdx === -1) return\n const next = [...currentIds]\n const [moved] = next.splice(oldIdx, 1)\n next.splice(newIdx, 0, moved)\n setColumnOrder(next)\n table.setColumnOrder(next)\n }, [columnOrder, table])\n\n const perspectiveApiWarning = perspectiveApiMissing && canUsePerspectives\n ? t('ui.dataTable.perspectives.warning.apiUnavailable', 'Perspectives API is not available yet. Run `yarn generate` to regenerate module routes, then restart the server.')\n : null\n\n const loadStartRef = React.useRef<number | null>(null)\n const [measuredDurationMs, setMeasuredDurationMs] = React.useState<number | null>(null)\n\n React.useEffect(() => {\n if (typeof isLoading !== 'boolean') return\n if (isLoading) {\n if (loadStartRef.current === null) {\n const now = typeof performance !== 'undefined' && typeof performance.now === 'function'\n ? performance.now()\n : Date.now()\n loadStartRef.current = now\n }\n return\n }\n if (loadStartRef.current !== null) {\n const now = typeof performance !== 'undefined' && typeof performance.now === 'function'\n ? performance.now()\n : Date.now()\n setMeasuredDurationMs(now - loadStartRef.current)\n loadStartRef.current = null\n }\n }, [isLoading])\n\n React.useLayoutEffect(() => {\n if (!canUsePerspectives) return\n if (!perspectiveTableId) return\n if (initialSnapshotRef.current) return\n if (initialPerspectiveAppliedRef.current && activePerspectiveId != null) return\n\n const source = perspectiveData ?? perspectiveConfig?.initialState?.response\n if (!source) return\n\n const tryResolve = (id: string | null | undefined): PerspectiveDto | RolePerspectiveDto | undefined => {\n if (!id) return undefined\n return source.perspectives.find((p) => p.id === id)\n ?? source.rolePerspectives.find((p) => p.id === id)\n }\n\n let target: PerspectiveDto | RolePerspectiveDto | undefined\n if (activePerspectiveId) {\n target = tryResolve(activePerspectiveId)\n }\n const cookieId = readPerspectiveCookie(perspectiveTableId)\n if (!target && cookieId) target = tryResolve(cookieId)\n if (!target && source.defaultPerspectiveId) {\n target = tryResolve(source.defaultPerspectiveId)\n }\n if (!target) {\n target = source.rolePerspectives.find((p) => p.isDefault)\n }\n if (!target) {\n target = source.perspectives[0]\n }\n if (target) {\n applyPerspectiveSettings(target.settings, target.id)\n }\n initialPerspectiveAppliedRef.current = true\n }, [canUsePerspectives, perspectiveData, perspectiveTableId, perspectiveConfig, applyPerspectiveSettings, activePerspectiveId])\n\n const scrollTableIntoView = React.useCallback(() => {\n const rect = containerRef.current?.getBoundingClientRect()\n if (!rect || rect.top >= 0) return\n const behavior = window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'instant' : 'smooth'\n containerRef.current?.scrollIntoView({ behavior, block: 'start' })\n }, [])\n\n const paginationNode = React.useMemo(() => {\n if (!pagination || pagination.total === 0) return null\n\n const { page, totalPages, onPageChange, durationMs, cacheStatus } = pagination\n const startItem = (page - 1) * pagination.pageSize + 1\n const endItem = Math.min(page * pagination.pageSize, pagination.total)\n const effectiveDuration = (typeof durationMs === 'number' && Number.isFinite(durationMs) && durationMs >= 0)\n ? durationMs\n : measuredDurationMs ?? undefined\n const durationLabel = formatDurationLabel(effectiveDuration)\n const normalizedCacheStatus = cacheStatus === 'hit' || cacheStatus === 'miss' ? cacheStatus : null\n const cacheBadge = normalizedCacheStatus ? (\n <span\n className=\"inline-flex items-center justify-center\"\n aria-label={t('ui.dataTable.pagination.cache.ariaLabel', 'Cache {status}', { status: normalizedCacheStatus.toUpperCase() })}\n title={t('ui.dataTable.pagination.cache.title', 'Cache {status}', { status: normalizedCacheStatus.toUpperCase() })}\n >\n <Circle\n className={`h-3.5 w-3.5 ${normalizedCacheStatus === 'hit' ? 'text-emerald-500' : 'text-amber-500'}`}\n strokeWidth={3}\n />\n <span className=\"sr-only\">{t('ui.dataTable.pagination.cache.srOnly', 'Cache {status}', { status: normalizedCacheStatus.toUpperCase() })}</span>\n </span>\n ) : null\n\n const pageSizeOptions = Array.isArray(pagination.pageSizeOptions)\n ? Array.from(new Set(\n [pagination.pageSize, ...pagination.pageSizeOptions]\n .filter((size): size is number => typeof size === 'number' && Number.isFinite(size) && size > 0)\n .map((size) => Math.max(1, Math.floor(size))),\n )).sort((left, right) => left - right)\n : []\n const pageSizeSelect = pageSizeOptions.length > 0 && pagination.onPageSizeChange ? (\n <span className=\"inline-flex items-center gap-1.5\">\n <select\n className=\"rounded border bg-background pl-2 pr-7 py-0.5 text-sm min-w-[3.5rem]\"\n value={pagination.pageSize}\n onChange={(event) => {\n pagination.onPageSizeChange!(Number(event.target.value))\n scrollTableIntoView()\n }}\n aria-label={t('ui.dataTable.pagination.rowsPerPage', 'Rows per page')}\n >\n {pageSizeOptions.map((size) => (\n <option key={size} value={size}>{size}</option>\n ))}\n </select>\n <span className=\"text-muted-foreground\">{t('ui.dataTable.pagination.perPage', 'per page')}</span>\n </span>\n ) : null\n\n return (\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 px-4 py-3 border-t\">\n <div className=\"text-sm text-muted-foreground flex items-center justify-center sm:justify-start gap-2 flex-wrap\">\n <span>\n {durationLabel\n ? t('ui.dataTable.pagination.resultsWithDuration', 'Showing {start} to {end} of {total} results in {duration}', { start: startItem, end: endItem, total: pagination.total, duration: durationLabel })\n : t('ui.dataTable.pagination.results', 'Showing {start} to {end} of {total} results', { start: startItem, end: endItem, total: pagination.total })\n }\n </span>\n {cacheBadge}\n {pageSizeSelect}\n </div>\n <div className=\"flex items-center justify-center sm:justify-end gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => { onPageChange(page - 1); scrollTableIntoView() }}\n disabled={page <= 1}\n >\n {t('ui.dataTable.pagination.previous', 'Previous')}\n </Button>\n <span className=\"text-sm whitespace-nowrap\">\n {t('ui.dataTable.pagination.pageInfo', 'Page {page} of {totalPages}', { page, totalPages })}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => { onPageChange(page + 1); scrollTableIntoView() }}\n disabled={page >= totalPages}\n >\n {t('ui.dataTable.pagination.next', 'Next')}\n </Button>\n </div>\n </div>\n )\n }, [pagination, measuredDurationMs, scrollTableIntoView, t])\n\n // Auto filters: fetch custom field defs when requested\n const resolvedEntityIds = React.useMemo(() => {\n if (Array.isArray(entityIds) && entityIds.length) {\n const dedup = new Set<string>()\n const list: string[] = []\n entityIds.forEach((id) => {\n const trimmed = typeof id === 'string' ? id.trim() : ''\n if (!trimmed || dedup.has(trimmed)) return\n dedup.add(trimmed)\n list.push(trimmed)\n })\n return list\n }\n if (typeof entityId === 'string' && entityId.trim().length > 0) {\n return [entityId.trim()]\n }\n return []\n }, [entityId, entityIds])\n const entityKey = React.useMemo(() => (resolvedEntityIds.length ? resolvedEntityIds.join('|') : null), [resolvedEntityIds])\n const customFieldFilterExtrasSignature = React.useMemo(\n () => JSON.stringify(customFieldFilterKeyExtras ?? []),\n [customFieldFilterKeyExtras]\n )\n\n const [cfFilterFieldsetsByEntity, setCfFilterFieldsetsByEntity] = React.useState<Record<string, CustomFieldsetDto[]>>({})\n const [cfFilterFieldsetSelection, setCfFilterFieldsetSelection] = React.useState<Record<string, string | null>>({})\n\n React.useEffect(() => {\n if (!entityKey) {\n setCfFilterFieldsetsByEntity({})\n setCfFilterFieldsetSelection({})\n return\n }\n let cancelled = false\n const loadFieldsets = async () => {\n try {\n const payload = await fetchCustomFieldDefinitionsPayload(resolvedEntityIds)\n if (cancelled) return\n const fieldsets = payload.fieldsetsByEntity ?? {}\n setCfFilterFieldsetsByEntity(fieldsets)\n const selectionChanges: Array<[string, string | null]> = []\n let shouldNotify = false\n setCfFilterFieldsetSelection((prev) => {\n const next: Record<string, string | null> = {}\n let changed = false\n resolvedEntityIds.forEach((entityId) => {\n const list = fieldsets[entityId] ?? []\n if (!list.length) {\n if (prev[entityId] !== undefined) changed = true\n return\n }\n const existing = prev[entityId]\n const fallback = list[0]?.code ?? null\n const isValidExisting = existing ? list.some((entry) => entry.code === existing) : false\n const value = isValidExisting ? existing : fallback ?? null\n next[entityId] = value\n if (value !== existing) {\n changed = true\n selectionChanges.push([entityId, value])\n }\n })\n if (Object.keys(prev).length !== Object.keys(next).length) changed = true\n if (changed) {\n shouldNotify = true\n return next\n }\n return prev\n })\n if (shouldNotify && selectionChanges.length && onCustomFieldFilterFieldsetChange) {\n selectionChanges.forEach(([entityId, value]) => onCustomFieldFilterFieldsetChange(value, entityId))\n }\n } catch {\n if (!cancelled) {\n setCfFilterFieldsetsByEntity({})\n setCfFilterFieldsetSelection({})\n }\n }\n }\n loadFieldsets()\n return () => {\n cancelled = true\n }\n }, [customFieldFilterExtrasSignature, entityKey, onCustomFieldFilterFieldsetChange, resolvedEntityIds])\n\n const supportsCustomFieldFilterFieldsets =\n resolvedEntityIds.length === 1 &&\n (cfFilterFieldsetsByEntity[resolvedEntityIds[0]]?.length ?? 0) > 0\n const activeCustomFieldFilterFieldset = supportsCustomFieldFilterFieldsets\n ? cfFilterFieldsetSelection[resolvedEntityIds[0]] ?? cfFilterFieldsetsByEntity[resolvedEntityIds[0]]?.[0]?.code ?? null\n : null\n\n const handleCustomFieldFilterFieldsetChange = React.useCallback(\n (value: string) => {\n if (!supportsCustomFieldFilterFieldsets) return\n const entityId = resolvedEntityIds[0]\n const nextValue = value || null\n setCfFilterFieldsetSelection((prev) => {\n if (prev[entityId] === nextValue) return prev\n return { ...prev, [entityId]: nextValue }\n })\n if (onCustomFieldFilterFieldsetChange) {\n onCustomFieldFilterFieldsetChange(nextValue, entityId)\n }\n },\n [onCustomFieldFilterFieldsetChange, resolvedEntityIds, supportsCustomFieldFilterFieldsets],\n )\n\n const { data: cfFilters = [] } = useCustomFieldFilterDefs(entityKey ? resolvedEntityIds : [], {\n enabled: !!entityKey,\n fieldset: supportsCustomFieldFilterFieldsets ? activeCustomFieldFilterFieldset ?? undefined : undefined,\n keyExtras: customFieldFilterKeyExtras,\n })\n\n const isAutoAdvancedFilter = Boolean(advancedFilter?.auto)\n const isAutoColumnChooser = Boolean(columnChooser?.auto)\n const needsAutoDiscovery = isAutoAdvancedFilter || isAutoColumnChooser\n const { data: autoDiscoveryDefs = [] } = useCustomFieldDefs(\n needsAutoDiscovery && entityKey ? resolvedEntityIds : [],\n { enabled: needsAutoDiscovery && !!entityKey },\n )\n const autoDiscovered = useAutoDiscoveredFields({\n columns: needsAutoDiscovery ? mergedColumns : [],\n customFieldDefs: needsAutoDiscovery ? autoDiscoveryDefs : [],\n })\n const resolvedAdvancedFilterFields = isAutoAdvancedFilter\n ? autoDiscovered.advancedFilterFields\n : advancedFilter?.fields ?? []\n const resolvedColumnChooserFields = isAutoColumnChooser\n ? autoDiscovered.columnChooserFields\n : columnChooser?.availableColumns ?? []\n\n const effectiveColumnChooserFields = React.useMemo<ColumnChooserField[]>(() => {\n if (resolvedColumnChooserFields.length > 0) return resolvedColumnChooserFields\n return table.getAllLeafColumns().map((col) => ({\n key: col.id,\n label: resolveColumnLabel(col),\n group: 'Columns',\n alwaysVisible: !col.getCanHide(),\n }))\n }, [resolvedColumnChooserFields, table, resolveColumnLabel, columns])\n\n const visibleColumnKeys = React.useMemo(\n () => table.getAllLeafColumns().filter((c) => c.getIsVisible()).map((c) => c.id),\n [table, columnVisibility, columns],\n )\n\n const selectedRows = React.useMemo<T[]>(() => {\n if (!hasInjectedBulkActions) return []\n return table.getSelectedRowModel().rows.map((row) => row.original as T)\n }, [hasInjectedBulkActions, table, rowSelection])\n const trackedBulkProgressJobIdsRef = React.useRef(new Set<string>())\n\n const clearTrackedBulkProgressJob = React.useCallback((jobId: string | null): boolean => {\n if (!jobId) return false\n return trackedBulkProgressJobIdsRef.current.delete(jobId)\n }, [])\n\n const refreshAfterBulkProgressCompletion = React.useCallback(() => {\n if (refreshButton?.onRefresh) {\n refreshButton.onRefresh()\n return\n }\n scheduleRouterRefresh(router)\n }, [refreshButton, router])\n\n useAppEvent(\n 'progress.job.completed',\n (event) => {\n const payload = event.payload as { jobId?: unknown } | null | undefined\n const jobId = typeof payload?.jobId === 'string' ? payload.jobId : null\n if (!clearTrackedBulkProgressJob(jobId)) return\n refreshAfterBulkProgressCompletion()\n },\n [clearTrackedBulkProgressJob, refreshAfterBulkProgressCompletion],\n )\n\n useAppEvent(\n 'progress.job.failed',\n (event) => {\n const payload = event.payload as { jobId?: unknown } | null | undefined\n const jobId = typeof payload?.jobId === 'string' ? payload.jobId : null\n clearTrackedBulkProgressJob(jobId)\n },\n [clearTrackedBulkProgressJob],\n )\n\n useAppEvent(\n 'progress.job.cancelled',\n (event) => {\n const payload = event.payload as { jobId?: unknown } | null | undefined\n const jobId = typeof payload?.jobId === 'string' ? payload.jobId : null\n clearTrackedBulkProgressJob(jobId)\n },\n [clearTrackedBulkProgressJob],\n )\n\n const runBulkAction = React.useCallback(\n async (action: InjectionBulkActionDefinition) => {\n if (action.requiresSelection !== false && !selectedRows.length) return\n try {\n const result = await action.onExecute(selectedRows, {\n tableId: extensionTableId,\n navigate: (href: string) => router.push(href),\n confirm,\n refresh: refreshButton?.onRefresh,\n injectionContext: resolvedInjectionContext,\n translate: t,\n })\n const normalized = result as BulkActionExecuteResult | void\n if (normalized && normalized.ok === false) {\n if (normalized.message === undefined) return\n flash(\n normalized.message\n ?? t('ui.dataTable.bulkAction.error', 'Bulk action failed.'),\n 'error',\n )\n return\n }\n if (normalized?.progressJobId) {\n trackedBulkProgressJobIdsRef.current.add(normalized.progressJobId)\n setRowSelection({})\n flash(\n normalized.message\n ?? t('ui.dataTable.bulkAction.started', 'Bulk action started. Track progress in the top bar.'),\n 'success',\n )\n return\n }\n flash(\n normalized?.message\n ?? t('ui.dataTable.bulkAction.success', 'Bulk action completed.'),\n 'success',\n )\n setRowSelection({})\n if (refreshButton?.onRefresh) {\n refreshButton.onRefresh()\n } else {\n scheduleRouterRefresh(router)\n }\n } catch (error) {\n flash(\n error instanceof Error\n ? error.message\n : t('ui.dataTable.bulkAction.error', 'Bulk action failed.'),\n 'error',\n )\n }\n },\n [confirm, extensionTableId, refreshButton, resolvedInjectionContext, router, selectedRows, t],\n )\n\n const runPropBulkAction = React.useCallback(\n async (action: BulkAction<T>) => {\n const result = await action.onExecute(selectedRows)\n if (result !== false) {\n setRowSelection({})\n }\n },\n [selectedRows],\n )\n\n const builtToolbar = React.useMemo(() => {\n if (toolbar) return toolbar\n const anySearch = onSearchChange != null\n const anyFilters = (baseFilters && baseFilters.length > 0) || (cfFilters && cfFilters.length > 0) || injectedFilters.length > 0\n const hasBulkButtons = hasInjectedBulkActions || hasPropBulkActions\n if (!anySearch && !anyFilters && !hasBulkButtons) return null\n // Merge base filters with CF filters, preferring base definitions when ids collide\n const baseList = baseFilters || []\n const existing = new Set(baseList.map((f) => f.id))\n const cfOnly = (cfFilters || []).filter((f) => !existing.has(f.id))\n const injectedOnly = injectedFilters.filter((f) => !existing.has(f.id) && !cfOnly.some((cf) => cf.id === f.id))\n const combined: FilterDef[] = [...baseList, ...cfOnly, ...injectedOnly]\n const perspectiveButton = canUsePerspectives ? (\n <ViewSwitcherDropdown\n activePerspectiveId={activePerspectiveId}\n perspectives={perspectiveData?.perspectives ?? []}\n rolePerspectives={perspectiveData?.rolePerspectives ?? []}\n onClear={() => applyPerspectiveSettings({}, null)}\n onActivate={handlePerspectiveActivate}\n onOpenSidebar={() => setPerspectiveOpen(true)}\n t={t}\n />\n ) : null\n const fieldsetSelector =\n supportsCustomFieldFilterFieldsets && resolvedEntityIds.length === 1\n ? (\n <div className=\"space-y-1\">\n <div className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {t('ui.dataTable.fieldset.label', 'Fieldset')}\n </div>\n <select\n className=\"w-full rounded border bg-background px-2 py-2 text-sm\"\n value={activeCustomFieldFilterFieldset ?? ''}\n onChange={(event) => handleCustomFieldFilterFieldsetChange(event.target.value)}\n >\n {(cfFilterFieldsetsByEntity[resolvedEntityIds[0]] ?? []).map((fieldset) => (\n <option key={fieldset.code} value={fieldset.code}>\n {fieldset.label}\n </option>\n ))}\n </select>\n </div>\n )\n : null\n const leadingItems = perspectiveButton ? <div className=\"flex items-center gap-2\">{perspectiveButton}</div> : null\n const trailingItems = hasBulkButtons ? (\n <div className=\"flex flex-wrap items-center gap-2\">\n {selectedRows.length > 0 ? (\n <span className=\"text-sm text-muted-foreground\">\n {t('ui.dataTable.bulkAction.selectedCount', '{count} selected', { count: selectedRows.length })}\n </span>\n ) : null}\n {injectedBulkActions.map((action) => {\n const label = t(action.label, action.label)\n const iconNode = resolveInjectedIcon(action.icon, 'h-4 w-4 shrink-0')\n return (\n <Button\n key={action.id}\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n title={label}\n aria-label={label}\n className={iconNode ? 'px-2 sm:px-3' : undefined}\n disabled={action.requiresSelection !== false && selectedRows.length === 0}\n onClick={() => void runBulkAction(action)}\n >\n {iconNode}\n <span className={iconNode ? 'hidden sm:inline' : undefined}>{label}</span>\n </Button>\n )\n })}\n {selectedRows.length > 0 ? (bulkActionsProp ?? []).map((action) => {\n const ActionIcon = action.icon\n return (\n <Button\n key={action.id}\n type=\"button\"\n size=\"sm\"\n variant={action.destructive ? 'destructive' : 'outline'}\n onClick={() => void runPropBulkAction(action)}\n >\n {ActionIcon ? <ActionIcon className=\"h-4 w-4 shrink-0\" /> : null}\n <span>{action.label}</span>\n </Button>\n )\n }) : null}\n </div>\n ) : null\n return (\n <FilterBar\n searchValue={searchValue}\n onSearchChange={onSearchChange}\n searchPlaceholder={searchPlaceholder}\n searchAlign={searchAlign}\n filters={combined}\n values={filterValues}\n onApply={onFiltersApply}\n onClear={onFiltersClear}\n leadingItems={leadingItems}\n trailingItems={trailingItems}\n filtersExtraContent={fieldsetSelector}\n layout={embedded ? 'inline' : 'stacked'}\n className={embedded ? 'min-h-[2.25rem]' : undefined}\n />\n )\n }, [\n toolbar,\n searchValue,\n onSearchChange,\n searchPlaceholder,\n searchAlign,\n baseFilters,\n cfFilters,\n injectedFilters,\n filterValues,\n onFiltersApply,\n onFiltersClear,\n canUsePerspectives,\n embedded,\n supportsCustomFieldFilterFieldsets,\n resolvedEntityIds,\n activeCustomFieldFilterFieldset,\n handleCustomFieldFilterFieldsetChange,\n cfFilterFieldsetsByEntity,\n hasInjectedBulkActions,\n hasPropBulkActions,\n injectedBulkActions,\n bulkActionsProp,\n selectedRows.length,\n selectedRows,\n runBulkAction,\n runPropBulkAction,\n ])\n\n const hasTitle = title != null\n const hasActions = actions !== undefined && actions !== null && actions !== false\n const shouldReserveActionsSpace = actions === null || actions === false\n const exportConfig = exporter === false ? null : exporter || null\n const resolvedExportSections = React.useMemo(() => resolveExportSections(exportConfig), [exportConfig])\n const hasExport = resolvedExportSections.length > 0\n const refreshButtonConfig = refreshButton\n const hasRefreshButton = Boolean(refreshButtonConfig)\n const hasToolbar = builtToolbar != null\n const hasToolbarInjection = Boolean(toolbarInjectionSpotId)\n const shouldRenderActionsWrapper = hasActions || hasRefreshButton || shouldReserveActionsSpace || hasExport || hasToolbarInjection || Boolean(advancedFilter)\n const renderToolbarInline = embedded && hasToolbar\n const shouldRenderToolbarBelow = hasToolbar && !renderToolbarInline\n const shouldRenderHeader = hasTitle || renderToolbarInline || shouldRenderActionsWrapper || shouldRenderToolbarBelow\n const containerClassName = embedded ? '' : 'rounded-lg border bg-card mx-1 sm:mx-2'\n const headerWrapperClassName = embedded ? 'pb-3' : 'px-4 py-3 border-b'\n const headerContentClassName = 'flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between'\n const toolbarWrapperClassName = embedded ? 'mt-2' : 'mt-3 pt-3 border-t'\n const tableScrollWrapperClassName = embedded ? '' : 'overflow-auto'\n\n const virtualScrollRef = React.useRef<HTMLDivElement>(null)\n const allRows = table.getRowModel().rows\n const rowVirtualizer = virtualized\n ? useVirtualizer({\n count: allRows.length,\n getScrollElement: () => virtualScrollRef.current,\n estimateSize: () => 48,\n overscan: virtualizedOverscan,\n })\n : null\n const virtualMaxHeightStyle: React.CSSProperties | undefined = virtualized\n ? {\n maxHeight: typeof virtualizedMaxHeight === 'number'\n ? `${virtualizedMaxHeight}px`\n : virtualizedMaxHeight ?? 'calc(100vh - 300px)',\n overflow: 'auto',\n }\n : undefined\n\n const titleContent = hasTitle ? (\n <div className=\"text-base font-semibold leading-tight min-h-[2.25rem] flex items-center\">\n {typeof title === 'string' ? <h2 className=\"text-base font-semibold\">{title}</h2> : title}\n </div>\n ) : <div className=\"min-h-[2.25rem]\" />\n\n return (\n <TooltipProvider delayDuration={300}>\n <div ref={containerRef} className={containerClassName} data-component-handle={resolvedReplacementHandle}>\n {shouldRenderHeader && (\n <div className={headerWrapperClassName}>\n {(hasTitle || shouldRenderActionsWrapper || renderToolbarInline) && (\n <div className={headerContentClassName}>\n <div className=\"flex-1 min-w-0\">\n {renderToolbarInline ? builtToolbar : titleContent}\n </div>\n {shouldRenderActionsWrapper ? (\n <div className=\"flex flex-wrap items-center gap-2 min-h-[2.25rem]\">\n {refreshButtonConfig ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={refreshButtonConfig.onRefresh}\n aria-label={refreshButtonConfig.label}\n title={refreshButtonConfig.label}\n disabled={refreshButtonConfig.disabled || refreshButtonConfig.isRefreshing}\n >\n {refreshButtonConfig.isRefreshing ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <RefreshCw className=\"h-4 w-4\" />\n )}\n <span className=\"sr-only\">{refreshButtonConfig.label}</span>\n </Button>\n ) : null}\n {advancedFilter ? (\n <Button\n type=\"button\"\n variant={advancedFilter.value.conditions.length > 0 ? 'secondary' : 'ghost'}\n size=\"icon\"\n onClick={() => {\n const opening = !isAdvancedFilterOpen\n if (opening && advancedFilter.value.conditions.length === 0) {\n const newCondition = createEmptyCondition()\n if (resolvedAdvancedFilterFields.length > 0) {\n newCondition.field = resolvedAdvancedFilterFields[0].key\n newCondition.operator = getDefaultOperator(resolvedAdvancedFilterFields[0].type)\n }\n advancedFilter.onChange({ ...advancedFilter.value, conditions: [newCondition] })\n }\n setAdvancedFilterOpen(opening)\n }}\n aria-label={t('ui.advancedFilter.toggle', 'Advanced filters')}\n title={t('ui.advancedFilter.toggle', 'Advanced filters')}\n >\n <Filter className=\"h-4 w-4\" />\n {advancedFilter.value.conditions.length > 0 ? (\n <span className=\"absolute -top-1 -right-1 flex h-4 w-4 items-center justify-center rounded-full bg-primary text-[10px] text-primary-foreground\">\n {advancedFilter.value.conditions.length}\n </span>\n ) : null}\n </Button>\n ) : null}\n {canUsePerspectives ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setPerspectiveOpen(true)}\n aria-label={t('ui.dataTable.customizeColumns.ariaLabel', 'Customize columns')}\n title={t('ui.dataTable.customizeColumns.title', 'Customize columns')}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">{t('ui.dataTable.customizeColumns.srOnly', 'Customize columns')}</span>\n </Button>\n ) : null}\n {exportConfig && hasExport ? <ExportMenu config={exportConfig} sections={resolvedExportSections} /> : null}\n {toolbarInjectionSpotId ? (\n <InjectionSpot spotId={toolbarInjectionSpotId} context={resolvedInjectionContext} />\n ) : null}\n {hasActions ? actions : null}\n </div>\n ) : null}\n </div>\n )}\n {shouldRenderToolbarBelow ? <div className={toolbarWrapperClassName}>{builtToolbar}</div> : null}\n {headerInjectionSpotId ? (\n <div className={embedded ? 'mt-2' : 'mt-3'}>\n <InjectionSpot spotId={headerInjectionSpotId} context={resolvedInjectionContext} />\n </div>\n ) : null}\n </div>\n )}\n {advancedFilter && isAdvancedFilterOpen ? (\n <div className=\"border-b\">\n <AdvancedFilterBuilder\n fields={resolvedAdvancedFilterFields}\n value={advancedFilter.value}\n onChange={advancedFilter.onChange}\n onApply={() => { advancedFilter.onApply(); setAdvancedFilterOpen(false) }}\n onClear={() => { advancedFilter.onClear(); setAdvancedFilterOpen(false) }}\n />\n </div>\n ) : null}\n {advancedFilter && advancedFilter.value.conditions.length > 0 && !isAdvancedFilterOpen ? (\n <div className=\"flex items-center gap-2 flex-wrap px-4 py-2 border-b text-sm\">\n <span className=\"text-muted-foreground\">\n {t('ui.advancedFilter.activeCount', '{count} active filters', { count: advancedFilter.value.conditions.length })}\n </span>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"h-auto px-1 py-0.5 text-xs\" onClick={() => setAdvancedFilterOpen(true)}>\n {t('ui.advancedFilter.edit', 'Edit')}\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"h-auto px-1 py-0.5 text-xs text-muted-foreground\" onClick={advancedFilter.onClear}>\n {t('ui.advancedFilter.clearAll', 'Clear all')}\n </Button>\n </div>\n ) : null}\n <HeaderDndWrapper\n enabled={enableHeaderDnd}\n contextId={`${stableDndContextId}-headers`}\n sensors={dndSensors}\n columnIds={headerColumnIds}\n onDragEnd={handleHeaderDragEnd}\n >\n <div ref={virtualized ? virtualScrollRef : undefined} className={tableScrollWrapperClassName} style={virtualMaxHeightStyle}>\n <Table className=\"min-w-[640px] md:min-w-0\">\n <TableHeader>\n {table.getHeaderGroups().map((hg) => (\n <TableRow key={hg.id}>\n {hasInjectedBulkActions ? (\n <TableHead className=\"w-8\">\n <Checkbox\n checked={table.getIsAllPageRowsSelected()}\n onCheckedChange={(checked) => {\n table.toggleAllPageRowsSelected(Boolean(checked))\n }}\n aria-label={t('ui.dataTable.bulkAction.selectAll', 'Select all rows')}\n />\n </TableHead>\n ) : null}\n {hg.headers.map((header, headerIndex) => {\n const columnMeta = (header.column.columnDef as any)?.meta\n const priority = resolvePriority(header.column)\n const isFirstDataColumn = headerIndex === 0\n const stickyClass = stickyFirstColumn && isFirstDataColumn ? ' sticky left-0 z-10 bg-background' : ''\n const headerCellContent = header.isPlaceholder ? null : (\n <Button\n variant=\"ghost\"\n type=\"button\"\n className={`h-auto p-0 font-medium ${sortable && header.column.getCanSort?.() ? 'cursor-pointer select-none' : ''}`}\n onClick={() => sortable && header.column.toggleSorting?.(header.column.getIsSorted() === 'asc')}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {sortable && header.column.getCanSort?.() ? (\n <span className=\"ml-1 inline-flex flex-col text-[10px] leading-none gap-px\">\n <span className={header.column.getIsSorted() === 'asc' ? 'text-foreground' : 'text-muted-foreground/40'}>\u25B2</span>\n <span className={header.column.getIsSorted() === 'desc' ? 'text-foreground' : 'text-muted-foreground/40'}>\u25BC</span>\n </span>\n ) : null}\n </Button>\n )\n return enableHeaderDnd ? (\n <SortableHeaderCell key={header.id} id={header.id} className={responsiveClass(priority, columnMeta?.hidden) + stickyClass}>\n {headerCellContent}\n </SortableHeaderCell>\n ) : (\n <TableHead key={header.id} className={responsiveClass(priority, columnMeta?.hidden) + stickyClass}>\n {headerCellContent}\n </TableHead>\n )\n })}\n {rowActions || injectedRowActions.length > 0 ? (\n <TableHead\n className={cn(\n 'w-0 text-right',\n stickyActionsColumn && 'sticky right-0 z-20 bg-background',\n )}\n >\n {t('ui.dataTable.actionsColumn', 'Actions')}\n </TableHead>\n ) : null}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {isLoading ? (\n <TableRow>\n <TableCell colSpan={mergedColumns.length + (rowActions || injectedRowActions.length > 0 ? 1 : 0) + (hasInjectedBulkActions ? 1 : 0)} className=\"h-24 text-center\">\n <div className=\"flex items-center justify-center gap-2\">\n <Spinner size=\"md\" />\n <span className=\"text-muted-foreground\">{t('ui.dataTable.loading', 'Loading data...')}</span>\n </div>\n </TableCell>\n </TableRow>\n ) : error ? (\n <TableRow>\n <TableCell colSpan={mergedColumns.length + (rowActions || injectedRowActions.length > 0 ? 1 : 0) + (hasInjectedBulkActions ? 1 : 0)} className=\"h-24 text-center text-destructive\">\n {error}\n </TableCell>\n </TableRow>\n ) : allRows.length ? (\n <>\n {virtualized && rowVirtualizer ? (\n <>\n {rowVirtualizer.getVirtualItems()[0]?.start > 0 ? (\n <tr style={{ height: `${rowVirtualizer.getVirtualItems()[0].start}px` }} />\n ) : null}\n </>\n ) : null}\n {(virtualized && rowVirtualizer\n ? rowVirtualizer.getVirtualItems().map((vi) => allRows[vi.index])\n : allRows\n ).map((row) => {\n const rowActionsElement = resolvedRowActions(row.original as T)\n const defaultRowAction = onRowClick ? null : pickDefaultRowAction(rowActionsElement, resolvedRowClickActionIds)\n const isClickable = !disableRowClick && (onRowClick || defaultRowAction)\n \n return (\n <TableRow \n key={row.id} \n data-state={row.getIsSelected() && 'selected'}\n className={isClickable ? 'cursor-pointer hover:bg-muted/50 transition-colors' : ''}\n onClick={isClickable ? (e) => {\n // Don't trigger row click if clicking on actions cell\n if ((e.target as HTMLElement).closest('[data-actions-cell]')) {\n return\n }\n \n if (onRowClick) {\n onRowClick(row.original as T)\n } else if (defaultRowAction) {\n if (defaultRowAction.href) {\n router.push(defaultRowAction.href)\n } else if (defaultRowAction.onSelect) {\n defaultRowAction.onSelect()\n }\n }\n } : undefined}\n >\n {hasInjectedBulkActions ? (\n <TableCell className=\"w-8\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(checked) => row.toggleSelected(Boolean(checked))}\n aria-label={t('ui.dataTable.bulkAction.selectRow', 'Select row')}\n onClick={(event) => event.stopPropagation()}\n />\n </TableCell>\n ) : null}\n {row.getVisibleCells().map((cell, cellIndex) => {\n const columnMeta = (cell.column.columnDef as any)?.meta\n const priority = resolvePriority(cell.column)\n const isStickyCell = stickyFirstColumn && cellIndex === 0\n const hasCustomCell = Boolean(cell.column.columnDef.cell)\n const columnId = String((cell.column as any).id || '')\n const accessorKey = String((cell.column.columnDef as any)?.accessorKey || '')\n const isDateCol = dateColumnIds ? dateColumnIds.has(columnId) : false\n\n let content: React.ReactNode\n if (isDateCol) {\n const raw = cell.getValue() as any\n const d = tryParseDate(raw)\n content = d ? simpleFormat(d, DATE_FORMAT) : (raw as any)\n } else {\n content = flexRender(cell.column.columnDef.cell, cell.getContext())\n }\n\n // Get truncation configuration for this column\n const skipTruncation = shouldSkipTruncation(columnId)\n // Get truncation configuration for this column\n const truncateConfig = getColumnTruncateConfig(columnId, accessorKey, columnMeta)\n const shouldTruncate = truncateConfig.truncate && !skipTruncation\n const maxWidth = truncateConfig.maxWidth\n\n // Wrap content with TruncatedCell if truncation is enabled\n // Get raw cell value for tooltip - flexRender returns React elements\n // that cannot have their text extracted, so we pass the raw value directly\n // Check for custom tooltip content function in column meta for complex cells\n const cellValue = cell.getValue()\n const metaTooltipContent = columnMeta?.tooltipContent as ((row: unknown) => string | undefined) | undefined\n let tooltipText: string | undefined\n if (metaTooltipContent) {\n tooltipText = metaTooltipContent(row.original)\n } else if (isDateCol && cellValue != null) {\n const parsedDate = tryParseDate(cellValue)\n tooltipText = parsedDate ? simpleFormat(parsedDate, DATE_FORMAT) : String(cellValue)\n } else {\n tooltipText = cellValue != null ? String(cellValue) : undefined\n }\n\n const wrappedContent = shouldTruncate ? (\n <TruncatedCell maxWidth={maxWidth} tooltipContent={tooltipText}>\n {content}\n </TruncatedCell>\n ) : content\n\n return (\n <TableCell key={cell.id} className={responsiveClass(priority, columnMeta?.hidden) + (isStickyCell ? ' sticky left-0 z-10 bg-background' : '')}>\n {wrappedContent}\n </TableCell>\n )\n })}\n {rowActions || injectedRowActions.length > 0 ? (\n <TableCell\n className={cn(\n 'text-right whitespace-nowrap',\n stickyActionsColumn && 'sticky right-0 z-10 bg-background',\n )}\n data-actions-cell\n >\n {rowActionsElement}\n </TableCell>\n ) : null}\n </TableRow>\n )\n })}\n {virtualized && rowVirtualizer ? (() => {\n const virtualItems = rowVirtualizer.getVirtualItems()\n const lastItem = virtualItems[virtualItems.length - 1]\n const bottomPadding = lastItem ? rowVirtualizer.getTotalSize() - lastItem.end : 0\n return bottomPadding > 0 ? <tr style={{ height: `${bottomPadding}px` }} /> : null\n })() : null}\n </>\n ) : (\n <TableRow>\n <TableCell colSpan={mergedColumns.length + (rowActions || injectedRowActions.length > 0 ? 1 : 0) + (hasInjectedBulkActions ? 1 : 0)} className=\"h-24 text-center text-muted-foreground\">\n {emptyState ?? t('ui.dataTable.emptyState.default', 'No results.')}\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n </HeaderDndWrapper>\n {footerInjectionSpotId ? (\n <div className={embedded ? 'mt-3' : 'px-4 py-3 border-t'}>\n <InjectionSpot spotId={footerInjectionSpotId} context={resolvedInjectionContext} />\n </div>\n ) : null}\n {paginationNode}\n {ConfirmDialogElement}\n {canUsePerspectives ? (\n <PerspectiveSidebar\n open={isPerspectiveOpen}\n onOpenChange={setPerspectiveOpen}\n loading={perspectiveQuery.isFetching && !perspectiveQuery.data}\n perspectives={perspectiveData?.perspectives ?? []}\n rolePerspectives={perspectiveData?.rolePerspectives ?? []}\n roles={perspectiveData?.roles ?? []}\n activePerspectiveId={activePerspectiveId}\n onActivatePerspective={handlePerspectiveActivate}\n onDeletePerspective={handlePerspectiveDelete}\n onClearRole={handleClearRole}\n onSave={handlePerspectiveSave}\n canApplyToRoles={Boolean(perspectiveData?.canApplyToRoles && canUseRoleDefaultsFeature)}\n availableColumns={effectiveColumnChooserFields}\n visibleColumnKeys={visibleColumnKeys}\n columnOrder={columnOrder}\n onToggleColumn={handleColumnChooserToggle}\n onReorderColumns={handleColumnChooserReorder}\n saving={savePerspectiveMutation.isPending}\n deletingIds={deletingIds}\n roleClearingIds={roleClearingIds}\n apiWarning={perspectiveApiWarning}\n />\n ) : null}\n </div>\n </TooltipProvider>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["data", "d", "entityId", "error"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/ui",
|
|
3
|
-
"version": "0.5.1-develop.
|
|
3
|
+
"version": "0.5.1-develop.2802.9223828f7f",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -132,12 +132,12 @@
|
|
|
132
132
|
"recharts": "^3.8.1"
|
|
133
133
|
},
|
|
134
134
|
"peerDependencies": {
|
|
135
|
-
"@open-mercato/shared": "0.5.1-develop.
|
|
135
|
+
"@open-mercato/shared": "0.5.1-develop.2802.9223828f7f",
|
|
136
136
|
"react": ">=18.0.0",
|
|
137
137
|
"react-dom": ">=18.0.0"
|
|
138
138
|
},
|
|
139
139
|
"devDependencies": {
|
|
140
|
-
"@open-mercato/shared": "0.5.1-develop.
|
|
140
|
+
"@open-mercato/shared": "0.5.1-develop.2802.9223828f7f",
|
|
141
141
|
"@testing-library/dom": "^10.4.1",
|
|
142
142
|
"@testing-library/jest-dom": "^6.9.1",
|
|
143
143
|
"@testing-library/react": "^16.3.1",
|
|
@@ -204,6 +204,7 @@ export type DataTableProps<T> = {
|
|
|
204
204
|
rowClickActionIds?: string[]
|
|
205
205
|
disableRowClick?: boolean
|
|
206
206
|
bulkActions?: BulkAction<T>[]
|
|
207
|
+
selectionScopeKey?: string
|
|
207
208
|
|
|
208
209
|
// Auto FilterBar options (rendered as toolbar when provided and no custom toolbar passed)
|
|
209
210
|
searchValue?: string
|
|
@@ -861,6 +862,7 @@ export function DataTable<T>({
|
|
|
861
862
|
rowClickActionIds,
|
|
862
863
|
disableRowClick = false,
|
|
863
864
|
bulkActions: bulkActionsProp,
|
|
865
|
+
selectionScopeKey,
|
|
864
866
|
searchValue,
|
|
865
867
|
onSearchChange,
|
|
866
868
|
searchPlaceholder,
|
|
@@ -1289,6 +1291,7 @@ export function DataTable<T>({
|
|
|
1289
1291
|
const hasPropBulkActions = Array.isArray(bulkActionsProp) && bulkActionsProp.length > 0
|
|
1290
1292
|
const hasInjectedBulkActions = injectedBulkActions.length > 0 || hasPropBulkActions
|
|
1291
1293
|
const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({})
|
|
1294
|
+
const selectionScopeKeyRef = React.useRef<string | undefined>(selectionScopeKey)
|
|
1292
1295
|
const table = useReactTable<T>({
|
|
1293
1296
|
data: clientFilteredData,
|
|
1294
1297
|
columns: mergedColumns,
|
|
@@ -1313,6 +1316,19 @@ export function DataTable<T>({
|
|
|
1313
1316
|
onRowSelectionChange: setRowSelection,
|
|
1314
1317
|
})
|
|
1315
1318
|
React.useEffect(() => { if (sortingProp) setSorting(sortingProp) }, [sortingProp])
|
|
1319
|
+
React.useEffect(() => {
|
|
1320
|
+
if (selectionScopeKey === undefined) {
|
|
1321
|
+
selectionScopeKeyRef.current = undefined
|
|
1322
|
+
return
|
|
1323
|
+
}
|
|
1324
|
+
if (selectionScopeKeyRef.current === undefined) {
|
|
1325
|
+
selectionScopeKeyRef.current = selectionScopeKey
|
|
1326
|
+
return
|
|
1327
|
+
}
|
|
1328
|
+
if (selectionScopeKeyRef.current === selectionScopeKey) return
|
|
1329
|
+
selectionScopeKeyRef.current = selectionScopeKey
|
|
1330
|
+
setRowSelection({})
|
|
1331
|
+
}, [selectionScopeKey])
|
|
1316
1332
|
React.useEffect(() => {
|
|
1317
1333
|
if (hasInjectedBulkActions) return
|
|
1318
1334
|
if (Object.keys(rowSelection).length === 0) return
|
|
@@ -41,19 +41,21 @@ class ResizeObserverMock {
|
|
|
41
41
|
|
|
42
42
|
function renderTable(elementProps: Record<string, unknown>) {
|
|
43
43
|
const queryClient = new QueryClient({ defaultOptions: { queries: { gcTime: 0 } } })
|
|
44
|
-
const
|
|
44
|
+
const renderElement = (props: Record<string, unknown>) => React.createElement(
|
|
45
|
+
QueryClientProvider as any,
|
|
46
|
+
{ client: queryClient },
|
|
45
47
|
React.createElement(
|
|
46
|
-
|
|
47
|
-
{
|
|
48
|
-
React.createElement(
|
|
49
|
-
I18nProvider as any,
|
|
50
|
-
{ locale: 'en', dict: {} },
|
|
51
|
-
React.createElement(DataTable as any, elementProps),
|
|
52
|
-
),
|
|
48
|
+
I18nProvider as any,
|
|
49
|
+
{ locale: 'en', dict: {} },
|
|
50
|
+
React.createElement(DataTable as any, props),
|
|
53
51
|
),
|
|
54
52
|
)
|
|
53
|
+
const view = render(
|
|
54
|
+
renderElement(elementProps),
|
|
55
|
+
)
|
|
55
56
|
return {
|
|
56
57
|
...view,
|
|
58
|
+
rerenderTable: (nextProps: Record<string, unknown>) => view.rerender(renderElement(nextProps)),
|
|
57
59
|
cleanupQueryClient: () => queryClient.clear(),
|
|
58
60
|
}
|
|
59
61
|
}
|
|
@@ -315,6 +317,57 @@ describe('DataTable extensions', () => {
|
|
|
315
317
|
}
|
|
316
318
|
})
|
|
317
319
|
|
|
320
|
+
it('clears selection when selectionScopeKey changes', async () => {
|
|
321
|
+
const rendered = renderTable({
|
|
322
|
+
columns: [{ accessorKey: 'name', header: 'Name' }],
|
|
323
|
+
data: [{ id: 'r1', name: 'Alice' }],
|
|
324
|
+
bulkActions: [{ id: 'bulk', label: 'Bulk', onExecute: jest.fn() }],
|
|
325
|
+
selectionScopeKey: 'scope-1',
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
try {
|
|
329
|
+
fireEvent.click(screen.getByRole('checkbox', { name: 'Select all rows' }))
|
|
330
|
+
|
|
331
|
+
await waitFor(() => expect(screen.getByText('1 selected')).toBeInTheDocument())
|
|
332
|
+
|
|
333
|
+
rendered.rerenderTable({
|
|
334
|
+
columns: [{ accessorKey: 'name', header: 'Name' }],
|
|
335
|
+
data: [{ id: 'r1', name: 'Alice' }],
|
|
336
|
+
bulkActions: [{ id: 'bulk', label: 'Bulk', onExecute: jest.fn() }],
|
|
337
|
+
selectionScopeKey: 'scope-2',
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
await waitFor(() => expect(screen.queryByText('1 selected')).not.toBeInTheDocument())
|
|
341
|
+
} finally {
|
|
342
|
+
rendered.cleanupQueryClient()
|
|
343
|
+
}
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
it('keeps selection unchanged when selectionScopeKey is omitted', async () => {
|
|
347
|
+
const rendered = renderTable({
|
|
348
|
+
columns: [{ accessorKey: 'name', header: 'Name' }],
|
|
349
|
+
data: [{ id: 'r1', name: 'Alice' }],
|
|
350
|
+
bulkActions: [{ id: 'bulk', label: 'Bulk', onExecute: jest.fn() }],
|
|
351
|
+
})
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
fireEvent.click(screen.getByRole('checkbox', { name: 'Select all rows' }))
|
|
355
|
+
|
|
356
|
+
await waitFor(() => expect(screen.getByText('1 selected')).toBeInTheDocument())
|
|
357
|
+
|
|
358
|
+
rendered.rerenderTable({
|
|
359
|
+
columns: [{ accessorKey: 'name', header: 'Name' }],
|
|
360
|
+
data: [{ id: 'r1', name: 'Alice' }],
|
|
361
|
+
bulkActions: [{ id: 'bulk', label: 'Bulk', onExecute: jest.fn() }],
|
|
362
|
+
title: 'Messages',
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
await waitFor(() => expect(screen.getByText('1 selected')).toBeInTheDocument())
|
|
366
|
+
} finally {
|
|
367
|
+
rendered.cleanupQueryClient()
|
|
368
|
+
}
|
|
369
|
+
})
|
|
370
|
+
|
|
318
371
|
it('applies sticky positioning to the actions column when enabled', () => {
|
|
319
372
|
const rendered = renderTable({
|
|
320
373
|
columns: [{ accessorKey: 'name', header: 'Name' }],
|