@burdenoff/microfe-assethandler 2026.710.1 → 2026.713.2

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 (36) hide show
  1. package/dist/assethandler/AssetHandlerRoot.d.ts.map +1 -1
  2. package/dist/assethandler/AssetHandlerRoot.js +16 -8
  3. package/dist/assethandler/AssetHandlerRoot.js.map +1 -1
  4. package/dist/assethandler/components/AttachmentsPanel.d.ts.map +1 -1
  5. package/dist/assethandler/components/AttachmentsPanel.js.map +1 -1
  6. package/dist/assethandler/pages/AssetsAssetCategoriesPage.d.ts.map +1 -1
  7. package/dist/assethandler/pages/AssetsAssetCategoriesPage.js +144 -137
  8. package/dist/assethandler/pages/AssetsAssetCategoriesPage.js.map +1 -1
  9. package/dist/assethandler/pages/AssetsAssetCreatePage.d.ts.map +1 -1
  10. package/dist/assethandler/pages/AssetsAssetCreatePage.js +202 -201
  11. package/dist/assethandler/pages/AssetsAssetCreatePage.js.map +1 -1
  12. package/dist/assethandler/pages/AssetsAssetListPage.d.ts.map +1 -1
  13. package/dist/assethandler/pages/AssetsAssetListPage.js +135 -132
  14. package/dist/assethandler/pages/AssetsAssetListPage.js.map +1 -1
  15. package/dist/assethandler/providers/AssetHandlerProvider.d.ts +14 -0
  16. package/dist/assethandler/providers/AssetHandlerProvider.d.ts.map +1 -1
  17. package/dist/assethandler/providers/AssetHandlerProvider.js +14 -2
  18. package/dist/assethandler/providers/AssetHandlerProvider.js.map +1 -1
  19. package/dist/assethandler/store/assethandlerStore.d.ts.map +1 -1
  20. package/dist/assethandler/store/assethandlerStore.js.map +1 -1
  21. package/dist/assethandler/types/index.d.ts +32 -0
  22. package/dist/assethandler/types/index.d.ts.map +1 -1
  23. package/dist/services/createSandboxAssistantTransport.d.ts +8 -26
  24. package/dist/services/createSandboxAssistantTransport.d.ts.map +1 -1
  25. package/dist/services/createSandboxAssistantTransport.js +8 -114
  26. package/dist/services/createSandboxAssistantTransport.js.map +1 -1
  27. package/dist/types/assistant.d.ts.map +1 -1
  28. package/dist/utils/pageContext.d.ts.map +1 -1
  29. package/dist/utils/pageContext.js.map +1 -1
  30. package/package.json +2 -2
  31. package/dist/generated/wspace-operations.js +0 -255
  32. package/dist/generated/wspace-operations.js.map +0 -1
  33. package/dist/services/assistantApi.d.ts +0 -71
  34. package/dist/services/assistantApi.d.ts.map +0 -1
  35. package/dist/services/assistantApi.js +0 -215
  36. package/dist/services/assistantApi.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AssetHandlerRoot.d.ts","sourceRoot":"","sources":["../../src/assethandler/AssetHandlerRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAgBhC,OAAO,KAAK,EAAE,qBAAqB,EAAW,MAAM,SAAS,CAAC;AAG9D,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAyItD,CAAC"}
