/home/techb158/balavpn.abdallabala.com/.next/cache/webpack/client-production
Edit: /home/techb158/balavpn.abdallabala.com/.next/cache/webpack/client-production/3.pack (2760565B)
wpc i* webpack/lib/cache/PackFileCacheStrategyPackContentItems Compilation/modules|javascript/auto|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-flight-client-module-loader.js!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-swc-loader.js??ruleSet[1].rules[16].oneOf[6].use[1]!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\app\dashboard\page.jsx|app-pages-browser FlagDependencyExportsPlugin|javascript/auto|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-flight-client-module-loader.js!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-swc-loader.js??ruleSet[1].rules[16].oneOf[6].use[1]!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\app\dashboard\page.jsx|app-pages-browser Compilation/codeGeneration|javascript/auto|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-flight-client-module-loader.js!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-swc-loader.js??ruleSet[1].rules[16].oneOf[6].use[1]!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\app\dashboard\page.jsx|app-pages-browser|7e16abe844e36332|webpackCompilation/assets|chunk5105MinifierWebpackPlugin|static/chunks/app/dashboard/page-b1c4a66f026fada8.jsRealContentHashPlugin|analyse|static/chunks/app/dashboard/page-b1c4a66f026fada8.jswebpack/lib/NormalModulewebpack/lib/util/registerExternalSerializerwebpack-sources/RawSourcevn /* __next_internal_client_entry_do_not_use__ default auto */ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useEffect, useState, useCallback, useMemo } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { api } from '../../lib/api-client';
import ErrorBoundary from '../../components/ErrorBoundary';
const TABS = [
'Overview',
'Projects',
'Risks',
'Mitigations',
'Gate',
'Integrations',
'Audit'
];
const PAGE_SIZE = 20;
const DIMENSIONS = [
'Technical',
'Governance',
'Legal',
'Ethical',
'Operational'
];
const LIFECYCLE_PHASES = [
'Design',
'Development',
'Testing',
'Deployment'
];
const RISK_STATUSES = [
'OPEN',
'IN_MITIGATION',
'ACCEPTED',
'CLOSED'
];
const MITIGATION_STATUSES = [
'NOT_STARTED',
'IN_PROGRESS',
'DONE',
'REJECTED'
];
function useToast() {
const [toasts, setToasts] = useState([]);
const add = useCallback(function(message) {
let type = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 'success';
const id = Date.now() + Math.random();
setToasts((prev)=>[
...prev,
{
id,
message,
type
}
]);
setTimeout(()=>setToasts((prev)=>prev.filter((t)=>t.id !== id)), 3000);
}, []);
return {
toasts,
add
};
}
function ToastContainer(param) {
let { toasts } = param;
if (!toasts.length) return null;
return /*#__PURE__*/ _jsx("div", {
className: "toast-container",
children: toasts.map((t)=>/*#__PURE__*/ _jsx("div", {
className: "toast ".concat(t.type),
children: t.message
}, t.id))
});
}
function SearchInput(param) {
let { value, onChange, placeholder } = param;
return /*#__PURE__*/ _jsxs("div", {
className: "search-wrap",
children: [
/*#__PURE__*/ _jsx("span", {
className: "search-icon",
children: "⌕"
}),
/*#__PURE__*/ _jsx("input", {
className: "input",
value: value,
onChange: (e)=>onChange(e.target.value),
placeholder: placeholder || 'Search...'
})
]
});
}
function sortData(list, sortKey, sortDir) {
if (!sortKey) return list;
return [
...list
].sort((a, b)=>{
const va = a[sortKey], vb = b[sortKey];
if (va == null) return 1;
if (vb == null) return -1;
const cmp = typeof va === 'number' ? va - vb : String(va).localeCompare(String(vb));
return sortDir === 'asc' ? cmp : -cmp;
});
}
function Badge(param) {
let { children, className } = param;
return /*#__PURE__*/ _jsx("span", {
className: "badge ".concat(className || ''),
children: children
});
}
function FormField(param) {
let { label, children } = param;
return /*#__PURE__*/ _jsxs("div", {
style: {
marginBottom: 10
},
children: [
/*#__PURE__*/ _jsx("label", {
style: {
display: 'block',
fontSize: 12,
color: 'var(--muted)',
marginBottom: 3
},
children: label
}),
children
]
});
}
function InlineInput(param) {
let { value, onChange, type = 'text', min, max, style: extraStyle } = param;
return /*#__PURE__*/ _jsx("input", {
className: "input",
type: type,
value: value,
onChange: (e)=>onChange(e.target.value),
min: min,
max: max,
style: {
width: '100%',
...extraStyle
}
});
}
function InlineSelect(param) {
let { value, onChange, options } = param;
const items = options || [];
return /*#__PURE__*/ _jsxs("select", {
className: "input",
value: value,
onChange: (e)=>onChange(e.target.value),
style: {
width: '100%'
},
children: [
/*#__PURE__*/ _jsx("option", {
value: "",
children: "— Select —"
}),
items.map((o)=>{
const val = typeof o === 'object' ? o.value : o;
const lbl = typeof o === 'object' ? o.label : o;
return /*#__PURE__*/ _jsx("option", {
value: val,
children: lbl
}, val);
})
]
});
}
function ConfirmDelete(param) {
let { label, onConfirm, onCancel, deleting } = param;
return /*#__PURE__*/ _jsx("div", {
className: "modal-overlay",
onClick: onCancel,
children: /*#__PURE__*/ _jsxs("div", {
className: "modal",
onClick: (e)=>e.stopPropagation(),
style: {
maxWidth: 380
},
children: [
/*#__PURE__*/ _jsxs("h3", {
children: [
"Delete ",
label,
"?"
]
}),
/*#__PURE__*/ _jsx("p", {
style: {
fontSize: 13,
color: 'var(--muted)'
},
children: "This cannot be undone."
}),
/*#__PURE__*/ _jsxs("div", {
className: "modal-actions",
children: [
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: onCancel,
children: "Cancel"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
style: {
background: 'var(--danger)',
color: '#fff'
},
onClick: onConfirm,
disabled: deleting,
children: deleting ? 'Deleting...' : 'Delete'
})
]
})
]
})
});
}
function OverviewTab(param) {
let { project, dashboard } = param;
const panels = useMemo(()=>{
var _dashboard_summary, _dashboard_summary1, _dashboard_summary2, _dashboard_summary3, _dashboard_summary4, _dashboard_summary5, _dashboard_summary6, _dashboard_gate, _dashboard_summary7, _dashboard_summary8, _dashboard_summary9, _dashboard_summary10, _dashboard_summary11, _dashboard_summary12, _dashboard_summary13;
if (!dashboard) return [];
var _dashboard_summary_overallScore, _dashboard_summary_gateStatus, _dashboard_summary_openRisks, _dashboard_summary_mitigationCompletion;
return [
{
label: 'Overall Score',
value: (_dashboard_summary_overallScore = (_dashboard_summary = dashboard.summary) === null || _dashboard_summary === void 0 ? void 0 : _dashboard_summary.overallScore) !== null && _dashboard_summary_overallScore !== void 0 ? _dashboard_summary_overallScore : '-',
cls: ((_dashboard_summary1 = dashboard.summary) === null || _dashboard_summary1 === void 0 ? void 0 : _dashboard_summary1.overallScore) >= 75 ? 'bad' : ((_dashboard_summary2 = dashboard.summary) === null || _dashboard_summary2 === void 0 ? void 0 : _dashboard_summary2.overallScore) >= 50 ? 'warn' : 'good',
sub: "Risk level: ".concat(((_dashboard_summary3 = dashboard.summary) === null || _dashboard_summary3 === void 0 ? void 0 : _dashboard_summary3.riskLevel) || '-')
},
{
label: 'Deployment Gate',
value: (_dashboard_summary_gateStatus = (_dashboard_summary4 = dashboard.summary) === null || _dashboard_summary4 === void 0 ? void 0 : _dashboard_summary4.gateStatus) !== null && _dashboard_summary_gateStatus !== void 0 ? _dashboard_summary_gateStatus : '-',
cls: ((_dashboard_summary5 = dashboard.summary) === null || _dashboard_summary5 === void 0 ? void 0 : _dashboard_summary5.gateStatus) === 'Ready' ? 'good' : ((_dashboard_summary6 = dashboard.summary) === null || _dashboard_summary6 === void 0 ? void 0 : _dashboard_summary6.gateStatus) === 'Warning' ? 'warn' : 'bad',
sub: ((_dashboard_gate = dashboard.gate) === null || _dashboard_gate === void 0 ? void 0 : _dashboard_gate.message) || ''
},
{
label: 'Open Risks',
value: (_dashboard_summary_openRisks = (_dashboard_summary7 = dashboard.summary) === null || _dashboard_summary7 === void 0 ? void 0 : _dashboard_summary7.openRisks) !== null && _dashboard_summary_openRisks !== void 0 ? _dashboard_summary_openRisks : 0,
cls: (((_dashboard_summary8 = dashboard.summary) === null || _dashboard_summary8 === void 0 ? void 0 : _dashboard_summary8.openRisks) || 0) > 5 ? 'bad' : (((_dashboard_summary9 = dashboard.summary) === null || _dashboard_summary9 === void 0 ? void 0 : _dashboard_summary9.openRisks) || 0) > 2 ? 'warn' : 'good',
sub: "".concat(((_dashboard_summary10 = dashboard.summary) === null || _dashboard_summary10 === void 0 ? void 0 : _dashboard_summary10.totalRisks) || 0, " total risks")
},
{
label: 'Mitigation',
value: "".concat((_dashboard_summary_mitigationCompletion = (_dashboard_summary11 = dashboard.summary) === null || _dashboard_summary11 === void 0 ? void 0 : _dashboard_summary11.mitigationCompletion) !== null && _dashboard_summary_mitigationCompletion !== void 0 ? _dashboard_summary_mitigationCompletion : 0, "%"),
cls: (((_dashboard_summary12 = dashboard.summary) === null || _dashboard_summary12 === void 0 ? void 0 : _dashboard_summary12.mitigationCompletion) || 0) < 40 ? 'bad' : (((_dashboard_summary13 = dashboard.summary) === null || _dashboard_summary13 === void 0 ? void 0 : _dashboard_summary13.mitigationCompletion) || 0) < 70 ? 'warn' : 'good',
sub: 'Average active-risk completion'
}
];
}, [
dashboard
]);
if (!dashboard) return /*#__PURE__*/ _jsx("div", {
className: "empty-state",
children: /*#__PURE__*/ _jsx("p", {
children: "Loading dashboard data..."
})
});
return /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsx("div", {
className: "grid",
style: {
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))'
},
children: panels.map((p)=>/*#__PURE__*/ _jsxs("div", {
className: "metric-card",
children: [
/*#__PURE__*/ _jsx("h3", {
children: p.label
}),
/*#__PURE__*/ _jsx("div", {
className: "metric-value ".concat(p.cls),
children: p.value
}),
/*#__PURE__*/ _jsx("div", {
className: "metric-sub",
children: p.sub
})
]
}, p.label))
}),
/*#__PURE__*/ _jsxs("div", {
className: "grid",
style: {
gridTemplateColumns: '1fr 1fr',
marginTop: 18
},
children: [
/*#__PURE__*/ _jsxs("div", {
className: "panel",
children: [
/*#__PURE__*/ _jsx("h2", {
children: "Dimensions"
}),
(dashboard.dimensions || []).map((dim)=>/*#__PURE__*/ _jsxs("div", {
style: {
marginBottom: 12
},
children: [
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'flex',
justifyContent: 'space-between',
marginBottom: 4
},
children: [
/*#__PURE__*/ _jsx("span", {
style: {
fontSize: 13
},
children: dim.name
}),
/*#__PURE__*/ _jsx("strong", {
style: {
fontSize: 13
},
children: dim.score
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "bar-wrap",
children: /*#__PURE__*/ _jsx("div", {
className: "bar-fill",
style: {
width: "".concat(Math.min(dim.score, 100), "%"),
background: dim.score >= 50 ? 'var(--danger)' : dim.score >= 25 ? 'var(--warn)' : 'var(--accent)'
}
})
})
]
}, dim.name))
]
}),
/*#__PURE__*/ _jsxs("div", {
className: "panel",
children: [
/*#__PURE__*/ _jsx("h2", {
children: "Lifecycle"
}),
(dashboard.lifecycle || []).map((phase)=>/*#__PURE__*/ _jsxs("div", {
style: {
marginBottom: 12
},
children: [
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'flex',
justifyContent: 'space-between',
marginBottom: 4
},
children: [
/*#__PURE__*/ _jsx("span", {
style: {
fontSize: 13
},
children: phase.name
}),
/*#__PURE__*/ _jsxs("span", {
className: "muted",
style: {
fontSize: 12
},
children: [
phase.openRisks,
" open"
]
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "bar-wrap",
children: /*#__PURE__*/ _jsx("div", {
className: "bar-fill",
style: {
width: "".concat(Math.min(phase.riskScore || 0, 100), "%"),
background: (phase.riskScore || 0) >= 50 ? 'var(--danger)' : (phase.riskScore || 0) >= 25 ? 'var(--warn)' : 'var(--accent)'
}
})
})
]
}, phase.name))
]
})
]
})
]
});
}
function RiskFormModal(param) {
let { project, onClose, onSaved, toast } = param;
const [saving, setSaving] = useState(false);
const [form, setForm] = useState({
title: '',
description: '',
dimension: '',
domain: '',
lifecyclePhase: '',
probability: 50,
impact: 50,
detectability: 50,
ownerDisplayName: ''
});
const set = (key)=>(value)=>setForm((f)=>({
...f,
[key]: value
}));
const handleSave = async ()=>{
if (!form.title.trim()) {
toast.add('Title is required', 'error');
return;
}
if (!form.dimension) {
toast.add('Dimension is required', 'error');
return;
}
setSaving(true);
try {
await api.post("/api/projects/".concat(project.id, "/risks"), form);
toast.add('Risk created');
onSaved();
} catch (e) {
toast.add(e.message || 'Failed to create risk', 'error');
} finally{
setSaving(false);
}
};
return /*#__PURE__*/ _jsx("div", {
className: "modal-overlay",
onClick: onClose,
children: /*#__PURE__*/ _jsxs("div", {
className: "modal",
onClick: (e)=>e.stopPropagation(),
style: {
maxWidth: 500
},
children: [
/*#__PURE__*/ _jsx("h2", {
children: "New Risk"
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Title *",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: form.title,
onChange: set('title')
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Description",
children: /*#__PURE__*/ _jsx("textarea", {
className: "input",
value: form.description,
onChange: (e)=>set('description')(e.target.value),
rows: 3,
style: {
width: '100%',
resize: 'vertical'
}
})
}),
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: 8
},
children: [
/*#__PURE__*/ _jsx(FormField, {
label: "Dimension *",
children: /*#__PURE__*/ _jsx(InlineSelect, {
value: form.dimension,
onChange: set('dimension'),
options: DIMENSIONS
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Domain",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: form.domain,
onChange: set('domain')
})
})
]
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Lifecycle Phase",
children: /*#__PURE__*/ _jsx(InlineSelect, {
value: form.lifecyclePhase,
onChange: set('lifecyclePhase'),
options: LIFECYCLE_PHASES
})
}),
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'grid',
gridTemplateColumns: '1fr 1fr 1fr',
gap: 8
},
children: [
/*#__PURE__*/ _jsx(FormField, {
label: "Probability",
children: /*#__PURE__*/ _jsx(InlineInput, {
type: "number",
min: 0,
max: 100,
value: form.probability,
onChange: set('probability')
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Impact",
children: /*#__PURE__*/ _jsx(InlineInput, {
type: "number",
min: 0,
max: 100,
value: form.impact,
onChange: set('impact')
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Detectability",
children: /*#__PURE__*/ _jsx(InlineInput, {
type: "number",
min: 0,
max: 100,
value: form.detectability,
onChange: set('detectability')
})
})
]
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Owner",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: form.ownerDisplayName,
onChange: set('ownerDisplayName')
})
}),
/*#__PURE__*/ _jsxs("div", {
className: "modal-actions",
children: [
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: onClose,
children: "Cancel"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: handleSave,
disabled: saving,
children: saving ? 'Saving...' : 'Create Risk'
})
]
})
]
})
});
}
function RisksTab(param) {
let { project, dashboard, toast, onRefresh } = param;
const [search, setSearch] = useState('');
const [sortKey, setSortKey] = useState('normalizedScore');
const [sortDir, setSortDir] = useState('desc');
const [page, setPage] = useState(0);
const [selectedRisk, setSelectedRisk] = useState(null);
const [showCreate, setShowCreate] = useState(false);
const [editing, setEditing] = useState(false);
const [editForm, setEditForm] = useState({});
const [updating, setUpdating] = useState(null);
const [confirmDelete, setConfirmDelete] = useState(null);
const [deleting, setDeleting] = useState(false);
const risks = useMemo(()=>{
if (!(dashboard === null || dashboard === void 0 ? void 0 : dashboard.topRisks)) return [];
return sortData(dashboard.topRisks, sortKey, sortDir);
}, [
dashboard,
sortKey,
sortDir
]);
const filtered = useMemo(()=>{
if (!search) return risks;
const q = search.toLowerCase();
return risks.filter((r)=>(r.title || '').toLowerCase().includes(q) || (r.dimension || '').toLowerCase().includes(q) || (r.ownerDisplayName || '').toLowerCase().includes(q));
}, [
risks,
search
]);
const paged = filtered.slice(0, (page + 1) * PAGE_SIZE);
const handleSort = (key)=>{
if (sortKey === key) setSortDir((d)=>d === 'asc' ? 'desc' : 'asc');
else {
setSortKey(key);
setSortDir('asc');
}
};
const openDetail = (risk)=>{
setSelectedRisk(risk);
var _risk_probability, _risk_impact, _risk_detectability;
setEditForm({
title: risk.title || '',
description: risk.description || '',
dimension: risk.dimension || '',
domain: risk.domain || '',
lifecyclePhase: risk.lifecyclePhase || '',
probability: (_risk_probability = risk.probability) !== null && _risk_probability !== void 0 ? _risk_probability : 50,
impact: (_risk_impact = risk.impact) !== null && _risk_impact !== void 0 ? _risk_impact : 50,
detectability: (_risk_detectability = risk.detectability) !== null && _risk_detectability !== void 0 ? _risk_detectability : 50,
ownerDisplayName: risk.ownerDisplayName || ''
});
setEditing(false);
setConfirmDelete(null);
};
const updateStatus = async (riskId, status)=>{
setUpdating(riskId);
try {
await api.patch("/api/risks/".concat(riskId), {
status
});
toast.add("Risk status updated to ".concat(status));
setSelectedRisk(null);
onRefresh();
} catch (e) {
toast.add(e.message, 'error');
} finally{
setUpdating(null);
}
};
const saveEdit = async ()=>{
if (!editForm.title.trim()) {
toast.add('Title is required', 'error');
return;
}
setUpdating('edit');
try {
await api.patch("/api/risks/".concat(selectedRisk.id), editForm);
toast.add('Risk updated');
setSelectedRisk(null);
onRefresh();
} catch (e) {
toast.add(e.message || 'Failed to update', 'error');
} finally{
setUpdating(null);
}
};
const handleDelete = async ()=>{
setDeleting(true);
try {
await api.del("/api/risks/".concat(confirmDelete.id));
toast.add('Risk deleted');
setConfirmDelete(null);
setSelectedRisk(null);
onRefresh();
} catch (e) {
toast.add(e.message || 'Failed to delete', 'error');
} finally{
setDeleting(false);
}
};
if (!dashboard) return /*#__PURE__*/ _jsx("div", {
className: "empty-state",
children: /*#__PURE__*/ _jsx("p", {
children: "Loading..."
})
});
return /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'flex',
gap: 8,
marginBottom: 12
},
children: [
/*#__PURE__*/ _jsx(SearchInput, {
value: search,
onChange: setSearch,
placeholder: "Search risks by title, dimension, owner..."
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: ()=>setShowCreate(true),
children: "+ New Risk"
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "table-wrap",
children: /*#__PURE__*/ _jsxs("table", {
className: "table",
children: [
/*#__PURE__*/ _jsx("thead", {
children: /*#__PURE__*/ _jsx("tr", {
children: [
{
key: 'id',
label: 'ID'
},
{
key: 'title',
label: 'Risk'
},
{
key: 'dimension',
label: 'Dimension'
},
{
key: 'lifecyclePhase',
label: 'Phase'
},
{
key: 'normalizedScore',
label: 'Score'
},
{
key: 'residualScore',
label: 'Residual'
},
{
key: 'status',
label: 'Status'
},
{
key: 'ownerDisplayName',
label: 'Owner'
}
].map((col)=>/*#__PURE__*/ _jsxs("th", {
className: "sortable",
onClick: ()=>handleSort(col.key),
children: [
col.label,
" ",
sortKey === col.key ? sortDir === 'asc' ? '▲' : '▼' : ''
]
}, col.key))
})
}),
/*#__PURE__*/ _jsx("tbody", {
children: paged.map((risk)=>{
var _risk_id, _risk_dimension, _risk_status;
return /*#__PURE__*/ _jsxs("tr", {
onClick: ()=>openDetail(risk),
children: [
/*#__PURE__*/ _jsx("td", {
style: {
fontFamily: 'monospace',
fontSize: 12
},
children: (_risk_id = risk.id) === null || _risk_id === void 0 ? void 0 : _risk_id.slice(0, 8)
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx("strong", {
children: risk.title
})
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx(Badge, {
className: (_risk_dimension = risk.dimension) === null || _risk_dimension === void 0 ? void 0 : _risk_dimension.toLowerCase(),
children: risk.dimension
})
}),
/*#__PURE__*/ _jsx("td", {
style: {
fontSize: 12
},
children: risk.lifecyclePhase
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx("strong", {
children: risk.normalizedScore
})
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx("span", {
style: {
color: risk.residualScore >= 50 ? 'var(--danger)' : risk.residualScore >= 25 ? 'var(--warn)' : 'var(--accent)'
},
children: risk.residualScore
})
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx(Badge, {
className: (_risk_status = risk.status) === null || _risk_status === void 0 ? void 0 : _risk_status.toLowerCase().replace(/\s+/g, '-'),
children: risk.status
})
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx("span", {
className: "muted",
children: risk.ownerDisplayName || '-'
})
})
]
}, risk.id);
})
})
]
})
}),
filtered.length > paged.length && /*#__PURE__*/ _jsx("div", {
style: {
textAlign: 'center',
marginTop: 12
},
children: /*#__PURE__*/ _jsxs("button", {
className: "button secondary small",
onClick: ()=>setPage((p)=>p + 1),
children: [
"Show more (",
filtered.length - paged.length,
" remaining)"
]
})
}),
!filtered.length && /*#__PURE__*/ _jsx("div", {
className: "empty-state",
children: /*#__PURE__*/ _jsx("p", {
children: "No risks match your search"
})
}),
showCreate && /*#__PURE__*/ _jsx(RiskFormModal, {
project: project,
onClose: ()=>setShowCreate(false),
onSaved: ()=>{
setShowCreate(false);
onRefresh();
},
toast: toast
}),
selectedRisk && !confirmDelete && /*#__PURE__*/ _jsx("div", {
className: "modal-overlay",
onClick: ()=>setSelectedRisk(null),
children: /*#__PURE__*/ _jsxs("div", {
className: "modal",
onClick: (e)=>e.stopPropagation(),
style: {
maxWidth: 520
},
children: [
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center'
},
children: [
/*#__PURE__*/ _jsx("h2", {
style: {
margin: 0
},
children: selectedRisk.title
}),
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: ()=>setEditing(!editing),
children: editing ? 'View' : 'Edit'
})
]
}),
editing ? /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsxs("div", {
style: {
marginTop: 12
},
children: [
/*#__PURE__*/ _jsx(FormField, {
label: "Title *",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: editForm.title,
onChange: (v)=>setEditForm((f)=>({
...f,
title: v
}))
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Description",
children: /*#__PURE__*/ _jsx("textarea", {
className: "input",
value: editForm.description,
onChange: (e)=>setEditForm((f)=>({
...f,
description: e.target.value
})),
rows: 2,
style: {
width: '100%',
resize: 'vertical'
}
})
}),
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: 8
},
children: [
/*#__PURE__*/ _jsx(FormField, {
label: "Dimension",
children: /*#__PURE__*/ _jsx(InlineSelect, {
value: editForm.dimension,
onChange: (v)=>setEditForm((f)=>({
...f,
dimension: v
})),
options: DIMENSIONS
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Domain",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: editForm.domain,
onChange: (v)=>setEditForm((f)=>({
...f,
domain: v
}))
})
})
]
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Lifecycle Phase",
children: /*#__PURE__*/ _jsx(InlineSelect, {
value: editForm.lifecyclePhase,
onChange: (v)=>setEditForm((f)=>({
...f,
lifecyclePhase: v
})),
options: LIFECYCLE_PHASES
})
}),
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'grid',
gridTemplateColumns: '1fr 1fr 1fr',
gap: 8
},
children: [
/*#__PURE__*/ _jsx(FormField, {
label: "Probability",
children: /*#__PURE__*/ _jsx(InlineInput, {
type: "number",
min: 0,
max: 100,
value: editForm.probability,
onChange: (v)=>setEditForm((f)=>({
...f,
probability: Number(v)
}))
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Impact",
children: /*#__PURE__*/ _jsx(InlineInput, {
type: "number",
min: 0,
max: 100,
value: editForm.impact,
onChange: (v)=>setEditForm((f)=>({
...f,
impact: Number(v)
}))
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Detectability",
children: /*#__PURE__*/ _jsx(InlineInput, {
type: "number",
min: 0,
max: 100,
value: editForm.detectability,
onChange: (v)=>setEditForm((f)=>({
...f,
detectability: Number(v)
}))
})
})
]
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Owner",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: editForm.ownerDisplayName,
onChange: (v)=>setEditForm((f)=>({
...f,
ownerDisplayName: v
}))
})
})
]
}),
/*#__PURE__*/ _jsxs("div", {
className: "modal-actions",
children: [
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: ()=>setSelectedRisk(null),
children: "Cancel"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: saveEdit,
disabled: updating === 'edit',
children: updating === 'edit' ? 'Saving...' : 'Save Changes'
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
style: {
background: 'var(--danger)',
color: '#fff',
marginLeft: 'auto'
},
onClick: ()=>setConfirmDelete(selectedRisk),
children: "Delete"
})
]
})
]
}) : /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: 12,
fontSize: 13,
marginTop: 12
},
children: [
/*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsx("span", {
className: "muted",
children: "Dimension"
}),
/*#__PURE__*/ _jsx("br", {}),
selectedRisk.dimension
]
}),
/*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsx("span", {
className: "muted",
children: "Phase"
}),
/*#__PURE__*/ _jsx("br", {}),
selectedRisk.lifecyclePhase
]
}),
/*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsx("span", {
className: "muted",
children: "Probability"
}),
/*#__PURE__*/ _jsx("br", {}),
selectedRisk.probability
]
}),
/*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsx("span", {
className: "muted",
children: "Impact"
}),
/*#__PURE__*/ _jsx("br", {}),
selectedRisk.impact
]
}),
/*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsx("span", {
className: "muted",
children: "Detectability"
}),
/*#__PURE__*/ _jsx("br", {}),
selectedRisk.detectability
]
}),
/*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsx("span", {
className: "muted",
children: "Score"
}),
/*#__PURE__*/ _jsx("br", {}),
/*#__PURE__*/ _jsx("strong", {
children: selectedRisk.normalizedScore
})
]
}),
/*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsx("span", {
className: "muted",
children: "Residual"
}),
/*#__PURE__*/ _jsx("br", {}),
selectedRisk.residualScore
]
}),
/*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsx("span", {
className: "muted",
children: "Owner"
}),
/*#__PURE__*/ _jsx("br", {}),
selectedRisk.ownerDisplayName || '-'
]
})
]
}),
selectedRisk.description && /*#__PURE__*/ _jsxs("div", {
style: {
marginTop: 12,
fontSize: 13
},
children: [
/*#__PURE__*/ _jsx("span", {
className: "muted",
children: "Description"
}),
/*#__PURE__*/ _jsx("br", {}),
selectedRisk.description
]
}),
/*#__PURE__*/ _jsxs("div", {
style: {
marginTop: 16
},
children: [
/*#__PURE__*/ _jsx("span", {
className: "muted",
style: {
fontSize: 12
},
children: "Update status:"
}),
/*#__PURE__*/ _jsx("div", {
style: {
display: 'flex',
gap: 6,
marginTop: 6,
flexWrap: 'wrap'
},
children: RISK_STATUSES.map((s)=>/*#__PURE__*/ _jsx("button", {
className: "button small ".concat(s === 'OPEN' ? 'secondary' : ''),
onClick: ()=>updateStatus(selectedRisk.id, s),
disabled: updating === selectedRisk.id,
children: s.replace('_', ' ')
}, s))
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "modal-actions",
children: /*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: ()=>setSelectedRisk(null),
children: "Close"
})
})
]
})
]
})
}),
confirmDelete && /*#__PURE__*/ _jsx(ConfirmDelete, {
label: "this risk",
onConfirm: handleDelete,
onCancel: ()=>setConfirmDelete(null),
deleting: deleting
})
]
});
}
function MitigationFormModal(param) {
let { project, risks, onClose, onSaved, toast } = param;
const [saving, setSaving] = useState(false);
const [form, setForm] = useState({
riskId: '',
title: '',
description: '',
status: 'NOT_STARTED',
progressPercent: 0,
effectivenessPercent: 0,
dueDate: '',
ownerDisplayName: ''
});
const set = (key)=>(value)=>setForm((f)=>({
...f,
[key]: value
}));
const handleSave = async ()=>{
if (!form.title.trim()) {
toast.add('Title is required', 'error');
return;
}
if (!form.riskId) {
toast.add('Please select a risk', 'error');
return;
}
setSaving(true);
try {
const body = {
...form,
progressPercent: Number(form.progressPercent),
effectivenessPercent: Number(form.effectivenessPercent)
};
if (body.dueDate) body.dueDate = new Date(body.dueDate).toISOString();
else delete body.dueDate;
await api.post("/api/risks/".concat(form.riskId, "/mitigations"), body);
toast.add('Mitigation created');
onSaved();
} catch (e) {
toast.add(e.message || 'Failed to create mitigation', 'error');
} finally{
setSaving(false);
}
};
return /*#__PURE__*/ _jsx("div", {
className: "modal-overlay",
onClick: onClose,
children: /*#__PURE__*/ _jsxs("div", {
className: "modal",
onClick: (e)=>e.stopPropagation(),
style: {
maxWidth: 500
},
children: [
/*#__PURE__*/ _jsx("h2", {
children: "New Mitigation"
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Risk *",
children: /*#__PURE__*/ _jsx(InlineSelect, {
value: form.riskId,
onChange: set('riskId'),
options: (risks || []).map((r)=>({
value: r.id,
label: r.title
}))
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Title *",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: form.title,
onChange: set('title')
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Description",
children: /*#__PURE__*/ _jsx("textarea", {
className: "input",
value: form.description,
onChange: (e)=>set('description')(e.target.value),
rows: 2,
style: {
width: '100%',
resize: 'vertical'
}
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Status",
children: /*#__PURE__*/ _jsx(InlineSelect, {
value: form.status,
onChange: set('status'),
options: MITIGATION_STATUSES
})
}),
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: 8
},
children: [
/*#__PURE__*/ _jsx(FormField, {
label: "Progress %",
children: /*#__PURE__*/ _jsx(InlineInput, {
type: "number",
min: 0,
max: 100,
value: form.progressPercent,
onChange: set('progressPercent')
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Effectiveness %",
children: /*#__PURE__*/ _jsx(InlineInput, {
type: "number",
min: 0,
max: 100,
value: form.effectivenessPercent,
onChange: set('effectivenessPercent')
})
})
]
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Due Date",
children: /*#__PURE__*/ _jsx(InlineInput, {
type: "date",
value: form.dueDate,
onChange: set('dueDate')
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Owner",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: form.ownerDisplayName,
onChange: set('ownerDisplayName')
})
}),
/*#__PURE__*/ _jsxs("div", {
className: "modal-actions",
children: [
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: onClose,
children: "Cancel"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: handleSave,
disabled: saving,
children: saving ? 'Saving...' : 'Create Mitigation'
})
]
})
]
})
});
}
function MitigationsTab(param) {
let { project, dashboard, toast, onRefresh } = param;
const [search, setSearch] = useState('');
const [sortKey, setSortKey] = useState('progressPercent');
const [sortDir, setSortDir] = useState('asc');
const [showCreate, setShowCreate] = useState(false);
const [selectedMitigation, setSelectedMitigation] = useState(null);
const [editing, setEditing] = useState(false);
const [editForm, setEditForm] = useState({});
const [updating, setUpdating] = useState(null);
const [confirmDelete, setConfirmDelete] = useState(null);
const [deleting, setDeleting] = useState(false);
const mitigations = useMemo(()=>{
if (!(dashboard === null || dashboard === void 0 ? void 0 : dashboard.mitigations)) return [];
return sortData(dashboard.mitigations, sortKey, sortDir);
}, [
dashboard,
sortKey,
sortDir
]);
const risks = useMemo(()=>{
if (!(dashboard === null || dashboard === void 0 ? void 0 : dashboard.topRisks)) return [];
return dashboard.topRisks;
}, [
dashboard
]);
const filtered = useMemo(()=>{
if (!search) return mitigations;
const q = search.toLowerCase();
return mitigations.filter((m)=>(m.title || '').toLowerCase().includes(q) || (m.riskTitle || '').toLowerCase().includes(q));
}, [
mitigations,
search
]);
const handleSort = (key)=>{
if (sortKey === key) setSortDir((d)=>d === 'asc' ? 'desc' : 'asc');
else {
setSortKey(key);
setSortDir('asc');
}
};
const openDetail = (m)=>{
setSelectedMitigation(m);
var _m_progressPercent, _m_effectivenessPercent;
setEditForm({
title: m.title || '',
description: m.description || '',
status: m.status || 'NOT_STARTED',
progressPercent: (_m_progressPercent = m.progressPercent) !== null && _m_progressPercent !== void 0 ? _m_progressPercent : 0,
effectivenessPercent: (_m_effectivenessPercent = m.effectivenessPercent) !== null && _m_effectivenessPercent !== void 0 ? _m_effectivenessPercent : 0,
dueDate: m.dueDate ? m.dueDate.slice(0, 10) : '',
ownerDisplayName: m.ownerDisplayName || ''
});
setEditing(true);
setConfirmDelete(null);
};
const saveEdit = async ()=>{
if (!editForm.title.trim()) {
toast.add('Title is required', 'error');
return;
}
setUpdating('edit');
try {
const body = {
...editForm,
progressPercent: Number(editForm.progressPercent),
effectivenessPercent: Number(editForm.effectivenessPercent)
};
if (body.dueDate) body.dueDate = new Date(body.dueDate).toISOString();
else body.dueDate = null;
await api.patch("/api/mitigations/".concat(selectedMitigation.id), body);
toast.add('Mitigation updated');
setSelectedMitigation(null);
onRefresh();
} catch (e) {
toast.add(e.message || 'Failed to update', 'error');
} finally{
setUpdating(null);
}
};
const handleDelete = async ()=>{
setDeleting(true);
try {
await api.del("/api/mitigations/".concat(confirmDelete.id));
toast.add('Mitigation deleted');
setConfirmDelete(null);
setSelectedMitigation(null);
onRefresh();
} catch (e) {
toast.add(e.message || 'Failed to delete', 'error');
} finally{
setDeleting(false);
}
};
if (!dashboard) return /*#__PURE__*/ _jsx("div", {
className: "empty-state",
children: /*#__PURE__*/ _jsx("p", {
children: "Loading..."
})
});
return /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'flex',
gap: 8,
marginBottom: 12
},
children: [
/*#__PURE__*/ _jsx(SearchInput, {
value: search,
onChange: setSearch,
placeholder: "Search mitigations..."
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: ()=>setShowCreate(true),
children: "+ New Mitigation"
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "table-wrap",
children: /*#__PURE__*/ _jsxs("table", {
className: "table",
children: [
/*#__PURE__*/ _jsx("thead", {
children: /*#__PURE__*/ _jsx("tr", {
children: [
{
key: 'title',
label: 'Title'
},
{
key: 'riskTitle',
label: 'Risk'
},
{
key: 'status',
label: 'Status'
},
{
key: 'progressPercent',
label: 'Progress'
},
{
key: 'effectivenessPercent',
label: 'Effectiveness'
},
{
key: 'ownerDisplayName',
label: 'Owner'
}
].map((col)=>/*#__PURE__*/ _jsxs("th", {
className: "sortable",
onClick: ()=>handleSort(col.key),
children: [
col.label,
" ",
sortKey === col.key ? sortDir === 'asc' ? '▲' : '▼' : ''
]
}, col.key))
})
}),
/*#__PURE__*/ _jsx("tbody", {
children: filtered.slice(0, 50).map((m)=>{
var _m_status;
return /*#__PURE__*/ _jsxs("tr", {
onClick: ()=>openDetail(m),
style: {
cursor: 'pointer'
},
children: [
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx("strong", {
children: m.title
})
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx("span", {
className: "muted",
children: m.riskTitle
})
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx(Badge, {
className: (_m_status = m.status) === null || _m_status === void 0 ? void 0 : _m_status.toLowerCase().replace(/\s+/g, '-'),
children: m.status
})
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsxs("div", {
style: {
display: 'flex',
alignItems: 'center',
gap: 8
},
children: [
/*#__PURE__*/ _jsx("div", {
className: "bar-wrap",
style: {
flex: 1,
maxWidth: 80
},
children: /*#__PURE__*/ _jsx("div", {
className: "bar-fill",
style: {
width: "".concat(m.progressPercent || 0, "%"),
background: (m.progressPercent || 0) >= 80 ? 'var(--accent)' : (m.progressPercent || 0) >= 30 ? 'var(--warn)' : 'var(--danger)'
}
})
}),
m.progressPercent || 0,
"%"
]
})
}),
/*#__PURE__*/ _jsxs("td", {
children: [
m.effectivenessPercent || 0,
"%"
]
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx("span", {
className: "muted",
children: m.ownerDisplayName || '-'
})
})
]
}, m.id);
})
})
]
})
}),
!filtered.length && /*#__PURE__*/ _jsx("div", {
className: "empty-state",
children: /*#__PURE__*/ _jsx("p", {
children: "No mitigations found"
})
}),
showCreate && /*#__PURE__*/ _jsx(MitigationFormModal, {
project: project,
risks: risks,
onClose: ()=>setShowCreate(false),
onSaved: ()=>{
setShowCreate(false);
onRefresh();
},
toast: toast
}),
selectedMitigation && !confirmDelete && /*#__PURE__*/ _jsx("div", {
className: "modal-overlay",
onClick: ()=>setSelectedMitigation(null),
children: /*#__PURE__*/ _jsxs("div", {
className: "modal",
onClick: (e)=>e.stopPropagation(),
style: {
maxWidth: 500
},
children: [
/*#__PURE__*/ _jsx("h2", {
style: {
margin: 0
},
children: editing ? 'Edit Mitigation' : selectedMitigation.title
}),
/*#__PURE__*/ _jsxs("div", {
style: {
marginTop: 12
},
children: [
/*#__PURE__*/ _jsx(FormField, {
label: "Title *",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: editForm.title,
onChange: (v)=>setEditForm((f)=>({
...f,
title: v
}))
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Description",
children: /*#__PURE__*/ _jsx("textarea", {
className: "input",
value: editForm.description,
onChange: (e)=>setEditForm((f)=>({
...f,
description: e.target.value
})),
rows: 2,
style: {
width: '100%',
resize: 'vertical'
}
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Status",
children: /*#__PURE__*/ _jsx(InlineSelect, {
value: editForm.status,
onChange: (v)=>setEditForm((f)=>({
...f,
status: v
})),
options: MITIGATION_STATUSES
})
}),
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: 8
},
children: [
/*#__PURE__*/ _jsx(FormField, {
label: "Progress %",
children: /*#__PURE__*/ _jsx(InlineInput, {
type: "number",
min: 0,
max: 100,
value: editForm.progressPercent,
onChange: (v)=>setEditForm((f)=>({
...f,
progressPercent: Number(v)
}))
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Effectiveness %",
children: /*#__PURE__*/ _jsx(InlineInput, {
type: "number",
min: 0,
max: 100,
value: editForm.effectivenessPercent,
onChange: (v)=>setEditForm((f)=>({
...f,
effectivenessPercent: Number(v)
}))
})
})
]
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Due Date",
children: /*#__PURE__*/ _jsx(InlineInput, {
type: "date",
value: editForm.dueDate,
onChange: (v)=>setEditForm((f)=>({
...f,
dueDate: v
}))
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Owner",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: editForm.ownerDisplayName,
onChange: (v)=>setEditForm((f)=>({
...f,
ownerDisplayName: v
}))
})
})
]
}),
/*#__PURE__*/ _jsxs("div", {
className: "modal-actions",
children: [
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: ()=>setSelectedMitigation(null),
children: "Cancel"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: saveEdit,
disabled: updating === 'edit',
children: updating === 'edit' ? 'Saving...' : 'Save Changes'
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
style: {
background: 'var(--danger)',
color: '#fff',
marginLeft: 'auto'
},
onClick: ()=>setConfirmDelete(selectedMitigation),
children: "Delete"
})
]
})
]
})
}),
confirmDelete && /*#__PURE__*/ _jsx(ConfirmDelete, {
label: "this mitigation",
onConfirm: handleDelete,
onCancel: ()=>setConfirmDelete(null),
deleting: deleting
})
]
});
}
function GateTab(param) {
let { project, dashboard, toast, onRefresh } = param;
var _dashboard_gate, _dashboard_summary, _dashboard_gate1;
const [evaluating, setEvaluating] = useState(false);
const [showDecision, setShowDecision] = useState(false);
const [decisionForm, setDecisionForm] = useState({
decision: 'APPROVED',
reviewerName: '',
reason: ''
});
const [savingDecision, setSavingDecision] = useState(false);
const criteria = (dashboard === null || dashboard === void 0 ? void 0 : (_dashboard_gate = dashboard.gate) === null || _dashboard_gate === void 0 ? void 0 : _dashboard_gate.criteria) || [];
const gateStatus = (dashboard === null || dashboard === void 0 ? void 0 : (_dashboard_summary = dashboard.summary) === null || _dashboard_summary === void 0 ? void 0 : _dashboard_summary.gateStatus) || 'Unknown';
const gateId = dashboard === null || dashboard === void 0 ? void 0 : (_dashboard_gate1 = dashboard.gate) === null || _dashboard_gate1 === void 0 ? void 0 : _dashboard_gate1.id;
const gateCls = gateStatus === 'Ready' ? 'good' : gateStatus === 'Warning' ? 'warn' : 'bad';
const handleEvaluate = async ()=>{
setEvaluating(true);
try {
await api.post("/api/projects/".concat(project.id, "/gate/evaluate"), {});
toast.add('Gate evaluated');
onRefresh();
} catch (e) {
toast.add(e.message || 'Evaluation failed', 'error');
} finally{
setEvaluating(false);
}
};
const submitDecision = async ()=>{
if (!decisionForm.reviewerName.trim()) {
toast.add('Reviewer name is required', 'error');
return;
}
setSavingDecision(true);
try {
await api.post("/api/gates/".concat(gateId, "/decisions"), decisionForm);
toast.add('Decision submitted');
setShowDecision(false);
onRefresh();
} catch (e) {
toast.add(e.message || 'Failed to submit decision', 'error');
} finally{
setSavingDecision(false);
}
};
if (!dashboard) return /*#__PURE__*/ _jsx("div", {
className: "empty-state",
children: /*#__PURE__*/ _jsx("p", {
children: "Loading..."
})
});
return /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsxs("div", {
className: "dash-header",
children: [
/*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsx("h1", {
children: "Deployment Gate"
}),
/*#__PURE__*/ _jsx("p", {
className: "muted",
children: "Gate evaluation for AI deployment readiness"
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "dash-actions",
children: /*#__PURE__*/ _jsx("div", {
className: "metric-value ".concat(gateCls),
style: {
fontSize: 28
},
children: gateStatus
})
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "table-wrap",
children: /*#__PURE__*/ _jsxs("table", {
className: "table",
children: [
/*#__PURE__*/ _jsx("thead", {
children: /*#__PURE__*/ _jsxs("tr", {
children: [
/*#__PURE__*/ _jsx("th", {
children: "Criterion"
}),
/*#__PURE__*/ _jsx("th", {
children: "Required"
}),
/*#__PURE__*/ _jsx("th", {
children: "Actual"
}),
/*#__PURE__*/ _jsx("th", {
children: "Status"
})
]
})
}),
/*#__PURE__*/ _jsx("tbody", {
children: criteria.map((c)=>{
var _c_status;
return /*#__PURE__*/ _jsxs("tr", {
children: [
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx("strong", {
children: c.name
})
}),
/*#__PURE__*/ _jsx("td", {
children: c.required
}),
/*#__PURE__*/ _jsx("td", {
children: c.actual
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx(Badge, {
className: (_c_status = c.status) === null || _c_status === void 0 ? void 0 : _c_status.toLowerCase(),
children: c.status
})
})
]
}, c.name);
})
})
]
})
}),
!criteria.length && /*#__PURE__*/ _jsx("div", {
className: "empty-state",
children: /*#__PURE__*/ _jsx("p", {
children: "No gate criteria evaluated yet"
})
}),
/*#__PURE__*/ _jsxs("div", {
style: {
marginTop: 16,
display: 'flex',
gap: 8,
flexWrap: 'wrap'
},
children: [
/*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: handleEvaluate,
disabled: evaluating,
children: evaluating ? 'Evaluating...' : 'Evaluate Gate'
}),
gateId && /*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: ()=>setShowDecision(true),
children: "Add Decision"
}),
/*#__PURE__*/ _jsx("a", {
href: "/api/projects/".concat(project === null || project === void 0 ? void 0 : project.id, "/gate/history"),
className: "button secondary small",
target: "_blank",
children: "History (API)"
})
]
}),
showDecision && /*#__PURE__*/ _jsx("div", {
className: "modal-overlay",
onClick: ()=>setShowDecision(false),
children: /*#__PURE__*/ _jsxs("div", {
className: "modal",
onClick: (e)=>e.stopPropagation(),
style: {
maxWidth: 400
},
children: [
/*#__PURE__*/ _jsx("h2", {
children: "Gate Decision"
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Decision",
children: /*#__PURE__*/ _jsx(InlineSelect, {
value: decisionForm.decision,
onChange: (v)=>setDecisionForm((f)=>({
...f,
decision: v
})),
options: [
'APPROVED',
'REJECTED',
'ACCEPTED',
'NEEDS_CHANGES'
]
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Reviewer Name *",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: decisionForm.reviewerName,
onChange: (v)=>setDecisionForm((f)=>({
...f,
reviewerName: v
}))
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Reason",
children: /*#__PURE__*/ _jsx("textarea", {
className: "input",
value: decisionForm.reason,
onChange: (e)=>setDecisionForm((f)=>({
...f,
reason: e.target.value
})),
rows: 3,
style: {
width: '100%',
resize: 'vertical'
}
})
}),
/*#__PURE__*/ _jsxs("div", {
className: "modal-actions",
children: [
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: ()=>setShowDecision(false),
children: "Cancel"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: submitDecision,
disabled: savingDecision,
children: savingDecision ? 'Saving...' : 'Submit Decision'
})
]
})
]
})
})
]
});
}
function IntegrationFormModal(param) {
let { project, dashboard, onClose, onSaved, toast } = param;
var _dashboard_gate;
const [saving, setSaving] = useState(false);
const [form, setForm] = useState({
provider: 'TRELLO',
workspaceName: '',
baseUrl: '',
authMode: 'API_KEY'
});
const set = (key)=>(value)=>setForm((f)=>({
...f,
[key]: value
}));
const wsId = (dashboard === null || dashboard === void 0 ? void 0 : (_dashboard_gate = dashboard.gate) === null || _dashboard_gate === void 0 ? void 0 : _dashboard_gate.workspaceId) || (project === null || project === void 0 ? void 0 : project.workspaceId);
const handleSave = async ()=>{
if (!form.workspaceName.trim()) {
toast.add('Workspace name is required', 'error');
return;
}
setSaving(true);
try {
await api.post("/api/workspaces/".concat(wsId, "/integrations"), form);
toast.add('Integration created');
onSaved();
} catch (e) {
toast.add(e.message || 'Failed to create integration', 'error');
} finally{
setSaving(false);
}
};
return /*#__PURE__*/ _jsx("div", {
className: "modal-overlay",
onClick: onClose,
children: /*#__PURE__*/ _jsxs("div", {
className: "modal",
onClick: (e)=>e.stopPropagation(),
style: {
maxWidth: 450
},
children: [
/*#__PURE__*/ _jsx("h2", {
children: "New Integration"
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Provider",
children: /*#__PURE__*/ _jsx(InlineSelect, {
value: form.provider,
onChange: set('provider'),
options: [
'TRELLO',
'JIRA',
'ASANA',
'MICROSOFT_PLANNER'
]
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Workspace Name *",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: form.workspaceName,
onChange: set('workspaceName')
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Base URL",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: form.baseUrl,
onChange: set('baseUrl')
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Auth Mode",
children: /*#__PURE__*/ _jsx(InlineSelect, {
value: form.authMode,
onChange: set('authMode'),
options: [
'API_KEY',
'OAUTH',
'BASIC'
]
})
}),
/*#__PURE__*/ _jsxs("div", {
className: "modal-actions",
children: [
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: onClose,
children: "Cancel"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: handleSave,
disabled: saving,
children: saving ? 'Saving...' : 'Create Integration'
})
]
})
]
})
});
}
function IntegrationsTab(param) {
let { project, dashboard, toast, onRefresh } = param;
const [showCreate, setShowCreate] = useState(false);
const integrations = (dashboard === null || dashboard === void 0 ? void 0 : dashboard.integrations) || [];
return /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsxs("div", {
className: "dash-header",
children: [
/*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsx("h1", {
children: "Integrations"
}),
/*#__PURE__*/ _jsx("p", {
className: "muted",
children: "Connect Trello, Jira, Asana, or Microsoft Planner"
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "dash-actions",
children: /*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: ()=>setShowCreate(true),
children: "+ New Integration"
})
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "grid",
style: {
gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))'
},
children: [
'TRELLO',
'JIRA',
'ASANA',
'MICROSOFT_PLANNER'
].map((provider)=>{
const existing = integrations.find((i)=>i.provider === provider);
return /*#__PURE__*/ _jsxs("div", {
className: "panel",
style: {
textAlign: 'center'
},
children: [
/*#__PURE__*/ _jsx("div", {
style: {
fontSize: 32,
marginBottom: 8
},
children: provider === 'TRELLO' ? '⊞' : provider === 'JIRA' ? '◆' : provider === 'ASANA' ? '◇' : '▣'
}),
/*#__PURE__*/ _jsx("h3", {
style: {
margin: '0 0 4px'
},
children: provider.replace('_', ' ')
}),
/*#__PURE__*/ _jsx("p", {
className: "muted",
style: {
fontSize: 12,
margin: '0 0 12px'
},
children: existing ? existing.workspaceName : 'Not configured'
}),
/*#__PURE__*/ _jsx("div", {
style: {
display: 'flex',
gap: 6,
justifyContent: 'center'
},
children: existing ? /*#__PURE__*/ _jsx("a", {
href: "/api/integrations/".concat(existing.id),
className: "button secondary small",
target: "_blank",
children: "Manage"
}) : /*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: ()=>setShowCreate(true),
children: "Configure"
})
})
]
}, provider);
})
}),
showCreate && /*#__PURE__*/ _jsx(IntegrationFormModal, {
project: project,
dashboard: dashboard,
onClose: ()=>setShowCreate(false),
onSaved: ()=>{
setShowCreate(false);
onRefresh();
},
toast: toast
}),
!integrations.length && /*#__PURE__*/ _jsx("div", {
style: {
marginTop: 12
},
children: /*#__PURE__*/ _jsx("a", {
href: "/api/integration-providers",
className: "button secondary small",
target: "_blank",
children: "Integration providers (API)"
})
})
]
});
}
function AuditTab(param) {
let { project, toast } = param;
const [events, setEvents] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const load = useCallback(async ()=>{
if (!project) return;
setLoading(true);
setError(null);
try {
const resp = await api.get("/api/projects/".concat(project.id, "/audit"));
setEvents(resp.auditEvents || []);
} catch (e) {
setError(e.message || 'Failed to load audit log');
} finally{
setLoading(false);
}
}, [
project
]);
useEffect(()=>{
load();
}, [
load
]);
if (loading) return /*#__PURE__*/ _jsx("div", {
className: "empty-state",
children: /*#__PURE__*/ _jsx("p", {
children: "Loading audit log..."
})
});
if (error) return /*#__PURE__*/ _jsx("div", {
className: "empty-state",
children: /*#__PURE__*/ _jsx("p", {
children: error
})
});
if (!events.length) return /*#__PURE__*/ _jsx("div", {
className: "empty-state",
children: /*#__PURE__*/ _jsx("p", {
children: "No audit events recorded yet"
})
});
return /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsxs("div", {
className: "dash-header",
children: [
/*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsx("h1", {
children: "Audit Log"
}),
/*#__PURE__*/ _jsx("p", {
className: "muted",
children: "Project activity history"
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "dash-actions",
children: /*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: load,
children: "Refresh"
})
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "table-wrap",
children: /*#__PURE__*/ _jsxs("table", {
className: "table",
children: [
/*#__PURE__*/ _jsx("thead", {
children: /*#__PURE__*/ _jsxs("tr", {
children: [
/*#__PURE__*/ _jsx("th", {
children: "Date"
}),
/*#__PURE__*/ _jsx("th", {
children: "Action"
}),
/*#__PURE__*/ _jsx("th", {
children: "Entity"
}),
/*#__PURE__*/ _jsx("th", {
children: "Actor"
}),
/*#__PURE__*/ _jsx("th", {
children: "Details"
})
]
})
}),
/*#__PURE__*/ _jsx("tbody", {
children: events.map((e)=>{
var _e_action, _e_entityId;
return /*#__PURE__*/ _jsxs("tr", {
children: [
/*#__PURE__*/ _jsx("td", {
style: {
fontSize: 12,
whiteSpace: 'nowrap'
},
children: new Date(e.createdAt).toLocaleString()
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx(Badge, {
className: (_e_action = e.action) === null || _e_action === void 0 ? void 0 : _e_action.toLowerCase().replace(/\s+/g, '-'),
children: e.action
})
}),
/*#__PURE__*/ _jsxs("td", {
style: {
fontSize: 12
},
children: [
e.entityType,
" ",
/*#__PURE__*/ _jsxs("span", {
className: "muted",
children: [
"(",
(_e_entityId = e.entityId) === null || _e_entityId === void 0 ? void 0 : _e_entityId.slice(0, 8),
")"
]
})
]
}),
/*#__PURE__*/ _jsx("td", {
style: {
fontSize: 12
},
children: e.actorUserId || 'system'
}),
/*#__PURE__*/ _jsx("td", {
style: {
fontSize: 12,
maxWidth: 300,
overflow: 'hidden',
textOverflow: 'ellipsis'
},
children: e.afterJson ? JSON.stringify(e.afterJson).slice(0, 80) : '-'
})
]
}, e.id);
})
})
]
})
})
]
});
}
function ProjectsTab(param) {
let { projects, workspaceId, currentProjectId, onSwitch, onRefresh, toast } = param;
const [deleting, setDeleting] = useState(null);
const [confirmDelete, setConfirmDelete] = useState(null);
const [showNew, setShowNew] = useState(false);
const handleDelete = async ()=>{
setDeleting(true);
try {
await api.del("/api/projects/".concat(confirmDelete.id));
toast.add('Project "'.concat(confirmDelete.name, '" deleted'));
setConfirmDelete(null);
onRefresh();
} catch (e) {
toast.add(e.message || 'Failed to delete project', 'error');
} finally{
setDeleting(false);
}
};
return /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsxs("div", {
className: "dash-header",
children: [
/*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsx("h1", {
children: "All Projects"
}),
/*#__PURE__*/ _jsxs("p", {
className: "muted",
children: [
projects.length,
" project(s) in workspace"
]
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "dash-actions",
children: /*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: ()=>setShowNew(true),
children: "+ New Project"
})
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "table-wrap",
children: /*#__PURE__*/ _jsxs("table", {
className: "table",
children: [
/*#__PURE__*/ _jsx("thead", {
children: /*#__PURE__*/ _jsxs("tr", {
children: [
/*#__PURE__*/ _jsx("th", {
children: "Name"
}),
/*#__PURE__*/ _jsx("th", {
children: "Status"
}),
/*#__PURE__*/ _jsx("th", {
children: "Type"
}),
/*#__PURE__*/ _jsx("th", {
children: "Created"
}),
/*#__PURE__*/ _jsx("th", {
children: "Actions"
})
]
})
}),
/*#__PURE__*/ _jsx("tbody", {
children: [
...projects
].sort((a, b)=>new Date(b.createdAt) - new Date(a.createdAt)).map((p)=>{
var _p_status;
return /*#__PURE__*/ _jsxs("tr", {
style: {
background: p.id === currentProjectId ? 'var(--surface-alt)' : ''
},
children: [
/*#__PURE__*/ _jsxs("td", {
children: [
/*#__PURE__*/ _jsx("strong", {
children: p.name
}),
p.id === currentProjectId ? /*#__PURE__*/ _jsx("span", {
className: "muted",
style: {
fontSize: 11,
marginLeft: 6
},
children: "(current)"
}) : '',
p.description ? /*#__PURE__*/ _jsx("div", {
className: "muted",
style: {
fontSize: 11
},
children: p.description
}) : ''
]
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx(Badge, {
className: (_p_status = p.status) === null || _p_status === void 0 ? void 0 : _p_status.toLowerCase(),
children: p.status
})
}),
/*#__PURE__*/ _jsx("td", {
style: {
fontSize: 12
},
children: p.projectType
}),
/*#__PURE__*/ _jsx("td", {
style: {
fontSize: 12
},
children: new Date(p.createdAt).toLocaleDateString()
}),
/*#__PURE__*/ _jsxs("td", {
style: {
textAlign: 'right',
whiteSpace: 'nowrap'
},
children: [
p.id !== currentProjectId && /*#__PURE__*/ _jsx("button", {
className: "button secondary small",
style: {
marginRight: 6
},
onClick: ()=>onSwitch(p.id),
children: "Open"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
style: {
background: 'var(--danger)',
color: '#fff'
},
onClick: ()=>setConfirmDelete(p),
disabled: deleting === p.id,
children: "Delete"
})
]
})
]
}, p.id);
})
})
]
})
}),
!projects.length && /*#__PURE__*/ _jsx("div", {
className: "empty-state",
children: /*#__PURE__*/ _jsx("p", {
children: "No projects yet. Create one to get started."
})
}),
showNew && /*#__PURE__*/ _jsx(NewProjectModal, {
workspaceId: workspaceId,
onClose: ()=>setShowNew(false),
onSaved: ()=>{
setShowNew(false);
onRefresh();
},
toast: toast
}),
confirmDelete && /*#__PURE__*/ _jsx("div", {
className: "modal-overlay",
onClick: ()=>setConfirmDelete(null),
children: /*#__PURE__*/ _jsxs("div", {
className: "modal",
onClick: (e)=>e.stopPropagation(),
style: {
maxWidth: 380
},
children: [
/*#__PURE__*/ _jsxs("h3", {
children: [
'Delete "',
confirmDelete.name,
'"?'
]
}),
/*#__PURE__*/ _jsx("p", {
style: {
fontSize: 13,
color: 'var(--muted)'
},
children: "This permanently deletes the project and all its risks, mitigations, and data."
}),
/*#__PURE__*/ _jsxs("div", {
className: "modal-actions",
children: [
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: ()=>setConfirmDelete(null),
children: "Cancel"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
style: {
background: 'var(--danger)',
color: '#fff'
},
onClick: handleDelete,
disabled: deleting,
children: deleting ? 'Deleting...' : 'Delete Project'
})
]
})
]
})
})
]
});
}
function ProjectSettingsModal(param) {
let { project, onClose, onSaved, toast } = param;
const [saving, setSaving] = useState(false);
const [form, setForm] = useState({
name: (project === null || project === void 0 ? void 0 : project.name) || '',
description: (project === null || project === void 0 ? void 0 : project.description) || '',
subtitle: (project === null || project === void 0 ? void 0 : project.subtitle) || '',
status: (project === null || project === void 0 ? void 0 : project.status) || 'Active'
});
const handleSave = async ()=>{
if (!form.name.trim()) {
toast.add('Project name is required', 'error');
return;
}
setSaving(true);
try {
await api.patch("/api/projects/".concat(project.id), form);
toast.add('Project updated');
onSaved();
} catch (e) {
toast.add(e.message || 'Failed to update project', 'error');
} finally{
setSaving(false);
}
};
return /*#__PURE__*/ _jsx("div", {
className: "modal-overlay",
onClick: onClose,
children: /*#__PURE__*/ _jsxs("div", {
className: "modal",
onClick: (e)=>e.stopPropagation(),
style: {
maxWidth: 450
},
children: [
/*#__PURE__*/ _jsx("h2", {
children: "Project Settings"
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Name *",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: form.name,
onChange: (v)=>setForm((f)=>({
...f,
name: v
}))
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Subtitle",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: form.subtitle,
onChange: (v)=>setForm((f)=>({
...f,
subtitle: v
}))
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Description",
children: /*#__PURE__*/ _jsx("textarea", {
className: "input",
value: form.description,
onChange: (e)=>setForm((f)=>({
...f,
description: e.target.value
})),
rows: 3,
style: {
width: '100%',
resize: 'vertical'
}
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Status",
children: /*#__PURE__*/ _jsx(InlineSelect, {
value: form.status,
onChange: (v)=>setForm((f)=>({
...f,
status: v
})),
options: [
'Active',
'Archived',
'On Hold'
]
})
}),
/*#__PURE__*/ _jsxs("div", {
className: "modal-actions",
children: [
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: onClose,
children: "Cancel"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: handleSave,
disabled: saving,
children: saving ? 'Saving...' : 'Save Changes'
})
]
})
]
})
});
}
function NewProjectModal(param) {
let { workspaceId, onClose, onSaved, toast } = param;
const [saving, setSaving] = useState(false);
const [form, setForm] = useState({
name: '',
description: '',
projectType: 'AI-Enabler'
});
const handleSave = async ()=>{
if (!form.name.trim()) {
toast.add('Project name is required', 'error');
return;
}
setSaving(true);
try {
await api.post("/api/workspaces/".concat(workspaceId, "/projects"), form);
toast.add('Project created');
onSaved();
} catch (e) {
toast.add(e.message || 'Failed to create project', 'error');
} finally{
setSaving(false);
}
};
return /*#__PURE__*/ _jsx("div", {
className: "modal-overlay",
onClick: onClose,
children: /*#__PURE__*/ _jsxs("div", {
className: "modal",
onClick: (e)=>e.stopPropagation(),
style: {
maxWidth: 450
},
children: [
/*#__PURE__*/ _jsx("h2", {
children: "New Project"
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Name *",
children: /*#__PURE__*/ _jsx(InlineInput, {
value: form.name,
onChange: (v)=>setForm((f)=>({
...f,
name: v
}))
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Description",
children: /*#__PURE__*/ _jsx("textarea", {
className: "input",
value: form.description,
onChange: (e)=>setForm((f)=>({
...f,
description: e.target.value
})),
rows: 3,
style: {
width: '100%',
resize: 'vertical'
}
})
}),
/*#__PURE__*/ _jsx(FormField, {
label: "Project Type",
children: /*#__PURE__*/ _jsx(InlineSelect, {
value: form.projectType,
onChange: (v)=>setForm((f)=>({
...f,
projectType: v
})),
options: [
'AI-Enabler',
'GENERATIVE_AI',
'ML-Pipeline',
'Automation'
]
})
}),
/*#__PURE__*/ _jsxs("div", {
className: "modal-actions",
children: [
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: onClose,
children: "Cancel"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: handleSave,
disabled: saving,
children: saving ? 'Saving...' : 'Create Project'
})
]
})
]
})
});
}
function ProjectManagerModal(param) {
let { projects, workspaceId, currentProjectId, onClose, onSwitch, onSaved, toast } = param;
const [deleting, setDeleting] = useState(null);
const [confirmDelete, setConfirmDelete] = useState(null);
const [showNew, setShowNew] = useState(false);
const handleDelete = async ()=>{
setDeleting(true);
try {
await api.del("/api/projects/".concat(confirmDelete.id));
toast.add('Project "'.concat(confirmDelete.name, '" deleted'));
setConfirmDelete(null);
onSaved();
} catch (e) {
toast.add(e.message || 'Failed to delete project', 'error');
} finally{
setDeleting(false);
}
};
return /*#__PURE__*/ _jsxs("div", {
className: "modal-overlay",
onClick: onClose,
children: [
/*#__PURE__*/ _jsxs("div", {
className: "modal",
onClick: (e)=>e.stopPropagation(),
style: {
maxWidth: 700,
maxHeight: '80vh',
overflow: 'auto'
},
children: [
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center'
},
children: [
/*#__PURE__*/ _jsx("h2", {
style: {
margin: 0
},
children: "All Projects"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: ()=>setShowNew(true),
children: "+ New Project"
})
]
}),
/*#__PURE__*/ _jsxs("p", {
className: "muted",
style: {
fontSize: 12,
marginTop: 4
},
children: [
projects.length,
" project(s) in workspace"
]
}),
/*#__PURE__*/ _jsx("div", {
className: "table-wrap",
style: {
marginTop: 12
},
children: /*#__PURE__*/ _jsxs("table", {
className: "table",
children: [
/*#__PURE__*/ _jsx("thead", {
children: /*#__PURE__*/ _jsxs("tr", {
children: [
/*#__PURE__*/ _jsx("th", {
children: "Name"
}),
/*#__PURE__*/ _jsx("th", {
children: "Status"
}),
/*#__PURE__*/ _jsx("th", {
children: "Type"
}),
/*#__PURE__*/ _jsx("th", {
children: "Created"
}),
/*#__PURE__*/ _jsx("th", {})
]
})
}),
/*#__PURE__*/ _jsx("tbody", {
children: [
...projects
].sort((a, b)=>new Date(b.createdAt) - new Date(a.createdAt)).map((p)=>{
var _p_status;
return /*#__PURE__*/ _jsxs("tr", {
style: {
background: p.id === currentProjectId ? 'var(--surface-alt)' : ''
},
children: [
/*#__PURE__*/ _jsxs("td", {
children: [
/*#__PURE__*/ _jsx("strong", {
children: p.name
}),
p.id === currentProjectId ? /*#__PURE__*/ _jsx("span", {
className: "muted",
style: {
fontSize: 11,
marginLeft: 6
},
children: "(current)"
}) : ''
]
}),
/*#__PURE__*/ _jsx("td", {
children: /*#__PURE__*/ _jsx(Badge, {
className: (_p_status = p.status) === null || _p_status === void 0 ? void 0 : _p_status.toLowerCase(),
children: p.status
})
}),
/*#__PURE__*/ _jsx("td", {
style: {
fontSize: 12
},
children: p.projectType
}),
/*#__PURE__*/ _jsx("td", {
style: {
fontSize: 12
},
children: new Date(p.createdAt).toLocaleDateString()
}),
/*#__PURE__*/ _jsxs("td", {
style: {
textAlign: 'right',
whiteSpace: 'nowrap'
},
children: [
p.id !== currentProjectId && /*#__PURE__*/ _jsx("button", {
className: "button secondary small",
style: {
marginRight: 6
},
onClick: ()=>{
onSwitch(p.id);
onClose();
},
children: "Open"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
style: {
background: 'var(--danger)',
color: '#fff'
},
onClick: ()=>setConfirmDelete(p),
disabled: deleting === p.id,
children: "✕"
})
]
})
]
}, p.id);
})
})
]
})
}),
!projects.length && /*#__PURE__*/ _jsx("div", {
className: "empty-state",
children: /*#__PURE__*/ _jsx("p", {
children: "No projects yet"
})
}),
/*#__PURE__*/ _jsx("div", {
className: "modal-actions",
children: /*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: onClose,
children: "Close"
})
})
]
}),
confirmDelete && /*#__PURE__*/ _jsx("div", {
className: "modal-overlay",
onClick: ()=>setConfirmDelete(null),
children: /*#__PURE__*/ _jsxs("div", {
className: "modal",
onClick: (e)=>e.stopPropagation(),
style: {
maxWidth: 380
},
children: [
/*#__PURE__*/ _jsxs("h3", {
children: [
'Delete "',
confirmDelete.name,
'"?'
]
}),
/*#__PURE__*/ _jsx("p", {
style: {
fontSize: 13,
color: 'var(--muted)'
},
children: "This permanently deletes the project and all its risks, mitigations, and data."
}),
/*#__PURE__*/ _jsxs("div", {
className: "modal-actions",
children: [
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: ()=>setConfirmDelete(null),
children: "Cancel"
}),
/*#__PURE__*/ _jsx("button", {
className: "button small",
style: {
background: 'var(--danger)',
color: '#fff'
},
onClick: handleDelete,
disabled: deleting,
children: deleting ? 'Deleting...' : 'Delete Project'
})
]
})
]
})
}),
showNew && /*#__PURE__*/ _jsx(NewProjectModal, {
workspaceId: workspaceId,
onClose: ()=>setShowNew(false),
onSaved: ()=>{
setShowNew(false);
onSaved();
},
toast: toast
})
]
});
}
export default function DashboardPage() {
const router = useRouter();
const searchParams = useSearchParams();
const tab = TABS.includes(searchParams.get('tab')) ? searchParams.get('tab') : 'Overview';
const [project, setProject] = useState(null);
const [projects, setProjects] = useState([]);
const [selectedProjectId, setSelectedProjectId] = useState(searchParams.get('projectId') || null);
const [dashboard, setDashboard] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [retryCount, setRetryCount] = useState(0);
const [showProjectSettings, setShowProjectSettings] = useState(false);
const [showProjectManager, setShowProjectManager] = useState(false);
const [workspaceId, setWorkspaceId] = useState(null);
const { toasts, add } = useToast();
const onRefresh = useCallback(()=>setRetryCount((c)=>c + 1), []);
const loadDashboard = useCallback(async (projectId)=>{
setLoading(true);
setError(null);
try {
var _session_memberships, _workspacesResp_workspaces;
const session = await api.get('/api/auth/session');
if (!(session === null || session === void 0 ? void 0 : session.authenticated)) {
setError('Not authenticated.');
setLoading(false);
return;
}
const membership = (_session_memberships = session.memberships) === null || _session_memberships === void 0 ? void 0 : _session_memberships[0];
if (!membership) {
setError('No organization membership found.');
setLoading(false);
return;
}
const orgId = membership.organizationId;
const workspacesResp = await api.get("/api/workspaces?organizationId=".concat(orgId));
const ws = (_workspacesResp_workspaces = workspacesResp.workspaces) === null || _workspacesResp_workspaces === void 0 ? void 0 : _workspacesResp_workspaces[0];
if (!ws) {
setError('No workspace found — create one to get started.');
setLoading(false);
return;
}
setWorkspaceId(ws.id);
const projectsResp = await api.get("/api/workspaces/".concat(ws.id, "/projects"));
const allProjects = projectsResp.projects || [];
if (!allProjects.length) {
setError('No project found — create a project to get started.');
setLoading(false);
return;
}
setProjects(allProjects);
let proj = projectId ? allProjects.find((p)=>p.id === projectId) : null;
if (!proj) proj = allProjects[0];
if (proj.id !== (searchParams.get('projectId') || null)) {
const currentTab = searchParams.get('tab') || 'Overview';
router.replace("/dashboard?tab=".concat(currentTab, "&projectId=").concat(proj.id));
}
setProject(proj);
const dashResp = await api.get("/api/projects/".concat(proj.id, "/dashboard"));
setDashboard(dashResp.dashboard);
setLoading(false);
} catch (e) {
setError(e.message || 'Failed to load dashboard data');
setLoading(false);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(()=>{
loadDashboard(selectedProjectId);
}, [
loadDashboard,
retryCount,
selectedProjectId
]);
const switchProject = (pid)=>{
setSelectedProjectId(pid);
router.push("/dashboard?tab=".concat(tab, "&projectId=").concat(pid));
};
const [showCreateOnError, setShowCreateOnError] = useState(false);
if (loading && tab !== 'Integrations') return /*#__PURE__*/ _jsx("div", {
className: "shell-loading",
children: /*#__PURE__*/ _jsx("div", {
className: "spinner"
})
});
if (error && tab !== 'Integrations') return /*#__PURE__*/ _jsxs("div", {
className: "empty-state",
children: [
/*#__PURE__*/ _jsx("div", {
className: "empty-icon",
children: "!"
}),
/*#__PURE__*/ _jsx("p", {
children: error
}),
/*#__PURE__*/ _jsxs("div", {
style: {
marginTop: 12,
display: 'flex',
gap: 8,
justifyContent: 'center'
},
children: [
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: ()=>setRetryCount((c)=>c + 1),
children: "Retry"
}),
error.includes('No project found') && workspaceId && /*#__PURE__*/ _jsx("button", {
className: "button small",
onClick: ()=>setShowCreateOnError(true),
children: "+ Create Project"
})
]
}),
showCreateOnError && workspaceId && /*#__PURE__*/ _jsx(NewProjectModal, {
workspaceId: workspaceId,
onClose: ()=>setShowCreateOnError(false),
onSaved: ()=>{
setShowCreateOnError(false);
setRetryCount((c)=>c + 1);
},
toast: {
add
}
})
]
});
return /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsxs("div", {
className: "dash-header",
children: [
/*#__PURE__*/ _jsx("div", {
style: {
display: 'flex',
alignItems: 'center',
gap: 10
},
children: /*#__PURE__*/ _jsxs("div", {
children: [
/*#__PURE__*/ _jsxs("div", {
style: {
display: 'flex',
alignItems: 'center',
gap: 6
},
children: [
/*#__PURE__*/ _jsx("select", {
className: "input",
value: (project === null || project === void 0 ? void 0 : project.id) || '',
onChange: (e)=>switchProject(e.target.value),
style: {
fontSize: 16,
fontWeight: 700,
width: 'auto',
minWidth: 200,
border: 'none',
background: 'transparent',
cursor: 'pointer'
},
children: projects.map((p)=>/*#__PURE__*/ _jsxs("option", {
value: p.id,
children: [
p.name,
" ",
p.status !== 'Active' ? "(".concat(p.status, ")") : ''
]
}, p.id))
}),
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
style: {
fontSize: 14,
padding: '2px 8px'
},
onClick: ()=>setShowProjectSettings(true),
title: "Project settings",
children: "⚙"
}),
/*#__PURE__*/ _jsx("button", {
className: "button secondary small",
onClick: ()=>setShowProjectManager(true),
children: "Projects"
})
]
}),
/*#__PURE__*/ _jsx("p", {
className: "muted",
style: {
margin: 0
},
children: (project === null || project === void 0 ? void 0 : project.subtitle) || (project === null || project === void 0 ? void 0 : project.description) || ''
})
]
})
}),
/*#__PURE__*/ _jsxs("div", {
className: "dash-actions",
children: [
/*#__PURE__*/ _jsx("a", {
href: "/api/projects/".concat(project === null || project === void 0 ? void 0 : project.id, "/reports/executive.html"),
className: "button secondary small",
target: "_blank",
children: "Report"
}),
/*#__PURE__*/ _jsx("a", {
href: "/api/projects/".concat(project === null || project === void 0 ? void 0 : project.id, "/reports/risk-register.csv"),
className: "button secondary small",
target: "_blank",
children: "CSV"
})
]
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "tabs",
children: TABS.map((t)=>/*#__PURE__*/ _jsx("button", {
className: "tab ".concat(tab === t ? 'active' : ''),
onClick: ()=>router.push("/dashboard?tab=".concat(t).concat(project ? "&projectId=".concat(project.id) : '')),
children: t
}, t))
}),
tab === 'Overview' && /*#__PURE__*/ _jsx(ErrorBoundary, {
name: "Overview",
children: /*#__PURE__*/ _jsx(OverviewTab, {
project: project,
dashboard: dashboard
})
}, "overview"),
tab === 'Projects' && /*#__PURE__*/ _jsx(ErrorBoundary, {
name: "Projects",
children: /*#__PURE__*/ _jsx(ProjectsTab, {
projects: projects,
workspaceId: workspaceId,
currentProjectId: project === null || project === void 0 ? void 0 : project.id,
onSwitch: switchProject,
onRefresh: onRefresh,
toast: {
add
}
})
}, "projects"),
tab === 'Risks' && /*#__PURE__*/ _jsx(ErrorBoundary, {
name: "Risks",
children: /*#__PURE__*/ _jsx(RisksTab, {
project: project,
dashboard: dashboard,
toast: {
add
},
onRefresh: onRefresh
})
}, "risks"),
tab === 'Mitigations' && /*#__PURE__*/ _jsx(ErrorBoundary, {
name: "Mitigations",
children: /*#__PURE__*/ _jsx(MitigationsTab, {
project: project,
dashboard: dashboard,
toast: {
add
},
onRefresh: onRefresh
})
}, "mitigations"),
tab === 'Gate' && /*#__PURE__*/ _jsx(ErrorBoundary, {
name: "Gate",
children: /*#__PURE__*/ _jsx(GateTab, {
project: project,
dashboard: dashboard,
toast: {
add
},
onRefresh: onRefresh
})
}, "gate"),
tab === 'Integrations' && /*#__PURE__*/ _jsx(ErrorBoundary, {
name: "Integrations",
children: /*#__PURE__*/ _jsx(IntegrationsTab, {
project: project,
dashboard: dashboard,
toast: {
add
},
onRefresh: onRefresh
})
}, "integrations"),
tab === 'Audit' && /*#__PURE__*/ _jsx(ErrorBoundary, {
name: "Audit",
children: /*#__PURE__*/ _jsx(AuditTab, {
project: project,
toast: {
add
}
})
}, "audit"),
showProjectSettings && /*#__PURE__*/ _jsx(ProjectSettingsModal, {
project: project,
onClose: ()=>setShowProjectSettings(false),
onSaved: ()=>{
setShowProjectSettings(false);
onRefresh();
},
toast: {
add
}
}),
showProjectManager && /*#__PURE__*/ _jsx(ProjectManagerModal, {
projects: projects,
workspaceId: workspaceId,
currentProjectId: project === null || project === void 0 ? void 0 : project.id,
onClose: ()=>setShowProjectManager(false),
onSwitch: switchProject,
onSaved: ()=>{
setShowProjectManager(false);
onRefresh();
},
toast: {
add
}
}),
/*#__PURE__*/ _jsx(ToastContainer, {
toasts: toasts
})
]
});
}
exportsTypesideEffectFreenamespace
javascript/autoapp-pages-browser C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\app\dashboardaliasfullySpecifiedmainFieldsfallback`$server-only$client-only$next/dist/compiled/client-only$next/dist/compiled/server-only C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\head.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\image.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\constants.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\router.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dynamic.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\script.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\link.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\form.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\navigation.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\headers.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\og.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\server.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\document.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\app.jsreact$react/compiler-runtime$react/jsx-dev-runtime$react/jsx-runtime$react-dom$react-dom/client$react-dom/server$react-dom/server.browser$react-dom/server.edge$react-dom/static$react-dom/static.browser$react-dom/static.edge$react-server-dom-webpack/client$react-server-dom-webpack/server$react-server-dom-webpack/server.node$react-server-dom-webpack/static$@vercel/turbopack-ecmascript-runtime/browser/dev/hmr-client/hmr-client.tsnextnext/dist/compiled/server-only/indexnext/dist/compiled/client-only/indexnext/dist/client/components/noop-headnext/dist/api/imagenext/dist/api/constantsnext/dist/api/routernext/dist/api/app-dynamicnext/dist/api/scriptnext/dist/client/app-dir/linknext/dist/client/app-dir/formnext/dist/api/navigationnext/dist/api/headersnext/dist/api/ognext/dist/api/servernext/dist/api/documentnext/dist/api/appnext/dist/compiled/reactnext/dist/compiled/react/compiler-runtimenext/dist/compiled/react/jsx-dev-runtimenext/dist/compiled/react/jsx-runtimenext/dist/compiled/react-domnext/dist/compiled/react-dom/clientnext/dist/compiled/react-dom/server.browsernext/dist/build/webpack/alias/react-dom-server.jsnext/dist/compiled/react-dom/static.browsernext/dist/compiled/react-dom/static.edgenext/dist/compiled/react-server-dom-webpack/client.browsernext/dist/compiled/react-server-dom-webpack/server.browsernext/dist/compiled/react-server-dom-webpack/server.nodenext/dist/compiled/react-server-dom-webpack/static.browsernext/dist/client/dev/noop-turbopack-hmr C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next
browsermodulemain`assertbufferconstantscryptodomainhttphttpsospathpunycodeprocessquerystringstreamstring_decodersystimersttyutilvmzlibeventssetImmediate C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\assert\assert.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\buffer\index.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\constants-browserify\constants.json C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\crypto-browserify\index.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\domain-browser\index.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\stream-http\index.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\https-browserify\index.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\os-browserify\browser.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\path-browserify\index.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\punycode\punycode.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\polyfills\process.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\querystring-es3\index.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\stream-browserify\index.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\string_decoder\string_decoder.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\util\util.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\timers-browserify\main.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\tty-browserify\index.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\vm-browserify\index.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\browserify-zlib\index.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\events\events.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\compiled\setimmediate\setImmediate.js~`cacheableparsedfileDependenciescontextDependenciesmissingDependenciesbuildDependenciesvalueDependencieshashassetsassetsInforscstrictexportsArgumenttopLevelDeclarationssnapshotwebpack/lib/util/LazySet C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-flight-client-module-loader.js C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-swc-loader.jswebpack/DefinePlugin_hashff9a23f26abba7278c6b41bftypeactionIdsisClientRefclient__webpack_exports__`useToastToastContainerSearchInputsortDataBadgeFormFieldInlineInputInlineSelectConfirmDeleteOverviewTabRiskFormModalRisksTabMitigationFormModalMitigationsTabGateTabIntegrationFormModalIntegrationsTabAuditTabProjectsTabProjectSettingsModalNewProjectModalProjectManagerModalTABSPAGE_SIZEDIMENSIONSLIFECYCLE_PHASESRISK_STATUSESMITIGATION_STATUSES*default*DashboardPagewebpack/lib/FileSystemInfoSnapshot +{yB C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\app\dashboard\page.jsxsafeTimetimestamp! vyB vyBa057250d3bb7785dwebpack/lib/dependencies/HarmonyCompatibilityDependency
d webpack/lib/dependencies/ConstDependency`=@
a=@ A
`BA
`=A @
`+AA |
`;webpack/lib/dependencies/HarmonyExportHeaderDependencyA3 Wn A3 Wn
@ @
@g webpack/lib/dependencies/HarmonyImportSideEffectDependencyreact/jsx-runtime
a=@ react
`Bnext/navigation
`=../../lib/api-client
`+../../components/ErrorBoundary
`;webpack/lib/dependencies/PureExpressionDependency A default
a A$ x
c A
c A 0
c" AN
c#(webpack/lib/dependencies/HarmonyImportSpecifierDependency
useState
A
c* *(
useCallback
A
c++
jsx_jsx
AV Z
c@@
A
cB0B4
jsxs_jsxs
A
cJJ
A
cMM
A
cQQ
AQ U
chh
A
coo
A
ctt
A> B
@ `@ `
A
@ `@ `
A
@ `@ `
A
@ `%@ `)
A
@ `@ `
A9 >
@ ` @ `%
A
@ `@ `#
A
@ `@ `"
A
@ `@ `#
Ae i
@ `&@ `*
AW [
@ `&@ `*
useMemo
A
@ `@ `
A-) 1)
{{
@ `)@ `-
A}) )
ww
@ ` @ `$
A) )
ss
@ `@ `
Fragment_Fragment
A) )
4mm
@ `@ `(
A(* ,*
ii
@ `@ `
A
+ +
ee
@ `8@ `=
A+ +
aa
@ `*@ `.
A%, ),
]]
@ `*@ `.
A, ,
YY
@ `*@ `.
A- -
UU
@ `@ `
A. .
QQ
@$ `"@$ `'
uv
Ao/ s/
MM
@' `*@' `.
|}
A%0 *0
II
@* `R@* `W
xy
A'1 ,1
EE
@/ `6@/ `;
ij
A2 2
AA
@6 `>@6 `B
ef
Ac4 g4
==
@< `>@< `B
ab
A86 <6
99
@D `6@D `:
]^
A6 6
55
@F `D@F `H
de
A9 9
11
@R `"@R `'
UV
A: :
--
@U `*@U `.
\]
A: :
))
@X `S@X `X
XY
A; ;
%%
@] `6@] `;
IJ
A= =
!!
@d `>@d `B
PQ
A ? ?
@j `>@j `C
AB
AA A
@v `6@v `:
=>
AqB uB
@x `D@x `H
.-
AE E
@ ` @ `(
)(
A
F F
@ `@ `$
apipost
AH H
AH H
@ `@ `
)*
AI I
@ `@ `
01
A\J aJ
@ ` @ `%
!"
A2K 6K
@ `@ `"
AK K
@ `@ `"
AK L
@ `,@ `0
AL L
@ `@ `"
AM !M
@ `,@ `0
AN N
@ `@ `#
AO O
@ `&@ `*
AXP \P
@ `4@ `8
AuQ yQ
@ `&@ `*
AQ Q
@ `4@ `8
AR R
@ `@ `"
AVS ZS
@ `,@ `0
AST XT
@ `@ `#
A`U dU
@ `&@ `*
AU U
@ `4@ `8
AEW IW
@ `&@ `*
AW W
@ `4@ `8
AY Y
@ `&@ `*
AY Y
@
`4@
`8
A'[ +[
@ `@ `"
A[ [
@ `,@ `0
AV\ [\
@ `@ `#
A\ \
@! `&@! `*
A] ]
@& `&@& `*
A_ _
@4 ` @4 `(
A_ _
@5 `"@5 `*
A ` `
@6 `"@6 `*
A7` ?`
@7 `@7 `$
Ap` x`
@8 `,@8 `4
A` `
@9 `(@9 `0
A` `
@: `"@: `*
Aa a
~~
@; `$@; `,
ABa Ja
zz
@< `$@< `,
Aa a
vv
@= `.@= `6
Aa a
rr
@> `$@> `,
Aa a
nn
@? `@? `
Ab b
jj
@G `@G `
\patchZ
Ai i
Ai i
hh
@k `@k `
VU
A9k Bk
A9k