@memoarchitect/architect 0.4.6 → 0.6.0
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/README.md +44 -3
- package/dist/assets/AskPanel-CbZrbBeK.js +1 -0
- package/dist/assets/ComplianceWizard-s0BYP9sH.js +1 -0
- package/dist/assets/{DSMView-B4IEz19F.js → DSMView-C55GKPeE.js} +1 -1
- package/dist/assets/{Dashboard-DNRzU1Hk.js → Dashboard-DGiiwpMx.js} +1 -1
- package/dist/assets/DhfDashboard-BE5JabB1.js +1 -0
- package/dist/assets/{DhfSettingsPanel-C89T0dv7.js → DhfSettingsPanel-BYTUIoK4.js} +1 -1
- package/dist/assets/{DhfWorkbench-4gHayn-l.js → DhfWorkbench-CUzn_SQo.js} +3 -3
- package/dist/assets/DiagramCanvas-IINBJE7R.js +1 -0
- package/dist/assets/DiagramEditor-Ce5_o4RB.js +4 -0
- package/dist/assets/{ElementDetailView-AclSjurg.js → ElementDetailView-CZ8SUxsc.js} +2 -2
- package/dist/assets/{ImportView-t1dIoZF5.js → ImportView-CdHzpWCe.js} +1 -1
- package/dist/assets/{LayerGrid-fSGvqSEj.js → LayerGrid-Bnv8Ww8p.js} +1 -1
- package/dist/assets/{LayerTable-D8QCFY1b.js → LayerTable-CeO0t2NX.js} +2 -2
- package/dist/assets/{MaxGraphCanvas-DYs6MPuP.js → MaxGraphCanvas-BH29OQf7.js} +6 -6
- package/dist/assets/{ModelDiff-CLFqnELG.js → ModelDiff-DoGTGDhy.js} +1 -1
- package/dist/assets/OntologyDecompositionDiagram-CerdFGpm.js +1 -0
- package/dist/assets/{OntologyViewer-72jTw72H.js → OntologyViewer-BGl9FWMx.js} +2 -2
- package/dist/assets/{RelationshipOverlay-BDrBRSPP.js → RelationshipOverlay-DSzjs5U7.js} +1 -1
- package/dist/assets/{RelationshipsSection-D1-tuVYo.js → RelationshipsSection-2CEoiF6o.js} +1 -1
- package/dist/assets/{ReviewDashboard-BVOe2I5w.js → ReviewDashboard-Du0bEgrG.js} +1 -1
- package/dist/assets/ScenarioEditor-BjLWOYwL.js +3 -0
- package/dist/assets/{StatisticsDashboard-Dn6lsnKe.js → StatisticsDashboard-BdrXtbp4.js} +1 -1
- package/dist/assets/{SysmlCodeEditor-BLcw6hdp.js → SysmlCodeEditor-CGOcUFE7.js} +1 -1
- package/dist/assets/SysmlGenerator-CxtxOJ9I.js +1 -0
- package/dist/assets/{TabularView-B99xy3H3.js → TabularView-BJQSVDMO.js} +1 -1
- package/dist/assets/TraceabilityMatrix-BhDLjHki.js +1 -0
- package/dist/assets/{WorkflowWizard-C38DZKOe.js → WorkflowWizard-BWKNcz03.js} +1 -1
- package/dist/assets/index-CRFOCEAK.js +3277 -0
- package/dist/assets/index-DPzXL4uF.css +1 -0
- package/dist/assets/{layout-providers-BAUgp0nu.js → layout-providers-BFnfta4Z.js} +13 -13
- package/dist/assets/layout-selection-CtqXOAtf.js +1 -0
- package/dist/assets/{reactflow-WKyu73tD.js → reactflow-CX-HDacK.js} +1 -1
- package/dist/index.html +3 -3
- package/lib/bin/memo-architect.js +39 -3
- package/lib/bin/memo-architect.js.map +1 -1
- package/lib/commands/dev.d.ts.map +1 -1
- package/lib/commands/dev.js +9 -0
- package/lib/commands/dev.js.map +1 -1
- package/lib/commands/example.d.ts +16 -0
- package/lib/commands/example.d.ts.map +1 -0
- package/lib/commands/example.js +143 -0
- package/lib/commands/example.js.map +1 -0
- package/package.json +4 -4
- package/dist/assets/AskPanel-D9_AKyYt.js +0 -1
- package/dist/assets/ComplianceWizard-BNvT_ic6.js +0 -1
- package/dist/assets/DhfDashboard-DguH-rDT.js +0 -1
- package/dist/assets/DiagramCanvas-BgfO0AtP.js +0 -1
- package/dist/assets/DiagramEditor-CEr6iqBf.js +0 -4
- package/dist/assets/DiagramSurface-B_lfUNzV.js +0 -2
- package/dist/assets/OntologyDecompositionDiagram-cpmTTMRH.js +0 -1
- package/dist/assets/ScenarioEditor-CvOkiRC6.js +0 -3
- package/dist/assets/SysmlGenerator-CfBQWovl.js +0 -1
- package/dist/assets/TraceabilityMatrix-BAJb0X7G.js +0 -1
- package/dist/assets/index-CgRwea72.js +0 -3277
- package/dist/assets/index-CnFhl4_e.css +0 -1
- package/dist/assets/layout-selection-BQ2WuAEB.js +0 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
|
-
<code>memo-architect 0.
|
|
12
|
+
<code>memo-architect 0.6.0</code> · MIT · SysML v2 ·
|
|
13
13
|
ISO 14971 · IEC 62304 · ISO/IEC/IEEE 42010
|
|
14
14
|
</p>
|
|
15
15
|
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
| 03 | Reusable engine libraries and the `memo` CLI | [memo-tools](https://github.com/memoarchitect/memo-tools) |
|
|
27
27
|
| 04 | Complete visual workbench | **memo-architect** (this repository) |
|
|
28
28
|
|
|
29
|
-
All three products share a `MAJOR.MINOR` compatibility line. Any `0.
|
|
30
|
-
release is intended to work with the other `0.
|
|
29
|
+
All three products share a `MAJOR.MINOR` compatibility line. Any `0.5.x`
|
|
30
|
+
release is intended to work with the other `0.5.x` products; patch versions
|
|
31
31
|
may advance independently for fixes and additive changes.
|
|
32
32
|
|
|
33
33
|
Architect reuses the parser, semantic model, validation, document, and project
|
|
@@ -51,6 +51,45 @@ interaction; it does not maintain a second engineering model.
|
|
|
51
51
|
- Author and export Design History File documents from the versioned model.
|
|
52
52
|
- Run the same validation and export operations through the CLI or the workbench.
|
|
53
53
|
|
|
54
|
+
## Try it on a bundled example
|
|
55
|
+
|
|
56
|
+
The examples ship inside the ontology package, `@memoarchitect/ontology`, so
|
|
57
|
+
they are already present once Architect is installed — there is nothing to
|
|
58
|
+
clone or download. One command opens one:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
memo-architect --example gpca
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
memo-architect --example standard-sysml-diagrams
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Example | What it contains |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `gpca` | GPCA infusion-pump reference model — the full worked device |
|
|
71
|
+
| `standard-sysml-diagrams` | One openable view per standard SysML v2 diagram type |
|
|
72
|
+
|
|
73
|
+
Where the example is opened from depends on where the ontology resolves:
|
|
74
|
+
|
|
75
|
+
- **A local checkout** (a sibling clone or workspace link) is served **in
|
|
76
|
+
place**, so edits are real and can be committed. The path is printed on
|
|
77
|
+
startup.
|
|
78
|
+
- **An installed package** under `node_modules` is copied to a disposable
|
|
79
|
+
directory first and the copy is discarded on exit, so a dependency is never
|
|
80
|
+
modified.
|
|
81
|
+
|
|
82
|
+
Pass `--read-only` to force the disposable copy even from a checkout, and
|
|
83
|
+
`--port` to choose a port.
|
|
84
|
+
|
|
85
|
+
Every view is addressable, so any page can be bookmarked or shared while the
|
|
86
|
+
app is running — `/dashboard`, `/ontology`, `/dhf`, `/statistics`,
|
|
87
|
+
`/catalog/<family>/<shortId>` for an element, `/diagrams/<type>/<id>` for a
|
|
88
|
+
diagram. Back and Forward work as expected.
|
|
89
|
+
|
|
90
|
+
To point Architect at your own project instead, run `memo-architect dev` from
|
|
91
|
+
the project directory.
|
|
92
|
+
|
|
54
93
|
## Repository layout
|
|
55
94
|
|
|
56
95
|
```text
|
|
@@ -98,6 +137,8 @@ pnpm architect -- dev
|
|
|
98
137
|
pnpm architect -- build --output dist
|
|
99
138
|
```
|
|
100
139
|
|
|
140
|
+
To open a bundled example, see [Try it on a bundled example](#try-it-on-a-bundled-example).
|
|
141
|
+
|
|
101
142
|
## Documentation
|
|
102
143
|
|
|
103
144
|
- [Start here](docs/src/index.md)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as t}from"./reactflow-CX-HDacK.js";import{a as i}from"./zustand-qbFpP9Up.js";import{u as d,k}from"./index-CRFOCEAK.js";const S=["What hazards have no risk controls?","Show trace from requirements to verification.","Which layers have the most gaps?","How many unmitigated hazards are there?","List all SOUP components."];function I(){const o=d(e=>e.llmAvailable),b=d(e=>e.llmProvider),E=d(e=>e.llmModel),v=d(e=>e.model),f=d(e=>e.registerLlmRequest),[p,c]=i.useState([]),[l,u]=i.useState(""),[s,h]=i.useState(!1),g=i.useRef(null),j=i.useRef(null);i.useEffect(()=>{var e;(e=g.current)==null||e.scrollIntoView({behavior:"smooth"})},[p]);const x=i.useCallback(async e=>{if(!e.trim()||s)return;const r=e.trim();u(""),c(n=>[...n,{role:"user",content:r}]),h(!0);const y=`ask-${Date.now()}-${Math.random().toString(36).slice(2)}`;try{const n=await new Promise((a,m)=>{f(y,a,m),k(y,r),setTimeout(()=>m(new Error("Request timed out after 60 seconds.")),6e4)});c(a=>[...a,{role:"assistant",content:n}])}catch(n){c(a=>[...a,{role:"assistant",content:(n==null?void 0:n.message)??"Unknown error",error:!0}])}finally{h(!1)}},[s,f]),A=e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),x(l))};return v?t.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%",background:"#F7F7F5",overflow:"hidden"},children:[t.jsx("div",{style:{padding:"14px 20px 10px",borderBottom:"1px solid #E5E5E0",background:"#fff",flexShrink:0},children:t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"10px"},children:[t.jsx("span",{style:{fontSize:"16px"},children:"✦"}),t.jsxs("div",{children:[t.jsx("div",{style:{fontSize:"14px",fontWeight:700,color:"#1B3A4B"},children:"Model Q&A"}),t.jsx("div",{style:{fontSize:"11px",color:o?"#059669":"#dc2626",marginTop:"1px"},children:o?`${b??"LLM"} · ${E??"unknown model"}`:"No LLM provider — set ANTHROPIC_API_KEY or OPENAI_API_KEY"})]})]})}),t.jsxs("div",{style:{flex:1,overflowY:"auto",padding:"16px 20px",display:"flex",flexDirection:"column",gap:"12px"},children:[p.length===0&&t.jsxs("div",{style:{paddingTop:"8px"},children:[t.jsx("div",{style:{fontSize:"12px",color:"#9CA3AF",marginBottom:"12px"},children:"Ask questions about your model in plain English."}),t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"6px"},children:S.map(e=>t.jsx("button",{onClick:()=>x(e),disabled:!o||s,style:{textAlign:"left",padding:"8px 12px",borderRadius:"8px",background:"#fff",border:"1px solid #E5E5E0",fontSize:"12px",color:"#374151",cursor:"pointer",transition:"border-color 0.1s",opacity:o?1:.5},onMouseEnter:r=>{o&&(r.currentTarget.style.borderColor="#2DD4A8")},onMouseLeave:r=>{r.currentTarget.style.borderColor="#E5E5E0"},children:e},e))})]}),p.map((e,r)=>t.jsxs("div",{style:{display:"flex",flexDirection:e.role==="user"?"row-reverse":"row",gap:"8px",alignItems:"flex-start"},children:[t.jsx("div",{style:{width:"24px",height:"24px",borderRadius:"50%",flexShrink:0,display:"flex",alignItems:"center",justifyContent:"center",background:e.role==="user"?"#1B3A4B":"#2DD4A815",fontSize:"10px",fontWeight:700,color:e.role==="user"?"#fff":"#2DD4A8",marginTop:"2px"},children:e.role==="user"?"U":"✦"}),t.jsx("div",{style:{maxWidth:"85%",padding:"10px 12px",borderRadius:"10px",background:e.role==="user"?"#1B3A4B":e.error?"#fef2f2":"#fff",color:e.role==="user"?"#fff":e.error?"#dc2626":"#1B3A4B",fontSize:"13px",lineHeight:"1.6",border:e.role==="assistant"?`1px solid ${e.error?"#fecaca":"#E5E5E0"}`:"none",whiteSpace:"pre-wrap"},children:e.content})]},r)),s&&t.jsxs("div",{style:{display:"flex",gap:"8px",alignItems:"flex-start"},children:[t.jsx("div",{style:{width:"24px",height:"24px",borderRadius:"50%",background:"#2DD4A815",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"10px",color:"#2DD4A8",fontWeight:700},children:"✦"}),t.jsx("div",{style:{padding:"10px 14px",borderRadius:"10px",background:"#fff",border:"1px solid #E5E5E0",display:"flex",gap:"4px",alignItems:"center"},children:t.jsx(w,{})})]}),t.jsx("div",{ref:g})]}),t.jsxs("div",{style:{padding:"12px 16px",borderTop:"1px solid #E5E5E0",background:"#fff",flexShrink:0},children:[t.jsxs("div",{style:{display:"flex",gap:"8px",alignItems:"flex-end"},children:[t.jsx("textarea",{ref:j,value:l,onChange:e=>u(e.target.value),onKeyDown:A,disabled:!o||s,placeholder:o?"Ask a question… (Enter to send, Shift+Enter for newline)":"LLM not configured",rows:2,style:{flex:1,padding:"8px 12px",border:"1px solid #E5E5E0",borderRadius:"8px",fontSize:"13px",resize:"none",fontFamily:"inherit",outline:"none",background:"#F7F7F5",color:"#1B3A4B",lineHeight:"1.5",opacity:o?1:.5},onFocus:e=>{e.target.style.borderColor="#2DD4A8"},onBlur:e=>{e.target.style.borderColor="#E5E5E0"}}),t.jsx("button",{onClick:()=>x(l),disabled:!o||s||!l.trim(),style:{padding:"8px 14px",borderRadius:"8px",border:"none",background:"#1B3A4B",color:"#fff",fontSize:"12px",fontWeight:600,cursor:"pointer",flexShrink:0,opacity:!o||!l.trim()?.4:1,transition:"opacity 0.15s"},children:"Send"})]}),p.length>0&&t.jsx("button",{onClick:()=>c([]),style:{marginTop:"6px",background:"none",border:"none",color:"#9CA3AF",fontSize:"11px",cursor:"pointer",padding:0},children:"Clear conversation"})]})]}):t.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%",color:"#9CA3AF"},children:"Waiting for model data…"})}function w(){return t.jsxs("span",{style:{display:"inline-flex",gap:"3px",alignItems:"center"},children:[[0,1,2].map(o=>t.jsx("span",{style:{width:"5px",height:"5px",borderRadius:"50%",background:"#9CA3AF",animation:"llm-pulse 1.2s ease-in-out infinite",animationDelay:`${o*.2}s`}},o)),t.jsx("style",{children:"@keyframes llm-pulse{0%,80%,100%{opacity:0.3}40%{opacity:1}}"})]})}export{I as AskPanel};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e}from"./reactflow-CX-HDacK.js";import{a as g}from"./zustand-qbFpP9Up.js";import{u as j,f as k}from"./index-CRFOCEAK.js";const C=[{id:"iso-14971",name:"ISO 14971",description:"Risk Management for Medical Devices",steps:[{id:"hazard-identification",label:"Hazard Identification",description:"Identify hazards and hazardous situations"},{id:"risk-estimation",label:"Risk Estimation",description:"Estimate severity and probability for each hazardous situation"},{id:"control-measures",label:"Risk Controls",description:"Define risk control measures and link to hazards"},{id:"verification",label:"Verification",description:"Verify risk control effectiveness"},{id:"summary",label:"Summary",description:"Review compliance status"}],requiredKinds:["Hazard","HazardousSituation","Harm","RiskControlMeasure"],requiredRelationships:["causes","leadsTo","mitigates"]},{id:"iec-62304",name:"IEC 62304",description:"Software Lifecycle for Medical Devices",steps:[{id:"hazard-identification",label:"Software Items",description:"Identify software items and their safety classification"},{id:"risk-estimation",label:"Architecture",description:"Review software architecture decomposition"},{id:"control-measures",label:"Requirements Tracing",description:"Trace software requirements to system requirements"},{id:"verification",label:"Verification",description:"Verify test coverage for software items"},{id:"summary",label:"Summary",description:"Review compliance status"}],requiredKinds:["SoftwareComponent","SoftwareModule","Requirement","Test"],requiredRelationships:["decomposedBy","traceTo","verify"]}];function w(i){if(!i)return[];const d=Object.values(i.elements),a=[],o=d.filter(n=>n.kind==="Hazard"),l=d.filter(n=>n.kind==="HazardousSituation"),u=d.filter(n=>n.kind==="Harm"),p=d.filter(n=>n.kind==="RiskControlMeasure");a.push({label:"Hazards identified",status:o.length>0?"pass":"fail",detail:`${o.length} hazards found`,elementIds:o.map(n=>n.id)}),a.push({label:"Hazardous situations linked",status:l.length>0?"pass":"warning",detail:`${l.length} hazardous situations`,elementIds:l.map(n=>n.id)}),a.push({label:"Harms documented",status:u.length>0?"pass":"warning",detail:`${u.length} harms identified`,elementIds:u.map(n=>n.id)});const c=new Set(i.relationships.filter(n=>n.type==="mitigates").map(n=>n.targetId)),t=o.filter(n=>!c.has(n.id));a.push({label:"Risk controls applied",status:t.length===0&&o.length>0?"pass":t.length>0?"fail":"warning",detail:t.length>0?`${t.length} hazards without controls`:`${p.length} controls applied`,elementIds:t.map(n=>n.id)});const h=new Set(i.relationships.filter(n=>n.type==="verify").map(n=>n.targetId)),f=p.filter(n=>!h.has(n.id));return a.push({label:"Controls verified",status:f.length===0&&p.length>0?"pass":f.length>0?"warning":"fail",detail:f.length>0?`${f.length} controls not verified`:`All ${p.length} controls verified`,elementIds:f.map(n=>n.id)}),a}function E(i){if(!i)return[];const d=Object.values(i.elements),a=[],o=d.filter(t=>t.kind==="SoftwareComponent"||t.kind==="SoftwareModule"),l=d.filter(t=>t.kind==="Requirement"),u=d.filter(t=>t.kind==="Test");a.push({label:"Software items identified",status:o.length>0?"pass":"fail",detail:`${o.length} software items`,elementIds:o.map(t=>t.id)}),a.push({label:"Software requirements defined",status:l.length>0?"pass":"fail",detail:`${l.length} software requirements`,elementIds:l.map(t=>t.id)});const p=new Set(i.relationships.filter(t=>t.type==="traceTo").map(t=>t.sourceId)),c=l.filter(t=>!p.has(t.id));return a.push({label:"Requirements traced",status:c.length===0&&l.length>0?"pass":c.length>0?"warning":"fail",detail:c.length>0?`${c.length} requirements not traced`:"All requirements traced",elementIds:c.map(t=>t.id)}),a.push({label:"Test coverage",status:u.length>0?"pass":"warning",detail:`${u.length} tests defined`,elementIds:u.map(t=>t.id)}),a}function A(){const i=j(d=>d.availableOntologies);return g.useMemo(()=>{const d=new Map;for(const a of i)for(const o of a.layers)for(const l of o.kinds)l.standard&&d.set(l.standard,(d.get(l.standard)??0)+1);return Array.from(d.entries()).map(([a,o])=>({standard:a,label:a.replace(/_/g," ").replace(/\b\w/g,l=>l.toUpperCase()),kindCount:o})).sort((a,o)=>a.standard.localeCompare(o.standard))},[i])}function z(){const i=j(s=>s.model),d=j(s=>s.selectElement),[a,o]=g.useState(null),[l,u]=g.useState(0),p=A(),c=C.find(s=>s.id===a),t=c==null?void 0:c.steps[l],h=g.useMemo(()=>!a||!i?[]:a==="iso-14971"?w(i):a==="iec-62304"?E(i):[],[a,i]),f=h.filter(s=>s.status==="pass").length,n=h.length,x=n>0?Math.round(f/n*100):0,v={pass:"#2ECC71",warning:"#F39C12",fail:"#E74C3C"},N={pass:"✓",warning:"⚠",fail:"✗"},y=g.useMemo(()=>{if(!i||!t)return[];const s=Object.values(i.elements);switch(t.id){case"hazard-identification":return a==="iso-14971"?s.filter(r=>r.kind==="Hazard"||r.kind==="HazardousSituation"):s.filter(r=>r.kind==="SoftwareComponent"||r.kind==="SoftwareModule");case"risk-estimation":return a==="iso-14971"?s.filter(r=>r.kind==="HazardousSituation"||r.kind==="Harm"):s.filter(r=>r.kind==="SoftwareComponent"||r.kind==="Subsystem"||r.kind==="Component");case"control-measures":return a==="iso-14971"?s.filter(r=>r.kind==="RiskControlMeasure"):s.filter(r=>r.kind==="Requirement"||r.kind==="Requirement");case"verification":return s.filter(r=>r.kind==="Test");default:return[]}},[i,t,a]);return a?e.jsxs("div",{className:"flex flex-1 overflow-hidden",children:[e.jsxs("div",{className:"w-64 flex flex-col overflow-hidden",style:{background:"#FFFFFF",borderRight:"1px solid #E5E5E0"},children:[e.jsxs("div",{className:"px-4 py-3",style:{background:"linear-gradient(135deg, #1B3A4B, #2D6A7A)"},children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:()=>{o(null),u(0)},className:"text-xs px-1.5 py-0.5 rounded",style:{color:"rgba(255,255,255,0.6)",background:"rgba(255,255,255,0.1)"},children:"←"}),e.jsx("h2",{className:"text-sm font-bold tracking-wide",style:{color:"#2DD4A8"},children:c.name})]}),e.jsx("p",{className:"text-xs mt-0.5",style:{color:"rgba(255,255,255,0.6)"},children:c.description})]}),e.jsxs("div",{className:"px-4 py-3",style:{borderBottom:"1px solid #E5E5E0"},children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("span",{className:"text-xs font-medium",style:{color:"#374151"},children:"Compliance"}),e.jsxs("span",{className:"text-xs font-bold",style:{color:x>=80?"#2ECC71":x>=50?"#F39C12":"#E74C3C"},children:[x,"%"]})]}),e.jsx("div",{className:"w-full h-1.5 rounded-full",style:{background:"#F3F4F6"},children:e.jsx("div",{className:"h-full rounded-full transition-all",style:{width:`${x}%`,background:x>=80?"#2ECC71":x>=50?"#F39C12":"#E74C3C"}})})]}),e.jsx("div",{className:"flex-1 overflow-y-auto py-1",children:c.steps.map((s,r)=>{const m=l===r,b=r<l;return e.jsxs("div",{className:"flex items-center gap-2 px-3 py-2 cursor-pointer mx-1 rounded-lg",style:{background:m?"#2DD4A818":"transparent",fontWeight:m?500:400},onMouseEnter:F=>{m||(F.currentTarget.style.background="#F0F0ED")},onMouseLeave:F=>{m||(F.currentTarget.style.background=m?"#2DD4A818":"transparent")},onClick:()=>u(r),children:[e.jsx("span",{className:"w-5 h-5 rounded-full flex items-center justify-center text-xs flex-shrink-0",style:{background:m?"#2DD4A8":b?"#2ECC7130":"#F3F4F6",color:m?"#FFFFFF":b?"#2ECC71":"#9CA3AF"},children:b?"✓":r+1}),e.jsx("span",{className:"text-xs",style:{color:m?"#1B3A4B":"#6B7280"},children:s.label})]},s.id)})})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-6",style:{background:"#F7F7F5"},children:e.jsx("div",{className:"max-w-3xl",children:t&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-3 mb-1",children:[e.jsx("h2",{className:"text-lg font-semibold",style:{color:"#374151"},children:t.label}),e.jsxs("span",{className:"text-xs px-2 py-0.5 rounded-full",style:{background:"#F3F4F6",color:"#9CA3AF"},children:["Step ",l+1," of ",c.steps.length]})]}),e.jsx("p",{className:"text-sm mb-6",style:{color:"#9CA3AF"},children:t.description}),t.id==="summary"?e.jsx("div",{className:"space-y-2",children:h.map((s,r)=>e.jsxs("div",{className:"flex items-center gap-3 p-3 rounded-lg",style:{background:"#FFFFFF",border:`1px solid ${v[s.status]}40`},children:[e.jsx("span",{className:"text-sm font-bold",style:{color:v[s.status]},children:N[s.status]}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"text-xs font-medium",style:{color:"#374151"},children:s.label}),e.jsx("div",{className:"text-xs",style:{color:"#9CA3AF"},children:s.detail})]}),s.elementIds&&s.elementIds.length>0&&s.status!=="pass"&&e.jsx("button",{onClick:()=>d(s.elementIds[0]),className:"text-xs px-2 py-0.5 rounded",style:{background:"#4A90D915",color:"#4A90D9"},children:"View"})]},r))}):e.jsx(e.Fragment,{children:e.jsxs("div",{className:"mb-4",children:[e.jsxs("h3",{className:"text-xs font-semibold uppercase tracking-wider mb-2",style:{color:"#6B7280"},children:["Relevant Elements (",y.length,")"]}),y.length===0&&e.jsx("div",{className:"p-4 rounded-lg text-center text-xs",style:{background:"#FEF2F2",border:"1px solid #FECACA",color:"#E74C3C"},children:"No elements found for this step. Create the required element types in your .sysml files."}),e.jsx("div",{className:"space-y-1",children:y.map(s=>{const r=i.relationships.filter(m=>m.sourceId===s.id||m.targetId===s.id);return e.jsxs("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg cursor-pointer text-xs",style:{background:"#FFFFFF",border:"1px solid #E5E5E0"},onMouseEnter:m=>m.currentTarget.style.background="#F0F0ED",onMouseLeave:m=>m.currentTarget.style.background="#FFFFFF",onClick:()=>d(s.id),children:[e.jsx("span",{className:"w-2 h-2 rounded-full",style:{background:k[s.layer]||"#95A5A6"}}),e.jsx("span",{className:"font-medium flex-1 truncate",style:{color:"#374151"},children:s.name}),e.jsx("span",{className:"px-1.5 py-0.5 rounded",style:{background:(k[s.layer]||"#95A5A6")+"18",color:k[s.layer]||"#95A5A6"},children:s.kind}),e.jsxs("span",{style:{color:"#9CA3AF"},children:[r.length," rels"]})]},s.id)})})]})}),e.jsxs("div",{className:"flex items-center gap-2 mt-6 pt-4",style:{borderTop:"1px solid #E5E5E0"},children:[l>0&&e.jsxs("button",{onClick:()=>u(l-1),className:"px-4 py-2 text-xs rounded-lg",style:{background:"#F3F4F6",color:"#6B7280"},children:["←"," Previous"]}),e.jsx("div",{className:"flex-1"}),l<c.steps.length-1&&e.jsxs("button",{onClick:()=>u(l+1),className:"px-4 py-2 text-xs rounded-lg font-medium",style:{background:"#2DD4A8",color:"#FFFFFF"},children:["Next ","→"]})]})]})})})]}):e.jsx("div",{className:"flex-1 overflow-y-auto p-8",style:{background:"#F7F7F5"},children:e.jsxs("div",{className:"max-w-2xl mx-auto",children:[e.jsx("h2",{className:"text-lg font-semibold mb-1",style:{color:"#374151"},children:"Compliance Wizard"}),e.jsx("p",{className:"text-sm mb-6",style:{color:"#9CA3AF"},children:"Select a standard to walk through compliance requirements step by step."}),e.jsx("div",{className:"space-y-3",children:C.map(s=>e.jsxs("button",{onClick:()=>{o(s.id),u(0)},className:"w-full text-left p-4 rounded-lg transition-colors",style:{background:"#FFFFFF",border:"1px solid #E5E5E0"},onMouseEnter:r=>r.currentTarget.style.borderColor="#2DD4A8",onMouseLeave:r=>r.currentTarget.style.borderColor="#E5E5E0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-sm font-semibold",style:{color:"#1B3A4B"},children:s.name}),e.jsxs("span",{className:"text-xs px-2 py-0.5 rounded-full",style:{background:"#F3F4F6",color:"#6B7280"},children:[s.steps.length," steps"]})]}),e.jsx("p",{className:"text-xs mt-1",style:{color:"#6B7280"},children:s.description})]},s.id))}),p.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider mt-8 mb-3",style:{color:"#6B7280"},children:"Discovered Standards"}),e.jsx("div",{className:"space-y-2",children:p.map(s=>e.jsxs("div",{className:"flex items-center gap-3 p-3 rounded-lg",style:{background:"#FFFFFF",border:"1px solid #E5E5E0"},children:[e.jsx("span",{className:"w-2 h-2 rounded-full flex-shrink-0",style:{background:"#7C3AED"}}),e.jsx("span",{className:"text-sm font-medium flex-1",style:{color:"#374151"},children:s.label}),e.jsxs("span",{className:"text-xs px-2 py-0.5 rounded-full",style:{background:"#F3F4F6",color:"#6B7280"},children:[s.kindCount," ",s.kindCount===1?"kind":"kinds"]})]},s.standard))})]})]})})}export{z as ComplianceWizard};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as s}from"./reactflow-WKyu73tD.js";import{a as b}from"./zustand-qbFpP9Up.js";import{u as C,d as _,R as v}from"./index-CgRwea72.js";const U=["Function","Function","ActionDefinition","ActionUsage"],H=["flow","decomposedBy","composedOf","allocateTo","succession"];function K(o,c){const m=new Set((c==null?void 0:c.kinds)??U),u=new Set((c==null?void 0:c.relationshipTypes)??H),p=(c==null?void 0:c.cluster)??!0,d=[];for(const e of Object.values(o.elements))m.has(e.kind)&&d.push(e);d.sort((e,h)=>{const g=e.kind.localeCompare(h.kind);return g!==0?g:e.name.localeCompare(h.name)});const a=d.map(e=>e.id),f=new Map;for(let e=0;e<a.length;e++)f.set(a[e],e);const r=a.length,y={};for(const e of d)y[e.id]={name:e.name,kind:e.kind,layer:e.layer,allocatedTo:e.allocatedTo};const l=Array.from({length:r},()=>Array.from({length:r},()=>null));let t=0;for(const e of o.relationships){if(!u.has(e.type))continue;const h=f.get(e.sourceId),g=f.get(e.targetId);if(h===void 0||g===void 0||h===g)continue;let F=l[h][g];F||(F={count:0,types:[],flowItems:[]},l[h][g]=F),F.count++,F.types.includes(e.type)||F.types.push(e.type),e.flowItem&&!F.flowItems.includes(e.flowItem)&&F.flowItems.push(e.flowItem),t++}const i=p?Y(a,l):new Map;return{elementIds:a,elements:y,matrix:l,clusters:i,totalDependencies:t}}function Y(o,c){const m=o.length,u=Array.from({length:m},(l,t)=>t),p=new Array(m).fill(0);function d(l){return u[l]!==l&&(u[l]=d(u[l])),u[l]}function a(l,t){const i=d(l),e=d(t);i!==e&&(p[i]<p[e]?u[i]=e:p[i]>p[e]?u[e]=i:(u[e]=i,p[i]++))}for(let l=0;l<m;l++)for(let t=0;t<m;t++)l!==t&&(c[l][t]||c[t][l])&&a(l,t);const f=new Map;for(let l=0;l<m;l++){const t=d(l);f.has(t)||f.set(t,[]),f.get(t).push(o[l])}const r=new Map;let y=0;for(const l of f.values())r.set(y++,l);return r}function P(o){const c=[],m=new Set;for(const[,a]of o.clusters)for(const f of a)m.has(f)||(c.push(f),m.add(f));for(const a of o.elementIds)m.has(a)||c.push(a);const u=c.length,p=new Map;for(let a=0;a<o.elementIds.length;a++)p.set(o.elementIds[a],a);const d=Array.from({length:u},()=>Array.from({length:u},()=>null));for(let a=0;a<u;a++)for(let f=0;f<u;f++)d[a][f]=o.matrix[p.get(c[a])][p.get(c[f])];return{...o,elementIds:c,matrix:d}}const R=new Set(["Function","Function","UserActivity"]),z=new Set(["System","Subsystem","Component","LogicalComponent","SoftwareComponent","SoftwareModule","Software"]);function V(o){var y,l;const c=[],m=[];for(const t of Object.values(o.elements))R.has(t.kind)&&c.push(t),z.has(t.kind)&&m.push(t);const u=[],p=new Set,d=new Map;for(const t of m)d.set(t.id,[]);for(const t of o.relationships){if(t.type!=="allocateTo")continue;const i=o.elements[t.sourceId],e=o.elements[t.targetId];!i||!e||R.has(i.kind)&&z.has(e.kind)&&(u.push({functionId:i.id,functionName:i.name,targetId:e.id,targetName:e.name}),p.add(i.id),d.has(e.id)||d.set(e.id,[]),d.get(e.id).push(i.id))}for(const t of c)if(t.allocatedTo&&!p.has(t.id)){const i=m.find(e=>e.name===t.allocatedTo||e.id===t.allocatedTo);i&&(u.push({functionId:t.id,functionName:t.name,targetId:i.id,targetName:i.name}),p.add(t.id),d.has(i.id)||d.set(i.id,[]),d.get(i.id).push(t.id))}const a=[];let f=0;for(const t of c)p.has(t.id)||a.push({id:`ci-${f++}`,type:"unallocated-function",severity:"warning",elementId:t.id,elementName:t.name,message:`Function "${t.name}" is not allocated to any component`});for(const t of m){const i=d.get(t.id);(!i||i.length===0)&&a.push({id:`ci-${f++}`,type:"no-functions-allocated",severity:"info",elementId:t.id,elementName:t.name,message:`Component "${t.name}" has no functions allocated to it`})}const r=new Map;for(const t of u)r.set(t.functionId,t.targetId);for(const t of o.relationships){if(t.type!=="flow")continue;const i=r.get(t.sourceId),e=r.get(t.targetId);if(i&&e&&i!==e){const h=o.elements[t.sourceId],g=o.elements[t.targetId];h&&g&&a.push({id:`ci-${f++}`,type:"cross-component-flow",severity:"info",elementId:t.sourceId,elementName:h.name,message:`Flow from "${h.name}" to "${g.name}" crosses component boundary (${(y=o.elements[i])==null?void 0:y.name} → ${(l=o.elements[e])==null?void 0:l.name})`,relatedIds:[t.targetId,i,e]})}}return{allocations:u,componentFunctions:d,issues:a,functions:c,structures:m}}function N(o){for(const c of o.types)if(v[c])return v[c];return"#6B7280"}function Z(o){const c=N(o),m=Math.min(.15+o.count*.15,.6);return`${c}${Math.round(m*255).toString(16).padStart(2,"0")}`}const E=36,D=160;function Q(){const o=C(n=>n.model),c=C(n=>n.selectElement),m=C(n=>n.selectedElementId),u=C(n=>n.setAnalysisIssues),[p,d]=b.useState(!0),[a,f]=b.useState(!1),[r,y]=b.useState(null),[l,t]=b.useState("functional"),i=b.useMemo(()=>{switch(l){case"functional":return["Function","Function"];case"behavior":return["ActionDefinition","ActionUsage"];case"all":return["Function","Function","ActionDefinition","ActionUsage"]}},[l]),e=b.useMemo(()=>{if(!o)return null;const n=K(o,{kinds:i});return p?P(n):n},[o,p,i]),h=b.useMemo(()=>o?V(o):null,[o]);b.useEffect(()=>{if(h)return u(h.issues.map(n=>({id:n.id,source:"DSM",severity:n.severity,elementId:n.elementId,elementName:n.elementName,message:n.message,tag:n.type==="unallocated-function"?"unallocated":n.type==="cross-component-flow"?"cross-boundary":"no functions"}))),()=>u([])},[h,u]);const g=b.useCallback((n,x)=>{y({row:n,col:x})},[]),F=b.useCallback(()=>{y(null)},[]);if(!o||!e)return s.jsx("div",{className:"flex-1 flex items-center justify-center",style:{color:"#9CA3AF"},children:s.jsx("p",{children:"No model loaded"})});if(e.elementIds.length===0)return s.jsx("div",{className:"flex-1 flex items-center justify-center",style:{background:"#F7F7F5"},children:s.jsxs("div",{className:"text-center",style:{maxWidth:"320px"},children:[s.jsx("div",{style:{fontSize:"40px",marginBottom:"16px",opacity:.4},children:"▤"}),s.jsx("h3",{style:{fontSize:"15px",fontWeight:600,color:"#374151",marginBottom:"8px"},children:"No Functional Elements"}),s.jsx("p",{style:{fontSize:"13px",color:"#9CA3AF",lineHeight:1.6},children:"Add Function or Function elements to your model to see the DSM."})]})});const B=e.elementIds.length,k=new Set;if(p&&e.clusters.size>1){let n=0;for(const[,x]of e.clusters)n+=x.length,n<B&&k.add(n)}const j=r?(()=>{const n=e.matrix[r.row][r.col],x=e.elements[e.elementIds[r.row]],w=e.elements[e.elementIds[r.col]];return{cell:n,rowEl:x,colEl:w}})():null;return s.jsxs("div",{className:"flex-1 flex flex-col",style:{background:"#F7F7F5"},children:[s.jsxs("div",{className:"flex items-center gap-3 px-4 py-2",style:{borderBottom:"1px solid #E5E5E0",background:"#FFFFFF"},children:[s.jsx("span",{style:{fontSize:"13px",fontWeight:600,color:"#374151"},children:"Design Structure Matrix"}),s.jsxs("span",{style:{fontSize:"11px",color:"#9CA3AF"},children:[B," elements, ",e.totalDependencies," dependencies"]}),s.jsx("div",{className:"flex-1"}),s.jsx("div",{className:"flex rounded overflow-hidden",style:{border:"1px solid #E5E5E0"},children:["functional","behavior","all"].map(n=>s.jsx("button",{onClick:()=>t(n),className:"px-2 py-0.5 text-xs font-medium",style:{background:l===n?"#1B3A4B":"#FFFFFF",color:l===n?"#FFFFFF":"#6B7280"},children:n==="functional"?"Functions":n==="behavior"?"Behavior":"All"},n))}),s.jsxs("label",{className:"flex items-center gap-1.5 text-xs",style:{color:"#6B7280"},children:[s.jsx("input",{type:"checkbox",checked:p,onChange:n=>d(n.target.checked),style:{accentColor:"#2DD4A8"}}),"Cluster"]}),s.jsxs("label",{className:"flex items-center gap-1.5 text-xs",style:{color:"#6B7280"},children:[s.jsx("input",{type:"checkbox",checked:a,onChange:n=>f(n.target.checked),style:{accentColor:"#E67E22"}}),"Allocation"]})]}),s.jsxs("div",{className:"flex-1 overflow-auto p-4",children:[s.jsxs("div",{style:{display:"inline-block",position:"relative"},children:[s.jsx("div",{style:{display:"flex",marginLeft:D,marginBottom:"4px"},children:e.elementIds.map((n,x)=>{const w=e.elements[n],A=(r==null?void 0:r.col)===x;return s.jsx("div",{style:{width:E,height:D-20,position:"relative",borderRight:k.has(x+1)?"2px solid #2DD4A8":void 0},children:s.jsx("div",{style:{position:"absolute",bottom:0,left:E/2,transformOrigin:"bottom left",transform:"rotate(-60deg)",whiteSpace:"nowrap",fontSize:"11px",fontWeight:A?600:400,color:A?"#1a1a1a":"#6B7280",cursor:"pointer"},onClick:()=>c(n),children:w.name})},n)})}),e.elementIds.map((n,x)=>{const w=e.elements[n],A=(r==null?void 0:r.row)===x,M=m===n,L=k.has(x);return s.jsxs("div",{style:{display:"flex",alignItems:"center",borderTop:L?"2px solid #2DD4A8":void 0},children:[s.jsxs("div",{style:{width:D,paddingRight:"8px",fontSize:"11px",fontWeight:A||M?600:400,color:A||M?"#1a1a1a":"#6B7280",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",textAlign:"right",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"flex-end",gap:"6px",height:E},onClick:()=>c(n),title:`${w.name} (${w.kind})`,children:[a&&w.allocatedTo&&s.jsx("span",{style:{fontSize:"9px",padding:"1px 4px",borderRadius:"3px",background:"#E67E2220",color:"#E67E22",fontWeight:500},children:w.allocatedTo}),s.jsx("span",{style:{width:"3px",height:"14px",borderRadius:"2px",background:_[w.layer]||"#9CA3AF",flexShrink:0}}),w.name]}),e.elementIds.map(($,I)=>{const S=e.matrix[x][I],T=x===I,W=(r==null?void 0:r.row)===x&&(r==null?void 0:r.col)===I,O=(r==null?void 0:r.row)===x||(r==null?void 0:r.col)===I;return s.jsx("div",{onMouseEnter:()=>g(x,I),onMouseLeave:F,onClick:()=>{S&&c(n)},style:{width:E,height:E,border:"1px solid #E5E5E0",borderRight:k.has(I+1)?"2px solid #2DD4A8":"1px solid #E5E5E0",background:T?"#F3F4F6":S?Z(S):O?"#FAFAFA":"#FFFFFF",display:"flex",alignItems:"center",justifyContent:"center",cursor:S?"pointer":"default",transition:"background 100ms ease",outline:W&&S?`2px solid ${N(S)}`:void 0,outlineOffset:"-2px"},children:S&&!T&&s.jsx("span",{style:{fontSize:"10px",fontWeight:600,color:N(S)},children:S.count>1?S.count:"●"})},$)})]},n)})]}),(j==null?void 0:j.cell)&&s.jsxs("div",{style:{position:"fixed",bottom:"80px",right:"20px",background:"#FFFFFF",border:"1px solid #E5E5E0",borderRadius:"8px",padding:"12px 16px",boxShadow:"0 4px 16px rgba(0,0,0,0.12)",fontSize:"12px",zIndex:100,maxWidth:"280px"},children:[s.jsx("div",{style:{fontWeight:600,color:"#1a1a1a",marginBottom:"6px"},children:j.rowEl.name}),s.jsxs("div",{style:{color:"#6B7280",marginBottom:"4px"},children:["→"," ",j.colEl.name]}),s.jsx("div",{style:{display:"flex",gap:"4px",flexWrap:"wrap"},children:j.cell.types.map(n=>s.jsx("span",{style:{fontSize:"10px",padding:"2px 6px",borderRadius:"4px",background:(v[n]||"#6B7280")+"20",color:v[n]||"#6B7280",fontWeight:500},children:n},n))}),j.cell.flowItems.length>0&&s.jsxs("div",{style:{marginTop:"4px",color:"#9CA3AF",fontSize:"11px"},children:["Items: ",j.cell.flowItems.join(", ")]})]}),s.jsxs("div",{style:{marginTop:"20px",display:"flex",gap:"16px",flexWrap:"wrap",fontSize:"11px",color:"#6B7280"},children:[["flow","decomposedBy","composedOf","allocateTo","succession"].map(n=>s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[s.jsx("span",{style:{width:"10px",height:"10px",borderRadius:"2px",background:v[n]||"#6B7280"}}),n]},n)),p&&e.clusters.size>1&&s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[s.jsx("span",{style:{width:"10px",height:"2px",background:"#2DD4A8"}}),"cluster boundary"]})]})]})]})}export{Q as DSMView};
|
|
1
|
+
import{j as s}from"./reactflow-CX-HDacK.js";import{a as b}from"./zustand-qbFpP9Up.js";import{u as C,f as _,R as v}from"./index-CRFOCEAK.js";const U=["Function","Function","ActionDefinition","ActionUsage"],H=["flow","decomposedBy","composedOf","allocateTo","succession"];function K(o,c){const m=new Set((c==null?void 0:c.kinds)??U),u=new Set((c==null?void 0:c.relationshipTypes)??H),p=(c==null?void 0:c.cluster)??!0,d=[];for(const e of Object.values(o.elements))m.has(e.kind)&&d.push(e);d.sort((e,h)=>{const g=e.kind.localeCompare(h.kind);return g!==0?g:e.name.localeCompare(h.name)});const a=d.map(e=>e.id),f=new Map;for(let e=0;e<a.length;e++)f.set(a[e],e);const r=a.length,y={};for(const e of d)y[e.id]={name:e.name,kind:e.kind,layer:e.layer,allocatedTo:e.allocatedTo};const l=Array.from({length:r},()=>Array.from({length:r},()=>null));let t=0;for(const e of o.relationships){if(!u.has(e.type))continue;const h=f.get(e.sourceId),g=f.get(e.targetId);if(h===void 0||g===void 0||h===g)continue;let F=l[h][g];F||(F={count:0,types:[],flowItems:[]},l[h][g]=F),F.count++,F.types.includes(e.type)||F.types.push(e.type),e.flowItem&&!F.flowItems.includes(e.flowItem)&&F.flowItems.push(e.flowItem),t++}const i=p?Y(a,l):new Map;return{elementIds:a,elements:y,matrix:l,clusters:i,totalDependencies:t}}function Y(o,c){const m=o.length,u=Array.from({length:m},(l,t)=>t),p=new Array(m).fill(0);function d(l){return u[l]!==l&&(u[l]=d(u[l])),u[l]}function a(l,t){const i=d(l),e=d(t);i!==e&&(p[i]<p[e]?u[i]=e:p[i]>p[e]?u[e]=i:(u[e]=i,p[i]++))}for(let l=0;l<m;l++)for(let t=0;t<m;t++)l!==t&&(c[l][t]||c[t][l])&&a(l,t);const f=new Map;for(let l=0;l<m;l++){const t=d(l);f.has(t)||f.set(t,[]),f.get(t).push(o[l])}const r=new Map;let y=0;for(const l of f.values())r.set(y++,l);return r}function P(o){const c=[],m=new Set;for(const[,a]of o.clusters)for(const f of a)m.has(f)||(c.push(f),m.add(f));for(const a of o.elementIds)m.has(a)||c.push(a);const u=c.length,p=new Map;for(let a=0;a<o.elementIds.length;a++)p.set(o.elementIds[a],a);const d=Array.from({length:u},()=>Array.from({length:u},()=>null));for(let a=0;a<u;a++)for(let f=0;f<u;f++)d[a][f]=o.matrix[p.get(c[a])][p.get(c[f])];return{...o,elementIds:c,matrix:d}}const R=new Set(["Function","Function","UserActivity"]),z=new Set(["System","Subsystem","Component","LogicalComponent","SoftwareComponent","SoftwareModule","Software"]);function V(o){var y,l;const c=[],m=[];for(const t of Object.values(o.elements))R.has(t.kind)&&c.push(t),z.has(t.kind)&&m.push(t);const u=[],p=new Set,d=new Map;for(const t of m)d.set(t.id,[]);for(const t of o.relationships){if(t.type!=="allocateTo")continue;const i=o.elements[t.sourceId],e=o.elements[t.targetId];!i||!e||R.has(i.kind)&&z.has(e.kind)&&(u.push({functionId:i.id,functionName:i.name,targetId:e.id,targetName:e.name}),p.add(i.id),d.has(e.id)||d.set(e.id,[]),d.get(e.id).push(i.id))}for(const t of c)if(t.allocatedTo&&!p.has(t.id)){const i=m.find(e=>e.name===t.allocatedTo||e.id===t.allocatedTo);i&&(u.push({functionId:t.id,functionName:t.name,targetId:i.id,targetName:i.name}),p.add(t.id),d.has(i.id)||d.set(i.id,[]),d.get(i.id).push(t.id))}const a=[];let f=0;for(const t of c)p.has(t.id)||a.push({id:`ci-${f++}`,type:"unallocated-function",severity:"warning",elementId:t.id,elementName:t.name,message:`Function "${t.name}" is not allocated to any component`});for(const t of m){const i=d.get(t.id);(!i||i.length===0)&&a.push({id:`ci-${f++}`,type:"no-functions-allocated",severity:"info",elementId:t.id,elementName:t.name,message:`Component "${t.name}" has no functions allocated to it`})}const r=new Map;for(const t of u)r.set(t.functionId,t.targetId);for(const t of o.relationships){if(t.type!=="flow")continue;const i=r.get(t.sourceId),e=r.get(t.targetId);if(i&&e&&i!==e){const h=o.elements[t.sourceId],g=o.elements[t.targetId];h&&g&&a.push({id:`ci-${f++}`,type:"cross-component-flow",severity:"info",elementId:t.sourceId,elementName:h.name,message:`Flow from "${h.name}" to "${g.name}" crosses component boundary (${(y=o.elements[i])==null?void 0:y.name} → ${(l=o.elements[e])==null?void 0:l.name})`,relatedIds:[t.targetId,i,e]})}}return{allocations:u,componentFunctions:d,issues:a,functions:c,structures:m}}function N(o){for(const c of o.types)if(v[c])return v[c];return"#6B7280"}function Z(o){const c=N(o),m=Math.min(.15+o.count*.15,.6);return`${c}${Math.round(m*255).toString(16).padStart(2,"0")}`}const E=36,D=160;function Q(){const o=C(n=>n.model),c=C(n=>n.selectElement),m=C(n=>n.selectedElementId),u=C(n=>n.setAnalysisIssues),[p,d]=b.useState(!0),[a,f]=b.useState(!1),[r,y]=b.useState(null),[l,t]=b.useState("functional"),i=b.useMemo(()=>{switch(l){case"functional":return["Function","Function"];case"behavior":return["ActionDefinition","ActionUsage"];case"all":return["Function","Function","ActionDefinition","ActionUsage"]}},[l]),e=b.useMemo(()=>{if(!o)return null;const n=K(o,{kinds:i});return p?P(n):n},[o,p,i]),h=b.useMemo(()=>o?V(o):null,[o]);b.useEffect(()=>{if(h)return u(h.issues.map(n=>({id:n.id,source:"DSM",severity:n.severity,elementId:n.elementId,elementName:n.elementName,message:n.message,tag:n.type==="unallocated-function"?"unallocated":n.type==="cross-component-flow"?"cross-boundary":"no functions"}))),()=>u([])},[h,u]);const g=b.useCallback((n,x)=>{y({row:n,col:x})},[]),F=b.useCallback(()=>{y(null)},[]);if(!o||!e)return s.jsx("div",{className:"flex-1 flex items-center justify-center",style:{color:"#9CA3AF"},children:s.jsx("p",{children:"No model loaded"})});if(e.elementIds.length===0)return s.jsx("div",{className:"flex-1 flex items-center justify-center",style:{background:"#F7F7F5"},children:s.jsxs("div",{className:"text-center",style:{maxWidth:"320px"},children:[s.jsx("div",{style:{fontSize:"40px",marginBottom:"16px",opacity:.4},children:"▤"}),s.jsx("h3",{style:{fontSize:"15px",fontWeight:600,color:"#374151",marginBottom:"8px"},children:"No Functional Elements"}),s.jsx("p",{style:{fontSize:"13px",color:"#9CA3AF",lineHeight:1.6},children:"Add Function or Function elements to your model to see the DSM."})]})});const B=e.elementIds.length,k=new Set;if(p&&e.clusters.size>1){let n=0;for(const[,x]of e.clusters)n+=x.length,n<B&&k.add(n)}const j=r?(()=>{const n=e.matrix[r.row][r.col],x=e.elements[e.elementIds[r.row]],w=e.elements[e.elementIds[r.col]];return{cell:n,rowEl:x,colEl:w}})():null;return s.jsxs("div",{className:"flex-1 flex flex-col",style:{background:"#F7F7F5"},children:[s.jsxs("div",{className:"flex items-center gap-3 px-4 py-2",style:{borderBottom:"1px solid #E5E5E0",background:"#FFFFFF"},children:[s.jsx("span",{style:{fontSize:"13px",fontWeight:600,color:"#374151"},children:"Design Structure Matrix"}),s.jsxs("span",{style:{fontSize:"11px",color:"#9CA3AF"},children:[B," elements, ",e.totalDependencies," dependencies"]}),s.jsx("div",{className:"flex-1"}),s.jsx("div",{className:"flex rounded overflow-hidden",style:{border:"1px solid #E5E5E0"},children:["functional","behavior","all"].map(n=>s.jsx("button",{onClick:()=>t(n),className:"px-2 py-0.5 text-xs font-medium",style:{background:l===n?"#1B3A4B":"#FFFFFF",color:l===n?"#FFFFFF":"#6B7280"},children:n==="functional"?"Functions":n==="behavior"?"Behavior":"All"},n))}),s.jsxs("label",{className:"flex items-center gap-1.5 text-xs",style:{color:"#6B7280"},children:[s.jsx("input",{type:"checkbox",checked:p,onChange:n=>d(n.target.checked),style:{accentColor:"#2DD4A8"}}),"Cluster"]}),s.jsxs("label",{className:"flex items-center gap-1.5 text-xs",style:{color:"#6B7280"},children:[s.jsx("input",{type:"checkbox",checked:a,onChange:n=>f(n.target.checked),style:{accentColor:"#E67E22"}}),"Allocation"]})]}),s.jsxs("div",{className:"flex-1 overflow-auto p-4",children:[s.jsxs("div",{style:{display:"inline-block",position:"relative"},children:[s.jsx("div",{style:{display:"flex",marginLeft:D,marginBottom:"4px"},children:e.elementIds.map((n,x)=>{const w=e.elements[n],A=(r==null?void 0:r.col)===x;return s.jsx("div",{style:{width:E,height:D-20,position:"relative",borderRight:k.has(x+1)?"2px solid #2DD4A8":void 0},children:s.jsx("div",{style:{position:"absolute",bottom:0,left:E/2,transformOrigin:"bottom left",transform:"rotate(-60deg)",whiteSpace:"nowrap",fontSize:"11px",fontWeight:A?600:400,color:A?"#1a1a1a":"#6B7280",cursor:"pointer"},onClick:()=>c(n),children:w.name})},n)})}),e.elementIds.map((n,x)=>{const w=e.elements[n],A=(r==null?void 0:r.row)===x,M=m===n,L=k.has(x);return s.jsxs("div",{style:{display:"flex",alignItems:"center",borderTop:L?"2px solid #2DD4A8":void 0},children:[s.jsxs("div",{style:{width:D,paddingRight:"8px",fontSize:"11px",fontWeight:A||M?600:400,color:A||M?"#1a1a1a":"#6B7280",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",textAlign:"right",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"flex-end",gap:"6px",height:E},onClick:()=>c(n),title:`${w.name} (${w.kind})`,children:[a&&w.allocatedTo&&s.jsx("span",{style:{fontSize:"9px",padding:"1px 4px",borderRadius:"3px",background:"#E67E2220",color:"#E67E22",fontWeight:500},children:w.allocatedTo}),s.jsx("span",{style:{width:"3px",height:"14px",borderRadius:"2px",background:_[w.layer]||"#9CA3AF",flexShrink:0}}),w.name]}),e.elementIds.map(($,I)=>{const S=e.matrix[x][I],T=x===I,W=(r==null?void 0:r.row)===x&&(r==null?void 0:r.col)===I,O=(r==null?void 0:r.row)===x||(r==null?void 0:r.col)===I;return s.jsx("div",{onMouseEnter:()=>g(x,I),onMouseLeave:F,onClick:()=>{S&&c(n)},style:{width:E,height:E,border:"1px solid #E5E5E0",borderRight:k.has(I+1)?"2px solid #2DD4A8":"1px solid #E5E5E0",background:T?"#F3F4F6":S?Z(S):O?"#FAFAFA":"#FFFFFF",display:"flex",alignItems:"center",justifyContent:"center",cursor:S?"pointer":"default",transition:"background 100ms ease",outline:W&&S?`2px solid ${N(S)}`:void 0,outlineOffset:"-2px"},children:S&&!T&&s.jsx("span",{style:{fontSize:"10px",fontWeight:600,color:N(S)},children:S.count>1?S.count:"●"})},$)})]},n)})]}),(j==null?void 0:j.cell)&&s.jsxs("div",{style:{position:"fixed",bottom:"80px",right:"20px",background:"#FFFFFF",border:"1px solid #E5E5E0",borderRadius:"8px",padding:"12px 16px",boxShadow:"0 4px 16px rgba(0,0,0,0.12)",fontSize:"12px",zIndex:100,maxWidth:"280px"},children:[s.jsx("div",{style:{fontWeight:600,color:"#1a1a1a",marginBottom:"6px"},children:j.rowEl.name}),s.jsxs("div",{style:{color:"#6B7280",marginBottom:"4px"},children:["→"," ",j.colEl.name]}),s.jsx("div",{style:{display:"flex",gap:"4px",flexWrap:"wrap"},children:j.cell.types.map(n=>s.jsx("span",{style:{fontSize:"10px",padding:"2px 6px",borderRadius:"4px",background:(v[n]||"#6B7280")+"20",color:v[n]||"#6B7280",fontWeight:500},children:n},n))}),j.cell.flowItems.length>0&&s.jsxs("div",{style:{marginTop:"4px",color:"#9CA3AF",fontSize:"11px"},children:["Items: ",j.cell.flowItems.join(", ")]})]}),s.jsxs("div",{style:{marginTop:"20px",display:"flex",gap:"16px",flexWrap:"wrap",fontSize:"11px",color:"#6B7280"},children:[["flow","decomposedBy","composedOf","allocateTo","succession"].map(n=>s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[s.jsx("span",{style:{width:"10px",height:"10px",borderRadius:"2px",background:v[n]||"#6B7280"}}),n]},n)),p&&e.clusters.size>1&&s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[s.jsx("span",{style:{width:"10px",height:"2px",background:"#2DD4A8"}}),"cluster boundary"]})]})]})]})}export{Q as DSMView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./reactflow-WKyu73tD.js";import{a as f}from"./zustand-qbFpP9Up.js";import{u as g,d as m}from"./index-CgRwea72.js";function j(i,d,s){var u,l;const n=Object.values(i.elements),o={},t={};for(const r of n)o[r.layer]=(o[r.layer]||0)+1,t[r.kind.toLowerCase()]=(t[r.kind.toLowerCase()]||0)+1;const a={};for(const r of i.relationships)a[r.type.toLowerCase()]=(a[r.type.toLowerCase()]||0)+1;return{totalElements:n.length,totalRelationships:i.relationships.length,violations:d,completenessPercent:s,riskCount:(o.risk||0)+(o.analysis||0),requirementsCount:o.requirements||0,architectureCount:["logical","physical","functional","logical_structure","software_structure","hardware_structure","functions","interfaces","system","context","operational","behavior"].reduce((r,p)=>r+(o[p]||0),0),verificationCount:(o.verification||0)+(o.assurance||0),hazardCount:t.hazard||0,requirementCount:Object.entries(t).filter(([r])=>r.endsWith("requirement")).reduce((r,[,p])=>r+p,0),riskControlCount:t.riskcontrol||0,systemCount:(t.system||0)+(t.subsystem||0)+(t.softwaresystem||0)+(t.logicalcomponent||0)+(t.hardwareassembly||0)+(t.softwarecomponent||0)+(t.processingnode||0),testCount:(t.verificationcase||0)+(t.validationcase||0)+(t.testartifact||0)+(t.test||0),mitigatesCount:Object.entries(a).filter(([r])=>r.startsWith("mitigat")).reduce((r,[,p])=>r+p,0),verificationLinkCount:Object.entries(a).filter(([r])=>r.startsWith("verif")||r.startsWith("validate")||r==="testedbyusability").reduce((r,[,p])=>r+p,0),diagramCount:((u=i.diagrams)==null?void 0:u.length)??0,projectName:((l=i.metadata)==null?void 0:l.projectName)||i.projectName||i.name||"My Device Project"}}function k(i){return i.totalElements===0?{icon:"🚀",title:"Add your first model elements",description:"Start with intended use, actors, and a system requirement. Or use the Workflow Wizard to guide you step by step.",urgency:"high"}:i.requirementCount===0?{icon:"📋",title:"Define your first requirement",description:"Your model has elements but no system requirements yet. Add a Requirement in the Model Explorer.",urgency:"high"}:i.hazardCount===0?{icon:"⚠️",title:"Add your first hazard",description:`You have ${i.requirementCount} requirement(s) but no hazard analysis yet. ISO 14971 requires hazard identification early.`,urgency:"high"}:i.hazardCount>0&&i.mitigatesCount===0?{icon:"🔗",title:"Connect hazards to risk controls",description:`You have ${i.hazardCount} hazard(s) but no MitigatesHazard relationships. Connect hazards to risk controls to complete the ISO 14971 chain.`,urgency:"high"}:i.systemCount===0?{icon:"🏗️",title:"Define your system architecture",description:"No architecture components found (SoftwareSystem, LogicalComponent, HardwareAssembly, …). Add an architecture layer to ground your requirements and risk analysis.",urgency:"medium"}:i.testCount===0?{icon:"🧪",title:"Add verification tests",description:`${i.requirementCount} requirement(s) have no verification tests yet. Add VerificationCases and link them to requirements with VerifiedBy.`,urgency:"medium"}:i.verificationLinkCount===0&&i.testCount>0?{icon:"↔️",title:"Link tests to requirements",description:"Verification cases exist but no VerifiedBy links found. Open the Traceability Matrix to connect tests to their requirements.",urgency:"medium"}:{icon:"✅",title:"Good coverage so far",description:"Requirements, hazards, and risk controls are in place. Check the GapBar (⌘⇧P) for completeness gaps before your review.",urgency:"low"}}function h({label:i,value:d,color:s,subtitle:n}){return e.jsxs("div",{style:{background:"#FFFFFF",border:"1px solid #E5E5E0",borderRadius:"12px",padding:"20px 24px",display:"flex",flexDirection:"column",gap:"4px"},children:[e.jsx("div",{style:{fontSize:"28px",fontWeight:800,color:s,lineHeight:1},children:d}),e.jsx("div",{style:{fontSize:"12px",fontWeight:600,color:"#374151"},children:i}),n&&e.jsx("div",{style:{fontSize:"11px",color:"#9CA3AF"},children:n})]})}function y({layer:i,label:d,count:s,color:n,onClick:o}){const t=s>0;return e.jsxs("button",{onClick:o,style:{background:t?`${n}12`:"#F9FAFB",border:`1px solid ${t?n+"30":"#E5E5E0"}`,borderRadius:"12px",padding:"16px",cursor:"pointer",textAlign:"left",transition:"all 0.15s"},onMouseEnter:a=>{a.currentTarget.style.background=t?`${n}20`:"#F3F4F6",a.currentTarget.style.transform="translateY(-1px)",a.currentTarget.style.boxShadow="0 4px 12px rgba(0,0,0,0.08)"},onMouseLeave:a=>{a.currentTarget.style.background=t?`${n}12`:"#F9FAFB",a.currentTarget.style.transform="none",a.currentTarget.style.boxShadow="none"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"8px"},children:[e.jsx("span",{style:{fontSize:"11px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.06em",color:t?n:"#9CA3AF"},children:d}),e.jsxs("span",{style:{fontSize:"10px",fontWeight:600,padding:"2px 8px",borderRadius:"999px",background:t?n+"20":"#F3F4F6",color:t?n:"#9CA3AF"},children:[s," elements"]})]}),e.jsx("div",{style:{width:"100%",height:"4px",background:"#F3F4F6",borderRadius:"2px"},children:e.jsx("div",{style:{height:"100%",borderRadius:"2px",background:t?n:"transparent",width:t?`${Math.min(100,s/10*100)}%`:"0",transition:"width 0.4s ease"}})}),e.jsx("div",{style:{fontSize:"11px",color:"#9CA3AF",marginTop:"8px"},children:t?"Click to explore →":"Not started"})]})}function x({icon:i,label:d,onClick:s,variant:n="secondary"}){const o=n==="primary";return e.jsxs("button",{onClick:s,style:{display:"flex",alignItems:"center",gap:"8px",padding:"10px 16px",borderRadius:"8px",cursor:"pointer",fontSize:"13px",fontWeight:600,border:"none",background:o?"#1B3A4B":"rgba(255,255,255,0.7)",color:o?"#FFFFFF":"#374151",backdropFilter:"blur(4px)",transition:"all 0.15s"},onMouseEnter:t=>{t.currentTarget.style.background=o?"#244D63":"rgba(255,255,255,0.95)",t.currentTarget.style.boxShadow="0 2px 8px rgba(0,0,0,0.1)"},onMouseLeave:t=>{t.currentTarget.style.background=o?"#1B3A4B":"rgba(255,255,255,0.7)",t.currentTarget.style.boxShadow="none"},children:[e.jsx("span",{children:i}),e.jsx("span",{children:d})]})}function S(){var b;const i=g(c=>c.model),d=g(c=>c.validation),s=g(c=>c.completeness),n=g(c=>c.setActiveView),o=g(c=>c.setExplorerTab),t=g(c=>c.toggleGapBar),a=((b=d==null?void 0:d.violations)==null?void 0:b.length)??0,u=f.useMemo(()=>{if(typeof(s==null?void 0:s.overall)=="number")return Math.round(s.overall);if(!(s!=null&&s.layers)||s.layers.length===0)return 0;const c=s.layers.reduce((C,v)=>C+(v.completeness||0),0)/s.layers.length;return Math.round(c)},[s]),l=f.useMemo(()=>i?j(i,a,u):null,[i,a,u]),r=f.useMemo(()=>l?k(l):null,[l]);return!l||!i?e.jsx("div",{style:{flex:1,display:"flex",alignItems:"center",justifyContent:"center",background:"#F7F7F5"},children:e.jsx("div",{style:{fontSize:"13px",color:"#9CA3AF"},children:"Loading dashboard…"})}):e.jsx("div",{style:{flex:1,overflowY:"auto",background:"linear-gradient(135deg, #EEF7F3 0%, #EAF2F8 55%, #F2EEF8 100%)",padding:"32px 40px"},children:e.jsxs("div",{style:{maxWidth:"960px",margin:"0 auto"},children:[e.jsxs("div",{style:{marginBottom:"28px"},children:[e.jsx("h1",{style:{fontSize:"22px",fontWeight:800,color:"#1B3A4B",margin:"0 0 4px 0"},children:l.projectName}),e.jsxs("p",{style:{fontSize:"13px",color:"#4B6E80",margin:0},children:["Model dashboard · ",new Date().toLocaleDateString("en-US",{month:"long",day:"numeric",year:"numeric"})]})]}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(4, 1fr)",gap:"12px",marginBottom:"24px"},children:[e.jsx(h,{label:"Elements",value:l.totalElements,color:"#1B3A4B"}),e.jsx(h,{label:"Relationships",value:l.totalRelationships,color:"#4A90D9"}),e.jsx(h,{label:"Completeness",value:`${u}%`,color:u>=70?"#2ECC71":u>=40?"#F39C12":"#E74C3C"}),e.jsx(h,{label:"Violations",value:a,color:a===0?"#2ECC71":"#E74C3C",subtitle:a===0?"All rules passing":"Open the GapBar"})]}),e.jsxs("div",{style:{marginBottom:"24px"},children:[e.jsx("h2",{style:{fontSize:"11px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em",color:"#7A9BAA",margin:"0 0 12px 0"},children:"Layer Coverage"}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(4, 1fr)",gap:"12px"},children:[e.jsx(y,{layer:"requirements",label:"Requirements",count:l.requirementsCount,color:m.requirements,onClick:()=>{o("model"),n({type:"welcome"})}}),e.jsx(y,{layer:"risk",label:"Risk",count:l.riskCount,color:m.risk,onClick:()=>{o("model"),n({type:"welcome"})}}),e.jsx(y,{layer:"logical",label:"Architecture",count:l.architectureCount,color:m.logical,onClick:()=>{o("views"),n({type:"welcome"})}}),e.jsx(y,{layer:"verification",label:"Verification",count:l.verificationCount,color:m.verification,onClick:()=>n({type:"traceability"})})]})]}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"16px",marginBottom:"24px"},children:[r&&e.jsxs("div",{style:{background:r.urgency==="high"?"rgba(231,76,60,0.06)":r.urgency==="medium"?"rgba(243,156,18,0.06)":"rgba(46,204,113,0.06)",border:`1px solid ${r.urgency==="high"?"#E74C3C30":r.urgency==="medium"?"#F39C1230":"#2ECC7130"}`,borderRadius:"12px",padding:"20px"},children:[e.jsx("div",{style:{fontSize:"11px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em",color:"#7A9BAA",marginBottom:"10px"},children:"💡 Suggested Next Step"}),e.jsx("div",{style:{fontSize:"16px",marginBottom:"6px"},children:r.icon}),e.jsx("div",{style:{fontSize:"14px",fontWeight:700,color:"#1B3A4B",marginBottom:"6px"},children:r.title}),e.jsx("div",{style:{fontSize:"12px",color:"#4B6E80",lineHeight:"1.6"},children:r.description}),r.urgency!=="low"&&e.jsx("button",{onClick:()=>n({type:"workflow-wizard"}),style:{marginTop:"14px",padding:"8px 14px",fontSize:"12px",fontWeight:600,background:"#1B3A4B",color:"#FFFFFF",border:"none",borderRadius:"6px",cursor:"pointer"},onMouseEnter:c=>c.currentTarget.style.background="#244D63",onMouseLeave:c=>c.currentTarget.style.background="#1B3A4B",children:"Open Workflow Wizard →"})]}),e.jsxs("div",{style:{background:"rgba(255,255,255,0.6)",border:"1px solid rgba(255,255,255,0.9)",borderRadius:"12px",padding:"20px",backdropFilter:"blur(4px)"},children:[e.jsx("div",{style:{fontSize:"11px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em",color:"#7A9BAA",marginBottom:"14px"},children:"Quick Actions"}),e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"8px"},children:[e.jsx(x,{icon:"🗂️",label:"Browse Model",onClick:()=>{o("model")}}),e.jsx(x,{icon:"📊",label:"View Diagrams",onClick:()=>o("views")}),e.jsx(x,{icon:"↔️",label:"Traceability Matrix",onClick:()=>n({type:"traceability"})}),e.jsx(x,{icon:"📋",label:"First Review Dashboard",onClick:()=>n({type:"review-dashboard"})}),e.jsx(x,{icon:"✅",label:"Check Completeness",onClick:()=>t()}),e.jsx(x,{icon:"📈",label:"Full Statistics",onClick:()=>n({type:"statistics"})})]})]})]}),l.diagramCount>0&&e.jsx("div",{style:{background:"rgba(255,255,255,0.6)",border:"1px solid rgba(255,255,255,0.9)",borderRadius:"12px",padding:"16px 20px",backdropFilter:"blur(4px)"},children:e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[e.jsxs("div",{style:{fontSize:"13px",fontWeight:600,color:"#374151"},children:[l.diagramCount," diagram",l.diagramCount!==1?"s":""," in this project"]}),e.jsx("button",{onClick:()=>o("views"),style:{fontSize:"12px",color:"#4A90D9",background:"none",border:"none",cursor:"pointer",fontWeight:600},children:"Browse diagrams →"})]})})]})})}export{S as Dashboard};
|
|
1
|
+
import{j as e}from"./reactflow-CX-HDacK.js";import{a as f}from"./zustand-qbFpP9Up.js";import{u as g,f as m}from"./index-CRFOCEAK.js";function j(i,d,s){var u,l;const n=Object.values(i.elements),o={},t={};for(const r of n)o[r.layer]=(o[r.layer]||0)+1,t[r.kind.toLowerCase()]=(t[r.kind.toLowerCase()]||0)+1;const a={};for(const r of i.relationships)a[r.type.toLowerCase()]=(a[r.type.toLowerCase()]||0)+1;return{totalElements:n.length,totalRelationships:i.relationships.length,violations:d,completenessPercent:s,riskCount:(o.risk||0)+(o.analysis||0),requirementsCount:o.requirements||0,architectureCount:["logical","physical","functional","logical_structure","software_structure","hardware_structure","functions","interfaces","system","context","operational","behavior"].reduce((r,p)=>r+(o[p]||0),0),verificationCount:(o.verification||0)+(o.assurance||0),hazardCount:t.hazard||0,requirementCount:Object.entries(t).filter(([r])=>r.endsWith("requirement")).reduce((r,[,p])=>r+p,0),riskControlCount:t.riskcontrol||0,systemCount:(t.system||0)+(t.subsystem||0)+(t.softwaresystem||0)+(t.logicalcomponent||0)+(t.hardwareassembly||0)+(t.softwarecomponent||0)+(t.processingnode||0),testCount:(t.verificationcase||0)+(t.validationcase||0)+(t.testartifact||0)+(t.test||0),mitigatesCount:Object.entries(a).filter(([r])=>r.startsWith("mitigat")).reduce((r,[,p])=>r+p,0),verificationLinkCount:Object.entries(a).filter(([r])=>r.startsWith("verif")||r.startsWith("validate")||r==="testedbyusability").reduce((r,[,p])=>r+p,0),diagramCount:((u=i.diagrams)==null?void 0:u.length)??0,projectName:((l=i.metadata)==null?void 0:l.projectName)||i.projectName||i.name||"My Device Project"}}function k(i){return i.totalElements===0?{icon:"🚀",title:"Add your first model elements",description:"Start with intended use, actors, and a system requirement. Or use the Workflow Wizard to guide you step by step.",urgency:"high"}:i.requirementCount===0?{icon:"📋",title:"Define your first requirement",description:"Your model has elements but no system requirements yet. Add a Requirement in the Model Explorer.",urgency:"high"}:i.hazardCount===0?{icon:"⚠️",title:"Add your first hazard",description:`You have ${i.requirementCount} requirement(s) but no hazard analysis yet. ISO 14971 requires hazard identification early.`,urgency:"high"}:i.hazardCount>0&&i.mitigatesCount===0?{icon:"🔗",title:"Connect hazards to risk controls",description:`You have ${i.hazardCount} hazard(s) but no MitigatesHazard relationships. Connect hazards to risk controls to complete the ISO 14971 chain.`,urgency:"high"}:i.systemCount===0?{icon:"🏗️",title:"Define your system architecture",description:"No architecture components found (SoftwareSystem, LogicalComponent, HardwareAssembly, …). Add an architecture layer to ground your requirements and risk analysis.",urgency:"medium"}:i.testCount===0?{icon:"🧪",title:"Add verification tests",description:`${i.requirementCount} requirement(s) have no verification tests yet. Add VerificationCases and link them to requirements with VerifiedBy.`,urgency:"medium"}:i.verificationLinkCount===0&&i.testCount>0?{icon:"↔️",title:"Link tests to requirements",description:"Verification cases exist but no VerifiedBy links found. Open the Traceability Matrix to connect tests to their requirements.",urgency:"medium"}:{icon:"✅",title:"Good coverage so far",description:"Requirements, hazards, and risk controls are in place. Check the GapBar (⌘⇧P) for completeness gaps before your review.",urgency:"low"}}function h({label:i,value:d,color:s,subtitle:n}){return e.jsxs("div",{style:{background:"#FFFFFF",border:"1px solid #E5E5E0",borderRadius:"12px",padding:"20px 24px",display:"flex",flexDirection:"column",gap:"4px"},children:[e.jsx("div",{style:{fontSize:"28px",fontWeight:800,color:s,lineHeight:1},children:d}),e.jsx("div",{style:{fontSize:"12px",fontWeight:600,color:"#374151"},children:i}),n&&e.jsx("div",{style:{fontSize:"11px",color:"#9CA3AF"},children:n})]})}function y({layer:i,label:d,count:s,color:n,onClick:o}){const t=s>0;return e.jsxs("button",{onClick:o,style:{background:t?`${n}12`:"#F9FAFB",border:`1px solid ${t?n+"30":"#E5E5E0"}`,borderRadius:"12px",padding:"16px",cursor:"pointer",textAlign:"left",transition:"all 0.15s"},onMouseEnter:a=>{a.currentTarget.style.background=t?`${n}20`:"#F3F4F6",a.currentTarget.style.transform="translateY(-1px)",a.currentTarget.style.boxShadow="0 4px 12px rgba(0,0,0,0.08)"},onMouseLeave:a=>{a.currentTarget.style.background=t?`${n}12`:"#F9FAFB",a.currentTarget.style.transform="none",a.currentTarget.style.boxShadow="none"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"8px"},children:[e.jsx("span",{style:{fontSize:"11px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.06em",color:t?n:"#9CA3AF"},children:d}),e.jsxs("span",{style:{fontSize:"10px",fontWeight:600,padding:"2px 8px",borderRadius:"999px",background:t?n+"20":"#F3F4F6",color:t?n:"#9CA3AF"},children:[s," elements"]})]}),e.jsx("div",{style:{width:"100%",height:"4px",background:"#F3F4F6",borderRadius:"2px"},children:e.jsx("div",{style:{height:"100%",borderRadius:"2px",background:t?n:"transparent",width:t?`${Math.min(100,s/10*100)}%`:"0",transition:"width 0.4s ease"}})}),e.jsx("div",{style:{fontSize:"11px",color:"#9CA3AF",marginTop:"8px"},children:t?"Click to explore →":"Not started"})]})}function x({icon:i,label:d,onClick:s,variant:n="secondary"}){const o=n==="primary";return e.jsxs("button",{onClick:s,style:{display:"flex",alignItems:"center",gap:"8px",padding:"10px 16px",borderRadius:"8px",cursor:"pointer",fontSize:"13px",fontWeight:600,border:"none",background:o?"#1B3A4B":"rgba(255,255,255,0.7)",color:o?"#FFFFFF":"#374151",backdropFilter:"blur(4px)",transition:"all 0.15s"},onMouseEnter:t=>{t.currentTarget.style.background=o?"#244D63":"rgba(255,255,255,0.95)",t.currentTarget.style.boxShadow="0 2px 8px rgba(0,0,0,0.1)"},onMouseLeave:t=>{t.currentTarget.style.background=o?"#1B3A4B":"rgba(255,255,255,0.7)",t.currentTarget.style.boxShadow="none"},children:[e.jsx("span",{children:i}),e.jsx("span",{children:d})]})}function S(){var b;const i=g(c=>c.model),d=g(c=>c.validation),s=g(c=>c.completeness),n=g(c=>c.setActiveView),o=g(c=>c.setExplorerTab),t=g(c=>c.toggleGapBar),a=((b=d==null?void 0:d.violations)==null?void 0:b.length)??0,u=f.useMemo(()=>{if(typeof(s==null?void 0:s.overall)=="number")return Math.round(s.overall);if(!(s!=null&&s.layers)||s.layers.length===0)return 0;const c=s.layers.reduce((C,v)=>C+(v.completeness||0),0)/s.layers.length;return Math.round(c)},[s]),l=f.useMemo(()=>i?j(i,a,u):null,[i,a,u]),r=f.useMemo(()=>l?k(l):null,[l]);return!l||!i?e.jsx("div",{style:{flex:1,display:"flex",alignItems:"center",justifyContent:"center",background:"#F7F7F5"},children:e.jsx("div",{style:{fontSize:"13px",color:"#9CA3AF"},children:"Loading dashboard…"})}):e.jsx("div",{style:{flex:1,overflowY:"auto",background:"linear-gradient(135deg, #EEF7F3 0%, #EAF2F8 55%, #F2EEF8 100%)",padding:"32px 40px"},children:e.jsxs("div",{style:{maxWidth:"960px",margin:"0 auto"},children:[e.jsxs("div",{style:{marginBottom:"28px"},children:[e.jsx("h1",{style:{fontSize:"22px",fontWeight:800,color:"#1B3A4B",margin:"0 0 4px 0"},children:l.projectName}),e.jsxs("p",{style:{fontSize:"13px",color:"#4B6E80",margin:0},children:["Model dashboard · ",new Date().toLocaleDateString("en-US",{month:"long",day:"numeric",year:"numeric"})]})]}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(4, 1fr)",gap:"12px",marginBottom:"24px"},children:[e.jsx(h,{label:"Elements",value:l.totalElements,color:"#1B3A4B"}),e.jsx(h,{label:"Relationships",value:l.totalRelationships,color:"#4A90D9"}),e.jsx(h,{label:"Completeness",value:`${u}%`,color:u>=70?"#2ECC71":u>=40?"#F39C12":"#E74C3C"}),e.jsx(h,{label:"Violations",value:a,color:a===0?"#2ECC71":"#E74C3C",subtitle:a===0?"All rules passing":"Open the GapBar"})]}),e.jsxs("div",{style:{marginBottom:"24px"},children:[e.jsx("h2",{style:{fontSize:"11px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em",color:"#7A9BAA",margin:"0 0 12px 0"},children:"Layer Coverage"}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(4, 1fr)",gap:"12px"},children:[e.jsx(y,{layer:"requirements",label:"Requirements",count:l.requirementsCount,color:m.requirements,onClick:()=>{o("model"),n({type:"welcome"})}}),e.jsx(y,{layer:"risk",label:"Risk",count:l.riskCount,color:m.risk,onClick:()=>{o("model"),n({type:"welcome"})}}),e.jsx(y,{layer:"logical",label:"Architecture",count:l.architectureCount,color:m.logical,onClick:()=>{o("views"),n({type:"welcome"})}}),e.jsx(y,{layer:"verification",label:"Verification",count:l.verificationCount,color:m.verification,onClick:()=>n({type:"traceability"})})]})]}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"16px",marginBottom:"24px"},children:[r&&e.jsxs("div",{style:{background:r.urgency==="high"?"rgba(231,76,60,0.06)":r.urgency==="medium"?"rgba(243,156,18,0.06)":"rgba(46,204,113,0.06)",border:`1px solid ${r.urgency==="high"?"#E74C3C30":r.urgency==="medium"?"#F39C1230":"#2ECC7130"}`,borderRadius:"12px",padding:"20px"},children:[e.jsx("div",{style:{fontSize:"11px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em",color:"#7A9BAA",marginBottom:"10px"},children:"💡 Suggested Next Step"}),e.jsx("div",{style:{fontSize:"16px",marginBottom:"6px"},children:r.icon}),e.jsx("div",{style:{fontSize:"14px",fontWeight:700,color:"#1B3A4B",marginBottom:"6px"},children:r.title}),e.jsx("div",{style:{fontSize:"12px",color:"#4B6E80",lineHeight:"1.6"},children:r.description}),r.urgency!=="low"&&e.jsx("button",{onClick:()=>n({type:"workflow-wizard"}),style:{marginTop:"14px",padding:"8px 14px",fontSize:"12px",fontWeight:600,background:"#1B3A4B",color:"#FFFFFF",border:"none",borderRadius:"6px",cursor:"pointer"},onMouseEnter:c=>c.currentTarget.style.background="#244D63",onMouseLeave:c=>c.currentTarget.style.background="#1B3A4B",children:"Open Workflow Wizard →"})]}),e.jsxs("div",{style:{background:"rgba(255,255,255,0.6)",border:"1px solid rgba(255,255,255,0.9)",borderRadius:"12px",padding:"20px",backdropFilter:"blur(4px)"},children:[e.jsx("div",{style:{fontSize:"11px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.08em",color:"#7A9BAA",marginBottom:"14px"},children:"Quick Actions"}),e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"8px"},children:[e.jsx(x,{icon:"🗂️",label:"Browse Model",onClick:()=>{o("model")}}),e.jsx(x,{icon:"📊",label:"View Diagrams",onClick:()=>o("views")}),e.jsx(x,{icon:"↔️",label:"Traceability Matrix",onClick:()=>n({type:"traceability"})}),e.jsx(x,{icon:"📋",label:"First Review Dashboard",onClick:()=>n({type:"review-dashboard"})}),e.jsx(x,{icon:"✅",label:"Check Completeness",onClick:()=>t()}),e.jsx(x,{icon:"📈",label:"Full Statistics",onClick:()=>n({type:"statistics"})})]})]})]}),l.diagramCount>0&&e.jsx("div",{style:{background:"rgba(255,255,255,0.6)",border:"1px solid rgba(255,255,255,0.9)",borderRadius:"12px",padding:"16px 20px",backdropFilter:"blur(4px)"},children:e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[e.jsxs("div",{style:{fontSize:"13px",fontWeight:600,color:"#374151"},children:[l.diagramCount," diagram",l.diagramCount!==1?"s":""," in this project"]}),e.jsx("button",{onClick:()=>o("views"),style:{fontSize:"12px",color:"#4A90D9",background:"none",border:"none",cursor:"pointer",fontWeight:600},children:"Browse diagrams →"})]})})]})})}export{S as Dashboard};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e}from"./reactflow-CX-HDacK.js";import{a as m}from"./zustand-qbFpP9Up.js";import{u as b}from"./index-CRFOCEAK.js";const h=[{id:"rmp",title:"Risk Management Plan",standards:["ISO 14971:2019 §4.4"],layers:["risk"],relevantKinds:["Hazard","HazardousSituation","Harm","RiskControlMeasure","RiskAcceptabilityCriteria"],group:"risk"},{id:"har",title:"Hazard Analysis Report",standards:["ISO 14971:2019 §5","ISO 14971:2019 §6"],layers:["risk"],relevantKinds:["Hazard","HazardousSituation","Harm","RiskControlMeasure"],group:"risk"},{id:"fmea",title:"Failure Mode and Effects Analysis",standards:["IEC 60812:2018"],layers:["risk","functional","physical"],relevantKinds:["Hazard","RiskControlMeasure","Function","Component","Subsystem"],group:"risk"},{id:"rtm",title:"Requirements Traceability Matrix",standards:["IEC 62304:2006 §5.1.1"],layers:["requirements","functional","verification"],relevantKinds:["Requirement","Requirement","DesignInput","DesignOutput","TestCase","VerificationActivity"],group:"design"},{id:"sad",title:"System Architecture Description",standards:["ISO/IEC/IEEE 42010:2022"],layers:["functional","logical","physical","software","interfaces"],relevantKinds:["Function","Component","Subsystem","Interface","Port","SoftwareItem","SOUPComponent"],group:"design"},{id:"sds",title:"Software Design Specification",standards:["IEC 62304:2006 §5.4"],layers:["software"],relevantKinds:["SoftwareItem","SoftwareUnit","SoftwareSystem","SOUPComponent","Interface"],group:"design"},{id:"soup",title:"SOUP List",standards:["IEC 62304:2006 §8.1.2"],layers:["software"],relevantKinds:["SOUPComponent"],group:"design"},{id:"dip",title:"Design Input Plan",standards:["ISO 13485:2016 §7.3.3"],layers:["requirements","business"],relevantKinds:["DesignInput","Requirement","Need","UseCase"],group:"design"},{id:"dop",title:"Design Output Plan",standards:["ISO 13485:2016 §7.3.4"],layers:["functional","physical","software"],relevantKinds:["DesignOutput","Component","SoftwareItem","Function"],group:"design"},{id:"vvp",title:"Verification & Validation Plan",standards:["ISO 13485:2016 §7.3.6"],layers:["verification"],relevantKinds:["TestCase","VerificationActivity","ValidationActivity","TestProtocol"],group:"verification"},{id:"vvr",title:"Verification & Validation Report",standards:["ISO 13485:2016 §7.3.7"],layers:["verification"],relevantKinds:["TestCase","VerificationActivity","ValidationActivity","TestResult"],group:"verification"},{id:"sdp",title:"Software Development Plan",standards:["IEC 62304:2006 §5.1"],layers:["software","verification"],relevantKinds:["SoftwareItem","SoftwareUnit","SoftwareSystem","TestCase"],group:"compliance"},{id:"csr",title:"Clinical Safety Report",standards:["ISO 14971:2019 §10"],layers:["risk","verification"],relevantKinds:["Hazard","RiskControlMeasure","ClinicalEvidence","ValidationActivity"],group:"compliance"},{id:"uer",title:"Usability Engineering Report",standards:["IEC 62366-1:2015"],layers:["ui","requirements"],relevantKinds:["UseCase","UserActivity","UserInterface","UsabilityRequirement"],group:"compliance"},{id:"cybersecurity",title:"Cybersecurity Documentation",standards:["IEC 81001-5-1:2021"],layers:["software","interfaces"],relevantKinds:["ThreatModel","SecurityControl","Interface","SOUPComponent"],group:"compliance"},{id:"labeling",title:"Labeling Specification",standards:["21 CFR 801"],layers:["requirements","ui"],relevantKinds:["LabelingRequirement","Requirement"],group:"compliance"},{id:"dhf-index",title:"Design History File Index",standards:["ISO 13485:2016 §4.2.4"],layers:[],relevantKinds:[],group:"all"},{id:"change-log",title:"Design Change Log",standards:["ISO 13485:2016 §7.3.9"],layers:[],relevantKinds:[],group:"all"}],j={risk:"Risk Management",design:"Design & Architecture",verification:"Verification & Validation",compliance:"Compliance & Standards",all:"General"},v={risk:"#E74C3C",design:"#4A90D9",verification:"#2ECC71",compliance:"#8E44AD",all:"#6B7280"};function B(n,i,o){const l=Object.values(i.elements).filter(s=>n.relevantKinds.includes(s.kind)),c=((o==null?void 0:o.violations)||[]).filter(s=>n.relevantKinds.includes(s.elementKind)||n.layers.includes(s.layer)),a=c.filter(s=>s.severity==="error").length;return{elementCount:l.length,gapCount:a,status:l.length===0?"empty":a===0?"complete":"partial",violations:c}}function z(){const n=b(t=>t.model),i=b(t=>t.validation),o=b(t=>t.completeness),[l,c]=m.useState(null),[a,s]=m.useState(null),r=m.useMemo(()=>{if(!n)return new Map;const t=new Map;for(const d of h)t.set(d.id,B(d,n,i));return t},[n,i]),x=m.useMemo(()=>a?h.filter(t=>t.group===a||t.group==="all"):h,[a]),g=m.useMemo(()=>{const t=new Map;for(const d of x){const p=d.group;t.has(p)||t.set(p,[]),t.get(p).push(d)}return t},[x]),f=m.useMemo(()=>{let t=0,d=0,p=0;for(const y of r.values())y.status==="complete"?t++:y.status==="partial"?d++:p++;return{complete:t,partial:d,empty:p,total:h.length}},[r]);if(!n)return e.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%",color:"#9CA3AF"},children:"Waiting for model data..."});const C=l?h.find(t=>t.id===l):null,A=l?r.get(l):null;return e.jsxs("div",{style:{height:"100%",overflow:"auto",background:"#F7F7F5",padding:"24px"},children:[e.jsxs("div",{style:{marginBottom:"24px"},children:[e.jsx("h2",{style:{fontSize:"20px",fontWeight:700,color:"#1B3A4B",margin:0},children:"Design History File Dashboard"}),e.jsxs("p",{style:{color:"#6B7280",fontSize:"13px",marginTop:"4px"},children:[f.total," documents | ",f.complete," complete | ",f.partial," partial | ",f.empty," empty",o&&` | Overall completeness: ${o.overall}%`]})]}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(140px, 1fr))",gap:"12px",marginBottom:"24px"},children:[e.jsx(u,{label:"Complete",value:f.complete,color:"#059669"}),e.jsx(u,{label:"Partial",value:f.partial,color:"#d97706"}),e.jsx(u,{label:"Empty",value:f.empty,color:"#dc2626"}),e.jsx(u,{label:"Completeness",value:`${(o==null?void 0:o.overall)||0}%`,color:"#2563eb"})]}),e.jsxs("div",{style:{display:"flex",gap:"8px",marginBottom:"20px",flexWrap:"wrap"},children:[e.jsx(S,{label:"All",active:!a,onClick:()=>s(null)}),Object.entries(j).filter(([t])=>t!=="all").map(([t,d])=>e.jsx(S,{label:d,active:a===t,onClick:()=>s(a===t?null:t),color:v[t]},t))]}),l?e.jsx(w,{doc:C,status:A,model:n,validation:i,onBack:()=>c(null)}):Array.from(g.entries()).map(([t,d])=>e.jsxs("div",{style:{marginBottom:"24px"},children:[e.jsxs("h3",{style:{fontSize:"14px",fontWeight:600,color:v[t]||"#374151",marginBottom:"12px",display:"flex",alignItems:"center",gap:"8px"},children:[e.jsx("span",{style:{width:"8px",height:"8px",borderRadius:"50%",background:v[t]||"#6B7280",display:"inline-block"}}),j[t]||t]}),e.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(280px, 1fr))",gap:"12px"},children:d.map(p=>{const y=r.get(p.id);return e.jsx(k,{doc:p,status:y,onClick:()=>c(p.id)},p.id)})})]},t))]})}function u({label:n,value:i,color:o}){return e.jsxs("div",{style:{background:"#fff",border:"1px solid #e5e7eb",borderRadius:"8px",padding:"14px 16px",textAlign:"center"},children:[e.jsx("div",{style:{fontSize:"24px",fontWeight:700,color:o},children:i}),e.jsx("div",{style:{fontSize:"11px",color:"#6B7280",marginTop:"2px"},children:n})]})}function S({label:n,active:i,onClick:o,color:l}){return e.jsx("button",{onClick:o,style:{padding:"4px 12px",borderRadius:"16px",fontSize:"12px",fontWeight:500,border:`1px solid ${i?l||"#2DD4A8":"#e5e7eb"}`,background:i?(l||"#2DD4A8")+"15":"#fff",color:i?l||"#1B3A4B":"#6B7280",cursor:"pointer"},children:n})}function k({doc:n,status:i,onClick:o}){const l=i.status==="complete"?"#059669":i.status==="partial"?"#d97706":"#dc2626",c=i.status==="complete"?"#ecfdf5":i.status==="partial"?"#fffbeb":"#fef2f2",a=i.status==="complete"?"Complete":i.status==="partial"?"Partial":"Empty";return e.jsxs("div",{onClick:o,style:{background:"#fff",border:"1px solid #e5e7eb",borderRadius:"8px",padding:"16px",cursor:"pointer",transition:"border-color 0.15s, box-shadow 0.15s"},onMouseEnter:s=>{s.currentTarget.style.borderColor="#2DD4A8",s.currentTarget.style.boxShadow="0 2px 8px rgba(0,0,0,0.06)"},onMouseLeave:s=>{s.currentTarget.style.borderColor="#e5e7eb",s.currentTarget.style.boxShadow="none"},children:[e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:"8px"},children:[e.jsx("span",{style:{fontSize:"11px",fontWeight:600,color:"#6B7280",fontFamily:"monospace"},children:n.id.toUpperCase()}),e.jsx("span",{style:{fontSize:"10px",fontWeight:600,padding:"2px 6px",borderRadius:"4px",background:c,color:l},children:a})]}),e.jsx("div",{style:{fontSize:"14px",fontWeight:600,color:"#1B3A4B",marginBottom:"6px"},children:n.title}),e.jsx("div",{style:{fontSize:"11px",color:"#9CA3AF",marginBottom:"8px"},children:n.standards[0]}),e.jsxs("div",{style:{display:"flex",gap:"16px",fontSize:"12px",color:"#6B7280"},children:[e.jsxs("span",{children:[i.elementCount," elements"]}),i.gapCount>0&&e.jsxs("span",{style:{color:"#dc2626"},children:[i.gapCount," gaps"]})]})]})}function w({doc:n,status:i,model:o,validation:l,onBack:c}){const a=Object.values(o.elements).filter(r=>n.relevantKinds.includes(r.kind)),s=new Map;for(const r of a)s.has(r.kind)||s.set(r.kind,[]),s.get(r.kind).push(r);return e.jsxs("div",{children:[e.jsxs("div",{style:{marginBottom:"20px"},children:[e.jsx("button",{onClick:c,style:{background:"none",border:"none",color:"#2563eb",cursor:"pointer",fontSize:"13px",padding:0,marginBottom:"8px"},children:"← Back to dashboard"}),e.jsx("h3",{style:{fontSize:"18px",fontWeight:700,color:"#1B3A4B",margin:0},children:n.title}),e.jsxs("p",{style:{color:"#6B7280",fontSize:"12px",marginTop:"4px"},children:[n.id.toUpperCase()," | ",n.standards.join(", ")]})]}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(120px, 1fr))",gap:"12px",marginBottom:"20px"},children:[e.jsx(u,{label:"Elements",value:i.elementCount,color:"#2563eb"}),e.jsx(u,{label:"Gaps",value:i.gapCount,color:i.gapCount>0?"#dc2626":"#059669"}),e.jsx(u,{label:"Status",value:i.status,color:i.status==="complete"?"#059669":i.status==="partial"?"#d97706":"#dc2626"})]}),Array.from(s.entries()).sort().map(([r,x])=>e.jsxs("div",{style:{marginBottom:"16px"},children:[e.jsxs("h4",{style:{fontSize:"13px",fontWeight:600,color:"#374151",marginBottom:"8px"},children:[r," (",x.length,")"]}),e.jsxs("div",{style:{background:"#fff",border:"1px solid #e5e7eb",borderRadius:"6px",overflow:"hidden"},children:[e.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:"12px"},children:[e.jsx("thead",{children:e.jsxs("tr",{style:{background:"#f3f4f6"},children:[e.jsx("th",{style:{padding:"6px 10px",textAlign:"left",fontWeight:600,color:"#374151"},children:"Name"}),e.jsx("th",{style:{padding:"6px 10px",textAlign:"left",fontWeight:600,color:"#374151"},children:"Layer"}),e.jsx("th",{style:{padding:"6px 10px",textAlign:"left",fontWeight:600,color:"#374151"},children:"Description"})]})}),e.jsx("tbody",{children:x.slice(0,50).map(g=>e.jsxs("tr",{style:{borderTop:"1px solid #e5e7eb"},children:[e.jsx("td",{style:{padding:"6px 10px",color:"#2563eb",fontWeight:500},children:g.name}),e.jsx("td",{style:{padding:"6px 10px",color:"#6B7280"},children:g.layer}),e.jsx("td",{style:{padding:"6px 10px",color:"#6B7280",maxWidth:"300px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:g.doc||"—"})]},g.id))})]}),x.length>50&&e.jsxs("div",{style:{padding:"8px 10px",fontSize:"11px",color:"#9CA3AF",background:"#f9fafb"},children:["...and ",x.length-50," more"]})]})]},r)),i.violations.length>0&&e.jsxs("div",{style:{marginBottom:"16px"},children:[e.jsxs("h4",{style:{fontSize:"13px",fontWeight:600,color:"#dc2626",marginBottom:"8px"},children:["Validation Issues (",i.violations.length,")"]}),e.jsx("div",{style:{background:"#fff",border:"1px solid #e5e7eb",borderRadius:"6px",overflow:"hidden"},children:e.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:"12px"},children:[e.jsx("thead",{children:e.jsxs("tr",{style:{background:"#f3f4f6"},children:[e.jsx("th",{style:{padding:"6px 10px",textAlign:"left",fontWeight:600},children:"Severity"}),e.jsx("th",{style:{padding:"6px 10px",textAlign:"left",fontWeight:600},children:"Rule"}),e.jsx("th",{style:{padding:"6px 10px",textAlign:"left",fontWeight:600},children:"Element"}),e.jsx("th",{style:{padding:"6px 10px",textAlign:"left",fontWeight:600},children:"Description"})]})}),e.jsx("tbody",{children:i.violations.slice(0,50).map((r,x)=>e.jsxs("tr",{style:{borderTop:"1px solid #e5e7eb"},children:[e.jsx("td",{style:{padding:"6px 10px"},children:e.jsx("span",{style:{fontSize:"10px",fontWeight:600,padding:"1px 6px",borderRadius:"3px",background:r.severity==="error"?"#fef2f2":"#fffbeb",color:r.severity==="error"?"#dc2626":"#d97706"},children:r.severity})}),e.jsx("td",{style:{padding:"6px 10px",color:"#6B7280",fontFamily:"monospace",fontSize:"11px"},children:r.ruleId}),e.jsx("td",{style:{padding:"6px 10px",color:"#2563eb"},children:r.elementName}),e.jsx("td",{style:{padding:"6px 10px",color:"#6B7280"},children:r.description})]},x))})]})})]}),a.length===0&&e.jsxs("div",{style:{padding:"40px",textAlign:"center",color:"#9CA3AF",background:"#fff",border:"1px solid #e5e7eb",borderRadius:"8px"},children:[e.jsx("p",{style:{fontSize:"14px",marginBottom:"4px"},children:"No model elements found for this document type."}),e.jsxs("p",{style:{fontSize:"12px"},children:["Add elements of kinds: ",n.relevantKinds.join(", ")]})]})]})}export{z as DhfDashboard};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./reactflow-
|
|
1
|
+
import{j as e}from"./reactflow-CX-HDacK.js";import{a as d}from"./zustand-qbFpP9Up.js";import{u as p}from"./index-CRFOCEAK.js";const y=[{value:"",label:"— Select phase —"},{value:"concept",label:"Concept"},{value:"design",label:"Design & Development"},{value:"verification",label:"Verification & Validation"},{value:"production",label:"Production"}],i={width:"100%",padding:"7px 10px",border:"1px solid #D1D5DB",borderRadius:"6px",fontSize:"13px",color:"#1B3A4B",background:"#fff",boxSizing:"border-box",outline:"none",fontFamily:"inherit"},n={fontSize:"11px",fontWeight:600,color:"#6B7280",textTransform:"uppercase",letterSpacing:"0.04em",display:"block",marginBottom:"4px"},s={fontSize:"12px",fontWeight:700,color:"#1B3A4B",paddingBottom:"6px",borderBottom:"1px solid #E5E7EB",marginBottom:"12px",marginTop:"4px"},j={display:"grid",gridTemplateColumns:"1fr 1fr",gap:"12px"};function C({onClose:a}){const c=p(o=>o.dhfSettings),x=p(o=>o.updateDhfSettings),[l,g]=d.useState({...c}),[r,h]=d.useState("identity");function t(o,m){g(f=>({...f,[o]:m}))}function u(){x(l),a()}return e.jsx("div",{style:{position:"fixed",inset:0,zIndex:9999,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.45)"},onClick:o=>{o.target===o.currentTarget&&a()},children:e.jsxs("div",{style:{background:"#fff",borderRadius:"12px",width:"560px",maxHeight:"86vh",display:"flex",flexDirection:"column",boxShadow:"0 24px 60px rgba(0,0,0,0.22)",overflow:"hidden"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"10px",padding:"16px 20px",borderBottom:"1px solid #E5E7EB",flexShrink:0},children:[e.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"#6B7280",strokeWidth:"2",children:[e.jsx("circle",{cx:"12",cy:"12",r:"3"}),e.jsx("path",{d:"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"})]}),e.jsx("span",{style:{fontSize:"15px",fontWeight:700,color:"#1B3A4B",flex:1},children:"DHF Global Settings"}),e.jsx("button",{onClick:a,style:{background:"none",border:"none",cursor:"pointer",color:"#9CA3AF",fontSize:"20px",lineHeight:1,padding:"0 2px"},children:"×"})]}),e.jsx("div",{style:{display:"flex",borderBottom:"1px solid #E5E7EB",flexShrink:0,padding:"0 20px"},children:["identity","branding","layout"].map(o=>e.jsx("button",{onClick:()=>h(o),style:{padding:"10px 14px",border:"none",background:"none",fontSize:"12px",fontWeight:600,cursor:"pointer",color:r===o?"#1B3A4B":"#9CA3AF",borderBottom:`2px solid ${r===o?"#2DD4A8":"transparent"}`,marginBottom:"-1px",textTransform:"capitalize"},children:o==="identity"?"Project":o==="branding"?"Branding":"Layout"},o))}),e.jsxs("div",{style:{flex:1,overflowY:"auto",padding:"20px"},children:[r==="identity"&&e.jsxs("div",{children:[e.jsx("p",{style:s,children:"Project Identity"}),e.jsxs("p",{style:{fontSize:"12px",color:"#6B7280",marginBottom:"16px",lineHeight:"1.5"},children:["These values resolve ",e.jsx("code",{style:{background:"#F3F4F6",padding:"1px 4px",borderRadius:"3px"},children:"{{project.*}}"})," directives in all templates and the AI drafting context."]}),e.jsxs("div",{style:j,children:[e.jsxs("div",{children:[e.jsx("label",{style:n,children:"Company / Manufacturer"}),e.jsx("input",{style:i,value:l.company,onChange:o=>t("company",o.target.value),placeholder:"Acme Medical Devices Inc."})]}),e.jsxs("div",{children:[e.jsx("label",{style:n,children:"Product / Device Name"}),e.jsx("input",{style:i,value:l.product,onChange:o=>t("product",o.target.value),placeholder:"InfuSafe IV Pump"})]}),e.jsxs("div",{children:[e.jsx("label",{style:n,children:"Device Type"}),e.jsx("input",{style:i,value:l.deviceType,onChange:o=>t("deviceType",o.target.value),placeholder:"Class II active implantable"})]}),e.jsxs("div",{children:[e.jsx("label",{style:n,children:"Document Version"}),e.jsx("input",{style:i,value:l.version,onChange:o=>t("version",o.target.value),placeholder:"1.0.0"})]}),e.jsxs("div",{style:{gridColumn:"1 / -1"},children:[e.jsx("label",{style:n,children:"Development Phase"}),e.jsx("select",{style:i,value:l.phase,onChange:o=>t("phase",o.target.value),children:y.map(o=>e.jsx("option",{value:o.value,children:o.label},o.value))})]}),e.jsxs("div",{style:{gridColumn:"1 / -1"},children:[e.jsx("label",{style:n,children:"Document ID Prefix"}),e.jsx("input",{style:{...i,fontFamily:"monospace"},value:l.documentNumberingPrefix,onChange:o=>t("documentNumberingPrefix",o.target.value),placeholder:"DOC"}),e.jsxs("p",{style:{fontSize:"11px",color:"#9CA3AF",marginTop:"4px"},children:["Used in document IDs, e.g. ",e.jsxs("code",{children:[l.documentNumberingPrefix||"DOC","-RMP-001"]})]})]})]})]}),r==="branding"&&e.jsxs("div",{children:[e.jsx("p",{style:s,children:"Branding"}),e.jsx("p",{style:{fontSize:"12px",color:"#6B7280",marginBottom:"16px",lineHeight:"1.5"},children:"Branding applied to exported HTML and DOCX documents. Per-document overrides can be set in the document's frontmatter."}),e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"14px"},children:[e.jsxs("div",{children:[e.jsx("label",{style:n,children:"Full Logo URL"}),e.jsx("input",{style:i,value:l.logoUrl,onChange:o=>t("logoUrl",o.target.value),placeholder:"https://... or data:image/png;base64,..."}),e.jsx("p",{style:{fontSize:"11px",color:"#9CA3AF",marginTop:"4px"},children:"Shown in document cover pages and report headers."}),l.logoUrl&&e.jsx("img",{src:l.logoUrl,alt:"Logo preview",style:{maxHeight:"48px",maxWidth:"200px",marginTop:"8px",border:"1px solid #E5E7EB",borderRadius:"4px",padding:"4px"}})]}),e.jsxs("div",{children:[e.jsx("label",{style:n,children:"Compact Logo URL"}),e.jsx("input",{style:i,value:l.compactLogoUrl,onChange:o=>t("compactLogoUrl",o.target.value),placeholder:"https://... or data:image/png;base64,..."}),e.jsx("p",{style:{fontSize:"11px",color:"#9CA3AF",marginTop:"4px"},children:"Shown in page headers (small). Falls back to Full Logo if empty."}),l.compactLogoUrl&&e.jsx("img",{src:l.compactLogoUrl,alt:"Compact logo preview",style:{maxHeight:"28px",maxWidth:"120px",marginTop:"8px",border:"1px solid #E5E7EB",borderRadius:"4px",padding:"4px"}})]}),e.jsxs("div",{children:[e.jsx("label",{style:n,children:"Primary Color"}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"10px"},children:[e.jsx("input",{type:"color",value:l.primaryColor,onChange:o=>t("primaryColor",o.target.value),style:{width:"40px",height:"32px",padding:"2px",border:"1px solid #D1D5DB",borderRadius:"6px",cursor:"pointer"}}),e.jsx("input",{style:{...i,flex:1,fontFamily:"monospace"},value:l.primaryColor,onChange:o=>t("primaryColor",o.target.value),placeholder:"#1B3A4B"})]}),e.jsx("p",{style:{fontSize:"11px",color:"#9CA3AF",marginTop:"4px"},children:"Used for headings, table headers, and badges in exported documents."})]})]})]}),r==="layout"&&e.jsxs("div",{children:[e.jsx("p",{style:s,children:"Document Layout"}),e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"16px"},children:[e.jsxs("div",{children:[e.jsxs("label",{style:{...n,display:"flex",alignItems:"center",gap:"8px",textTransform:"none",fontSize:"13px",fontWeight:600,color:"#1B3A4B",marginBottom:0},children:[e.jsx("input",{type:"checkbox",checked:l.compactMode,onChange:o=>t("compactMode",o.target.checked),style:{accentColor:"#2DD4A8"}}),"Compact mode"]}),e.jsx("p",{style:{fontSize:"12px",color:"#6B7280",marginTop:"4px",marginLeft:"20px"},children:"Tighter line spacing and smaller heading sizes. Useful for regulatory submissions."})]}),e.jsxs("div",{children:[e.jsx("label",{style:n,children:"Page Header Template"}),e.jsx("input",{style:{...i,fontFamily:"monospace",fontSize:"12px"},value:l.headerTemplate,onChange:o=>t("headerTemplate",o.target.value)}),e.jsxs("p",{style:{fontSize:"11px",color:"#9CA3AF",marginTop:"4px"},children:["Tokens: ",e.jsx("code",{children:"{{id}}"}),", ",e.jsx("code",{children:"{{title}}"}),", ",e.jsx("code",{children:"{{project.product}}"}),", ",e.jsx("code",{children:"{{project.version}}"}),", ",e.jsx("code",{children:"{{date}}"})]})]}),e.jsxs("div",{children:[e.jsx("label",{style:n,children:"Page Footer Template"}),e.jsx("input",{style:{...i,fontFamily:"monospace",fontSize:"12px"},value:l.footerTemplate,onChange:o=>t("footerTemplate",o.target.value)}),e.jsxs("p",{style:{fontSize:"11px",color:"#9CA3AF",marginTop:"4px"},children:["Tokens: same as header, plus ",e.jsx("code",{children:"{{page}}"})," and ",e.jsx("code",{children:"{{pages}}"})]})]})]})]})]}),e.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:"8px",padding:"14px 20px",borderTop:"1px solid #E5E7EB",flexShrink:0,background:"#FAFAFA"},children:[e.jsx("button",{onClick:a,style:{padding:"8px 16px",borderRadius:"6px",border:"1px solid #D1D5DB",background:"#fff",fontSize:"13px",cursor:"pointer",color:"#374151"},children:"Cancel"}),e.jsx("button",{onClick:u,style:{padding:"8px 20px",borderRadius:"6px",border:"none",background:"#2DD4A8",fontSize:"13px",fontWeight:600,cursor:"pointer",color:"#065F46"},children:"Save Settings"})]})]})})}export{C as DhfSettingsPanel};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/DhfSettingsPanel-
|
|
2
|
-
import{u as w,
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/DhfSettingsPanel-BYTUIoK4.js","assets/reactflow-CX-HDacK.js","assets/zustand-qbFpP9Up.js","assets/index-CRFOCEAK.js","assets/index-DPzXL4uF.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{u as w,j as te,_ as oe}from"./index-CRFOCEAK.js";import{j as e}from"./reactflow-CX-HDacK.js";import{a as x}from"./zustand-qbFpP9Up.js";const ne=/<div class="memo-doc-diagram" data-diagram-id="([^"]*)"><\/div>/;function m(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function H(t,r){const n=t.split(`
|
|
3
3
|
`).map(o=>o.trim()).filter(Boolean);return n.length===0?`<tr><td colspan="4" style="color:#9CA3AF;font-style:italic">No ${r.toLowerCase()}s defined</td></tr>`:n.map(o=>{const[i="",d=""]=o.split("|").map(a=>a.trim());return`<tr><td>${m(i)}</td><td>${m(d||r)}</td><td style="color:#9CA3AF">—</td><td style="color:#9CA3AF">—</td></tr>`}).join("")}function re(t){const r=t.authors.trim().length>0,n=t.approvers.trim().length>0,o="<thead><tr><th>Name</th><th>Role</th><th>Signature</th><th>Date</th></tr></thead>";return`
|
|
4
4
|
<h2>Authors</h2>
|
|
5
5
|
<table>${o}<tbody>${H(t.authors,"Author")}</tbody></table>
|
|
@@ -60,7 +60,7 @@ ${o.word?'<meta name="ProgId" content="Word.Document"><!--[if gte mso 9]><xml><w
|
|
|
60
60
|
<style>${K(n)}${ae}${o.word?ce:""}</style>
|
|
61
61
|
</head>
|
|
62
62
|
<body>${d}</body>
|
|
63
|
-
</html>`}function N(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function _(t,r,n){const o=new Blob([r],{type:n}),i=URL.createObjectURL(o),d=document.createElement("a");d.href=i,d.download=t,d.click(),URL.revokeObjectURL(i)}function me(t,r,n){_(`${t.id}.html`,T(t,r,n),"text/html;charset=utf-8")}function xe(t,r,n){_(`${t.id}.doc`,T(t,r,n,{word:!0}),"application/msword")}function he(t){_(`${t.id}.md`,t.content,"text/markdown;charset=utf-8")}function fe(t,r,n){const o=window.open("","_blank");o&&(o.document.write(T(t,r,n)),o.document.close(),o.setTimeout(()=>{o.focus(),o.print()},150))}const U=x.lazy(()=>oe(()=>import("./DhfSettingsPanel-
|
|
63
|
+
</html>`}function N(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function _(t,r,n){const o=new Blob([r],{type:n}),i=URL.createObjectURL(o),d=document.createElement("a");d.href=i,d.download=t,d.click(),URL.revokeObjectURL(i)}function me(t,r,n){_(`${t.id}.html`,T(t,r,n),"text/html;charset=utf-8")}function xe(t,r,n){_(`${t.id}.doc`,T(t,r,n,{word:!0}),"application/msword")}function he(t){_(`${t.id}.md`,t.content,"text/markdown;charset=utf-8")}function fe(t,r,n){const o=window.open("","_blank");o&&(o.document.write(T(t,r,n)),o.document.close(),o.setTimeout(()=>{o.focus(),o.print()},150))}const U=x.lazy(()=>oe(()=>import("./DhfSettingsPanel-BYTUIoK4.js"),__vite__mapDeps([0,1,2,3,4])).then(t=>({default:t.DhfSettingsPanel}))),V=[{id:"q-hazards",label:"Hazard Table",description:"All hazards in the risk layer",category:"query",code:'```memo-query\nkind: Hazard\ndisplay: table\ncolumns: name, layer, doc\nsort: name\nempty: "No hazards defined."\n```'},{id:"q-hazardous-situations",label:"Hazardous Situations",description:"All hazardous situations",category:"query",code:"```memo-query\nkind: HazardousSituation\ndisplay: table\ncolumns: name, layer, doc\nsort: name\n```"},{id:"q-risk-controls",label:"Risk Controls",description:"All risk control measures",category:"query",code:"```memo-query\nkind: RiskControlMeasure\ndisplay: table\ncolumns: name, layer, doc\nsort: name\n```"},{id:"q-requirements",label:"Requirements",description:"All system requirements",category:"query",code:"```memo-query\nkind: Requirement\ndisplay: table\ncolumns: name, layer, doc\nsort: name\n```"},{id:"q-soup",label:"SOUP List",description:"All SOUP components",category:"query",code:"```memo-query\nkind: SOUPComponent\ndisplay: table\ncolumns: name, layer, doc\n```"},{id:"q-sw-items",label:"Software Items",description:"All software items",category:"query",code:"```memo-query\nkind: SoftwareItem\ndisplay: table\ncolumns: name, layer, doc\n```"},{id:"q-test-cases",label:"Test Cases",description:"All test cases",category:"query",code:"```memo-query\nkind: TestCase\ndisplay: table\ncolumns: name, layer, doc\n```"},{id:"q-hazard-count",label:"Hazard Count (metric)",description:"Metric badge with hazard count",category:"query",code:"```memo-query\nkind: Hazard\ndisplay: count\nlabel: Total hazards\n```"},{id:"s-unmitigated",label:"Unmitigated Hazards",description:"Hazards without risk controls",category:"script",code:"```memo-script\nconst hazards = query({ kind: 'Hazard' });\nconst unmitigated = hazards.filter(h => h.mitigatedBy?.length === 0);\nif (unmitigated.length === 0) return 'All hazards have associated risk controls.';\nreturn table(unmitigated, ['name', 'layer', 'doc']);\n```"},{id:"s-coverage",label:"Requirements Coverage",description:"Requirements with/without test cases",category:"script",code:"```memo-script\nconst reqs = query({ kind: 'Requirement' });\nconst covered = reqs.filter(r => r.verifiedBy?.length > 0);\nreturn count(covered, `covered of ${reqs.length} requirements`);\n```"},{id:"i-doc-header",label:"Document Control Header",description:"Standard doc control table",category:"include",code:"{{include:shared/snippets/document-control-header.md}}"},{id:"i-approval",label:"Approval Block",description:"Reviewer/approver signature table",category:"include",code:"{{include:shared/snippets/approval-block.md}}"},{id:"i-revision",label:"Revision History",description:"Revision history table",category:"include",code:"{{include:shared/snippets/revision-history-table.md}}"},{id:"i-references",label:"References Section",description:"Normative references block",category:"include",code:"{{include:shared/snippets/references-section.md}}"},{id:"d-toc",label:"Table of Contents",description:"Auto-generated TOC (on export)",category:"directive",code:"{{toc}}"},{id:"d-glossary",label:"Glossary",description:"Auto-generated glossary (on export)",category:"directive",code:"{{glossary}}"}],J={query:"#2563eb",script:"#7c3aed",include:"#0891b2",directive:"#6B7280"},Q={query:"Query",script:"Script",include:"Snippet",directive:"Directive"};function Ae(){const t=w(s=>s.model),r=w(s=>s.activeView),n=w(s=>s.dhfDocuments),o=w(s=>s.updateDhfDocumentContent),i=w(s=>s.updateDhfDocumentMeta),d=w(s=>s.llmAvailable),a=w(s=>s.registerLlmRequest),l=w(s=>s.dhfSettings),[p,h]=x.useState("split"),c=x.useRef(null),[S,u]=x.useState(!1),[k,g]=x.useState(null),[f,b]=x.useState(!1),[y,$]=x.useState(!1),[C,v]=x.useState(!1),[E,R]=x.useState("all"),X=x.useCallback(async(s,A)=>{u(!0),g(null);const z=`draft-${Date.now()}-${Math.random().toString(36).slice(2)}`,q=A.split("/").pop()??A;try{const B=await new Promise((W,D)=>{a(z,W,D),te(z,q),setTimeout(()=>D(new Error("Request timed out after 120 seconds.")),12e4)});o(s,B.markdown)}catch(B){g((B==null?void 0:B.message)??"Unknown error")}finally{u(!1)}},[a,o]),Z=x.useCallback(s=>{if(!c.current)return;const A=c.current,z=A.selectionStart,q=A.selectionEnd,B=`
|
|
64
64
|
|
|
65
65
|
${s.code}
|
|
66
66
|
|