@burdenoff/microfe-assethandler 2026.703.2 → 2026.703.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/AssetHandlerRoot.js +18 -18
- package/dist/assethandler/hooks/useAssetHandlerNavigate.js +19 -0
- package/dist/assethandler/hooks/useAssetHandlerNavigate.js.map +1 -0
- package/dist/assethandler/pages/AiPredictionsPage.js +29 -29
- package/dist/assethandler/pages/AnalyticsPage.js +154 -154
- package/dist/assethandler/pages/AssetsAssetCategoriesPage.js +48 -48
- package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js +84 -84
- package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCreatePage.js +82 -82
- package/dist/assethandler/pages/AssetsAssetCreatePage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetDetailPage.js +104 -103
- package/dist/assethandler/pages/AssetsAssetDetailPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetListPage.js +132 -132
- package/dist/assethandler/pages/AssetsAssetListPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetTrackingPage.js +52 -52
- package/dist/assethandler/pages/CmdbBrowserPage.js +27 -27
- package/dist/assethandler/pages/DashboardPage.js +119 -119
- package/dist/assethandler/pages/DashboardPage.js.map +1 -1
- package/dist/assethandler/pages/DigitalTwinPage.js +22 -22
- package/dist/assethandler/pages/DiscoveryJobsPage.js +35 -35
- package/dist/assethandler/pages/EsgDashboardPage.js +32 -32
- package/dist/assethandler/pages/FinanceBudgetDetailPage.js +57 -56
- package/dist/assethandler/pages/FinanceBudgetDetailPage.js.map +1 -1
- package/dist/assethandler/pages/FinanceFinanceHubPage.js +98 -98
- package/dist/assethandler/pages/FinanceFinanceHubPage.js.map +1 -1
- package/dist/assethandler/pages/FinanceInvoiceDetailPage.js +58 -57
- package/dist/assethandler/pages/FinanceInvoiceDetailPage.js.map +1 -1
- package/dist/assethandler/pages/IotDevicesPage.js +29 -29
- package/dist/assethandler/pages/ItilChangeDetailPage.js +76 -75
- package/dist/assethandler/pages/ItilChangeDetailPage.js.map +1 -1
- package/dist/assethandler/pages/ItilChangeManagementPage.js +49 -49
- package/dist/assethandler/pages/ItilIncidentDetailPage.js +63 -62
- package/dist/assethandler/pages/ItilIncidentDetailPage.js.map +1 -1
- package/dist/assethandler/pages/ItilIncidentManagementPage.js +72 -72
- package/dist/assethandler/pages/ItilItilhubPage.js +112 -112
- package/dist/assethandler/pages/ItilItilhubPage.js.map +1 -1
- package/dist/assethandler/pages/ItilProblemDetailPage.js +61 -60
- package/dist/assethandler/pages/ItilProblemDetailPage.js.map +1 -1
- package/dist/assethandler/pages/ItilProblemManagementPage.js +46 -46
- package/dist/assethandler/pages/KnowledgeBasePage.js +28 -28
- package/dist/assethandler/pages/MaintenanceMaintenanceCalendarPage.js +52 -52
- package/dist/assethandler/pages/MaintenanceMaintenanceSchedulerPage.js +29 -29
- package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js +58 -57
- package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js.map +1 -1
- package/dist/assethandler/pages/OperationsOperationsHubPage.js +80 -80
- package/dist/assethandler/pages/OperationsOperationsHubPage.js.map +1 -1
- package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js +49 -48
- package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js.map +1 -1
- package/dist/assethandler/pages/PortfolioPortfolioOverviewPage.js +52 -52
- package/dist/assethandler/pages/ProvenancePage.js +36 -36
- package/dist/assethandler/pages/SamLicensesPage.js +27 -27
- package/dist/assethandler/pages/SecurityComplianceDetailPage.js +39 -38
- package/dist/assethandler/pages/SecurityComplianceDetailPage.js.map +1 -1
- package/dist/assethandler/pages/SecurityPolicyDetailPage.js +50 -49
- package/dist/assethandler/pages/SecurityPolicyDetailPage.js.map +1 -1
- package/dist/assethandler/pages/SecuritySecurityEventDetailPage.js +47 -46
- package/dist/assethandler/pages/SecuritySecurityEventDetailPage.js.map +1 -1
- package/dist/assethandler/pages/SecuritySecurityHubPage.js +104 -104
- package/dist/assethandler/pages/SecuritySecurityHubPage.js.map +1 -1
- package/dist/assethandler/pages/TransactionsTransactionDetailPage.js +74 -73
- package/dist/assethandler/pages/TransactionsTransactionDetailPage.js.map +1 -1
- package/dist/assethandler/pages/TransactionsTransactionListPage.js +77 -77
- package/dist/assethandler/providers/AssetHandlerProvider.js +12 -12
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetsAssetListPage.js","names":[],"sources":["../../../src/assethandler/pages/AssetsAssetListPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\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 EmphasisPanel,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Search, Plus, Grid3x3, List, Table as TableIcon } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { tWithFallback } from '../utils/i18n';\n\nconst statusColors: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n active: 'default',\n inactive: 'outline',\n maintenance: 'secondary',\n retired: 'outline',\n disposed: 'destructive',\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\nexport function AssetsAssetListPage() {\n const { t } = useI18n();\n const navigate = useNavigate();\n const { assets, hydrated } = useAssetHandlerStore();\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\n const categories = useMemo(\n () => [...new Set(assets.map((a) => a.category).filter(Boolean))].sort(),\n [assets]\n );\n\n const filteredAssets = useMemo(() => {\n return assets.filter((a) => {\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]);\n\n const activeCount = assets.filter((a) => a.status === 'active').length;\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>\n {tWithFallback(t, 'assethandler.assets.list.title', 'Asset Inventory')}\n </GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {assets.length}{' '}\n {tWithFallback(t, 'assethandler.assets.list.subtitle.totalAssets', 'total assets')}{' '}\n · {activeCount}{' '}\n {tWithFallback(t, 'assethandler.assets.list.subtitle.active', 'active')}\n </p>\n </div>\n <Button size=\"sm\" onClick={() => navigate('/assets/asset-create')}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {tWithFallback(t, 'assethandler.assets.list.actions.addAsset', 'Add Asset')}\n </Button>\n </div>\n\n <PagePurpose>\n {tWithFallback(\n t,\n 'assethandler.assets.list.purpose',\n 'The single source of truth for every asset 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 {/* Inventory summary emphasis */}\n <EmphasisPanel className=\"flex flex-wrap items-center justify-between gap-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.summary.tracked', 'Assets tracked')}\n </p>\n <p className=\"text-3xl font-bold tabular-nums\">{assets.length}</p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.summary.categories', 'Categories')}\n </p>\n <p className=\"text-3xl font-bold tabular-nums\">{categories.length}</p>\n </div>\n </EmphasisPanel>\n\n {/* Filters Bar */}\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex flex-col md:flex-row gap-3\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={tWithFallback(\n t,\n 'assethandler.assets.list.search.placeholder',\n 'Search by name, asset 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-[180px]\">\n <SelectValue\n placeholder={tWithFallback(\n t,\n 'assethandler.assets.list.filters.category.placeholder',\n 'Category'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(\n t,\n 'assethandler.assets.list.filters.category.all',\n 'All Categories'\n )}\n </SelectItem>\n {categories.map((category) => (\n <SelectItem key={category} value={category} className=\"capitalize\">\n {category.replace(/_/g, ' ')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger className=\"w-[160px]\">\n <SelectValue\n placeholder={tWithFallback(\n t,\n 'assethandler.assets.list.filters.status.placeholder',\n 'Status'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.all', 'All Statuses')}\n </SelectItem>\n <SelectItem value=\"active\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.active', 'Active')}\n </SelectItem>\n <SelectItem value=\"inactive\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.inactive', 'Inactive')}\n </SelectItem>\n <SelectItem value=\"maintenance\">\n {tWithFallback(\n t,\n 'assethandler.assets.list.filters.status.maintenance',\n 'Maintenance'\n )}\n </SelectItem>\n <SelectItem value=\"retired\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.retired', 'Retired')}\n </SelectItem>\n <SelectItem value=\"disposed\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.disposed', 'Disposed')}\n </SelectItem>\n </SelectContent>\n </Select>\n <div className=\"flex gap-1 border rounded-md p-0.5\">\n <Button\n variant={viewMode === 'table' ? 'default' : 'ghost'}\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setViewMode('table')}\n >\n <TableIcon className=\"h-4 w-4\" />\n </Button>\n <Button\n variant={viewMode === 'grid' ? 'default' : 'ghost'}\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setViewMode('grid')}\n >\n <Grid3x3 className=\"h-4 w-4\" />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'default' : 'ghost'}\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setViewMode('list')}\n >\n <List className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n\n {/* Results */}\n <div className=\"text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.results.showing', 'Showing')}{' '}\n {filteredAssets.length} {tWithFallback(t, 'assethandler.assets.list.results.of', 'of')}{' '}\n {assets.length} {tWithFallback(t, 'assethandler.assets.list.results.assets', 'assets')}\n </div>\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 {viewMode === '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\">\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.assetTag', 'Asset Tag')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.name', 'Name')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.category', 'Category')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.status', 'Status')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.condition', 'Condition')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.location', 'Location')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.assignedTo', 'Assigned To')}\n </th>\n </tr>\n </thead>\n <tbody>\n {filteredAssets.map((asset) => (\n <tr\n key={asset.id}\n className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <td className=\"p-3 font-mono text-xs\">{asset.assetTag}</td>\n <td className=\"p-3\">\n <div>\n <p className=\"font-medium\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">{asset.serialNumber}</p>\n </div>\n </td>\n <td className=\"p-3 capitalize\">{asset.category.replace(/_/g, ' ')}</td>\n <td className=\"p-3\">\n <Badge variant={statusColors[asset.status] || 'outline'}>\n {asset.status.replace(/_/g, ' ')}\n </Badge>\n </td>\n <td className=\"p-3\">\n <span\n className={`inline-flex rounded-md px-2 py-0.5 text-xs font-medium ${conditionColors[asset.condition] || ''}`}\n >\n {asset.condition}\n </span>\n </td>\n <td className=\"p-3 text-xs max-w-[200px] truncate\">\n {asset.location || '—'}\n </td>\n <td className=\"p-3 text-xs\">{asset.assignedTo || '—'}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n\n {viewMode === 'grid' && filteredAssets.length > 0 && (\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {filteredAssets.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\">\n <Badge variant={statusColors[asset.status] || 'outline'}>\n {asset.status.replace(/_/g, ' ')}\n </Badge>\n <span className=\"text-xs font-mono text-text-secondary\">{asset.assetTag}</span>\n </div>\n <CardTitle className=\"text-base mt-2\">{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 {tWithFallback(t, 'assethandler.assets.list.grid.category', 'Category')}\n </span>\n <span className=\"capitalize\">{asset.category.replace(/_/g, ' ')}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.grid.condition', 'Condition')}\n </span>\n <span\n className={`rounded-md px-2 py-0.5 text-xs font-medium ${conditionColors[asset.condition] || ''}`}\n >\n {asset.condition}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tWithFallback(t, '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 {viewMode === 'list' && filteredAssets.length > 0 && (\n <div className=\"space-y-2\">\n {filteredAssets.map((asset) => (\n <Card\n key={asset.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <CardContent className=\"py-3 px-4\">\n <div className=\"flex items-center gap-4\">\n <div className=\"flex-1 min-w-0 grid grid-cols-5 gap-4 items-center\">\n <div className=\"col-span-2\">\n <p className=\"font-medium text-sm truncate\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">\n {asset.assetTag} · {asset.serialNumber}\n </p>\n </div>\n <div className=\"capitalize text-sm\">{asset.category.replace(/_/g, ' ')}</div>\n <div>\n <Badge variant={statusColors[asset.status] || 'outline'} className=\"text-xs\">\n {asset.status.replace(/_/g, ' ')}\n </Badge>\n </div>\n <div className=\"text-sm text-text-secondary truncate\">\n {asset.location || '—'}\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\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={tWithFallback(t, 'assethandler.assets.list.empty.title', 'No assets found')}\n description={tWithFallback(\n t,\n 'assethandler.assets.list.empty.description',\n 'Try adjusting your filters or add a new asset 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 {tWithFallback(t, 'assethandler.assets.list.actions.addAsset', 'Add Asset')}\n </Button>\n }\n />\n )}\n </div>\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 { useState, useMemo } from 'react';\nimport {\n Badge,\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 EmphasisPanel,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { Search, Plus, Grid3x3, List, Table as TableIcon } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\nimport { tWithFallback } from '../utils/i18n';\n\nconst statusColors: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n active: 'default',\n inactive: 'outline',\n maintenance: 'secondary',\n retired: 'outline',\n disposed: 'destructive',\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\nexport function AssetsAssetListPage() {\n const { t } = useI18n();\n const navigate = useAssetHandlerNavigate();\n const { assets, hydrated } = useAssetHandlerStore();\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\n const categories = useMemo(\n () => [...new Set(assets.map((a) => a.category).filter(Boolean))].sort(),\n [assets]\n );\n\n const filteredAssets = useMemo(() => {\n return assets.filter((a) => {\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]);\n\n const activeCount = assets.filter((a) => a.status === 'active').length;\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>\n {tWithFallback(t, 'assethandler.assets.list.title', 'Asset Inventory')}\n </GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {assets.length}{' '}\n {tWithFallback(t, 'assethandler.assets.list.subtitle.totalAssets', 'total assets')}{' '}\n · {activeCount}{' '}\n {tWithFallback(t, 'assethandler.assets.list.subtitle.active', 'active')}\n </p>\n </div>\n <Button size=\"sm\" onClick={() => navigate('/assets/asset-create')}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {tWithFallback(t, 'assethandler.assets.list.actions.addAsset', 'Add Asset')}\n </Button>\n </div>\n\n <PagePurpose>\n {tWithFallback(\n t,\n 'assethandler.assets.list.purpose',\n 'The single source of truth for every asset 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 {/* Inventory summary emphasis */}\n <EmphasisPanel className=\"flex flex-wrap items-center justify-between gap-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.summary.tracked', 'Assets tracked')}\n </p>\n <p className=\"text-3xl font-bold tabular-nums\">{assets.length}</p>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.summary.categories', 'Categories')}\n </p>\n <p className=\"text-3xl font-bold tabular-nums\">{categories.length}</p>\n </div>\n </EmphasisPanel>\n\n {/* Filters Bar */}\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex flex-col md:flex-row gap-3\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={tWithFallback(\n t,\n 'assethandler.assets.list.search.placeholder',\n 'Search by name, asset 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-[180px]\">\n <SelectValue\n placeholder={tWithFallback(\n t,\n 'assethandler.assets.list.filters.category.placeholder',\n 'Category'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(\n t,\n 'assethandler.assets.list.filters.category.all',\n 'All Categories'\n )}\n </SelectItem>\n {categories.map((category) => (\n <SelectItem key={category} value={category} className=\"capitalize\">\n {category.replace(/_/g, ' ')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger className=\"w-[160px]\">\n <SelectValue\n placeholder={tWithFallback(\n t,\n 'assethandler.assets.list.filters.status.placeholder',\n 'Status'\n )}\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.all', 'All Statuses')}\n </SelectItem>\n <SelectItem value=\"active\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.active', 'Active')}\n </SelectItem>\n <SelectItem value=\"inactive\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.inactive', 'Inactive')}\n </SelectItem>\n <SelectItem value=\"maintenance\">\n {tWithFallback(\n t,\n 'assethandler.assets.list.filters.status.maintenance',\n 'Maintenance'\n )}\n </SelectItem>\n <SelectItem value=\"retired\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.retired', 'Retired')}\n </SelectItem>\n <SelectItem value=\"disposed\">\n {tWithFallback(t, 'assethandler.assets.list.filters.status.disposed', 'Disposed')}\n </SelectItem>\n </SelectContent>\n </Select>\n <div className=\"flex gap-1 border rounded-md p-0.5\">\n <Button\n variant={viewMode === 'table' ? 'default' : 'ghost'}\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setViewMode('table')}\n >\n <TableIcon className=\"h-4 w-4\" />\n </Button>\n <Button\n variant={viewMode === 'grid' ? 'default' : 'ghost'}\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setViewMode('grid')}\n >\n <Grid3x3 className=\"h-4 w-4\" />\n </Button>\n <Button\n variant={viewMode === 'list' ? 'default' : 'ghost'}\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setViewMode('list')}\n >\n <List className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n\n {/* Results */}\n <div className=\"text-sm text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.results.showing', 'Showing')}{' '}\n {filteredAssets.length} {tWithFallback(t, 'assethandler.assets.list.results.of', 'of')}{' '}\n {assets.length} {tWithFallback(t, 'assethandler.assets.list.results.assets', 'assets')}\n </div>\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 {viewMode === '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\">\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.assetTag', 'Asset Tag')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.name', 'Name')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.category', 'Category')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.status', 'Status')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.condition', 'Condition')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.location', 'Location')}\n </th>\n <th className=\"text-left p-3 font-medium\">\n {tWithFallback(t, 'assethandler.assets.list.table.assignedTo', 'Assigned To')}\n </th>\n </tr>\n </thead>\n <tbody>\n {filteredAssets.map((asset) => (\n <tr\n key={asset.id}\n className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <td className=\"p-3 font-mono text-xs\">{asset.assetTag}</td>\n <td className=\"p-3\">\n <div>\n <p className=\"font-medium\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">{asset.serialNumber}</p>\n </div>\n </td>\n <td className=\"p-3 capitalize\">{asset.category.replace(/_/g, ' ')}</td>\n <td className=\"p-3\">\n <Badge variant={statusColors[asset.status] || 'outline'}>\n {asset.status.replace(/_/g, ' ')}\n </Badge>\n </td>\n <td className=\"p-3\">\n <span\n className={`inline-flex rounded-md px-2 py-0.5 text-xs font-medium ${conditionColors[asset.condition] || ''}`}\n >\n {asset.condition}\n </span>\n </td>\n <td className=\"p-3 text-xs max-w-[200px] truncate\">\n {asset.location || '—'}\n </td>\n <td className=\"p-3 text-xs\">{asset.assignedTo || '—'}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n\n {viewMode === 'grid' && filteredAssets.length > 0 && (\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {filteredAssets.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\">\n <Badge variant={statusColors[asset.status] || 'outline'}>\n {asset.status.replace(/_/g, ' ')}\n </Badge>\n <span className=\"text-xs font-mono text-text-secondary\">{asset.assetTag}</span>\n </div>\n <CardTitle className=\"text-base mt-2\">{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 {tWithFallback(t, 'assethandler.assets.list.grid.category', 'Category')}\n </span>\n <span className=\"capitalize\">{asset.category.replace(/_/g, ' ')}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tWithFallback(t, 'assethandler.assets.list.grid.condition', 'Condition')}\n </span>\n <span\n className={`rounded-md px-2 py-0.5 text-xs font-medium ${conditionColors[asset.condition] || ''}`}\n >\n {asset.condition}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tWithFallback(t, '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 {viewMode === 'list' && filteredAssets.length > 0 && (\n <div className=\"space-y-2\">\n {filteredAssets.map((asset) => (\n <Card\n key={asset.id}\n className=\"cursor-pointer\"\n onClick={() => navigate(`/assets/${asset.id}`)}\n >\n <CardContent className=\"py-3 px-4\">\n <div className=\"flex items-center gap-4\">\n <div className=\"flex-1 min-w-0 grid grid-cols-5 gap-4 items-center\">\n <div className=\"col-span-2\">\n <p className=\"font-medium text-sm truncate\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">\n {asset.assetTag} · {asset.serialNumber}\n </p>\n </div>\n <div className=\"capitalize text-sm\">{asset.category.replace(/_/g, ' ')}</div>\n <div>\n <Badge variant={statusColors[asset.status] || 'outline'} className=\"text-xs\">\n {asset.status.replace(/_/g, ' ')}\n </Badge>\n </div>\n <div className=\"text-sm text-text-secondary truncate\">\n {asset.location || '—'}\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\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={tWithFallback(t, 'assethandler.assets.list.empty.title', 'No assets found')}\n description={tWithFallback(\n t,\n 'assethandler.assets.list.empty.description',\n 'Try adjusting your filters or add a new asset 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 {tWithFallback(t, 'assethandler.assets.list.actions.addAsset', 'Add Asset')}\n </Button>\n }\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useAssetHandlerStore as e } from "../store/assethandlerStore.js";
|
|
2
2
|
import { useMemo as t } from "react";
|
|
3
3
|
import { Building as n, HelpCircle as r, MapPin as i, Radio as a, RefreshCw as o, Search as s } from "lucide-react";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
5
|
+
import { Badge as u, Button as d, Card as f, CardContent as p, CardDescription as m, CardHeader as h, CardTitle as g, EmphasisPanel as _, GradientText as v, IllustratedEmptyState as y, Input as b, PagePurpose as x } from "@burdenoff/fe-libs/ui";
|
|
6
6
|
//#region src/assethandler/pages/AssetsAssetTrackingPage.tsx
|
|
7
7
|
var S = {
|
|
8
8
|
active: "default",
|
|
@@ -16,89 +16,89 @@ function w() {
|
|
|
16
16
|
let n = t.location.trim() || C;
|
|
17
17
|
return e[n] || (e[n] = []), e[n].push(t), e;
|
|
18
18
|
}, {}), [w]), E = w.filter((e) => e.location.trim()).length, D = w.length - E, O = Object.keys(T).filter((e) => e !== C).length;
|
|
19
|
-
return /* @__PURE__ */
|
|
19
|
+
return /* @__PURE__ */ l("div", {
|
|
20
20
|
className: "space-y-6 p-6",
|
|
21
21
|
children: [
|
|
22
|
-
/* @__PURE__ */
|
|
22
|
+
/* @__PURE__ */ l("div", {
|
|
23
23
|
className: "flex items-center justify-between",
|
|
24
|
-
children: [/* @__PURE__ */
|
|
24
|
+
children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h1", {
|
|
25
25
|
className: "text-2xl font-bold",
|
|
26
|
-
children: /* @__PURE__ */
|
|
27
|
-
}), /* @__PURE__ */
|
|
26
|
+
children: /* @__PURE__ */ c(v, { children: "Asset Tracking" })
|
|
27
|
+
}), /* @__PURE__ */ l("p", {
|
|
28
28
|
className: "text-sm text-text-secondary",
|
|
29
29
|
children: [
|
|
30
30
|
"Location overview for ",
|
|
31
31
|
w.length,
|
|
32
32
|
" assets"
|
|
33
33
|
]
|
|
34
|
-
})] }), /* @__PURE__ */
|
|
34
|
+
})] }), /* @__PURE__ */ l("div", {
|
|
35
35
|
className: "flex gap-2",
|
|
36
|
-
children: [/* @__PURE__ */
|
|
36
|
+
children: [/* @__PURE__ */ l(d, {
|
|
37
37
|
variant: "outline",
|
|
38
38
|
size: "sm",
|
|
39
|
-
children: [/* @__PURE__ */
|
|
40
|
-
}), /* @__PURE__ */
|
|
39
|
+
children: [/* @__PURE__ */ c(o, { className: "mr-2 h-4 w-4" }), "Refresh"]
|
|
40
|
+
}), /* @__PURE__ */ l(d, {
|
|
41
41
|
size: "sm",
|
|
42
|
-
children: [/* @__PURE__ */
|
|
42
|
+
children: [/* @__PURE__ */ c(a, { className: "mr-2 h-4 w-4" }), "Track New Asset"]
|
|
43
43
|
})]
|
|
44
44
|
})]
|
|
45
45
|
}),
|
|
46
|
-
/* @__PURE__ */
|
|
46
|
+
/* @__PURE__ */ l("div", {
|
|
47
47
|
className: "grid gap-4 md:grid-cols-3",
|
|
48
48
|
children: [
|
|
49
|
-
/* @__PURE__ */
|
|
49
|
+
/* @__PURE__ */ c(f, { children: /* @__PURE__ */ l(p, {
|
|
50
50
|
className: "pt-4",
|
|
51
|
-
children: [/* @__PURE__ */
|
|
51
|
+
children: [/* @__PURE__ */ l("div", {
|
|
52
52
|
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
53
|
-
children: [/* @__PURE__ */
|
|
54
|
-
}), /* @__PURE__ */
|
|
53
|
+
children: [/* @__PURE__ */ c(a, { className: "h-4 w-4" }), "Located Assets"]
|
|
54
|
+
}), /* @__PURE__ */ c("p", {
|
|
55
55
|
className: "text-2xl font-bold mt-1",
|
|
56
56
|
children: E
|
|
57
57
|
})]
|
|
58
58
|
}) }),
|
|
59
|
-
/* @__PURE__ */
|
|
59
|
+
/* @__PURE__ */ c(f, { children: /* @__PURE__ */ l(p, {
|
|
60
60
|
className: "pt-4",
|
|
61
|
-
children: [/* @__PURE__ */
|
|
61
|
+
children: [/* @__PURE__ */ l("div", {
|
|
62
62
|
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
63
|
-
children: [/* @__PURE__ */
|
|
64
|
-
}), /* @__PURE__ */
|
|
63
|
+
children: [/* @__PURE__ */ c(n, { className: "h-4 w-4" }), "Locations"]
|
|
64
|
+
}), /* @__PURE__ */ c("p", {
|
|
65
65
|
className: "text-2xl font-bold mt-1",
|
|
66
66
|
children: O
|
|
67
67
|
})]
|
|
68
68
|
}) }),
|
|
69
|
-
/* @__PURE__ */
|
|
69
|
+
/* @__PURE__ */ c(f, { children: /* @__PURE__ */ l(p, {
|
|
70
70
|
className: "pt-4",
|
|
71
|
-
children: [/* @__PURE__ */
|
|
71
|
+
children: [/* @__PURE__ */ l("div", {
|
|
72
72
|
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
73
|
-
children: [/* @__PURE__ */
|
|
74
|
-
}), /* @__PURE__ */
|
|
73
|
+
children: [/* @__PURE__ */ c(r, { className: "h-4 w-4" }), "Unlocated"]
|
|
74
|
+
}), /* @__PURE__ */ c("p", {
|
|
75
75
|
className: "text-2xl font-bold mt-1",
|
|
76
76
|
children: D
|
|
77
77
|
})]
|
|
78
78
|
}) })
|
|
79
79
|
]
|
|
80
80
|
}),
|
|
81
|
-
/* @__PURE__ */
|
|
82
|
-
/* @__PURE__ */
|
|
81
|
+
/* @__PURE__ */ c(x, { children: "Know where your assets physically are. See them grouped by location, so you can locate equipment fast, spot assets that still have no recorded location, and confirm items are where they should be." }),
|
|
82
|
+
/* @__PURE__ */ l("div", {
|
|
83
83
|
className: "grid gap-6 lg:grid-cols-5",
|
|
84
|
-
children: [/* @__PURE__ */
|
|
84
|
+
children: [/* @__PURE__ */ l(_, {
|
|
85
85
|
className: "lg:col-span-3",
|
|
86
|
-
children: [/* @__PURE__ */
|
|
86
|
+
children: [/* @__PURE__ */ l(h, {
|
|
87
87
|
className: "px-0 pt-0",
|
|
88
|
-
children: [/* @__PURE__ */
|
|
89
|
-
}), /* @__PURE__ */
|
|
88
|
+
children: [/* @__PURE__ */ c(g, { children: "Location Map" }), /* @__PURE__ */ c(m, { children: "Geographic distribution of tracked assets" })]
|
|
89
|
+
}), /* @__PURE__ */ c(p, {
|
|
90
90
|
className: "px-0 pb-0",
|
|
91
|
-
children: /* @__PURE__ */
|
|
91
|
+
children: /* @__PURE__ */ c("div", {
|
|
92
92
|
className: "bg-bg-sunken rounded-lg h-80 flex items-center justify-center border-2 border-dashed",
|
|
93
|
-
children: /* @__PURE__ */
|
|
93
|
+
children: /* @__PURE__ */ l("div", {
|
|
94
94
|
className: "text-center",
|
|
95
95
|
children: [
|
|
96
|
-
/* @__PURE__ */
|
|
97
|
-
/* @__PURE__ */
|
|
96
|
+
/* @__PURE__ */ c(i, { className: "h-12 w-12 text-text-secondary mx-auto mb-2" }),
|
|
97
|
+
/* @__PURE__ */ c("p", {
|
|
98
98
|
className: "text-text-secondary",
|
|
99
99
|
children: "Interactive map view"
|
|
100
100
|
}),
|
|
101
|
-
/* @__PURE__ */
|
|
101
|
+
/* @__PURE__ */ c("p", {
|
|
102
102
|
className: "text-xs text-text-secondary mt-1",
|
|
103
103
|
children: "Map integration would render here"
|
|
104
104
|
})
|
|
@@ -106,53 +106,53 @@ function w() {
|
|
|
106
106
|
})
|
|
107
107
|
})
|
|
108
108
|
})]
|
|
109
|
-
}), /* @__PURE__ */
|
|
109
|
+
}), /* @__PURE__ */ l(f, {
|
|
110
110
|
className: "lg:col-span-2",
|
|
111
|
-
children: [/* @__PURE__ */
|
|
111
|
+
children: [/* @__PURE__ */ l(h, { children: [/* @__PURE__ */ c(g, { children: "Asset Locations" }), /* @__PURE__ */ l("div", {
|
|
112
112
|
className: "relative mt-2",
|
|
113
|
-
children: [/* @__PURE__ */
|
|
113
|
+
children: [/* @__PURE__ */ c(s, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ c(b, {
|
|
114
114
|
placeholder: "Search assets...",
|
|
115
115
|
className: "pl-9"
|
|
116
116
|
})]
|
|
117
|
-
})] }), /* @__PURE__ */
|
|
117
|
+
})] }), /* @__PURE__ */ c(p, { children: w.length === 0 ? /* @__PURE__ */ c(y, {
|
|
118
118
|
illustration: "empty-generic",
|
|
119
119
|
title: "No assets to track",
|
|
120
120
|
description: "Add an asset and give it a location to see it grouped here."
|
|
121
|
-
}) : /* @__PURE__ */
|
|
121
|
+
}) : /* @__PURE__ */ c("div", {
|
|
122
122
|
className: "space-y-4",
|
|
123
|
-
children: Object.entries(T).map(([e, t]) => /* @__PURE__ */
|
|
123
|
+
children: Object.entries(T).map(([e, t]) => /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ l("h4", {
|
|
124
124
|
className: "text-sm font-medium flex items-center gap-2 mb-2",
|
|
125
125
|
children: [
|
|
126
|
-
/* @__PURE__ */
|
|
126
|
+
/* @__PURE__ */ c(n, { className: "h-3.5 w-3.5" }),
|
|
127
127
|
e,
|
|
128
|
-
/* @__PURE__ */
|
|
128
|
+
/* @__PURE__ */ c(u, {
|
|
129
129
|
variant: "secondary",
|
|
130
130
|
className: "text-[10px]",
|
|
131
131
|
children: t.length
|
|
132
132
|
})
|
|
133
133
|
]
|
|
134
|
-
}), /* @__PURE__ */
|
|
134
|
+
}), /* @__PURE__ */ c("div", {
|
|
135
135
|
className: "space-y-2 ml-5",
|
|
136
|
-
children: t.map((e) => /* @__PURE__ */
|
|
136
|
+
children: t.map((e) => /* @__PURE__ */ l("div", {
|
|
137
137
|
className: "flex items-start gap-3 rounded border p-2.5",
|
|
138
|
-
children: [/* @__PURE__ */
|
|
138
|
+
children: [/* @__PURE__ */ c(i, { className: "h-3.5 w-3.5 mt-0.5 text-text-secondary shrink-0" }), /* @__PURE__ */ l("div", {
|
|
139
139
|
className: "flex-1 min-w-0",
|
|
140
140
|
children: [
|
|
141
|
-
/* @__PURE__ */
|
|
141
|
+
/* @__PURE__ */ c("p", {
|
|
142
142
|
className: "text-sm font-medium truncate",
|
|
143
143
|
children: e.name
|
|
144
144
|
}),
|
|
145
|
-
/* @__PURE__ */
|
|
145
|
+
/* @__PURE__ */ c("p", {
|
|
146
146
|
className: "text-xs text-text-secondary",
|
|
147
147
|
children: e.assetTag
|
|
148
148
|
}),
|
|
149
|
-
/* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ l("div", {
|
|
150
150
|
className: "flex items-center gap-2 mt-1",
|
|
151
|
-
children: [/* @__PURE__ */
|
|
151
|
+
children: [/* @__PURE__ */ c(u, {
|
|
152
152
|
variant: S[e.status] || "outline",
|
|
153
153
|
className: "text-[10px]",
|
|
154
154
|
children: e.status.replace("_", " ")
|
|
155
|
-
}), e.updatedAt ? /* @__PURE__ */
|
|
155
|
+
}), e.updatedAt ? /* @__PURE__ */ l("span", {
|
|
156
156
|
className: "text-[10px] text-text-secondary",
|
|
157
157
|
children: ["Updated: ", new Date(e.updatedAt).toLocaleDateString()]
|
|
158
158
|
}) : null]
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Network as e } from "lucide-react";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { gql as t } from "@apollo/client";
|
|
3
|
+
import { useQuery as n } from "@apollo/client/react";
|
|
4
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
|
+
import { GlassCard as a, GradientText as o, IllustratedEmptyState as s, PagePurpose as c } from "@burdenoff/fe-libs/ui";
|
|
6
6
|
//#region src/assethandler/pages/CmdbBrowserPage.tsx
|
|
7
|
-
var l =
|
|
7
|
+
var l = t`
|
|
8
8
|
query AssetHandlerConfigurationItems {
|
|
9
9
|
configurationItems {
|
|
10
10
|
id
|
|
@@ -19,54 +19,54 @@ var l = s`
|
|
|
19
19
|
}
|
|
20
20
|
`;
|
|
21
21
|
function u() {
|
|
22
|
-
let { data:
|
|
23
|
-
return /* @__PURE__ */
|
|
22
|
+
let { data: t, loading: u } = n(l, { fetchPolicy: "cache-and-network" }), d = t?.configurationItems ?? [];
|
|
23
|
+
return /* @__PURE__ */ i("div", {
|
|
24
24
|
className: "space-y-4 p-4",
|
|
25
25
|
children: [
|
|
26
|
-
/* @__PURE__ */
|
|
26
|
+
/* @__PURE__ */ i("h1", {
|
|
27
27
|
className: "flex items-center gap-2 text-2xl font-semibold",
|
|
28
28
|
children: [
|
|
29
|
-
/* @__PURE__ */
|
|
29
|
+
/* @__PURE__ */ r(e, { className: "h-6 w-6" }),
|
|
30
30
|
" ",
|
|
31
|
-
/* @__PURE__ */
|
|
31
|
+
/* @__PURE__ */ r(o, { children: "CMDB Browser" })
|
|
32
32
|
]
|
|
33
33
|
}),
|
|
34
|
-
/* @__PURE__ */
|
|
35
|
-
/* @__PURE__ */
|
|
34
|
+
/* @__PURE__ */ r(c, { children: "Your configuration management database (CMDB): a living map of every configuration item — servers, services, network gear and how they depend on each other. Use it to understand blast radius before a change, trace what an incident touches, and keep asset relationships accurate." }),
|
|
35
|
+
/* @__PURE__ */ i(a, {
|
|
36
36
|
treatment: "glass",
|
|
37
37
|
glow: !0,
|
|
38
38
|
className: "overflow-hidden border-border-seam",
|
|
39
39
|
children: [
|
|
40
|
-
/* @__PURE__ */
|
|
40
|
+
/* @__PURE__ */ i("div", {
|
|
41
41
|
className: "grid grid-cols-5 gap-3 border-b px-4 py-3 text-xs font-semibold uppercase tracking-wide text-text-secondary",
|
|
42
42
|
children: [
|
|
43
|
-
/* @__PURE__ */
|
|
44
|
-
/* @__PURE__ */
|
|
45
|
-
/* @__PURE__ */
|
|
46
|
-
/* @__PURE__ */
|
|
47
|
-
/* @__PURE__ */
|
|
43
|
+
/* @__PURE__ */ r("span", { children: "CI Number" }),
|
|
44
|
+
/* @__PURE__ */ r("span", { children: "Name" }),
|
|
45
|
+
/* @__PURE__ */ r("span", { children: "Type" }),
|
|
46
|
+
/* @__PURE__ */ r("span", { children: "Status" }),
|
|
47
|
+
/* @__PURE__ */ r("span", { children: "Environment" })
|
|
48
48
|
]
|
|
49
49
|
}),
|
|
50
|
-
u && d.length === 0 ? /* @__PURE__ */
|
|
50
|
+
u && d.length === 0 ? /* @__PURE__ */ r("div", {
|
|
51
51
|
className: "space-y-2 px-4 py-4",
|
|
52
|
-
children: Array.from({ length: 4 }).map((e, t) => /* @__PURE__ */
|
|
52
|
+
children: Array.from({ length: 4 }).map((e, t) => /* @__PURE__ */ r("div", { className: "h-8 rounded-md bg-bg-sunken motion-safe:animate-vc-shimmer" }, t))
|
|
53
53
|
}) : null,
|
|
54
|
-
!u && d.length === 0 ? /* @__PURE__ */
|
|
54
|
+
!u && d.length === 0 ? /* @__PURE__ */ r(s, {
|
|
55
55
|
illustration: "empty-data",
|
|
56
56
|
title: "No configuration items found",
|
|
57
57
|
description: "Configuration items will appear here once discovered."
|
|
58
58
|
}) : null,
|
|
59
|
-
d.map((e) => /* @__PURE__ */
|
|
59
|
+
d.map((e) => /* @__PURE__ */ i("div", {
|
|
60
60
|
className: "grid grid-cols-5 gap-3 border-b px-4 py-3 text-sm last:border-b-0",
|
|
61
61
|
children: [
|
|
62
|
-
/* @__PURE__ */
|
|
62
|
+
/* @__PURE__ */ r("span", {
|
|
63
63
|
className: "font-medium",
|
|
64
64
|
children: e.ciNumber
|
|
65
65
|
}),
|
|
66
|
-
/* @__PURE__ */
|
|
67
|
-
/* @__PURE__ */
|
|
68
|
-
/* @__PURE__ */
|
|
69
|
-
/* @__PURE__ */
|
|
66
|
+
/* @__PURE__ */ r("span", { children: e.name }),
|
|
67
|
+
/* @__PURE__ */ r("span", { children: e.ciType }),
|
|
68
|
+
/* @__PURE__ */ r("span", { children: e.status }),
|
|
69
|
+
/* @__PURE__ */ r("span", { children: e.environment ?? "n/a" })
|
|
70
70
|
]
|
|
71
71
|
}, e.id))
|
|
72
72
|
]
|