@burdenoff/microfe-assethandler 2026.820.3 → 2026.820.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.
- package/dist/assethandler/components/AssetTag.d.ts +20 -0
- package/dist/assethandler/components/AssetTag.d.ts.map +1 -0
- package/dist/assethandler/components/AssetTag.js +8 -0
- package/dist/assethandler/components/AssetTag.js.map +1 -0
- package/dist/assethandler/components/index.d.ts +2 -0
- package/dist/assethandler/components/index.d.ts.map +1 -1
- package/dist/assethandler/components/index.js +1 -0
- package/dist/assethandler/pages/AssetsAssetCheckInOutPage.d.ts.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js +344 -181
- package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetDetailPage.d.ts.map +1 -1
- package/dist/assethandler/pages/AssetsAssetDetailPage.js +338 -325
- package/dist/assethandler/pages/AssetsAssetDetailPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetListPage.d.ts.map +1 -1
- package/dist/assethandler/pages/AssetsAssetListPage.js +177 -163
- package/dist/assethandler/pages/AssetsAssetListPage.js.map +1 -1
- package/dist/assethandler/providers/AssetHandlerProvider.d.ts.map +1 -1
- package/dist/assethandler/providers/AssetHandlerProvider.js +1 -0
- package/dist/assethandler/providers/AssetHandlerProvider.js.map +1 -1
- package/dist/assethandler/store/assethandlerStore.d.ts +2 -0
- package/dist/assethandler/store/assethandlerStore.d.ts.map +1 -1
- package/dist/assethandler/store/assethandlerStore.js +1 -0
- package/dist/assethandler/store/assethandlerStore.js.map +1 -1
- package/dist/assethandler/utils/printAssetTag.d.ts +24 -0
- package/dist/assethandler/utils/printAssetTag.d.ts.map +1 -0
- package/dist/assethandler/utils/printAssetTag.js +124 -0
- package/dist/assethandler/utils/printAssetTag.js.map +1 -0
- package/dist/node_modules/dijkstrajs/dijkstra.js +61 -0
- package/dist/node_modules/dijkstrajs/dijkstra.js.map +1 -0
- package/dist/node_modules/qrcode/lib/browser.js +40 -0
- package/dist/node_modules/qrcode/lib/browser.js.map +1 -0
- package/dist/node_modules/qrcode/lib/can-promise.js +12 -0
- package/dist/node_modules/qrcode/lib/can-promise.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/alignment-pattern.js +21 -0
- package/dist/node_modules/qrcode/lib/core/alignment-pattern.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/alphanumeric-data.js +28 -0
- package/dist/node_modules/qrcode/lib/core/alphanumeric-data.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/bit-buffer.js +28 -0
- package/dist/node_modules/qrcode/lib/core/bit-buffer.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/bit-matrix.js +23 -0
- package/dist/node_modules/qrcode/lib/core/bit-matrix.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/byte-data.js +23 -0
- package/dist/node_modules/qrcode/lib/core/byte-data.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/error-correction-code.js +350 -0
- package/dist/node_modules/qrcode/lib/core/error-correction-code.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/error-correction-level.js +34 -0
- package/dist/node_modules/qrcode/lib/core/error-correction-level.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/finder-pattern.js +19 -0
- package/dist/node_modules/qrcode/lib/core/finder-pattern.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/format-info.js +16 -0
- package/dist/node_modules/qrcode/lib/core/format-info.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/galois-field.js +22 -0
- package/dist/node_modules/qrcode/lib/core/galois-field.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/kanji-data.js +31 -0
- package/dist/node_modules/qrcode/lib/core/kanji-data.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/mask-pattern.js +84 -0
- package/dist/node_modules/qrcode/lib/core/mask-pattern.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/mode.js +74 -0
- package/dist/node_modules/qrcode/lib/core/mode.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/numeric-data.js +26 -0
- package/dist/node_modules/qrcode/lib/core/numeric-data.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/polynomial.js +30 -0
- package/dist/node_modules/qrcode/lib/core/polynomial.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/qrcode.js +117 -0
- package/dist/node_modules/qrcode/lib/core/qrcode.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/reed-solomon-encoder.js +27 -0
- package/dist/node_modules/qrcode/lib/core/reed-solomon-encoder.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/regex.js +21 -0
- package/dist/node_modules/qrcode/lib/core/regex.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/segments.js +144 -0
- package/dist/node_modules/qrcode/lib/core/segments.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/utils.js +70 -0
- package/dist/node_modules/qrcode/lib/core/utils.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/version-check.js +12 -0
- package/dist/node_modules/qrcode/lib/core/version-check.js.map +1 -0
- package/dist/node_modules/qrcode/lib/core/version.js +60 -0
- package/dist/node_modules/qrcode/lib/core/version.js.map +1 -0
- package/dist/node_modules/qrcode/lib/renderer/canvas.js +32 -0
- package/dist/node_modules/qrcode/lib/renderer/canvas.js.map +1 -0
- package/dist/node_modules/qrcode/lib/renderer/svg-tag.js +31 -0
- package/dist/node_modules/qrcode/lib/renderer/svg-tag.js.map +1 -0
- package/dist/node_modules/qrcode/lib/renderer/utils.js +55 -0
- package/dist/node_modules/qrcode/lib/renderer/utils.js.map +1 -0
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetsAssetListPage.js","names":[],"sources":["../../../src/assethandler/pages/AssetsAssetListPage.tsx"],"sourcesContent":["import { useAssetHandlerNavigate } from '../hooks/useAssetHandlerNavigate';\nimport {\n formatAssetCategory,\n useAssetCategoryPresentation,\n useHiddenCategoryIds,\n} from '../providers/AssetHandlerProvider';\nimport { useState, useMemo, useSyncExternalStore } from 'react';\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n Plus,\n Grid3x3,\n List,\n Table as TableIcon,\n ArrowUp,\n ArrowDown,\n ChevronsUpDown,\n MoreHorizontal,\n Copy,\n Eye,\n Monitor,\n Server,\n Wifi,\n Truck,\n Wrench,\n Code,\n Box,\n Boxes,\n CheckCircle2,\n} from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { notify } from '../utils/toast';\nimport { useCopy } from '../hooks/useCopy';\nimport {\n Pagination,\n usePagination,\n ChartCard,\n StatTile,\n DonutChart,\n BarsChart,\n formatCompact,\n} from '../components';\n\n// Soft, semantic status pill — matches the mock's soft pills (green/amber/gray/red).\nconst STATUS_PILL: Record<string, string> = {\n active: 'bg-status-success-bg-subtle text-status-success-text',\n maintenance: 'bg-status-warning-bg-subtle text-status-warning-text',\n inactive: 'bg-bg-sunken text-text-secondary',\n retired: 'bg-bg-sunken text-text-secondary',\n disposed: 'bg-status-error-bg-subtle text-status-error-text',\n};\n\nconst conditionColors: Record<string, string> = {\n excellent: 'text-status-success-text bg-status-success-bg-subtle',\n good: 'text-status-info-text bg-status-info-bg-subtle',\n fair: 'text-status-warning-text bg-status-warning-bg-subtle',\n poor: 'text-status-warning-text bg-status-warning-bg-subtle',\n damaged: 'text-status-error-text bg-status-error-bg-subtle',\n};\n\n// Status distribution slice colours — semantic tokens (theme-aware CSS vars).\nconst STATUS_SLICE_COLOR: Record<string, string> = {\n active: 'var(--color-status-success-bg)',\n maintenance: 'var(--color-status-warning-bg)',\n inactive: 'var(--color-status-info-bg)',\n retired: 'var(--color-text-muted)',\n disposed: 'var(--color-status-error-bg)',\n};\n\nconst categoryIcons: Record<string, typeof Box> = {\n electronics: Monitor,\n it_hardware: Monitor,\n furniture: Box,\n vehicles: Truck,\n equipment: Wrench,\n software: Code,\n networking: Wifi,\n servers: Server,\n};\nconst categoryTints: Record<string, string> = {\n electronics: 'bg-status-info-bg-subtle text-status-info-text',\n it_hardware: 'bg-status-info-bg-subtle text-status-info-text',\n furniture: 'bg-status-warning-bg-subtle text-status-warning-text',\n vehicles: 'bg-status-success-bg-subtle text-status-success-text',\n equipment: 'bg-status-warning-bg-subtle text-status-warning-text',\n software: 'bg-action-primary-bg/10 text-action-primary-bg',\n networking: 'bg-status-info-bg-subtle text-status-info-text',\n servers: 'bg-status-error-bg-subtle text-status-error-text',\n};\nfunction CategoryIconTile({ category }: { category: string }) {\n const Icon = categoryIcons[category] ?? Box;\n const tint = categoryTints[category] ?? 'bg-bg-sunken text-text-secondary';\n return (\n <span className={`inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md ${tint}`}>\n <Icon className=\"h-4 w-4\" />\n </span>\n );\n}\n\nfunction StatusPill({ status }: { status: string }) {\n return (\n <span\n className={`inline-flex rounded-full px-2.5 py-0.5 text-xs font-medium capitalize ${\n STATUS_PILL[status] || 'bg-bg-sunken text-text-secondary'\n }`}\n >\n {status.replace(/_/g, ' ')}\n </span>\n );\n}\n\ntype SortKey = 'assetTag' | 'name' | 'category' | 'status' | 'condition' | 'assignedTo';\n\n// SSR-safe narrow-viewport hook (auto-fall-back the table to cards on phones).\nfunction useIsNarrow(): boolean {\n return useSyncExternalStore(\n (cb) => {\n if (typeof window === 'undefined' || !window.matchMedia) return () => {};\n const mq = window.matchMedia('(max-width: 767px)');\n mq.addEventListener('change', cb);\n return () => mq.removeEventListener('change', cb);\n },\n () =>\n typeof window !== 'undefined' && window.matchMedia\n ? window.matchMedia('(max-width: 767px)').matches\n : false,\n () => false\n );\n}\n\nexport function AssetsAssetListPage() {\n const tc = useCopy();\n const navigate = useAssetHandlerNavigate();\n const hiddenCategories = useHiddenCategoryIds();\n const { labels: categoryLabels, options: configuredCategoryOptions } =\n useAssetCategoryPresentation();\n const { assets, hydrated } = useAssetHandlerStore();\n const isNarrow = useIsNarrow();\n const [searchQuery, setSearchQuery] = useState('');\n const [categoryFilter, setCategoryFilter] = useState('all');\n const [statusFilter, setStatusFilter] = useState('all');\n const [viewMode, setViewMode] = useState<'table' | 'grid' | 'list'>('table');\n const [userPickedView, setUserPickedView] = useState(false);\n const [sortKey, setSortKey] = useState<SortKey>('name');\n const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc');\n\n // On phones, default to the card list (unless the user explicitly chose a view).\n const effectiveView = !userPickedView && isNarrow && viewMode === 'table' ? 'list' : viewMode;\n const pickView = (mode: 'table' | 'grid' | 'list') => {\n setUserPickedView(true);\n setViewMode(mode);\n };\n\n const categories = useMemo(\n () =>\n [\n ...new Set([\n ...(configuredCategoryOptions?.map((option) => option.id) ?? []),\n ...assets.map((a) => a.category).filter(Boolean),\n ]),\n ]\n .filter((c) => !hiddenCategories.has(c))\n .sort(),\n [assets, configuredCategoryOptions, hiddenCategories]\n );\n\n const filteredAssets = useMemo(() => {\n return assets.filter((a) => {\n if (hiddenCategories.has(a.category)) return false;\n const matchesSearch =\n searchQuery === '' ||\n a.name.toLowerCase().includes(searchQuery.toLowerCase()) ||\n a.assetTag.toLowerCase().includes(searchQuery.toLowerCase()) ||\n a.serialNumber.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesCategory = categoryFilter === 'all' || a.category === categoryFilter;\n const matchesStatus = statusFilter === 'all' || a.status === statusFilter;\n return matchesSearch && matchesCategory && matchesStatus;\n });\n }, [assets, searchQuery, categoryFilter, statusFilter, hiddenCategories]);\n\n const sortedAssets = useMemo(() => {\n const dir = sortDir === 'asc' ? 1 : -1;\n return [...filteredAssets].sort((a, b) => {\n const av = (a[sortKey] ?? '').toString().toLowerCase();\n const bv = (b[sortKey] ?? '').toString().toLowerCase();\n return av.localeCompare(bv) * dir;\n });\n }, [filteredAssets, sortKey, sortDir]);\n\n const activeCount = assets.filter((a) => a.status === 'active').length;\n\n const statusSlices = useMemo(() => {\n const counts: Record<string, number> = {};\n for (const a of assets) counts[a.status] = (counts[a.status] || 0) + 1;\n return Object.entries(counts).map(([status, value]) => ({\n name: status.charAt(0).toUpperCase() + status.slice(1),\n value,\n color: STATUS_SLICE_COLOR[status],\n }));\n }, [assets]);\n\n const categoryBars = useMemo(() => {\n const counts: Record<string, number> = {};\n for (const a of assets) counts[a.category] = (counts[a.category] || 0) + 1;\n return Object.entries(counts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 8)\n .map(([category, count]) => ({\n category: formatAssetCategory(category, categoryLabels),\n count,\n }));\n }, [assets, categoryLabels]);\n\n const pager = usePagination(sortedAssets, {\n pageSize: 12,\n resetKey: `${searchQuery}|${categoryFilter}|${statusFilter}|${sortKey}|${sortDir}`,\n });\n\n const toggleSort = (key: SortKey) => {\n if (sortKey === key) {\n setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'));\n } else {\n setSortKey(key);\n setSortDir('asc');\n }\n };\n\n const renderSortHeader = (label: string, col: SortKey) => (\n <th className=\"p-3 text-left font-medium\">\n <button\n type=\"button\"\n onClick={() => toggleSort(col)}\n className=\"inline-flex items-center gap-1 hover:text-text-primary\"\n >\n {label}\n {sortKey === col ? (\n sortDir === 'asc' ? (\n <ArrowUp className=\"h-3 w-3 text-action-primary-bg\" />\n ) : (\n <ArrowDown className=\"h-3 w-3 text-action-primary-bg\" />\n )\n ) : (\n <ChevronsUpDown className=\"h-3 w-3 text-text-muted\" />\n )}\n </button>\n </th>\n );\n\n const copyTag = (tag: string) => {\n void navigator.clipboard?.writeText(tag);\n notify.success('Asset tag copied', `${tag} copied to clipboard.`);\n };\n\n return (\n <div className=\"space-y-6 p-4 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>\n {tc('assethandler.assets.list.title', '{{asset}} Inventory')}\n </GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {assets.length}{' '}\n {tc('assethandler.assets.list.subtitle.totalAssets', 'total {{assetsLower}}')} ·{' '}\n {activeCount} {tc('assethandler.assets.list.subtitle.active', 'active')}\n </p>\n </div>\n <Button\n className=\"w-full sm:w-auto\"\n size=\"sm\"\n onClick={() => navigate('/assets/asset-create')}\n >\n <Plus className=\"mr-2 h-4 w-4\" />\n {tc('assethandler.assets.list.actions.addAsset', 'Add {{asset}}')}\n </Button>\n </div>\n\n <PagePurpose>\n {tc(\n 'assethandler.assets.list.purpose',\n 'The single source of truth for every {{assetLower}} you own or manage. Search, filter and group by category, status or condition to find any item fast, review its assignment, then drill in to update, check it in/out or schedule maintenance.'\n )}\n </PagePurpose>\n\n {/* Insight strip */}\n {assets.length > 0 ? (\n <>\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatTile\n label=\"Total assets\"\n value={assets.length}\n format={formatCompact}\n icon={Boxes}\n hero\n />\n <StatTile\n label=\"Active\"\n value={activeCount}\n format={formatCompact}\n icon={CheckCircle2}\n />\n <StatTile\n label=\"Categories\"\n value={categories.length}\n format={formatCompact}\n icon={Box}\n />\n <StatTile\n label=\"Showing\"\n value={filteredAssets.length}\n format={formatCompact}\n icon={Search}\n />\n </div>\n <div className=\"grid gap-4 lg:grid-cols-2\">\n <ChartCard title=\"Status mix\" subtitle=\"Assets by lifecycle status\">\n <DonutChart\n data={statusSlices}\n centerLabel=\"Total\"\n centerValue={assets.length}\n height={220}\n />\n </ChartCard>\n <ChartCard title=\"By category\" subtitle=\"Top categories by asset count\">\n <BarsChart\n data={categoryBars}\n xKey=\"category\"\n orientation=\"horizontal\"\n height={220}\n categoryWidth={110}\n valueFormat={formatCompact}\n series={[\n {\n key: 'count',\n label: tc('assethandler.assets.list.chart.series', '{{assets}}'),\n },\n ]}\n />\n </ChartCard>\n </div>\n </>\n ) : null}\n\n {/* Filters Bar */}\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex flex-col gap-3 md:flex-row md:flex-wrap\">\n <div className=\"relative min-w-0 flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder={tc(\n 'assethandler.assets.list.search.placeholder',\n 'Search by name, {{assetLower}} tag, serial number...'\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <Select value={categoryFilter} onValueChange={setCategoryFilter}>\n <SelectTrigger className=\"w-full sm:w-[180px]\">\n <SelectValue\n placeholder={tc(\n 'assethandler.assets.list.filters.category.placeholder',\n 'Category'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tc('assethandler.assets.list.filters.category.all', 'All Categories')}\n </SelectItem>\n {categories.map((category) => (\n <SelectItem key={category} value={category} className=\"capitalize\">\n {formatAssetCategory(category, categoryLabels)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger className=\"w-full sm:w-[160px]\">\n <SelectValue\n placeholder={tc('assethandler.assets.list.filters.status.placeholder', 'Status')}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tc('assethandler.assets.list.filters.status.all', 'All Statuses')}\n </SelectItem>\n <SelectItem value=\"active\">\n {tc('assethandler.assets.list.filters.status.active', 'Active')}\n </SelectItem>\n <SelectItem value=\"inactive\">\n {tc('assethandler.assets.list.filters.status.inactive', 'Inactive')}\n </SelectItem>\n <SelectItem value=\"maintenance\">\n {tc('assethandler.assets.list.filters.status.maintenance', 'Maintenance')}\n </SelectItem>\n <SelectItem value=\"retired\">\n {tc('assethandler.assets.list.filters.status.retired', 'Retired')}\n </SelectItem>\n <SelectItem value=\"disposed\">\n {tc('assethandler.assets.list.filters.status.disposed', 'Disposed')}\n </SelectItem>\n </SelectContent>\n </Select>\n <div className=\"flex gap-1 rounded-md border p-0.5\">\n <Button\n variant={effectiveView === 'table' ? 'default' : 'ghost'}\n size=\"sm\"\n className=\"h-8 gap-1.5 px-2\"\n aria-pressed={effectiveView === 'table'}\n onClick={() => pickView('table')}\n >\n <TableIcon className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">Table</span>\n </Button>\n <Button\n variant={effectiveView === 'grid' ? 'default' : 'ghost'}\n size=\"sm\"\n className=\"h-8 gap-1.5 px-2\"\n aria-pressed={effectiveView === 'grid'}\n onClick={() => pickView('grid')}\n >\n <Grid3x3 className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">Grid</span>\n </Button>\n <Button\n variant={effectiveView === 'list' ? 'default' : 'ghost'}\n size=\"sm\"\n className=\"h-8 gap-1.5 px-2\"\n aria-pressed={effectiveView === 'list'}\n onClick={() => pickView('list')}\n >\n <List className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">List</span>\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n\n {!hydrated && assets.length === 0 ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div key={i} className=\"h-10 rounded-md bg-bg-sunken motion-safe:animate-vc-shimmer\" />\n ))}\n </div>\n ) : null}\n\n {effectiveView === 'table' && filteredAssets.length > 0 && (\n <Card>\n <CardContent className=\"p-0\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-bg-sunken/50 text-text-secondary\">\n {renderSortHeader(\n tc('assethandler.assets.list.table.assetTag', '{{asset}} Tag'),\n 'assetTag'\n )}\n {renderSortHeader(tc('assethandler.assets.list.table.name', 'Name'), 'name')}\n {renderSortHeader(\n tc('assethandler.assets.list.table.category', 'Category'),\n 'category'\n )}\n {renderSortHeader(\n tc('assethandler.assets.list.table.status', 'Status'),\n 'status'\n )}\n {renderSortHeader(\n tc('assethandler.assets.list.table.condition', 'Condition'),\n 'condition'\n )}\n <th className=\"p-3 text-left font-medium\">\n {tc('assethandler.assets.list.table.location', 'Location')}\n </th>\n {renderSortHeader(\n tc('assethandler.assets.list.table.assignedTo', 'Assigned To'),\n 'assignedTo'\n )}\n <th className=\"w-10 p-3\" />\n </tr>\n </thead>\n <tbody>\n {pager.pageItems.map((asset) => (\n <tr\n key={asset.id}\n className=\"cursor-pointer border-b hover:bg-bg-sunken/50\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <td className=\"p-3\">\n <span className=\"flex items-center gap-3\">\n <CategoryIconTile category={asset.category} />\n <span className=\"font-mono text-xs\">{asset.assetTag}</span>\n </span>\n </td>\n <td className=\"p-3\">\n <p className=\"font-medium text-text-primary\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">{asset.serialNumber}</p>\n </td>\n <td className=\"p-3\">{formatAssetCategory(asset.category, categoryLabels)}</td>\n <td className=\"p-3\">\n <StatusPill status={asset.status} />\n </td>\n <td className=\"p-3\">\n <span\n className={`inline-flex rounded-md px-2 py-0.5 text-xs font-medium capitalize ${conditionColors[asset.condition] || ''}`}\n >\n {asset.condition}\n </span>\n </td>\n <td className=\"max-w-[200px] truncate p-3 text-xs\">\n {asset.location || '—'}\n </td>\n <td className=\"p-3 text-xs\">{asset.assignedTo || '—'}</td>\n <td className=\"p-3\" onClick={(e) => e.stopPropagation()}>\n <RowActions\n onView={() => navigate(`/assets/${asset.id}`)}\n onCopy={() => copyTag(asset.assetTag)}\n />\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n\n {effectiveView === 'grid' && filteredAssets.length > 0 && (\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {pager.pageItems.map((asset) => (\n <Card\n key={asset.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"flex min-w-0 items-center gap-2.5\">\n <CategoryIconTile category={asset.category} />\n <span className=\"font-mono text-xs text-text-secondary\">{asset.assetTag}</span>\n </span>\n <StatusPill status={asset.status} />\n </div>\n <CardTitle className=\"mt-2 text-base\">{asset.name}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tc('assethandler.assets.list.grid.category', 'Category')}\n </span>\n <span>{formatAssetCategory(asset.category, categoryLabels)}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tc('assethandler.assets.list.grid.condition', 'Condition')}\n </span>\n <span\n className={`rounded-md px-2 py-0.5 text-xs font-medium capitalize ${conditionColors[asset.condition] || ''}`}\n >\n {asset.condition}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tc('assethandler.assets.list.grid.assignedTo', 'Assigned To')}\n </span>\n <span className=\"text-xs\">{asset.assignedTo || '—'}</span>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {effectiveView === 'list' && filteredAssets.length > 0 && (\n <div className=\"space-y-2\">\n {pager.pageItems.map((asset) => (\n <Card\n key={asset.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <CardContent className=\"px-4 py-3\">\n <div className=\"flex items-center gap-3\">\n <CategoryIconTile category={asset.category} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <p className=\"truncate text-sm font-medium\">{asset.name}</p>\n <StatusPill status={asset.status} />\n </div>\n <p className=\"truncate text-xs text-text-secondary\">\n {asset.assetTag}\n {asset.serialNumber ? <> · {asset.serialNumber}</> : null}\n {asset.location ? <> · {asset.location}</> : null}\n </p>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {filteredAssets.length > 0 && (\n <Pagination\n page={pager.page}\n pageCount={pager.pageCount}\n rangeStart={pager.rangeStart}\n rangeEnd={pager.rangeEnd}\n totalItems={pager.totalItems}\n canPrev={pager.canPrev}\n canNext={pager.canNext}\n onPrev={pager.prevPage}\n onNext={pager.nextPage}\n itemLabel=\"assets\"\n />\n )}\n\n {hydrated && filteredAssets.length === 0 && (\n <IllustratedEmptyState\n illustration={\n searchQuery || categoryFilter !== 'all' || statusFilter !== 'all'\n ? 'empty-search'\n : 'empty-data'\n }\n title={tc('assethandler.assets.list.empty.title', 'No {{assetsLower}} found')}\n description={tc(\n 'assethandler.assets.list.empty.description',\n 'Try adjusting your filters or add a new {{assetLower}} to get started.'\n )}\n action={\n <Button size=\"sm\" onClick={() => navigate('/assets/asset-create')}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {tc('assethandler.assets.list.actions.addAsset', 'Add {{asset}}')}\n </Button>\n }\n />\n )}\n </div>\n );\n}\n\nfunction RowActions({ onView, onCopy }: { onView: () => void; onCopy: () => void }) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" aria-label=\"Asset actions\">\n <MoreHorizontal className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={onView}>\n <Eye className=\"mr-2 h-4 w-4\" />\n View details\n </DropdownMenuItem>\n <DropdownMenuItem onClick={onCopy}>\n <Copy className=\"mr-2 h-4 w-4\" />\n Copy asset tag\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AssetsAssetListPage.js","names":[],"sources":["../../../src/assethandler/pages/AssetsAssetListPage.tsx"],"sourcesContent":["import { useAssetHandlerNavigate } from '../hooks/useAssetHandlerNavigate';\nimport {\n formatAssetCategory,\n useAssetCategoryPresentation,\n useHiddenCategoryIds,\n} from '../providers/AssetHandlerProvider';\nimport { useState, useMemo, useSyncExternalStore } from 'react';\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n Plus,\n Grid3x3,\n List,\n Table as TableIcon,\n ArrowUp,\n ArrowDown,\n ChevronsUpDown,\n MoreHorizontal,\n Copy,\n Eye,\n Monitor,\n Server,\n Wifi,\n Truck,\n Wrench,\n Code,\n Box,\n Boxes,\n CheckCircle2,\n Printer,\n} from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { notify } from '../utils/toast';\nimport { useCopy } from '../hooks/useCopy';\nimport { printAssetTag } from '../utils/printAssetTag';\nimport {\n Pagination,\n usePagination,\n ChartCard,\n StatTile,\n DonutChart,\n BarsChart,\n formatCompact,\n} from '../components';\n\n// Soft, semantic status pill — matches the mock's soft pills (green/amber/gray/red).\nconst STATUS_PILL: Record<string, string> = {\n active: 'bg-status-success-bg-subtle text-status-success-text',\n maintenance: 'bg-status-warning-bg-subtle text-status-warning-text',\n inactive: 'bg-bg-sunken text-text-secondary',\n retired: 'bg-bg-sunken text-text-secondary',\n disposed: 'bg-status-error-bg-subtle text-status-error-text',\n};\n\nconst conditionColors: Record<string, string> = {\n excellent: 'text-status-success-text bg-status-success-bg-subtle',\n good: 'text-status-info-text bg-status-info-bg-subtle',\n fair: 'text-status-warning-text bg-status-warning-bg-subtle',\n poor: 'text-status-warning-text bg-status-warning-bg-subtle',\n damaged: 'text-status-error-text bg-status-error-bg-subtle',\n};\n\n// Status distribution slice colours — semantic tokens (theme-aware CSS vars).\nconst STATUS_SLICE_COLOR: Record<string, string> = {\n active: 'var(--color-status-success-bg)',\n maintenance: 'var(--color-status-warning-bg)',\n inactive: 'var(--color-status-info-bg)',\n retired: 'var(--color-text-muted)',\n disposed: 'var(--color-status-error-bg)',\n};\n\nconst categoryIcons: Record<string, typeof Box> = {\n electronics: Monitor,\n it_hardware: Monitor,\n furniture: Box,\n vehicles: Truck,\n equipment: Wrench,\n software: Code,\n networking: Wifi,\n servers: Server,\n};\nconst categoryTints: Record<string, string> = {\n electronics: 'bg-status-info-bg-subtle text-status-info-text',\n it_hardware: 'bg-status-info-bg-subtle text-status-info-text',\n furniture: 'bg-status-warning-bg-subtle text-status-warning-text',\n vehicles: 'bg-status-success-bg-subtle text-status-success-text',\n equipment: 'bg-status-warning-bg-subtle text-status-warning-text',\n software: 'bg-action-primary-bg/10 text-action-primary-bg',\n networking: 'bg-status-info-bg-subtle text-status-info-text',\n servers: 'bg-status-error-bg-subtle text-status-error-text',\n};\nfunction CategoryIconTile({ category }: { category: string }) {\n const Icon = categoryIcons[category] ?? Box;\n const tint = categoryTints[category] ?? 'bg-bg-sunken text-text-secondary';\n return (\n <span className={`inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md ${tint}`}>\n <Icon className=\"h-4 w-4\" />\n </span>\n );\n}\n\nfunction StatusPill({ status }: { status: string }) {\n return (\n <span\n className={`inline-flex rounded-full px-2.5 py-0.5 text-xs font-medium capitalize ${\n STATUS_PILL[status] || 'bg-bg-sunken text-text-secondary'\n }`}\n >\n {status.replace(/_/g, ' ')}\n </span>\n );\n}\n\ntype SortKey = 'assetTag' | 'name' | 'category' | 'status' | 'condition' | 'assignedTo';\n\n// SSR-safe narrow-viewport hook (auto-fall-back the table to cards on phones).\nfunction useIsNarrow(): boolean {\n return useSyncExternalStore(\n (cb) => {\n if (typeof window === 'undefined' || !window.matchMedia) return () => {};\n const mq = window.matchMedia('(max-width: 767px)');\n mq.addEventListener('change', cb);\n return () => mq.removeEventListener('change', cb);\n },\n () =>\n typeof window !== 'undefined' && window.matchMedia\n ? window.matchMedia('(max-width: 767px)').matches\n : false,\n () => false\n );\n}\n\nexport function AssetsAssetListPage() {\n const tc = useCopy();\n const navigate = useAssetHandlerNavigate();\n const hiddenCategories = useHiddenCategoryIds();\n const { labels: categoryLabels, options: configuredCategoryOptions } =\n useAssetCategoryPresentation();\n const { assets, hydrated } = useAssetHandlerStore();\n const isNarrow = useIsNarrow();\n const [searchQuery, setSearchQuery] = useState('');\n const [categoryFilter, setCategoryFilter] = useState('all');\n const [statusFilter, setStatusFilter] = useState('all');\n const [viewMode, setViewMode] = useState<'table' | 'grid' | 'list'>('table');\n const [userPickedView, setUserPickedView] = useState(false);\n const [sortKey, setSortKey] = useState<SortKey>('name');\n const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc');\n\n // On phones, default to the card list (unless the user explicitly chose a view).\n const effectiveView = !userPickedView && isNarrow && viewMode === 'table' ? 'list' : viewMode;\n const pickView = (mode: 'table' | 'grid' | 'list') => {\n setUserPickedView(true);\n setViewMode(mode);\n };\n\n const categories = useMemo(\n () =>\n [\n ...new Set([\n ...(configuredCategoryOptions?.map((option) => option.id) ?? []),\n ...assets.map((a) => a.category).filter(Boolean),\n ]),\n ]\n .filter((c) => !hiddenCategories.has(c))\n .sort(),\n [assets, configuredCategoryOptions, hiddenCategories]\n );\n\n const filteredAssets = useMemo(() => {\n return assets.filter((a) => {\n if (hiddenCategories.has(a.category)) return false;\n const matchesSearch =\n searchQuery === '' ||\n a.name.toLowerCase().includes(searchQuery.toLowerCase()) ||\n a.assetTag.toLowerCase().includes(searchQuery.toLowerCase()) ||\n a.serialNumber.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesCategory = categoryFilter === 'all' || a.category === categoryFilter;\n const matchesStatus = statusFilter === 'all' || a.status === statusFilter;\n return matchesSearch && matchesCategory && matchesStatus;\n });\n }, [assets, searchQuery, categoryFilter, statusFilter, hiddenCategories]);\n\n const sortedAssets = useMemo(() => {\n const dir = sortDir === 'asc' ? 1 : -1;\n return [...filteredAssets].sort((a, b) => {\n const av = (a[sortKey] ?? '').toString().toLowerCase();\n const bv = (b[sortKey] ?? '').toString().toLowerCase();\n return av.localeCompare(bv) * dir;\n });\n }, [filteredAssets, sortKey, sortDir]);\n\n const activeCount = assets.filter((a) => a.status === 'active').length;\n\n const statusSlices = useMemo(() => {\n const counts: Record<string, number> = {};\n for (const a of assets) counts[a.status] = (counts[a.status] || 0) + 1;\n return Object.entries(counts).map(([status, value]) => ({\n name: status.charAt(0).toUpperCase() + status.slice(1),\n value,\n color: STATUS_SLICE_COLOR[status],\n }));\n }, [assets]);\n\n const categoryBars = useMemo(() => {\n const counts: Record<string, number> = {};\n for (const a of assets) counts[a.category] = (counts[a.category] || 0) + 1;\n return Object.entries(counts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 8)\n .map(([category, count]) => ({\n category: formatAssetCategory(category, categoryLabels),\n count,\n }));\n }, [assets, categoryLabels]);\n\n const pager = usePagination(sortedAssets, {\n pageSize: 12,\n resetKey: `${searchQuery}|${categoryFilter}|${statusFilter}|${sortKey}|${sortDir}`,\n });\n\n const toggleSort = (key: SortKey) => {\n if (sortKey === key) {\n setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'));\n } else {\n setSortKey(key);\n setSortDir('asc');\n }\n };\n\n const renderSortHeader = (label: string, col: SortKey) => (\n <th className=\"p-3 text-left font-medium\">\n <button\n type=\"button\"\n onClick={() => toggleSort(col)}\n className=\"inline-flex items-center gap-1 hover:text-text-primary\"\n >\n {label}\n {sortKey === col ? (\n sortDir === 'asc' ? (\n <ArrowUp className=\"h-3 w-3 text-action-primary-bg\" />\n ) : (\n <ArrowDown className=\"h-3 w-3 text-action-primary-bg\" />\n )\n ) : (\n <ChevronsUpDown className=\"h-3 w-3 text-text-muted\" />\n )}\n </button>\n </th>\n );\n\n const copyTag = (tag: string) => {\n void navigator.clipboard?.writeText(tag);\n notify.success('Asset tag copied', `${tag} copied to clipboard.`);\n };\n\n return (\n <div className=\"space-y-6 p-4 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>\n {tc('assethandler.assets.list.title', '{{asset}} Inventory')}\n </GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {assets.length}{' '}\n {tc('assethandler.assets.list.subtitle.totalAssets', 'total {{assetsLower}}')} ·{' '}\n {activeCount} {tc('assethandler.assets.list.subtitle.active', 'active')}\n </p>\n </div>\n <Button\n className=\"w-full sm:w-auto\"\n size=\"sm\"\n onClick={() => navigate('/assets/asset-create')}\n >\n <Plus className=\"mr-2 h-4 w-4\" />\n {tc('assethandler.assets.list.actions.addAsset', 'Add {{asset}}')}\n </Button>\n </div>\n\n <PagePurpose>\n {tc(\n 'assethandler.assets.list.purpose',\n 'The single source of truth for every {{assetLower}} you own or manage. Search, filter and group by category, status or condition to find any item fast, review its assignment, then drill in to update, check it in/out or schedule maintenance.'\n )}\n </PagePurpose>\n\n {/* Insight strip */}\n {assets.length > 0 ? (\n <>\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatTile\n label=\"Total assets\"\n value={assets.length}\n format={formatCompact}\n icon={Boxes}\n hero\n />\n <StatTile\n label=\"Active\"\n value={activeCount}\n format={formatCompact}\n icon={CheckCircle2}\n />\n <StatTile\n label=\"Categories\"\n value={categories.length}\n format={formatCompact}\n icon={Box}\n />\n <StatTile\n label=\"Showing\"\n value={filteredAssets.length}\n format={formatCompact}\n icon={Search}\n />\n </div>\n <div className=\"grid gap-4 lg:grid-cols-2\">\n <ChartCard title=\"Status mix\" subtitle=\"Assets by lifecycle status\">\n <DonutChart\n data={statusSlices}\n centerLabel=\"Total\"\n centerValue={assets.length}\n height={220}\n />\n </ChartCard>\n <ChartCard title=\"By category\" subtitle=\"Top categories by asset count\">\n <BarsChart\n data={categoryBars}\n xKey=\"category\"\n orientation=\"horizontal\"\n height={220}\n categoryWidth={110}\n valueFormat={formatCompact}\n series={[\n {\n key: 'count',\n label: tc('assethandler.assets.list.chart.series', '{{assets}}'),\n },\n ]}\n />\n </ChartCard>\n </div>\n </>\n ) : null}\n\n {/* Filters Bar */}\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex flex-col gap-3 md:flex-row md:flex-wrap\">\n <div className=\"relative min-w-0 flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder={tc(\n 'assethandler.assets.list.search.placeholder',\n 'Search by name, {{assetLower}} tag, serial number...'\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <Select value={categoryFilter} onValueChange={setCategoryFilter}>\n <SelectTrigger className=\"w-full sm:w-[180px]\">\n <SelectValue\n placeholder={tc(\n 'assethandler.assets.list.filters.category.placeholder',\n 'Category'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tc('assethandler.assets.list.filters.category.all', 'All Categories')}\n </SelectItem>\n {categories.map((category) => (\n <SelectItem key={category} value={category} className=\"capitalize\">\n {formatAssetCategory(category, categoryLabels)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger className=\"w-full sm:w-[160px]\">\n <SelectValue\n placeholder={tc('assethandler.assets.list.filters.status.placeholder', 'Status')}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tc('assethandler.assets.list.filters.status.all', 'All Statuses')}\n </SelectItem>\n <SelectItem value=\"active\">\n {tc('assethandler.assets.list.filters.status.active', 'Active')}\n </SelectItem>\n <SelectItem value=\"inactive\">\n {tc('assethandler.assets.list.filters.status.inactive', 'Inactive')}\n </SelectItem>\n <SelectItem value=\"maintenance\">\n {tc('assethandler.assets.list.filters.status.maintenance', 'Maintenance')}\n </SelectItem>\n <SelectItem value=\"retired\">\n {tc('assethandler.assets.list.filters.status.retired', 'Retired')}\n </SelectItem>\n <SelectItem value=\"disposed\">\n {tc('assethandler.assets.list.filters.status.disposed', 'Disposed')}\n </SelectItem>\n </SelectContent>\n </Select>\n <div className=\"flex gap-1 rounded-md border p-0.5\">\n <Button\n variant={effectiveView === 'table' ? 'default' : 'ghost'}\n size=\"sm\"\n className=\"h-8 gap-1.5 px-2\"\n aria-pressed={effectiveView === 'table'}\n onClick={() => pickView('table')}\n >\n <TableIcon className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">Table</span>\n </Button>\n <Button\n variant={effectiveView === 'grid' ? 'default' : 'ghost'}\n size=\"sm\"\n className=\"h-8 gap-1.5 px-2\"\n aria-pressed={effectiveView === 'grid'}\n onClick={() => pickView('grid')}\n >\n <Grid3x3 className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">Grid</span>\n </Button>\n <Button\n variant={effectiveView === 'list' ? 'default' : 'ghost'}\n size=\"sm\"\n className=\"h-8 gap-1.5 px-2\"\n aria-pressed={effectiveView === 'list'}\n onClick={() => pickView('list')}\n >\n <List className=\"h-4 w-4\" />\n <span className=\"hidden sm:inline\">List</span>\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n\n {!hydrated && assets.length === 0 ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div key={i} className=\"h-10 rounded-md bg-bg-sunken motion-safe:animate-vc-shimmer\" />\n ))}\n </div>\n ) : null}\n\n {effectiveView === 'table' && filteredAssets.length > 0 && (\n <Card>\n <CardContent className=\"p-0\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-bg-sunken/50 text-text-secondary\">\n {renderSortHeader(\n tc('assethandler.assets.list.table.assetTag', '{{asset}} Tag'),\n 'assetTag'\n )}\n {renderSortHeader(tc('assethandler.assets.list.table.name', 'Name'), 'name')}\n {renderSortHeader(\n tc('assethandler.assets.list.table.category', 'Category'),\n 'category'\n )}\n {renderSortHeader(\n tc('assethandler.assets.list.table.status', 'Status'),\n 'status'\n )}\n {renderSortHeader(\n tc('assethandler.assets.list.table.condition', 'Condition'),\n 'condition'\n )}\n <th className=\"p-3 text-left font-medium\">\n {tc('assethandler.assets.list.table.location', 'Location')}\n </th>\n {renderSortHeader(\n tc('assethandler.assets.list.table.assignedTo', 'Assigned To'),\n 'assignedTo'\n )}\n <th className=\"w-10 p-3\" />\n </tr>\n </thead>\n <tbody>\n {pager.pageItems.map((asset) => (\n <tr\n key={asset.id}\n className=\"cursor-pointer border-b hover:bg-bg-sunken/50\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <td className=\"p-3\">\n <span className=\"flex items-center gap-3\">\n <CategoryIconTile category={asset.category} />\n <span className=\"font-mono text-xs\">{asset.assetTag}</span>\n </span>\n </td>\n <td className=\"p-3\">\n <p className=\"font-medium text-text-primary\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">{asset.serialNumber}</p>\n </td>\n <td className=\"p-3\">{formatAssetCategory(asset.category, categoryLabels)}</td>\n <td className=\"p-3\">\n <StatusPill status={asset.status} />\n </td>\n <td className=\"p-3\">\n <span\n className={`inline-flex rounded-md px-2 py-0.5 text-xs font-medium capitalize ${conditionColors[asset.condition] || ''}`}\n >\n {asset.condition}\n </span>\n </td>\n <td className=\"max-w-[200px] truncate p-3 text-xs\">\n {asset.location || '—'}\n </td>\n <td className=\"p-3 text-xs\">{asset.assignedTo || '—'}</td>\n <td className=\"p-3\" onClick={(e) => e.stopPropagation()}>\n <RowActions\n onView={() => navigate(`/assets/${asset.id}`)}\n onCopy={() => copyTag(asset.assetTag)}\n onPrint={() =>\n void printAssetTag({\n name: asset.name,\n tagId: asset.tagId,\n assetTag: asset.assetTag,\n category: asset.category,\n })\n }\n />\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n\n {effectiveView === 'grid' && filteredAssets.length > 0 && (\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {pager.pageItems.map((asset) => (\n <Card\n key={asset.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"flex min-w-0 items-center gap-2.5\">\n <CategoryIconTile category={asset.category} />\n <span className=\"font-mono text-xs text-text-secondary\">{asset.assetTag}</span>\n </span>\n <StatusPill status={asset.status} />\n </div>\n <CardTitle className=\"mt-2 text-base\">{asset.name}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tc('assethandler.assets.list.grid.category', 'Category')}\n </span>\n <span>{formatAssetCategory(asset.category, categoryLabels)}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tc('assethandler.assets.list.grid.condition', 'Condition')}\n </span>\n <span\n className={`rounded-md px-2 py-0.5 text-xs font-medium capitalize ${conditionColors[asset.condition] || ''}`}\n >\n {asset.condition}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tc('assethandler.assets.list.grid.assignedTo', 'Assigned To')}\n </span>\n <span className=\"text-xs\">{asset.assignedTo || '—'}</span>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {effectiveView === 'list' && filteredAssets.length > 0 && (\n <div className=\"space-y-2\">\n {pager.pageItems.map((asset) => (\n <Card\n key={asset.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <CardContent className=\"px-4 py-3\">\n <div className=\"flex items-center gap-3\">\n <CategoryIconTile category={asset.category} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <p className=\"truncate text-sm font-medium\">{asset.name}</p>\n <StatusPill status={asset.status} />\n </div>\n <p className=\"truncate text-xs text-text-secondary\">\n {asset.assetTag}\n {asset.serialNumber ? <> · {asset.serialNumber}</> : null}\n {asset.location ? <> · {asset.location}</> : null}\n </p>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n\n {filteredAssets.length > 0 && (\n <Pagination\n page={pager.page}\n pageCount={pager.pageCount}\n rangeStart={pager.rangeStart}\n rangeEnd={pager.rangeEnd}\n totalItems={pager.totalItems}\n canPrev={pager.canPrev}\n canNext={pager.canNext}\n onPrev={pager.prevPage}\n onNext={pager.nextPage}\n itemLabel=\"assets\"\n />\n )}\n\n {hydrated && filteredAssets.length === 0 && (\n <IllustratedEmptyState\n illustration={\n searchQuery || categoryFilter !== 'all' || statusFilter !== 'all'\n ? 'empty-search'\n : 'empty-data'\n }\n title={tc('assethandler.assets.list.empty.title', 'No {{assetsLower}} found')}\n description={tc(\n 'assethandler.assets.list.empty.description',\n 'Try adjusting your filters or add a new {{assetLower}} to get started.'\n )}\n action={\n <Button size=\"sm\" onClick={() => navigate('/assets/asset-create')}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {tc('assethandler.assets.list.actions.addAsset', 'Add {{asset}}')}\n </Button>\n }\n />\n )}\n </div>\n );\n}\n\nfunction RowActions({\n onView,\n onCopy,\n onPrint,\n}: {\n onView: () => void;\n onCopy: () => void;\n onPrint: () => void;\n}) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" aria-label=\"Asset actions\">\n <MoreHorizontal className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={onView}>\n <Eye className=\"mr-2 h-4 w-4\" />\n View details\n </DropdownMenuItem>\n <DropdownMenuItem onClick={onCopy}>\n <Copy className=\"mr-2 h-4 w-4\" />\n Copy asset tag\n </DropdownMenuItem>\n <DropdownMenuItem onClick={onPrint}>\n <Printer className=\"mr-2 h-4 w-4\" />\n Print tag\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetHandlerProvider.d.ts","sourceRoot":"","sources":["../../../src/assethandler/providers/AssetHandlerProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAKnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAItD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"AssetHandlerProvider.d.ts","sourceRoot":"","sources":["../../../src/assethandler/providers/AssetHandlerProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAKnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAItD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AA8UpE,eAAO,MAAM,eAAe,6BAI3B,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;CAAgD,CAAC;AAEjF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QAAO;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAMrE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,QAAO;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,KAAK,MAAM,CAAC;IACrD,kEAAkE;IAClE,OAAO,EAAE,cAAc,CAAC;CAazB,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,oBAAoB,QAAO,GAAG,CAAC,MAAM,CAGjD,CAAC;AAEF,eAAO,MAAM,4BAA4B,QAAO;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,qBAAqB,CAAC,iBAAiB,CAAC,CAAC;CAIpD,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,iBAAiB,CAAC,qBAAqB,CAAC,CAwC7E,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetHandlerProvider.js","names":[],"sources":["../../../src/assethandler/providers/AssetHandlerProvider.tsx"],"sourcesContent":["import type { FC, PropsWithChildren } from 'react';\nimport { createContext, useContext, useMemo, useEffect } from 'react';\nimport { MemoryRouter } from 'react-router';\nimport { ApolloClient, HttpLink, InMemoryCache, gql } from '@apollo/client';\nimport { ApolloProvider, useApolloClient, useQuery } from '@apollo/client/react';\nimport type { AssetHandlerRootProps } from '../types';\nimport type { AssetHandlerBootstrapPayload } from '../store/assethandlerStore';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { DEFAULT_CURRENCY, currencySymbol, formatMoney } from '../utils/money';\nimport type { ValueFormatter } from '../components/charts/chartTheme';\nimport { formatCurrencyCompact } from '../components/charts/chartTheme';\nexport { formatAssetCategory } from '../utils/categoryPresentation';\n\ntype AssetHandlerContextValue = AssetHandlerRootProps;\n\nconst AssetHandlerContext = createContext<AssetHandlerContextValue | null>(null);\n\n/**\n * The module's data is fetched as several small queries rather than one query\n * with all thirteen root fields.\n *\n * BOFF-6381: `wspace-assethandler-svc` sets `enableRlsGucTagging: true`, so\n * be-sdk routes every Prisma call through `runOperationWithRlsGuc`, which wraps\n * it in its own interactive transaction and pins a pooled connection for the\n * duration. GraphQL resolves root fields in parallel, so the old single query\n * asked for thirteen simultaneously-pinned transactions from a service that\n * measured a hard ceiling of about three. It failed 100% of the time in\n * production — `data: null`, so `hydrateFromBootstrap` never ran and every\n * AssetHandler page rendered empty, including the machinery register.\n *\n * Measured against prod (success rate by concurrent operations):\n * 1 -> 100% 2 -> 100% 3 -> 100% 4 -> 90% 6 -> 57% 8 -> 45%\n * A sibling service without the extension was 100% at all of those, so the\n * ceiling is this service's, not the database's.\n *\n * The batches below are therefore sized to stay at or under that ceiling, and\n * the hydrator awaits them one at a time — issuing them in parallel would\n * recreate exactly the concurrency the split exists to avoid.\n * `dashboardOverview` is alone because it internally fans out to four parallel\n * counts in `AssetHandlerService.getDashboardOverview`.\n *\n * The first batch keeps the name `AssetHandlerBootstrap` so the ~36 existing\n * `refetchQueries: ['AssetHandlerBootstrap']` call sites keep working. When it\n * refetches, its new `data` identity re-runs the sequential loop, so those\n * sites still refresh the whole module, as before.\n */\n\nconst Q_ASSETS = gql`\n query AssetHandlerBootstrap {\n assets {\n id\n assetNumber\n name\n description\n category\n status\n condition\n serialNumber\n locationName\n assignedTo\n tags\n createdAt\n updatedAt\n purchaseValue\n purchaseDate\n usefulLifeMonths\n salvageValue\n depreciationMethod\n meterUnit\n department\n warrantyExpiry\n supplier\n disposalDate\n disposalMethod\n disposalNotes\n currentValue\n accumulatedDepreciation\n # totalCostOfOwnership is deliberately NOT selected here. Unlike\n # currentValue and accumulatedDepreciation, which are computed in-process\n # from fields already on the row, Asset.totalCostOfOwnership calls\n # AssetHandlerService.computeAssetTco, which issues TWO aggregate queries\n # per asset (maintenanceRecord + workOrder) under Promise.all. Selecting\n # it turns this one-root query into 1 + 2N database operations — 21 for\n # ten assets — against a service that caps out around three (BOFF-6395),\n # so it errored the batch and left the whole module empty again even\n # after the bootstrap was split. It scales with the number of assets, so\n # it can never be made to fit here.\n #\n # The only consumer that read it from the store is\n # PortfolioPortfolioOverviewPage, which now fetches it itself.\n }\n }\n`;\n\nconst Q_OVERVIEW = gql`\n query AssetHandlerBootstrapOverview {\n dashboardOverview {\n totalAssets\n openIncidents\n openWorkOrders\n totalTransactions\n }\n }\n`;\n\nconst Q_OPS = gql`\n query AssetHandlerBootstrapOps {\n incidents {\n id\n title\n description\n category\n priority\n status\n assignedTo\n reportedBy\n reportedAt\n resolvedAt\n resolution\n slaBreached\n }\n workOrders {\n id\n title\n description\n type\n status\n priority\n assetId\n assignedTo\n createdAt\n updatedAt\n completedAt\n }\n }\n`;\n\nconst Q_MAINTENANCE = gql`\n query AssetHandlerBootstrapMaintenance {\n maintenanceRecords {\n id\n assetId\n title\n description\n type\n status\n priority\n scheduledAt\n completedAt\n estimatedCost\n actualCost\n checklist\n createdAt\n updatedAt\n }\n transactions {\n id\n type\n status\n amount\n currency\n category\n description\n vendor\n department\n occurredAt\n }\n }\n`;\n\nconst Q_ITIL = gql`\n query AssetHandlerBootstrapItil {\n changeRequests {\n id\n title\n description\n type\n status\n risk\n requestedBy\n assignedTo\n affectedAssets\n scheduledStart\n scheduledEnd\n approvals\n createdAt\n updatedAt\n }\n problems {\n id\n title\n description\n status\n priority\n category\n assignedTo\n relatedIncidents\n rootCause\n workaround\n resolution\n createdAt\n updatedAt\n }\n }\n`;\n\nconst Q_FINANCE = gql`\n query AssetHandlerBootstrapFinance {\n budgets {\n id\n name\n category\n allocated\n spent\n remaining\n period\n department\n status\n }\n invoices {\n id\n number\n vendor\n amount\n currency\n issueDate\n dueDate\n status\n items\n relatedPO\n paidAt\n }\n }\n`;\n\nconst Q_SECURITY = gql`\n query AssetHandlerBootstrapSecurity {\n securityEvents: getVaultSecurityEvents {\n items {\n id\n eventType\n severity\n title: message\n description\n source: resourceType\n userId\n ipAddress\n occurredAt: timestamp\n resolved: reviewed\n }\n }\n complianceFrameworks: securityComplianceFrameworks(filter: { sourceProduct: \"assethandler\" }) {\n items {\n id\n name\n version\n status\n score\n totalControls\n passedControls\n failedControls\n lastAssessment\n nextAssessment\n lastAssessedAt\n }\n }\n securityPolicies: securityGovernancePolicies(filter: { sourceProduct: \"assethandler\" }) {\n items {\n id\n name\n description\n category\n status\n version\n effectiveDate\n reviewDate\n owner\n applicableTo\n }\n }\n }\n`;\n\nfunction AssetHandlerBootstrapHydrator() {\n const hydrateFromBootstrap = useAssetHandlerStore((s) => s.hydrateFromBootstrap);\n const setBootstrapRefetch = useAssetHandlerStore((s) => s.setBootstrapRefetch);\n\n const client = useApolloClient();\n\n // Batch 1 stays a `useQuery` named `AssetHandlerBootstrap` so Apollo keeps it\n // as an active, named, cached query — that is what makes the existing\n // `refetchQueries: ['AssetHandlerBootstrap']` call sites work.\n const assets = useQuery<AssetHandlerBootstrapPayload>(Q_ASSETS, {\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'all',\n });\n\n useEffect(() => {\n if (assets.data) hydrateFromBootstrap(assets.data);\n }, [assets.data, hydrateFromBootstrap]);\n\n // The remaining batches run strictly one after another, awaited in a loop\n // rather than as parallel hooks — running them concurrently would recreate\n // exactly the load the split exists to avoid. Hydration is additive, so a\n // batch that fails leaves its slice at the previous value instead of\n // blanking the whole module the way the single combined query did.\n useEffect(() => {\n if (!assets.data) return;\n let cancelled = false;\n void (async () => {\n for (const query of [Q_OVERVIEW, Q_OPS, Q_MAINTENANCE, Q_ITIL, Q_FINANCE, Q_SECURITY]) {\n if (cancelled) return;\n try {\n const result = await client.query<AssetHandlerBootstrapPayload>({\n query,\n fetchPolicy: 'network-only',\n errorPolicy: 'all',\n });\n if (!cancelled && result.data) hydrateFromBootstrap(result.data);\n } catch {\n // One failed section must not stop the others, and must not clear\n // what is already on screen.\n }\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [assets.data, client, hydrateFromBootstrap]);\n\n // Refetching batch 1 is enough to refresh the module: a new `assets.data`\n // identity re-runs the sequential loop above, so the existing\n // `refetchQueries: ['AssetHandlerBootstrap']` sites still refresh everything.\n const refetchAssets = assets.refetch;\n useEffect(() => {\n setBootstrapRefetch(() => {\n void refetchAssets();\n });\n return () => setBootstrapRefetch(null);\n }, [refetchAssets, setBootstrapRefetch]);\n\n return null;\n}\n\nexport const useAssetHandler = () => {\n const context = useContext(AssetHandlerContext);\n if (!context) throw new Error('useAssetHandler must be used within AssetHandlerProvider');\n return context;\n};\n\nexport const DEFAULT_TERMINOLOGY = { asset: 'Asset', assets: 'Assets' } as const;\n\n/**\n * Resolved singular/plural noun for the module, applying consumer overrides on\n * top of the module defaults (\"Asset\"/\"Assets\").\n */\nexport const useAssetTerminology = (): { asset: string; assets: string } => {\n const { terminology } = useAssetHandler();\n return {\n asset: terminology?.asset || DEFAULT_TERMINOLOGY.asset,\n assets: terminology?.assets || DEFAULT_TERMINOLOGY.assets,\n };\n};\n\n/**\n * Resolved money presentation for the module: the consumer's `currency` prop\n * with the module default (\"USD\") applied, plus the three formatters every\n * surface needs. Amounts are never converted — see {@link formatMoney}.\n */\nexport const useAssetMoney = (): {\n currency: string;\n symbol: string;\n /** Full amount; renders an em dash for null/undefined/non-finite. */\n format: (value: number | null | undefined) => string;\n /** Compact amount for axis ticks and dense KPIs, e.g. `₹8.5L`. */\n compact: ValueFormatter;\n} => {\n const { currency } = useAssetHandler();\n const resolved = currency || DEFAULT_CURRENCY;\n return useMemo(\n () => ({\n currency: resolved,\n symbol: currencySymbol(resolved),\n format: (value: number | null | undefined) => formatMoney(value, resolved),\n compact: formatCurrencyCompact(resolved),\n }),\n [resolved]\n );\n};\n\n/** Set of category ids the consumer asked to hide (empty by default). */\nexport const useHiddenCategoryIds = (): Set<string> => {\n const { hiddenCategoryIds } = useAssetHandler();\n return useMemo(() => new Set(hiddenCategoryIds ?? []), [hiddenCategoryIds]);\n};\n\nexport const useAssetCategoryPresentation = (): {\n labels?: Record<string, string>;\n options?: AssetHandlerRootProps['categoryOptions'];\n} => {\n const { categoryLabels, categoryOptions } = useAssetHandler();\n return { labels: categoryLabels, options: categoryOptions };\n};\n\nexport const AssetHandlerProvider: FC<PropsWithChildren<AssetHandlerRootProps>> = ({\n children,\n ...props\n}) => {\n const apolloClient = useMemo(\n () =>\n new ApolloClient({\n link: new HttpLink({\n uri: props.apiGatewayUrl\n ? `${props.apiGatewayUrl}/workspaces/graphql`\n : '/workspaces/graphql',\n headers: props.authToken\n ? {\n Authorization: `Bearer ${props.authToken}`,\n ...(props.workspaceToken\n ? { 'X-Workspace-Authorization': `Bearer ${props.workspaceToken}` }\n : {}),\n }\n : undefined,\n }),\n cache: new InMemoryCache(),\n }),\n [props.apiGatewayUrl, props.authToken, props.workspaceToken]\n );\n\n const isIntegrated = !!props.basePath;\n const content = (\n <AssetHandlerContext.Provider value={props}>\n <AssetHandlerBootstrapHydrator />\n {children}\n </AssetHandlerContext.Provider>\n );\n\n return isIntegrated ? (\n content\n ) : (\n <ApolloProvider client={apolloClient}>\n <MemoryRouter>{content}</MemoryRouter>\n </ApolloProvider>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AssetHandlerProvider.js","names":[],"sources":["../../../src/assethandler/providers/AssetHandlerProvider.tsx"],"sourcesContent":["import type { FC, PropsWithChildren } from 'react';\nimport { createContext, useContext, useMemo, useEffect } from 'react';\nimport { MemoryRouter } from 'react-router';\nimport { ApolloClient, HttpLink, InMemoryCache, gql } from '@apollo/client';\nimport { ApolloProvider, useApolloClient, useQuery } from '@apollo/client/react';\nimport type { AssetHandlerRootProps } from '../types';\nimport type { AssetHandlerBootstrapPayload } from '../store/assethandlerStore';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { DEFAULT_CURRENCY, currencySymbol, formatMoney } from '../utils/money';\nimport type { ValueFormatter } from '../components/charts/chartTheme';\nimport { formatCurrencyCompact } from '../components/charts/chartTheme';\nexport { formatAssetCategory } from '../utils/categoryPresentation';\n\ntype AssetHandlerContextValue = AssetHandlerRootProps;\n\nconst AssetHandlerContext = createContext<AssetHandlerContextValue | null>(null);\n\n/**\n * The module's data is fetched as several small queries rather than one query\n * with all thirteen root fields.\n *\n * BOFF-6381: `wspace-assethandler-svc` sets `enableRlsGucTagging: true`, so\n * be-sdk routes every Prisma call through `runOperationWithRlsGuc`, which wraps\n * it in its own interactive transaction and pins a pooled connection for the\n * duration. GraphQL resolves root fields in parallel, so the old single query\n * asked for thirteen simultaneously-pinned transactions from a service that\n * measured a hard ceiling of about three. It failed 100% of the time in\n * production — `data: null`, so `hydrateFromBootstrap` never ran and every\n * AssetHandler page rendered empty, including the machinery register.\n *\n * Measured against prod (success rate by concurrent operations):\n * 1 -> 100% 2 -> 100% 3 -> 100% 4 -> 90% 6 -> 57% 8 -> 45%\n * A sibling service without the extension was 100% at all of those, so the\n * ceiling is this service's, not the database's.\n *\n * The batches below are therefore sized to stay at or under that ceiling, and\n * the hydrator awaits them one at a time — issuing them in parallel would\n * recreate exactly the concurrency the split exists to avoid.\n * `dashboardOverview` is alone because it internally fans out to four parallel\n * counts in `AssetHandlerService.getDashboardOverview`.\n *\n * The first batch keeps the name `AssetHandlerBootstrap` so the ~36 existing\n * `refetchQueries: ['AssetHandlerBootstrap']` call sites keep working. When it\n * refetches, its new `data` identity re-runs the sequential loop, so those\n * sites still refresh the whole module, as before.\n */\n\nconst Q_ASSETS = gql`\n query AssetHandlerBootstrap {\n assets {\n id\n assetNumber\n tagId\n name\n description\n category\n status\n condition\n serialNumber\n locationName\n assignedTo\n tags\n createdAt\n updatedAt\n purchaseValue\n purchaseDate\n usefulLifeMonths\n salvageValue\n depreciationMethod\n meterUnit\n department\n warrantyExpiry\n supplier\n disposalDate\n disposalMethod\n disposalNotes\n currentValue\n accumulatedDepreciation\n # totalCostOfOwnership is deliberately NOT selected here. Unlike\n # currentValue and accumulatedDepreciation, which are computed in-process\n # from fields already on the row, Asset.totalCostOfOwnership calls\n # AssetHandlerService.computeAssetTco, which issues TWO aggregate queries\n # per asset (maintenanceRecord + workOrder) under Promise.all. Selecting\n # it turns this one-root query into 1 + 2N database operations — 21 for\n # ten assets — against a service that caps out around three (BOFF-6395),\n # so it errored the batch and left the whole module empty again even\n # after the bootstrap was split. It scales with the number of assets, so\n # it can never be made to fit here.\n #\n # The only consumer that read it from the store is\n # PortfolioPortfolioOverviewPage, which now fetches it itself.\n }\n }\n`;\n\nconst Q_OVERVIEW = gql`\n query AssetHandlerBootstrapOverview {\n dashboardOverview {\n totalAssets\n openIncidents\n openWorkOrders\n totalTransactions\n }\n }\n`;\n\nconst Q_OPS = gql`\n query AssetHandlerBootstrapOps {\n incidents {\n id\n title\n description\n category\n priority\n status\n assignedTo\n reportedBy\n reportedAt\n resolvedAt\n resolution\n slaBreached\n }\n workOrders {\n id\n title\n description\n type\n status\n priority\n assetId\n assignedTo\n createdAt\n updatedAt\n completedAt\n }\n }\n`;\n\nconst Q_MAINTENANCE = gql`\n query AssetHandlerBootstrapMaintenance {\n maintenanceRecords {\n id\n assetId\n title\n description\n type\n status\n priority\n scheduledAt\n completedAt\n estimatedCost\n actualCost\n checklist\n createdAt\n updatedAt\n }\n transactions {\n id\n type\n status\n amount\n currency\n category\n description\n vendor\n department\n occurredAt\n }\n }\n`;\n\nconst Q_ITIL = gql`\n query AssetHandlerBootstrapItil {\n changeRequests {\n id\n title\n description\n type\n status\n risk\n requestedBy\n assignedTo\n affectedAssets\n scheduledStart\n scheduledEnd\n approvals\n createdAt\n updatedAt\n }\n problems {\n id\n title\n description\n status\n priority\n category\n assignedTo\n relatedIncidents\n rootCause\n workaround\n resolution\n createdAt\n updatedAt\n }\n }\n`;\n\nconst Q_FINANCE = gql`\n query AssetHandlerBootstrapFinance {\n budgets {\n id\n name\n category\n allocated\n spent\n remaining\n period\n department\n status\n }\n invoices {\n id\n number\n vendor\n amount\n currency\n issueDate\n dueDate\n status\n items\n relatedPO\n paidAt\n }\n }\n`;\n\nconst Q_SECURITY = gql`\n query AssetHandlerBootstrapSecurity {\n securityEvents: getVaultSecurityEvents {\n items {\n id\n eventType\n severity\n title: message\n description\n source: resourceType\n userId\n ipAddress\n occurredAt: timestamp\n resolved: reviewed\n }\n }\n complianceFrameworks: securityComplianceFrameworks(filter: { sourceProduct: \"assethandler\" }) {\n items {\n id\n name\n version\n status\n score\n totalControls\n passedControls\n failedControls\n lastAssessment\n nextAssessment\n lastAssessedAt\n }\n }\n securityPolicies: securityGovernancePolicies(filter: { sourceProduct: \"assethandler\" }) {\n items {\n id\n name\n description\n category\n status\n version\n effectiveDate\n reviewDate\n owner\n applicableTo\n }\n }\n }\n`;\n\nfunction AssetHandlerBootstrapHydrator() {\n const hydrateFromBootstrap = useAssetHandlerStore((s) => s.hydrateFromBootstrap);\n const setBootstrapRefetch = useAssetHandlerStore((s) => s.setBootstrapRefetch);\n\n const client = useApolloClient();\n\n // Batch 1 stays a `useQuery` named `AssetHandlerBootstrap` so Apollo keeps it\n // as an active, named, cached query — that is what makes the existing\n // `refetchQueries: ['AssetHandlerBootstrap']` call sites work.\n const assets = useQuery<AssetHandlerBootstrapPayload>(Q_ASSETS, {\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'all',\n });\n\n useEffect(() => {\n if (assets.data) hydrateFromBootstrap(assets.data);\n }, [assets.data, hydrateFromBootstrap]);\n\n // The remaining batches run strictly one after another, awaited in a loop\n // rather than as parallel hooks — running them concurrently would recreate\n // exactly the load the split exists to avoid. Hydration is additive, so a\n // batch that fails leaves its slice at the previous value instead of\n // blanking the whole module the way the single combined query did.\n useEffect(() => {\n if (!assets.data) return;\n let cancelled = false;\n void (async () => {\n for (const query of [Q_OVERVIEW, Q_OPS, Q_MAINTENANCE, Q_ITIL, Q_FINANCE, Q_SECURITY]) {\n if (cancelled) return;\n try {\n const result = await client.query<AssetHandlerBootstrapPayload>({\n query,\n fetchPolicy: 'network-only',\n errorPolicy: 'all',\n });\n if (!cancelled && result.data) hydrateFromBootstrap(result.data);\n } catch {\n // One failed section must not stop the others, and must not clear\n // what is already on screen.\n }\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [assets.data, client, hydrateFromBootstrap]);\n\n // Refetching batch 1 is enough to refresh the module: a new `assets.data`\n // identity re-runs the sequential loop above, so the existing\n // `refetchQueries: ['AssetHandlerBootstrap']` sites still refresh everything.\n const refetchAssets = assets.refetch;\n useEffect(() => {\n setBootstrapRefetch(() => {\n void refetchAssets();\n });\n return () => setBootstrapRefetch(null);\n }, [refetchAssets, setBootstrapRefetch]);\n\n return null;\n}\n\nexport const useAssetHandler = () => {\n const context = useContext(AssetHandlerContext);\n if (!context) throw new Error('useAssetHandler must be used within AssetHandlerProvider');\n return context;\n};\n\nexport const DEFAULT_TERMINOLOGY = { asset: 'Asset', assets: 'Assets' } as const;\n\n/**\n * Resolved singular/plural noun for the module, applying consumer overrides on\n * top of the module defaults (\"Asset\"/\"Assets\").\n */\nexport const useAssetTerminology = (): { asset: string; assets: string } => {\n const { terminology } = useAssetHandler();\n return {\n asset: terminology?.asset || DEFAULT_TERMINOLOGY.asset,\n assets: terminology?.assets || DEFAULT_TERMINOLOGY.assets,\n };\n};\n\n/**\n * Resolved money presentation for the module: the consumer's `currency` prop\n * with the module default (\"USD\") applied, plus the three formatters every\n * surface needs. Amounts are never converted — see {@link formatMoney}.\n */\nexport const useAssetMoney = (): {\n currency: string;\n symbol: string;\n /** Full amount; renders an em dash for null/undefined/non-finite. */\n format: (value: number | null | undefined) => string;\n /** Compact amount for axis ticks and dense KPIs, e.g. `₹8.5L`. */\n compact: ValueFormatter;\n} => {\n const { currency } = useAssetHandler();\n const resolved = currency || DEFAULT_CURRENCY;\n return useMemo(\n () => ({\n currency: resolved,\n symbol: currencySymbol(resolved),\n format: (value: number | null | undefined) => formatMoney(value, resolved),\n compact: formatCurrencyCompact(resolved),\n }),\n [resolved]\n );\n};\n\n/** Set of category ids the consumer asked to hide (empty by default). */\nexport const useHiddenCategoryIds = (): Set<string> => {\n const { hiddenCategoryIds } = useAssetHandler();\n return useMemo(() => new Set(hiddenCategoryIds ?? []), [hiddenCategoryIds]);\n};\n\nexport const useAssetCategoryPresentation = (): {\n labels?: Record<string, string>;\n options?: AssetHandlerRootProps['categoryOptions'];\n} => {\n const { categoryLabels, categoryOptions } = useAssetHandler();\n return { labels: categoryLabels, options: categoryOptions };\n};\n\nexport const AssetHandlerProvider: FC<PropsWithChildren<AssetHandlerRootProps>> = ({\n children,\n ...props\n}) => {\n const apolloClient = useMemo(\n () =>\n new ApolloClient({\n link: new HttpLink({\n uri: props.apiGatewayUrl\n ? `${props.apiGatewayUrl}/workspaces/graphql`\n : '/workspaces/graphql',\n headers: props.authToken\n ? {\n Authorization: `Bearer ${props.authToken}`,\n ...(props.workspaceToken\n ? { 'X-Workspace-Authorization': `Bearer ${props.workspaceToken}` }\n : {}),\n }\n : undefined,\n }),\n cache: new InMemoryCache(),\n }),\n [props.apiGatewayUrl, props.authToken, props.workspaceToken]\n );\n\n const isIntegrated = !!props.basePath;\n const content = (\n <AssetHandlerContext.Provider value={props}>\n <AssetHandlerBootstrapHydrator />\n {children}\n </AssetHandlerContext.Provider>\n );\n\n return isIntegrated ? (\n content\n ) : (\n <ApolloProvider client={apolloClient}>\n <MemoryRouter>{content}</MemoryRouter>\n </ApolloProvider>\n );\n};\n"],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ export interface Asset {
|
|
|
10
10
|
condition: AssetCondition;
|
|
11
11
|
serialNumber: string;
|
|
12
12
|
assetTag: string;
|
|
13
|
+
tagId: string;
|
|
13
14
|
location: string;
|
|
14
15
|
assignedTo: string;
|
|
15
16
|
tags: string[];
|
|
@@ -214,6 +215,7 @@ export interface AssetHandlerBootstrapPayload {
|
|
|
214
215
|
assets?: Array<{
|
|
215
216
|
id: string;
|
|
216
217
|
assetNumber: string;
|
|
218
|
+
tagId?: string | null;
|
|
217
219
|
name: string;
|
|
218
220
|
description?: string | null;
|
|
219
221
|
category: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assethandlerStore.d.ts","sourceRoot":"","sources":["../../../src/assethandler/store/assethandlerStore.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"assethandlerStore.d.ts","sourceRoot":"","sources":["../../../src/assethandler/store/assethandlerStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assethandlerStore.js","names":[],"sources":["../../../src/assethandler/store/assethandlerStore.ts"],"sourcesContent":["import { create } from 'zustand';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// View-model types — aligned 1:1 with wspace-assethandler-svc GraphQL schema.\n// Backend enum values (UPPER_CASE) are lowercased once during hydration so the\n// UI can render them directly. No field in this store is invented client-side;\n// everything is hydrated from the bootstrap query in AssetHandlerProvider.\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ─── Asset Types ──────────────────────────────────────────────────\nexport type AssetStatus = 'active' | 'inactive' | 'maintenance' | 'retired' | 'disposed';\nexport type AssetCondition = 'excellent' | 'good' | 'fair' | 'poor' | 'damaged';\nexport type DepreciationMethod = 'straight_line' | 'reducing_balance' | 'none';\n\nexport interface Asset {\n id: string;\n name: string;\n description: string;\n category: string;\n status: AssetStatus;\n condition: AssetCondition;\n serialNumber: string;\n assetTag: string;\n location: string;\n assignedTo: string;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n // ─── Financial / depreciation (backend-computed where noted) ───\n purchaseValue?: number;\n purchaseDate?: string;\n usefulLifeMonths?: number;\n salvageValue?: number;\n depreciationMethod?: DepreciationMethod;\n /** What this asset's usage meter counts — HOURS | KM | MILES | CYCLES | UNITS. */\n meterUnit?: string | null;\n department?: string;\n warrantyExpiry?: string;\n supplier?: string;\n disposalDate?: string;\n disposalMethod?: string;\n disposalNotes?: string;\n /** Computed book value (floored at salvage); undefined if no purchaseValue. */\n currentValue?: number;\n /** Computed accumulated depreciation. */\n accumulatedDepreciation?: number;\n /** Computed = purchaseValue + maintenance actualCost + work-order cost. */\n totalCostOfOwnership?: number;\n}\n\n// ─── ITIL Types ───────────────────────────────────────────────────\nexport type IncidentPriority = 'critical' | 'high' | 'medium' | 'low';\nexport type IncidentStatus = 'open' | 'in_progress' | 'resolved' | 'closed';\nexport type ChangeStatus =\n | 'draft'\n | 'submitted'\n | 'approved'\n | 'in_progress'\n | 'completed'\n | 'rejected';\nexport type ChangeRisk = 'low' | 'medium' | 'high' | 'critical';\nexport type ProblemStatus = 'open' | 'investigating' | 'known_error' | 'resolved' | 'closed';\n\nexport interface Incident {\n id: string;\n title: string;\n description: string;\n category: string;\n priority: IncidentPriority;\n status: IncidentStatus;\n assignedTo: string;\n reportedBy: string;\n createdAt: string;\n resolvedAt?: string;\n resolution?: string;\n slaBreached: boolean;\n}\n\nexport interface ChangeRequest {\n id: string;\n title: string;\n description: string;\n type: string;\n status: ChangeStatus;\n risk: ChangeRisk;\n requestedBy: string;\n assignedTo: string;\n affectedAssets: string[];\n scheduledStart: string;\n scheduledEnd: string;\n createdAt: string;\n approvals: { name: string; status: string; date: string }[];\n}\n\nexport interface Problem {\n id: string;\n title: string;\n description: string;\n status: ProblemStatus;\n priority: IncidentPriority;\n category: string;\n assignedTo: string;\n relatedIncidents: string[];\n rootCause?: string;\n workaround?: string;\n resolution?: string;\n createdAt: string;\n updatedAt: string;\n}\n\n// ─── Finance Types ────────────────────────────────────────────────\nexport type TransactionType = 'purchase' | 'lease' | 'disposal' | 'transfer' | 'maintenance';\nexport type TransactionStatus = 'pending' | 'approved' | 'completed' | 'rejected';\n\nexport interface FinanceTransaction {\n id: string;\n type: TransactionType;\n amount: number;\n currency: string;\n description: string;\n category: string;\n date: string;\n status: TransactionStatus;\n vendor?: string;\n department: string;\n}\n\nexport interface Budget {\n id: string;\n name: string;\n category: string;\n allocated: number;\n spent: number;\n remaining: number;\n period: string;\n department: string;\n status: 'on_track' | 'over_budget' | 'under_budget';\n}\n\nexport interface Invoice {\n id: string;\n number: string;\n vendor: string;\n amount: number;\n currency: string;\n issueDate: string;\n dueDate: string;\n status: 'draft' | 'sent' | 'paid' | 'overdue' | 'cancelled';\n items: { description: string; qty: number; unitPrice: number; total: number }[];\n relatedPO?: string;\n paidAt?: string;\n}\n\n// ─── Maintenance Types ────────────────────────────────────────────\nexport type MaintenancePriority = 'critical' | 'high' | 'medium' | 'low';\n\nexport interface MaintenanceRecord {\n id: string;\n assetId: string;\n type: string;\n priority: MaintenancePriority;\n status: string;\n title: string;\n description: string;\n scheduledDate?: string;\n completedDate?: string;\n estimatedCost?: number;\n actualCost?: number;\n checklist: { task: string; completed: boolean }[];\n}\n\n// ─── Security Types ───────────────────────────────────────────────\nexport interface SecurityEvent {\n id: string;\n type: string;\n severity: 'critical' | 'high' | 'medium' | 'low' | 'info';\n title: string;\n description: string;\n source: string;\n userId?: string;\n ipAddress?: string;\n timestamp: string;\n resolved: boolean;\n}\n\nexport interface ComplianceFramework {\n id: string;\n name: string;\n version: string;\n status: 'compliant' | 'non_compliant' | 'partial' | 'under_review';\n score: number;\n totalControls: number;\n passedControls: number;\n failedControls: number;\n lastAssessment: string;\n nextAssessment: string;\n lastAssessedAt?: string;\n}\n\nexport interface SecurityPolicy {\n id: string;\n name: string;\n description: string;\n category: string;\n status: 'active' | 'draft' | 'deprecated' | 'under_review';\n version: string;\n effectiveDate: string;\n reviewDate: string;\n owner: string;\n applicableTo: string[];\n}\n\n// ─── Operations Types ─────────────────────────────────────────────\nexport interface WorkOrder {\n id: string;\n title: string;\n description: string;\n priority: 'critical' | 'high' | 'medium' | 'low';\n status: 'draft' | 'scheduled' | 'approved' | 'in_progress' | 'completed' | 'cancelled';\n assignedTo: string;\n assetId: string;\n type: string;\n createdAt: string;\n completedAt?: string;\n}\n\n// ─── Dashboard Types ──────────────────────────────────────────────\nexport interface DashboardOverview {\n totalAssets: number;\n openIncidents: number;\n openWorkOrders: number;\n totalTransactions: number;\n}\n\n// ─── Bootstrap payload (raw backend shapes) ───────────────────────\nexport interface AssetHandlerBootstrapPayload {\n dashboardOverview?: {\n totalAssets?: number;\n openIncidents?: number;\n openWorkOrders?: number;\n totalTransactions?: number;\n } | null;\n assets?: Array<{\n id: string;\n assetNumber: string;\n name: string;\n description?: string | null;\n category: string;\n status: string;\n condition: string;\n serialNumber?: string | null;\n locationName?: string | null;\n assignedTo?: string | null;\n tags?: string[];\n createdAt?: string;\n updatedAt?: string;\n purchaseValue?: number | null;\n purchaseDate?: string | null;\n usefulLifeMonths?: number | null;\n salvageValue?: number | null;\n depreciationMethod?: string | null;\n meterUnit?: string | null;\n department?: string | null;\n warrantyExpiry?: string | null;\n supplier?: string | null;\n disposalDate?: string | null;\n disposalMethod?: string | null;\n disposalNotes?: string | null;\n currentValue?: number | null;\n accumulatedDepreciation?: number | null;\n totalCostOfOwnership?: number | null;\n }> | null;\n incidents?: Array<{\n id: string;\n title: string;\n description: string;\n category: string;\n priority: string;\n status: string;\n assignedTo?: string | null;\n reportedBy: string;\n reportedAt: string;\n resolvedAt?: string | null;\n resolution?: string | null;\n slaBreached: boolean;\n }> | null;\n workOrders?: Array<{\n id: string;\n title: string;\n description?: string | null;\n type: string;\n status: string;\n priority: string;\n assetId?: string | null;\n assignedTo?: string | null;\n createdAt: string;\n completedAt?: string | null;\n }> | null;\n maintenanceRecords?: Array<{\n id: string;\n assetId: string;\n title: string;\n description?: string | null;\n type: string;\n status: string;\n priority: string;\n scheduledAt?: string | null;\n completedAt?: string | null;\n estimatedCost?: number | null;\n actualCost?: number | null;\n checklist?: Array<Record<string, unknown>>;\n }> | null;\n transactions?: Array<{\n id: string;\n type: string;\n status: string;\n amount: number;\n currency: string;\n category: string;\n description: string;\n vendor?: string | null;\n department?: string | null;\n occurredAt: string;\n }> | null;\n changeRequests?: Array<{\n id: string;\n title: string;\n description: string;\n type: string;\n status: string;\n risk: string;\n requestedBy: string;\n assignedTo?: string | null;\n affectedAssets: string[];\n scheduledStart?: string | null;\n scheduledEnd?: string | null;\n approvals?: Array<{ name?: string; status?: string; date?: string }>;\n createdAt: string;\n }> | null;\n problems?: Array<{\n id: string;\n title: string;\n description: string;\n status: string;\n priority: string;\n category: string;\n assignedTo?: string | null;\n relatedIncidents: string[];\n rootCause?: string | null;\n workaround?: string | null;\n resolution?: string | null;\n createdAt: string;\n updatedAt: string;\n }> | null;\n budgets?: Array<{\n id: string;\n name: string;\n category: string;\n allocated: number;\n spent: number;\n remaining: number;\n period: string;\n department: string;\n status: string;\n }> | null;\n invoices?: Array<{\n id: string;\n number: string;\n vendor: string;\n amount: number;\n currency: string;\n issueDate: string;\n dueDate: string;\n status: string;\n items?: Array<{ description?: string; qty?: number; unitPrice?: number; total?: number }>;\n relatedPO?: string | null;\n paidAt?: string | null;\n }> | null;\n securityEvents?: {\n items: Array<{\n id: string;\n eventType: string;\n severity: string;\n title: string;\n description?: string | null;\n source?: string | null;\n userId?: string | null;\n ipAddress?: string | null;\n occurredAt: string;\n resolved: boolean;\n }>;\n } | null;\n complianceFrameworks?: {\n items: Array<{\n id: string;\n name: string;\n version: string;\n status: string;\n score: number;\n totalControls: number;\n passedControls: number;\n failedControls: number;\n lastAssessment: string;\n nextAssessment: string;\n lastAssessedAt?: string | null;\n }>;\n } | null;\n securityPolicies?: {\n items: Array<{\n id: string;\n name: string;\n description?: string | null;\n category: string;\n status: string;\n version: string;\n effectiveDate: string;\n reviewDate: string;\n owner: string;\n applicableTo: string[];\n }>;\n } | null;\n}\n\ninterface AssetHandlerState {\n /** True once the bootstrap query has hydrated the store at least once. */\n hydrated: boolean;\n\n // Domain data — always sourced from the backend, never seeded locally.\n overview: DashboardOverview | null;\n assets: Asset[];\n incidents: Incident[];\n changeRequests: ChangeRequest[];\n problems: Problem[];\n transactions: FinanceTransaction[];\n budgets: Budget[];\n invoices: Invoice[];\n maintenanceRecords: MaintenanceRecord[];\n securityEvents: SecurityEvent[];\n complianceFrameworks: ComplianceFramework[];\n securityPolicies: SecurityPolicy[];\n workOrders: WorkOrder[];\n\n hydrateFromBootstrap: (payload: AssetHandlerBootstrapPayload) => void;\n\n /**\n * Imperative refetch of the bootstrap query, registered by the provider's\n * hydrator. Pages that mutate domain data can call `refetchBootstrap()` to\n * pull fresh store data. Prefer Apollo `refetchQueries: ['AssetHandlerBootstrap']`\n * on the mutation itself; use this for cross-component imperative refresh.\n */\n bootstrapRefetch: (() => void) | null;\n setBootstrapRefetch: (refetch: (() => void) | null) => void;\n refetchBootstrap: () => void;\n}\n\nexport const useAssetHandlerStore = create<AssetHandlerState>((set, get) => ({\n hydrated: false,\n\n bootstrapRefetch: null,\n setBootstrapRefetch: (refetch) => set({ bootstrapRefetch: refetch }),\n refetchBootstrap: () => {\n get().bootstrapRefetch?.();\n },\n\n overview: null,\n assets: [],\n incidents: [],\n changeRequests: [],\n problems: [],\n transactions: [],\n budgets: [],\n invoices: [],\n maintenanceRecords: [],\n securityEvents: [],\n complianceFrameworks: [],\n securityPolicies: [],\n workOrders: [],\n\n hydrateFromBootstrap: (payload) =>\n set(() => {\n const assets: Asset[] = (payload.assets ?? []).map((asset) => ({\n id: asset.id,\n name: asset.name,\n description: asset.description ?? '',\n category: asset.category.toLowerCase(),\n status: asset.status.toLowerCase() as AssetStatus,\n condition: asset.condition.toLowerCase() as AssetCondition,\n serialNumber: asset.serialNumber ?? '',\n assetTag: asset.assetNumber,\n location: asset.locationName ?? '',\n assignedTo: asset.assignedTo ?? '',\n tags: asset.tags ?? [],\n createdAt: asset.createdAt ?? '',\n updatedAt: asset.updatedAt ?? '',\n purchaseValue: asset.purchaseValue ?? undefined,\n purchaseDate: asset.purchaseDate ?? undefined,\n usefulLifeMonths: asset.usefulLifeMonths ?? undefined,\n salvageValue: asset.salvageValue ?? undefined,\n depreciationMethod: asset.depreciationMethod\n ? (asset.depreciationMethod.toLowerCase() as DepreciationMethod)\n : undefined,\n // Kept UPPER-CASE, unlike depreciationMethod above: it is compared against the\n // GraphQL enum values, not against a lower-cased UI string.\n meterUnit: asset.meterUnit ?? null,\n department: asset.department ?? undefined,\n warrantyExpiry: asset.warrantyExpiry ?? undefined,\n supplier: asset.supplier ?? undefined,\n disposalDate: asset.disposalDate ?? undefined,\n disposalMethod: asset.disposalMethod ?? undefined,\n disposalNotes: asset.disposalNotes ?? undefined,\n currentValue: asset.currentValue ?? undefined,\n accumulatedDepreciation: asset.accumulatedDepreciation ?? undefined,\n totalCostOfOwnership: asset.totalCostOfOwnership ?? undefined,\n }));\n\n const incidents: Incident[] = (payload.incidents ?? []).map((incident) => ({\n id: incident.id,\n title: incident.title,\n description: incident.description,\n category: incident.category,\n priority: incident.priority.toLowerCase() as IncidentPriority,\n status: incident.status.toLowerCase() as IncidentStatus,\n assignedTo: incident.assignedTo ?? '',\n reportedBy: incident.reportedBy,\n createdAt: incident.reportedAt,\n resolvedAt: incident.resolvedAt ?? undefined,\n resolution: incident.resolution ?? undefined,\n slaBreached: incident.slaBreached,\n }));\n\n const workOrders: WorkOrder[] = (payload.workOrders ?? []).map((workOrder) => ({\n id: workOrder.id,\n title: workOrder.title,\n description: workOrder.description ?? '',\n assetId: workOrder.assetId ?? '',\n priority: workOrder.priority.toLowerCase() as WorkOrder['priority'],\n status: workOrder.status.toLowerCase() as WorkOrder['status'],\n assignedTo: workOrder.assignedTo ?? '',\n createdAt: workOrder.createdAt,\n completedAt: workOrder.completedAt ?? undefined,\n type: workOrder.type.toLowerCase(),\n }));\n\n const maintenanceRecords: MaintenanceRecord[] = (payload.maintenanceRecords ?? []).map(\n (record) => ({\n id: record.id,\n assetId: record.assetId,\n type: record.type.toLowerCase(),\n priority: record.priority.toLowerCase() as MaintenancePriority,\n status: record.status.toLowerCase(),\n title: record.title,\n description: record.description ?? '',\n scheduledDate: record.scheduledAt ?? undefined,\n completedDate: record.completedAt ?? undefined,\n estimatedCost: record.estimatedCost ?? undefined,\n actualCost: record.actualCost ?? undefined,\n checklist: (record.checklist ?? []).map((item) => ({\n task: String(item.task ?? 'Task'),\n completed: Boolean(item.completed ?? false),\n })),\n })\n );\n\n const transactions: FinanceTransaction[] = (payload.transactions ?? []).map((tx) => ({\n id: tx.id,\n type: tx.type.toLowerCase() as TransactionType,\n amount: tx.amount,\n currency: tx.currency,\n description: tx.description,\n category: tx.category,\n date: tx.occurredAt,\n status: tx.status.toLowerCase() as TransactionStatus,\n vendor: tx.vendor ?? undefined,\n department: tx.department ?? '',\n }));\n\n const changeRequests: ChangeRequest[] = (payload.changeRequests ?? []).map((change) => ({\n id: change.id,\n title: change.title,\n description: change.description,\n type: change.type.toLowerCase(),\n status: change.status.toLowerCase() as ChangeStatus,\n risk: change.risk.toLowerCase() as ChangeRisk,\n requestedBy: change.requestedBy,\n assignedTo: change.assignedTo ?? '',\n affectedAssets: change.affectedAssets,\n scheduledStart: change.scheduledStart ?? '',\n scheduledEnd: change.scheduledEnd ?? '',\n createdAt: change.createdAt,\n approvals: (change.approvals ?? []).map((approval) => ({\n name: approval.name ?? 'Approver',\n status: approval.status ?? 'pending',\n date: approval.date ?? change.createdAt,\n })),\n }));\n\n const problems: Problem[] = (payload.problems ?? []).map((problem) => ({\n id: problem.id,\n title: problem.title,\n description: problem.description,\n status: problem.status.toLowerCase() as ProblemStatus,\n priority: problem.priority.toLowerCase() as IncidentPriority,\n category: problem.category,\n assignedTo: problem.assignedTo ?? '',\n relatedIncidents: problem.relatedIncidents,\n rootCause: problem.rootCause ?? undefined,\n workaround: problem.workaround ?? undefined,\n resolution: problem.resolution ?? undefined,\n createdAt: problem.createdAt,\n updatedAt: problem.updatedAt,\n }));\n\n const budgets: Budget[] = (payload.budgets ?? []).map((budget) => ({\n id: budget.id,\n name: budget.name,\n category: budget.category,\n allocated: budget.allocated,\n spent: budget.spent,\n remaining: budget.remaining,\n period: budget.period,\n department: budget.department,\n status: budget.status.toLowerCase() as Budget['status'],\n }));\n\n const invoices: Invoice[] = (payload.invoices ?? []).map((invoice) => ({\n id: invoice.id,\n number: invoice.number,\n vendor: invoice.vendor,\n amount: invoice.amount,\n currency: invoice.currency,\n issueDate: invoice.issueDate,\n dueDate: invoice.dueDate,\n status: invoice.status.toLowerCase() as Invoice['status'],\n items: (invoice.items ?? []).map((item) => ({\n description: item.description ?? 'Line item',\n qty: item.qty ?? 1,\n unitPrice: item.unitPrice ?? item.total ?? 0,\n total: item.total ?? item.unitPrice ?? 0,\n })),\n relatedPO: invoice.relatedPO ?? undefined,\n paidAt: invoice.paidAt ?? undefined,\n }));\n\n const securityEvents: SecurityEvent[] = (payload.securityEvents?.items ?? []).map(\n (event) => ({\n id: event.id,\n type: event.eventType,\n severity: event.severity.toLowerCase() as SecurityEvent['severity'],\n title: event.title,\n description: event.description ?? '',\n source: event.source ?? 'security',\n userId: event.userId ?? undefined,\n ipAddress: event.ipAddress ?? undefined,\n timestamp: event.occurredAt,\n resolved: event.resolved,\n })\n );\n\n const complianceFrameworks: ComplianceFramework[] = (\n payload.complianceFrameworks?.items ?? []\n ).map((framework) => ({\n id: framework.id,\n name: framework.name,\n version: framework.version,\n status: framework.status.toLowerCase() as ComplianceFramework['status'],\n score: framework.score,\n totalControls: framework.totalControls,\n passedControls: framework.passedControls,\n failedControls: framework.failedControls,\n lastAssessment: framework.lastAssessment,\n nextAssessment: framework.nextAssessment,\n lastAssessedAt: framework.lastAssessedAt ?? undefined,\n }));\n\n const securityPolicies: SecurityPolicy[] = (payload.securityPolicies?.items ?? []).map(\n (policy) => ({\n id: policy.id,\n name: policy.name,\n description: policy.description ?? '',\n category: policy.category,\n status: policy.status.toLowerCase() as SecurityPolicy['status'],\n version: policy.version,\n effectiveDate: policy.effectiveDate,\n reviewDate: policy.reviewDate,\n owner: policy.owner,\n applicableTo: policy.applicableTo,\n })\n );\n\n const overview: DashboardOverview | null = payload.dashboardOverview\n ? {\n totalAssets: payload.dashboardOverview.totalAssets ?? assets.length,\n openIncidents: payload.dashboardOverview.openIncidents ?? 0,\n openWorkOrders: payload.dashboardOverview.openWorkOrders ?? 0,\n totalTransactions: payload.dashboardOverview.totalTransactions ?? 0,\n }\n : null;\n\n // Only overwrite the slices this payload actually carries. The provider\n // fetches the module's data as several smaller queries rather than one\n // 13-root query (BOFF-6381 — wspace-assethandler-svc rejects more than\n // ~3 concurrent operations, so the single combined query failed 100% of\n // the time in production and left every page empty). Each batch hydrates\n // independently, so a rebuild of all thirteen slices here would let a\n // later batch wipe an earlier one back to `[]`. zustand's `set` merges\n // shallowly, so an omitted key keeps its previous value.\n return {\n hydrated: true,\n ...(payload.dashboardOverview !== undefined ? { overview } : {}),\n ...(payload.assets !== undefined ? { assets } : {}),\n ...(payload.incidents !== undefined ? { incidents } : {}),\n ...(payload.changeRequests !== undefined ? { changeRequests } : {}),\n ...(payload.problems !== undefined ? { problems } : {}),\n ...(payload.workOrders !== undefined ? { workOrders } : {}),\n ...(payload.maintenanceRecords !== undefined ? { maintenanceRecords } : {}),\n ...(payload.transactions !== undefined ? { transactions } : {}),\n ...(payload.budgets !== undefined ? { budgets } : {}),\n ...(payload.invoices !== undefined ? { invoices } : {}),\n ...(payload.securityEvents !== undefined ? { securityEvents } : {}),\n ...(payload.complianceFrameworks !== undefined ? { complianceFrameworks } : {}),\n ...(payload.securityPolicies !== undefined ? { securityPolicies } : {}),\n };\n }),\n}));\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"assethandlerStore.js","names":[],"sources":["../../../src/assethandler/store/assethandlerStore.ts"],"sourcesContent":["import { create } from 'zustand';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// View-model types — aligned 1:1 with wspace-assethandler-svc GraphQL schema.\n// Backend enum values (UPPER_CASE) are lowercased once during hydration so the\n// UI can render them directly. No field in this store is invented client-side;\n// everything is hydrated from the bootstrap query in AssetHandlerProvider.\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ─── Asset Types ──────────────────────────────────────────────────\nexport type AssetStatus = 'active' | 'inactive' | 'maintenance' | 'retired' | 'disposed';\nexport type AssetCondition = 'excellent' | 'good' | 'fair' | 'poor' | 'damaged';\nexport type DepreciationMethod = 'straight_line' | 'reducing_balance' | 'none';\n\nexport interface Asset {\n id: string;\n name: string;\n description: string;\n category: string;\n status: AssetStatus;\n condition: AssetCondition;\n serialNumber: string;\n assetTag: string;\n tagId: string;\n location: string;\n assignedTo: string;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n // ─── Financial / depreciation (backend-computed where noted) ───\n purchaseValue?: number;\n purchaseDate?: string;\n usefulLifeMonths?: number;\n salvageValue?: number;\n depreciationMethod?: DepreciationMethod;\n /** What this asset's usage meter counts — HOURS | KM | MILES | CYCLES | UNITS. */\n meterUnit?: string | null;\n department?: string;\n warrantyExpiry?: string;\n supplier?: string;\n disposalDate?: string;\n disposalMethod?: string;\n disposalNotes?: string;\n /** Computed book value (floored at salvage); undefined if no purchaseValue. */\n currentValue?: number;\n /** Computed accumulated depreciation. */\n accumulatedDepreciation?: number;\n /** Computed = purchaseValue + maintenance actualCost + work-order cost. */\n totalCostOfOwnership?: number;\n}\n\n// ─── ITIL Types ───────────────────────────────────────────────────\nexport type IncidentPriority = 'critical' | 'high' | 'medium' | 'low';\nexport type IncidentStatus = 'open' | 'in_progress' | 'resolved' | 'closed';\nexport type ChangeStatus =\n 'draft' | 'submitted' | 'approved' | 'in_progress' | 'completed' | 'rejected';\nexport type ChangeRisk = 'low' | 'medium' | 'high' | 'critical';\nexport type ProblemStatus = 'open' | 'investigating' | 'known_error' | 'resolved' | 'closed';\n\nexport interface Incident {\n id: string;\n title: string;\n description: string;\n category: string;\n priority: IncidentPriority;\n status: IncidentStatus;\n assignedTo: string;\n reportedBy: string;\n createdAt: string;\n resolvedAt?: string;\n resolution?: string;\n slaBreached: boolean;\n}\n\nexport interface ChangeRequest {\n id: string;\n title: string;\n description: string;\n type: string;\n status: ChangeStatus;\n risk: ChangeRisk;\n requestedBy: string;\n assignedTo: string;\n affectedAssets: string[];\n scheduledStart: string;\n scheduledEnd: string;\n createdAt: string;\n approvals: { name: string; status: string; date: string }[];\n}\n\nexport interface Problem {\n id: string;\n title: string;\n description: string;\n status: ProblemStatus;\n priority: IncidentPriority;\n category: string;\n assignedTo: string;\n relatedIncidents: string[];\n rootCause?: string;\n workaround?: string;\n resolution?: string;\n createdAt: string;\n updatedAt: string;\n}\n\n// ─── Finance Types ────────────────────────────────────────────────\nexport type TransactionType = 'purchase' | 'lease' | 'disposal' | 'transfer' | 'maintenance';\nexport type TransactionStatus = 'pending' | 'approved' | 'completed' | 'rejected';\n\nexport interface FinanceTransaction {\n id: string;\n type: TransactionType;\n amount: number;\n currency: string;\n description: string;\n category: string;\n date: string;\n status: TransactionStatus;\n vendor?: string;\n department: string;\n}\n\nexport interface Budget {\n id: string;\n name: string;\n category: string;\n allocated: number;\n spent: number;\n remaining: number;\n period: string;\n department: string;\n status: 'on_track' | 'over_budget' | 'under_budget';\n}\n\nexport interface Invoice {\n id: string;\n number: string;\n vendor: string;\n amount: number;\n currency: string;\n issueDate: string;\n dueDate: string;\n status: 'draft' | 'sent' | 'paid' | 'overdue' | 'cancelled';\n items: { description: string; qty: number; unitPrice: number; total: number }[];\n relatedPO?: string;\n paidAt?: string;\n}\n\n// ─── Maintenance Types ────────────────────────────────────────────\nexport type MaintenancePriority = 'critical' | 'high' | 'medium' | 'low';\n\nexport interface MaintenanceRecord {\n id: string;\n assetId: string;\n type: string;\n priority: MaintenancePriority;\n status: string;\n title: string;\n description: string;\n scheduledDate?: string;\n completedDate?: string;\n estimatedCost?: number;\n actualCost?: number;\n checklist: { task: string; completed: boolean }[];\n}\n\n// ─── Security Types ───────────────────────────────────────────────\nexport interface SecurityEvent {\n id: string;\n type: string;\n severity: 'critical' | 'high' | 'medium' | 'low' | 'info';\n title: string;\n description: string;\n source: string;\n userId?: string;\n ipAddress?: string;\n timestamp: string;\n resolved: boolean;\n}\n\nexport interface ComplianceFramework {\n id: string;\n name: string;\n version: string;\n status: 'compliant' | 'non_compliant' | 'partial' | 'under_review';\n score: number;\n totalControls: number;\n passedControls: number;\n failedControls: number;\n lastAssessment: string;\n nextAssessment: string;\n lastAssessedAt?: string;\n}\n\nexport interface SecurityPolicy {\n id: string;\n name: string;\n description: string;\n category: string;\n status: 'active' | 'draft' | 'deprecated' | 'under_review';\n version: string;\n effectiveDate: string;\n reviewDate: string;\n owner: string;\n applicableTo: string[];\n}\n\n// ─── Operations Types ─────────────────────────────────────────────\nexport interface WorkOrder {\n id: string;\n title: string;\n description: string;\n priority: 'critical' | 'high' | 'medium' | 'low';\n status: 'draft' | 'scheduled' | 'approved' | 'in_progress' | 'completed' | 'cancelled';\n assignedTo: string;\n assetId: string;\n type: string;\n createdAt: string;\n completedAt?: string;\n}\n\n// ─── Dashboard Types ──────────────────────────────────────────────\nexport interface DashboardOverview {\n totalAssets: number;\n openIncidents: number;\n openWorkOrders: number;\n totalTransactions: number;\n}\n\n// ─── Bootstrap payload (raw backend shapes) ───────────────────────\nexport interface AssetHandlerBootstrapPayload {\n dashboardOverview?: {\n totalAssets?: number;\n openIncidents?: number;\n openWorkOrders?: number;\n totalTransactions?: number;\n } | null;\n assets?: Array<{\n id: string;\n assetNumber: string;\n tagId?: string | null;\n name: string;\n description?: string | null;\n category: string;\n status: string;\n condition: string;\n serialNumber?: string | null;\n locationName?: string | null;\n assignedTo?: string | null;\n tags?: string[];\n createdAt?: string;\n updatedAt?: string;\n purchaseValue?: number | null;\n purchaseDate?: string | null;\n usefulLifeMonths?: number | null;\n salvageValue?: number | null;\n depreciationMethod?: string | null;\n meterUnit?: string | null;\n department?: string | null;\n warrantyExpiry?: string | null;\n supplier?: string | null;\n disposalDate?: string | null;\n disposalMethod?: string | null;\n disposalNotes?: string | null;\n currentValue?: number | null;\n accumulatedDepreciation?: number | null;\n totalCostOfOwnership?: number | null;\n }> | null;\n incidents?: Array<{\n id: string;\n title: string;\n description: string;\n category: string;\n priority: string;\n status: string;\n assignedTo?: string | null;\n reportedBy: string;\n reportedAt: string;\n resolvedAt?: string | null;\n resolution?: string | null;\n slaBreached: boolean;\n }> | null;\n workOrders?: Array<{\n id: string;\n title: string;\n description?: string | null;\n type: string;\n status: string;\n priority: string;\n assetId?: string | null;\n assignedTo?: string | null;\n createdAt: string;\n completedAt?: string | null;\n }> | null;\n maintenanceRecords?: Array<{\n id: string;\n assetId: string;\n title: string;\n description?: string | null;\n type: string;\n status: string;\n priority: string;\n scheduledAt?: string | null;\n completedAt?: string | null;\n estimatedCost?: number | null;\n actualCost?: number | null;\n checklist?: Array<Record<string, unknown>>;\n }> | null;\n transactions?: Array<{\n id: string;\n type: string;\n status: string;\n amount: number;\n currency: string;\n category: string;\n description: string;\n vendor?: string | null;\n department?: string | null;\n occurredAt: string;\n }> | null;\n changeRequests?: Array<{\n id: string;\n title: string;\n description: string;\n type: string;\n status: string;\n risk: string;\n requestedBy: string;\n assignedTo?: string | null;\n affectedAssets: string[];\n scheduledStart?: string | null;\n scheduledEnd?: string | null;\n approvals?: Array<{ name?: string; status?: string; date?: string }>;\n createdAt: string;\n }> | null;\n problems?: Array<{\n id: string;\n title: string;\n description: string;\n status: string;\n priority: string;\n category: string;\n assignedTo?: string | null;\n relatedIncidents: string[];\n rootCause?: string | null;\n workaround?: string | null;\n resolution?: string | null;\n createdAt: string;\n updatedAt: string;\n }> | null;\n budgets?: Array<{\n id: string;\n name: string;\n category: string;\n allocated: number;\n spent: number;\n remaining: number;\n period: string;\n department: string;\n status: string;\n }> | null;\n invoices?: Array<{\n id: string;\n number: string;\n vendor: string;\n amount: number;\n currency: string;\n issueDate: string;\n dueDate: string;\n status: string;\n items?: Array<{ description?: string; qty?: number; unitPrice?: number; total?: number }>;\n relatedPO?: string | null;\n paidAt?: string | null;\n }> | null;\n securityEvents?: {\n items: Array<{\n id: string;\n eventType: string;\n severity: string;\n title: string;\n description?: string | null;\n source?: string | null;\n userId?: string | null;\n ipAddress?: string | null;\n occurredAt: string;\n resolved: boolean;\n }>;\n } | null;\n complianceFrameworks?: {\n items: Array<{\n id: string;\n name: string;\n version: string;\n status: string;\n score: number;\n totalControls: number;\n passedControls: number;\n failedControls: number;\n lastAssessment: string;\n nextAssessment: string;\n lastAssessedAt?: string | null;\n }>;\n } | null;\n securityPolicies?: {\n items: Array<{\n id: string;\n name: string;\n description?: string | null;\n category: string;\n status: string;\n version: string;\n effectiveDate: string;\n reviewDate: string;\n owner: string;\n applicableTo: string[];\n }>;\n } | null;\n}\n\ninterface AssetHandlerState {\n /** True once the bootstrap query has hydrated the store at least once. */\n hydrated: boolean;\n\n // Domain data — always sourced from the backend, never seeded locally.\n overview: DashboardOverview | null;\n assets: Asset[];\n incidents: Incident[];\n changeRequests: ChangeRequest[];\n problems: Problem[];\n transactions: FinanceTransaction[];\n budgets: Budget[];\n invoices: Invoice[];\n maintenanceRecords: MaintenanceRecord[];\n securityEvents: SecurityEvent[];\n complianceFrameworks: ComplianceFramework[];\n securityPolicies: SecurityPolicy[];\n workOrders: WorkOrder[];\n\n hydrateFromBootstrap: (payload: AssetHandlerBootstrapPayload) => void;\n\n /**\n * Imperative refetch of the bootstrap query, registered by the provider's\n * hydrator. Pages that mutate domain data can call `refetchBootstrap()` to\n * pull fresh store data. Prefer Apollo `refetchQueries: ['AssetHandlerBootstrap']`\n * on the mutation itself; use this for cross-component imperative refresh.\n */\n bootstrapRefetch: (() => void) | null;\n setBootstrapRefetch: (refetch: (() => void) | null) => void;\n refetchBootstrap: () => void;\n}\n\nexport const useAssetHandlerStore = create<AssetHandlerState>((set, get) => ({\n hydrated: false,\n\n bootstrapRefetch: null,\n setBootstrapRefetch: (refetch) => set({ bootstrapRefetch: refetch }),\n refetchBootstrap: () => {\n get().bootstrapRefetch?.();\n },\n\n overview: null,\n assets: [],\n incidents: [],\n changeRequests: [],\n problems: [],\n transactions: [],\n budgets: [],\n invoices: [],\n maintenanceRecords: [],\n securityEvents: [],\n complianceFrameworks: [],\n securityPolicies: [],\n workOrders: [],\n\n hydrateFromBootstrap: (payload) =>\n set(() => {\n const assets: Asset[] = (payload.assets ?? []).map((asset) => ({\n id: asset.id,\n name: asset.name,\n description: asset.description ?? '',\n category: asset.category.toLowerCase(),\n status: asset.status.toLowerCase() as AssetStatus,\n condition: asset.condition.toLowerCase() as AssetCondition,\n serialNumber: asset.serialNumber ?? '',\n assetTag: asset.assetNumber,\n tagId: asset.tagId ?? asset.id,\n location: asset.locationName ?? '',\n assignedTo: asset.assignedTo ?? '',\n tags: asset.tags ?? [],\n createdAt: asset.createdAt ?? '',\n updatedAt: asset.updatedAt ?? '',\n purchaseValue: asset.purchaseValue ?? undefined,\n purchaseDate: asset.purchaseDate ?? undefined,\n usefulLifeMonths: asset.usefulLifeMonths ?? undefined,\n salvageValue: asset.salvageValue ?? undefined,\n depreciationMethod: asset.depreciationMethod\n ? (asset.depreciationMethod.toLowerCase() as DepreciationMethod)\n : undefined,\n // Kept UPPER-CASE, unlike depreciationMethod above: it is compared against the\n // GraphQL enum values, not against a lower-cased UI string.\n meterUnit: asset.meterUnit ?? null,\n department: asset.department ?? undefined,\n warrantyExpiry: asset.warrantyExpiry ?? undefined,\n supplier: asset.supplier ?? undefined,\n disposalDate: asset.disposalDate ?? undefined,\n disposalMethod: asset.disposalMethod ?? undefined,\n disposalNotes: asset.disposalNotes ?? undefined,\n currentValue: asset.currentValue ?? undefined,\n accumulatedDepreciation: asset.accumulatedDepreciation ?? undefined,\n totalCostOfOwnership: asset.totalCostOfOwnership ?? undefined,\n }));\n\n const incidents: Incident[] = (payload.incidents ?? []).map((incident) => ({\n id: incident.id,\n title: incident.title,\n description: incident.description,\n category: incident.category,\n priority: incident.priority.toLowerCase() as IncidentPriority,\n status: incident.status.toLowerCase() as IncidentStatus,\n assignedTo: incident.assignedTo ?? '',\n reportedBy: incident.reportedBy,\n createdAt: incident.reportedAt,\n resolvedAt: incident.resolvedAt ?? undefined,\n resolution: incident.resolution ?? undefined,\n slaBreached: incident.slaBreached,\n }));\n\n const workOrders: WorkOrder[] = (payload.workOrders ?? []).map((workOrder) => ({\n id: workOrder.id,\n title: workOrder.title,\n description: workOrder.description ?? '',\n assetId: workOrder.assetId ?? '',\n priority: workOrder.priority.toLowerCase() as WorkOrder['priority'],\n status: workOrder.status.toLowerCase() as WorkOrder['status'],\n assignedTo: workOrder.assignedTo ?? '',\n createdAt: workOrder.createdAt,\n completedAt: workOrder.completedAt ?? undefined,\n type: workOrder.type.toLowerCase(),\n }));\n\n const maintenanceRecords: MaintenanceRecord[] = (payload.maintenanceRecords ?? []).map(\n (record) => ({\n id: record.id,\n assetId: record.assetId,\n type: record.type.toLowerCase(),\n priority: record.priority.toLowerCase() as MaintenancePriority,\n status: record.status.toLowerCase(),\n title: record.title,\n description: record.description ?? '',\n scheduledDate: record.scheduledAt ?? undefined,\n completedDate: record.completedAt ?? undefined,\n estimatedCost: record.estimatedCost ?? undefined,\n actualCost: record.actualCost ?? undefined,\n checklist: (record.checklist ?? []).map((item) => ({\n task: String(item.task ?? 'Task'),\n completed: Boolean(item.completed ?? false),\n })),\n })\n );\n\n const transactions: FinanceTransaction[] = (payload.transactions ?? []).map((tx) => ({\n id: tx.id,\n type: tx.type.toLowerCase() as TransactionType,\n amount: tx.amount,\n currency: tx.currency,\n description: tx.description,\n category: tx.category,\n date: tx.occurredAt,\n status: tx.status.toLowerCase() as TransactionStatus,\n vendor: tx.vendor ?? undefined,\n department: tx.department ?? '',\n }));\n\n const changeRequests: ChangeRequest[] = (payload.changeRequests ?? []).map((change) => ({\n id: change.id,\n title: change.title,\n description: change.description,\n type: change.type.toLowerCase(),\n status: change.status.toLowerCase() as ChangeStatus,\n risk: change.risk.toLowerCase() as ChangeRisk,\n requestedBy: change.requestedBy,\n assignedTo: change.assignedTo ?? '',\n affectedAssets: change.affectedAssets,\n scheduledStart: change.scheduledStart ?? '',\n scheduledEnd: change.scheduledEnd ?? '',\n createdAt: change.createdAt,\n approvals: (change.approvals ?? []).map((approval) => ({\n name: approval.name ?? 'Approver',\n status: approval.status ?? 'pending',\n date: approval.date ?? change.createdAt,\n })),\n }));\n\n const problems: Problem[] = (payload.problems ?? []).map((problem) => ({\n id: problem.id,\n title: problem.title,\n description: problem.description,\n status: problem.status.toLowerCase() as ProblemStatus,\n priority: problem.priority.toLowerCase() as IncidentPriority,\n category: problem.category,\n assignedTo: problem.assignedTo ?? '',\n relatedIncidents: problem.relatedIncidents,\n rootCause: problem.rootCause ?? undefined,\n workaround: problem.workaround ?? undefined,\n resolution: problem.resolution ?? undefined,\n createdAt: problem.createdAt,\n updatedAt: problem.updatedAt,\n }));\n\n const budgets: Budget[] = (payload.budgets ?? []).map((budget) => ({\n id: budget.id,\n name: budget.name,\n category: budget.category,\n allocated: budget.allocated,\n spent: budget.spent,\n remaining: budget.remaining,\n period: budget.period,\n department: budget.department,\n status: budget.status.toLowerCase() as Budget['status'],\n }));\n\n const invoices: Invoice[] = (payload.invoices ?? []).map((invoice) => ({\n id: invoice.id,\n number: invoice.number,\n vendor: invoice.vendor,\n amount: invoice.amount,\n currency: invoice.currency,\n issueDate: invoice.issueDate,\n dueDate: invoice.dueDate,\n status: invoice.status.toLowerCase() as Invoice['status'],\n items: (invoice.items ?? []).map((item) => ({\n description: item.description ?? 'Line item',\n qty: item.qty ?? 1,\n unitPrice: item.unitPrice ?? item.total ?? 0,\n total: item.total ?? item.unitPrice ?? 0,\n })),\n relatedPO: invoice.relatedPO ?? undefined,\n paidAt: invoice.paidAt ?? undefined,\n }));\n\n const securityEvents: SecurityEvent[] = (payload.securityEvents?.items ?? []).map(\n (event) => ({\n id: event.id,\n type: event.eventType,\n severity: event.severity.toLowerCase() as SecurityEvent['severity'],\n title: event.title,\n description: event.description ?? '',\n source: event.source ?? 'security',\n userId: event.userId ?? undefined,\n ipAddress: event.ipAddress ?? undefined,\n timestamp: event.occurredAt,\n resolved: event.resolved,\n })\n );\n\n const complianceFrameworks: ComplianceFramework[] = (\n payload.complianceFrameworks?.items ?? []\n ).map((framework) => ({\n id: framework.id,\n name: framework.name,\n version: framework.version,\n status: framework.status.toLowerCase() as ComplianceFramework['status'],\n score: framework.score,\n totalControls: framework.totalControls,\n passedControls: framework.passedControls,\n failedControls: framework.failedControls,\n lastAssessment: framework.lastAssessment,\n nextAssessment: framework.nextAssessment,\n lastAssessedAt: framework.lastAssessedAt ?? undefined,\n }));\n\n const securityPolicies: SecurityPolicy[] = (payload.securityPolicies?.items ?? []).map(\n (policy) => ({\n id: policy.id,\n name: policy.name,\n description: policy.description ?? '',\n category: policy.category,\n status: policy.status.toLowerCase() as SecurityPolicy['status'],\n version: policy.version,\n effectiveDate: policy.effectiveDate,\n reviewDate: policy.reviewDate,\n owner: policy.owner,\n applicableTo: policy.applicableTo,\n })\n );\n\n const overview: DashboardOverview | null = payload.dashboardOverview\n ? {\n totalAssets: payload.dashboardOverview.totalAssets ?? assets.length,\n openIncidents: payload.dashboardOverview.openIncidents ?? 0,\n openWorkOrders: payload.dashboardOverview.openWorkOrders ?? 0,\n totalTransactions: payload.dashboardOverview.totalTransactions ?? 0,\n }\n : null;\n\n // Only overwrite the slices this payload actually carries. The provider\n // fetches the module's data as several smaller queries rather than one\n // 13-root query (BOFF-6381 — wspace-assethandler-svc rejects more than\n // ~3 concurrent operations, so the single combined query failed 100% of\n // the time in production and left every page empty). Each batch hydrates\n // independently, so a rebuild of all thirteen slices here would let a\n // later batch wipe an earlier one back to `[]`. zustand's `set` merges\n // shallowly, so an omitted key keeps its previous value.\n return {\n hydrated: true,\n ...(payload.dashboardOverview !== undefined ? { overview } : {}),\n ...(payload.assets !== undefined ? { assets } : {}),\n ...(payload.incidents !== undefined ? { incidents } : {}),\n ...(payload.changeRequests !== undefined ? { changeRequests } : {}),\n ...(payload.problems !== undefined ? { problems } : {}),\n ...(payload.workOrders !== undefined ? { workOrders } : {}),\n ...(payload.maintenanceRecords !== undefined ? { maintenanceRecords } : {}),\n ...(payload.transactions !== undefined ? { transactions } : {}),\n ...(payload.budgets !== undefined ? { budgets } : {}),\n ...(payload.invoices !== undefined ? { invoices } : {}),\n ...(payload.securityEvents !== undefined ? { securityEvents } : {}),\n ...(payload.complianceFrameworks !== undefined ? { complianceFrameworks } : {}),\n ...(payload.securityPolicies !== undefined ? { securityPolicies } : {}),\n };\n }),\n}));\n"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface PrintAssetTagOptions {
|
|
2
|
+
/** Human-readable asset name. */
|
|
3
|
+
name: string;
|
|
4
|
+
/** The scannable tagId (stable, workspace-unique). */
|
|
5
|
+
tagId: string;
|
|
6
|
+
/** Display value for the legacy asset tag / asset number. */
|
|
7
|
+
assetTag: string;
|
|
8
|
+
/** Optional category label shown beneath the name. */
|
|
9
|
+
category?: string;
|
|
10
|
+
/** Document title for the print window. */
|
|
11
|
+
documentTitle?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Open a small print window that renders a single asset tag (QR + details) and
|
|
15
|
+
* triggers the browser print dialog. The popup is closed automatically after
|
|
16
|
+
* printing.
|
|
17
|
+
*
|
|
18
|
+
* The print window is a blank document that does not load the host app's CSS
|
|
19
|
+
* variables, so the inline stylesheet below uses concrete hex values. Those
|
|
20
|
+
* colours are chosen to print reliably on any printer and are not part of the
|
|
21
|
+
* application's live theme surface.
|
|
22
|
+
*/
|
|
23
|
+
export declare function printAssetTag({ name, tagId, assetTag, category, documentTitle, }: PrintAssetTagOptions): Promise<void>;
|
|
24
|
+
//# sourceMappingURL=printAssetTag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"printAssetTag.d.ts","sourceRoot":"","sources":["../../../src/assethandler/utils/printAssetTag.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,EAClC,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,aAA2B,GAC5B,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8HtC"}
|