1
+ {"version":3,"file":"AssetHandlerRoot.d.ts","sourceRoot":"","sources":["../../src/assethandler/AssetHandlerRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAgBhC,OAAO,KAAK,EAAE,qBAAqB,EAAW,MAAM,SAAS,CAAC;AAG9D,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CA0JtD,CAAC"}
@@ -7,11 +7,12 @@ import { jsx as f } from "react/jsx-runtime";
7
7
  import { FeatureFlagProvider as p } from "@burdenoff/fe-libs/shared/feature-flags";
8
8
  //#region src/assethandler/AssetHandlerRoot.tsx
9
9
  var m = (m) => {
10
- let { registerNavItems: h, registerFooterItems: g, basePath: _ = "/" } = m;
10
+ let { registerNavItems: h, registerFooterItems: g, basePath: _ = "/", brandLabel: v = "AssetHandler", terminology: y, hiddenCategoryIds: b } = m, x = y?.assets || "Assets";
11
11
  return r(() => {
12
- if (h) return h({
12
+ if (!h) return;
13
+ let e = new Set(b ?? []), n = (t) => e.has(t.replace(/^assethandler-/, "")), r = {
13
14
  id: "assethandler",
14
- label: "AssetHandler",
15
+ label: v,
15
16
  path: _,
16
17
  icon: /* @__PURE__ */ f(i, { size: 20 }),
17
18
  order: 82,
@@ -25,7 +26,7 @@ var m = (m) => {
25
26
  },
26
27
  {
27
28
  id: "assethandler-assets",
28
- label: "Assets",
29
+ label: x,
29
30
  path: t(_, "assets/asset-list"),
30
31
  order: 1
31
32
  },
@@ -110,16 +111,23 @@ var m = (m) => {
110
111
  order: 17
111
112
  }
112
113
  ]
113
- });
114
- }, [_, h]), r(() => {
114
+ };
115
+ return r.children &&= r.children.filter((e) => !n(e.id)), h(r);
116
+ }, [
117
+ _,
118
+ h,
119
+ v,
120
+ x,
121
+ b
122
+ ]), r(() => {
115
123
  if (g) return g([{
116
124
  id: "assethandler-status",
117
- label: "AssetHandler Live",
125
+ label: `${v} Live`,
118
126
  type: "status",
119
127
  section: "left",
120
128
  order: 10
121
129
  }]);
122
- }, [g]), /* @__PURE__ */ f(p, {
130
+ }, [g, v]), /* @__PURE__ */ f(p, {
123
131
  workspaceId: null,
124
132
  gateway: "global",
125
133
  defaultEnabled: !0,
@@ -1 +1 @@
1
- {"version":3,"file":"AssetHandlerRoot.js","names":[],"sources":["../../src/assethandler/AssetHandlerRoot.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect } from 'react';\nimport {\n BrainCircuit,\n Boxes,\n Cpu,\n KeyRound,\n Leaf,\n Network,\n Radar,\n ShieldCheck,\n} from 'lucide-react';\n\nimport { AssetHandlerRoutes } from './AssetHandlerRoutes';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { AssetHandlerProvider } from './providers/AssetHandlerProvider';\nimport type { AssetHandlerRootProps, NavItem } from './types';\nimport { joinPath } from './utils/navigation';\n\nexport const AssetHandlerRoot: FC<AssetHandlerRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '/' } = props;\n\n useEffect(() => {\n if (!registerNavItems) {\n return;\n }\n\n const navItem: NavItem = {\n id: 'assethandler',\n label: 'AssetHandler',\n path: basePath,\n icon: <Boxes size={20} />,\n order: 82,\n group: 'products',\n children: [\n {\n id: 'assethandler-dashboard',\n label: 'Dashboard',\n path: basePath,\n order: 0,\n },\n {\n id: 'assethandler-assets',\n label: 'Assets',\n path: joinPath(basePath, 'assets/asset-list'),\n order: 1,\n },\n {\n id: 'assethandler-operations',\n label: 'Operations',\n path: joinPath(basePath, 'operations/operations-hub'),\n order: 2,\n },\n {\n id: 'assethandler-itil',\n label: 'ITIL',\n path: joinPath(basePath, 'itil/itilhub'),\n order: 3,\n },\n {\n id: 'assethandler-finance',\n label: 'Finance',\n path: joinPath(basePath, 'finance/finance-hub'),\n order: 4,\n },\n {\n id: 'assethandler-security',\n label: 'Security',\n path: joinPath(basePath, 'security/security-hub'),\n order: 7,\n },\n {\n id: 'assethandler-iot',\n label: 'IoT Devices',\n path: joinPath(basePath, 'advanced/iot-devices'),\n icon: <Cpu size={16} />,\n order: 10,\n },\n {\n id: 'assethandler-digital-twin',\n label: 'Digital Twin',\n path: joinPath(basePath, 'advanced/digital-twin'),\n icon: <Boxes size={16} />,\n order: 11,\n },\n {\n id: 'assethandler-sam',\n label: 'SAM',\n path: joinPath(basePath, 'advanced/sam-licenses'),\n icon: <KeyRound size={16} />,\n order: 12,\n },\n {\n id: 'assethandler-cmdb',\n label: 'CMDB',\n path: joinPath(basePath, 'advanced/cmdb-browser'),\n icon: <Network size={16} />,\n order: 13,\n },\n {\n id: 'assethandler-discovery',\n label: 'Discovery',\n path: joinPath(basePath, 'advanced/discovery-jobs'),\n icon: <Radar size={16} />,\n order: 14,\n },\n {\n id: 'assethandler-provenance',\n label: 'Provenance',\n path: joinPath(basePath, 'advanced/provenance'),\n icon: <ShieldCheck size={16} />,\n order: 15,\n },\n {\n id: 'assethandler-esg',\n label: 'ESG',\n path: joinPath(basePath, 'advanced/esg-dashboard'),\n icon: <Leaf size={16} />,\n order: 16,\n },\n {\n id: 'assethandler-ai',\n label: 'AI Predictions',\n path: joinPath(basePath, 'advanced/ai-predictions'),\n icon: <BrainCircuit size={16} />,\n order: 17,\n },\n ],\n };\n\n return registerNavItems(navItem);\n }, [basePath, registerNavItems]);\n\n useEffect(() => {\n if (!registerFooterItems) {\n return;\n }\n\n return registerFooterItems([\n {\n id: 'assethandler-status',\n label: 'AssetHandler Live',\n type: 'status',\n section: 'left',\n order: 10,\n },\n ]);\n }, [registerFooterItems]);\n\n return (\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <AssetHandlerProvider {...props}>\n <AssetHandlerRoutes />\n </AssetHandlerProvider>\n </FeatureFlagProvider>\n );\n};\n"],"mappings":";;;;;;;;AAmBA,IAAa,KAA+C,MAAU;CACpE,IAAM,EAAE,qBAAkB,wBAAqB,cAAW,QAAQ;AAiIlE,QA/HA,QAAgB;AACT,QA2GL,QAAO,EAvGkB;GACvB,IAAI;GACJ,OAAO;GACP,MAAM;GACN,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;GACzB,OAAO;GACP,OAAO;GACP,UAAU;IACR;KACE,IAAI;KACJ,OAAO;KACP,MAAM;KACN,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,oBAAoB;KAC7C,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,4BAA4B;KACrD,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,eAAe;KACxC,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,sBAAsB;KAC/C,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,wBAAwB;KACjD,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,uBAAuB;KAChD,MAAM,kBAAC,GAAD,EAAK,MAAM,IAAM,CAAA;KACvB,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,wBAAwB;KACjD,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;KACzB,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,wBAAwB;KACjD,MAAM,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA;KAC5B,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,wBAAwB;KACjD,MAAM,kBAAC,GAAD,EAAS,MAAM,IAAM,CAAA;KAC3B,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,0BAA0B;KACnD,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;KACzB,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,sBAAsB;KAC/C,MAAM,kBAAC,GAAD,EAAa,MAAM,IAAM,CAAA;KAC/B,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,yBAAyB;KAClD,MAAM,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;KACxB,OAAO;KACR;IACD;KACE,IAAI;KACJ,OAAO;KACP,MAAM,EAAS,GAAU,0BAA0B;KACnD,MAAM,kBAAC,GAAD,EAAc,MAAM,IAAM,CAAA;KAChC,OAAO;KACR;IACF;GACF,CAE+B;IAC/B,CAAC,GAAU,EAAiB,CAAC,EAEhC,QAAgB;AACT,QAIL,QAAO,EAAoB,CACzB;GACE,IAAI;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,OAAO;GACR,CACF,CAAC;IACD,CAAC,EAAoB,CAAC,EAGvB,kBAAC,GAAD;EAAqB,aAAa;EAAM,SAAQ;EAAS,gBAAgB;YACvE,kBAAC,GAAD;GAAsB,GAAI;aACxB,kBAAC,GAAD,EAAsB,CAAA;GACD,CAAA;EACH,CAAA"}
1
+ {"version":3,"file":"AssetHandlerRoot.js","names":[],"sources":["../../src/assethandler/AssetHandlerRoot.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect } from 'react';\nimport {\n BrainCircuit,\n Boxes,\n Cpu,\n KeyRound,\n Leaf,\n Network,\n Radar,\n ShieldCheck,\n} from 'lucide-react';\n\nimport { AssetHandlerRoutes } from './AssetHandlerRoutes';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { AssetHandlerProvider } from './providers/AssetHandlerProvider';\nimport type { AssetHandlerRootProps, NavItem } from './types';\nimport { joinPath } from './utils/navigation';\n\nexport const AssetHandlerRoot: FC<AssetHandlerRootProps> = (props) => {\n const {\n registerNavItems,\n registerFooterItems,\n basePath = '/',\n brandLabel = 'AssetHandler',\n terminology,\n hiddenCategoryIds,\n } = props;\n const assetsLabel = terminology?.assets || 'Assets';\n\n useEffect(() => {\n if (!registerNavItems) {\n return;\n }\n\n // Consumers can hide advanced (IT-specific) nav children by passing their\n // id with the \"assethandler-\" prefix stripped, e.g. \"digital-twin\".\n const hidden = new Set(hiddenCategoryIds ?? []);\n const isHidden = (id: string) => hidden.has(id.replace(/^assethandler-/, ''));\n\n const navItem: NavItem = {\n id: 'assethandler',\n label: brandLabel,\n path: basePath,\n icon: <Boxes size={20} />,\n order: 82,\n group: 'products',\n children: [\n {\n id: 'assethandler-dashboard',\n label: 'Dashboard',\n path: basePath,\n order: 0,\n },\n {\n id: 'assethandler-assets',\n label: assetsLabel,\n path: joinPath(basePath, 'assets/asset-list'),\n order: 1,\n },\n {\n id: 'assethandler-operations',\n label: 'Operations',\n path: joinPath(basePath, 'operations/operations-hub'),\n order: 2,\n },\n {\n id: 'assethandler-itil',\n label: 'ITIL',\n path: joinPath(basePath, 'itil/itilhub'),\n order: 3,\n },\n {\n id: 'assethandler-finance',\n label: 'Finance',\n path: joinPath(basePath, 'finance/finance-hub'),\n order: 4,\n },\n {\n id: 'assethandler-security',\n label: 'Security',\n path: joinPath(basePath, 'security/security-hub'),\n order: 7,\n },\n {\n id: 'assethandler-iot',\n label: 'IoT Devices',\n path: joinPath(basePath, 'advanced/iot-devices'),\n icon: <Cpu size={16} />,\n order: 10,\n },\n {\n id: 'assethandler-digital-twin',\n label: 'Digital Twin',\n path: joinPath(basePath, 'advanced/digital-twin'),\n icon: <Boxes size={16} />,\n order: 11,\n },\n {\n id: 'assethandler-sam',\n label: 'SAM',\n path: joinPath(basePath, 'advanced/sam-licenses'),\n icon: <KeyRound size={16} />,\n order: 12,\n },\n {\n id: 'assethandler-cmdb',\n label: 'CMDB',\n path: joinPath(basePath, 'advanced/cmdb-browser'),\n icon: <Network size={16} />,\n order: 13,\n },\n {\n id: 'assethandler-discovery',\n label: 'Discovery',\n path: joinPath(basePath, 'advanced/discovery-jobs'),\n icon: <Radar size={16} />,\n order: 14,\n },\n {\n id: 'assethandler-provenance',\n label: 'Provenance',\n path: joinPath(basePath, 'advanced/provenance'),\n icon: <ShieldCheck size={16} />,\n order: 15,\n },\n {\n id: 'assethandler-esg',\n label: 'ESG',\n path: joinPath(basePath, 'advanced/esg-dashboard'),\n icon: <Leaf size={16} />,\n order: 16,\n },\n {\n id: 'assethandler-ai',\n label: 'AI Predictions',\n path: joinPath(basePath, 'advanced/ai-predictions'),\n icon: <BrainCircuit size={16} />,\n order: 17,\n },\n ],\n };\n\n if (navItem.children) {\n navItem.children = navItem.children.filter((child) => !isHidden(child.id));\n }\n\n return registerNavItems(navItem);\n }, [basePath, registerNavItems, brandLabel, assetsLabel, hiddenCategoryIds]);\n\n useEffect(() => {\n if (!registerFooterItems) {\n return;\n }\n\n return registerFooterItems([\n {\n id: 'assethandler-status',\n label: `${brandLabel} Live`,\n type: 'status',\n section: 'left',\n order: 10,\n },\n ]);\n }, [registerFooterItems, brandLabel]);\n\n return (\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <AssetHandlerProvider {...props}>\n <AssetHandlerRoutes />\n </AssetHandlerProvider>\n </FeatureFlagProvider>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentsPanel.d.ts","sourceRoot":"","sources":["../../../src/assethandler/components/AttachmentsPanel.tsx"],"names":[],"mappings":"AAiCA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AA2ND,wBAAgB,gBAAgB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,qBAAqB,+BAmP/E"}
1
+ {"version":3,"file":"AttachmentsPanel.d.ts","sourceRoot":"","sources":["../../../src/assethandler/components/AttachmentsPanel.tsx"],"names":[],"mappings":"AAiCA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAmND,wBAAgB,gBAAgB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,qBAAqB,+BAmP/E"}
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentsPanel.js","names":[],"sources":["../../../src/assethandler/components/AttachmentsPanel.tsx"],"sourcesContent":["import { useMemo, useRef, useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n IllustratedEmptyState,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Paperclip,\n Upload,\n Link2,\n FileText,\n FileSpreadsheet,\n FileArchive,\n FileCode2,\n FileVideo,\n FileAudio,\n Image as ImageIcon,\n File as FileIcon,\n Loader2,\n Download,\n MoreHorizontal,\n} from 'lucide-react';\nimport { notify } from '../utils/toast';\n\n/**\n * Attach and reference files for an AssetHandler entity, backed by the\n * federated wspace-files-svc (same wspace gateway/Apollo client). Fully real (no fabricated data) —\n * lists workspace files via `getFiles`, uploads new files through the\n * `initiateUpload` → presigned PUT → `completeUpload` flow, and mints public\n * share links via `createFileShareLink`. All entries are live data.\n *\n * `entityType`/`entityId` scope the panel to the record it is mounted on and\n * are used for context labelling; uploaded files land in the workspace file\n * store so they can be shared and reused.\n */\nexport interface AttachmentsPanelProps {\n entityType: string;\n entityId: string;\n}\n\ninterface FileNode {\n id: string;\n name: string;\n extension: string;\n mimeType: string;\n size: number;\n downloadUrl?: string | null;\n createdAt: string;\n}\n\ninterface GetFilesResult {\n getFiles: {\n files: FileNode[];\n total: number;\n hasMore: boolean;\n };\n}\n\nconst GET_FILES_QUERY = gql`\n query AssetHandlerGetFiles($pagination: PaginationInput, $sort: FileSortInput) {\n getFiles(pagination: $pagination, sort: $sort) {\n total\n hasMore\n files {\n id\n name\n extension\n mimeType\n size\n downloadUrl\n createdAt\n }\n }\n }\n`;\n\nconst INITIATE_UPLOAD_MUTATION = gql`\n mutation AssetHandlerInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session {\n id\n }\n }\n }\n`;\n\nconst COMPLETE_UPLOAD_MUTATION = gql`\n mutation AssetHandlerCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n file {\n id\n name\n }\n }\n }\n`;\n\nconst CREATE_SHARE_LINK_MUTATION = gql`\n mutation AssetHandlerCreateFileShareLink($input: CreateShareGrantLinkInput!) {\n createFileShareLink(input: $input) {\n id\n shareUrl\n }\n }\n`;\n\nfunction formatSize(bytes: number): string {\n if (!bytes) return '0 B';\n const units = ['B', 'KB', 'MB', 'GB'];\n const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);\n const value = bytes / Math.pow(1024, exponent);\n return `${value.toFixed(exponent === 0 ? 0 : 1)} ${units[exponent]}`;\n}\n\nfunction extensionOf(fileName: string): string {\n const dot = fileName.lastIndexOf('.');\n return dot >= 0 ? fileName.slice(dot + 1).toLowerCase() : 'bin';\n}\n\n/** Compact relative time (\"2 hrs ago\"), with the full timestamp on hover. */\nfunction relativeTime(iso: string): string {\n const then = new Date(iso).getTime();\n if (Number.isNaN(then)) return '';\n const diff = Date.now() - then;\n const sec = Math.round(diff / 1000);\n if (sec < 45) return 'just now';\n const min = Math.round(sec / 60);\n if (min < 60) return `${min} min ago`;\n const hr = Math.round(min / 60);\n if (hr < 24) return `${hr} hr${hr === 1 ? '' : 's'} ago`;\n const day = Math.round(hr / 24);\n if (day < 30) return `${day} day${day === 1 ? '' : 's'} ago`;\n return new Date(iso).toLocaleDateString();\n}\n\ntype FileKind =\n | 'image'\n | 'pdf'\n | 'sheet'\n | 'doc'\n | 'archive'\n | 'code'\n | 'video'\n | 'audio'\n | 'other';\n\n/** Map a file's extension/mime to a recognisable kind for icon + tint. */\nfunction kindOf(file: FileNode): FileKind {\n const mime = (file.mimeType || '').toLowerCase();\n const ext = (file.extension || extensionOf(file.name)).toLowerCase();\n if (\n mime.startsWith('image/') ||\n ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'avif', 'bmp'].includes(ext)\n )\n return 'image';\n if (mime.startsWith('video/') || ['mp4', 'mov', 'webm', 'avi', 'mkv'].includes(ext))\n return 'video';\n if (mime.startsWith('audio/') || ['mp3', 'wav', 'ogg', 'm4a', 'flac'].includes(ext))\n return 'audio';\n if (mime === 'application/pdf' || ext === 'pdf') return 'pdf';\n if (['xls', 'xlsx', 'csv', 'tsv', 'ods'].includes(ext)) return 'sheet';\n if (['zip', 'rar', '7z', 'tar', 'gz', 'bz2'].includes(ext)) return 'archive';\n if (\n [\n 'js',\n 'ts',\n 'tsx',\n 'jsx',\n 'json',\n 'xml',\n 'yml',\n 'yaml',\n 'html',\n 'css',\n 'sh',\n 'py',\n 'sql',\n ].includes(ext)\n )\n return 'code';\n if (['doc', 'docx', 'txt', 'md', 'rtf', 'odt', 'pages'].includes(ext)) return 'doc';\n return 'other';\n}\n\nconst KIND_STYLE: Record<\n FileKind,\n { Icon: typeof FileText; iconClass: string; tileClass: string }\n> = {\n image: {\n Icon: ImageIcon,\n iconClass: 'text-status-success-text',\n tileClass: 'bg-status-success-bg-subtle',\n },\n pdf: {\n Icon: FileText,\n iconClass: 'text-status-error-text',\n tileClass: 'bg-status-error-bg-subtle',\n },\n sheet: {\n Icon: FileSpreadsheet,\n iconClass: 'text-status-success-text',\n tileClass: 'bg-status-success-bg-subtle',\n },\n doc: {\n Icon: FileText,\n iconClass: 'text-status-info-text',\n tileClass: 'bg-status-info-bg-subtle',\n },\n archive: {\n Icon: FileArchive,\n iconClass: 'text-status-warning-text',\n tileClass: 'bg-status-warning-bg-subtle',\n },\n code: {\n Icon: FileCode2,\n iconClass: 'text-status-info-text',\n tileClass: 'bg-status-info-bg-subtle',\n },\n video: {\n Icon: FileVideo,\n iconClass: 'text-status-info-text',\n tileClass: 'bg-status-info-bg-subtle',\n },\n audio: {\n Icon: FileAudio,\n iconClass: 'text-status-warning-text',\n tileClass: 'bg-status-warning-bg-subtle',\n },\n other: { Icon: FileIcon, iconClass: 'text-text-secondary', tileClass: 'bg-bg-sunken' },\n};\n\n/** File-type badge tile — an inline thumbnail for images, a tinted glyph otherwise. */\nfunction FileBadge({ file }: { file: FileNode }) {\n const kind = kindOf(file);\n const { Icon, iconClass, tileClass } = KIND_STYLE[kind];\n if (kind === 'image' && file.downloadUrl) {\n return (\n <img\n src={file.downloadUrl}\n alt=\"\"\n loading=\"lazy\"\n className=\"h-10 w-10 shrink-0 rounded-lg border border-border-subtle object-cover\"\n />\n );\n }\n return (\n <span\n className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-lg ${tileClass}`}\n aria-hidden=\"true\"\n >\n <Icon className={`h-5 w-5 ${iconClass}`} />\n </span>\n );\n}\n\nexport function AttachmentsPanel({ entityType, entityId }: AttachmentsPanelProps) {\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [uploading, setUploading] = useState(false);\n const [sharingId, setSharingId] = useState<string | null>(null);\n\n const { data, loading, refetch } = useQuery<GetFilesResult>(GET_FILES_QUERY, {\n variables: {\n pagination: { limit: 25, offset: 0 },\n sort: { field: 'CREATED_AT', order: 'DESC' },\n },\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'all',\n });\n\n const [initiateUpload] = useMutation<{\n initiateUpload: { uploadUrl?: string | null; session: { id: string } };\n }>(INITIATE_UPLOAD_MUTATION);\n const [completeUpload] = useMutation(COMPLETE_UPLOAD_MUTATION);\n const [createShareLink] = useMutation<{\n createFileShareLink: { id: string; shareUrl?: string | null };\n }>(CREATE_SHARE_LINK_MUTATION);\n\n const files = useMemo(() => data?.getFiles.files ?? [], [data]);\n\n const handleFileSelected = async (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n // Reset the input so selecting the same file again re-triggers change.\n event.target.value = '';\n if (!file) return;\n\n setUploading(true);\n try {\n const initiated = await initiateUpload({\n variables: {\n input: {\n fileName: file.name,\n extension: extensionOf(file.name),\n fileSize: file.size,\n mimeType: file.type || 'application/octet-stream',\n visibility: 'WORKSPACE',\n },\n },\n });\n\n const uploadUrl = initiated.data?.initiateUpload.uploadUrl;\n const sessionId = initiated.data?.initiateUpload.session.id;\n if (!uploadUrl || !sessionId) {\n throw new Error('Upload could not be initialised.');\n }\n\n const putResponse = await fetch(uploadUrl, {\n method: 'PUT',\n body: file,\n headers: { 'Content-Type': file.type || 'application/octet-stream' },\n });\n if (!putResponse.ok) {\n throw new Error(`Storage rejected the upload (HTTP ${putResponse.status}).`);\n }\n\n await completeUpload({\n variables: { input: { sessionId, fileSize: file.size } },\n });\n\n notify.success('File uploaded', `${file.name} is now available on this record.`);\n await refetch();\n } catch (error) {\n notify.error(\n 'Upload failed',\n error instanceof Error ? error.message : 'The file could not be uploaded.'\n );\n } finally {\n setUploading(false);\n }\n };\n\n const handleShare = async (fileId: string) => {\n setSharingId(fileId);\n try {\n const result = await createShareLink({\n variables: { input: { resourceId: fileId, role: 'VIEWER' } },\n });\n const url = result.data?.createFileShareLink.shareUrl;\n if (!url) {\n throw new Error('No share link was returned.');\n }\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(url);\n notify.success('Share link copied', 'A view-only link is on your clipboard.');\n } else {\n notify.info('Share link ready', url);\n }\n } catch (error) {\n notify.error(\n 'Could not create share link',\n error instanceof Error ? error.message : 'Please try again.'\n );\n } finally {\n setSharingId(null);\n }\n };\n\n const total = data?.getFiles.total ?? 0;\n const hasFiles = files.length > 0;\n\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between gap-2 space-y-0\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Paperclip className=\"h-4 w-4\" />\n Attachments\n {total ? (\n <span className=\"text-sm font-normal text-text-secondary\">\n {total} file{total === 1 ? '' : 's'}\n </span>\n ) : null}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <input\n ref={fileInputRef}\n type=\"file\"\n className=\"hidden\"\n onChange={(event) => void handleFileSelected(event)}\n aria-label={`Upload a file for ${entityType} ${entityId}`}\n />\n\n {loading && !hasFiles ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 3 }).map((_, i) => (\n <div\n key={i}\n className=\"h-14 rounded-lg bg-bg-sunken motion-safe:animate-vc-shimmer\"\n />\n ))}\n </div>\n ) : !hasFiles ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No files yet\"\n description=\"Upload photos, receipts, warranties or documents to keep them with this record.\"\n />\n ) : (\n <ul className=\"space-y-1.5\">\n {files.map((file) => {\n const isSharing = sharingId === file.id;\n return (\n <li\n key={file.id}\n className=\"flex items-center gap-3 rounded-lg border border-border-subtle bg-bg-surface p-2.5\"\n >\n <FileBadge file={file} />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium\" title={file.name}>\n {file.name}\n </p>\n <p className=\"truncate text-xs text-text-secondary\">\n {formatSize(Number(file.size))} · {relativeTime(file.createdAt)}\n </p>\n </div>\n {/* Desktop: inline actions. Mobile: kebab menu to avoid crowding. */}\n <div className=\"hidden items-center gap-1 sm:flex\">\n {file.downloadUrl ? (\n <a\n href={file.downloadUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"rounded-md p-1.5 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n aria-label={`Download ${file.name}`}\n title=\"Download\"\n >\n <Download className=\"h-4 w-4\" />\n </a>\n ) : null}\n <button\n type=\"button\"\n disabled={isSharing}\n onClick={() => void handleShare(file.id)}\n className=\"rounded-md p-1.5 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary disabled:opacity-60\"\n aria-label={`Copy share link for ${file.name}`}\n title=\"Copy share link\"\n >\n {isSharing ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Link2 className=\"h-4 w-4\" />\n )}\n </button>\n </div>\n <div className=\"sm:hidden\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className=\"rounded-md p-1.5 text-text-secondary hover:bg-bg-sunken hover:text-text-primary\"\n aria-label={`Actions for ${file.name}`}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {file.downloadUrl ? (\n <DropdownMenuItem asChild>\n <a href={file.downloadUrl} target=\"_blank\" rel=\"noreferrer\">\n <Download className=\"mr-2 h-4 w-4\" />\n Download\n </a>\n </DropdownMenuItem>\n ) : null}\n <DropdownMenuItem\n disabled={isSharing}\n onSelect={(e) => {\n e.preventDefault();\n void handleShare(file.id);\n }}\n >\n <Link2 className=\"mr-2 h-4 w-4\" />\n Copy share link\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </li>\n );\n })}\n </ul>\n )}\n\n {/* Prominent full-width primary upload CTA (matches the reference concept). */}\n <Button\n className=\"w-full\"\n disabled={uploading}\n onClick={() => fileInputRef.current?.click()}\n >\n {uploading ? (\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n ) : (\n <Upload className=\"mr-2 h-4 w-4\" />\n )}\n {uploading ? 'Uploading…' : 'Upload files'}\n </Button>\n </CardContent>\n </Card>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AttachmentsPanel.js","names":[],"sources":["../../../src/assethandler/components/AttachmentsPanel.tsx"],"sourcesContent":["import { useMemo, useRef, useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n IllustratedEmptyState,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Paperclip,\n Upload,\n Link2,\n FileText,\n FileSpreadsheet,\n FileArchive,\n FileCode2,\n FileVideo,\n FileAudio,\n Image as ImageIcon,\n File as FileIcon,\n Loader2,\n Download,\n MoreHorizontal,\n} from 'lucide-react';\nimport { notify } from '../utils/toast';\n\n/**\n * Attach and reference files for an AssetHandler entity, backed by the\n * federated wspace-files-svc (same wspace gateway/Apollo client). Fully real (no fabricated data) —\n * lists workspace files via `getFiles`, uploads new files through the\n * `initiateUpload` → presigned PUT → `completeUpload` flow, and mints public\n * share links via `createFileShareLink`. All entries are live data.\n *\n * `entityType`/`entityId` scope the panel to the record it is mounted on and\n * are used for context labelling; uploaded files land in the workspace file\n * store so they can be shared and reused.\n */\nexport interface AttachmentsPanelProps {\n entityType: string;\n entityId: string;\n}\n\ninterface FileNode {\n id: string;\n name: string;\n extension: string;\n mimeType: string;\n size: number;\n downloadUrl?: string | null;\n createdAt: string;\n}\n\ninterface GetFilesResult {\n getFiles: {\n files: FileNode[];\n total: number;\n hasMore: boolean;\n };\n}\n\nconst GET_FILES_QUERY = gql`\n query AssetHandlerGetFiles($pagination: PaginationInput, $sort: FileSortInput) {\n getFiles(pagination: $pagination, sort: $sort) {\n total\n hasMore\n files {\n id\n name\n extension\n mimeType\n size\n downloadUrl\n createdAt\n }\n }\n }\n`;\n\nconst INITIATE_UPLOAD_MUTATION = gql`\n mutation AssetHandlerInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session {\n id\n }\n }\n }\n`;\n\nconst COMPLETE_UPLOAD_MUTATION = gql`\n mutation AssetHandlerCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n file {\n id\n name\n }\n }\n }\n`;\n\nconst CREATE_SHARE_LINK_MUTATION = gql`\n mutation AssetHandlerCreateFileShareLink($input: CreateShareGrantLinkInput!) {\n createFileShareLink(input: $input) {\n id\n shareUrl\n }\n }\n`;\n\nfunction formatSize(bytes: number): string {\n if (!bytes) return '0 B';\n const units = ['B', 'KB', 'MB', 'GB'];\n const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);\n const value = bytes / Math.pow(1024, exponent);\n return `${value.toFixed(exponent === 0 ? 0 : 1)} ${units[exponent]}`;\n}\n\nfunction extensionOf(fileName: string): string {\n const dot = fileName.lastIndexOf('.');\n return dot >= 0 ? fileName.slice(dot + 1).toLowerCase() : 'bin';\n}\n\n/** Compact relative time (\"2 hrs ago\"), with the full timestamp on hover. */\nfunction relativeTime(iso: string): string {\n const then = new Date(iso).getTime();\n if (Number.isNaN(then)) return '';\n const diff = Date.now() - then;\n const sec = Math.round(diff / 1000);\n if (sec < 45) return 'just now';\n const min = Math.round(sec / 60);\n if (min < 60) return `${min} min ago`;\n const hr = Math.round(min / 60);\n if (hr < 24) return `${hr} hr${hr === 1 ? '' : 's'} ago`;\n const day = Math.round(hr / 24);\n if (day < 30) return `${day} day${day === 1 ? '' : 's'} ago`;\n return new Date(iso).toLocaleDateString();\n}\n\ntype FileKind =\n 'image' | 'pdf' | 'sheet' | 'doc' | 'archive' | 'code' | 'video' | 'audio' | 'other';\n\n/** Map a file's extension/mime to a recognisable kind for icon + tint. */\nfunction kindOf(file: FileNode): FileKind {\n const mime = (file.mimeType || '').toLowerCase();\n const ext = (file.extension || extensionOf(file.name)).toLowerCase();\n if (\n mime.startsWith('image/') ||\n ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'avif', 'bmp'].includes(ext)\n )\n return 'image';\n if (mime.startsWith('video/') || ['mp4', 'mov', 'webm', 'avi', 'mkv'].includes(ext))\n return 'video';\n if (mime.startsWith('audio/') || ['mp3', 'wav', 'ogg', 'm4a', 'flac'].includes(ext))\n return 'audio';\n if (mime === 'application/pdf' || ext === 'pdf') return 'pdf';\n if (['xls', 'xlsx', 'csv', 'tsv', 'ods'].includes(ext)) return 'sheet';\n if (['zip', 'rar', '7z', 'tar', 'gz', 'bz2'].includes(ext)) return 'archive';\n if (\n [\n 'js',\n 'ts',\n 'tsx',\n 'jsx',\n 'json',\n 'xml',\n 'yml',\n 'yaml',\n 'html',\n 'css',\n 'sh',\n 'py',\n 'sql',\n ].includes(ext)\n )\n return 'code';\n if (['doc', 'docx', 'txt', 'md', 'rtf', 'odt', 'pages'].includes(ext)) return 'doc';\n return 'other';\n}\n\nconst KIND_STYLE: Record<\n FileKind,\n { Icon: typeof FileText; iconClass: string; tileClass: string }\n> = {\n image: {\n Icon: ImageIcon,\n iconClass: 'text-status-success-text',\n tileClass: 'bg-status-success-bg-subtle',\n },\n pdf: {\n Icon: FileText,\n iconClass: 'text-status-error-text',\n tileClass: 'bg-status-error-bg-subtle',\n },\n sheet: {\n Icon: FileSpreadsheet,\n iconClass: 'text-status-success-text',\n tileClass: 'bg-status-success-bg-subtle',\n },\n doc: {\n Icon: FileText,\n iconClass: 'text-status-info-text',\n tileClass: 'bg-status-info-bg-subtle',\n },\n archive: {\n Icon: FileArchive,\n iconClass: 'text-status-warning-text',\n tileClass: 'bg-status-warning-bg-subtle',\n },\n code: {\n Icon: FileCode2,\n iconClass: 'text-status-info-text',\n tileClass: 'bg-status-info-bg-subtle',\n },\n video: {\n Icon: FileVideo,\n iconClass: 'text-status-info-text',\n tileClass: 'bg-status-info-bg-subtle',\n },\n audio: {\n Icon: FileAudio,\n iconClass: 'text-status-warning-text',\n tileClass: 'bg-status-warning-bg-subtle',\n },\n other: { Icon: FileIcon, iconClass: 'text-text-secondary', tileClass: 'bg-bg-sunken' },\n};\n\n/** File-type badge tile — an inline thumbnail for images, a tinted glyph otherwise. */\nfunction FileBadge({ file }: { file: FileNode }) {\n const kind = kindOf(file);\n const { Icon, iconClass, tileClass } = KIND_STYLE[kind];\n if (kind === 'image' && file.downloadUrl) {\n return (\n <img\n src={file.downloadUrl}\n alt=\"\"\n loading=\"lazy\"\n className=\"h-10 w-10 shrink-0 rounded-lg border border-border-subtle object-cover\"\n />\n );\n }\n return (\n <span\n className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-lg ${tileClass}`}\n aria-hidden=\"true\"\n >\n <Icon className={`h-5 w-5 ${iconClass}`} />\n </span>\n );\n}\n\nexport function AttachmentsPanel({ entityType, entityId }: AttachmentsPanelProps) {\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [uploading, setUploading] = useState(false);\n const [sharingId, setSharingId] = useState<string | null>(null);\n\n const { data, loading, refetch } = useQuery<GetFilesResult>(GET_FILES_QUERY, {\n variables: {\n pagination: { limit: 25, offset: 0 },\n sort: { field: 'CREATED_AT', order: 'DESC' },\n },\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'all',\n });\n\n const [initiateUpload] = useMutation<{\n initiateUpload: { uploadUrl?: string | null; session: { id: string } };\n }>(INITIATE_UPLOAD_MUTATION);\n const [completeUpload] = useMutation(COMPLETE_UPLOAD_MUTATION);\n const [createShareLink] = useMutation<{\n createFileShareLink: { id: string; shareUrl?: string | null };\n }>(CREATE_SHARE_LINK_MUTATION);\n\n const files = useMemo(() => data?.getFiles.files ?? [], [data]);\n\n const handleFileSelected = async (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n // Reset the input so selecting the same file again re-triggers change.\n event.target.value = '';\n if (!file) return;\n\n setUploading(true);\n try {\n const initiated = await initiateUpload({\n variables: {\n input: {\n fileName: file.name,\n extension: extensionOf(file.name),\n fileSize: file.size,\n mimeType: file.type || 'application/octet-stream',\n visibility: 'WORKSPACE',\n },\n },\n });\n\n const uploadUrl = initiated.data?.initiateUpload.uploadUrl;\n const sessionId = initiated.data?.initiateUpload.session.id;\n if (!uploadUrl || !sessionId) {\n throw new Error('Upload could not be initialised.');\n }\n\n const putResponse = await fetch(uploadUrl, {\n method: 'PUT',\n body: file,\n headers: { 'Content-Type': file.type || 'application/octet-stream' },\n });\n if (!putResponse.ok) {\n throw new Error(`Storage rejected the upload (HTTP ${putResponse.status}).`);\n }\n\n await completeUpload({\n variables: { input: { sessionId, fileSize: file.size } },\n });\n\n notify.success('File uploaded', `${file.name} is now available on this record.`);\n await refetch();\n } catch (error) {\n notify.error(\n 'Upload failed',\n error instanceof Error ? error.message : 'The file could not be uploaded.'\n );\n } finally {\n setUploading(false);\n }\n };\n\n const handleShare = async (fileId: string) => {\n setSharingId(fileId);\n try {\n const result = await createShareLink({\n variables: { input: { resourceId: fileId, role: 'VIEWER' } },\n });\n const url = result.data?.createFileShareLink.shareUrl;\n if (!url) {\n throw new Error('No share link was returned.');\n }\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(url);\n notify.success('Share link copied', 'A view-only link is on your clipboard.');\n } else {\n notify.info('Share link ready', url);\n }\n } catch (error) {\n notify.error(\n 'Could not create share link',\n error instanceof Error ? error.message : 'Please try again.'\n );\n } finally {\n setSharingId(null);\n }\n };\n\n const total = data?.getFiles.total ?? 0;\n const hasFiles = files.length > 0;\n\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between gap-2 space-y-0\">\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Paperclip className=\"h-4 w-4\" />\n Attachments\n {total ? (\n <span className=\"text-sm font-normal text-text-secondary\">\n {total} file{total === 1 ? '' : 's'}\n </span>\n ) : null}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <input\n ref={fileInputRef}\n type=\"file\"\n className=\"hidden\"\n onChange={(event) => void handleFileSelected(event)}\n aria-label={`Upload a file for ${entityType} ${entityId}`}\n />\n\n {loading && !hasFiles ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 3 }).map((_, i) => (\n <div\n key={i}\n className=\"h-14 rounded-lg bg-bg-sunken motion-safe:animate-vc-shimmer\"\n />\n ))}\n </div>\n ) : !hasFiles ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No files yet\"\n description=\"Upload photos, receipts, warranties or documents to keep them with this record.\"\n />\n ) : (\n <ul className=\"space-y-1.5\">\n {files.map((file) => {\n const isSharing = sharingId === file.id;\n return (\n <li\n key={file.id}\n className=\"flex items-center gap-3 rounded-lg border border-border-subtle bg-bg-surface p-2.5\"\n >\n <FileBadge file={file} />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium\" title={file.name}>\n {file.name}\n </p>\n <p className=\"truncate text-xs text-text-secondary\">\n {formatSize(Number(file.size))} · {relativeTime(file.createdAt)}\n </p>\n </div>\n {/* Desktop: inline actions. Mobile: kebab menu to avoid crowding. */}\n <div className=\"hidden items-center gap-1 sm:flex\">\n {file.downloadUrl ? (\n <a\n href={file.downloadUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"rounded-md p-1.5 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n aria-label={`Download ${file.name}`}\n title=\"Download\"\n >\n <Download className=\"h-4 w-4\" />\n </a>\n ) : null}\n <button\n type=\"button\"\n disabled={isSharing}\n onClick={() => void handleShare(file.id)}\n className=\"rounded-md p-1.5 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary disabled:opacity-60\"\n aria-label={`Copy share link for ${file.name}`}\n title=\"Copy share link\"\n >\n {isSharing ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Link2 className=\"h-4 w-4\" />\n )}\n </button>\n </div>\n <div className=\"sm:hidden\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className=\"rounded-md p-1.5 text-text-secondary hover:bg-bg-sunken hover:text-text-primary\"\n aria-label={`Actions for ${file.name}`}\n >\n <MoreHorizontal className=\"h-4 w-4\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {file.downloadUrl ? (\n <DropdownMenuItem asChild>\n <a href={file.downloadUrl} target=\"_blank\" rel=\"noreferrer\">\n <Download className=\"mr-2 h-4 w-4\" />\n Download\n </a>\n </DropdownMenuItem>\n ) : null}\n <DropdownMenuItem\n disabled={isSharing}\n onSelect={(e) => {\n e.preventDefault();\n void handleShare(file.id);\n }}\n >\n <Link2 className=\"mr-2 h-4 w-4\" />\n Copy share link\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </li>\n );\n })}\n </ul>\n )}\n\n {/* Prominent full-width primary upload CTA (matches the reference concept). */}\n <Button\n className=\"w-full\"\n disabled={uploading}\n onClick={() => fileInputRef.current?.click()}\n >\n {uploading ? (\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n ) : (\n <Upload className=\"mr-2 h-4 w-4\" />\n )}\n {uploading ? 'Uploading…' : 'Upload files'}\n </Button>\n </CardContent>\n </Card>\n );\n}\n"],"mappings":";;;;;;;;AAmEA,IAAM,IAAkB,CAAG;;;;;;;;;;;;;;;;GAkBrB,IAA2B,CAAG;;;;;;;;;GAW9B,IAA2B,CAAG;;;;;;;;;;GAY9B,IAA6B,CAAG;;;;;;;;AAStC,SAAS,EAAW,GAAuB;AACzC,KAAI,CAAC,EAAO,QAAO;CACnB,IAAM,IAAQ;EAAC;EAAK;EAAM;EAAM;EAAK,EAC/B,IAAW,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI,EAAM,GAAG,KAAK,IAAI,KAAK,CAAC,EAAE,EAAM,SAAS,EAAE;AAEzF,QAAO,IADO,IAAiB,QAAM,GACrB,QAAQ,MAAa,IAAI,IAAI,EAAE,CAAC,GAAG,EAAM;;AAG3D,SAAS,EAAY,GAA0B;CAC7C,IAAM,IAAM,EAAS,YAAY,IAAI;AACrC,QAAO,KAAO,IAAI,EAAS,MAAM,IAAM,EAAE,CAAC,aAAa,GAAG;;AAI5D,SAAS,EAAa,GAAqB;CACzC,IAAM,IAAO,IAAI,KAAK,EAAI,CAAC,SAAS;AACpC,KAAI,OAAO,MAAM,EAAK,CAAE,QAAO;CAC/B,IAAM,IAAO,KAAK,KAAK,GAAG,GACpB,IAAM,KAAK,MAAM,IAAO,IAAK;AACnC,KAAI,IAAM,GAAI,QAAO;CACrB,IAAM,IAAM,KAAK,MAAM,IAAM,GAAG;AAChC,KAAI,IAAM,GAAI,QAAO,GAAG,EAAI;CAC5B,IAAM,IAAK,KAAK,MAAM,IAAM,GAAG;AAC/B,KAAI,IAAK,GAAI,QAAO,GAAG,EAAG,KAAK,MAAO,IAAI,KAAK,IAAI;CACnD,IAAM,IAAM,KAAK,MAAM,IAAK,GAAG;AAE/B,QADI,IAAM,KAAW,GAAG,EAAI,MAAM,MAAQ,IAAI,KAAK,IAAI,QAChD,IAAI,KAAK,EAAI,CAAC,oBAAoB;;AAO3C,SAAS,EAAO,GAA0B;CACxC,IAAM,KAAQ,EAAK,YAAY,IAAI,aAAa,EAC1C,KAAO,EAAK,aAAa,EAAY,EAAK,KAAK,EAAE,aAAa;AAgCpE,QA9BE,EAAK,WAAW,SAAS,IACzB;EAAC;EAAO;EAAO;EAAQ;EAAO;EAAQ;EAAO;EAAQ;EAAM,CAAC,SAAS,EAAI,GAElE,UACL,EAAK,WAAW,SAAS,IAAI;EAAC;EAAO;EAAO;EAAQ;EAAO;EAAM,CAAC,SAAS,EAAI,GAC1E,UACL,EAAK,WAAW,SAAS,IAAI;EAAC;EAAO;EAAO;EAAO;EAAO;EAAO,CAAC,SAAS,EAAI,GAC1E,UACL,MAAS,qBAAqB,MAAQ,QAAc,QACpD;EAAC;EAAO;EAAQ;EAAO;EAAO;EAAM,CAAC,SAAS,EAAI,GAAS,UAC3D;EAAC;EAAO;EAAO;EAAM;EAAO;EAAM;EAAM,CAAC,SAAS,EAAI,GAAS,YAEjE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,SAAS,EAAI,GAER,SACL;EAAC;EAAO;EAAQ;EAAO;EAAM;EAAO;EAAO;EAAQ,CAAC,SAAS,EAAI,GAAS,QACvE;;AAGT,IAAM,IAGF;CACF,OAAO;EACL,MAAM;EACN,WAAW;EACX,WAAW;EACZ;CACD,KAAK;EACH,MAAM;EACN,WAAW;EACX,WAAW;EACZ;CACD,OAAO;EACL,MAAM;EACN,WAAW;EACX,WAAW;EACZ;CACD,KAAK;EACH,MAAM;EACN,WAAW;EACX,WAAW;EACZ;CACD,SAAS;EACP,MAAM;EACN,WAAW;EACX,WAAW;EACZ;CACD,MAAM;EACJ,MAAM;EACN,WAAW;EACX,WAAW;EACZ;CACD,OAAO;EACL,MAAM;EACN,WAAW;EACX,WAAW;EACZ;CACD,OAAO;EACL,MAAM;EACN,WAAW;EACX,WAAW;EACZ;CACD,OAAO;EAAE,MAAM;EAAU,WAAW;EAAuB,WAAW;EAAgB;CACvF;AAGD,SAAS,EAAU,EAAE,WAA4B;CAC/C,IAAM,IAAO,EAAO,EAAK,EACnB,EAAE,SAAM,cAAW,iBAAc,EAAW;AAWlD,QAVI,MAAS,WAAW,EAAK,cAEzB,kBAAC,OAAD;EACE,KAAK,EAAK;EACV,KAAI;EACJ,SAAQ;EACR,WAAU;EACV,CAAA,GAIJ,kBAAC,QAAD;EACE,WAAW,kEAAkE;EAC7E,eAAY;YAEZ,kBAAC,GAAD,EAAM,WAAW,WAAW,KAAe,CAAA;EACtC,CAAA;;AAIX,SAAgB,EAAiB,EAAE,eAAY,eAAmC;CAChF,IAAM,IAAe,EAAyB,KAAK,EAC7C,CAAC,GAAW,KAAgB,EAAS,GAAM,EAC3C,CAAC,GAAW,KAAgB,EAAwB,KAAK,EAEzD,EAAE,SAAM,YAAS,eAAY,EAAyB,GAAiB;EAC3E,WAAW;GACT,YAAY;IAAE,OAAO;IAAI,QAAQ;IAAG;GACpC,MAAM;IAAE,OAAO;IAAc,OAAO;IAAQ;GAC7C;EACD,aAAa;EACb,aAAa;EACd,CAAC,EAEI,CAAC,KAAkB,EAEtB,EAAyB,EACtB,CAAC,KAAkB,EAAY,EAAyB,EACxD,CAAC,KAAmB,EAEvB,EAA2B,EAExB,IAAQ,QAAc,GAAM,SAAS,SAAS,EAAE,EAAE,CAAC,EAAK,CAAC,EAEzD,IAAqB,OAAO,MAA+C;EAC/E,IAAM,IAAO,EAAM,OAAO,QAAQ;AAElC,QAAM,OAAO,QAAQ,IAChB,GAEL;KAAa,GAAK;AAClB,OAAI;IACF,IAAM,IAAY,MAAM,EAAe,EACrC,WAAW,EACT,OAAO;KACL,UAAU,EAAK;KACf,WAAW,EAAY,EAAK,KAAK;KACjC,UAAU,EAAK;KACf,UAAU,EAAK,QAAQ;KACvB,YAAY;KACb,EACF,EACF,CAAC,EAEI,IAAY,EAAU,MAAM,eAAe,WAC3C,IAAY,EAAU,MAAM,eAAe,QAAQ;AACzD,QAAI,CAAC,KAAa,CAAC,EACjB,OAAU,MAAM,mCAAmC;IAGrD,IAAM,IAAc,MAAM,MAAM,GAAW;KACzC,QAAQ;KACR,MAAM;KACN,SAAS,EAAE,gBAAgB,EAAK,QAAQ,4BAA4B;KACrE,CAAC;AACF,QAAI,CAAC,EAAY,GACf,OAAU,MAAM,qCAAqC,EAAY,OAAO,IAAI;AAQ9E,IALA,MAAM,EAAe,EACnB,WAAW,EAAE,OAAO;KAAE;KAAW,UAAU,EAAK;KAAM,EAAE,EACzD,CAAC,EAEF,EAAO,QAAQ,iBAAiB,GAAG,EAAK,KAAK,mCAAmC,EAChF,MAAM,GAAS;YACR,GAAO;AACd,MAAO,MACL,iBACA,aAAiB,QAAQ,EAAM,UAAU,kCAC1C;aACO;AACR,MAAa,GAAM;;;IAIjB,IAAc,OAAO,MAAmB;AAC5C,IAAa,EAAO;AACpB,MAAI;GAIF,IAAM,KAHS,MAAM,EAAgB,EACnC,WAAW,EAAE,OAAO;IAAE,YAAY;IAAQ,MAAM;IAAU,EAAE,EAC7D,CAAC,EACiB,MAAM,oBAAoB;AAC7C,OAAI,CAAC,EACH,OAAU,MAAM,8BAA8B;AAEhD,GAAI,UAAU,WAAW,aACvB,MAAM,UAAU,UAAU,UAAU,EAAI,EACxC,EAAO,QAAQ,qBAAqB,yCAAyC,IAE7E,EAAO,KAAK,oBAAoB,EAAI;WAE/B,GAAO;AACd,KAAO,MACL,+BACA,aAAiB,QAAQ,EAAM,UAAU,oBAC1C;YACO;AACR,KAAa,KAAK;;IAIhB,IAAQ,GAAM,SAAS,SAAS,GAChC,IAAW,EAAM,SAAS;AAEhC,QACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;EAAY,WAAU;YACpB,kBAAC,GAAD;GAAW,WAAU;aAArB;IACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;;IAEhC,IACC,kBAAC,QAAD;KAAM,WAAU;eAAhB;MACG;MAAM;MAAM,MAAU,IAAI,KAAK;MAC3B;SACL;IACM;;EACD,CAAA,EACb,kBAAC,GAAD;EAAa,WAAU;YAAvB;GACE,kBAAC,SAAD;IACE,KAAK;IACL,MAAK;IACL,WAAU;IACV,WAAW,MAAU,KAAK,EAAmB,EAAM;IACnD,cAAY,qBAAqB,EAAW,GAAG;IAC/C,CAAA;GAED,KAAW,CAAC,IACX,kBAAC,OAAD;IAAK,WAAU;cACZ,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,OAAD,EAEE,WAAU,+DACV,EAFK,EAEL,CACF;IACE,CAAA,GACH,IAOH,kBAAC,MAAD;IAAI,WAAU;cACX,EAAM,KAAK,MAAS;KACnB,IAAM,IAAY,MAAc,EAAK;AACrC,YACE,kBAAC,MAAD;MAEE,WAAU;gBAFZ;OAIE,kBAAC,GAAD,EAAiB,SAAQ,CAAA;OACzB,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;SAA+B,OAAO,EAAK;mBACrD,EAAK;SACJ,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBAAb;UACG,EAAW,OAAO,EAAK,KAAK,CAAC;UAAC;UAAI,EAAa,EAAK,UAAU;UAC7D;WACA;;OAEN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACG,EAAK,cACJ,kBAAC,KAAD;SACE,MAAM,EAAK;SACX,QAAO;SACP,KAAI;SACJ,WAAU;SACV,cAAY,YAAY,EAAK;SAC7B,OAAM;mBAEN,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;SAC9B,CAAA,GACF,MACJ,kBAAC,UAAD;SACE,MAAK;SACL,UAAU;SACV,eAAe,KAAK,EAAY,EAAK,GAAG;SACxC,WAAU;SACV,cAAY,uBAAuB,EAAK;SACxC,OAAM;mBAEL,IACC,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,GAE5C,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;SAExB,CAAA,CACL;;OACN,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;SAAqB,SAAA;mBACnB,kBAAC,UAAD;UACE,MAAK;UACL,WAAU;UACV,cAAY,eAAe,EAAK;oBAEhC,kBAAC,GAAD,EAAgB,WAAU,WAAY,CAAA;UAC/B,CAAA;SACW,CAAA,EACtB,kBAAC,GAAD;SAAqB,OAAM;mBAA3B,CACG,EAAK,cACJ,kBAAC,GAAD;UAAkB,SAAA;oBAChB,kBAAC,KAAD;WAAG,MAAM,EAAK;WAAa,QAAO;WAAS,KAAI;qBAA/C,CACE,kBAAC,GAAD,EAAU,WAAU,gBAAiB,CAAA,EAAA,WAEnC;;UACa,CAAA,GACjB,MACJ,kBAAC,GAAD;UACE,UAAU;UACV,WAAW,MAAM;AAEV,WADL,EAAE,gBAAgB,EACb,EAAY,EAAK,GAAG;;oBAJ7B,CAOE,kBAAC,GAAD,EAAO,WAAU,gBAAiB,CAAA,EAAA,kBAEjB;YACC;WACT,EAAA,CAAA;QACX,CAAA;OACH;QA1EE,EAAK,GA0EP;MAEP;IACC,CAAA,GAxFL,kBAAC,GAAD;IACE,cAAa;IACb,OAAM;IACN,aAAY;IACZ,CAAA;GAwFJ,kBAAC,GAAD;IACE,WAAU;IACV,UAAU;IACV,eAAe,EAAa,SAAS,OAAO;cAH9C,CAKG,IACC,kBAAC,GAAD,EAAS,WAAU,6BAA8B,CAAA,GAEjD,kBAAC,GAAD,EAAQ,WAAU,gBAAiB,CAAA,EAEpC,IAAY,eAAe,eACrB;;GACG;IACT,EAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"AssetsAssetCategoriesPage.d.ts","sourceRoot":"","sources":["../../../src/assethandler/pages/AssetsAssetCategoriesPage.tsx"],"names":[],"mappings":"AAwGA,wBAAgB,yBAAyB,gCA8UxC"}
1
+ {"version":3,"file":"AssetsAssetCategoriesPage.d.ts","sourceRoot":"","sources":["../../../src/assethandler/pages/AssetsAssetCategoriesPage.tsx"],"names":[],"mappings":"AAyGA,wBAAgB,yBAAyB,gCAyVxC"}