@burdenoff/microfe-assethandler 2026.703.1 → 2026.703.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assethandler/pages/AiPredictionsPage.js.map +1 -1
- package/dist/assethandler/pages/AnalyticsPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCategoriesPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetCheckInOutPage.js.map +1 -1
- package/dist/assethandler/pages/AssetsAssetTrackingPage.js.map +1 -1
- package/dist/assethandler/pages/DigitalTwinPage.js.map +1 -1
- package/dist/assethandler/pages/DiscoveryJobsPage.js.map +1 -1
- package/dist/assethandler/pages/EsgDashboardPage.js.map +1 -1
- package/dist/assethandler/pages/FinanceBudgetDetailPage.js.map +1 -1
- package/dist/assethandler/pages/FinanceFinanceHubPage.js.map +1 -1
- package/dist/assethandler/pages/ItilChangeManagementPage.js.map +1 -1
- package/dist/assethandler/pages/ItilIncidentManagementPage.js.map +1 -1
- package/dist/assethandler/pages/ItilItilhubPage.js +1 -2
- package/dist/assethandler/pages/ItilItilhubPage.js.map +1 -1
- package/dist/assethandler/pages/ItilProblemManagementPage.js.map +1 -1
- package/dist/assethandler/pages/KnowledgeBasePage.js.map +1 -1
- package/dist/assethandler/pages/MaintenanceMaintenanceCalendarPage.js.map +1 -1
- package/dist/assethandler/pages/MaintenanceMaintenanceSchedulerPage.js.map +1 -1
- package/dist/assethandler/pages/OperationsMaintenanceDetailPage.js.map +1 -1
- package/dist/assethandler/pages/OperationsOperationsHubPage.js.map +1 -1
- package/dist/assethandler/pages/OperationsWorkOrderDetailPage.js.map +1 -1
- package/dist/assethandler/pages/PortfolioPortfolioOverviewPage.js.map +1 -1
- package/dist/assethandler/pages/ProvenancePage.js.map +1 -1
- package/dist/assethandler/pages/SecuritySecurityHubPage.js.map +1 -1
- package/dist/assethandler/pages/TransactionsTransactionDetailPage.js.map +1 -1
- package/dist/assethandler/store/assethandlerStore.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FinanceBudgetDetailPage.js","names":[],"sources":["../../../src/assethandler/pages/FinanceBudgetDetailPage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowLeft, Edit } from 'lucide-react';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nexport function FinanceBudgetDetailPage() {\n const navigate = useNavigate();\n const { budgetId } = useParams<{ budgetId: string }>();\n const { budgets, transactions } = useAssetHandlerStore();\n const budget = budgets.find((item) => item.id === budgetId) ?? budgets[0];\n\n if (!budget)\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Budget not found\"\n description=\"This budget may have been archived or removed. Return to the finance hub to find it.\"\n action={\n <Button size=\"sm\" onClick={() => navigate('/finance/finance-hub')}>\n Back to finance\n </Button>\n }\n />\n </div>\n );\n\n const relatedTxns = transactions.filter((t) => t.category === budget.category);\n const utilizationPct = Math.round((budget.spent / budget.allocated) * 100);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => navigate('/finance/finance-hub')}>\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <div className=\"flex items-center gap-3\">\n <h1 className=\"text-2xl font-bold\">\n <GradientText>{budget.name}</GradientText>\n </h1>\n <Badge\n variant={\n budget.status === 'over_budget'\n ? 'destructive'\n : budget.status === 'under_budget'\n ? 'secondary'\n : 'default'\n }\n >\n {budget.status.replace('_', ' ')}\n </Badge>\n </div>\n <p className=\"text-sm text-text-secondary mt-1\">\n {budget.department} · {budget.period}\n </p>\n </div>\n </div>\n <Button size=\"sm\">\n <Edit className=\"mr-2 h-4 w-4\" />\n Edit Budget\n </Button>\n </div>\n\n <PagePurpose>\n Drill into a single budget to see exactly how it is being consumed: what was allocated,\n what has been spent, what remains, and every transaction charged against it. Use it to catch\n overruns early and decide whether to reallocate, cut spend or top up.\n </PagePurpose>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Allocated</p>\n <p className=\"text-2xl font-bold tabular-nums\">${budget.allocated.toLocaleString()}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Spent</p>\n <p className=\"text-2xl font-bold tabular-nums\">${budget.spent.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">{utilizationPct}% utilized</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Remaining</p>\n <p\n className={`text-2xl font-bold ${budget.remaining < 0 ? 'text-status-error-text' : 'text-status-success-text'}`}\n >\n ${budget.remaining.toLocaleString()}\n </p>\n </CardContent>\n </Card>\n </div>\n\n <EmphasisPanel>\n <CardHeader className=\"px-0 pt-0\">\n <CardTitle>Budget Utilization</CardTitle>\n </CardHeader>\n <CardContent className=\"px-0 pb-0\">\n <div className=\"h-4 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className={`h-full rounded-full transition-all ${budget.status === 'over_budget' ? 'bg-status-error-bg' : 'bg-action-primary-bg'}`}\n style={{ width: `${Math.min(utilizationPct, 100)}%` }}\n />\n </div>\n <p className=\"text-sm text-text-secondary mt-2\">\n {utilizationPct}% of ${budget.allocated.toLocaleString()} allocated budget consumed\n </p>\n </CardContent>\n </EmphasisPanel>\n\n <Card>\n <CardHeader>\n <CardTitle>Related Transactions</CardTitle>\n <CardDescription>Transactions in {budget.category} category</CardDescription>\n </CardHeader>\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Description</th>\n <th className=\"text-right p-3 font-medium\">Amount</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Date</th>\n </tr>\n </thead>\n <tbody>\n {relatedTxns.map((txn) => (\n <tr key={txn.id} className=\"border-b hover:bg-bg-sunken/50\">\n <td className=\"p-3 font-mono text-xs\">{txn.id}</td>\n <td className=\"p-3 truncate max-w-xs\">{txn.description}</td>\n <td className=\"p-3 text-right font-medium\">\n ${Math.abs(txn.amount).toLocaleString()}\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{txn.status}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{new Date(txn.date).toLocaleDateString()}</td>\n </tr>\n ))}\n </tbody>\n </table>\n {relatedTxns.length === 0 && (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No related transactions\"\n description={`No spend has been charged to the ${budget.category} category yet.`}\n />\n )}\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FinanceBudgetDetailPage.js","names":[],"sources":["../../../src/assethandler/pages/FinanceBudgetDetailPage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowLeft, Edit } from 'lucide-react';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nexport function FinanceBudgetDetailPage() {\n const navigate = useNavigate();\n const { budgetId } = useParams<{ budgetId: string }>();\n const { budgets, transactions } = useAssetHandlerStore();\n const budget = budgets.find((item) => item.id === budgetId) ?? budgets[0];\n\n if (!budget)\n return (\n <div className=\"p-6\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Budget not found\"\n description=\"This budget may have been archived or removed. Return to the finance hub to find it.\"\n action={\n <Button size=\"sm\" onClick={() => navigate('/finance/finance-hub')}>\n Back to finance\n </Button>\n }\n />\n </div>\n );\n\n const relatedTxns = transactions.filter((t) => t.category === budget.category);\n const utilizationPct = Math.round((budget.spent / budget.allocated) * 100);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => navigate('/finance/finance-hub')}>\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <div className=\"flex items-center gap-3\">\n <h1 className=\"text-2xl font-bold\">\n <GradientText>{budget.name}</GradientText>\n </h1>\n <Badge\n variant={\n budget.status === 'over_budget'\n ? 'destructive'\n : budget.status === 'under_budget'\n ? 'secondary'\n : 'default'\n }\n >\n {budget.status.replace('_', ' ')}\n </Badge>\n </div>\n <p className=\"text-sm text-text-secondary mt-1\">\n {budget.department} · {budget.period}\n </p>\n </div>\n </div>\n <Button size=\"sm\">\n <Edit className=\"mr-2 h-4 w-4\" />\n Edit Budget\n </Button>\n </div>\n\n <PagePurpose>\n Drill into a single budget to see exactly how it is being consumed: what was allocated, what\n has been spent, what remains, and every transaction charged against it. Use it to catch\n overruns early and decide whether to reallocate, cut spend or top up.\n </PagePurpose>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Allocated</p>\n <p className=\"text-2xl font-bold tabular-nums\">${budget.allocated.toLocaleString()}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Spent</p>\n <p className=\"text-2xl font-bold tabular-nums\">${budget.spent.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">{utilizationPct}% utilized</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Remaining</p>\n <p\n className={`text-2xl font-bold ${budget.remaining < 0 ? 'text-status-error-text' : 'text-status-success-text'}`}\n >\n ${budget.remaining.toLocaleString()}\n </p>\n </CardContent>\n </Card>\n </div>\n\n <EmphasisPanel>\n <CardHeader className=\"px-0 pt-0\">\n <CardTitle>Budget Utilization</CardTitle>\n </CardHeader>\n <CardContent className=\"px-0 pb-0\">\n <div className=\"h-4 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className={`h-full rounded-full transition-all ${budget.status === 'over_budget' ? 'bg-status-error-bg' : 'bg-action-primary-bg'}`}\n style={{ width: `${Math.min(utilizationPct, 100)}%` }}\n />\n </div>\n <p className=\"text-sm text-text-secondary mt-2\">\n {utilizationPct}% of ${budget.allocated.toLocaleString()} allocated budget consumed\n </p>\n </CardContent>\n </EmphasisPanel>\n\n <Card>\n <CardHeader>\n <CardTitle>Related Transactions</CardTitle>\n <CardDescription>Transactions in {budget.category} category</CardDescription>\n </CardHeader>\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Description</th>\n <th className=\"text-right p-3 font-medium\">Amount</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Date</th>\n </tr>\n </thead>\n <tbody>\n {relatedTxns.map((txn) => (\n <tr key={txn.id} className=\"border-b hover:bg-bg-sunken/50\">\n <td className=\"p-3 font-mono text-xs\">{txn.id}</td>\n <td className=\"p-3 truncate max-w-xs\">{txn.description}</td>\n <td className=\"p-3 text-right font-medium\">\n ${Math.abs(txn.amount).toLocaleString()}\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{txn.status}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{new Date(txn.date).toLocaleDateString()}</td>\n </tr>\n ))}\n </tbody>\n </table>\n {relatedTxns.length === 0 && (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No related transactions\"\n description={`No spend has been charged to the ${budget.category} category yet.`}\n />\n )}\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FinanceFinanceHubPage.js","names":[],"sources":["../../../src/assethandler/pages/FinanceFinanceHubPage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n GradientText,\n CTAOverflowMenu,\n EmphasisPanel,\n PagePurpose,\n NextSteps,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport {\n DollarSign,\n TrendingDown,\n Receipt,\n CreditCard,\n Download,\n} from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nexport function FinanceFinanceHubPage() {\n const navigate = useNavigate();\n const { transactions, budgets, invoices } = useAssetHandlerStore();\n\n const totalSpend = transactions.filter((t) => t.amount > 0).reduce((s, t) => s + t.amount, 0);\n const pendingTxns = transactions.filter((t) => t.status === 'pending');\n const overBudget = budgets.filter((b) => b.status === 'over_budget');\n const overdueInvoices = invoices.filter((i) => i.status === 'overdue');\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>Finance Hub</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Financial management for IT assets</p>\n </div>\n <CTAOverflowMenu\n primary={{ label: 'New Transaction', onSelect: () => {} }}\n actions={[\n { label: 'Export', onSelect: () => {}, icon: <Download className=\"h-4 w-4\" /> },\n ]}\n />\n </div>\n\n <PagePurpose>\n The money side of your asset estate: track spend, keep departmental budgets on course, and\n stay on top of vendor invoices. Use this hub to spot over-budget areas and overdue invoices\n early — so asset costs stay predictable and nothing slips past its due date.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"assethandler-finance-hub\"\n steps={[\n {\n id: 'transactions',\n label: 'Review recent transactions',\n description: 'Check spend and approve anything still pending.',\n onClick: () => navigate('/transactions/transaction-list'),\n },\n {\n id: 'budgets',\n label: 'Review reporting dashboard',\n description: 'See budget health and spend trends across departments.',\n onClick: () => navigate('/reports/reports-dashboard'),\n },\n {\n id: 'reports',\n label: 'Build a finance report',\n description: 'Turn spend and budget data into a shareable report.',\n onClick: () => navigate('/reports/report-builder'),\n },\n ]}\n />\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <EmphasisPanel>\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <DollarSign className=\"h-4 w-4\" />\n Total Spend\n </div>\n <p className=\"text-2xl font-bold mt-1 tabular-nums\">${totalSpend.toLocaleString()}</p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <CreditCard className=\"h-4 w-4\" />\n Pending\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-info-text\">{pendingTxns.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <TrendingDown className=\"h-4 w-4\" />\n Over Budget\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-error-text\">{overBudget.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Receipt className=\"h-4 w-4\" />\n Overdue Invoices\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-warning-text\">\n {overdueInvoices.length}\n </p>\n </CardContent>\n </Card>\n </div>\n\n <Tabs defaultValue=\"transactions\">\n <TabsList>\n <TabsTrigger value=\"transactions\">Transactions</TabsTrigger>\n <TabsTrigger value=\"budgets\">Budgets</TabsTrigger>\n <TabsTrigger value=\"invoices\">Invoices</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"transactions\" className=\"mt-4\">\n {transactions.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No transactions yet\"\n description=\"Asset-related spend and reimbursements will appear here as they are recorded.\"\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Type</th>\n <th className=\"text-left p-3 font-medium\">Description</th>\n <th className=\"text-left p-3 font-medium\">Department</th>\n <th className=\"text-right p-3 font-medium\">Amount</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Date</th>\n </tr>\n </thead>\n <tbody>\n {transactions.map((txn) => (\n <tr key={txn.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{txn.id}</td>\n <td className=\"p-3 capitalize\">{txn.type}</td>\n <td className=\"p-3 truncate max-w-xs\">{txn.description}</td>\n <td className=\"p-3 text-xs\">{txn.department}</td>\n <td\n className={`p-3 text-right font-medium ${txn.amount < 0 ? 'text-status-error-text' : ''}`}\n >\n ${Math.abs(txn.amount).toLocaleString()}\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{txn.status}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{new Date(txn.date).toLocaleDateString()}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </TabsContent>\n\n <TabsContent value=\"budgets\" className=\"mt-4\">\n {budgets.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No budgets defined\"\n description=\"Create departmental budgets to track allocated vs. actual asset spend.\"\n />\n ) : (\n <div className=\"grid gap-4 md:grid-cols-2\">\n {budgets.map((budget) => (\n <Card key={budget.id}>\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">{budget.name}</CardTitle>\n <Badge\n variant={\n budget.status === 'over_budget'\n ? 'destructive'\n : budget.status === 'under_budget'\n ? 'secondary'\n : 'default'\n }\n >\n {budget.status.replace('_', ' ')}\n </Badge>\n </div>\n <CardDescription>\n {budget.department} · {budget.period}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-secondary\">Allocated</span>\n <span className=\"font-medium\">${budget.allocated.toLocaleString()}</span>\n </div>\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-secondary\">Spent</span>\n <span className=\"font-medium\">${budget.spent.toLocaleString()}</span>\n </div>\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-secondary\">Remaining</span>\n <span\n className={`font-medium ${budget.remaining < 0 ? 'text-status-error-text' : 'text-status-success-text'}`}\n >\n ${budget.remaining.toLocaleString()}\n </span>\n </div>\n <div className=\"h-2 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className={`h-full rounded-full ${budget.status === 'over_budget' ? 'bg-status-error-bg' : 'bg-action-primary-bg'}`}\n style={{\n width: `${Math.min((budget.spent / budget.allocated) * 100, 100)}%`,\n }}\n />\n </div>\n <p className=\"text-xs text-text-secondary text-right\">\n {Math.round((budget.spent / budget.allocated) * 100)}% utilized\n </p>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n </TabsContent>\n\n <TabsContent value=\"invoices\" className=\"mt-4\">\n {invoices.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-files\"\n title=\"No invoices\"\n description=\"Vendor invoices for asset purchases and services will be listed here.\"\n />\n ) : (\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\">Invoice #</th>\n <th className=\"text-left p-3 font-medium\">Vendor</th>\n <th className=\"text-right p-3 font-medium\">Amount</th>\n <th className=\"text-left p-3 font-medium\">Issue Date</th>\n <th className=\"text-left p-3 font-medium\">Due Date</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n </tr>\n </thead>\n <tbody>\n {invoices.map((inv) => (\n <tr key={inv.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{inv.number}</td>\n <td className=\"p-3\">{inv.vendor}</td>\n <td className=\"p-3 text-right font-medium\">\n ${inv.amount.toLocaleString()}\n </td>\n <td className=\"p-3 text-xs\">{inv.issueDate}</td>\n <td className=\"p-3 text-xs\">{inv.dueDate}</td>\n <td className=\"p-3\">\n <Badge\n variant={\n inv.status === 'overdue'\n ? 'destructive'\n : inv.status === 'paid'\n ? 'default'\n : 'outline'\n }\n >\n {inv.status}\n </Badge>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FinanceFinanceHubPage.js","names":[],"sources":["../../../src/assethandler/pages/FinanceFinanceHubPage.tsx"],"sourcesContent":["import {\n Badge,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n GradientText,\n CTAOverflowMenu,\n EmphasisPanel,\n PagePurpose,\n NextSteps,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { DollarSign, TrendingDown, Receipt, CreditCard, Download } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nexport function FinanceFinanceHubPage() {\n const navigate = useNavigate();\n const { transactions, budgets, invoices } = useAssetHandlerStore();\n\n const totalSpend = transactions.filter((t) => t.amount > 0).reduce((s, t) => s + t.amount, 0);\n const pendingTxns = transactions.filter((t) => t.status === 'pending');\n const overBudget = budgets.filter((b) => b.status === 'over_budget');\n const overdueInvoices = invoices.filter((i) => i.status === 'overdue');\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>Finance Hub</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">Financial management for IT assets</p>\n </div>\n <CTAOverflowMenu\n primary={{ label: 'New Transaction', onSelect: () => {} }}\n actions={[\n { label: 'Export', onSelect: () => {}, icon: <Download className=\"h-4 w-4\" /> },\n ]}\n />\n </div>\n\n <PagePurpose>\n The money side of your asset estate: track spend, keep departmental budgets on course, and\n stay on top of vendor invoices. Use this hub to spot over-budget areas and overdue invoices\n early — so asset costs stay predictable and nothing slips past its due date.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"assethandler-finance-hub\"\n steps={[\n {\n id: 'transactions',\n label: 'Review recent transactions',\n description: 'Check spend and approve anything still pending.',\n onClick: () => navigate('/transactions/transaction-list'),\n },\n {\n id: 'budgets',\n label: 'Review reporting dashboard',\n description: 'See budget health and spend trends across departments.',\n onClick: () => navigate('/reports/reports-dashboard'),\n },\n {\n id: 'reports',\n label: 'Build a finance report',\n description: 'Turn spend and budget data into a shareable report.',\n onClick: () => navigate('/reports/report-builder'),\n },\n ]}\n />\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <EmphasisPanel>\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <DollarSign className=\"h-4 w-4\" />\n Total Spend\n </div>\n <p className=\"text-2xl font-bold mt-1 tabular-nums\">${totalSpend.toLocaleString()}</p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <CreditCard className=\"h-4 w-4\" />\n Pending\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-info-text\">{pendingTxns.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <TrendingDown className=\"h-4 w-4\" />\n Over Budget\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-error-text\">{overBudget.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Receipt className=\"h-4 w-4\" />\n Overdue Invoices\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-warning-text\">\n {overdueInvoices.length}\n </p>\n </CardContent>\n </Card>\n </div>\n\n <Tabs defaultValue=\"transactions\">\n <TabsList>\n <TabsTrigger value=\"transactions\">Transactions</TabsTrigger>\n <TabsTrigger value=\"budgets\">Budgets</TabsTrigger>\n <TabsTrigger value=\"invoices\">Invoices</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"transactions\" className=\"mt-4\">\n {transactions.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No transactions yet\"\n description=\"Asset-related spend and reimbursements will appear here as they are recorded.\"\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Type</th>\n <th className=\"text-left p-3 font-medium\">Description</th>\n <th className=\"text-left p-3 font-medium\">Department</th>\n <th className=\"text-right p-3 font-medium\">Amount</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Date</th>\n </tr>\n </thead>\n <tbody>\n {transactions.map((txn) => (\n <tr key={txn.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{txn.id}</td>\n <td className=\"p-3 capitalize\">{txn.type}</td>\n <td className=\"p-3 truncate max-w-xs\">{txn.description}</td>\n <td className=\"p-3 text-xs\">{txn.department}</td>\n <td\n className={`p-3 text-right font-medium ${txn.amount < 0 ? 'text-status-error-text' : ''}`}\n >\n ${Math.abs(txn.amount).toLocaleString()}\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{txn.status}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{new Date(txn.date).toLocaleDateString()}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </TabsContent>\n\n <TabsContent value=\"budgets\" className=\"mt-4\">\n {budgets.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No budgets defined\"\n description=\"Create departmental budgets to track allocated vs. actual asset spend.\"\n />\n ) : (\n <div className=\"grid gap-4 md:grid-cols-2\">\n {budgets.map((budget) => (\n <Card key={budget.id}>\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">{budget.name}</CardTitle>\n <Badge\n variant={\n budget.status === 'over_budget'\n ? 'destructive'\n : budget.status === 'under_budget'\n ? 'secondary'\n : 'default'\n }\n >\n {budget.status.replace('_', ' ')}\n </Badge>\n </div>\n <CardDescription>\n {budget.department} · {budget.period}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-secondary\">Allocated</span>\n <span className=\"font-medium\">${budget.allocated.toLocaleString()}</span>\n </div>\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-secondary\">Spent</span>\n <span className=\"font-medium\">${budget.spent.toLocaleString()}</span>\n </div>\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-text-secondary\">Remaining</span>\n <span\n className={`font-medium ${budget.remaining < 0 ? 'text-status-error-text' : 'text-status-success-text'}`}\n >\n ${budget.remaining.toLocaleString()}\n </span>\n </div>\n <div className=\"h-2 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className={`h-full rounded-full ${budget.status === 'over_budget' ? 'bg-status-error-bg' : 'bg-action-primary-bg'}`}\n style={{\n width: `${Math.min((budget.spent / budget.allocated) * 100, 100)}%`,\n }}\n />\n </div>\n <p className=\"text-xs text-text-secondary text-right\">\n {Math.round((budget.spent / budget.allocated) * 100)}% utilized\n </p>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n )}\n </TabsContent>\n\n <TabsContent value=\"invoices\" className=\"mt-4\">\n {invoices.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-files\"\n title=\"No invoices\"\n description=\"Vendor invoices for asset purchases and services will be listed here.\"\n />\n ) : (\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\">Invoice #</th>\n <th className=\"text-left p-3 font-medium\">Vendor</th>\n <th className=\"text-right p-3 font-medium\">Amount</th>\n <th className=\"text-left p-3 font-medium\">Issue Date</th>\n <th className=\"text-left p-3 font-medium\">Due Date</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n </tr>\n </thead>\n <tbody>\n {invoices.map((inv) => (\n <tr key={inv.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{inv.number}</td>\n <td className=\"p-3\">{inv.vendor}</td>\n <td className=\"p-3 text-right font-medium\">\n ${inv.amount.toLocaleString()}\n </td>\n <td className=\"p-3 text-xs\">{inv.issueDate}</td>\n <td className=\"p-3 text-xs\">{inv.dueDate}</td>\n <td className=\"p-3\">\n <Badge\n variant={\n inv.status === 'overdue'\n ? 'destructive'\n : inv.status === 'paid'\n ? 'default'\n : 'outline'\n }\n >\n {inv.status}\n </Badge>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ItilChangeManagementPage.js","names":[],"sources":["../../../src/assethandler/pages/ItilChangeManagementPage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { Plus } from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nconst riskColors: Record<string, 'destructive' | 'default' | 'secondary' | 'outline'> = {\n critical: 'destructive',\n high: 'destructive',\n medium: 'default',\n low: 'secondary',\n};\n\nexport function ItilChangeManagementPage() {\n const { changeRequests } = useAssetHandlerStore();\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>Change Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{changeRequests.length} change requests</p>\n </div>\n <Button size=\"sm\">\n <Plus className=\"mr-2 h-4 w-4\" />\n New Change Request\n </Button>\n </div>\n\n <PagePurpose>\n Plan and govern every change to your assets and services so nothing breaks unexpectedly.\n Capture the change, assess its risk, route it for approval, and schedule it for a safe\n window — giving you a controlled, auditable trail of what changed, when and why.\n </PagePurpose>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <EmphasisPanel>\n <p className=\"text-sm text-text-secondary\">Total</p>\n <p className=\"text-2xl font-bold tabular-nums\">{changeRequests.length}</p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Approved</p>\n <p className=\"text-2xl font-bold text-status-success-text\">\n {changeRequests.filter((c) => c.status === 'approved').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Submitted</p>\n <p className=\"text-2xl font-bold text-status-info-text\">\n {changeRequests.filter((c) => c.status === 'submitted').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Completed</p>\n <p className=\"text-2xl font-bold tabular-nums\">\n {changeRequests.filter((c) => c.status === 'completed').length}\n </p>\n </CardContent>\n </Card>\n </div>\n\n {changeRequests.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No change requests\"\n description=\"Raise a change request to plan and risk-assess updates to your assets.\"\n />\n ) : (\n
|
|
1
|
+
{"version":3,"file":"ItilChangeManagementPage.js","names":[],"sources":["../../../src/assethandler/pages/ItilChangeManagementPage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { Plus } from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nconst riskColors: Record<string, 'destructive' | 'default' | 'secondary' | 'outline'> = {\n critical: 'destructive',\n high: 'destructive',\n medium: 'default',\n low: 'secondary',\n};\n\nexport function ItilChangeManagementPage() {\n const { changeRequests } = useAssetHandlerStore();\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>Change Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{changeRequests.length} change requests</p>\n </div>\n <Button size=\"sm\">\n <Plus className=\"mr-2 h-4 w-4\" />\n New Change Request\n </Button>\n </div>\n\n <PagePurpose>\n Plan and govern every change to your assets and services so nothing breaks unexpectedly.\n Capture the change, assess its risk, route it for approval, and schedule it for a safe\n window — giving you a controlled, auditable trail of what changed, when and why.\n </PagePurpose>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <EmphasisPanel>\n <p className=\"text-sm text-text-secondary\">Total</p>\n <p className=\"text-2xl font-bold tabular-nums\">{changeRequests.length}</p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Approved</p>\n <p className=\"text-2xl font-bold text-status-success-text\">\n {changeRequests.filter((c) => c.status === 'approved').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Submitted</p>\n <p className=\"text-2xl font-bold text-status-info-text\">\n {changeRequests.filter((c) => c.status === 'submitted').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Completed</p>\n <p className=\"text-2xl font-bold tabular-nums\">\n {changeRequests.filter((c) => c.status === 'completed').length}\n </p>\n </CardContent>\n </Card>\n </div>\n\n {changeRequests.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No change requests\"\n description=\"Raise a change request to plan and risk-assess updates to your assets.\"\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Type</th>\n <th className=\"text-left p-3 font-medium\">Risk</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Requested By</th>\n <th className=\"text-left p-3 font-medium\">Scheduled</th>\n <th className=\"text-left p-3 font-medium\">Approvals</th>\n </tr>\n </thead>\n <tbody>\n {changeRequests.map((chg) => (\n <tr key={chg.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{chg.id}</td>\n <td className=\"p-3\">\n <p className=\"font-medium\">{chg.title}</p>\n <p className=\"text-xs text-text-secondary truncate max-w-xs\">\n {chg.description}\n </p>\n </td>\n <td className=\"p-3\">\n <Badge\n variant={chg.type === 'emergency' ? 'destructive' : 'outline'}\n className=\"capitalize\"\n >\n {chg.type}\n </Badge>\n </td>\n <td className=\"p-3\">\n <Badge variant={riskColors[chg.risk]}>{chg.risk}</Badge>\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{chg.status.replace('_', ' ')}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{chg.requestedBy}</td>\n <td className=\"p-3 text-xs\">\n {new Date(chg.scheduledStart).toLocaleDateString()}\n </td>\n <td className=\"p-3 text-xs\">\n {chg.approvals.length > 0\n ? chg.approvals.map((a) => a.status).join(', ')\n : 'Pending'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ItilIncidentManagementPage.js","names":[],"sources":["../../../src/assethandler/pages/ItilIncidentManagementPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { Plus, Search } from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nconst priorityColors: Record<string, 'destructive' | 'default' | 'secondary' | 'outline'> = {\n critical: 'destructive',\n high: 'destructive',\n medium: 'default',\n low: 'secondary',\n};\n\nexport function ItilIncidentManagementPage() {\n const { incidents } = useAssetHandlerStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [statusFilter, setStatusFilter] = useState('all');\n const [priorityFilter, setPriorityFilter] = useState('all');\n\n const filtered = useMemo(\n () =>\n incidents.filter((i) => {\n const matchSearch =\n searchQuery === '' ||\n i.title.toLowerCase().includes(searchQuery.toLowerCase()) ||\n i.id.toLowerCase().includes(searchQuery.toLowerCase());\n const matchStatus = statusFilter === 'all' || i.status === statusFilter;\n const matchPriority = priorityFilter === 'all' || i.priority === priorityFilter;\n return matchSearch && matchStatus && matchPriority;\n }),\n [incidents, searchQuery, statusFilter, priorityFilter]\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>Incident Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{incidents.length} total incidents</p>\n </div>\n <Button size=\"sm\">\n <Plus className=\"mr-2 h-4 w-4\" />\n New Incident\n </Button>\n </div>\n\n <PagePurpose>\n Track every service-disrupting incident from report to resolution. Filter by priority and\n status to focus on what hurts most, watch SLA timers, and make sure critical issues are\n assigned and moving — so outages get fixed fast and nothing breaches its commitment.\n </PagePurpose>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <EmphasisPanel>\n <p className=\"text-sm text-text-secondary\">Critical</p>\n <p className=\"text-2xl font-bold tabular-nums text-status-error-text\">\n {incidents.filter((i) => i.priority === 'critical').length}\n </p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">High</p>\n <p className=\"text-2xl font-bold text-status-warning-text\">\n {incidents.filter((i) => i.priority === 'high').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">In Progress</p>\n <p className=\"text-2xl font-bold tabular-nums\">\n {incidents.filter((i) => i.status === 'in_progress').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Resolved</p>\n <p className=\"text-2xl font-bold text-status-success-text\">\n {incidents.filter((i) => i.status === 'resolved').length}\n </p>\n </CardContent>\n </Card>\n </div>\n\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=\"Search incidents...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger className=\"w-[160px]\">\n <SelectValue placeholder=\"Status\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All Statuses</SelectItem>\n <SelectItem value=\"new\">New</SelectItem>\n <SelectItem value=\"in_progress\">In Progress</SelectItem>\n <SelectItem value=\"resolved\">Resolved</SelectItem>\n <SelectItem value=\"escalated\">Escalated</SelectItem>\n </SelectContent>\n </Select>\n <Select value={priorityFilter} onValueChange={setPriorityFilter}>\n <SelectTrigger className=\"w-[140px]\">\n <SelectValue placeholder=\"Priority\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All</SelectItem>\n <SelectItem value=\"critical\">Critical</SelectItem>\n <SelectItem value=\"high\">High</SelectItem>\n <SelectItem value=\"medium\">Medium</SelectItem>\n <SelectItem value=\"low\">Low</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </CardContent>\n </Card>\n\n {filtered.length === 0 ? (\n <IllustratedEmptyState\n illustration={\n searchQuery || statusFilter !== 'all' || priorityFilter !== 'all'\n ? 'empty-search'\n : 'empty-notifications'\n }\n title=\"No incidents to show\"\n description={\n searchQuery || statusFilter !== 'all' || priorityFilter !== 'all'\n ? 'No incidents match your filters — try clearing them.'\n : 'When incidents are reported they will be listed here for triage.'\n }\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Category</th>\n <th className=\"text-left p-3 font-medium\">Priority</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Assigned To</th>\n <th className=\"text-left p-3 font-medium\">Reported</th>\n <th className=\"text-left p-3 font-medium\">SLA</th>\n </tr>\n </thead>\n <tbody>\n {filtered.map((inc) => (\n <tr key={inc.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{inc.id}</td>\n <td className=\"p-3\">\n <p className=\"font-medium\">{inc.title}</p>\n <p className=\"text-xs text-text-secondary truncate max-w-xs\">\n {inc.description}\n </p>\n </td>\n <td className=\"p-3 text-xs\">{inc.category}</td>\n <td className=\"p-3\">\n <Badge variant={priorityColors[inc.priority]}>{inc.priority}</Badge>\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{inc.status.replace('_', ' ')}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{inc.assignedTo || 'Unassigned'}</td>\n <td className=\"p-3 text-xs\">{new Date(inc.createdAt).toLocaleDateString()}</td>\n <td className=\"p-3\">\n {inc.slaBreached ? (\n <Badge variant=\"destructive\">Breached</Badge>\n ) : (\n <Badge variant=\"secondary\">OK</Badge>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;AAoBA,IAAM,IAAsF;CAC1F,UAAU;CACV,MAAM;CACN,QAAQ;CACR,KAAK;CACN;AAED,SAAgB,IAA6B;CAC3C,IAAM,EAAE,iBAAc,GAAsB,EACtC,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAc,KAAmB,EAAS,MAAM,EACjD,CAAC,GAAgB,KAAqB,EAAS,MAAM,EAErD,IAAW,QAEb,EAAU,QAAQ,MAAM;EACtB,IAAM,IACJ,MAAgB,MAChB,EAAE,MAAM,aAAa,CAAC,SAAS,EAAY,aAAa,CAAC,IACzD,EAAE,GAAG,aAAa,CAAC,SAAS,EAAY,aAAa,CAAC,EAClD,IAAc,MAAiB,SAAS,EAAE,WAAW,GACrD,IAAgB,MAAmB,SAAS,EAAE,aAAa;AACjE,SAAO,KAAe,KAAe;GACrC,EACJ;EAAC;EAAW;EAAa;EAAc;EAAe,CACvD;AAED,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eACZ,kBAAC,GAAD,EAAA,UAAc,uBAAkC,CAAA;KAC7C,CAAA,EACL,kBAAC,KAAD;KAAG,WAAU;eAAb,CAA4C,EAAU,QAAO,mBAAoB;OAC7E,EAAA,CAAA,EACN,kBAAC,GAAD;KAAQ,MAAK;eAAb,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAAA,eAE1B;OACL;;GAEN,kBAAC,GAAD,EAAA,UAAa,0QAIC,CAAA;GAEd,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,KAAD;MAAG,WAAU;gBAA8B;MAAY,CAAA,EACvD,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAU,QAAQ,MAAM,EAAE,aAAa,WAAW,CAAC;MAClD,CAAA,CACU,EAAA,CAAA;KAChB,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,KAAD;OAAG,WAAU;iBAA8B;OAAQ,CAAA,EACnD,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAU,QAAQ,MAAM,EAAE,aAAa,OAAO,CAAC;OAC9C,CAAA,CACQ;SACT,CAAA;KACP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,KAAD;OAAG,WAAU;iBAA8B;OAAe,CAAA,EAC1D,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAU,QAAQ,MAAM,EAAE,WAAW,cAAc,CAAC;OACnD,CAAA,CACQ;SACT,CAAA;KACP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,KAAD;OAAG,WAAU;iBAA8B;OAAY,CAAA,EACvD,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAU,QAAQ,MAAM,EAAE,WAAW,WAAW,CAAC;OAChD,CAAA,CACQ;SACT,CAAA;KACH;;GAEN,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IAAa,WAAU;cACrB,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,wEAAyE,CAAA,EAC3F,kBAAC,GAAD;QACE,aAAY;QACZ,OAAO;QACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;QAC/C,WAAU;QACV,CAAA,CACE;;MACN,kBAAC,GAAD;OAAQ,OAAO;OAAc,eAAe;iBAA5C,CACE,kBAAC,GAAD;QAAe,WAAU;kBACvB,kBAAC,GAAD,EAAa,aAAY,UAAW,CAAA;QACtB,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA;QACE,kBAAC,GAAD;SAAY,OAAM;mBAAM;SAAyB,CAAA;QACjD,kBAAC,GAAD;SAAY,OAAM;mBAAM;SAAgB,CAAA;QACxC,kBAAC,GAAD;SAAY,OAAM;mBAAc;SAAwB,CAAA;QACxD,kBAAC,GAAD;SAAY,OAAM;mBAAW;SAAqB,CAAA;QAClD,kBAAC,GAAD;SAAY,OAAM;mBAAY;SAAsB,CAAA;QACtC,EAAA,CAAA,CACT;;MACT,kBAAC,GAAD;OAAQ,OAAO;OAAgB,eAAe;iBAA9C,CACE,kBAAC,GAAD;QAAe,WAAU;kBACvB,kBAAC,GAAD,EAAa,aAAY,YAAa,CAAA;QACxB,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA;QACE,kBAAC,GAAD;SAAY,OAAM;mBAAM;SAAgB,CAAA;QACxC,kBAAC,GAAD;SAAY,OAAM;mBAAW;SAAqB,CAAA;QAClD,kBAAC,GAAD;SAAY,OAAM;mBAAO;SAAiB,CAAA;QAC1C,kBAAC,GAAD;SAAY,OAAM;mBAAS;SAAmB,CAAA;QAC9C,kBAAC,GAAD;SAAY,OAAM;mBAAM;SAAgB,CAAA;QAC1B,EAAA,CAAA,CACT;;MACL;;IACM,CAAA,EACT,CAAA;GAEN,EAAS,WAAW,IACnB,kBAAC,GAAD;IACE,cACE,KAAe,MAAiB,SAAS,MAAmB,QACxD,iBACA;IAEN,OAAM;IACN,aACE,KAAe,MAAiB,SAAS,MAAmB,QACxD,yDACA;IAEN,CAAA,GAEJ,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IAAa,WAAU;cACrB,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,SAAD;MAAO,WAAU;gBAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;OAAI,WAAU;iBAAd;QACE,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAO,CAAA;QACjD,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAU,CAAA;QACpD,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAa,CAAA;QACvD,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAa,CAAA;QACvD,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAW,CAAA;QACrD,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAgB,CAAA;QAC1D,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAa,CAAA;QACvD,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAQ,CAAA;QAC/C;UACC,CAAA,EACR,kBAAC,SAAD,EAAA,UACG,EAAS,KAAK,MACb,kBAAC,MAAD;OAAiB,WAAU;iBAA3B;QACE,kBAAC,MAAD;SAAI,WAAU;mBAAyB,EAAI;SAAQ,CAAA;QACnD,kBAAC,MAAD;SAAI,WAAU;mBAAd,CACE,kBAAC,KAAD;UAAG,WAAU;oBAAe,EAAI;UAAU,CAAA,EAC1C,kBAAC,KAAD;UAAG,WAAU;oBACV,EAAI;UACH,CAAA,CACD;;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAe,EAAI;SAAc,CAAA;QAC/C,kBAAC,MAAD;SAAI,WAAU;mBACZ,kBAAC,GAAD;UAAO,SAAS,EAAe,EAAI;oBAAY,EAAI;UAAiB,CAAA;SACjE,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACZ,kBAAC,GAAD;UAAO,SAAQ;oBAAW,EAAI,OAAO,QAAQ,KAAK,IAAI;UAAS,CAAA;SAC5D,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAe,EAAI,cAAc;SAAkB,CAAA;QACjE,kBAAC,MAAD;SAAI,WAAU;mBAAe,IAAI,KAAK,EAAI,UAAU,CAAC,oBAAoB;SAAM,CAAA;QAC/E,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAI,cACH,kBAAC,GAAD;UAAO,SAAQ;oBAAc;UAAgB,CAAA,GAE7C,kBAAC,GAAD;UAAO,SAAQ;oBAAY;UAAU,CAAA;SAEpC,CAAA;QACF;SAxBI,EAAI,GAwBR,CACL,EACI,CAAA,CACF;;KACJ,CAAA;IACM,CAAA,EACT,CAAA;GAEH"}
|
|
1
|
+
{"version":3,"file":"ItilIncidentManagementPage.js","names":[],"sources":["../../../src/assethandler/pages/ItilIncidentManagementPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { Plus, Search } from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nconst priorityColors: Record<string, 'destructive' | 'default' | 'secondary' | 'outline'> = {\n critical: 'destructive',\n high: 'destructive',\n medium: 'default',\n low: 'secondary',\n};\n\nexport function ItilIncidentManagementPage() {\n const { incidents } = useAssetHandlerStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [statusFilter, setStatusFilter] = useState('all');\n const [priorityFilter, setPriorityFilter] = useState('all');\n\n const filtered = useMemo(\n () =>\n incidents.filter((i) => {\n const matchSearch =\n searchQuery === '' ||\n i.title.toLowerCase().includes(searchQuery.toLowerCase()) ||\n i.id.toLowerCase().includes(searchQuery.toLowerCase());\n const matchStatus = statusFilter === 'all' || i.status === statusFilter;\n const matchPriority = priorityFilter === 'all' || i.priority === priorityFilter;\n return matchSearch && matchStatus && matchPriority;\n }),\n [incidents, searchQuery, statusFilter, priorityFilter]\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>Incident Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{incidents.length} total incidents</p>\n </div>\n <Button size=\"sm\">\n <Plus className=\"mr-2 h-4 w-4\" />\n New Incident\n </Button>\n </div>\n\n <PagePurpose>\n Track every service-disrupting incident from report to resolution. Filter by priority and\n status to focus on what hurts most, watch SLA timers, and make sure critical issues are\n assigned and moving — so outages get fixed fast and nothing breaches its commitment.\n </PagePurpose>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <EmphasisPanel>\n <p className=\"text-sm text-text-secondary\">Critical</p>\n <p className=\"text-2xl font-bold tabular-nums text-status-error-text\">\n {incidents.filter((i) => i.priority === 'critical').length}\n </p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">High</p>\n <p className=\"text-2xl font-bold text-status-warning-text\">\n {incidents.filter((i) => i.priority === 'high').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">In Progress</p>\n <p className=\"text-2xl font-bold tabular-nums\">\n {incidents.filter((i) => i.status === 'in_progress').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Resolved</p>\n <p className=\"text-2xl font-bold text-status-success-text\">\n {incidents.filter((i) => i.status === 'resolved').length}\n </p>\n </CardContent>\n </Card>\n </div>\n\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=\"Search incidents...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <Select value={statusFilter} onValueChange={setStatusFilter}>\n <SelectTrigger className=\"w-[160px]\">\n <SelectValue placeholder=\"Status\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All Statuses</SelectItem>\n <SelectItem value=\"new\">New</SelectItem>\n <SelectItem value=\"in_progress\">In Progress</SelectItem>\n <SelectItem value=\"resolved\">Resolved</SelectItem>\n <SelectItem value=\"escalated\">Escalated</SelectItem>\n </SelectContent>\n </Select>\n <Select value={priorityFilter} onValueChange={setPriorityFilter}>\n <SelectTrigger className=\"w-[140px]\">\n <SelectValue placeholder=\"Priority\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All</SelectItem>\n <SelectItem value=\"critical\">Critical</SelectItem>\n <SelectItem value=\"high\">High</SelectItem>\n <SelectItem value=\"medium\">Medium</SelectItem>\n <SelectItem value=\"low\">Low</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </CardContent>\n </Card>\n\n {filtered.length === 0 ? (\n <IllustratedEmptyState\n illustration={\n searchQuery || statusFilter !== 'all' || priorityFilter !== 'all'\n ? 'empty-search'\n : 'empty-notifications'\n }\n title=\"No incidents to show\"\n description={\n searchQuery || statusFilter !== 'all' || priorityFilter !== 'all'\n ? 'No incidents match your filters — try clearing them.'\n : 'When incidents are reported they will be listed here for triage.'\n }\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Category</th>\n <th className=\"text-left p-3 font-medium\">Priority</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Assigned To</th>\n <th className=\"text-left p-3 font-medium\">Reported</th>\n <th className=\"text-left p-3 font-medium\">SLA</th>\n </tr>\n </thead>\n <tbody>\n {filtered.map((inc) => (\n <tr key={inc.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{inc.id}</td>\n <td className=\"p-3\">\n <p className=\"font-medium\">{inc.title}</p>\n <p className=\"text-xs text-text-secondary truncate max-w-xs\">\n {inc.description}\n </p>\n </td>\n <td className=\"p-3 text-xs\">{inc.category}</td>\n <td className=\"p-3\">\n <Badge variant={priorityColors[inc.priority]}>{inc.priority}</Badge>\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{inc.status.replace('_', ' ')}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{inc.assignedTo || 'Unassigned'}</td>\n <td className=\"p-3 text-xs\">\n {new Date(inc.createdAt).toLocaleDateString()}\n </td>\n <td className=\"p-3\">\n {inc.slaBreached ? (\n <Badge variant=\"destructive\">Breached</Badge>\n ) : (\n <Badge variant=\"secondary\">OK</Badge>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -34,8 +34,7 @@ function C() {
|
|
|
34
34
|
/* @__PURE__ */ b("strong", { children: "incidents" }),
|
|
35
35
|
", plan and approve ",
|
|
36
36
|
/* @__PURE__ */ b("strong", { children: "changes" }),
|
|
37
|
-
" safely, and run root-cause",
|
|
38
|
-
" ",
|
|
37
|
+
" safely, and run root-cause ",
|
|
39
38
|
/* @__PURE__ */ b("strong", { children: "problem" }),
|
|
40
39
|
" investigations — all tied back to the affected assets. Use this hub to see what is breaching SLA right now and where to act first."
|
|
41
40
|
] }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ItilItilhubPage.js","names":[],"sources":["../../../src/assethandler/pages/ItilItilhubPage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n NextSteps,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { AlertTriangle, GitPullRequest, Search, CheckCircle, XCircle } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nconst priorityColors: Record<string, 'destructive' | 'default' | 'secondary' | 'outline'> = {\n critical: 'destructive',\n high: 'destructive',\n medium: 'default',\n low: 'secondary',\n};\n\nexport function ItilItilhubPage() {\n const navigate = useNavigate();\n const { incidents, changeRequests, problems } = useAssetHandlerStore();\n\n const activeIncidents = incidents.filter((i) => i.status !== 'resolved' && i.status !== 'closed');\n const resolvedIncidents = incidents.filter(\n (i) => i.status === 'resolved' || i.status === 'closed'\n );\n const slaBreaches = incidents.filter((i) => i.slaBreached);\n const pendingChanges = changeRequests.filter(\n (c) => c.status !== 'completed' && c.status !== 'rejected'\n );\n const openProblems = problems.filter((p) => p.status !== 'resolved' && p.status !== 'closed');\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>ITIL Service Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Incident, Change, and Problem management hub\n </p>\n </div>\n <Button size=\"sm\">Create Ticket</Button>\n </div>\n\n <PagePurpose>\n Your single ITIL service-management desk: triage and resolve service-disrupting{' '}\n <strong>incidents</strong>, plan and approve <strong>changes</strong> safely, and run root-cause{' '}\n <strong>problem</strong> investigations — all tied back to the affected assets. Use this hub\n to see what is breaching SLA right now and where to act first.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"assethandler-itil-hub\"\n steps={[\n {\n id: 'incidents',\n label: 'Review active incidents',\n description: 'Triage what is impacting users and check SLA risk.',\n onClick: () => navigate('/itil/incident-management'),\n },\n {\n id: 'changes',\n label: 'Plan a change',\n description: 'Schedule and risk-assess upcoming asset changes.',\n onClick: () => navigate('/itil/change-management'),\n },\n {\n id: 'problems',\n label: 'Open a problem record',\n description: 'Investigate recurring incidents for root cause.',\n onClick: () => navigate('/itil/problem-management'),\n },\n ]}\n />\n\n {/* KPI Cards */}\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-5\">\n <EmphasisPanel>\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <AlertTriangle className=\"h-4 w-4\" />\n Active Incidents\n </div>\n <p className=\"text-2xl font-bold mt-1 tabular-nums\">{activeIncidents.length}</p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <CheckCircle className=\"h-4 w-4\" />\n Resolved\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-success-text\">\n {resolvedIncidents.length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <XCircle className=\"h-4 w-4\" />\n SLA Breaches\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-error-text\">{slaBreaches.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <GitPullRequest className=\"h-4 w-4\" />\n Pending Changes\n </div>\n <p className=\"text-2xl font-bold mt-1\">{pendingChanges.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Search className=\"h-4 w-4\" />\n Open Problems\n </div>\n <p className=\"text-2xl font-bold mt-1\">{openProblems.length}</p>\n </CardContent>\n </Card>\n </div>\n\n <Tabs defaultValue=\"incidents\">\n <TabsList>\n <TabsTrigger value=\"incidents\">Incidents ({incidents.length})</TabsTrigger>\n <TabsTrigger value=\"changes\">Changes ({changeRequests.length})</TabsTrigger>\n <TabsTrigger value=\"problems\">Problems ({problems.length})</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"incidents\" className=\"mt-4\">\n {incidents.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title=\"No incidents reported\"\n description=\"When service-affecting incidents are raised, they will appear here for triage.\"\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Priority</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Assigned To</th>\n <th className=\"text-left p-3 font-medium\">SLA</th>\n </tr>\n </thead>\n <tbody>\n {incidents.map((inc) => (\n <tr key={inc.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{inc.id}</td>\n <td className=\"p-3\">\n <p className=\"font-medium\">{inc.title}</p>\n <p className=\"text-xs text-text-secondary truncate max-w-xs\">\n {inc.description}\n </p>\n </td>\n <td className=\"p-3\">\n <Badge variant={priorityColors[inc.priority]}>{inc.priority}</Badge>\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{inc.status.replace('_', ' ')}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{inc.assignedTo || 'Unassigned'}</td>\n <td className=\"p-3\">\n {inc.slaBreached ? (\n <Badge variant=\"destructive\">Breached</Badge>\n ) : (\n <Badge variant=\"secondary\">OK</Badge>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </TabsContent>\n\n <TabsContent value=\"changes\" className=\"mt-4\">\n {changeRequests.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No change requests\"\n description=\"Planned changes to your assets and services will be listed here once raised.\"\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Type</th>\n <th className=\"text-left p-3 font-medium\">Risk</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Scheduled</th>\n </tr>\n </thead>\n <tbody>\n {changeRequests.map((chg) => (\n <tr key={chg.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{chg.id}</td>\n <td className=\"p-3\">\n <p className=\"font-medium\">{chg.title}</p>\n <p className=\"text-xs text-text-secondary truncate max-w-xs\">\n {chg.description}\n </p>\n </td>\n <td className=\"p-3 capitalize\">{chg.type}</td>\n <td className=\"p-3\">\n <Badge variant={priorityColors[chg.risk]}>{chg.risk}</Badge>\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{chg.status.replace('_', ' ')}</Badge>\n </td>\n <td className=\"p-3 text-xs\">\n {new Date(chg.scheduledStart).toLocaleDateString()}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </TabsContent>\n\n <TabsContent value=\"problems\" className=\"mt-4\">\n {problems.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No problem records\"\n description=\"Open a problem record to investigate the root cause of recurring incidents.\"\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Priority</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Related Incidents</th>\n <th className=\"text-left p-3 font-medium\">Assigned To</th>\n </tr>\n </thead>\n <tbody>\n {problems.map((prob) => (\n <tr key={prob.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{prob.id}</td>\n <td className=\"p-3\">\n <p className=\"font-medium\">{prob.title}</p>\n <p className=\"text-xs text-text-secondary truncate max-w-xs\">\n {prob.description}\n </p>\n </td>\n <td className=\"p-3\">\n <Badge variant={priorityColors[prob.priority]}>{prob.priority}</Badge>\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{prob.status.replace('_', ' ')}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{prob.relatedIncidents.length} incident(s)</td>\n <td className=\"p-3 text-xs\">{prob.assignedTo}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ItilItilhubPage.js","names":[],"sources":["../../../src/assethandler/pages/ItilItilhubPage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n NextSteps,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { AlertTriangle, GitPullRequest, Search, CheckCircle, XCircle } from 'lucide-react';\nimport { useNavigate } from 'react-router-dom';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nconst priorityColors: Record<string, 'destructive' | 'default' | 'secondary' | 'outline'> = {\n critical: 'destructive',\n high: 'destructive',\n medium: 'default',\n low: 'secondary',\n};\n\nexport function ItilItilhubPage() {\n const navigate = useNavigate();\n const { incidents, changeRequests, problems } = useAssetHandlerStore();\n\n const activeIncidents = incidents.filter((i) => i.status !== 'resolved' && i.status !== 'closed');\n const resolvedIncidents = incidents.filter(\n (i) => i.status === 'resolved' || i.status === 'closed'\n );\n const slaBreaches = incidents.filter((i) => i.slaBreached);\n const pendingChanges = changeRequests.filter(\n (c) => c.status !== 'completed' && c.status !== 'rejected'\n );\n const openProblems = problems.filter((p) => p.status !== 'resolved' && p.status !== 'closed');\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>ITIL Service Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n Incident, Change, and Problem management hub\n </p>\n </div>\n <Button size=\"sm\">Create Ticket</Button>\n </div>\n\n <PagePurpose>\n Your single ITIL service-management desk: triage and resolve service-disrupting{' '}\n <strong>incidents</strong>, plan and approve <strong>changes</strong> safely, and run\n root-cause <strong>problem</strong> investigations — all tied back to the affected assets.\n Use this hub to see what is breaching SLA right now and where to act first.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"assethandler-itil-hub\"\n steps={[\n {\n id: 'incidents',\n label: 'Review active incidents',\n description: 'Triage what is impacting users and check SLA risk.',\n onClick: () => navigate('/itil/incident-management'),\n },\n {\n id: 'changes',\n label: 'Plan a change',\n description: 'Schedule and risk-assess upcoming asset changes.',\n onClick: () => navigate('/itil/change-management'),\n },\n {\n id: 'problems',\n label: 'Open a problem record',\n description: 'Investigate recurring incidents for root cause.',\n onClick: () => navigate('/itil/problem-management'),\n },\n ]}\n />\n\n {/* KPI Cards */}\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-5\">\n <EmphasisPanel>\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <AlertTriangle className=\"h-4 w-4\" />\n Active Incidents\n </div>\n <p className=\"text-2xl font-bold mt-1 tabular-nums\">{activeIncidents.length}</p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <CheckCircle className=\"h-4 w-4\" />\n Resolved\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-success-text\">\n {resolvedIncidents.length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <XCircle className=\"h-4 w-4\" />\n SLA Breaches\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-error-text\">{slaBreaches.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <GitPullRequest className=\"h-4 w-4\" />\n Pending Changes\n </div>\n <p className=\"text-2xl font-bold mt-1\">{pendingChanges.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Search className=\"h-4 w-4\" />\n Open Problems\n </div>\n <p className=\"text-2xl font-bold mt-1\">{openProblems.length}</p>\n </CardContent>\n </Card>\n </div>\n\n <Tabs defaultValue=\"incidents\">\n <TabsList>\n <TabsTrigger value=\"incidents\">Incidents ({incidents.length})</TabsTrigger>\n <TabsTrigger value=\"changes\">Changes ({changeRequests.length})</TabsTrigger>\n <TabsTrigger value=\"problems\">Problems ({problems.length})</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"incidents\" className=\"mt-4\">\n {incidents.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title=\"No incidents reported\"\n description=\"When service-affecting incidents are raised, they will appear here for triage.\"\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Priority</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Assigned To</th>\n <th className=\"text-left p-3 font-medium\">SLA</th>\n </tr>\n </thead>\n <tbody>\n {incidents.map((inc) => (\n <tr key={inc.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{inc.id}</td>\n <td className=\"p-3\">\n <p className=\"font-medium\">{inc.title}</p>\n <p className=\"text-xs text-text-secondary truncate max-w-xs\">\n {inc.description}\n </p>\n </td>\n <td className=\"p-3\">\n <Badge variant={priorityColors[inc.priority]}>{inc.priority}</Badge>\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{inc.status.replace('_', ' ')}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{inc.assignedTo || 'Unassigned'}</td>\n <td className=\"p-3\">\n {inc.slaBreached ? (\n <Badge variant=\"destructive\">Breached</Badge>\n ) : (\n <Badge variant=\"secondary\">OK</Badge>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </TabsContent>\n\n <TabsContent value=\"changes\" className=\"mt-4\">\n {changeRequests.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No change requests\"\n description=\"Planned changes to your assets and services will be listed here once raised.\"\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Type</th>\n <th className=\"text-left p-3 font-medium\">Risk</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Scheduled</th>\n </tr>\n </thead>\n <tbody>\n {changeRequests.map((chg) => (\n <tr key={chg.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{chg.id}</td>\n <td className=\"p-3\">\n <p className=\"font-medium\">{chg.title}</p>\n <p className=\"text-xs text-text-secondary truncate max-w-xs\">\n {chg.description}\n </p>\n </td>\n <td className=\"p-3 capitalize\">{chg.type}</td>\n <td className=\"p-3\">\n <Badge variant={priorityColors[chg.risk]}>{chg.risk}</Badge>\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{chg.status.replace('_', ' ')}</Badge>\n </td>\n <td className=\"p-3 text-xs\">\n {new Date(chg.scheduledStart).toLocaleDateString()}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </TabsContent>\n\n <TabsContent value=\"problems\" className=\"mt-4\">\n {problems.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No problem records\"\n description=\"Open a problem record to investigate the root cause of recurring incidents.\"\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Priority</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Related Incidents</th>\n <th className=\"text-left p-3 font-medium\">Assigned To</th>\n </tr>\n </thead>\n <tbody>\n {problems.map((prob) => (\n <tr key={prob.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{prob.id}</td>\n <td className=\"p-3\">\n <p className=\"font-medium\">{prob.title}</p>\n <p className=\"text-xs text-text-secondary truncate max-w-xs\">\n {prob.description}\n </p>\n </td>\n <td className=\"p-3\">\n <Badge variant={priorityColors[prob.priority]}>{prob.priority}</Badge>\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{prob.status.replace('_', ' ')}</Badge>\n </td>\n <td className=\"p-3 text-xs\">\n {prob.relatedIncidents.length} incident(s)\n </td>\n <td className=\"p-3 text-xs\">{prob.assignedTo}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ItilProblemManagementPage.js","names":[],"sources":["../../../src/assethandler/pages/ItilProblemManagementPage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { Plus } from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nconst priorityColors: Record<string, 'destructive' | 'default' | 'secondary' | 'outline'> = {\n critical: 'destructive',\n high: 'destructive',\n medium: 'default',\n low: 'secondary',\n};\n\nexport function ItilProblemManagementPage() {\n const { problems } = useAssetHandlerStore();\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>Problem Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{problems.length} problems tracked</p>\n </div>\n <Button size=\"sm\">\n <Plus className=\"mr-2 h-4 w-4\" />\n New Problem\n </Button>\n </div>\n\n <PagePurpose>\n Get to the root cause of recurring incidents instead of firefighting the same issue twice.\n Track problems through investigation to a known error and a permanent fix, link the\n incidents they explain, and stop repeat outages at the source.\n </PagePurpose>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <EmphasisPanel>\n <p className=\"text-sm text-text-secondary\">Open</p>\n <p className=\"text-2xl font-bold tabular-nums\">\n {problems.filter((p) => p.status === 'open').length}\n </p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Investigating</p>\n <p className=\"text-2xl font-bold text-status-info-text\">\n {problems.filter((p) => p.status === 'investigating').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Known Error</p>\n <p className=\"text-2xl font-bold text-status-warning-text\">\n {problems.filter((p) => p.status === 'known_error').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Resolved</p>\n <p className=\"text-2xl font-bold text-status-success-text\">\n {problems.filter((p) => p.status === 'resolved' || p.status === 'closed').length}\n </p>\n </CardContent>\n </Card>\n </div>\n\n {problems.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No problems tracked\"\n description=\"Open a problem record to investigate the root cause behind recurring incidents.\"\n />\n ) : (\n
|
|
1
|
+
{"version":3,"file":"ItilProblemManagementPage.js","names":[],"sources":["../../../src/assethandler/pages/ItilProblemManagementPage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { Plus } from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nconst priorityColors: Record<string, 'destructive' | 'default' | 'secondary' | 'outline'> = {\n critical: 'destructive',\n high: 'destructive',\n medium: 'default',\n low: 'secondary',\n};\n\nexport function ItilProblemManagementPage() {\n const { problems } = useAssetHandlerStore();\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>Problem Management</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">{problems.length} problems tracked</p>\n </div>\n <Button size=\"sm\">\n <Plus className=\"mr-2 h-4 w-4\" />\n New Problem\n </Button>\n </div>\n\n <PagePurpose>\n Get to the root cause of recurring incidents instead of firefighting the same issue twice.\n Track problems through investigation to a known error and a permanent fix, link the\n incidents they explain, and stop repeat outages at the source.\n </PagePurpose>\n\n <div className=\"grid gap-4 md:grid-cols-4\">\n <EmphasisPanel>\n <p className=\"text-sm text-text-secondary\">Open</p>\n <p className=\"text-2xl font-bold tabular-nums\">\n {problems.filter((p) => p.status === 'open').length}\n </p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Investigating</p>\n <p className=\"text-2xl font-bold text-status-info-text\">\n {problems.filter((p) => p.status === 'investigating').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Known Error</p>\n <p className=\"text-2xl font-bold text-status-warning-text\">\n {problems.filter((p) => p.status === 'known_error').length}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <p className=\"text-sm text-text-secondary\">Resolved</p>\n <p className=\"text-2xl font-bold text-status-success-text\">\n {problems.filter((p) => p.status === 'resolved' || p.status === 'closed').length}\n </p>\n </CardContent>\n </Card>\n </div>\n\n {problems.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No problems tracked\"\n description=\"Open a problem record to investigate the root cause behind recurring incidents.\"\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Category</th>\n <th className=\"text-left p-3 font-medium\">Priority</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n <th className=\"text-left p-3 font-medium\">Related Incidents</th>\n <th className=\"text-left p-3 font-medium\">Assigned To</th>\n </tr>\n </thead>\n <tbody>\n {problems.map((prob) => (\n <tr key={prob.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{prob.id}</td>\n <td className=\"p-3\">\n <p className=\"font-medium\">{prob.title}</p>\n <p className=\"text-xs text-text-secondary truncate max-w-xs\">\n {prob.description}\n </p>\n </td>\n <td className=\"p-3 text-xs\">{prob.category}</td>\n <td className=\"p-3\">\n <Badge variant={priorityColors[prob.priority]}>{prob.priority}</Badge>\n </td>\n <td className=\"p-3\">\n <Badge variant=\"outline\">{prob.status.replace('_', ' ')}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{prob.relatedIncidents.join(', ')}</td>\n <td className=\"p-3 text-xs\">{prob.assignedTo}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </CardContent>\n </Card>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KnowledgeBasePage.js","names":[],"sources":["../../../src/assethandler/pages/KnowledgeBasePage.tsx"],"sourcesContent":["import { BookOpen } from 'lucide-react';\nimport {
|
|
1
|
+
{"version":3,"file":"KnowledgeBasePage.js","names":[],"sources":["../../../src/assethandler/pages/KnowledgeBasePage.tsx"],"sourcesContent":["import { BookOpen } from 'lucide-react';\nimport {\n GradientText,\n IllustratedEmptyState,\n EmphasisPanel,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\n\nconst KNOWLEDGE_ARTICLES_QUERY = gql`\n query AssetHandlerKnowledgeArticles {\n knowledgeArticles {\n id\n title\n slug\n summary\n status\n tags\n updatedAt\n }\n }\n`;\n\nconst CREATE_KNOWLEDGE_ARTICLE_MUTATION = gql`\n mutation AssetHandlerCreateKnowledgeArticle($input: CreateKnowledgeArticleInput!) {\n createKnowledgeArticle(input: $input) {\n id\n }\n }\n`;\n\nexport function KnowledgeBasePage() {\n const [title, setTitle] = useState('Runbook: Failed Discovery Job Recovery');\n const [slug, setSlug] = useState('runbook-failed-discovery-recovery');\n\n const { data, loading, refetch } = useQuery<{\n knowledgeArticles: Array<{\n id: string;\n title: string;\n slug: string;\n summary: string | null;\n status: string;\n tags: string[];\n updatedAt: string;\n }>;\n }>(KNOWLEDGE_ARTICLES_QUERY, { fetchPolicy: 'cache-and-network' });\n\n const [createArticle, { loading: creating }] = useMutation(CREATE_KNOWLEDGE_ARTICLE_MUTATION, {\n onCompleted: () => {\n void refetch();\n },\n });\n\n const articles = data?.knowledgeArticles ?? [];\n\n return (\n <div className=\"space-y-4 p-4\">\n <h1 className=\"flex items-center gap-2 text-2xl font-semibold\">\n <BookOpen className=\"h-6 w-6\" /> <GradientText>Knowledge Base</GradientText>\n </h1>\n <PagePurpose>\n Capture the fixes and runbooks your team relies on so the next person doesn't start\n from scratch. Link articles to incidents and assets, then search them when troubleshooting —\n turning one-off resolutions into repeatable, shareable operational knowledge.\n </PagePurpose>\n <EmphasisPanel>\n <h2 className=\"text-sm font-semibold mb-3\">Publish an article</h2>\n <form\n className=\"grid gap-3 md:grid-cols-3\"\n onSubmit={(event) => {\n event.preventDefault();\n void createArticle({\n variables: {\n input: {\n title,\n slug,\n summary: 'Operational recovery guidance for discovery pipeline failures.',\n content:\n '1) Verify connector credentials. 2) Re-run with scoped segment. 3) Escalate to platform ops if retries fail.',\n tags: ['runbook', 'discovery', 'operations'],\n status: 'PUBLISHED',\n },\n },\n });\n }}\n >\n <input\n className=\"rounded-md border px-3 py-2\"\n value={title}\n onChange={(event) => setTitle(event.target.value)}\n aria-label=\"Article title\"\n />\n <input\n className=\"rounded-md border px-3 py-2\"\n value={slug}\n onChange={(event) => setSlug(event.target.value)}\n aria-label=\"Article slug\"\n />\n <button\n className=\"rounded-md bg-action-primary-bg px-3 py-2 text-action-primary-text\"\n disabled={creating}\n type=\"submit\"\n >\n {creating ? 'Creating...' : 'Publish Article'}\n </button>\n </form>\n </EmphasisPanel>\n <div className=\"grid gap-3 md:grid-cols-2\">\n {loading && articles.length === 0 ? (\n <div className=\"space-y-2 px-4 py-4\">\n {Array.from({ length: 4 }).map((_, i) => (\n <div key={i} className=\"h-8 rounded-md bg-bg-sunken motion-safe:animate-vc-shimmer\" />\n ))}\n </div>\n ) : null}\n {!loading && articles.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No knowledge articles found\"\n description=\"Create an article to start building your knowledge base.\"\n />\n ) : null}\n {articles.map((article) => (\n <article key={article.id} className=\"rounded-lg border p-4\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">{article.status}</p>\n <h2 className=\"mt-1 text-base font-semibold\">{article.title}</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {article.summary ?? 'No summary available.'}\n </p>\n <p className=\"mt-2 text-xs text-text-secondary\">/{article.slug}</p>\n </article>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;AAWA,IAAM,IAA2B,CAAG;;;;;;;;;;;;GAc9B,IAAoC,CAAG;;;;;;;AAQ7C,SAAgB,IAAoB;CAClC,IAAM,CAAC,GAAO,KAAY,EAAS,yCAAyC,EACtE,CAAC,GAAM,KAAW,EAAS,oCAAoC,EAE/D,EAAE,SAAM,YAAS,eAAY,EAUhC,GAA0B,EAAE,aAAa,qBAAqB,CAAC,EAE5D,CAAC,GAAe,EAAE,SAAS,OAAc,EAAY,GAAmC,EAC5F,mBAAmB;AACZ,KAAS;IAEjB,CAAC,EAEI,IAAW,GAAM,qBAAqB,EAAE;AAE9C,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,MAAD;IAAI,WAAU;cAAd;KACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;;KAAC,kBAAC,GAAD,EAAA,UAAc,kBAA6B,CAAA;KACzE;;GACL,kBAAC,GAAD,EAAA,UAAa,kQAIC,CAAA;GACd,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;cAA6B;IAAuB,CAAA,EAClE,kBAAC,QAAD;IACE,WAAU;IACV,WAAW,MAAU;AAEd,KADL,EAAM,gBAAgB,EACjB,EAAc,EACjB,WAAW,EACT,OAAO;MACL;MACA;MACA,SAAS;MACT,SACE;MACF,MAAM;OAAC;OAAW;OAAa;OAAa;MAC5C,QAAQ;MACT,EACF,EACF,CAAC;;cAhBN;KAmBE,kBAAC,SAAD;MACE,WAAU;MACV,OAAO;MACP,WAAW,MAAU,EAAS,EAAM,OAAO,MAAM;MACjD,cAAW;MACX,CAAA;KACF,kBAAC,SAAD;MACE,WAAU;MACV,OAAO;MACP,WAAW,MAAU,EAAQ,EAAM,OAAO,MAAM;MAChD,cAAW;MACX,CAAA;KACF,kBAAC,UAAD;MACE,WAAU;MACV,UAAU;MACV,MAAK;gBAEJ,IAAW,gBAAgB;MACrB,CAAA;KACJ;MACO,EAAA,CAAA;GAChB,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,KAAW,EAAS,WAAW,IAC9B,kBAAC,OAAD;MAAK,WAAU;gBACZ,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,OAAD,EAAa,WAAU,8DAA+D,EAA5E,EAA4E,CACtF;MACE,CAAA,GACJ;KACH,CAAC,KAAW,EAAS,WAAW,IAC/B,kBAAC,GAAD;MACE,cAAa;MACb,OAAM;MACN,aAAY;MACZ,CAAA,GACA;KACH,EAAS,KAAK,MACb,kBAAC,WAAD;MAA0B,WAAU;gBAApC;OACE,kBAAC,KAAD;QAAG,WAAU;kBAAuD,EAAQ;QAAW,CAAA;OACvF,kBAAC,MAAD;QAAI,WAAU;kBAAgC,EAAQ;QAAW,CAAA;OACjE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAQ,WAAW;QAClB,CAAA;OACJ,kBAAC,KAAD;QAAG,WAAU;kBAAb,CAAgD,KAAE,EAAQ,KAAS;;OAC3D;QAPI,EAAQ,GAOZ,CACV;KACE;;GACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MaintenanceMaintenanceCalendarPage.js","names":[],"sources":["../../../src/assethandler/pages/MaintenanceMaintenanceCalendarPage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { Calendar, Wrench, Clock, CheckCircle } from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nconst priorityColors: Record<string, 'destructive' | 'default' | 'secondary' | 'outline'> = {\n critical: 'destructive',\n high: 'destructive',\n medium: 'default',\n low: 'secondary',\n};\n\nexport function MaintenanceMaintenanceCalendarPage() {\n const { maintenanceRecords } = useAssetHandlerStore();\n const scheduled = maintenanceRecords.filter((m) => m.status === 'scheduled');\n const inProgress = maintenanceRecords.filter((m) => m.status === 'in_progress');\n const completed = maintenanceRecords.filter((m) => m.status === 'completed');\n\n const daysInMonth = Array.from({ length: 28 }, (_, i) => i + 1);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>Maintenance Calendar</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {maintenanceRecords.length} maintenance activities tracked\n </p>\n </div>\n <Button size=\"sm\">\n <Wrench className=\"mr-2 h-4 w-4\" />\n Schedule Maintenance\n </Button>\n </div>\n\n <PagePurpose>\n See all planned, in-progress and completed maintenance on one calendar so you can spot\n clashes, balance the workload and never miss a due service. Use it to plan the month at a\n glance and keep assets healthy before they fail.\n </PagePurpose>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <EmphasisPanel>\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Clock className=\"h-4 w-4\" />\n Scheduled\n </div>\n <p className=\"text-2xl font-bold mt-1 tabular-nums\">{scheduled.length}</p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Wrench className=\"h-4 w-4\" />\n In Progress\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-info-text\">{inProgress.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <CheckCircle className=\"h-4 w-4\" />\n Completed\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-success-text\">{completed.length}</p>\n </CardContent>\n </Card>\n </div>\n\n {/* Calendar Grid Placeholder */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Calendar className=\"h-4 w-4\" />\n February 2026\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-7 gap-1 text-center text-sm\">\n {['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map((d) => (\n <div key={d} className=\"p-2 font-medium text-text-secondary\">\n {d}\n </div>\n ))}\n {/* Offset for Feb 2026 starting on Sunday */}\n {daysInMonth.map((day) => {\n const dateStr = `2026-02-${String(day).padStart(2, '0')}`;\n const dayRecords = maintenanceRecords.filter((m) => m.scheduledDate === dateStr);\n return (\n <div\n key={day}\n className={`p-2 rounded min-h-[60px] border ${dayRecords.length > 0 ? 'bg-action-primary-bg/5 border-primary/20' : 'border-transparent'}`}\n >\n <span className=\"text-xs\">{day}</span>\n {dayRecords.map((r) => (\n <div key={r.id} className=\"mt-1\">\n <Badge\n variant={priorityColors[r.priority]}\n className=\"text-[9px] w-full justify-center\"\n >\n {r.title.slice(0, 15)}\n </Badge>\n </div>\n ))}\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n\n {/* Upcoming List */}\n <Card>\n <CardHeader>\n <CardTitle>All Maintenance Activities</CardTitle>\n </CardHeader>\n <CardContent className=\"p-0\">\n {maintenanceRecords.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No maintenance activities\"\n description=\"Schedule maintenance and it will show up on the calendar and in this list.\"\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Asset</th>\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Type</th>\n <th className=\"text-left p-3 font-medium\">Priority</th>\n <th className=\"text-left p-3 font-medium\">Date</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n </tr>\n </thead>\n <tbody>\n {maintenanceRecords.map((rec) => (\n <tr key={rec.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{rec.id}</td>\n <td className=\"p-3 text-xs\">{rec.assetId}</td>\n <td className=\"p-3 font-medium\">{rec.title}</td>\n <td className=\"p-3 capitalize text-xs\">{rec.type}</td>\n <td className=\"p-3\">\n <Badge variant={priorityColors[rec.priority]}>{rec.priority}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{rec.scheduledDate}</td>\n <td className=\"p-3\">\n <Badge variant={rec.status === 'completed' ? 'default' : 'outline'}>\n {rec.status.replace('_', ' ')}\n </Badge>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":";;;;;AAeA,IAAM,IAAsF;CAC1F,UAAU;CACV,MAAM;CACN,QAAQ;CACR,KAAK;CACN;AAED,SAAgB,IAAqC;CACnD,IAAM,EAAE,0BAAuB,GAAsB,EAC/C,IAAY,EAAmB,QAAQ,MAAM,EAAE,WAAW,YAAY,EACtE,IAAa,EAAmB,QAAQ,MAAM,EAAE,WAAW,cAAc,EACzE,IAAY,EAAmB,QAAQ,MAAM,EAAE,WAAW,YAAY,EAEtE,IAAc,MAAM,KAAK,EAAE,QAAQ,IAAI,GAAG,GAAG,MAAM,IAAI,EAAE;AAE/D,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eACZ,kBAAC,GAAD,EAAA,UAAc,wBAAmC,CAAA;KAC9C,CAAA,EACL,kBAAC,KAAD;KAAG,WAAU;eAAb,CACG,EAAmB,QAAO,kCACzB;OACA,EAAA,CAAA,EACN,kBAAC,GAAD;KAAQ,MAAK;eAAb,CACE,kBAAC,GAAD,EAAQ,WAAU,gBAAiB,CAAA,EAAA,uBAE5B;OACL;;GAEN,kBAAC,GAAD,EAAA,UAAa,qOAIC,CAAA;GAEd,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,EAAA,YAEzB;SACN,kBAAC,KAAD;MAAG,WAAU;gBAAwC,EAAU;MAAW,CAAA,CAC5D,EAAA,CAAA;KAChB,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,cAE1B;UACN,kBAAC,KAAD;OAAG,WAAU;iBAAiD,EAAW;OAAW,CAAA,CACxE;SACT,CAAA;KACP,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA,EAAA,YAE/B;UACN,kBAAC,KAAD;OAAG,WAAU;iBAAoD,EAAU;OAAW,CAAA,CAC1E;SACT,CAAA;KACH;;GAGN,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IAAW,WAAU;cAArB,CACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA,EAAA,gBAEtB;OACD,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACG;KAAC;KAAO;KAAO;KAAO;KAAO;KAAO;KAAO;KAAM,CAAC,KAAK,MACtD,kBAAC,OAAD;KAAa,WAAU;eACpB;KACG,EAFI,EAEJ,CACN,EAED,EAAY,KAAK,MAAQ;KACxB,IAAM,IAAU,WAAW,OAAO,EAAI,CAAC,SAAS,GAAG,IAAI,IACjD,IAAa,EAAmB,QAAQ,MAAM,EAAE,kBAAkB,EAAQ;AAChF,YACE,kBAAC,OAAD;MAEE,WAAW,mCAAmC,EAAW,SAAS,IAAI,6CAA6C;gBAFrH,CAIE,kBAAC,QAAD;OAAM,WAAU;iBAAW;OAAW,CAAA,EACrC,EAAW,KAAK,MACf,kBAAC,OAAD;OAAgB,WAAU;iBACxB,kBAAC,GAAD;QACE,SAAS,EAAe,EAAE;QAC1B,WAAU;kBAET,EAAE,MAAM,MAAM,GAAG,GAAG;QACf,CAAA;OACJ,EAPI,EAAE,GAON,CACN,CACE;QAdC,EAcD;MAER,CACE;OACM,CAAA,CACT,EAAA,CAAA;GAGP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,8BAAsC,CAAA,EACtC,CAAA,EACb,kBAAC,GAAD;IAAa,WAAU;cACpB,EAAmB,WAAW,IAC7B,kBAAC,GAAD;KACE,cAAa;KACb,OAAM;KACN,aAAY;KACZ,CAAA,GAEJ,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,SAAD;MAAO,WAAU;gBAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;OAAI,WAAU;iBAAd;QACE,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAO,CAAA;QACjD,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAU,CAAA;QACpD,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAU,CAAA;QACpD,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAS,CAAA;QACnD,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAa,CAAA;QACvD,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAS,CAAA;QACnD,kBAAC,MAAD;SAAI,WAAU;mBAA4B;SAAW,CAAA;QAClD;UACC,CAAA,EACR,kBAAC,SAAD,EAAA,UACG,EAAmB,KAAK,MACvB,kBAAC,MAAD;OAAiB,WAAU;iBAA3B;QACE,kBAAC,MAAD;SAAI,WAAU;mBAAyB,EAAI;SAAQ,CAAA;QACnD,kBAAC,MAAD;SAAI,WAAU;mBAAe,EAAI;SAAa,CAAA;QAC9C,kBAAC,MAAD;SAAI,WAAU;mBAAmB,EAAI;SAAW,CAAA;QAChD,kBAAC,MAAD;SAAI,WAAU;mBAA0B,EAAI;SAAU,CAAA;QACtD,kBAAC,MAAD;SAAI,WAAU;mBACZ,kBAAC,GAAD;UAAO,SAAS,EAAe,EAAI;oBAAY,EAAI;UAAiB,CAAA;SACjE,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAe,EAAI;SAAmB,CAAA;QACpD,kBAAC,MAAD;SAAI,WAAU;mBACZ,kBAAC,GAAD;UAAO,SAAS,EAAI,WAAW,cAAc,YAAY;oBACtD,EAAI,OAAO,QAAQ,KAAK,IAAI;UACvB,CAAA;SACL,CAAA;QACF;SAdI,EAAI,GAcR,CACL,EACI,CAAA,CACF;;KACJ,CAAA;IAEM,CAAA,CACT,EAAA,CAAA;GACH"}
|
|
1
|
+
{"version":3,"file":"MaintenanceMaintenanceCalendarPage.js","names":[],"sources":["../../../src/assethandler/pages/MaintenanceMaintenanceCalendarPage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n GradientText,\n EmphasisPanel,\n PagePurpose,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport { Calendar, Wrench, Clock, CheckCircle } from 'lucide-react';\nimport { useAssetHandlerStore } from '../store/assethandlerStore';\n\nconst priorityColors: Record<string, 'destructive' | 'default' | 'secondary' | 'outline'> = {\n critical: 'destructive',\n high: 'destructive',\n medium: 'default',\n low: 'secondary',\n};\n\nexport function MaintenanceMaintenanceCalendarPage() {\n const { maintenanceRecords } = useAssetHandlerStore();\n const scheduled = maintenanceRecords.filter((m) => m.status === 'scheduled');\n const inProgress = maintenanceRecords.filter((m) => m.status === 'in_progress');\n const completed = maintenanceRecords.filter((m) => m.status === 'completed');\n\n const daysInMonth = Array.from({ length: 28 }, (_, i) => i + 1);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold\">\n <GradientText>Maintenance Calendar</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {maintenanceRecords.length} maintenance activities tracked\n </p>\n </div>\n <Button size=\"sm\">\n <Wrench className=\"mr-2 h-4 w-4\" />\n Schedule Maintenance\n </Button>\n </div>\n\n <PagePurpose>\n See all planned, in-progress and completed maintenance on one calendar so you can spot\n clashes, balance the workload and never miss a due service. Use it to plan the month at a\n glance and keep assets healthy before they fail.\n </PagePurpose>\n\n <div className=\"grid gap-4 md:grid-cols-3\">\n <EmphasisPanel>\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Clock className=\"h-4 w-4\" />\n Scheduled\n </div>\n <p className=\"text-2xl font-bold mt-1 tabular-nums\">{scheduled.length}</p>\n </EmphasisPanel>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Wrench className=\"h-4 w-4\" />\n In Progress\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-info-text\">{inProgress.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <CheckCircle className=\"h-4 w-4\" />\n Completed\n </div>\n <p className=\"text-2xl font-bold mt-1 text-status-success-text\">{completed.length}</p>\n </CardContent>\n </Card>\n </div>\n\n {/* Calendar Grid Placeholder */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Calendar className=\"h-4 w-4\" />\n February 2026\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-7 gap-1 text-center text-sm\">\n {['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map((d) => (\n <div key={d} className=\"p-2 font-medium text-text-secondary\">\n {d}\n </div>\n ))}\n {/* Offset for Feb 2026 starting on Sunday */}\n {daysInMonth.map((day) => {\n const dateStr = `2026-02-${String(day).padStart(2, '0')}`;\n const dayRecords = maintenanceRecords.filter((m) => m.scheduledDate === dateStr);\n return (\n <div\n key={day}\n className={`p-2 rounded min-h-[60px] border ${dayRecords.length > 0 ? 'bg-action-primary-bg/5 border-primary/20' : 'border-transparent'}`}\n >\n <span className=\"text-xs\">{day}</span>\n {dayRecords.map((r) => (\n <div key={r.id} className=\"mt-1\">\n <Badge\n variant={priorityColors[r.priority]}\n className=\"text-[9px] w-full justify-center\"\n >\n {r.title.slice(0, 15)}\n </Badge>\n </div>\n ))}\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n\n {/* Upcoming List */}\n <Card>\n <CardHeader>\n <CardTitle>All Maintenance Activities</CardTitle>\n </CardHeader>\n <CardContent className=\"p-0\">\n {maintenanceRecords.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No maintenance activities\"\n description=\"Schedule maintenance and it will show up on the calendar and in this list.\"\n />\n ) : (\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\">ID</th>\n <th className=\"text-left p-3 font-medium\">Asset</th>\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Type</th>\n <th className=\"text-left p-3 font-medium\">Priority</th>\n <th className=\"text-left p-3 font-medium\">Date</th>\n <th className=\"text-left p-3 font-medium\">Status</th>\n </tr>\n </thead>\n <tbody>\n {maintenanceRecords.map((rec) => (\n <tr key={rec.id} className=\"border-b hover:bg-bg-sunken/50 cursor-pointer\">\n <td className=\"p-3 font-mono text-xs\">{rec.id}</td>\n <td className=\"p-3 text-xs\">{rec.assetId}</td>\n <td className=\"p-3 font-medium\">{rec.title}</td>\n <td className=\"p-3 capitalize text-xs\">{rec.type}</td>\n <td className=\"p-3\">\n <Badge variant={priorityColors[rec.priority]}>{rec.priority}</Badge>\n </td>\n <td className=\"p-3 text-xs\">{rec.scheduledDate}</td>\n <td className=\"p-3\">\n <Badge variant={rec.status === 'completed' ? 'default' : 'outline'}>\n {rec.status.replace('_', ' ')}\n </Badge>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|