@alfadocs/ui-kit-debug 1.9.2 → 1.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/_chunks/{actions-cell-renderer-B2pw6iH8.js → actions-cell-renderer-WUTyAes8.js} +374 -363
  2. package/dist/_chunks/actions-cell-renderer-WUTyAes8.js.map +1 -0
  3. package/dist/_chunks/{patient-table-6XnaWimB.js → balance-badge-cell-DHTiSFyD.js} +283 -271
  4. package/dist/_chunks/balance-badge-cell-DHTiSFyD.js.map +1 -0
  5. package/dist/_chunks/editable-currency-cell-renderer-zLf_bXvL.js +412 -0
  6. package/dist/_chunks/editable-currency-cell-renderer-zLf_bXvL.js.map +1 -0
  7. package/dist/_chunks/{file-manager-Crg5dKez.js → file-manager-lAeBBfZi.js} +2 -2
  8. package/dist/_chunks/{file-manager-Crg5dKez.js.map → file-manager-lAeBBfZi.js.map} +1 -1
  9. package/dist/_chunks/{link-cell-renderer-BqO66pIA.js → link-cell-renderer-Cp2MSlJl.js} +235 -257
  10. package/dist/_chunks/link-cell-renderer-Cp2MSlJl.js.map +1 -0
  11. package/dist/agent-catalog.json +1 -1
  12. package/dist/components/data-table/cell-renderers/image-cell-renderer.d.ts.map +1 -1
  13. package/dist/components/data-table/index.js +11 -11
  14. package/dist/components/data-table/toolbar.d.ts.map +1 -1
  15. package/dist/components/file-manager/index.js +1 -1
  16. package/dist/components/patient-table/cell-renderers/transaction-chip-cell.d.ts +17 -0
  17. package/dist/components/patient-table/cell-renderers/transaction-chip-cell.d.ts.map +1 -0
  18. package/dist/components/patient-table/columns.d.ts.map +1 -1
  19. package/dist/components/patient-table/index.d.ts +2 -0
  20. package/dist/components/patient-table/index.d.ts.map +1 -1
  21. package/dist/components/patient-table/index.js +7 -6
  22. package/dist/index.js +335 -334
  23. package/dist/tokens.css +2 -2
  24. package/package.json +1 -1
  25. package/dist/_chunks/actions-cell-renderer-B2pw6iH8.js.map +0 -1
  26. package/dist/_chunks/editable-currency-cell-renderer-DYdzKpjL.js +0 -390
  27. package/dist/_chunks/editable-currency-cell-renderer-DYdzKpjL.js.map +0 -1
  28. package/dist/_chunks/link-cell-renderer-BqO66pIA.js.map +0 -1
  29. package/dist/_chunks/patient-table-6XnaWimB.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"file-manager-Crg5dKez.js","sources":["../../node_modules/lucide-react/dist/esm/icons/file-headphone.mjs","../../node_modules/lucide-react/dist/esm/icons/file-play.mjs","../../node_modules/lucide-react/dist/esm/icons/folder-input.mjs","../../node_modules/lucide-react/dist/esm/icons/folder-open.mjs","../../node_modules/lucide-react/dist/esm/icons/folder-plus.mjs","../../node_modules/lucide-react/dist/esm/icons/folder.mjs","../../src/components/file-manager/file-manager.agent.ts","../../src/components/file-manager/utils.ts","../../src/components/file-manager/folder-tree.tsx","../../src/components/file-manager/dialogs.tsx","../../src/components/file-manager/list-view.tsx","../../src/components/file-manager/toolbar.tsx","../../src/components/file-manager/file-manager.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M4 6.835V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2h-.343\",\n key: \"1vfytu\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\n \"path\",\n {\n d: \"M2 19a2 2 0 0 1 4 0v1a2 2 0 0 1-4 0v-4a6 6 0 0 1 12 0v4a2 2 0 0 1-4 0v-1a2 2 0 0 1 4 0\",\n key: \"1etmh7\"\n }\n ]\n];\nconst FileHeadphone = createLucideIcon(\"file-headphone\", __iconNode);\n\nexport { __iconNode, FileHeadphone as default };\n//# sourceMappingURL=file-headphone.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\",\n key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\n \"path\",\n {\n d: \"M15.033 13.44a.647.647 0 0 1 0 1.12l-4.065 2.352a.645.645 0 0 1-.968-.56v-4.704a.645.645 0 0 1 .967-.56z\",\n key: \"1tzo1f\"\n }\n ]\n];\nconst FilePlay = createLucideIcon(\"file-play\", __iconNode);\n\nexport { __iconNode, FilePlay as default };\n//# sourceMappingURL=file-play.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2 9V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-1\",\n key: \"fm4g5t\"\n }\n ],\n [\"path\", { d: \"M2 13h10\", key: \"pgb2dq\" }],\n [\"path\", { d: \"m9 16 3-3-3-3\", key: \"6m91ic\" }]\n];\nconst FolderInput = createLucideIcon(\"folder-input\", __iconNode);\n\nexport { __iconNode, FolderInput as default };\n//# sourceMappingURL=folder-input.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2\",\n key: \"usdka0\"\n }\n ]\n];\nconst FolderOpen = createLucideIcon(\"folder-open\", __iconNode);\n\nexport { __iconNode, FolderOpen as default };\n//# sourceMappingURL=folder-open.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 10v6\", key: \"1bos4e\" }],\n [\"path\", { d: \"M9 13h6\", key: \"1uhe8q\" }],\n [\n \"path\",\n {\n d: \"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z\",\n key: \"1kt360\"\n }\n ]\n];\nconst FolderPlus = createLucideIcon(\"folder-plus\", __iconNode);\n\nexport { __iconNode, FolderPlus as default };\n//# sourceMappingURL=folder-plus.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z\",\n key: \"1kt360\"\n }\n ]\n];\nconst Folder = createLucideIcon(\"folder\", __iconNode);\n\nexport { __iconNode, Folder as default };\n//# sourceMappingURL=folder.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — FileManager. */\n/* */\n/* PHI rule (PRS §26 §6): item display names are patient-identifiable */\n/* document titles. No always-on state slot ever returns a name — the */\n/* structural `items` snapshot carries ids/kinds/sizes/dates only. The */\n/* single name-returning read is the deliberate `get_item_names` action */\n/* with `safety: 'phi'`, so the host gates it behind confirm + audit. */\n/* */\n/* Mutations (upload/rename/move/delete) resolve through host callbacks */\n/* + confirmation dialogs and are NOT exposed as agent actions — the */\n/* adapter surface is view state, selection, navigation and reads. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { FileManagerHandle } from './types';\n\nconst ITEM_META_SCHEMA = {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n kind: { enum: ['file', 'folder'] },\n parentId: {\n type: ['string', 'null'],\n description: 'Parent folder id, null at the root.',\n },\n size: { type: 'number', description: 'Bytes — files only.' },\n updatedAt: { type: 'string', description: 'ISO 8601 timestamp.' },\n documentType: {\n type: 'string',\n description: 'Document-type category (non-identifying).',\n },\n signatureStatus: {\n enum: ['none', 'pending', 'signed'],\n description: 'Signature workflow state.',\n },\n },\n required: ['id', 'kind', 'parentId'],\n },\n} as const;\n\nexport const fileManagerAgent: AgentAdapter<FileManagerHandle> = {\n id: 'file-manager',\n // select_multiple → select_items / clear_selection; navigate → navigate;\n // filter → set_type_filter (proxied to the DataTable's documentType column);\n // open → open_item. Preview is NOT an agent action — item content can be PHI.\n capabilities: ['select_multiple', 'navigate', 'filter', 'open'],\n state: {\n selection: {\n type: 'string[]',\n descriptionKey: 'ui.agent.fileManager.state.selection',\n description: 'Item ids of the currently-selected files and folders.',\n read: (handle) => handle.getSelection(),\n },\n currentFolder: {\n type: 'string | null',\n descriptionKey: 'ui.agent.fileManager.state.currentFolder',\n description: 'Id of the folder being viewed, or null for the root.',\n read: (handle) => handle.getCurrentFolderId(),\n },\n typeFilter: {\n type: 'string[]',\n descriptionKey: 'ui.agent.fileManager.state.typeFilter',\n description:\n 'Active document-type filter applied to the open folder (empty = no filter).',\n read: (handle) => handle.getTypeFilter(),\n },\n items: {\n type: 'Array<{ id, kind, parentId, size, updatedAt, documentType, signatureStatus }>',\n descriptionKey: 'ui.agent.fileManager.state.items',\n description:\n 'Structural metadata for every item — ids, kinds, sizes, dates, document types, signature states. Names are PHI and never included; read them via get_item_names.',\n read: (handle) => handle.getItems(),\n },\n activeAction: {\n type: \"'none' | 'create-folder' | 'rename' | 'delete' | 'move'\",\n descriptionKey: 'ui.agent.fileManager.state.activeAction',\n description:\n 'The single in-flight action dialog. Only one action can be active at a time.',\n read: (handle) => handle.getActiveAction(),\n },\n },\n actions: {\n select_items: {\n // Transient view selection (data-table convention) — stays read.\n safety: 'read',\n argsType: '{ ids: string[] }',\n argsSchema: {\n type: 'object',\n properties: {\n ids: {\n type: 'array',\n items: { type: 'string' },\n description: 'Item ids to select (replaces the current selection).',\n },\n },\n required: ['ids'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.fileManager.actions.selectItems',\n description: 'Replace the current selection with the given item ids.',\n examples: [\n { args: { ids: ['doc-1', 'doc-2'] }, note: 'Select two items.' },\n ],\n invoke: (handle, args: { ids: string[] }) => {\n handle.setSelection(args.ids);\n },\n },\n clear_selection: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.fileManager.actions.clearSelection',\n description: 'Deselect every item.',\n invoke: (handle) => {\n handle.clearSelection();\n },\n },\n navigate: {\n safety: 'read',\n argsType: '{ folderId: string | null }',\n argsSchema: {\n type: 'object',\n properties: {\n folderId: {\n type: ['string', 'null'],\n description: 'Folder id to open, or null for the root.',\n },\n },\n required: ['folderId'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.fileManager.actions.navigate',\n description:\n 'Open the given folder (null for the root). Clears the current selection.',\n invoke: (handle, args: { folderId: string | null }) => {\n handle.navigateTo(args.folderId);\n },\n },\n set_type_filter: {\n safety: 'read',\n argsType: '{ documentTypes: string[] }',\n argsSchema: {\n type: 'object',\n properties: {\n documentTypes: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Document-type values to keep. Empty array clears the filter.',\n },\n },\n required: ['documentTypes'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.fileManager.actions.setTypeFilter',\n description:\n 'Filter the open folder to the given document types (empty clears the filter).',\n invoke: (handle, args: { documentTypes: string[] }) => {\n handle.setTypeFilter(args.documentTypes);\n },\n },\n open_item: {\n safety: 'read',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'Item id — folders navigate, files open via the host.',\n },\n },\n required: ['id'],\n },\n // Opening a file resolves through the host's onOpenFile callback,\n // which may reach a viewer outside this UI.\n openWorld: true,\n descriptionKey: 'ui.agent.fileManager.actions.openItem',\n description:\n 'Open an item: folders navigate into the folder, files resolve through the host preview callback.',\n invoke: (handle, args: { id: string }) => {\n handle.openItem(args.id);\n },\n },\n list_items: {\n safety: 'read',\n argsType: '{ folderId?: string | null }',\n argsSchema: {\n type: 'object',\n properties: {\n folderId: {\n type: ['string', 'null'],\n description:\n 'Folder whose children to list (null = root). Omit for every item.',\n },\n },\n },\n returns: 'Array<{ id, kind, parentId, size, updatedAt }>',\n returnsSchema: ITEM_META_SCHEMA as unknown as Record<string, unknown>,\n idempotent: true,\n descriptionKey: 'ui.agent.fileManager.actions.listItems',\n description:\n 'List structural metadata (ids, kinds, sizes, dates — never names) for a folder or the whole tree.',\n invoke: (handle, args: { folderId?: string | null }) =>\n handle.getItems(args?.folderId),\n },\n get_item_names: {\n // phi (not read): resolves display names, which can identify patients\n // (e.g. \"Rossi Maria — referto 2026.pdf\"). PRS §26 — phi outranks read\n // so the host gates it behind stricter confirm + audit. The always-on\n // items snapshot stays name-free.\n safety: 'phi',\n argsType: '{ ids: string[] }',\n argsSchema: {\n type: 'object',\n properties: {\n ids: {\n type: 'array',\n items: { type: 'string' },\n description: 'Item ids whose display names to read.',\n },\n },\n required: ['ids'],\n },\n returns: 'Array<{ id: string; name: string }>',\n returnsSchema: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n name: { type: 'string' },\n },\n required: ['id', 'name'],\n },\n },\n idempotent: true,\n descriptionKey: 'ui.agent.fileManager.actions.getItemNames',\n description:\n 'Read the display names for the given item ids. Names may identify patients (PHI).',\n invoke: (handle, args: { ids: string[] }) =>\n handle.getItemNames(args.ids),\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'file-manager',\n description: 'Marks the FileManager region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n item: {\n attr: 'data-item-id',\n description:\n 'Grid cards and folder-tree nodes carry the item id as data-item-id (ids only — never names). List-view rows are AG Grid rows inside the composed DataTable and carry its native row-id attribute keyed to the same ids.',\n },\n },\n};\n","/* -------------------------------------------------------------------- */\n/* FileManager — pure helpers (no React). */\n/* -------------------------------------------------------------------- */\n\nimport {\n File as FileIcon,\n FileArchive,\n FileHeadphone,\n FileImage,\n FileSpreadsheet,\n FileText,\n FilePlay,\n Folder,\n type LucideIcon,\n} from 'lucide-react';\nimport type { FileManagerItem } from './types';\n\nconst UNIT_KEYS = [\n 'fileManager.units.bytes',\n 'fileManager.units.kilobytes',\n 'fileManager.units.megabytes',\n 'fileManager.units.gigabytes',\n] as const;\n\nconst UNIT_FALLBACKS = ['B', 'KB', 'MB', 'GB'] as const;\n\nexport function formatFileSize(\n bytes: number,\n locale: string,\n t: (key: string, fallback: string) => string,\n): string {\n let value = bytes;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < UNIT_FALLBACKS.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n const formatted = new Intl.NumberFormat(locale, {\n maximumFractionDigits: unitIndex === 0 ? 0 : 1,\n }).format(value);\n return `${formatted} ${t(UNIT_KEYS[unitIndex], UNIT_FALLBACKS[unitIndex])}`;\n}\n\n/** Icon component per item — folders first, then a MIME-family lookup. */\nexport function getItemIcon(item: FileManagerItem): LucideIcon {\n if (item.kind === 'folder') return Folder;\n const mime = item.mimeType ?? '';\n if (mime.startsWith('image/')) return FileImage;\n if (mime.startsWith('audio/')) return FileHeadphone;\n if (mime.startsWith('video/')) return FilePlay;\n if (\n mime === 'application/pdf' ||\n mime.startsWith('text/') ||\n mime.includes('word') ||\n mime.includes('rtf')\n ) {\n return FileText;\n }\n if (\n mime.includes('zip') ||\n mime.includes('compressed') ||\n mime.includes('tar')\n ) {\n return FileArchive;\n }\n if (\n mime.includes('spreadsheet') ||\n mime.includes('excel') ||\n mime === 'text/csv'\n ) {\n return FileSpreadsheet;\n }\n return FileIcon;\n}\n\n/** Children of a folder, folders first, then locale-aware by name. */\nexport function childrenOf(\n items: FileManagerItem[],\n folderId: string | null,\n locale: string,\n): FileManagerItem[] {\n const collator = new Intl.Collator(locale, {\n numeric: true,\n sensitivity: 'base',\n });\n return items\n .filter((i) => i.parentId === folderId)\n .sort((a, b) => {\n if (a.kind !== b.kind) return a.kind === 'folder' ? -1 : 1;\n return collator.compare(a.name, b.name);\n });\n}\n\n/**\n * Every item whose ancestry passes through `folderId` (folders + files, any\n * depth) — the full subtree beneath a folder, excluding the folder itself.\n * Feeds AG Grid Tree Data when `groupByFolder` is on (the flat `childrenOf`\n * only returns the immediate level). Sort order matches `childrenOf` — folders\n * first, then locale-aware by name — so sibling order is stable at every depth.\n */\nexport function descendantsOf(\n items: FileManagerItem[],\n folderId: string | null,\n locale: string,\n): FileManagerItem[] {\n const includedIds = new Set<string>();\n // Seed with the current folder's direct children.\n for (const item of items) {\n if (item.parentId === folderId) includedIds.add(item.id);\n }\n // Expand transitively: any item whose parent is already in the subtree joins.\n let grew = true;\n while (grew) {\n grew = false;\n for (const item of items) {\n if (includedIds.has(item.id)) continue;\n if (item.parentId !== null && includedIds.has(item.parentId)) {\n includedIds.add(item.id);\n grew = true;\n }\n }\n }\n const collator = new Intl.Collator(locale, {\n numeric: true,\n sensitivity: 'base',\n });\n return items\n .filter((i) => includedIds.has(i.id))\n .sort((a, b) => {\n if (a.kind !== b.kind) return a.kind === 'folder' ? -1 : 1;\n return collator.compare(a.name, b.name);\n });\n}\n\n/**\n * AG Grid Tree Data path for an item: the id-chain from the current folder's\n * direct child down to (and including) the item. Walk `parentId` up, stopping\n * at `currentFolderId` (exclusive), then reverse and append the item's own id.\n * Every returned id is a real folder/file row, so AG Grid never synthesises\n * filler group rows. `itemsById` need only cover the current subtree.\n */\nexport function pathWithinFolder(\n item: FileManagerItem,\n itemsById: Map<string, FileManagerItem>,\n currentFolderId: string | null,\n): string[] {\n const path: string[] = [];\n let cursor: FileManagerItem | undefined = item;\n const seen = new Set<string>();\n while (cursor && !seen.has(cursor.id)) {\n seen.add(cursor.id);\n path.unshift(cursor.id);\n if (cursor.parentId === currentFolderId) break;\n cursor =\n cursor.parentId === null ? undefined : itemsById.get(cursor.parentId);\n }\n return path;\n}\n\n/** Path from the root down to `folderId` (exclusive of the virtual root). */\nexport function pathTo(\n items: FileManagerItem[],\n folderId: string | null,\n): FileManagerItem[] {\n const byId = new Map(items.map((i) => [i.id, i]));\n const path: FileManagerItem[] = [];\n let cursor = folderId === null ? undefined : byId.get(folderId);\n const seen = new Set<string>();\n while (cursor && !seen.has(cursor.id)) {\n seen.add(cursor.id);\n path.unshift(cursor);\n cursor = cursor.parentId === null ? undefined : byId.get(cursor.parentId);\n }\n return path;\n}\n\n/**\n * Ids of the given folders plus every folder nested inside them. Used to\n * exclude invalid targets from the move-destination tree (a folder can never\n * be moved into itself or one of its descendants).\n */\nexport function withDescendantFolderIds(\n items: FileManagerItem[],\n ids: string[],\n): Set<string> {\n const excluded = new Set(ids);\n let grew = true;\n while (grew) {\n grew = false;\n for (const item of items) {\n if (\n item.kind === 'folder' &&\n !excluded.has(item.id) &&\n item.parentId !== null &&\n excluded.has(item.parentId)\n ) {\n excluded.add(item.id);\n grew = true;\n }\n }\n }\n return excluded;\n}\n\n/** True when the two id lists contain the same set of ids. */\nexport function sameIdSet(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n const set = new Set(a);\n return b.every((id) => set.has(id));\n}\n","/* -------------------------------------------------------------------- */\n/* FileManager — folder tree (internal). */\n/* */\n/* WAI-ARIA tree: nested `role=\"group\"` lists under a `role=\"tree\"` */\n/* root, roving tabindex, Arrow/Home/End/Enter keyboard handling scoped */\n/* to the tree element. Reused by the move dialog as a destination */\n/* picker (`excludeIds` removes invalid targets). */\n/* -------------------------------------------------------------------- */\n\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ChevronRight, Folder, FolderOpen } from 'lucide-react';\nimport type { FileManagerItem } from './types';\nimport { childrenOf } from './utils';\n\n/** Key used for the virtual root node (`folderId === null`). */\nconst ROOT_KEY = '__root__';\n\nconst keyOf = (folderId: string | null): string => folderId ?? ROOT_KEY;\n\nconst treeItemRowVariants = cva(\n [\n 'ds:flex ds:items-center ds:gap-[var(--spacing-xs)]',\n 'ds:min-h-[var(--min-target-size)] ds:w-full',\n 'ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:text-[length:var(--font-size-sm)]',\n 'ds:cursor-pointer ds:select-none',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n selected: {\n true: 'ds:bg-primary/10 ds:text-primary ds:font-medium',\n false: 'ds:text-foreground ds:hover:bg-muted/10',\n },\n },\n defaultVariants: { selected: false },\n },\n);\n\ninterface TreeNode {\n key: string;\n folderId: string | null;\n item?: FileManagerItem;\n children: TreeNode[];\n}\n\nexport interface FolderTreeProps {\n items: FileManagerItem[];\n /** Folder highlighted as selected — `null` selects the virtual root. */\n selectedFolderId: string | null;\n onSelectFolder: (folderId: string | null) => void;\n 'aria-label': string;\n /** Folder ids to omit from the tree (move dialog: item + descendants). */\n excludeIds?: Set<string>;\n}\n\nfunction buildTree(\n items: FileManagerItem[],\n locale: string,\n excludeIds?: Set<string>,\n): TreeNode {\n const build = (folderId: string | null): TreeNode[] =>\n childrenOf(items, folderId, locale)\n .filter((i) => i.kind === 'folder' && !excludeIds?.has(i.id))\n .map((item) => ({\n key: keyOf(item.id),\n folderId: item.id,\n item,\n children: build(item.id),\n }));\n return { key: ROOT_KEY, folderId: null, children: build(null) };\n}\n\nfunction flattenVisible(root: TreeNode, expanded: Set<string>): TreeNode[] {\n const out: TreeNode[] = [];\n const walk = (node: TreeNode) => {\n out.push(node);\n if (expanded.has(node.key)) node.children.forEach(walk);\n };\n walk(root);\n return out;\n}\n\nfunction parentKeyOf(node: TreeNode): string | null {\n if (node.folderId === null) return null;\n return keyOf(node.item?.parentId ?? null);\n}\n\nexport function FolderTree({\n items,\n selectedFolderId,\n onSelectFolder,\n 'aria-label': ariaLabel,\n excludeIds,\n}: FolderTreeProps) {\n const { t, i18n } = useTranslation();\n const isRtl = i18n.dir() === 'rtl';\n\n const root = useMemo(\n () => buildTree(items, i18n.language, excludeIds),\n [items, i18n.language, excludeIds],\n );\n\n const [expanded, setExpanded] = useState<Set<string>>(\n () => new Set([ROOT_KEY]),\n );\n const [focusedKey, setFocusedKey] = useState<string>(keyOf(selectedFolderId));\n const itemRefs = useRef<Map<string, HTMLLIElement>>(new Map());\n\n // Reveal the selected folder: expand every ancestor when it changes.\n useEffect(() => {\n setExpanded((prev) => {\n const next = new Set(prev);\n next.add(ROOT_KEY);\n const byId = new Map(items.map((i) => [i.id, i]));\n let cursor = selectedFolderId ? byId.get(selectedFolderId) : undefined;\n const seen = new Set<string>();\n while (cursor && !seen.has(cursor.id)) {\n seen.add(cursor.id);\n if (cursor.parentId !== null) next.add(keyOf(cursor.parentId));\n cursor =\n cursor.parentId === null ? undefined : byId.get(cursor.parentId);\n }\n return next;\n });\n setFocusedKey(keyOf(selectedFolderId));\n }, [selectedFolderId, items]);\n\n const visible = useMemo(\n () => flattenVisible(root, expanded),\n [root, expanded],\n );\n\n // Keep the roving-tabindex target valid when folders disappear.\n useEffect(() => {\n if (!visible.some((n) => n.key === focusedKey)) {\n setFocusedKey(visible[0]?.key ?? ROOT_KEY);\n }\n }, [visible, focusedKey]);\n\n const focusNode = (key: string) => {\n setFocusedKey(key);\n itemRefs.current.get(key)?.focus();\n };\n\n const toggleExpanded = (key: string, force?: boolean) => {\n setExpanded((prev) => {\n const next = new Set(prev);\n const open = force ?? !next.has(key);\n if (open) next.add(key);\n else next.delete(key);\n return next;\n });\n };\n\n const handleTreeKeyDown = (event: KeyboardEvent<HTMLUListElement>) => {\n const target = (event.target as HTMLElement).closest<HTMLElement>(\n '[data-tree-key]',\n );\n const key = target?.getAttribute('data-tree-key');\n if (!key) return;\n const index = visible.findIndex((n) => n.key === key);\n if (index < 0) return;\n const node = visible[index];\n const hasChildren = node.children.length > 0;\n const isExpanded = expanded.has(key);\n\n // Logical expand/collapse keys — flipped in RTL.\n const expandKey = isRtl ? 'ArrowLeft' : 'ArrowRight';\n const collapseKey = isRtl ? 'ArrowRight' : 'ArrowLeft';\n\n switch (event.key) {\n case 'ArrowDown':\n if (index < visible.length - 1) focusNode(visible[index + 1].key);\n break;\n case 'ArrowUp':\n if (index > 0) focusNode(visible[index - 1].key);\n break;\n case expandKey:\n if (hasChildren && !isExpanded) toggleExpanded(key, true);\n else if (hasChildren && isExpanded) focusNode(node.children[0].key);\n break;\n case collapseKey: {\n if (hasChildren && isExpanded) {\n toggleExpanded(key, false);\n } else {\n const parentKey = parentKeyOf(node);\n if (parentKey !== null) focusNode(parentKey);\n }\n break;\n }\n case 'Home':\n focusNode(visible[0].key);\n break;\n case 'End':\n focusNode(visible[visible.length - 1].key);\n break;\n case 'Enter':\n case ' ':\n onSelectFolder(node.folderId);\n break;\n default:\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n };\n\n const renderNode = (node: TreeNode): ReactElement => {\n const isSelected = keyOf(selectedFolderId) === node.key;\n const isExpanded = expanded.has(node.key);\n const hasChildren = node.children.length > 0;\n const label =\n node.folderId === null\n ? t('fileManager.rootLabel', 'All files')\n : (node.item?.name ?? '');\n const IconComponent = isExpanded && hasChildren ? FolderOpen : Folder;\n\n const handleRowClick = (event: MouseEvent<HTMLLIElement>) => {\n event.stopPropagation();\n setFocusedKey(node.key);\n onSelectFolder(node.folderId);\n if (hasChildren) toggleExpanded(node.key, true);\n };\n\n const handleChevronClick = (event: MouseEvent<HTMLSpanElement>) => {\n event.stopPropagation();\n toggleExpanded(node.key);\n };\n\n return (\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events -- treeitem row; keyboard operation is handled at the role=\"tree\" container via roving tabindex + onKeyDown\n <li\n key={node.key}\n ref={(el) => {\n if (el) itemRefs.current.set(node.key, el);\n else itemRefs.current.delete(node.key);\n }}\n role=\"treeitem\"\n aria-expanded={hasChildren ? isExpanded : undefined}\n aria-selected={isSelected}\n tabIndex={focusedKey === node.key ? 0 : -1}\n data-tree-key={node.key}\n data-item-id={node.folderId ?? undefined}\n onClick={handleRowClick}\n onFocus={() => setFocusedKey(node.key)}\n className={[\n 'ds:list-none ds:rounded-[var(--radius-md)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n ].join(' ')}\n >\n <div className={treeItemRowVariants({ selected: isSelected })}>\n {hasChildren ? (\n <span\n aria-hidden=\"true\"\n onClick={handleChevronClick}\n className=\"ds:inline-flex ds:size-5 ds:shrink-0 ds:items-center ds:justify-center ds:text-muted-foreground\"\n >\n <ChevronRight\n className={[\n 'ds:size-4',\n 'ds:transition-transform ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n isExpanded ? 'ds:rotate-90' : 'ds:rtl:rotate-180',\n ].join(' ')}\n />\n </span>\n ) : (\n <span aria-hidden=\"true\" className=\"ds:size-5 ds:shrink-0\" />\n )}\n <IconComponent\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0 ds:text-muted-foreground\"\n />\n <span className=\"ds:truncate ds:text-start\">{label}</span>\n </div>\n {hasChildren && isExpanded && (\n <ul\n role=\"group\"\n className=\"ds:m-0 ds:list-none ds:p-0 ds:ps-[var(--spacing-md)]\"\n >\n {node.children.map(renderNode)}\n </ul>\n )}\n </li>\n );\n };\n\n return (\n <ul\n role=\"tree\"\n aria-label={ariaLabel}\n onKeyDown={handleTreeKeyDown}\n className=\"ds:m-0 ds:flex ds:flex-col ds:gap-px ds:list-none ds:p-0\"\n data-testid=\"file-manager-tree\"\n >\n {renderNode(root)}\n </ul>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* FileManager — action dialogs (internal). */\n/* */\n/* One dialog per action of the single-active-action state machine. */\n/* Each is fully controlled by the parent (`open` mirrors the active */\n/* action) and resolves through a submit callback — no local mutation. */\n/* -------------------------------------------------------------------- */\n\nimport { useEffect, useId, useState, type FormEvent } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Button } from '../button';\nimport { Dialog } from '../dialog';\nimport { FileUpload } from '../file-upload';\nimport { TextInput } from '../text-input';\nimport { FolderTree } from './folder-tree';\nimport type { FileManagerItem, FileManagerUploadConfig } from './types';\nimport { withDescendantFolderIds } from './utils';\n\n/* Characters the platform rejects in document / folder names. Stripped on\n input so an invalid name can never be submitted, and the 128-char cap\n matches the platform name column — both guard data integrity without a\n locale string (the full inline-rename flow is tracked separately). */\nconst FORBIDDEN_NAME_CHARS = /[\\\\/:*?\"<>|]/g;\nconst NAME_MAX_LENGTH = 128;\n\nfunction sanitizeName(value: string): string {\n return value.replace(FORBIDDEN_NAME_CHARS, '').slice(0, NAME_MAX_LENGTH);\n}\n\n/* ------------------------------------------------------------------ */\n/* Create folder */\n/* ------------------------------------------------------------------ */\n\nexport interface CreateFolderDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSubmit: (name: string) => void;\n}\n\nexport function CreateFolderDialog({\n open,\n onOpenChange,\n onSubmit,\n}: CreateFolderDialogProps) {\n const { t } = useTranslation();\n const inputId = useId();\n const [name, setName] = useState('');\n\n useEffect(() => {\n if (open) setName('');\n }, [open]);\n\n const handleSubmit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const trimmed = name.trim();\n if (trimmed.length === 0) return;\n onSubmit(trimmed);\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content size=\"sm\">\n <Dialog.Header>\n <Dialog.Title>\n {t('fileManager.dialogs.createFolder.title', 'New folder')}\n </Dialog.Title>\n </Dialog.Header>\n <form onSubmit={handleSubmit}>\n <Dialog.Body>\n <label\n htmlFor={inputId}\n className=\"type-label ds:block ds:mb-[var(--spacing-xs)]\"\n >\n {t('fileManager.dialogs.createFolder.nameLabel', 'Folder name')}\n </label>\n <TextInput\n id={inputId}\n value={name}\n maxLength={NAME_MAX_LENGTH}\n onChange={(event) => setName(sanitizeName(event.target.value))}\n // eslint-disable-next-line jsx-a11y/no-autofocus -- intentional: focus the name field when the dialog opens\n autoFocus\n />\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button type=\"button\" intent=\"outline\">\n {t('fileManager.dialogs.createFolder.cancel', 'Cancel')}\n </Button>\n </Dialog.Close>\n <Button\n type=\"submit\"\n intent=\"primary\"\n disabled={name.trim().length === 0}\n >\n {t('fileManager.dialogs.createFolder.confirm', 'Create folder')}\n </Button>\n </Dialog.Footer>\n </form>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Upload (per-file queue via the kit FileUpload) */\n/* ------------------------------------------------------------------ */\n\nexport interface UploadDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Bound to the destination folder by the parent. */\n onUpload: (\n file: File,\n helpers: { signal: AbortSignal; onProgress: (percent: number) => void },\n ) => Promise<void>;\n /** Human-readable destination folder name (root label when at the root). */\n destinationLabel: string;\n config?: FileManagerUploadConfig;\n}\n\nexport function UploadDialog({\n open,\n onOpenChange,\n onUpload,\n destinationLabel,\n config,\n}: UploadDialogProps) {\n const { t } = useTranslation();\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content size=\"md\">\n <Dialog.Header>\n <Dialog.Title>\n {t('fileManager.dialogs.upload.title', 'Upload to {{folder}}', {\n folder: destinationLabel,\n })}\n </Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <FileUpload\n variant=\"both\"\n multiple={config?.multiple ?? true}\n accept={config?.accept}\n maxSize={config?.maxSize}\n onUpload={onUpload}\n />\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button type=\"button\" intent=\"outline\">\n {t('fileManager.dialogs.upload.close', 'Done')}\n </Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Rename */\n/* ------------------------------------------------------------------ */\n\nexport interface RenameDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Current name of the item being renamed. */\n initialName: string;\n onSubmit: (name: string) => void;\n}\n\nexport function RenameDialog({\n open,\n onOpenChange,\n initialName,\n onSubmit,\n}: RenameDialogProps) {\n const { t } = useTranslation();\n const inputId = useId();\n const [name, setName] = useState(initialName);\n\n useEffect(() => {\n if (open) setName(initialName);\n }, [open, initialName]);\n\n const handleSubmit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const trimmed = name.trim();\n if (trimmed.length === 0) return;\n onSubmit(trimmed);\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content size=\"sm\">\n <Dialog.Header>\n <Dialog.Title>\n {t('fileManager.dialogs.rename.title', 'Rename')}\n </Dialog.Title>\n </Dialog.Header>\n <form onSubmit={handleSubmit}>\n <Dialog.Body>\n <label\n htmlFor={inputId}\n className=\"type-label ds:block ds:mb-[var(--spacing-xs)]\"\n >\n {t('fileManager.dialogs.rename.nameLabel', 'New name')}\n </label>\n <TextInput\n id={inputId}\n value={name}\n maxLength={NAME_MAX_LENGTH}\n onChange={(event) => setName(sanitizeName(event.target.value))}\n // eslint-disable-next-line jsx-a11y/no-autofocus -- intentional: focus the name field when the dialog opens\n autoFocus\n />\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button type=\"button\" intent=\"outline\">\n {t('fileManager.dialogs.rename.cancel', 'Cancel')}\n </Button>\n </Dialog.Close>\n <Button\n type=\"submit\"\n intent=\"primary\"\n disabled={name.trim().length === 0}\n >\n {t('fileManager.dialogs.rename.confirm', 'Rename')}\n </Button>\n </Dialog.Footer>\n </form>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Delete (forced-choice confirmation) */\n/* ------------------------------------------------------------------ */\n\nexport interface DeleteDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n count: number;\n onConfirm: () => void;\n}\n\nexport function DeleteDialog({\n open,\n onOpenChange,\n count,\n onConfirm,\n}: DeleteDialogProps) {\n const { t } = useTranslation();\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content size=\"sm\" variant=\"alert\">\n <Dialog.Header>\n <Dialog.Title>\n {t('fileManager.dialogs.delete.title', 'Delete {{count}} items?', {\n count,\n })}\n </Dialog.Title>\n </Dialog.Header>\n <Dialog.Description>\n {t(\n 'fileManager.dialogs.delete.description',\n 'This action cannot be undone.',\n )}\n </Dialog.Description>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button type=\"button\" intent=\"outline\">\n {t('fileManager.dialogs.delete.cancel', 'Cancel')}\n </Button>\n </Dialog.Close>\n <Button type=\"button\" intent=\"destructive\" onClick={onConfirm}>\n {t('fileManager.dialogs.delete.confirm', 'Delete')}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Move (destination picker) */\n/* ------------------------------------------------------------------ */\n\nexport interface MoveDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Full item list — the destination tree is derived from its folders. */\n items: FileManagerItem[];\n /** Items being moved — they and their descendants are invalid targets. */\n movingIds: string[];\n /** Folder the mover starts from (pre-selected destination). */\n currentFolderId: string | null;\n onConfirm: (targetFolderId: string | null) => void;\n}\n\nexport function MoveDialog({\n open,\n onOpenChange,\n items,\n movingIds,\n currentFolderId,\n onConfirm,\n}: MoveDialogProps) {\n const { t } = useTranslation();\n const [target, setTarget] = useState<string | null>(currentFolderId);\n\n useEffect(() => {\n if (open) setTarget(currentFolderId);\n }, [open, currentFolderId]);\n\n const excluded = withDescendantFolderIds(items, movingIds);\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content size=\"sm\">\n <Dialog.Header>\n <Dialog.Title>\n {t('fileManager.dialogs.move.title', 'Move {{count}} items', {\n count: movingIds.length,\n })}\n </Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <div className=\"ds:max-h-72 ds:overflow-y-auto ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)] ds:p-[var(--spacing-xs)]\">\n <FolderTree\n items={items}\n selectedFolderId={target}\n onSelectFolder={setTarget}\n aria-label={t(\n 'fileManager.dialogs.move.treeLabel',\n 'Destination folder',\n )}\n excludeIds={excluded}\n />\n </div>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button type=\"button\" intent=\"outline\">\n {t('fileManager.dialogs.move.cancel', 'Cancel')}\n </Button>\n </Dialog.Close>\n <Button\n type=\"button\"\n intent=\"primary\"\n onClick={() => onConfirm(target)}\n >\n {t('fileManager.dialogs.move.confirm', 'Move here')}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* FileManager — list view (internal). */\n/* */\n/* Composes the kit DataTable (AG Grid) — never a hand-rolled table. */\n/* Selection is lifted: the parent owns the id list; this view reflects */\n/* it into the grid and reports grid-side changes back up. */\n/* -------------------------------------------------------------------- */\n\nimport {\n useCallback,\n useEffect,\n useMemo,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport type { CustomCellRendererProps } from 'ag-grid-react';\nimport type {\n ColDef,\n GridOptions,\n RowClassParams,\n ValueFormatterParams,\n} from 'ag-grid-community';\nimport {\n Download,\n FolderInput,\n PenLine,\n Pencil,\n Share2,\n Trash2,\n} from 'lucide-react';\nimport {\n ActionsCellRenderer,\n actionsColumnWidth,\n DataTable,\n type ActionDef,\n type ActionsCellRendererParams,\n type DataTableHandle,\n} from '../data-table';\nimport { Badge } from '../badge';\nimport type {\n FileManagerItem,\n FileManagerItemAction,\n FileManagerPermissions,\n FileManagerSignatureStatus,\n} from './types';\nimport {\n formatFileSize,\n getItemIcon,\n pathWithinFolder,\n sameIdSet,\n} from './utils';\n\nconst SIGNATURE_VARIANT: Record<\n Exclude<FileManagerSignatureStatus, 'none'>,\n 'success' | 'warning'\n> = {\n signed: 'success',\n pending: 'warning',\n};\n\n// Name cell factory — closes over the previewed id so the row open in the host\n// rail carries a programmatic `aria-current` marker (not just the visual tint),\n// keeping assistive tech in sync with which document is being previewed.\nfunction makeNameCellRenderer(previewedItemId?: string | null) {\n return function NameCellRenderer(\n props: CustomCellRendererProps<FileManagerItem>,\n ) {\n const item = props.data;\n if (!item) return null;\n const IconComponent = getItemIcon(item);\n const isPreviewed = Boolean(previewedItemId) && item.id === previewedItemId;\n return (\n <span\n // Fill the cell and allow the label to shrink so a long name truncates\n // with an ellipsis instead of overflowing into the next column: the row\n // is a flex box (`inline-size:100%` + `min-inline-size:0`), the icon\n // never shrinks, and the name span truncates within the remaining space.\n className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)] ds:[inline-size:100%] ds:[min-inline-size:0]\"\n aria-current={isPreviewed ? 'true' : undefined}\n >\n <IconComponent\n aria-hidden=\"true\"\n className={[\n 'ds:size-4 ds:shrink-0',\n // Folders keep the brand primary; file glyphs take the accent, so\n // they read as documents and match the DocumentPreview header icon.\n item.kind === 'folder'\n ? 'ds:text-primary'\n : 'ds:text-[color:var(--accent)]',\n ].join(' ')}\n />\n <span className=\"ds:truncate ds:[min-inline-size:0]\">{item.name}</span>\n </span>\n );\n };\n}\n\nfunction TypeCellRenderer(props: CustomCellRendererProps<FileManagerItem>) {\n const item = props.data;\n if (!item || !item.documentType) return null;\n return (\n <Badge variant=\"neutral\" size=\"sm\">\n {item.documentType}\n </Badge>\n );\n}\n\nfunction makeSignatureCellRenderer(\n t: (key: string, fallback: string) => string,\n) {\n return function SignatureCellRenderer(\n props: CustomCellRendererProps<FileManagerItem>,\n ) {\n const status = props.data?.signatureStatus;\n if (!status || status === 'none') return null;\n return (\n <Badge variant={SIGNATURE_VARIANT[status]} size=\"sm\" withDot>\n {t(`fileManager.signature.${status}`, status)}\n </Badge>\n );\n };\n}\n\nexport interface ListViewProps {\n /** Items of the current folder (folders + files), locale-sorted. Filtering\n * is done by the DataTable's per-column floating filters (name + type). */\n items: FileManagerItem[];\n selectedIds: string[];\n /** Id of the file open in the host preview (e.g. the rail). Reuses the\n * selected-row tint so the user sees which document is active. */\n previewedItemId?: string | null;\n onSelectionChange: (ids: string[]) => void;\n onOpen: (item: FileManagerItem) => void;\n /** Primary single-click / keyboard activation — folders navigate, files\n * select-single (which fires the host `onPreviewItem`). */\n onRowActivate: (item: FileManagerItem) => void;\n /** Resolves the gate set for a single item. */\n can: (item: FileManagerItem) => Required<FileManagerPermissions>;\n onRequestRename: (itemId: string) => void;\n onRequestMove: (itemIds: string[]) => void;\n onRequestDelete: (itemIds: string[]) => void;\n onDownload?: (itemIds: string[]) => void;\n onShare?: (itemIds: string[]) => void;\n onRequestSignature?: (item: FileManagerItem) => void;\n /** Consumer actions appended after the built-in kebab entries. */\n itemActions?: (item: FileManagerItem) => FileManagerItemAction[];\n /**\n * Nest files under their folders via AG Grid Tree Data (`treeData` +\n * `getDataPath`). Sets the tree gridOption / autoGroupColumnDef flags only —\n * inert unless the consumer has registered the Enterprise `TreeDataModule`.\n * When on, `items` must be the whole descendant subtree (see `descendantsOf`)\n * and paths are built relative to `currentFolderId`. @default false\n */\n groupByFolder?: boolean;\n /**\n * Current folder id (`null` = root) — the anchor for tree-data path building.\n * Paths run from this folder's direct child down to each item.\n */\n currentFolderId: string | null;\n /** Forwarded as the DataTable `gridId` (namespaced by the caller). */\n gridId?: string;\n /** Handle to the composed DataTable — the FileManager proxies its\n * type-filter handle methods and agent `filter` action through this. */\n tableRef: RefObject<DataTableHandle<FileManagerItem> | null>;\n /** FileManager action cluster rendered in the DataTable's `Toolbar.Actions`. */\n toolbarActions: ReactNode;\n}\n\nexport function ListView({\n items,\n selectedIds,\n previewedItemId,\n onSelectionChange,\n onOpen,\n onRowActivate,\n can,\n onRequestRename,\n onRequestMove,\n onRequestDelete,\n onDownload,\n onShare,\n onRequestSignature,\n itemActions,\n groupByFolder = false,\n currentFolderId,\n gridId,\n tableRef,\n toolbarActions,\n}: ListViewProps) {\n const { t, i18n } = useTranslation();\n\n // Id → item over the current subtree — the tree-data path builder walks\n // `parentId` up through it, and it is cheap enough to keep memoised.\n const itemsById = useMemo(\n () => new Map(items.map((item) => [item.id, item])),\n [items],\n );\n\n const hasSignatureColumn = useMemo(\n () =>\n items.some(\n (item) => item.signatureStatus && item.signatureStatus !== 'none',\n ),\n [items],\n );\n const hasTypeColumn = useMemo(\n () => items.some((item) => Boolean(item.documentType)),\n [items],\n );\n\n // Reflect the lifted selection into the grid. The grid echoes the change\n // back through onSelectionChanged; the parent's set-equality guard stops\n // the loop.\n useEffect(() => {\n tableRef.current?.setSelection(selectedIds);\n }, [selectedIds, items]);\n\n // Per-row actions resolve permissions from the row data so a per-item\n // resolver gates each row independently.\n const rowActions = useMemo<ActionDef<FileManagerItem>[]>(() => {\n const actions: ActionDef<FileManagerItem>[] = [];\n if (onDownload) {\n actions.push({\n icon: <Download />,\n label: t('fileManager.toolbar.download', 'Download'),\n onClick: (data) => onDownload([data.id]),\n hidden: (data) => data.kind === 'folder' || !can(data).download,\n });\n }\n if (onRequestSignature) {\n actions.push({\n icon: <PenLine />,\n label: t('fileManager.toolbar.requestSignature', 'Request signature'),\n onClick: (data) => onRequestSignature(data),\n hidden: (data) => data.signatureStatus !== 'pending',\n });\n }\n if (onShare) {\n actions.push({\n icon: <Share2 />,\n label: t('fileManager.toolbar.share', 'Share'),\n onClick: (data) => onShare([data.id]),\n hidden: (data) => !can(data).share,\n });\n }\n actions.push({\n icon: <Pencil />,\n label: t('fileManager.toolbar.rename', 'Rename'),\n onClick: (data) => onRequestRename(data.id),\n hidden: (data) => !can(data).rename,\n });\n actions.push({\n icon: <FolderInput />,\n label: t('fileManager.toolbar.move', 'Move'),\n onClick: (data) => onRequestMove([data.id]),\n hidden: (data) => !can(data).move,\n });\n actions.push({\n icon: <Trash2 />,\n label: t('fileManager.toolbar.delete', 'Delete'),\n onClick: (data) => onRequestDelete([data.id]),\n variant: 'destructive',\n hidden: (data) => !can(data).delete,\n });\n if (itemActions) {\n // Consumer actions appended last. Each entry's per-item resolver is the\n // consumer's own — we render whatever it returns for the row.\n const resolvedIds = new Set<string>();\n for (const item of items) {\n for (const action of itemActions(item)) {\n if (resolvedIds.has(action.id)) continue;\n resolvedIds.add(action.id);\n const actionId = action.id;\n actions.push({\n icon: action.icon ?? <span aria-hidden=\"true\" />,\n label: action.label,\n onClick: (data) =>\n itemActions(data)\n .find((a) => a.id === actionId)\n ?.onSelect(data),\n variant: action.destructive ? 'destructive' : 'default',\n hidden: (data) => !itemActions(data).some((a) => a.id === actionId),\n });\n }\n }\n }\n return actions;\n }, [\n items,\n can,\n onDownload,\n onShare,\n onRequestSignature,\n onRequestRename,\n onRequestMove,\n onRequestDelete,\n itemActions,\n t,\n ]);\n\n const columnDefs = useMemo<ColDef<FileManagerItem>[]>(() => {\n const SignatureCellRenderer = makeSignatureCellRenderer(t);\n const NameCellRenderer = makeNameCellRenderer(previewedItemId);\n const defs: ColDef<FileManagerItem>[] = [];\n // In tree-data mode the auto group column (configured in gridOptions below)\n // renders the Name hierarchy, so the flat Name column is omitted.\n if (!groupByFolder) {\n defs.push({\n colId: 'name',\n field: 'name',\n headerName: t('fileManager.columns.name', 'Name'),\n cellRenderer: NameCellRenderer,\n flex: 2,\n minWidth: 200,\n });\n }\n if (hasTypeColumn) {\n defs.push({\n colId: 'documentType',\n field: 'documentType',\n headerName: t('fileManager.columns.type', 'Type'),\n cellRenderer: TypeCellRenderer,\n flex: 1,\n minWidth: 120,\n });\n }\n if (hasSignatureColumn) {\n defs.push({\n colId: 'signatureStatus',\n field: 'signatureStatus',\n headerName: t('fileManager.columns.signature', 'Signature'),\n cellRenderer: SignatureCellRenderer,\n flex: 1,\n minWidth: 150,\n });\n }\n defs.push({\n colId: 'size',\n field: 'size',\n headerName: t('fileManager.columns.size', 'Size'),\n valueFormatter: (params: ValueFormatterParams<FileManagerItem>) =>\n params.data?.kind === 'file' && params.data.size !== undefined\n ? formatFileSize(params.data.size, i18n.language, t)\n : t('fileManager.emptyCell', '—'),\n filter: false,\n flex: 1,\n minWidth: 110,\n });\n defs.push({\n colId: 'updatedAt',\n field: 'updatedAt',\n headerName: t('fileManager.columns.modified', 'Modified'),\n valueFormatter: (params: ValueFormatterParams<FileManagerItem>) =>\n params.data?.updatedAt\n ? new Intl.DateTimeFormat(i18n.language, {\n dateStyle: 'medium',\n }).format(new Date(params.data.updatedAt))\n : t('fileManager.emptyCell', '—'),\n filter: false,\n flex: 1,\n minWidth: 130,\n });\n if (rowActions.length > 0) {\n defs.push({\n colId: 'actions',\n headerName: t('fileManager.rowActions', 'Item actions'),\n cellRenderer: ActionsCellRenderer,\n cellRendererParams: {\n actions: rowActions,\n group: true,\n label: t('fileManager.rowActions', 'Item actions'),\n } satisfies ActionsCellRendererParams<FileManagerItem>,\n sortable: false,\n filter: false,\n resizable: false,\n width: actionsColumnWidth(rowActions.length),\n });\n }\n return defs;\n }, [\n rowActions,\n hasTypeColumn,\n hasSignatureColumn,\n previewedItemId,\n groupByFolder,\n t,\n i18n.language,\n ]);\n\n const gridOptions = useMemo<GridOptions<FileManagerItem>>(() => {\n const options: GridOptions<FileManagerItem> = {\n getRowId: (params) => params.data.id,\n onRowClicked: (event) => {\n // Skip clicks on the selection checkbox, the row-actions kebab, and the\n // tree expand/collapse chevron — those own their own behaviour\n // (multi-select toggle / menu / expand). A click on the row body is the\n // primary activation (select-single + fire onPreviewItem, or navigate\n // for folders). In tree-data mode every parent row is a real folder\n // item with `data`, so folder rows activate exactly like the flat view.\n const dom = event.event as Event | undefined;\n const target = dom?.target as HTMLElement | null;\n if (\n target?.closest(\n '.ag-selection-checkbox, .ag-checkbox-input-wrapper, [col-id=\"actions\"], [data-item-kebab], .ag-group-contracted, .ag-group-expanded',\n )\n ) {\n return;\n }\n if (event.data) onRowActivate(event.data);\n },\n onRowDoubleClicked: (event) => {\n if (event.data) onOpen(event.data);\n },\n };\n if (groupByFolder) {\n // AG Grid Tree Data: each folder is a parent row and its files nest\n // beneath it (a file-explorer tree). `getDataPath` reads the id-chain\n // from the current folder's direct child down to each item; every id is a\n // real row, so no filler group rows appear. `groupDefaultExpanded: 1`\n // opens the current folder's folders (showing their files) while deeper\n // nesting stays collapsed until requested. The auto group column reads as\n // \"Name\" and reuses NameCellRenderer, so folders and files render exactly\n // as in the flat view (icon + name + previewed aria-current) with AG\n // Grid's chevron on folders. Only these flags are set here — the\n // Enterprise TreeDataModule is registered by the consumer.\n const NameCellRenderer = makeNameCellRenderer(previewedItemId);\n options.treeData = true;\n options.getDataPath = (item) =>\n pathWithinFolder(item, itemsById, currentFolderId);\n options.groupDefaultExpanded = 1;\n options.autoGroupColumnDef = {\n headerName: t('fileManager.columns.name', 'Name'),\n flex: 2,\n minWidth: 200,\n cellRendererParams: {\n suppressCount: true,\n innerRenderer: NameCellRenderer,\n },\n };\n }\n return options;\n }, [\n onOpen,\n onRowActivate,\n groupByFolder,\n previewedItemId,\n t,\n itemsById,\n currentFolderId,\n ]);\n\n const handleSelectionChanged = (rows: FileManagerItem[]) => {\n const ids = rows.map((row) => row.id);\n if (!sameIdSet(ids, selectedIds)) onSelectionChange(ids);\n };\n\n // Reuse the grid's selected-row treatment (token-driven, no new colours) to\n // mark the row the host is previewing in the rail.\n const getRowClass = useCallback(\n (params: RowClassParams<FileManagerItem>) =>\n previewedItemId && params.data?.id === previewedItemId\n ? 'ag-row-selected'\n : undefined,\n [previewedItemId],\n );\n\n return (\n <DataTable<FileManagerItem>\n ref={tableRef}\n gridId={gridId}\n columnDefs={columnDefs}\n rowData={items}\n rowSelection=\"multiple\"\n gridOptions={gridOptions}\n getRowClass={getRowClass}\n onSelectionChanged={handleSelectionChanged}\n heightClass=\"ds:h-[420px]\"\n >\n <DataTable.Toolbar>\n <DataTable.Toolbar.Actions>{toolbarActions}</DataTable.Toolbar.Actions>\n </DataTable.Toolbar>\n </DataTable>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* FileManager — toolbar (internal). */\n/* */\n/* One end-aligned IconButtonGroup rendered inside the composed */\n/* DataTable's `Toolbar.Actions` slot. Upload is the primary action; */\n/* the rest are New Folder, consumer `addMenuItems`, then the selection- */\n/* scoped Download / Share / Rename / Move / Delete cluster. Every */\n/* affordance is permission-gated at render time: an action the host has */\n/* not granted simply does not exist in the DOM. `overflow=\"menu\"` lets */\n/* the strip collapse gracefully on narrow widths. */\n/* -------------------------------------------------------------------- */\n\nimport { useTranslation } from 'react-i18next';\nimport {\n Download,\n FolderInput,\n FolderPlus,\n Pencil,\n Plus,\n Share2,\n Trash2,\n Upload,\n} from 'lucide-react';\nimport { IconButton } from '../icon-button';\nimport { IconButtonGroup } from '../icon-button-group';\nimport type { FileManagerAddMenuItem, FileManagerPermissions } from './types';\n\nexport interface FileManagerToolbarProps {\n selectedIds: string[];\n permissions: Required<FileManagerPermissions>;\n onRequestCreateFolder: () => void;\n onRequestUpload?: () => void;\n addMenuItems?: FileManagerAddMenuItem[];\n onRequestRename: (itemId: string) => void;\n onRequestMove: (itemIds: string[]) => void;\n onRequestDelete: (itemIds: string[]) => void;\n onDownload?: (itemIds: string[]) => void;\n onShare?: (itemIds: string[]) => void;\n}\n\nexport function FileManagerToolbar({\n selectedIds,\n permissions,\n onRequestCreateFolder,\n onRequestUpload,\n addMenuItems,\n onRequestRename,\n onRequestMove,\n onRequestDelete,\n onDownload,\n onShare,\n}: FileManagerToolbarProps) {\n const { t } = useTranslation();\n\n const hasSelection = selectedIds.length > 0;\n const singleSelection = selectedIds.length === 1;\n const canUpload = permissions.upload && Boolean(onRequestUpload);\n const canDownload = permissions.download && Boolean(onDownload);\n const canShare = permissions.share && Boolean(onShare);\n const extraAddItems = addMenuItems ?? [];\n\n const hasAny =\n canUpload ||\n permissions.createFolder ||\n extraAddItems.length > 0 ||\n canDownload ||\n canShare ||\n permissions.rename ||\n permissions.move ||\n permissions.delete;\n\n if (!hasAny) return null;\n\n return (\n <IconButtonGroup\n role=\"toolbar\"\n overflow=\"menu\"\n size=\"sm\"\n aria-label={t('fileManager.toolbarLabel', 'File actions')}\n data-testid=\"file-manager-toolbar\"\n >\n {canUpload && (\n <IconButton\n intent=\"primary\"\n data-overflow-pin\n icon={<Upload />}\n tooltip={t('fileManager.toolbar.upload', 'Upload files')}\n onClick={() => onRequestUpload?.()}\n />\n )}\n {permissions.createFolder && (\n <IconButton\n icon={<FolderPlus />}\n tooltip={t('fileManager.toolbar.newFolder', 'New folder')}\n onClick={onRequestCreateFolder}\n />\n )}\n {extraAddItems.map((entry) => (\n <IconButton\n key={entry.id}\n icon={entry.icon ?? <Plus />}\n tooltip={entry.label}\n onClick={() => entry.onSelect()}\n />\n ))}\n {canDownload && (\n <IconButton\n icon={<Download />}\n tooltip={t('fileManager.toolbar.download', 'Download')}\n disabled={!hasSelection}\n onClick={() => onDownload?.(selectedIds)}\n />\n )}\n {canShare && (\n <IconButton\n icon={<Share2 />}\n tooltip={t('fileManager.toolbar.share', 'Share')}\n disabled={!hasSelection}\n onClick={() => onShare?.(selectedIds)}\n />\n )}\n {permissions.rename && (\n <IconButton\n icon={<Pencil />}\n tooltip={t('fileManager.toolbar.rename', 'Rename')}\n disabled={!singleSelection}\n onClick={() => onRequestRename(selectedIds[0])}\n />\n )}\n {permissions.move && (\n <IconButton\n icon={<FolderInput />}\n tooltip={t('fileManager.toolbar.move', 'Move')}\n disabled={!hasSelection}\n onClick={() => onRequestMove(selectedIds)}\n />\n )}\n {permissions.delete && (\n <IconButton\n icon={<Trash2 />}\n tooltip={t('fileManager.toolbar.delete', 'Delete')}\n disabled={!hasSelection}\n onClick={() => onRequestDelete(selectedIds)}\n />\n )}\n </IconButtonGroup>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* FileManager — a permission-gated file/folder browser. */\n/* */\n/* Composes the kit FolderTree sidebar, Breadcrumb path, and the */\n/* DataTable (AG Grid) list. Single-click a file row selects it and */\n/* fires `onPreviewItem` (the host renders a DocumentPreview — typically */\n/* in the Control Room rail); folders navigate; double-click resolves the */\n/* host `onOpenFile`. Keyboard Enter mirrors the primary gesture: a file */\n/* previews when a preview handler is wired, else opens. Every mutation */\n/* resolves through a host */\n/* callback; the component owns only view state (folder, selection, */\n/* active action). Agent-readiness: curated FileManagerHandle + */\n/* file-manager.agent.ts. */\n/* -------------------------------------------------------------------- */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type DragEvent,\n type KeyboardEvent,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Upload } from 'lucide-react';\nimport { Breadcrumb, BreadcrumbItem, BreadcrumbLink } from '../breadcrumb';\nimport type { DataTableHandle } from '../data-table';\nimport { EmptyState } from '../empty-state';\nimport { Skeleton } from '../skeleton';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { useAgentRegistration } from '../../agent';\nimport { fileManagerAgent } from './file-manager.agent';\nimport {\n CreateFolderDialog,\n DeleteDialog,\n MoveDialog,\n RenameDialog,\n UploadDialog,\n} from './dialogs';\nimport { FolderTree } from './folder-tree';\nimport { ListView } from './list-view';\nimport { FileManagerToolbar } from './toolbar';\nimport type {\n FileManagerActiveAction,\n FileManagerAddMenuItem,\n FileManagerHandle,\n FileManagerItem,\n FileManagerItemAction,\n FileManagerItemMeta,\n FileManagerPermissions,\n FileManagerPermissionsInput,\n FileManagerUploadConfig,\n FileManagerUploadHandler,\n} from './types';\nimport { childrenOf, descendantsOf, pathTo, sameIdSet } from './utils';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst fileManagerVariants = cva(\n 'ds:relative ds:flex ds:w-full ds:min-w-0 ds:flex-col ds:gap-[var(--spacing-md)]',\n {\n variants: {\n bordered: {\n true: 'ds:rounded-[var(--radius-lg)] ds:border ds:border-[color:var(--border)] ds:bg-background ds:p-[var(--spacing-md)]',\n false: '',\n },\n },\n defaultVariants: { bordered: true },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Props */\n/* ------------------------------------------------------------------ */\n\nexport interface FileManagerProps extends VariantProps<\n typeof fileManagerVariants\n> {\n /** Opaque instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** Flat item list keyed by `parentId`. The host owns this data. */\n items: FileManagerItem[];\n /**\n * Capability gates — a flat set or a per-item resolver. Default is all-true\n * (see FileManagerPermissions); `delete` always routes through a confirm.\n */\n permissions?: FileManagerPermissionsInput;\n /** Controlled current folder (`null` = root). */\n folderId?: string | null;\n /** @default null */\n defaultFolderId?: string | null;\n onNavigate?: (folderId: string | null) => void;\n onSelectionChange?: (ids: string[]) => void;\n /**\n * Opt-in folder-tree nav pane, rendered as a sidebar (hidden below the md\n * breakpoint). The default layout is the table full-width with the folder\n * breadcrumb in the footer; when `groupByFolder` is on the tree data already\n * surfaces folders in the list, so the sidebar is redundant unless a consumer\n * explicitly wants it.\n * @default false — opt-in nav pane\n */\n showTree?: boolean;\n /** Render the Skeleton loading state instead of the folder contents. */\n isLoading?: boolean;\n /** Opening a file resolves here (folders navigate internally). */\n onOpenFile?: (item: FileManagerItem) => void;\n onCreateFolder?: (\n name: string,\n parentId: string | null,\n ) => void | Promise<void>;\n onRenameItem?: (itemId: string, name: string) => void | Promise<void>;\n onDeleteItems?: (itemIds: string[]) => void | Promise<void>;\n onMoveItems?: (\n itemIds: string[],\n targetFolderId: string | null,\n ) => void | Promise<void>;\n onDownloadItems?: (itemIds: string[]) => void;\n /** Share affordance (kebab + toolbar). Hidden when absent. */\n onShare?: (itemIds: string[]) => void;\n /**\n * Request a signature for a pending-signature item. The action only appears\n * on items whose `signatureStatus` is `'pending'`; hidden when absent.\n */\n onRequestSignature?: (item: FileManagerItem) => void;\n /** Per-file upload handler (host owns transport). Enables the upload UI. */\n onUpload?: FileManagerUploadHandler;\n /** Upload transport config forwarded to the kit FileUpload. */\n uploadConfig?: FileManagerUploadConfig;\n /**\n * Fired when a **file** row is activated by a single click, or by keyboard\n * Enter on the selected file when this handler is wired (folders navigate\n * internally; double-click always resolves `onOpenFile`). The host is\n * expected to render the kit `DocumentPreview` in response — typically inside\n * the Control Room rail. When absent, single-click just selects the row and\n * Enter falls back to `onOpenFile`.\n */\n onPreviewItem?: (item: FileManagerItem) => void;\n /**\n * Id of the file the host is currently previewing (e.g. open in the rail).\n * When set, the matching list row reuses the DataTable's selected-row tint so\n * the user can see which document is open. `null` clears the highlight.\n */\n previewedItemId?: string | null;\n /** Consumer actions appended after the built-in per-item kebab entries. */\n itemActions?: (item: FileManagerItem) => FileManagerItemAction[];\n /** Consumer entries appended after the built-in action buttons. */\n addMenuItems?: FileManagerAddMenuItem[];\n /**\n * Nest files under their folders (Finder/Explorer style) via AG Grid Tree\n * Data. Requires the consumer to register the Enterprise `TreeDataModule`\n * (`ModuleRegistry.registerModules([TreeDataModule])`); the `treeData` /\n * `getDataPath` / `autoGroupColumnDef` flags set here are inert until it is.\n * @default false\n */\n groupByFolder?: boolean;\n className?: string;\n}\n\nconst ALL_PERMISSIONS: Required<FileManagerPermissions> = {\n createFolder: true,\n upload: true,\n download: true,\n rename: true,\n move: true,\n delete: true,\n share: true,\n};\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const FileManager = forwardRef<FileManagerHandle, FileManagerProps>(\n (\n {\n id,\n items,\n permissions,\n folderId: folderIdProp,\n defaultFolderId = null,\n onNavigate,\n onSelectionChange,\n showTree = false,\n isLoading = false,\n onOpenFile,\n onCreateFolder,\n onRenameItem,\n onDeleteItems,\n onMoveItems,\n onDownloadItems,\n onShare,\n onRequestSignature,\n onUpload,\n uploadConfig,\n onPreviewItem,\n previewedItemId,\n itemActions,\n addMenuItems,\n groupByFolder = false,\n bordered,\n className,\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n\n // Resolve gates. `can()` is the folder-level base (all-true when a per-item\n // resolver is supplied but no item is in scope); `canItem(item)` gates the\n // per-item kebab / row actions.\n const resolvePerms = useCallback(\n (item?: FileManagerItem): Required<FileManagerPermissions> => {\n if (typeof permissions === 'function') {\n return item\n ? { ...ALL_PERMISSIONS, ...permissions(item) }\n : ALL_PERMISSIONS;\n }\n return { ...ALL_PERMISSIONS, ...(permissions ?? {}) };\n },\n [permissions],\n );\n const can = useMemo(() => resolvePerms(), [resolvePerms]);\n const canItem = useCallback(\n (item: FileManagerItem) => resolvePerms(item),\n [resolvePerms],\n );\n\n const [folderRaw, setFolder] = useControllableState<string | null>({\n value: folderIdProp,\n defaultValue: defaultFolderId,\n onChange: onNavigate,\n });\n const currentFolderId = folderRaw ?? null;\n\n const [selectedIds, setSelectedIdsRaw] = useState<string[]>([]);\n const [activeAction, setActiveAction] = useState<FileManagerActiveAction>({\n type: 'none',\n });\n const [isDraggingFiles, setIsDraggingFiles] = useState(false);\n const dragDepth = useRef(0);\n\n // The composed DataTable's curated handle — the type-filter handle methods\n // and the agent `filter` action proxy through it.\n const dataTableRef = useRef<DataTableHandle<FileManagerItem>>(null);\n\n const liveRef = useRef<HTMLSpanElement>(null);\n const announce = useCallback((message: string) => {\n if (liveRef.current) liveRef.current.textContent = message;\n }, []);\n\n // The ListView is keyed by folder id and remounts on every navigation,\n // which would drop focus to <body>. After a folder change we move focus to\n // this stable content container so keyboard users keep their place; the\n // polite \"Opened {name}\" live region announces the change for screen\n // readers. The flag is only set by user-driven navigateTo, never on mount.\n const contentRef = useRef<HTMLDivElement>(null);\n const focusContentAfterNav = useRef(false);\n\n const itemsById = useMemo(\n () => new Map(items.map((item) => [item.id, item])),\n [items],\n );\n\n const setSelection = useCallback(\n (ids: string[]) => {\n setSelectedIdsRaw((prev) => {\n const valid = ids.filter((itemId) => itemsById.has(itemId));\n if (sameIdSet(prev, valid)) return prev;\n onSelectionChange?.(valid);\n return valid;\n });\n },\n [itemsById, onSelectionChange],\n );\n\n // Prune selected ids that no longer exist in the data set.\n useEffect(() => {\n setSelectedIdsRaw((prev) => {\n const valid = prev.filter((itemId) => itemsById.has(itemId));\n return valid.length === prev.length ? prev : valid;\n });\n }, [itemsById]);\n\n /* ---------------- navigation ---------------- */\n\n const navigateTo = useCallback(\n (targetId: string | null) => {\n if (targetId !== null) {\n const target = itemsById.get(targetId);\n if (!target || target.kind !== 'folder') return;\n }\n setFolder(targetId);\n setSelectedIdsRaw([]);\n focusContentAfterNav.current = true;\n const name =\n targetId === null\n ? t('fileManager.rootLabel', 'All files')\n : (itemsById.get(targetId)?.name ?? '');\n announce(\n t('fileManager.announce.navigated', 'Opened {{name}}', { name }),\n );\n },\n [itemsById, setFolder, announce, t],\n );\n\n // Move focus to the content container after the post-navigation remount so\n // it never falls back to <body> (paired with the live-region announcement).\n useEffect(() => {\n if (!focusContentAfterNav.current) return;\n focusContentAfterNav.current = false;\n contentRef.current?.focus();\n }, [currentFolderId]);\n\n /* ---------------- derived content ---------------- */\n\n // The footer breadcrumb traces the path to the PREVIEWED item — the\n // selected file, with the file itself as the final (plain) crumb — when one\n // is set; otherwise it falls back to the current folder's position.\n // Ancestor crumbs stay clickable to navigate up; the final crumb is text.\n const breadcrumbTargetId =\n previewedItemId && itemsById.has(previewedItemId)\n ? previewedItemId\n : currentFolderId;\n const path = useMemo(\n () => pathTo(items, breadcrumbTargetId),\n [items, breadcrumbTargetId],\n );\n\n const folderChildren = useMemo(\n () => childrenOf(items, currentFolderId, i18n.language),\n [items, currentFolderId, i18n.language],\n );\n\n // Tree-data feed: the whole subtree beneath the current folder so AG Grid\n // can nest files under folders. Off = flat immediate children only.\n const folderDescendants = useMemo(\n () =>\n groupByFolder\n ? descendantsOf(items, currentFolderId, i18n.language)\n : folderChildren,\n [groupByFolder, items, currentFolderId, i18n.language, folderChildren],\n );\n\n const currentFolderName =\n currentFolderId === null\n ? t('fileManager.rootLabel', 'All files')\n : (itemsById.get(currentFolderId)?.name ?? '');\n\n /* ---------------- single-active-action machine ---------------- */\n\n const beginAction = useCallback((action: FileManagerActiveAction) => {\n setActiveAction((prev) => (prev.type === 'none' ? action : prev));\n }, []);\n\n const endAction = useCallback(() => {\n setActiveAction({ type: 'none' });\n }, []);\n\n // Permission-gated entry points. Each checks its gate so keyboard\n // shortcuts, toolbar buttons and per-row actions share one guard.\n const requestCreateFolder = useCallback(() => {\n if (!can.createFolder || !onCreateFolder) return;\n beginAction({ type: 'create-folder' });\n }, [can.createFolder, onCreateFolder, beginAction]);\n\n const requestUpload = useCallback(() => {\n if (!can.upload || !onUpload) return;\n beginAction({ type: 'upload' });\n }, [can.upload, onUpload, beginAction]);\n\n const requestRename = useCallback(\n (itemId: string) => {\n const target = itemsById.get(itemId);\n if (!target || !canItem(target).rename || !onRenameItem) return;\n beginAction({ type: 'rename', itemId });\n },\n [canItem, onRenameItem, itemsById, beginAction],\n );\n\n const requestDelete = useCallback(\n (itemIds: string[]) => {\n if (!onDeleteItems || itemIds.length === 0) return;\n const allowed = itemIds.filter((itemId) => {\n const target = itemsById.get(itemId);\n return target ? canItem(target).delete : false;\n });\n if (allowed.length === 0) return;\n beginAction({ type: 'delete', itemIds: allowed });\n },\n [canItem, onDeleteItems, itemsById, beginAction],\n );\n\n const requestMove = useCallback(\n (itemIds: string[]) => {\n if (!onMoveItems || itemIds.length === 0) return;\n const allowed = itemIds.filter((itemId) => {\n const target = itemsById.get(itemId);\n return target ? canItem(target).move : false;\n });\n if (allowed.length === 0) return;\n beginAction({ type: 'move', itemIds: allowed });\n },\n [canItem, onMoveItems, itemsById, beginAction],\n );\n\n const handleDownload = useCallback(\n (itemIds: string[]) => {\n if (!onDownloadItems || itemIds.length === 0) return;\n const allowed = itemIds.filter((itemId) => {\n const target = itemsById.get(itemId);\n return target ? canItem(target).download : false;\n });\n if (allowed.length > 0) onDownloadItems(allowed);\n },\n [canItem, onDownloadItems, itemsById],\n );\n\n const handleShare = useCallback(\n (itemIds: string[]) => {\n if (!onShare || itemIds.length === 0) return;\n const allowed = itemIds.filter((itemId) => {\n const target = itemsById.get(itemId);\n return target ? canItem(target).share : false;\n });\n if (allowed.length > 0) onShare(allowed);\n },\n [canItem, onShare, itemsById],\n );\n\n /* ---------------- open / activate ---------------- */\n\n const openItem = useCallback(\n (item: FileManagerItem) => {\n if (item.kind === 'folder') navigateTo(item.id);\n else onOpenFile?.(item);\n },\n [navigateTo, onOpenFile],\n );\n\n // Primary single-click / keyboard activation: folders navigate; a file\n // becomes the single selection and fires `onPreviewItem` so the host can\n // open it in a DocumentPreview (e.g. the Control Room rail).\n const activateRow = useCallback(\n (item: FileManagerItem) => {\n if (item.kind === 'folder') {\n navigateTo(item.id);\n } else {\n setSelection([item.id]);\n onPreviewItem?.(item);\n }\n },\n [navigateTo, setSelection, onPreviewItem],\n );\n\n /* ---------------- dialog submits ---------------- */\n\n const submitCreateFolder = useCallback(\n (name: string) => {\n void onCreateFolder?.(name, currentFolderId);\n endAction();\n },\n [onCreateFolder, currentFolderId, endAction],\n );\n\n const submitRename = useCallback(\n (name: string) => {\n if (activeAction.type === 'rename') {\n void onRenameItem?.(activeAction.itemId, name);\n }\n endAction();\n },\n [activeAction, onRenameItem, endAction],\n );\n\n const submitDelete = useCallback(() => {\n if (activeAction.type === 'delete') {\n void onDeleteItems?.(activeAction.itemIds);\n setSelection([]);\n }\n endAction();\n }, [activeAction, onDeleteItems, setSelection, endAction]);\n\n const submitMove = useCallback(\n (targetFolderId: string | null) => {\n if (activeAction.type === 'move') {\n void onMoveItems?.(activeAction.itemIds, targetFolderId);\n }\n endAction();\n },\n [activeAction, onMoveItems, endAction],\n );\n\n const uploadToCurrentFolder = useCallback<\n (\n file: File,\n helpers: { signal: AbortSignal; onProgress: (percent: number) => void },\n ) => Promise<void>\n >(\n (file, helpers) =>\n onUpload ? onUpload(file, helpers, currentFolderId) : Promise.resolve(),\n [onUpload, currentFolderId],\n );\n\n /* ---------------- canvas drag-and-drop overlay ------------------ */\n\n const uploadEnabled = can.upload && Boolean(onUpload);\n\n const isFileDrag = (event: DragEvent) =>\n Array.from(event.dataTransfer?.types ?? []).includes('Files');\n\n const handleDragEnter = useCallback(\n (event: DragEvent<HTMLDivElement>) => {\n if (!uploadEnabled || !isFileDrag(event)) return;\n event.preventDefault();\n dragDepth.current += 1;\n setIsDraggingFiles(true);\n },\n [uploadEnabled],\n );\n\n const handleDragOver = useCallback(\n (event: DragEvent<HTMLDivElement>) => {\n if (!uploadEnabled || !isFileDrag(event)) return;\n event.preventDefault();\n },\n [uploadEnabled],\n );\n\n const handleDragLeave = useCallback(() => {\n if (!uploadEnabled) return;\n dragDepth.current = Math.max(0, dragDepth.current - 1);\n if (dragDepth.current === 0) setIsDraggingFiles(false);\n }, [uploadEnabled]);\n\n const handleDrop = useCallback(\n (event: DragEvent<HTMLDivElement>) => {\n if (!uploadEnabled || !isFileDrag(event)) return;\n event.preventDefault();\n dragDepth.current = 0;\n setIsDraggingFiles(false);\n // The FileUpload queue inside the dialog owns file intake; the canvas\n // overlay is the affordance that opens it on drop.\n requestUpload();\n },\n [uploadEnabled, requestUpload],\n );\n\n /* ---------------- keyboard (scoped to the component root) -------- */\n\n const handleRootKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n // Shortcuts are disabled while any action dialog is open.\n if (activeAction.type !== 'none') return;\n const target = event.target as HTMLElement;\n if (target.closest('input, textarea, [contenteditable=\"true\"]')) return;\n if (event.key === 'F2' && selectedIds.length === 1) {\n event.preventDefault();\n requestRename(selectedIds[0]);\n } else if (event.key === 'Delete' && selectedIds.length > 0) {\n event.preventDefault();\n requestDelete(selectedIds);\n } else if (event.key === 'Enter' && selectedIds.length === 1) {\n const only = itemsById.get(selectedIds[0]);\n if (only) {\n event.preventDefault();\n // Keyboard activation mirrors the primary pointer gesture so both\n // interactions stay keyboard-reachable (WCAG 2.1.1): a file with a\n // host preview handler previews (the single-click path); otherwise\n // it opens (the double-click path). Folders navigate either way.\n if (only.kind === 'file' && onPreviewItem) {\n activateRow(only);\n } else {\n openItem(only);\n }\n }\n } else if (\n event.key.toLowerCase() === 'a' &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault();\n setSelection(folderChildren.map((item) => item.id));\n }\n },\n [\n activeAction.type,\n selectedIds,\n itemsById,\n requestRename,\n requestDelete,\n openItem,\n activateRow,\n onPreviewItem,\n setSelection,\n folderChildren,\n ],\n );\n\n /* ---------------- curated handle + agent registration ------------ */\n\n // Live refs so the memoised handle always reads current state.\n const stateRef = useRef({\n selectedIds,\n currentFolderId,\n items,\n activeAction,\n });\n stateRef.current = {\n selectedIds,\n currentFolderId,\n items,\n activeAction,\n };\n const actionsRef = useRef({\n setSelection,\n navigateTo,\n openItem,\n requestRename,\n });\n actionsRef.current = {\n setSelection,\n navigateTo,\n openItem,\n requestRename,\n };\n\n const handle = useMemo<FileManagerHandle>(\n () => ({\n getSelection: () => [...stateRef.current.selectedIds],\n setSelection: (ids) => actionsRef.current.setSelection(ids),\n clearSelection: () => actionsRef.current.setSelection([]),\n getCurrentFolderId: () => stateRef.current.currentFolderId,\n navigateTo: (folderId) => actionsRef.current.navigateTo(folderId),\n getTypeFilter: () => {\n const model = dataTableRef.current?.getFilter() ?? {};\n const entry = model.documentType as { filter?: unknown } | undefined;\n return typeof entry?.filter === 'string' ? [entry.filter] : [];\n },\n setTypeFilter: (documentTypes) => {\n const api = dataTableRef.current?.getRawApi();\n if (!api) return;\n if (documentTypes.length === 0) {\n api.destroyFilter('documentType');\n return;\n }\n api.setColumnFilterModel('documentType', {\n type: 'equals',\n filter: documentTypes[0],\n });\n api.onFilterChanged();\n },\n getItems: (folderId): FileManagerItemMeta[] =>\n stateRef.current.items\n .filter((item) =>\n folderId === undefined ? true : item.parentId === folderId,\n )\n .map((item) => ({\n id: item.id,\n kind: item.kind,\n parentId: item.parentId,\n size: item.size,\n updatedAt: item.updatedAt,\n documentType: item.documentType,\n signatureStatus: item.signatureStatus,\n })),\n getItemNames: (ids) => {\n const wanted = new Set(ids);\n return stateRef.current.items\n .filter((item) => wanted.has(item.id))\n .map((item) => ({ id: item.id, name: item.name }));\n },\n openItem: (itemId) => {\n const item = stateRef.current.items.find((i) => i.id === itemId);\n if (item) actionsRef.current.openItem(item);\n },\n startRename: (itemId) => actionsRef.current.requestRename(itemId),\n getActiveAction: () => stateRef.current.activeAction.type,\n }),\n [],\n );\n\n useImperativeHandle(ref, () => handle, [handle]);\n useAgentRegistration(fileManagerAgent, handle, id);\n\n /* ---------------- render ---------------- */\n\n const renameItem =\n activeAction.type === 'rename'\n ? itemsById.get(activeAction.itemId)\n : undefined;\n\n if (isLoading) {\n return (\n <div\n data-component=\"file-manager\"\n data-component-id={id}\n role=\"region\"\n aria-label={t('fileManager.regionLabel', 'File manager')}\n aria-busy=\"true\"\n className={fileManagerVariants({ bordered, className })}\n >\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <Skeleton variant=\"rectangular\" size=\"sm\" className=\"ds:w-24\" />\n <Skeleton\n variant=\"rectangular\"\n size=\"sm\"\n className=\"ds:ms-auto ds:w-48\"\n />\n </div>\n <Skeleton variant=\"text\" size=\"sm\" className=\"ds:w-40\" />\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {[0, 1, 2, 3, 4].map((row) => (\n <Skeleton key={row} variant=\"rectangular\" size=\"sm\" />\n ))}\n </div>\n </div>\n );\n }\n\n const toolbarActions = (\n <FileManagerToolbar\n selectedIds={selectedIds}\n permissions={can}\n onRequestCreateFolder={requestCreateFolder}\n onRequestUpload={uploadEnabled ? requestUpload : undefined}\n addMenuItems={addMenuItems}\n onRequestRename={requestRename}\n onRequestMove={requestMove}\n onRequestDelete={requestDelete}\n onDownload={\n can.download && onDownloadItems ? handleDownload : undefined\n }\n onShare={can.share && onShare ? handleShare : undefined}\n />\n );\n\n return (\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- container-level keyboard shortcuts + drag-and-drop upload; interactive children remain individually operable\n <div\n data-component=\"file-manager\"\n data-component-id={id}\n role=\"region\"\n aria-label={t('fileManager.regionLabel', 'File manager')}\n onKeyDown={handleRootKeyDown}\n onDragEnter={uploadEnabled ? handleDragEnter : undefined}\n onDragOver={uploadEnabled ? handleDragOver : undefined}\n onDragLeave={uploadEnabled ? handleDragLeave : undefined}\n onDrop={uploadEnabled ? handleDrop : undefined}\n className={fileManagerVariants({ bordered, className })}\n >\n <div className=\"ds:flex ds:min-h-0 ds:items-start ds:gap-[var(--spacing-md)]\">\n {showTree && (\n <div className=\"ds:hidden ds:w-56 ds:shrink-0 ds:md:block\">\n <FolderTree\n items={items}\n selectedFolderId={currentFolderId}\n onSelectFolder={navigateTo}\n aria-label={t('fileManager.treeLabel', 'Folders')}\n />\n </div>\n )}\n\n <div\n ref={contentRef}\n tabIndex={-1}\n className=\"ds:min-w-0 ds:flex-1 ds:outline-none\"\n >\n {folderChildren.length === 0 ? (\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={t(\n 'fileManager.empty.folderTitle',\n 'This folder is empty',\n )}\n description={t(\n 'fileManager.empty.folderDescription',\n 'Upload files or create a folder to get started.',\n )}\n />\n ) : (\n /* Remount on folder change so the DataTable's column filters\n reset cleanly for the new folder. */\n <ListView\n key={currentFolderId ?? '__root__'}\n items={folderDescendants}\n currentFolderId={currentFolderId}\n selectedIds={selectedIds}\n previewedItemId={previewedItemId ?? null}\n onSelectionChange={setSelection}\n onOpen={openItem}\n onRowActivate={activateRow}\n can={canItem}\n onRequestRename={requestRename}\n onRequestMove={requestMove}\n onRequestDelete={requestDelete}\n onDownload={\n can.download && onDownloadItems ? handleDownload : undefined\n }\n onShare={can.share && onShare ? handleShare : undefined}\n onRequestSignature={onRequestSignature}\n itemActions={itemActions}\n groupByFolder={groupByFolder}\n gridId={id ? `${id}-list` : undefined}\n tableRef={dataTableRef}\n toolbarActions={toolbarActions}\n />\n )}\n </div>\n </div>\n\n {/* Footer path bar. The breadcrumb wraps its children in its own\n BreadcrumbList (the single <ol>), injects separators, and marks the\n final item current — the last crumb renders as plain text. Pass\n items directly; never nest a second BreadcrumbList (invalid\n <ol><ol>). Root + ancestors stay clickable to navigate up.\n `disableCollapse`: our ancestor crumbs are `asChild` <button>s (the\n path navigates in-memory, not by href), and the collapsed-ellipsis\n rebuild would wrap those in an <a> (nested interactive). A compact\n footer path doesn't need collapse, so we keep every crumb inline. */}\n <div className=\"ds:mt-[var(--spacing-sm)] ds:border-t ds:border-[color:var(--border)] ds:pt-[var(--spacing-sm)] ds:text-muted-foreground\">\n <Breadcrumb\n aria-label={t('fileManager.breadcrumbLabel', 'Folder path')}\n disableCollapse\n >\n <BreadcrumbItem>\n {path.length === 0 ? (\n <BreadcrumbLink>\n {t('fileManager.rootLabel', 'All files')}\n </BreadcrumbLink>\n ) : (\n <BreadcrumbLink asChild>\n <button type=\"button\" onClick={() => navigateTo(null)}>\n {t('fileManager.rootLabel', 'All files')}\n </button>\n </BreadcrumbLink>\n )}\n </BreadcrumbItem>\n {path.map((folder, index) => (\n <BreadcrumbItem key={folder.id}>\n {index === path.length - 1 ? (\n <BreadcrumbLink>{folder.name}</BreadcrumbLink>\n ) : (\n <BreadcrumbLink asChild>\n <button type=\"button\" onClick={() => navigateTo(folder.id)}>\n {folder.name}\n </button>\n </BreadcrumbLink>\n )}\n </BreadcrumbItem>\n ))}\n </Breadcrumb>\n </div>\n\n {/* Selection-count live region — always visually hidden. The DataTable\n already renders a VISIBLE \"N rows selected\" status bar, so showing\n our own count too duplicated it; we keep this only as the polite\n announcement (the DataTable's count is a plain span, not a live\n region) so the count is still spoken on Space toggle / Ctrl+A. */}\n <p role=\"status\" aria-live=\"polite\" className=\"ds:sr-only\">\n {selectedIds.length > 0\n ? t('fileManager.selected', '{{count}} items selected', {\n count: selectedIds.length,\n })\n : ''}\n </p>\n\n {isDraggingFiles && (\n <div\n aria-hidden=\"true\"\n className=\"ds:pointer-events-none ds:absolute ds:inset-0 ds:z-20 ds:flex ds:flex-col ds:items-center ds:justify-center ds:gap-[var(--spacing-sm)] ds:rounded-[var(--radius-lg)] ds:border-2 ds:border-dashed ds:border-primary ds:bg-primary/10\"\n >\n <Upload className=\"ds:size-8 ds:text-primary\" />\n <span className=\"type-label ds:text-primary\">\n {t(\n 'fileManager.dropOverlay',\n 'Drop files to upload to {{folder}}',\n {\n folder: currentFolderName,\n },\n )}\n </span>\n </div>\n )}\n\n <span\n ref={liveRef}\n role=\"status\"\n aria-live=\"polite\"\n className=\"ds:sr-only\"\n />\n\n <CreateFolderDialog\n open={activeAction.type === 'create-folder'}\n onOpenChange={(open) => {\n if (!open) endAction();\n }}\n onSubmit={submitCreateFolder}\n />\n <UploadDialog\n open={activeAction.type === 'upload'}\n onOpenChange={(open) => {\n if (!open) endAction();\n }}\n onUpload={uploadToCurrentFolder}\n destinationLabel={currentFolderName}\n config={uploadConfig}\n />\n <RenameDialog\n open={activeAction.type === 'rename'}\n onOpenChange={(open) => {\n if (!open) endAction();\n }}\n initialName={renameItem?.name ?? ''}\n onSubmit={submitRename}\n />\n <DeleteDialog\n open={activeAction.type === 'delete'}\n onOpenChange={(open) => {\n if (!open) endAction();\n }}\n count={\n activeAction.type === 'delete' ? activeAction.itemIds.length : 0\n }\n onConfirm={submitDelete}\n />\n <MoveDialog\n open={activeAction.type === 'move'}\n onOpenChange={(open) => {\n if (!open) endAction();\n }}\n items={items}\n movingIds={activeAction.type === 'move' ? activeAction.itemIds : []}\n currentFolderId={currentFolderId}\n onConfirm={submitMove}\n />\n </div>\n );\n },\n);\n\nFileManager.displayName = 'FileManager';\n"],"names":["__iconNode","FileHeadphone","createLucideIcon","FilePlay","FolderInput","FolderOpen","FolderPlus","Folder","ITEM_META_SCHEMA","fileManagerAgent","handle","args","UNIT_KEYS","UNIT_FALLBACKS","formatFileSize","bytes","locale","t","value","unitIndex","getItemIcon","item","mime","FileImage","FileText","FileArchive","FileSpreadsheet","FileIcon","childrenOf","items","folderId","collator","i","b","descendantsOf","includedIds","grew","a","pathWithinFolder","itemsById","currentFolderId","path","cursor","seen","pathTo","byId","withDescendantFolderIds","ids","excluded","sameIdSet","set","id","ROOT_KEY","keyOf","treeItemRowVariants","cva","buildTree","excludeIds","build","flattenVisible","root","expanded","out","walk","node","parentKeyOf","_a","FolderTree","selectedFolderId","onSelectFolder","ariaLabel","i18n","useTranslation","isRtl","useMemo","setExpanded","useState","focusedKey","setFocusedKey","itemRefs","useRef","useEffect","prev","next","visible","n","focusNode","key","toggleExpanded","force","handleTreeKeyDown","event","target","index","hasChildren","isExpanded","expandKey","collapseKey","parentKey","renderNode","isSelected","label","IconComponent","handleRowClick","handleChevronClick","jsxs","el","jsx","ChevronRight","FORBIDDEN_NAME_CHARS","NAME_MAX_LENGTH","sanitizeName","CreateFolderDialog","open","onOpenChange","onSubmit","inputId","useId","name","setName","handleSubmit","trimmed","Dialog","TextInput","Button","UploadDialog","onUpload","destinationLabel","config","FileUpload","RenameDialog","initialName","DeleteDialog","count","onConfirm","MoveDialog","movingIds","setTarget","SIGNATURE_VARIANT","makeNameCellRenderer","previewedItemId","props","isPreviewed","TypeCellRenderer","Badge","makeSignatureCellRenderer","status","ListView","selectedIds","onSelectionChange","onOpen","onRowActivate","can","onRequestRename","onRequestMove","onRequestDelete","onDownload","onShare","onRequestSignature","itemActions","groupByFolder","gridId","tableRef","toolbarActions","hasSignatureColumn","hasTypeColumn","rowActions","actions","Download","data","PenLine","Share2","Pencil","Trash2","resolvedIds","action","actionId","columnDefs","SignatureCellRenderer","NameCellRenderer","defs","params","ActionsCellRenderer","actionsColumnWidth","gridOptions","options","dom","handleSelectionChanged","rows","row","getRowClass","useCallback","DataTable","FileManagerToolbar","permissions","onRequestCreateFolder","onRequestUpload","addMenuItems","hasSelection","singleSelection","canUpload","canDownload","canShare","extraAddItems","IconButtonGroup","IconButton","Upload","entry","Plus","fileManagerVariants","ALL_PERMISSIONS","FileManager","forwardRef","folderIdProp","defaultFolderId","onNavigate","showTree","isLoading","onOpenFile","onCreateFolder","onRenameItem","onDeleteItems","onMoveItems","onDownloadItems","uploadConfig","onPreviewItem","bordered","className","ref","resolvePerms","canItem","folderRaw","setFolder","useControllableState","setSelectedIdsRaw","activeAction","setActiveAction","isDraggingFiles","setIsDraggingFiles","dragDepth","dataTableRef","liveRef","announce","message","contentRef","focusContentAfterNav","setSelection","valid","itemId","navigateTo","targetId","breadcrumbTargetId","folderChildren","folderDescendants","currentFolderName","beginAction","endAction","requestCreateFolder","requestUpload","requestRename","requestDelete","itemIds","allowed","requestMove","handleDownload","handleShare","openItem","activateRow","submitCreateFolder","submitRename","submitDelete","submitMove","targetFolderId","uploadToCurrentFolder","file","helpers","uploadEnabled","isFileDrag","handleDragEnter","handleDragOver","handleDragLeave","handleDrop","handleRootKeyDown","only","stateRef","actionsRef","documentTypes","api","wanted","useImperativeHandle","useAgentRegistration","renameItem","Skeleton","EmptyState","Breadcrumb","BreadcrumbItem","BreadcrumbLink","folder"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5]}
