Add BOM cost tracking

Suggested-default cost on CableType/DeviceTemplate, copied onto
placed Device instances (same pattern as ports) and overridable
per-connection/per-device in the diagram. BOM view shows per-line
and grand-total cost, excluding (and flagging) anything without a
computable cost rather than treating it as zero.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
This commit is contained in:
2026-09-04 15:55:57 -05:00
co-authored by Claude Sonnet 5
parent 7cf786e107
commit e8654a39d6
9 changed files with 242 additions and 11 deletions
+18 -1
View File
@@ -49,7 +49,7 @@ export default function DeviceInspector({ deviceId }: { deviceId: string }) {
className="mt-1 w-full rounded border border-slate-300 px-2 py-1 text-sm"
/>
</label>
<label className="col-span-2 text-xs font-medium text-slate-600">
<label className="text-xs font-medium text-slate-600">
Model
<input
value={device.model ?? ''}
@@ -57,6 +57,23 @@ export default function DeviceInspector({ deviceId }: { deviceId: string }) {
className="mt-1 w-full rounded border border-slate-300 px-2 py-1 text-sm"
/>
</label>
<label className="text-xs font-medium text-slate-600">
Cost
<div className="mt-1 flex items-center gap-1">
<span className="text-xs text-slate-500">$</span>
<input
type="number"
min={0}
step={0.01}
value={device.cost ?? ''}
onChange={(e) =>
updateDevice(device.id, { cost: e.target.value === '' ? undefined : Number(e.target.value) })
}
className="w-full rounded border border-slate-300 px-2 py-1 text-sm"
placeholder="e.g. 249.00"
/>
</div>
</label>
<label className="col-span-2 text-xs font-medium text-slate-600">
Notes
<textarea