1
+ {"version":3,"file":"file-manager-lAeBBfZi.js","sources":["../../node_modules/lucide-react/dist/esm/icons/file-headphone.mjs","../../node_modules/lucide-react/dist/esm/icons/file-play.mjs","../../node_modules/lucide-react/dist/esm/icons/folder-input.mjs","../../node_modules/lucide-react/dist/esm/icons/folder-open.mjs","../../node_modules/lucide-react/dist/esm/icons/folder-plus.mjs","../../node_modules/lucide-react/dist/esm/icons/folder.mjs","../../src/components/file-manager/file-manager.agent.ts","../../src/components/file-manager/utils.ts","../../src/components/file-manager/folder-tree.tsx","../../src/components/file-manager/dialogs.tsx","../../src/components/file-manager/list-view.tsx","../../src/components/file-manager/toolbar.tsx","../../src/components/file-manager/file-manager.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M4 6.835V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2h-.343\",\n key: \"1vfytu\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\n \"path\",\n {\n d: \"M2 19a2 2 0 0 1 4 0v1a2 2 0 0 1-4 0v-4a6 6 0 0 1 12 0v4a2 2 0 0 1-4 0v-1a2 2 0 0 1 4 0\",\n key: \"1etmh7\"\n }\n ]\n];\nconst FileHeadphone = createLucideIcon(\"file-headphone\", __iconNode);\n\nexport { __iconNode, FileHeadphone as default };\n//# sourceMappingURL=file-headphone.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\",\n key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\n \"path\",\n {\n d: \"M15.033 13.44a.647.647 0 0 1 0 1.12l-4.065 2.352a.645.645 0 0 1-.968-.56v-4.704a.645.645 0 0 1 .967-.56z\",\n key: \"1tzo1f\"\n }\n ]\n];\nconst FilePlay = createLucideIcon(\"file-play\", __iconNode);\n\nexport { __iconNode, FilePlay as default };\n//# sourceMappingURL=file-play.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2 9V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-1\",\n key: \"fm4g5t\"\n }\n ],\n [\"path\", { d: \"M2 13h10\", key: \"pgb2dq\" }],\n [\"path\", { d: \"m9 16 3-3-3-3\", key: \"6m91ic\" }]\n];\nconst FolderInput = createLucideIcon(\"folder-input\", __iconNode);\n\nexport { __iconNode, FolderInput as default };\n//# sourceMappingURL=folder-input.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2\",\n key: \"usdka0\"\n }\n ]\n];\nconst FolderOpen = createLucideIcon(\"folder-open\", __iconNode);\n\nexport { __iconNode, FolderOpen as default };\n//# sourceMappingURL=folder-open.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 10v6\", key: \"1bos4e\" }],\n [\"path\", { d: \"M9 13h6\", key: \"1uhe8q\" }],\n [\n \"path\",\n {\n d: \"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z\",\n key: \"1kt360\"\n }\n ]\n];\nconst FolderPlus = createLucideIcon(\"folder-plus\", __iconNode);\n\nexport { __iconNode, FolderPlus as default };\n//# sourceMappingURL=folder-plus.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z\",\n key: \"1kt360\"\n }\n ]\n];\nconst Folder = createLucideIcon(\"folder\", __iconNode);\n\nexport { __iconNode, Folder as default };\n//# sourceMappingURL=folder.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — FileManager. */\n/* */\n/* PHI rule (PRS §26 §6): item display names are patient-identifiable */\n/* document titles. No always-on state slot ever returns a name — the */\n/* structural `items` snapshot carries ids/kinds/sizes/dates only. The */\n/* single name-returning read is the deliberate `get_item_names` action */\n/* with `safety: 'phi'`, so the host gates it behind confirm + audit. */\n/* */\n/* Mutations (upload/rename/move/delete) resolve through host callbacks */\n/* + confirmation dialogs and are NOT exposed as agent actions — the */\n/* adapter surface is view state, selection, navigation and reads. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { FileManagerHandle } from './types';\n\nconst ITEM_META_SCHEMA = {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n kind: { enum: ['file', 'folder'] },\n parentId: {\n type: ['string', 'null'],\n description: 'Parent folder id, null at the root.',\n },\n size: { type: 'number', description: 'Bytes — files only.' },\n updatedAt: { type: 'string', description: 'ISO 8601 timestamp.' },\n documentType: {\n type: 'string',\n description: 'Document-type category (non-identifying).',\n },\n signatureStatus: {\n enum: ['none', 'pending', 'signed'],\n description: 'Signature workflow state.',\n },\n },\n required: ['id', 'kind', 'parentId'],\n },\n} as const;\n\nexport const fileManagerAgent: AgentAdapter<FileManagerHandle> = {\n id: 'file-manager',\n // select_multiple → select_items / clear_selection; navigate → navigate;\n // filter → set_type_filter (proxied to the DataTable's documentType column);\n // open → open_item. Preview is NOT an agent action — item content can be PHI.\n capabilities: ['select_multiple', 'navigate', 'filter', 'open'],\n state: {\n selection: {\n type: 'string[]',\n descriptionKey: 'ui.agent.fileManager.state.selection',\n description: 'Item ids of the currently-selected files and folders.',\n read: (handle) => handle.getSelection(),\n },\n currentFolder: {\n type: 'string | null',\n descriptionKey: 'ui.agent.fileManager.state.currentFolder',\n description: 'Id of the folder being viewed, or null for the root.',\n read: (handle) => handle.getCurrentFolderId(),\n },\n typeFilter: {\n type: 'string[]',\n descriptionKey: 'ui.agent.fileManager.state.typeFilter',\n description:\n 'Active document-type filter applied to the open folder (empty = no filter).',\n read: (handle) => handle.getTypeFilter(),\n },\n items: {\n type: 'Array<{ id, kind, parentId, size, updatedAt, documentType, signatureStatus }>',\n descriptionKey: 'ui.agent.fileManager.state.items',\n description:\n 'Structural metadata for every item — ids, kinds, sizes, dates, document types, signature states. Names are PHI and never included; read them via get_item_names.',\n read: (handle) => handle.getItems(),\n },\n activeAction: {\n type: \"'none' | 'create-folder' | 'rename' | 'delete' | 'move'\",\n descriptionKey: 'ui.agent.fileManager.state.activeAction',\n description:\n 'The single in-flight action dialog. Only one action can be active at a time.',\n read: (handle) => handle.getActiveAction(),\n },\n },\n actions: {\n select_items: {\n // Transient view selection (data-table convention) — stays read.\n safety: 'read',\n argsType: '{ ids: string[] }',\n argsSchema: {\n type: 'object',\n properties: {\n ids: {\n type: 'array',\n items: { type: 'string' },\n description: 'Item ids to select (replaces the current selection).',\n },\n },\n required: ['ids'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.fileManager.actions.selectItems',\n description: 'Replace the current selection with the given item ids.',\n examples: [\n { args: { ids: ['doc-1', 'doc-2'] }, note: 'Select two items.' },\n ],\n invoke: (handle, args: { ids: string[] }) => {\n handle.setSelection(args.ids);\n },\n },\n clear_selection: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.fileManager.actions.clearSelection',\n description: 'Deselect every item.',\n invoke: (handle) => {\n handle.clearSelection();\n },\n },\n navigate: {\n safety: 'read',\n argsType: '{ folderId: string | null }',\n argsSchema: {\n type: 'object',\n properties: {\n folderId: {\n type: ['string', 'null'],\n description: 'Folder id to open, or null for the root.',\n },\n },\n required: ['folderId'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.fileManager.actions.navigate',\n description:\n 'Open the given folder (null for the root). Clears the current selection.',\n invoke: (handle, args: { folderId: string | null }) => {\n handle.navigateTo(args.folderId);\n },\n },\n set_type_filter: {\n safety: 'read',\n argsType: '{ documentTypes: string[] }',\n argsSchema: {\n type: 'object',\n properties: {\n documentTypes: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Document-type values to keep. Empty array clears the filter.',\n },\n },\n required: ['documentTypes'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.fileManager.actions.setTypeFilter',\n description:\n 'Filter the open folder to the given document types (empty clears the filter).',\n invoke: (handle, args: { documentTypes: string[] }) => {\n handle.setTypeFilter(args.documentTypes);\n },\n },\n open_item: {\n safety: 'read',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'Item id — folders navigate, files open via the host.',\n },\n },\n required: ['id'],\n },\n // Opening a file resolves through the host's onOpenFile callback,\n // which may reach a viewer outside this UI.\n openWorld: true,\n descriptionKey: 'ui.agent.fileManager.actions.openItem',\n description:\n 'Open an item: folders navigate into the folder, files resolve through the host preview callback.',\n invoke: (handle, args: { id: string }) => {\n handle.openItem(args.id);\n },\n },\n list_items: {\n safety: 'read',\n argsType: '{ folderId?: string | null }',\n argsSchema: {\n type: 'object',\n properties: {\n folderId: {\n type: ['string', 'null'],\n description:\n 'Folder whose children to list (null = root). Omit for every item.',\n },\n },\n },\n returns: 'Array<{ id, kind, parentId, size, updatedAt }>',\n returnsSchema: ITEM_META_SCHEMA as unknown as Record<string, unknown>,\n idempotent: true,\n descriptionKey: 'ui.agent.fileManager.actions.listItems',\n description:\n 'List structural metadata (ids, kinds, sizes, dates — never names) for a folder or the whole tree.',\n invoke: (handle, args: { folderId?: string | null }) =>\n handle.getItems(args?.folderId),\n },\n get_item_names: {\n // phi (not read): resolves display names, which can identify patients\n // (e.g. \"Rossi Maria — referto 2026.pdf\"). PRS §26 — phi outranks read\n // so the host gates it behind stricter confirm + audit. The always-on\n // items snapshot stays name-free.\n safety: 'phi',\n argsType: '{ ids: string[] }',\n argsSchema: {\n type: 'object',\n properties: {\n ids: {\n type: 'array',\n items: { type: 'string' },\n description: 'Item ids whose display names to read.',\n },\n },\n required: ['ids'],\n },\n returns: 'Array<{ id: string; name: string }>',\n returnsSchema: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n name: { type: 'string' },\n },\n required: ['id', 'name'],\n },\n },\n idempotent: true,\n descriptionKey: 'ui.agent.fileManager.actions.getItemNames',\n description:\n 'Read the display names for the given item ids. Names may identify patients (PHI).',\n invoke: (handle, args: { ids: string[] }) =>\n handle.getItemNames(args.ids),\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'file-manager',\n description: 'Marks the FileManager region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n item: {\n attr: 'data-item-id',\n description:\n 'Grid cards and folder-tree nodes carry the item id as data-item-id (ids only — never names). List-view rows are AG Grid rows inside the composed DataTable and carry its native row-id attribute keyed to the same ids.',\n },\n },\n};\n","/* -------------------------------------------------------------------- */\n/* FileManager — pure helpers (no React). */\n/* -------------------------------------------------------------------- */\n\nimport {\n File as FileIcon,\n FileArchive,\n FileHeadphone,\n FileImage,\n FileSpreadsheet,\n FileText,\n FilePlay,\n Folder,\n type LucideIcon,\n} from 'lucide-react';\nimport type { FileManagerItem } from './types';\n\nconst UNIT_KEYS = [\n 'fileManager.units.bytes',\n 'fileManager.units.kilobytes',\n 'fileManager.units.megabytes',\n 'fileManager.units.gigabytes',\n] as const;\n\nconst UNIT_FALLBACKS = ['B', 'KB', 'MB', 'GB'] as const;\n\nexport function formatFileSize(\n bytes: number,\n locale: string,\n t: (key: string, fallback: string) => string,\n): string {\n let value = bytes;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < UNIT_FALLBACKS.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n const formatted = new Intl.NumberFormat(locale, {\n maximumFractionDigits: unitIndex === 0 ? 0 : 1,\n }).format(value);\n return `${formatted} ${t(UNIT_KEYS[unitIndex], UNIT_FALLBACKS[unitIndex])}`;\n}\n\n/** Icon component per item — folders first, then a MIME-family lookup. */\nexport function getItemIcon(item: FileManagerItem): LucideIcon {\n if (item.kind === 'folder') return Folder;\n const mime = item.mimeType ?? '';\n if (mime.startsWith('image/')) return FileImage;\n if (mime.startsWith('audio/')) return FileHeadphone;\n if (mime.startsWith('video/')) return FilePlay;\n if (\n mime === 'application/pdf' ||\n mime.startsWith('text/') ||\n mime.includes('word') ||\n mime.includes('rtf')\n ) {\n return FileText;\n }\n if (\n mime.includes('zip') ||\n mime.includes('compressed') ||\n mime.includes('tar')\n ) {\n return FileArchive;\n }\n if (\n mime.includes('spreadsheet') ||\n mime.includes('excel') ||\n mime === 'text/csv'\n ) {\n return FileSpreadsheet;\n }\n return FileIcon;\n}\n\n/** Children of a folder, folders first, then locale-aware by name. */\nexport function childrenOf(\n items: FileManagerItem[],\n folderId: string | null,\n locale: string,\n): FileManagerItem[] {\n const collator = new Intl.Collator(locale, {\n numeric: true,\n sensitivity: 'base',\n });\n return items\n .filter((i) => i.parentId === folderId)\n .sort((a, b) => {\n if (a.kind !== b.kind) return a.kind === 'folder' ? -1 : 1;\n return collator.compare(a.name, b.name);\n });\n}\n\n/**\n * Every item whose ancestry passes through `folderId` (folders + files, any\n * depth) — the full subtree beneath a folder, excluding the folder itself.\n * Feeds AG Grid Tree Data when `groupByFolder` is on (the flat `childrenOf`\n * only returns the immediate level). Sort order matches `childrenOf` — folders\n * first, then locale-aware by name — so sibling order is stable at every depth.\n */\nexport function descendantsOf(\n items: FileManagerItem[],\n folderId: string | null,\n locale: string,\n): FileManagerItem[] {\n const includedIds = new Set<string>();\n // Seed with the current folder's direct children.\n for (const item of items) {\n if (item.parentId === folderId) includedIds.add(item.id);\n }\n // Expand transitively: any item whose parent is already in the subtree joins.\n let grew = true;\n while (grew) {\n grew = false;\n for (const item of items) {\n if (includedIds.has(item.id)) continue;\n if (item.parentId !== null && includedIds.has(item.parentId)) {\n includedIds.add(item.id);\n grew = true;\n }\n }\n }\n const collator = new Intl.Collator(locale, {\n numeric: true,\n sensitivity: 'base',\n });\n return items\n .filter((i) => includedIds.has(i.id))\n .sort((a, b) => {\n if (a.kind !== b.kind) return a.kind === 'folder' ? -1 : 1;\n return collator.compare(a.name, b.name);\n });\n}\n\n/**\n * AG Grid Tree Data path for an item: the id-chain from the current folder's\n * direct child down to (and including) the item. Walk `parentId` up, stopping\n * at `currentFolderId` (exclusive), then reverse and append the item's own id.\n * Every returned id is a real folder/file row, so AG Grid never synthesises\n * filler group rows. `itemsById` need only cover the current subtree.\n */\nexport function pathWithinFolder(\n item: FileManagerItem,\n itemsById: Map<string, FileManagerItem>,\n currentFolderId: string | null,\n): string[] {\n const path: string[] = [];\n let cursor: FileManagerItem | undefined = item;\n const seen = new Set<string>();\n while (cursor && !seen.has(cursor.id)) {\n seen.add(cursor.id);\n path.unshift(cursor.id);\n if (cursor.parentId === currentFolderId) break;\n cursor =\n cursor.parentId === null ? undefined : itemsById.get(cursor.parentId);\n }\n return path;\n}\n\n/** Path from the root down to `folderId` (exclusive of the virtual root). */\nexport function pathTo(\n items: FileManagerItem[],\n folderId: string | null,\n): FileManagerItem[] {\n const byId = new Map(items.map((i) => [i.id, i]));\n const path: FileManagerItem[] = [];\n let cursor = folderId === null ? undefined : byId.get(folderId);\n const seen = new Set<string>();\n while (cursor && !seen.has(cursor.id)) {\n seen.add(cursor.id);\n path.unshift(cursor);\n cursor = cursor.parentId === null ? undefined : byId.get(cursor.parentId);\n }\n return path;\n}\n\n/**\n * Ids of the given folders plus every folder nested inside them. Used to\n * exclude invalid targets from the move-destination tree (a folder can never\n * be moved into itself or one of its descendants).\n */\nexport function withDescendantFolderIds(\n items: FileManagerItem[],\n ids: string[],\n): Set<string> {\n const excluded = new Set(ids);\n let grew = true;\n while (grew) {\n grew = false;\n for (const item of items) {\n if (\n item.kind === 'folder' &&\n !excluded.has(item.id) &&\n item.parentId !== null &&\n excluded.has(item.parentId)\n ) {\n excluded.add(item.id);\n grew = true;\n }\n }\n }\n return excluded;\n}\n\n/** True when the two id lists contain the same set of ids. */\nexport function sameIdSet(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n const set = new Set(a);\n return b.every((id) => set.has(id));\n}\n","/* -------------------------------------------------------------------- */\n/* FileManager — folder tree (internal). */\n/* */\n/* WAI-ARIA tree: nested `role=\"group\"` lists under a `role=\"tree\"` */\n/* root, roving tabindex, Arrow/Home/End/Enter keyboard handling scoped */\n/* to the tree element. Reused by the move dialog as a destination */\n/* picker (`excludeIds` removes invalid targets). */\n/* -------------------------------------------------------------------- */\n\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ChevronRight, Folder, FolderOpen } from 'lucide-react';\nimport type { FileManagerItem } from './types';\nimport { childrenOf } from './utils';\n\n/** Key used for the virtual root node (`folderId === null`). */\nconst ROOT_KEY = '__root__';\n\nconst keyOf = (folderId: string | null): string => folderId ?? ROOT_KEY;\n\nconst treeItemRowVariants = cva(\n [\n 'ds:flex ds:items-center ds:gap-[var(--spacing-xs)]',\n 'ds:min-h-[var(--min-target-size)] ds:w-full',\n 'ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:text-[length:var(--font-size-sm)]',\n 'ds:cursor-pointer ds:select-none',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n selected: {\n true: 'ds:bg-primary/10 ds:text-primary ds:font-medium',\n false: 'ds:text-foreground ds:hover:bg-muted/10',\n },\n },\n defaultVariants: { selected: false },\n },\n);\n\ninterface TreeNode {\n key: string;\n folderId: string | null;\n item?: FileManagerItem;\n children: TreeNode[];\n}\n\nexport interface FolderTreeProps {\n items: FileManagerItem[];\n /** Folder highlighted as selected — `null` selects the virtual root. */\n selectedFolderId: string | null;\n onSelectFolder: (folderId: string | null) => void;\n 'aria-label': string;\n /** Folder ids to omit from the tree (move dialog: item + descendants). */\n excludeIds?: Set<string>;\n}\n\nfunction buildTree(\n items: FileManagerItem[],\n locale: string,\n excludeIds?: Set<string>,\n): TreeNode {\n const build = (folderId: string | null): TreeNode[] =>\n childrenOf(items, folderId, locale)\n .filter((i) => i.kind === 'folder' && !excludeIds?.has(i.id))\n .map((item) => ({\n key: keyOf(item.id),\n folderId: item.id,\n item,\n children: build(item.id),\n }));\n return { key: ROOT_KEY, folderId: null, children: build(null) };\n}\n\nfunction flattenVisible(root: TreeNode, expanded: Set<string>): TreeNode[] {\n const out: TreeNode[] = [];\n const walk = (node: TreeNode) => {\n out.push(node);\n if (expanded.has(node.key)) node.children.forEach(walk);\n };\n walk(root);\n return out;\n}\n\nfunction parentKeyOf(node: TreeNode): string | null {\n if (node.folderId === null) return null;\n return keyOf(node.item?.parentId ?? null);\n}\n\nexport function FolderTree({\n items,\n selectedFolderId,\n onSelectFolder,\n 'aria-label': ariaLabel,\n excludeIds,\n}: FolderTreeProps) {\n const { t, i18n } = useTranslation();\n const isRtl = i18n.dir() === 'rtl';\n\n const root = useMemo(\n () => buildTree(items, i18n.language, excludeIds),\n [items, i18n.language, excludeIds],\n );\n\n const [expanded, setExpanded] = useState<Set<string>>(\n () => new Set([ROOT_KEY]),\n );\n const [focusedKey, setFocusedKey] = useState<string>(keyOf(selectedFolderId));\n const itemRefs = useRef<Map<string, HTMLLIElement>>(new Map());\n\n // Reveal the selected folder: expand every ancestor when it changes.\n useEffect(() => {\n setExpanded((prev) => {\n const next = new Set(prev);\n next.add(ROOT_KEY);\n const byId = new Map(items.map((i) => [i.id, i]));\n let cursor = selectedFolderId ? byId.get(selectedFolderId) : undefined;\n const seen = new Set<string>();\n while (cursor && !seen.has(cursor.id)) {\n seen.add(cursor.id);\n if (cursor.parentId !== null) next.add(keyOf(cursor.parentId));\n cursor =\n cursor.parentId === null ? undefined : byId.get(cursor.parentId);\n }\n return next;\n });\n setFocusedKey(keyOf(selectedFolderId));\n }, [selectedFolderId, items]);\n\n const visible = useMemo(\n () => flattenVisible(root, expanded),\n [root, expanded],\n );\n\n // Keep the roving-tabindex target valid when folders disappear.\n useEffect(() => {\n if (!visible.some((n) => n.key === focusedKey)) {\n setFocusedKey(visible[0]?.key ?? ROOT_KEY);\n }\n }, [visible, focusedKey]);\n\n const focusNode = (key: string) => {\n setFocusedKey(key);\n itemRefs.current.get(key)?.focus();\n };\n\n const toggleExpanded = (key: string, force?: boolean) => {\n setExpanded((prev) => {\n const next = new Set(prev);\n const open = force ?? !next.has(key);\n if (open) next.add(key);\n else next.delete(key);\n return next;\n });\n };\n\n const handleTreeKeyDown = (event: KeyboardEvent<HTMLUListElement>) => {\n const target = (event.target as HTMLElement).closest<HTMLElement>(\n '[data-tree-key]',\n );\n const key = target?.getAttribute('data-tree-key');\n if (!key) return;\n const index = visible.findIndex((n) => n.key === key);\n if (index < 0) return;\n const node = visible[index];\n const hasChildren = node.children.length > 0;\n const isExpanded = expanded.has(key);\n\n // Logical expand/collapse keys — flipped in RTL.\n const expandKey = isRtl ? 'ArrowLeft' : 'ArrowRight';\n const collapseKey = isRtl ? 'ArrowRight' : 'ArrowLeft';\n\n switch (event.key) {\n case 'ArrowDown':\n if (index < visible.length - 1) focusNode(visible[index + 1].key);\n break;\n case 'ArrowUp':\n if (index > 0) focusNode(visible[index - 1].key);\n break;\n case expandKey:\n if (hasChildren && !isExpanded) toggleExpanded(key, true);\n else if (hasChildren && isExpanded) focusNode(node.children[0].key);\n break;\n case collapseKey: {\n if (hasChildren && isExpanded) {\n toggleExpanded(key, false);\n } else {\n const parentKey = parentKeyOf(node);\n if (parentKey !== null) focusNode(parentKey);\n }\n break;\n }\n case 'Home':\n focusNode(visible[0].key);\n break;\n case 'End':\n focusNode(visible[visible.length - 1].key);\n break;\n case 'Enter':\n case ' ':\n onSelectFolder(node.folderId);\n break;\n default:\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n };\n\n const renderNode = (node: TreeNode): ReactElement => {\n const isSelected = keyOf(selectedFolderId) === node.key;\n const isExpanded = expanded.has(node.key);\n const hasChildren = node.children.length > 0;\n const label =\n node.folderId === null\n ? t('fileManager.rootLabel', 'All files')\n : (node.item?.name ?? '');\n const IconComponent = isExpanded && hasChildren ? FolderOpen : Folder;\n\n const handleRowClick = (event: MouseEvent<HTMLLIElement>) => {\n event.stopPropagation();\n setFocusedKey(node.key);\n onSelectFolder(node.folderId);\n if (hasChildren) toggleExpanded(node.key, true);\n };\n\n const handleChevronClick = (event: MouseEvent<HTMLSpanElement>) => {\n event.stopPropagation();\n toggleExpanded(node.key);\n };\n\n return (\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events -- treeitem row; keyboard operation is handled at the role=\"tree\" container via roving tabindex + onKeyDown\n <li\n key={node.key}\n ref={(el) => {\n if (el) itemRefs.current.set(node.key, el);\n else itemRefs.current.delete(node.key);\n }}\n role=\"treeitem\"\n aria-expanded={hasChildren ? isExpanded : undefined}\n aria-selected={isSelected}\n tabIndex={focusedKey === node.key ? 0 : -1}\n data-tree-key={node.key}\n data-item-id={node.folderId ?? undefined}\n onClick={handleRowClick}\n onFocus={() => setFocusedKey(node.key)}\n className={[\n 'ds:list-none ds:rounded-[var(--radius-md)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n ].join(' ')}\n >\n <div className={treeItemRowVariants({ selected: isSelected })}>\n {hasChildren ? (\n <span\n aria-hidden=\"true\"\n onClick={handleChevronClick}\n className=\"ds:inline-flex ds:size-5 ds:shrink-0 ds:items-center ds:justify-center ds:text-muted-foreground\"\n >\n <ChevronRight\n className={[\n 'ds:size-4',\n 'ds:transition-transform ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n isExpanded ? 'ds:rotate-90' : 'ds:rtl:rotate-180',\n ].join(' ')}\n />\n </span>\n ) : (\n <span aria-hidden=\"true\" className=\"ds:size-5 ds:shrink-0\" />\n )}\n <IconComponent\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0 ds:text-muted-foreground\"\n />\n <span className=\"ds:truncate ds:text-start\">{label}</span>\n </div>\n {hasChildren && isExpanded && (\n <ul\n role=\"group\"\n className=\"ds:m-0 ds:list-none ds:p-0 ds:ps-[var(--spacing-md)]\"\n >\n {node.children.map(renderNode)}\n </ul>\n )}\n </li>\n );\n };\n\n return (\n <ul\n role=\"tree\"\n aria-label={ariaLabel}\n onKeyDown={handleTreeKeyDown}\n className=\"ds:m-0 ds:flex ds:flex-col ds:gap-px ds:list-none ds:p-0\"\n data-testid=\"file-manager-tree\"\n >\n {renderNode(root)}\n </ul>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* FileManager — action dialogs (internal). */\n/* */\n/* One dialog per action of the single-active-action state machine. */\n/* Each is fully controlled by the parent (`open` mirrors the active */\n/* action) and resolves through a submit callback — no local mutation. */\n/* -------------------------------------------------------------------- */\n\nimport { useEffect, useId, useState, type FormEvent } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Button } from '../button';\nimport { Dialog } from '../dialog';\nimport { FileUpload } from '../file-upload';\nimport { TextInput } from '../text-input';\nimport { FolderTree } from './folder-tree';\nimport type { FileManagerItem, FileManagerUploadConfig } from './types';\nimport { withDescendantFolderIds } from './utils';\n\n/* Characters the platform rejects in document / folder names. Stripped on\n input so an invalid name can never be submitted, and the 128-char cap\n matches the platform name column — both guard data integrity without a\n locale string (the full inline-rename flow is tracked separately). */\nconst FORBIDDEN_NAME_CHARS = /[\\\\/:*?\"<>|]/g;\nconst NAME_MAX_LENGTH = 128;\n\nfunction sanitizeName(value: string): string {\n return value.replace(FORBIDDEN_NAME_CHARS, '').slice(0, NAME_MAX_LENGTH);\n}\n\n/* ------------------------------------------------------------------ */\n/* Create folder */\n/* ------------------------------------------------------------------ */\n\nexport interface CreateFolderDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSubmit: (name: string) => void;\n}\n\nexport function CreateFolderDialog({\n open,\n onOpenChange,\n onSubmit,\n}: CreateFolderDialogProps) {\n const { t } = useTranslation();\n const inputId = useId();\n const [name, setName] = useState('');\n\n useEffect(() => {\n if (open) setName('');\n }, [open]);\n\n const handleSubmit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const trimmed = name.trim();\n if (trimmed.length === 0) return;\n onSubmit(trimmed);\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content size=\"sm\">\n <Dialog.Header>\n <Dialog.Title>\n {t('fileManager.dialogs.createFolder.title', 'New folder')}\n </Dialog.Title>\n </Dialog.Header>\n <form onSubmit={handleSubmit}>\n <Dialog.Body>\n <label\n htmlFor={inputId}\n className=\"type-label ds:block ds:mb-[var(--spacing-xs)]\"\n >\n {t('fileManager.dialogs.createFolder.nameLabel', 'Folder name')}\n </label>\n <TextInput\n id={inputId}\n value={name}\n maxLength={NAME_MAX_LENGTH}\n onChange={(event) => setName(sanitizeName(event.target.value))}\n // eslint-disable-next-line jsx-a11y/no-autofocus -- intentional: focus the name field when the dialog opens\n autoFocus\n />\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button type=\"button\" intent=\"outline\">\n {t('fileManager.dialogs.createFolder.cancel', 'Cancel')}\n </Button>\n </Dialog.Close>\n <Button\n type=\"submit\"\n intent=\"primary\"\n disabled={name.trim().length === 0}\n >\n {t('fileManager.dialogs.createFolder.confirm', 'Create folder')}\n </Button>\n </Dialog.Footer>\n </form>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Upload (per-file queue via the kit FileUpload) */\n/* ------------------------------------------------------------------ */\n\nexport interface UploadDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Bound to the destination folder by the parent. */\n onUpload: (\n file: File,\n helpers: { signal: AbortSignal; onProgress: (percent: number) => void },\n ) => Promise<void>;\n /** Human-readable destination folder name (root label when at the root). */\n destinationLabel: string;\n config?: FileManagerUploadConfig;\n}\n\nexport function UploadDialog({\n open,\n onOpenChange,\n onUpload,\n destinationLabel,\n config,\n}: UploadDialogProps) {\n const { t } = useTranslation();\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content size=\"md\">\n <Dialog.Header>\n <Dialog.Title>\n {t('fileManager.dialogs.upload.title', 'Upload to {{folder}}', {\n folder: destinationLabel,\n })}\n </Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <FileUpload\n variant=\"both\"\n multiple={config?.multiple ?? true}\n accept={config?.accept}\n maxSize={config?.maxSize}\n onUpload={onUpload}\n />\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button type=\"button\" intent=\"outline\">\n {t('fileManager.dialogs.upload.close', 'Done')}\n </Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Rename */\n/* ------------------------------------------------------------------ */\n\nexport interface RenameDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Current name of the item being renamed. */\n initialName: string;\n onSubmit: (name: string) => void;\n}\n\nexport function RenameDialog({\n open,\n onOpenChange,\n initialName,\n onSubmit,\n}: RenameDialogProps) {\n const { t } = useTranslation();\n const inputId = useId();\n const [name, setName] = useState(initialName);\n\n useEffect(() => {\n if (open) setName(initialName);\n }, [open, initialName]);\n\n const handleSubmit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const trimmed = name.trim();\n if (trimmed.length === 0) return;\n onSubmit(trimmed);\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content size=\"sm\">\n <Dialog.Header>\n <Dialog.Title>\n {t('fileManager.dialogs.rename.title', 'Rename')}\n </Dialog.Title>\n </Dialog.Header>\n <form onSubmit={handleSubmit}>\n <Dialog.Body>\n <label\n htmlFor={inputId}\n className=\"type-label ds:block ds:mb-[var(--spacing-xs)]\"\n >\n {t('fileManager.dialogs.rename.nameLabel', 'New name')}\n </label>\n <TextInput\n id={inputId}\n value={name}\n maxLength={NAME_MAX_LENGTH}\n onChange={(event) => setName(sanitizeName(event.target.value))}\n // eslint-disable-next-line jsx-a11y/no-autofocus -- intentional: focus the name field when the dialog opens\n autoFocus\n />\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button type=\"button\" intent=\"outline\">\n {t('fileManager.dialogs.rename.cancel', 'Cancel')}\n </Button>\n </Dialog.Close>\n <Button\n type=\"submit\"\n intent=\"primary\"\n disabled={name.trim().length === 0}\n >\n {t('fileManager.dialogs.rename.confirm', 'Rename')}\n </Button>\n </Dialog.Footer>\n </form>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Delete (forced-choice confirmation) */\n/* ------------------------------------------------------------------ */\n\nexport interface DeleteDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n count: number;\n onConfirm: () => void;\n}\n\nexport function DeleteDialog({\n open,\n onOpenChange,\n count,\n onConfirm,\n}: DeleteDialogProps) {\n const { t } = useTranslation();\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content size=\"sm\" variant=\"alert\">\n <Dialog.Header>\n <Dialog.Title>\n {t('fileManager.dialogs.delete.title', 'Delete {{count}} items?', {\n count,\n })}\n </Dialog.Title>\n </Dialog.Header>\n <Dialog.Description>\n {t(\n 'fileManager.dialogs.delete.description',\n 'This action cannot be undone.',\n )}\n </Dialog.Description>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button type=\"button\" intent=\"outline\">\n {t('fileManager.dialogs.delete.cancel', 'Cancel')}\n </Button>\n </Dialog.Close>\n <Button type=\"button\" intent=\"destructive\" onClick={onConfirm}>\n {t('fileManager.dialogs.delete.confirm', 'Delete')}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Move (destination picker) */\n/* ------------------------------------------------------------------ */\n\nexport interface MoveDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Full item list — the destination tree is derived from its folders. */\n items: FileManagerItem[];\n /** Items being moved — they and their descendants are invalid targets. */\n movingIds: string[];\n /** Folder the mover starts from (pre-selected destination). */\n currentFolderId: string | null;\n onConfirm: (targetFolderId: string | null) => void;\n}\n\nexport function MoveDialog({\n open,\n onOpenChange,\n items,\n movingIds,\n currentFolderId,\n onConfirm,\n}: MoveDialogProps) {\n const { t } = useTranslation();\n const [target, setTarget] = useState<string | null>(currentFolderId);\n\n useEffect(() => {\n if (open) setTarget(currentFolderId);\n }, [open, currentFolderId]);\n\n const excluded = withDescendantFolderIds(items, movingIds);\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Content size=\"sm\">\n <Dialog.Header>\n <Dialog.Title>\n {t('fileManager.dialogs.move.title', 'Move {{count}} items', {\n count: movingIds.length,\n })}\n </Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <div className=\"ds:max-h-72 ds:overflow-y-auto ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)] ds:p-[var(--spacing-xs)]\">\n <FolderTree\n items={items}\n selectedFolderId={target}\n onSelectFolder={setTarget}\n aria-label={t(\n 'fileManager.dialogs.move.treeLabel',\n 'Destination folder',\n )}\n excludeIds={excluded}\n />\n </div>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button type=\"button\" intent=\"outline\">\n {t('fileManager.dialogs.move.cancel', 'Cancel')}\n </Button>\n </Dialog.Close>\n <Button\n type=\"button\"\n intent=\"primary\"\n onClick={() => onConfirm(target)}\n >\n {t('fileManager.dialogs.move.confirm', 'Move here')}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* FileManager — list view (internal). */\n/* */\n/* Composes the kit DataTable (AG Grid) — never a hand-rolled table. */\n/* Selection is lifted: the parent owns the id list; this view reflects */\n/* it into the grid and reports grid-side changes back up. */\n/* -------------------------------------------------------------------- */\n\nimport {\n useCallback,\n useEffect,\n useMemo,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport type { CustomCellRendererProps } from 'ag-grid-react';\nimport type {\n ColDef,\n GridOptions,\n RowClassParams,\n ValueFormatterParams,\n} from 'ag-grid-community';\nimport {\n Download,\n FolderInput,\n PenLine,\n Pencil,\n Share2,\n Trash2,\n} from 'lucide-react';\nimport {\n ActionsCellRenderer,\n actionsColumnWidth,\n DataTable,\n type ActionDef,\n type ActionsCellRendererParams,\n type DataTableHandle,\n} from '../data-table';\nimport { Badge } from '../badge';\nimport type {\n FileManagerItem,\n FileManagerItemAction,\n FileManagerPermissions,\n FileManagerSignatureStatus,\n} from './types';\nimport {\n formatFileSize,\n getItemIcon,\n pathWithinFolder,\n sameIdSet,\n} from './utils';\n\nconst SIGNATURE_VARIANT: Record<\n Exclude<FileManagerSignatureStatus, 'none'>,\n 'success' | 'warning'\n> = {\n signed: 'success',\n pending: 'warning',\n};\n\n// Name cell factory — closes over the previewed id so the row open in the host\n// rail carries a programmatic `aria-current` marker (not just the visual tint),\n// keeping assistive tech in sync with which document is being previewed.\nfunction makeNameCellRenderer(previewedItemId?: string | null) {\n return function NameCellRenderer(\n props: CustomCellRendererProps<FileManagerItem>,\n ) {\n const item = props.data;\n if (!item) return null;\n const IconComponent = getItemIcon(item);\n const isPreviewed = Boolean(previewedItemId) && item.id === previewedItemId;\n return (\n <span\n // Fill the cell and allow the label to shrink so a long name truncates\n // with an ellipsis instead of overflowing into the next column: the row\n // is a flex box (`inline-size:100%` + `min-inline-size:0`), the icon\n // never shrinks, and the name span truncates within the remaining space.\n className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)] ds:[inline-size:100%] ds:[min-inline-size:0]\"\n aria-current={isPreviewed ? 'true' : undefined}\n >\n <IconComponent\n aria-hidden=\"true\"\n className={[\n 'ds:size-4 ds:shrink-0',\n // Folders keep the brand primary; file glyphs take the accent, so\n // they read as documents and match the DocumentPreview header icon.\n item.kind === 'folder'\n ? 'ds:text-primary'\n : 'ds:text-[color:var(--accent)]',\n ].join(' ')}\n />\n <span className=\"ds:truncate ds:[min-inline-size:0]\">{item.name}</span>\n </span>\n );\n };\n}\n\nfunction TypeCellRenderer(props: CustomCellRendererProps<FileManagerItem>) {\n const item = props.data;\n if (!item || !item.documentType) return null;\n return (\n <Badge variant=\"neutral\" size=\"sm\">\n {item.documentType}\n </Badge>\n );\n}\n\nfunction makeSignatureCellRenderer(\n t: (key: string, fallback: string) => string,\n) {\n return function SignatureCellRenderer(\n props: CustomCellRendererProps<FileManagerItem>,\n ) {\n const status = props.data?.signatureStatus;\n if (!status || status === 'none') return null;\n return (\n <Badge variant={SIGNATURE_VARIANT[status]} size=\"sm\" withDot>\n {t(`fileManager.signature.${status}`, status)}\n </Badge>\n );\n };\n}\n\nexport interface ListViewProps {\n /** Items of the current folder (folders + files), locale-sorted. Filtering\n * is done by the DataTable's per-column floating filters (name + type). */\n items: FileManagerItem[];\n selectedIds: string[];\n /** Id of the file open in the host preview (e.g. the rail). Reuses the\n * selected-row tint so the user sees which document is active. */\n previewedItemId?: string | null;\n onSelectionChange: (ids: string[]) => void;\n onOpen: (item: FileManagerItem) => void;\n /** Primary single-click / keyboard activation — folders navigate, files\n * select-single (which fires the host `onPreviewItem`). */\n onRowActivate: (item: FileManagerItem) => void;\n /** Resolves the gate set for a single item. */\n can: (item: FileManagerItem) => Required<FileManagerPermissions>;\n onRequestRename: (itemId: string) => void;\n onRequestMove: (itemIds: string[]) => void;\n onRequestDelete: (itemIds: string[]) => void;\n onDownload?: (itemIds: string[]) => void;\n onShare?: (itemIds: string[]) => void;\n onRequestSignature?: (item: FileManagerItem) => void;\n /** Consumer actions appended after the built-in kebab entries. */\n itemActions?: (item: FileManagerItem) => FileManagerItemAction[];\n /**\n * Nest files under their folders via AG Grid Tree Data (`treeData` +\n * `getDataPath`). Sets the tree gridOption / autoGroupColumnDef flags only —\n * inert unless the consumer has registered the Enterprise `TreeDataModule`.\n * When on, `items` must be the whole descendant subtree (see `descendantsOf`)\n * and paths are built relative to `currentFolderId`. @default false\n */\n groupByFolder?: boolean;\n /**\n * Current folder id (`null` = root) — the anchor for tree-data path building.\n * Paths run from this folder's direct child down to each item.\n */\n currentFolderId: string | null;\n /** Forwarded as the DataTable `gridId` (namespaced by the caller). */\n gridId?: string;\n /** Handle to the composed DataTable — the FileManager proxies its\n * type-filter handle methods and agent `filter` action through this. */\n tableRef: RefObject<DataTableHandle<FileManagerItem> | null>;\n /** FileManager action cluster rendered in the DataTable's `Toolbar.Actions`. */\n toolbarActions: ReactNode;\n}\n\nexport function ListView({\n items,\n selectedIds,\n previewedItemId,\n onSelectionChange,\n onOpen,\n onRowActivate,\n can,\n onRequestRename,\n onRequestMove,\n onRequestDelete,\n onDownload,\n onShare,\n onRequestSignature,\n itemActions,\n groupByFolder = false,\n currentFolderId,\n gridId,\n tableRef,\n toolbarActions,\n}: ListViewProps) {\n const { t, i18n } = useTranslation();\n\n // Id → item over the current subtree — the tree-data path builder walks\n // `parentId` up through it, and it is cheap enough to keep memoised.\n const itemsById = useMemo(\n () => new Map(items.map((item) => [item.id, item])),\n [items],\n );\n\n const hasSignatureColumn = useMemo(\n () =>\n items.some(\n (item) => item.signatureStatus && item.signatureStatus !== 'none',\n ),\n [items],\n );\n const hasTypeColumn = useMemo(\n () => items.some((item) => Boolean(item.documentType)),\n [items],\n );\n\n // Reflect the lifted selection into the grid. The grid echoes the change\n // back through onSelectionChanged; the parent's set-equality guard stops\n // the loop.\n useEffect(() => {\n tableRef.current?.setSelection(selectedIds);\n }, [selectedIds, items]);\n\n // Per-row actions resolve permissions from the row data so a per-item\n // resolver gates each row independently.\n const rowActions = useMemo<ActionDef<FileManagerItem>[]>(() => {\n const actions: ActionDef<FileManagerItem>[] = [];\n if (onDownload) {\n actions.push({\n icon: <Download />,\n label: t('fileManager.toolbar.download', 'Download'),\n onClick: (data) => onDownload([data.id]),\n hidden: (data) => data.kind === 'folder' || !can(data).download,\n });\n }\n if (onRequestSignature) {\n actions.push({\n icon: <PenLine />,\n label: t('fileManager.toolbar.requestSignature', 'Request signature'),\n onClick: (data) => onRequestSignature(data),\n hidden: (data) => data.signatureStatus !== 'pending',\n });\n }\n if (onShare) {\n actions.push({\n icon: <Share2 />,\n label: t('fileManager.toolbar.share', 'Share'),\n onClick: (data) => onShare([data.id]),\n hidden: (data) => !can(data).share,\n });\n }\n actions.push({\n icon: <Pencil />,\n label: t('fileManager.toolbar.rename', 'Rename'),\n onClick: (data) => onRequestRename(data.id),\n hidden: (data) => !can(data).rename,\n });\n actions.push({\n icon: <FolderInput />,\n label: t('fileManager.toolbar.move', 'Move'),\n onClick: (data) => onRequestMove([data.id]),\n hidden: (data) => !can(data).move,\n });\n actions.push({\n icon: <Trash2 />,\n label: t('fileManager.toolbar.delete', 'Delete'),\n onClick: (data) => onRequestDelete([data.id]),\n variant: 'destructive',\n hidden: (data) => !can(data).delete,\n });\n if (itemActions) {\n // Consumer actions appended last. Each entry's per-item resolver is the\n // consumer's own — we render whatever it returns for the row.\n const resolvedIds = new Set<string>();\n for (const item of items) {\n for (const action of itemActions(item)) {\n if (resolvedIds.has(action.id)) continue;\n resolvedIds.add(action.id);\n const actionId = action.id;\n actions.push({\n icon: action.icon ?? <span aria-hidden=\"true\" />,\n label: action.label,\n onClick: (data) =>\n itemActions(data)\n .find((a) => a.id === actionId)\n ?.onSelect(data),\n variant: action.destructive ? 'destructive' : 'default',\n hidden: (data) => !itemActions(data).some((a) => a.id === actionId),\n });\n }\n }\n }\n return actions;\n }, [\n items,\n can,\n onDownload,\n onShare,\n onRequestSignature,\n onRequestRename,\n onRequestMove,\n onRequestDelete,\n itemActions,\n t,\n ]);\n\n const columnDefs = useMemo<ColDef<FileManagerItem>[]>(() => {\n const SignatureCellRenderer = makeSignatureCellRenderer(t);\n const NameCellRenderer = makeNameCellRenderer(previewedItemId);\n const defs: ColDef<FileManagerItem>[] = [];\n // In tree-data mode the auto group column (configured in gridOptions below)\n // renders the Name hierarchy, so the flat Name column is omitted.\n if (!groupByFolder) {\n defs.push({\n colId: 'name',\n field: 'name',\n headerName: t('fileManager.columns.name', 'Name'),\n cellRenderer: NameCellRenderer,\n flex: 2,\n minWidth: 200,\n });\n }\n if (hasTypeColumn) {\n defs.push({\n colId: 'documentType',\n field: 'documentType',\n headerName: t('fileManager.columns.type', 'Type'),\n cellRenderer: TypeCellRenderer,\n flex: 1,\n minWidth: 120,\n });\n }\n if (hasSignatureColumn) {\n defs.push({\n colId: 'signatureStatus',\n field: 'signatureStatus',\n headerName: t('fileManager.columns.signature', 'Signature'),\n cellRenderer: SignatureCellRenderer,\n flex: 1,\n minWidth: 150,\n });\n }\n defs.push({\n colId: 'size',\n field: 'size',\n headerName: t('fileManager.columns.size', 'Size'),\n valueFormatter: (params: ValueFormatterParams<FileManagerItem>) =>\n params.data?.kind === 'file' && params.data.size !== undefined\n ? formatFileSize(params.data.size, i18n.language, t)\n : t('fileManager.emptyCell', '—'),\n filter: false,\n flex: 1,\n minWidth: 110,\n });\n defs.push({\n colId: 'updatedAt',\n field: 'updatedAt',\n headerName: t('fileManager.columns.modified', 'Modified'),\n valueFormatter: (params: ValueFormatterParams<FileManagerItem>) =>\n params.data?.updatedAt\n ? new Intl.DateTimeFormat(i18n.language, {\n dateStyle: 'medium',\n }).format(new Date(params.data.updatedAt))\n : t('fileManager.emptyCell', '—'),\n filter: false,\n flex: 1,\n minWidth: 130,\n });\n if (rowActions.length > 0) {\n defs.push({\n colId: 'actions',\n headerName: t('fileManager.rowActions', 'Item actions'),\n cellRenderer: ActionsCellRenderer,\n cellRendererParams: {\n actions: rowActions,\n group: true,\n label: t('fileManager.rowActions', 'Item actions'),\n } satisfies ActionsCellRendererParams<FileManagerItem>,\n sortable: false,\n filter: false,\n resizable: false,\n width: actionsColumnWidth(rowActions.length),\n });\n }\n return defs;\n }, [\n rowActions,\n hasTypeColumn,\n hasSignatureColumn,\n previewedItemId,\n groupByFolder,\n t,\n i18n.language,\n ]);\n\n const gridOptions = useMemo<GridOptions<FileManagerItem>>(() => {\n const options: GridOptions<FileManagerItem> = {\n getRowId: (params) => params.data.id,\n onRowClicked: (event) => {\n // Skip clicks on the selection checkbox, the row-actions kebab, and the\n // tree expand/collapse chevron — those own their own behaviour\n // (multi-select toggle / menu / expand). A click on the row body is the\n // primary activation (select-single + fire onPreviewItem, or navigate\n // for folders). In tree-data mode every parent row is a real folder\n // item with `data`, so folder rows activate exactly like the flat view.\n const dom = event.event as Event | undefined;\n const target = dom?.target as HTMLElement | null;\n if (\n target?.closest(\n '.ag-selection-checkbox, .ag-checkbox-input-wrapper, [col-id=\"actions\"], [data-item-kebab], .ag-group-contracted, .ag-group-expanded',\n )\n ) {\n return;\n }\n if (event.data) onRowActivate(event.data);\n },\n onRowDoubleClicked: (event) => {\n if (event.data) onOpen(event.data);\n },\n };\n if (groupByFolder) {\n // AG Grid Tree Data: each folder is a parent row and its files nest\n // beneath it (a file-explorer tree). `getDataPath` reads the id-chain\n // from the current folder's direct child down to each item; every id is a\n // real row, so no filler group rows appear. `groupDefaultExpanded: 1`\n // opens the current folder's folders (showing their files) while deeper\n // nesting stays collapsed until requested. The auto group column reads as\n // \"Name\" and reuses NameCellRenderer, so folders and files render exactly\n // as in the flat view (icon + name + previewed aria-current) with AG\n // Grid's chevron on folders. Only these flags are set here — the\n // Enterprise TreeDataModule is registered by the consumer.\n const NameCellRenderer = makeNameCellRenderer(previewedItemId);\n options.treeData = true;\n options.getDataPath = (item) =>\n pathWithinFolder(item, itemsById, currentFolderId);\n options.groupDefaultExpanded = 1;\n options.autoGroupColumnDef = {\n headerName: t('fileManager.columns.name', 'Name'),\n flex: 2,\n minWidth: 200,\n cellRendererParams: {\n suppressCount: true,\n innerRenderer: NameCellRenderer,\n },\n };\n }\n return options;\n }, [\n onOpen,\n onRowActivate,\n groupByFolder,\n previewedItemId,\n t,\n itemsById,\n currentFolderId,\n ]);\n\n const handleSelectionChanged = (rows: FileManagerItem[]) => {\n const ids = rows.map((row) => row.id);\n if (!sameIdSet(ids, selectedIds)) onSelectionChange(ids);\n };\n\n // Reuse the grid's selected-row treatment (token-driven, no new colours) to\n // mark the row the host is previewing in the rail.\n const getRowClass = useCallback(\n (params: RowClassParams<FileManagerItem>) =>\n previewedItemId && params.data?.id === previewedItemId\n ? 'ag-row-selected'\n : undefined,\n [previewedItemId],\n );\n\n return (\n <DataTable<FileManagerItem>\n ref={tableRef}\n gridId={gridId}\n columnDefs={columnDefs}\n rowData={items}\n rowSelection=\"multiple\"\n gridOptions={gridOptions}\n getRowClass={getRowClass}\n onSelectionChanged={handleSelectionChanged}\n heightClass=\"ds:h-[420px]\"\n >\n <DataTable.Toolbar>\n <DataTable.Toolbar.Actions>{toolbarActions}</DataTable.Toolbar.Actions>\n </DataTable.Toolbar>\n </DataTable>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* FileManager — toolbar (internal). */\n/* */\n/* One end-aligned IconButtonGroup rendered inside the composed */\n/* DataTable's `Toolbar.Actions` slot. Upload is the primary action; */\n/* the rest are New Folder, consumer `addMenuItems`, then the selection- */\n/* scoped Download / Share / Rename / Move / Delete cluster. Every */\n/* affordance is permission-gated at render time: an action the host has */\n/* not granted simply does not exist in the DOM. `overflow=\"menu\"` lets */\n/* the strip collapse gracefully on narrow widths. */\n/* -------------------------------------------------------------------- */\n\nimport { useTranslation } from 'react-i18next';\nimport {\n Download,\n FolderInput,\n FolderPlus,\n Pencil,\n Plus,\n Share2,\n Trash2,\n Upload,\n} from 'lucide-react';\nimport { IconButton } from '../icon-button';\nimport { IconButtonGroup } from '../icon-button-group';\nimport type { FileManagerAddMenuItem, FileManagerPermissions } from './types';\n\nexport interface FileManagerToolbarProps {\n selectedIds: string[];\n permissions: Required<FileManagerPermissions>;\n onRequestCreateFolder: () => void;\n onRequestUpload?: () => void;\n addMenuItems?: FileManagerAddMenuItem[];\n onRequestRename: (itemId: string) => void;\n onRequestMove: (itemIds: string[]) => void;\n onRequestDelete: (itemIds: string[]) => void;\n onDownload?: (itemIds: string[]) => void;\n onShare?: (itemIds: string[]) => void;\n}\n\nexport function FileManagerToolbar({\n selectedIds,\n permissions,\n onRequestCreateFolder,\n onRequestUpload,\n addMenuItems,\n onRequestRename,\n onRequestMove,\n onRequestDelete,\n onDownload,\n onShare,\n}: FileManagerToolbarProps) {\n const { t } = useTranslation();\n\n const hasSelection = selectedIds.length > 0;\n const singleSelection = selectedIds.length === 1;\n const canUpload = permissions.upload && Boolean(onRequestUpload);\n const canDownload = permissions.download && Boolean(onDownload);\n const canShare = permissions.share && Boolean(onShare);\n const extraAddItems = addMenuItems ?? [];\n\n const hasAny =\n canUpload ||\n permissions.createFolder ||\n extraAddItems.length > 0 ||\n canDownload ||\n canShare ||\n permissions.rename ||\n permissions.move ||\n permissions.delete;\n\n if (!hasAny) return null;\n\n return (\n <IconButtonGroup\n role=\"toolbar\"\n overflow=\"menu\"\n size=\"sm\"\n aria-label={t('fileManager.toolbarLabel', 'File actions')}\n data-testid=\"file-manager-toolbar\"\n >\n {canUpload && (\n <IconButton\n intent=\"primary\"\n data-overflow-pin\n icon={<Upload />}\n tooltip={t('fileManager.toolbar.upload', 'Upload files')}\n onClick={() => onRequestUpload?.()}\n />\n )}\n {permissions.createFolder && (\n <IconButton\n icon={<FolderPlus />}\n tooltip={t('fileManager.toolbar.newFolder', 'New folder')}\n onClick={onRequestCreateFolder}\n />\n )}\n {extraAddItems.map((entry) => (\n <IconButton\n key={entry.id}\n icon={entry.icon ?? <Plus />}\n tooltip={entry.label}\n onClick={() => entry.onSelect()}\n />\n ))}\n {canDownload && (\n <IconButton\n icon={<Download />}\n tooltip={t('fileManager.toolbar.download', 'Download')}\n disabled={!hasSelection}\n onClick={() => onDownload?.(selectedIds)}\n />\n )}\n {canShare && (\n <IconButton\n icon={<Share2 />}\n tooltip={t('fileManager.toolbar.share', 'Share')}\n disabled={!hasSelection}\n onClick={() => onShare?.(selectedIds)}\n />\n )}\n {permissions.rename && (\n <IconButton\n icon={<Pencil />}\n tooltip={t('fileManager.toolbar.rename', 'Rename')}\n disabled={!singleSelection}\n onClick={() => onRequestRename(selectedIds[0])}\n />\n )}\n {permissions.move && (\n <IconButton\n icon={<FolderInput />}\n tooltip={t('fileManager.toolbar.move', 'Move')}\n disabled={!hasSelection}\n onClick={() => onRequestMove(selectedIds)}\n />\n )}\n {permissions.delete && (\n <IconButton\n icon={<Trash2 />}\n tooltip={t('fileManager.toolbar.delete', 'Delete')}\n disabled={!hasSelection}\n onClick={() => onRequestDelete(selectedIds)}\n />\n )}\n </IconButtonGroup>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* FileManager — a permission-gated file/folder browser. */\n/* */\n/* Composes the kit FolderTree sidebar, Breadcrumb path, and the */\n/* DataTable (AG Grid) list. Single-click a file row selects it and */\n/* fires `onPreviewItem` (the host renders a DocumentPreview — typically */\n/* in the Control Room rail); folders navigate; double-click resolves the */\n/* host `onOpenFile`. Keyboard Enter mirrors the primary gesture: a file */\n/* previews when a preview handler is wired, else opens. Every mutation */\n/* resolves through a host */\n/* callback; the component owns only view state (folder, selection, */\n/* active action). Agent-readiness: curated FileManagerHandle + */\n/* file-manager.agent.ts. */\n/* -------------------------------------------------------------------- */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type DragEvent,\n type KeyboardEvent,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Upload } from 'lucide-react';\nimport { Breadcrumb, BreadcrumbItem, BreadcrumbLink } from '../breadcrumb';\nimport type { DataTableHandle } from '../data-table';\nimport { EmptyState } from '../empty-state';\nimport { Skeleton } from '../skeleton';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { useAgentRegistration } from '../../agent';\nimport { fileManagerAgent } from './file-manager.agent';\nimport {\n CreateFolderDialog,\n DeleteDialog,\n MoveDialog,\n RenameDialog,\n UploadDialog,\n} from './dialogs';\nimport { FolderTree } from './folder-tree';\nimport { ListView } from './list-view';\nimport { FileManagerToolbar } from './toolbar';\nimport type {\n FileManagerActiveAction,\n FileManagerAddMenuItem,\n FileManagerHandle,\n FileManagerItem,\n FileManagerItemAction,\n FileManagerItemMeta,\n FileManagerPermissions,\n FileManagerPermissionsInput,\n FileManagerUploadConfig,\n FileManagerUploadHandler,\n} from './types';\nimport { childrenOf, descendantsOf, pathTo, sameIdSet } from './utils';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst fileManagerVariants = cva(\n 'ds:relative ds:flex ds:w-full ds:min-w-0 ds:flex-col ds:gap-[var(--spacing-md)]',\n {\n variants: {\n bordered: {\n true: 'ds:rounded-[var(--radius-lg)] ds:border ds:border-[color:var(--border)] ds:bg-background ds:p-[var(--spacing-md)]',\n false: '',\n },\n },\n defaultVariants: { bordered: true },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Props */\n/* ------------------------------------------------------------------ */\n\nexport interface FileManagerProps extends VariantProps<\n typeof fileManagerVariants\n> {\n /** Opaque instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** Flat item list keyed by `parentId`. The host owns this data. */\n items: FileManagerItem[];\n /**\n * Capability gates — a flat set or a per-item resolver. Default is all-true\n * (see FileManagerPermissions); `delete` always routes through a confirm.\n */\n permissions?: FileManagerPermissionsInput;\n /** Controlled current folder (`null` = root). */\n folderId?: string | null;\n /** @default null */\n defaultFolderId?: string | null;\n onNavigate?: (folderId: string | null) => void;\n onSelectionChange?: (ids: string[]) => void;\n /**\n * Opt-in folder-tree nav pane, rendered as a sidebar (hidden below the md\n * breakpoint). The default layout is the table full-width with the folder\n * breadcrumb in the footer; when `groupByFolder` is on the tree data already\n * surfaces folders in the list, so the sidebar is redundant unless a consumer\n * explicitly wants it.\n * @default false — opt-in nav pane\n */\n showTree?: boolean;\n /** Render the Skeleton loading state instead of the folder contents. */\n isLoading?: boolean;\n /** Opening a file resolves here (folders navigate internally). */\n onOpenFile?: (item: FileManagerItem) => void;\n onCreateFolder?: (\n name: string,\n parentId: string | null,\n ) => void | Promise<void>;\n onRenameItem?: (itemId: string, name: string) => void | Promise<void>;\n onDeleteItems?: (itemIds: string[]) => void | Promise<void>;\n onMoveItems?: (\n itemIds: string[],\n targetFolderId: string | null,\n ) => void | Promise<void>;\n onDownloadItems?: (itemIds: string[]) => void;\n /** Share affordance (kebab + toolbar). Hidden when absent. */\n onShare?: (itemIds: string[]) => void;\n /**\n * Request a signature for a pending-signature item. The action only appears\n * on items whose `signatureStatus` is `'pending'`; hidden when absent.\n */\n onRequestSignature?: (item: FileManagerItem) => void;\n /** Per-file upload handler (host owns transport). Enables the upload UI. */\n onUpload?: FileManagerUploadHandler;\n /** Upload transport config forwarded to the kit FileUpload. */\n uploadConfig?: FileManagerUploadConfig;\n /**\n * Fired when a **file** row is activated by a single click, or by keyboard\n * Enter on the selected file when this handler is wired (folders navigate\n * internally; double-click always resolves `onOpenFile`). The host is\n * expected to render the kit `DocumentPreview` in response — typically inside\n * the Control Room rail. When absent, single-click just selects the row and\n * Enter falls back to `onOpenFile`.\n */\n onPreviewItem?: (item: FileManagerItem) => void;\n /**\n * Id of the file the host is currently previewing (e.g. open in the rail).\n * When set, the matching list row reuses the DataTable's selected-row tint so\n * the user can see which document is open. `null` clears the highlight.\n */\n previewedItemId?: string | null;\n /** Consumer actions appended after the built-in per-item kebab entries. */\n itemActions?: (item: FileManagerItem) => FileManagerItemAction[];\n /** Consumer entries appended after the built-in action buttons. */\n addMenuItems?: FileManagerAddMenuItem[];\n /**\n * Nest files under their folders (Finder/Explorer style) via AG Grid Tree\n * Data. Requires the consumer to register the Enterprise `TreeDataModule`\n * (`ModuleRegistry.registerModules([TreeDataModule])`); the `treeData` /\n * `getDataPath` / `autoGroupColumnDef` flags set here are inert until it is.\n * @default false\n */\n groupByFolder?: boolean;\n className?: string;\n}\n\nconst ALL_PERMISSIONS: Required<FileManagerPermissions> = {\n createFolder: true,\n upload: true,\n download: true,\n rename: true,\n move: true,\n delete: true,\n share: true,\n};\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const FileManager = forwardRef<FileManagerHandle, FileManagerProps>(\n (\n {\n id,\n items,\n permissions,\n folderId: folderIdProp,\n defaultFolderId = null,\n onNavigate,\n onSelectionChange,\n showTree = false,\n isLoading = false,\n onOpenFile,\n onCreateFolder,\n onRenameItem,\n onDeleteItems,\n onMoveItems,\n onDownloadItems,\n onShare,\n onRequestSignature,\n onUpload,\n uploadConfig,\n onPreviewItem,\n previewedItemId,\n itemActions,\n addMenuItems,\n groupByFolder = false,\n bordered,\n className,\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n\n // Resolve gates. `can()` is the folder-level base (all-true when a per-item\n // resolver is supplied but no item is in scope); `canItem(item)` gates the\n // per-item kebab / row actions.\n const resolvePerms = useCallback(\n (item?: FileManagerItem): Required<FileManagerPermissions> => {\n if (typeof permissions === 'function') {\n return item\n ? { ...ALL_PERMISSIONS, ...permissions(item) }\n : ALL_PERMISSIONS;\n }\n return { ...ALL_PERMISSIONS, ...(permissions ?? {}) };\n },\n [permissions],\n );\n const can = useMemo(() => resolvePerms(), [resolvePerms]);\n const canItem = useCallback(\n (item: FileManagerItem) => resolvePerms(item),\n [resolvePerms],\n );\n\n const [folderRaw, setFolder] = useControllableState<string | null>({\n value: folderIdProp,\n defaultValue: defaultFolderId,\n onChange: onNavigate,\n });\n const currentFolderId = folderRaw ?? null;\n\n const [selectedIds, setSelectedIdsRaw] = useState<string[]>([]);\n const [activeAction, setActiveAction] = useState<FileManagerActiveAction>({\n type: 'none',\n });\n const [isDraggingFiles, setIsDraggingFiles] = useState(false);\n const dragDepth = useRef(0);\n\n // The composed DataTable's curated handle — the type-filter handle methods\n // and the agent `filter` action proxy through it.\n const dataTableRef = useRef<DataTableHandle<FileManagerItem>>(null);\n\n const liveRef = useRef<HTMLSpanElement>(null);\n const announce = useCallback((message: string) => {\n if (liveRef.current) liveRef.current.textContent = message;\n }, []);\n\n // The ListView is keyed by folder id and remounts on every navigation,\n // which would drop focus to <body>. After a folder change we move focus to\n // this stable content container so keyboard users keep their place; the\n // polite \"Opened {name}\" live region announces the change for screen\n // readers. The flag is only set by user-driven navigateTo, never on mount.\n const contentRef = useRef<HTMLDivElement>(null);\n const focusContentAfterNav = useRef(false);\n\n const itemsById = useMemo(\n () => new Map(items.map((item) => [item.id, item])),\n [items],\n );\n\n const setSelection = useCallback(\n (ids: string[]) => {\n setSelectedIdsRaw((prev) => {\n const valid = ids.filter((itemId) => itemsById.has(itemId));\n if (sameIdSet(prev, valid)) return prev;\n onSelectionChange?.(valid);\n return valid;\n });\n },\n [itemsById, onSelectionChange],\n );\n\n // Prune selected ids that no longer exist in the data set.\n useEffect(() => {\n setSelectedIdsRaw((prev) => {\n const valid = prev.filter((itemId) => itemsById.has(itemId));\n return valid.length === prev.length ? prev : valid;\n });\n }, [itemsById]);\n\n /* ---------------- navigation ---------------- */\n\n const navigateTo = useCallback(\n (targetId: string | null) => {\n if (targetId !== null) {\n const target = itemsById.get(targetId);\n if (!target || target.kind !== 'folder') return;\n }\n setFolder(targetId);\n setSelectedIdsRaw([]);\n focusContentAfterNav.current = true;\n const name =\n targetId === null\n ? t('fileManager.rootLabel', 'All files')\n : (itemsById.get(targetId)?.name ?? '');\n announce(\n t('fileManager.announce.navigated', 'Opened {{name}}', { name }),\n );\n },\n [itemsById, setFolder, announce, t],\n );\n\n // Move focus to the content container after the post-navigation remount so\n // it never falls back to <body> (paired with the live-region announcement).\n useEffect(() => {\n if (!focusContentAfterNav.current) return;\n focusContentAfterNav.current = false;\n contentRef.current?.focus();\n }, [currentFolderId]);\n\n /* ---------------- derived content ---------------- */\n\n // The footer breadcrumb traces the path to the PREVIEWED item — the\n // selected file, with the file itself as the final (plain) crumb — when one\n // is set; otherwise it falls back to the current folder's position.\n // Ancestor crumbs stay clickable to navigate up; the final crumb is text.\n const breadcrumbTargetId =\n previewedItemId && itemsById.has(previewedItemId)\n ? previewedItemId\n : currentFolderId;\n const path = useMemo(\n () => pathTo(items, breadcrumbTargetId),\n [items, breadcrumbTargetId],\n );\n\n const folderChildren = useMemo(\n () => childrenOf(items, currentFolderId, i18n.language),\n [items, currentFolderId, i18n.language],\n );\n\n // Tree-data feed: the whole subtree beneath the current folder so AG Grid\n // can nest files under folders. Off = flat immediate children only.\n const folderDescendants = useMemo(\n () =>\n groupByFolder\n ? descendantsOf(items, currentFolderId, i18n.language)\n : folderChildren,\n [groupByFolder, items, currentFolderId, i18n.language, folderChildren],\n );\n\n const currentFolderName =\n currentFolderId === null\n ? t('fileManager.rootLabel', 'All files')\n : (itemsById.get(currentFolderId)?.name ?? '');\n\n /* ---------------- single-active-action machine ---------------- */\n\n const beginAction = useCallback((action: FileManagerActiveAction) => {\n setActiveAction((prev) => (prev.type === 'none' ? action : prev));\n }, []);\n\n const endAction = useCallback(() => {\n setActiveAction({ type: 'none' });\n }, []);\n\n // Permission-gated entry points. Each checks its gate so keyboard\n // shortcuts, toolbar buttons and per-row actions share one guard.\n const requestCreateFolder = useCallback(() => {\n if (!can.createFolder || !onCreateFolder) return;\n beginAction({ type: 'create-folder' });\n }, [can.createFolder, onCreateFolder, beginAction]);\n\n const requestUpload = useCallback(() => {\n if (!can.upload || !onUpload) return;\n beginAction({ type: 'upload' });\n }, [can.upload, onUpload, beginAction]);\n\n const requestRename = useCallback(\n (itemId: string) => {\n const target = itemsById.get(itemId);\n if (!target || !canItem(target).rename || !onRenameItem) return;\n beginAction({ type: 'rename', itemId });\n },\n [canItem, onRenameItem, itemsById, beginAction],\n );\n\n const requestDelete = useCallback(\n (itemIds: string[]) => {\n if (!onDeleteItems || itemIds.length === 0) return;\n const allowed = itemIds.filter((itemId) => {\n const target = itemsById.get(itemId);\n return target ? canItem(target).delete : false;\n });\n if (allowed.length === 0) return;\n beginAction({ type: 'delete', itemIds: allowed });\n },\n [canItem, onDeleteItems, itemsById, beginAction],\n );\n\n const requestMove = useCallback(\n (itemIds: string[]) => {\n if (!onMoveItems || itemIds.length === 0) return;\n const allowed = itemIds.filter((itemId) => {\n const target = itemsById.get(itemId);\n return target ? canItem(target).move : false;\n });\n if (allowed.length === 0) return;\n beginAction({ type: 'move', itemIds: allowed });\n },\n [canItem, onMoveItems, itemsById, beginAction],\n );\n\n const handleDownload = useCallback(\n (itemIds: string[]) => {\n if (!onDownloadItems || itemIds.length === 0) return;\n const allowed = itemIds.filter((itemId) => {\n const target = itemsById.get(itemId);\n return target ? canItem(target).download : false;\n });\n if (allowed.length > 0) onDownloadItems(allowed);\n },\n [canItem, onDownloadItems, itemsById],\n );\n\n const handleShare = useCallback(\n (itemIds: string[]) => {\n if (!onShare || itemIds.length === 0) return;\n const allowed = itemIds.filter((itemId) => {\n const target = itemsById.get(itemId);\n return target ? canItem(target).share : false;\n });\n if (allowed.length > 0) onShare(allowed);\n },\n [canItem, onShare, itemsById],\n );\n\n /* ---------------- open / activate ---------------- */\n\n const openItem = useCallback(\n (item: FileManagerItem) => {\n if (item.kind === 'folder') navigateTo(item.id);\n else onOpenFile?.(item);\n },\n [navigateTo, onOpenFile],\n );\n\n // Primary single-click / keyboard activation: folders navigate; a file\n // becomes the single selection and fires `onPreviewItem` so the host can\n // open it in a DocumentPreview (e.g. the Control Room rail).\n const activateRow = useCallback(\n (item: FileManagerItem) => {\n if (item.kind === 'folder') {\n navigateTo(item.id);\n } else {\n setSelection([item.id]);\n onPreviewItem?.(item);\n }\n },\n [navigateTo, setSelection, onPreviewItem],\n );\n\n /* ---------------- dialog submits ---------------- */\n\n const submitCreateFolder = useCallback(\n (name: string) => {\n void onCreateFolder?.(name, currentFolderId);\n endAction();\n },\n [onCreateFolder, currentFolderId, endAction],\n );\n\n const submitRename = useCallback(\n (name: string) => {\n if (activeAction.type === 'rename') {\n void onRenameItem?.(activeAction.itemId, name);\n }\n endAction();\n },\n [activeAction, onRenameItem, endAction],\n );\n\n const submitDelete = useCallback(() => {\n if (activeAction.type === 'delete') {\n void onDeleteItems?.(activeAction.itemIds);\n setSelection([]);\n }\n endAction();\n }, [activeAction, onDeleteItems, setSelection, endAction]);\n\n const submitMove = useCallback(\n (targetFolderId: string | null) => {\n if (activeAction.type === 'move') {\n void onMoveItems?.(activeAction.itemIds, targetFolderId);\n }\n endAction();\n },\n [activeAction, onMoveItems, endAction],\n );\n\n const uploadToCurrentFolder = useCallback<\n (\n file: File,\n helpers: { signal: AbortSignal; onProgress: (percent: number) => void },\n ) => Promise<void>\n >(\n (file, helpers) =>\n onUpload ? onUpload(file, helpers, currentFolderId) : Promise.resolve(),\n [onUpload, currentFolderId],\n );\n\n /* ---------------- canvas drag-and-drop overlay ------------------ */\n\n const uploadEnabled = can.upload && Boolean(onUpload);\n\n const isFileDrag = (event: DragEvent) =>\n Array.from(event.dataTransfer?.types ?? []).includes('Files');\n\n const handleDragEnter = useCallback(\n (event: DragEvent<HTMLDivElement>) => {\n if (!uploadEnabled || !isFileDrag(event)) return;\n event.preventDefault();\n dragDepth.current += 1;\n setIsDraggingFiles(true);\n },\n [uploadEnabled],\n );\n\n const handleDragOver = useCallback(\n (event: DragEvent<HTMLDivElement>) => {\n if (!uploadEnabled || !isFileDrag(event)) return;\n event.preventDefault();\n },\n [uploadEnabled],\n );\n\n const handleDragLeave = useCallback(() => {\n if (!uploadEnabled) return;\n dragDepth.current = Math.max(0, dragDepth.current - 1);\n if (dragDepth.current === 0) setIsDraggingFiles(false);\n }, [uploadEnabled]);\n\n const handleDrop = useCallback(\n (event: DragEvent<HTMLDivElement>) => {\n if (!uploadEnabled || !isFileDrag(event)) return;\n event.preventDefault();\n dragDepth.current = 0;\n setIsDraggingFiles(false);\n // The FileUpload queue inside the dialog owns file intake; the canvas\n // overlay is the affordance that opens it on drop.\n requestUpload();\n },\n [uploadEnabled, requestUpload],\n );\n\n /* ---------------- keyboard (scoped to the component root) -------- */\n\n const handleRootKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n // Shortcuts are disabled while any action dialog is open.\n if (activeAction.type !== 'none') return;\n const target = event.target as HTMLElement;\n if (target.closest('input, textarea, [contenteditable=\"true\"]')) return;\n if (event.key === 'F2' && selectedIds.length === 1) {\n event.preventDefault();\n requestRename(selectedIds[0]);\n } else if (event.key === 'Delete' && selectedIds.length > 0) {\n event.preventDefault();\n requestDelete(selectedIds);\n } else if (event.key === 'Enter' && selectedIds.length === 1) {\n const only = itemsById.get(selectedIds[0]);\n if (only) {\n event.preventDefault();\n // Keyboard activation mirrors the primary pointer gesture so both\n // interactions stay keyboard-reachable (WCAG 2.1.1): a file with a\n // host preview handler previews (the single-click path); otherwise\n // it opens (the double-click path). Folders navigate either way.\n if (only.kind === 'file' && onPreviewItem) {\n activateRow(only);\n } else {\n openItem(only);\n }\n }\n } else if (\n event.key.toLowerCase() === 'a' &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault();\n setSelection(folderChildren.map((item) => item.id));\n }\n },\n [\n activeAction.type,\n selectedIds,\n itemsById,\n requestRename,\n requestDelete,\n openItem,\n activateRow,\n onPreviewItem,\n setSelection,\n folderChildren,\n ],\n );\n\n /* ---------------- curated handle + agent registration ------------ */\n\n // Live refs so the memoised handle always reads current state.\n const stateRef = useRef({\n selectedIds,\n currentFolderId,\n items,\n activeAction,\n });\n stateRef.current = {\n selectedIds,\n currentFolderId,\n items,\n activeAction,\n };\n const actionsRef = useRef({\n setSelection,\n navigateTo,\n openItem,\n requestRename,\n });\n actionsRef.current = {\n setSelection,\n navigateTo,\n openItem,\n requestRename,\n };\n\n const handle = useMemo<FileManagerHandle>(\n () => ({\n getSelection: () => [...stateRef.current.selectedIds],\n setSelection: (ids) => actionsRef.current.setSelection(ids),\n clearSelection: () => actionsRef.current.setSelection([]),\n getCurrentFolderId: () => stateRef.current.currentFolderId,\n navigateTo: (folderId) => actionsRef.current.navigateTo(folderId),\n getTypeFilter: () => {\n const model = dataTableRef.current?.getFilter() ?? {};\n const entry = model.documentType as { filter?: unknown } | undefined;\n return typeof entry?.filter === 'string' ? [entry.filter] : [];\n },\n setTypeFilter: (documentTypes) => {\n const api = dataTableRef.current?.getRawApi();\n if (!api) return;\n if (documentTypes.length === 0) {\n api.destroyFilter('documentType');\n return;\n }\n api.setColumnFilterModel('documentType', {\n type: 'equals',\n filter: documentTypes[0],\n });\n api.onFilterChanged();\n },\n getItems: (folderId): FileManagerItemMeta[] =>\n stateRef.current.items\n .filter((item) =>\n folderId === undefined ? true : item.parentId === folderId,\n )\n .map((item) => ({\n id: item.id,\n kind: item.kind,\n parentId: item.parentId,\n size: item.size,\n updatedAt: item.updatedAt,\n documentType: item.documentType,\n signatureStatus: item.signatureStatus,\n })),\n getItemNames: (ids) => {\n const wanted = new Set(ids);\n return stateRef.current.items\n .filter((item) => wanted.has(item.id))\n .map((item) => ({ id: item.id, name: item.name }));\n },\n openItem: (itemId) => {\n const item = stateRef.current.items.find((i) => i.id === itemId);\n if (item) actionsRef.current.openItem(item);\n },\n startRename: (itemId) => actionsRef.current.requestRename(itemId),\n getActiveAction: () => stateRef.current.activeAction.type,\n }),\n [],\n );\n\n useImperativeHandle(ref, () => handle, [handle]);\n useAgentRegistration(fileManagerAgent, handle, id);\n\n /* ---------------- render ---------------- */\n\n const renameItem =\n activeAction.type === 'rename'\n ? itemsById.get(activeAction.itemId)\n : undefined;\n\n if (isLoading) {\n return (\n <div\n data-component=\"file-manager\"\n data-component-id={id}\n role=\"region\"\n aria-label={t('fileManager.regionLabel', 'File manager')}\n aria-busy=\"true\"\n className={fileManagerVariants({ bordered, className })}\n >\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <Skeleton variant=\"rectangular\" size=\"sm\" className=\"ds:w-24\" />\n <Skeleton\n variant=\"rectangular\"\n size=\"sm\"\n className=\"ds:ms-auto ds:w-48\"\n />\n </div>\n <Skeleton variant=\"text\" size=\"sm\" className=\"ds:w-40\" />\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {[0, 1, 2, 3, 4].map((row) => (\n <Skeleton key={row} variant=\"rectangular\" size=\"sm\" />\n ))}\n </div>\n </div>\n );\n }\n\n const toolbarActions = (\n <FileManagerToolbar\n selectedIds={selectedIds}\n permissions={can}\n onRequestCreateFolder={requestCreateFolder}\n onRequestUpload={uploadEnabled ? requestUpload : undefined}\n addMenuItems={addMenuItems}\n onRequestRename={requestRename}\n onRequestMove={requestMove}\n onRequestDelete={requestDelete}\n onDownload={\n can.download && onDownloadItems ? handleDownload : undefined\n }\n onShare={can.share && onShare ? handleShare : undefined}\n />\n );\n\n return (\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- container-level keyboard shortcuts + drag-and-drop upload; interactive children remain individually operable\n <div\n data-component=\"file-manager\"\n data-component-id={id}\n role=\"region\"\n aria-label={t('fileManager.regionLabel', 'File manager')}\n onKeyDown={handleRootKeyDown}\n onDragEnter={uploadEnabled ? handleDragEnter : undefined}\n onDragOver={uploadEnabled ? handleDragOver : undefined}\n onDragLeave={uploadEnabled ? handleDragLeave : undefined}\n onDrop={uploadEnabled ? handleDrop : undefined}\n className={fileManagerVariants({ bordered, className })}\n >\n <div className=\"ds:flex ds:min-h-0 ds:items-start ds:gap-[var(--spacing-md)]\">\n {showTree && (\n <div className=\"ds:hidden ds:w-56 ds:shrink-0 ds:md:block\">\n <FolderTree\n items={items}\n selectedFolderId={currentFolderId}\n onSelectFolder={navigateTo}\n aria-label={t('fileManager.treeLabel', 'Folders')}\n />\n </div>\n )}\n\n <div\n ref={contentRef}\n tabIndex={-1}\n className=\"ds:min-w-0 ds:flex-1 ds:outline-none\"\n >\n {folderChildren.length === 0 ? (\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={t(\n 'fileManager.empty.folderTitle',\n 'This folder is empty',\n )}\n description={t(\n 'fileManager.empty.folderDescription',\n 'Upload files or create a folder to get started.',\n )}\n />\n ) : (\n /* Remount on folder change so the DataTable's column filters\n reset cleanly for the new folder. */\n <ListView\n key={currentFolderId ?? '__root__'}\n items={folderDescendants}\n currentFolderId={currentFolderId}\n selectedIds={selectedIds}\n previewedItemId={previewedItemId ?? null}\n onSelectionChange={setSelection}\n onOpen={openItem}\n onRowActivate={activateRow}\n can={canItem}\n onRequestRename={requestRename}\n onRequestMove={requestMove}\n onRequestDelete={requestDelete}\n onDownload={\n can.download && onDownloadItems ? handleDownload : undefined\n }\n onShare={can.share && onShare ? handleShare : undefined}\n onRequestSignature={onRequestSignature}\n itemActions={itemActions}\n groupByFolder={groupByFolder}\n gridId={id ? `${id}-list` : undefined}\n tableRef={dataTableRef}\n toolbarActions={toolbarActions}\n />\n )}\n </div>\n </div>\n\n {/* Footer path bar. The breadcrumb wraps its children in its own\n BreadcrumbList (the single <ol>), injects separators, and marks the\n final item current — the last crumb renders as plain text. Pass\n items directly; never nest a second BreadcrumbList (invalid\n <ol><ol>). Root + ancestors stay clickable to navigate up.\n `disableCollapse`: our ancestor crumbs are `asChild` <button>s (the\n path navigates in-memory, not by href), and the collapsed-ellipsis\n rebuild would wrap those in an <a> (nested interactive). A compact\n footer path doesn't need collapse, so we keep every crumb inline. */}\n <div className=\"ds:mt-[var(--spacing-sm)] ds:border-t ds:border-[color:var(--border)] ds:pt-[var(--spacing-sm)] ds:text-muted-foreground\">\n <Breadcrumb\n aria-label={t('fileManager.breadcrumbLabel', 'Folder path')}\n disableCollapse\n >\n <BreadcrumbItem>\n {path.length === 0 ? (\n <BreadcrumbLink>\n {t('fileManager.rootLabel', 'All files')}\n </BreadcrumbLink>\n ) : (\n <BreadcrumbLink asChild>\n <button type=\"button\" onClick={() => navigateTo(null)}>\n {t('fileManager.rootLabel', 'All files')}\n </button>\n </BreadcrumbLink>\n )}\n </BreadcrumbItem>\n {path.map((folder, index) => (\n <BreadcrumbItem key={folder.id}>\n {index === path.length - 1 ? (\n <BreadcrumbLink>{folder.name}</BreadcrumbLink>\n ) : (\n <BreadcrumbLink asChild>\n <button type=\"button\" onClick={() => navigateTo(folder.id)}>\n {folder.name}\n </button>\n </BreadcrumbLink>\n )}\n </BreadcrumbItem>\n ))}\n </Breadcrumb>\n </div>\n\n {/* Selection-count live region — always visually hidden. The DataTable\n already renders a VISIBLE \"N rows selected\" status bar, so showing\n our own count too duplicated it; we keep this only as the polite\n announcement (the DataTable's count is a plain span, not a live\n region) so the count is still spoken on Space toggle / Ctrl+A. */}\n <p role=\"status\" aria-live=\"polite\" className=\"ds:sr-only\">\n {selectedIds.length > 0\n ? t('fileManager.selected', '{{count}} items selected', {\n count: selectedIds.length,\n })\n : ''}\n </p>\n\n {isDraggingFiles && (\n <div\n aria-hidden=\"true\"\n className=\"ds:pointer-events-none ds:absolute ds:inset-0 ds:z-20 ds:flex ds:flex-col ds:items-center ds:justify-center ds:gap-[var(--spacing-sm)] ds:rounded-[var(--radius-lg)] ds:border-2 ds:border-dashed ds:border-primary ds:bg-primary/10\"\n >\n <Upload className=\"ds:size-8 ds:text-primary\" />\n <span className=\"type-label ds:text-primary\">\n {t(\n 'fileManager.dropOverlay',\n 'Drop files to upload to {{folder}}',\n {\n folder: currentFolderName,\n },\n )}\n </span>\n </div>\n )}\n\n <span\n ref={liveRef}\n role=\"status\"\n aria-live=\"polite\"\n className=\"ds:sr-only\"\n />\n\n <CreateFolderDialog\n open={activeAction.type === 'create-folder'}\n onOpenChange={(open) => {\n if (!open) endAction();\n }}\n onSubmit={submitCreateFolder}\n />\n <UploadDialog\n open={activeAction.type === 'upload'}\n onOpenChange={(open) => {\n if (!open) endAction();\n }}\n onUpload={uploadToCurrentFolder}\n destinationLabel={currentFolderName}\n config={uploadConfig}\n />\n <RenameDialog\n open={activeAction.type === 'rename'}\n onOpenChange={(open) => {\n if (!open) endAction();\n }}\n initialName={renameItem?.name ?? ''}\n onSubmit={submitRename}\n />\n <DeleteDialog\n open={activeAction.type === 'delete'}\n onOpenChange={(open) => {\n if (!open) endAction();\n }}\n count={\n activeAction.type === 'delete' ? activeAction.itemIds.length : 0\n }\n onConfirm={submitDelete}\n />\n <MoveDialog\n open={activeAction.type === 'move'}\n onOpenChange={(open) => {\n if (!open) endAction();\n }}\n items={items}\n movingIds={activeAction.type === 'move' ? activeAction.itemIds : []}\n currentFolderId={currentFolderId}\n onConfirm={submitMove}\n />\n </div>\n );\n },\n);\n\nFileManager.displayName = 'FileManager';\n"],"names":["__iconNode","FileHeadphone","createLucideIcon","FilePlay","FolderInput","FolderOpen","FolderPlus","Folder","ITEM_META_SCHEMA","fileManagerAgent","handle","args","UNIT_KEYS","UNIT_FALLBACKS","formatFileSize","bytes","locale","t","value","unitIndex","getItemIcon","item","mime","FileImage","FileText","FileArchive","FileSpreadsheet","FileIcon","childrenOf","items","folderId","collator","i","b","descendantsOf","includedIds","grew","a","pathWithinFolder","itemsById","currentFolderId","path","cursor","seen","pathTo","byId","withDescendantFolderIds","ids","excluded","sameIdSet","set","id","ROOT_KEY","keyOf","treeItemRowVariants","cva","buildTree","excludeIds","build","flattenVisible","root","expanded","out","walk","node","parentKeyOf","_a","FolderTree","selectedFolderId","onSelectFolder","ariaLabel","i18n","useTranslation","isRtl","useMemo","setExpanded","useState","focusedKey","setFocusedKey","itemRefs","useRef","useEffect","prev","next","visible","n","focusNode","key","toggleExpanded","force","handleTreeKeyDown","event","target","index","hasChildren","isExpanded","expandKey","collapseKey","parentKey","renderNode","isSelected","label","IconComponent","handleRowClick","handleChevronClick","jsxs","el","jsx","ChevronRight","FORBIDDEN_NAME_CHARS","NAME_MAX_LENGTH","sanitizeName","CreateFolderDialog","open","onOpenChange","onSubmit","inputId","useId","name","setName","handleSubmit","trimmed","Dialog","TextInput","Button","UploadDialog","onUpload","destinationLabel","config","FileUpload","RenameDialog","initialName","DeleteDialog","count","onConfirm","MoveDialog","movingIds","setTarget","SIGNATURE_VARIANT","makeNameCellRenderer","previewedItemId","props","isPreviewed","TypeCellRenderer","Badge","makeSignatureCellRenderer","status","ListView","selectedIds","onSelectionChange","onOpen","onRowActivate","can","onRequestRename","onRequestMove","onRequestDelete","onDownload","onShare","onRequestSignature","itemActions","groupByFolder","gridId","tableRef","toolbarActions","hasSignatureColumn","hasTypeColumn","rowActions","actions","Download","data","PenLine","Share2","Pencil","Trash2","resolvedIds","action","actionId","columnDefs","SignatureCellRenderer","NameCellRenderer","defs","params","ActionsCellRenderer","actionsColumnWidth","gridOptions","options","dom","handleSelectionChanged","rows","row","getRowClass","useCallback","DataTable","FileManagerToolbar","permissions","onRequestCreateFolder","onRequestUpload","addMenuItems","hasSelection","singleSelection","canUpload","canDownload","canShare","extraAddItems","IconButtonGroup","IconButton","Upload","entry","Plus","fileManagerVariants","ALL_PERMISSIONS","FileManager","forwardRef","folderIdProp","defaultFolderId","onNavigate","showTree","isLoading","onOpenFile","onCreateFolder","onRenameItem","onDeleteItems","onMoveItems","onDownloadItems","uploadConfig","onPreviewItem","bordered","className","ref","resolvePerms","canItem","folderRaw","setFolder","useControllableState","setSelectedIdsRaw","activeAction","setActiveAction","isDraggingFiles","setIsDraggingFiles","dragDepth","dataTableRef","liveRef","announce","message","contentRef","focusContentAfterNav","setSelection","valid","itemId","navigateTo","targetId","breadcrumbTargetId","folderChildren","folderDescendants","currentFolderName","beginAction","endAction","requestCreateFolder","requestUpload","requestRename","requestDelete","itemIds","allowed","requestMove","handleDownload","handleShare","openItem","activateRow","submitCreateFolder","submitRename","submitDelete","submitMove","targetFolderId","uploadToCurrentFolder","file","helpers","uploadEnabled","isFileDrag","handleDragEnter","handleDragOver","handleDragLeave","handleDrop","handleRootKeyDown","only","stateRef","actionsRef","documentTypes","api","wanted","useImperativeHandle","useAgentRegistration","renameItem","Skeleton","EmptyState","Breadcrumb","BreadcrumbItem","BreadcrumbLink","folder"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5]}