@memoarchitect/architect 0.6.5 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -4
- package/dist/assets/AiWorkspace-Bu9TlIWg.js +7 -0
- package/dist/assets/AnalysisWorkspace-CodmoI-v.js +39 -0
- package/dist/assets/{ComplianceWizard-DWolzleI.js → ComplianceWizard-CTihkUi-.js} +1 -1
- package/dist/assets/DSMView-BiC845df.js +1 -0
- package/dist/assets/Dashboard-CgnNLhKq.js +1 -0
- package/dist/assets/{DhfDashboard-D9JxRAbD.js → DhfDashboard-w-dJoJHU.js} +1 -1
- package/dist/assets/{DhfWorkbench-BQv2WQ9o.js → DhfWorkbench-o6B_MT-0.js} +15 -15
- package/dist/assets/DiagramCanvas-CqGqDbgT.js +3 -0
- package/dist/assets/DiagramEditor-UJDHcAUF.js +4 -0
- package/dist/assets/DiagramToolbarControls-B2gZFJlg.js +1 -0
- package/dist/assets/ElementDetailView-10U0rr33.js +2 -0
- package/dist/assets/ExplorerTreeRow-DqhF_qoO.js +3 -0
- package/dist/assets/{ImportView-33dFwj6A.js → ImportView-D8svP04Q.js} +1 -1
- package/dist/assets/{LayerGrid-B3MBWswK.js → LayerGrid-DEe0Ryz-.js} +1 -1
- package/dist/assets/{LayerTable-DyIzIt5M.js → LayerTable-CN_b2rDr.js} +2 -2
- package/dist/assets/{MaxGraphCanvas-BS5wYazZ.js → MaxGraphCanvas-bo8oPBct.js} +6 -6
- package/dist/assets/{ModelDiff-BoFREnpg.js → ModelDiff-xe95oVua.js} +1 -1
- package/dist/assets/{OntologyDecompositionDiagram-IG1gj1c3.js → OntologyDecompositionDiagram-BL9R8bdB.js} +1 -1
- package/dist/assets/{OntologyViewer-CQTEg-GI.js → OntologyViewer-CtqNkkCn.js} +2 -2
- package/dist/assets/{RelationshipOverlay-B9bqt4zl.js → RelationshipOverlay-DL0N8Vmk.js} +1 -1
- package/dist/assets/{RelationshipsSection-DttMvF2i.js → RelationshipsSection-BoJ0aUXe.js} +1 -1
- package/dist/assets/{ReviewDashboard-BJ_smBGS.js → ReviewDashboard-DeTge2oC.js} +1 -1
- package/dist/assets/ScenarioEditor-FAEYTHgP.js +3 -0
- package/dist/assets/{StatisticsDashboard-CBYJGUPH.js → StatisticsDashboard-BAZRqIPN.js} +1 -1
- package/dist/assets/{SysmlCodeEditor-Die2RUsz.js → SysmlCodeEditor-BBfup_Ni.js} +1 -1
- package/dist/assets/TabularView-I4LjHhoH.js +1 -0
- package/dist/assets/TraceabilityMatrix-DbrvjqLN.js +3 -0
- package/dist/assets/UiScreensWorkspace-DDD_PyJs.js +1 -0
- package/dist/assets/{WorkflowWizard-CbkDyd1W.js → WorkflowWizard-VwpEHt3R.js} +1 -1
- package/dist/assets/element-options-B7AgTB8R.js +3 -0
- package/dist/assets/html2canvas.esm-QH1iLAAe.js +22 -0
- package/dist/assets/index-BWMNo4wW.css +1 -0
- package/dist/assets/index-Bij8Q4Kg.js +45 -0
- package/dist/assets/index.es-ClbJxlAQ.js +18 -0
- package/dist/assets/jspdf.es.min-DZ68BGxk.js +170 -0
- package/dist/assets/notation-scene-DT8LpWVK.js +1 -0
- package/dist/assets/purify.es-DP5U8-sc.js +3 -0
- package/dist/assets/{reactflow-CsCqNKB-.js → reactflow-s7jmJtXx.js} +5 -5
- package/dist/index.html +3 -3
- package/lib/__tests__/compiler-bundling.test.d.ts +2 -0
- package/lib/__tests__/compiler-bundling.test.d.ts.map +1 -0
- package/lib/__tests__/compiler-bundling.test.js +32 -0
- package/lib/__tests__/compiler-bundling.test.js.map +1 -0
- package/lib/__tests__/standard-sysml-diagrams-smoke.test.d.ts +2 -0
- package/lib/__tests__/standard-sysml-diagrams-smoke.test.d.ts.map +1 -0
- package/lib/__tests__/standard-sysml-diagrams-smoke.test.js +22 -0
- package/lib/__tests__/standard-sysml-diagrams-smoke.test.js.map +1 -0
- package/lib/__tests__/supervised-child-args.test.d.ts +2 -0
- package/lib/__tests__/supervised-child-args.test.d.ts.map +1 -0
- package/lib/__tests__/supervised-child-args.test.js +35 -0
- package/lib/__tests__/supervised-child-args.test.js.map +1 -0
- package/lib/bin/memo-architect.js +30 -4
- package/lib/bin/memo-architect.js.map +1 -1
- package/lib/commands/dev.d.ts +18 -2
- package/lib/commands/dev.d.ts.map +1 -1
- package/lib/commands/dev.js +56 -8
- package/lib/commands/dev.js.map +1 -1
- package/lib/commands/example.d.ts +1 -0
- package/lib/commands/example.d.ts.map +1 -1
- package/lib/commands/example.js +2 -0
- package/lib/commands/example.js.map +1 -1
- package/lib/feature-grants.d.ts.map +1 -1
- package/lib/feature-grants.js +2 -2
- package/lib/feature-grants.js.map +1 -1
- package/package.json +12 -6
- package/dist/assets/AiWorkspace-DHZ6a9HJ.js +0 -3
- package/dist/assets/DSMView-TdC3EADB.js +0 -1
- package/dist/assets/Dashboard-DBfAOCJv.js +0 -1
- package/dist/assets/DhfSettingsPanel-Firov0IF.js +0 -1
- package/dist/assets/DiagramCanvas-BfwO8YE5.js +0 -1
- package/dist/assets/DiagramEditor-Cp9ORYoN.js +0 -4
- package/dist/assets/ElementDetailView-DOrG8v7V.js +0 -2
- package/dist/assets/ScenarioEditor-D06nbX4h.js +0 -3
- package/dist/assets/TabularView-BLzDtgmK.js +0 -1
- package/dist/assets/TraceabilityMatrix-DbL_FkAC.js +0 -1
- package/dist/assets/index-B8HDzVLs.css +0 -1
- package/dist/assets/index-D0vtjNjX.js +0 -3280
- package/dist/assets/layout-selection-DIQaaOIC.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.7.2</code> · MIT · SysML v2 ·
|
|
13
13
|
ISO 14971 · IEC 62304 · ISO/IEC/IEEE 42010
|
|
14
14
|
</p>
|
|
15
15
|
|
|
@@ -61,13 +61,31 @@ interaction; it does not maintain a second engineering model.
|
|
|
61
61
|
- Review requirements, risk, software, verification, and assurance traceability.
|
|
62
62
|
- Render BDD, IBD, action-flow, sequence, state, tree, DSM, and tabular views.
|
|
63
63
|
- Author and export Design History File documents from the versioned model.
|
|
64
|
+
- Open a live JupyterLab workspace with model-independent Syside sample notebooks.
|
|
64
65
|
- Run the same validation and export operations through the CLI or the workbench.
|
|
65
66
|
|
|
67
|
+
### Jupyter analysis
|
|
68
|
+
|
|
69
|
+
Projects created with `memo init` include seven notebooks under
|
|
70
|
+
`analysis/Samples/`: overview and quality reports, architecture hotspots,
|
|
71
|
+
change-impact exploration, charts, an SVG ownership graph, and an inventory
|
|
72
|
+
table with CSV export. Start JupyterLab from the project and select
|
|
73
|
+
**Analysis → Jupyter Notebooks** in Architect:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
source analysis/.venv/bin/activate
|
|
77
|
+
cd analysis
|
|
78
|
+
jupyter lab --port 8888
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The notebooks use the licensed Syside Python API and automatically locate the
|
|
82
|
+
project's nearest `model/` or `src/` tree.
|
|
83
|
+
|
|
66
84
|
## Try it on a bundled example
|
|
67
85
|
|
|
68
86
|
The examples ship inside the ontology package, `@memoarchitect/ontology`, so
|
|
69
87
|
they are already present once Architect is installed — there is nothing to
|
|
70
|
-
clone or download.
|
|
88
|
+
clone or download. In an installed environment, open one with:
|
|
71
89
|
|
|
72
90
|
```bash
|
|
73
91
|
memo-architect --example gpca
|
|
@@ -77,6 +95,26 @@ memo-architect --example gpca
|
|
|
77
95
|
memo-architect --example standard-sysml-diagrams
|
|
78
96
|
```
|
|
79
97
|
|
|
98
|
+
From an Architect development checkout, use the package script, which runs the
|
|
99
|
+
locally built CLI:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pnpm architect examples
|
|
103
|
+
pnpm architect --example standard-sysml-diagrams --keep-alive
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`pnpm architect examples` prints every bundled example ID available in the
|
|
107
|
+
resolved ontology package. `--keep-alive` keeps the development server running
|
|
108
|
+
if the browser temporarily disconnects, such as when a tab is backgrounded or
|
|
109
|
+
the computer sleeps. Without it, the server waits 10 seconds for a client to
|
|
110
|
+
reconnect before shutting down. From the `memo-meta` workspace root, run the
|
|
111
|
+
same commands through the Architect package:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
pnpm --filter @memoarchitect/architect architect examples
|
|
115
|
+
pnpm --filter @memoarchitect/architect architect --example standard-sysml-diagrams --keep-alive
|
|
116
|
+
```
|
|
117
|
+
|
|
80
118
|
| Example | What it contains |
|
|
81
119
|
|---|---|
|
|
82
120
|
| `gpca` | GPCA infusion-pump reference model — the full worked device |
|
|
@@ -128,10 +166,12 @@ For coordinated changes across Ontology, Tools, and Architect, use the private
|
|
|
128
166
|
`memo-meta` workspace. It checks out all three repositories as sibling
|
|
129
167
|
submodules and links their matching npm package versions locally.
|
|
130
168
|
|
|
131
|
-
|
|
169
|
+
List the available bundled examples, then run one in the local development
|
|
170
|
+
server:
|
|
132
171
|
|
|
133
172
|
```bash
|
|
134
|
-
pnpm
|
|
173
|
+
pnpm architect examples
|
|
174
|
+
pnpm architect --example gpca --keep-alive
|
|
135
175
|
# http://localhost:3000
|
|
136
176
|
```
|
|
137
177
|
|
|
@@ -156,6 +196,7 @@ To open a bundled example, see [Try it on a bundled example](#try-it-on-a-bundle
|
|
|
156
196
|
- [Published documentation](https://memoarchitect.com/memo-architect/)
|
|
157
197
|
- [Product website](https://memoarchitect.com/memo-architect.html)
|
|
158
198
|
- [Start here in the documentation source](docs/src/index.md)
|
|
199
|
+
- [Feature tour](docs/src/users/features.md)
|
|
159
200
|
- [Layers and their questions](docs/src/users/layers.md)
|
|
160
201
|
- [Choosing elements](docs/src/users/elements.md)
|
|
161
202
|
- [Connecting elements](docs/src/users/relationships.md)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{j as e}from"./reactflow-s7jmJtXx.js";import{u as v,q as L,t as _,v as G,w as U}from"./index-Bij8Q4Kg.js";import{a}from"./zustand-CrhqMOHB.js";const V={env:"an environment variable","env-file":"the project .env file","project-settings":"project settings","user-credentials":"your saved credentials",default:"the default"},Y={anthropic:"claude-opus-5",openai:"gpt-4o"};function Q({onClose:t}){const r=v(n=>n.llmSettings),f=v(n=>n.registerLlmRequest),[s,p]=a.useState((r==null?void 0:r.provider)??"anthropic"),[u,d]=a.useState((r==null?void 0:r.model)??""),[x,l]=a.useState(""),[y,S]=a.useState(!1),[b,j]=a.useState(null),k=a.useCallback(async()=>{S(!0),j(null);const n=`llmset-${Date.now()}-${Math.random().toString(36).slice(2)}`;try{await new Promise((c,m)=>{f(n,c,m),L(n,{provider:s,model:u.trim()||void 0,...x?{apiKey:x}:{}}),setTimeout(()=>m(new Error("The save timed out.")),2e4)}),l(""),j("Saved.")}catch(c){j((c==null?void 0:c.message)??"The settings could not be saved.")}finally{S(!1)}},[s,u,x,f]),C=a.useCallback(async()=>{S(!0),j(null);const n=`llmclear-${Date.now()}-${Math.random().toString(36).slice(2)}`;try{await new Promise((c,m)=>{f(n,c,m),L(n,{provider:s,apiKey:""}),setTimeout(()=>m(new Error("The request timed out.")),2e4)}),j("Key removed.")}catch(c){j((c==null?void 0:c.message)??"The key could not be removed.")}finally{S(!1)}},[s,f]),w={fontSize:"11px",fontWeight:600,color:"#374151",display:"block",marginBottom:"4px"},E={width:"100%",padding:"6px 10px",border:"1px solid #E5E5E0",borderRadius:"6px",fontSize:"12px",outline:"none",background:"#fff",color:"#1B3A4B",fontFamily:"inherit"};return e.jsxs("div",{style:{padding:"14px 20px",background:"#fff",borderBottom:"1px solid #E5E5E0",display:"flex",flexDirection:"column",gap:"12px",flexShrink:0},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center"},children:[e.jsx("div",{style:{flex:1,fontSize:"12px",fontWeight:700,color:"#1B3A4B"},children:"LLM settings"}),e.jsx("button",{onClick:t,style:{background:"none",border:"none",color:"#9CA3AF",fontSize:"14px",cursor:"pointer"},children:"✕"})]}),e.jsxs("div",{style:{display:"flex",gap:"10px"},children:[e.jsxs("div",{style:{flex:"0 0 130px"},children:[e.jsx("label",{style:w,children:"Provider"}),e.jsxs("select",{value:s,onChange:n=>p(n.target.value),style:{...E,cursor:"pointer"},children:[e.jsx("option",{value:"anthropic",children:"Anthropic"}),e.jsx("option",{value:"openai",children:"OpenAI-compatible"})]})]}),e.jsxs("div",{style:{flex:1},children:[e.jsx("label",{style:w,children:"Model"}),e.jsx("input",{value:u,onChange:n=>d(n.target.value),placeholder:Y[s]??"",style:E})]})]}),e.jsxs("div",{children:[e.jsx("label",{style:w,children:"API key"}),r&&!r.keyEditable&&r.configured?e.jsxs("div",{style:{fontSize:"11px",color:"#6B7280",lineHeight:1.6},children:["A key is already supplied by ",V[r.keyOrigin??"default"],", which takes precedence over anything saved here. Remove it there to set a key from this screen."]}):e.jsxs(e.Fragment,{children:[e.jsx("input",{type:"password",value:x,onChange:n=>l(n.target.value),placeholder:r!=null&&r.configured?"Saved — type a new key to replace it":"sk-…",autoComplete:"off",style:E}),e.jsxs("div",{style:{fontSize:"10px",color:"#9CA3AF",marginTop:"4px",lineHeight:1.5},children:["Stored in ",e.jsx("code",{children:"~/.memo/credentials.json"})," with owner-only permissions — outside this project, so it is never committed. You can also set"," ",e.jsx("code",{children:"ANTHROPIC_API_KEY"})," in the environment or a project ",e.jsx("code",{children:".env"}),"."]})]})]}),e.jsxs("div",{style:{display:"flex",gap:"8px",alignItems:"center"},children:[e.jsx("button",{onClick:k,disabled:y,style:{padding:"6px 14px",borderRadius:"6px",border:"none",background:"#1B3A4B",color:"#fff",fontSize:"11px",fontWeight:600,cursor:y?"default":"pointer",opacity:y?.5:1},children:y?"Saving…":"Save"}),(r==null?void 0:r.configured)&&r.keyEditable&&e.jsx("button",{onClick:C,disabled:y,style:{padding:"6px 12px",borderRadius:"6px",border:"1px solid #E5E5E0",background:"transparent",color:"#dc2626",fontSize:"11px",cursor:"pointer"},children:"Remove saved key"}),b&&e.jsx("span",{style:{fontSize:"11px",color:"#6B7280"},children:b})]})]})}const X=["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."],J=12e4;function Z(){const t=v(o=>o.llmAvailable),r=v(o=>o.llmProvider),f=v(o=>o.llmModel),s=v(o=>o.model),p=v(o=>o.registerLlmRequest),[u,d]=a.useState([]),[x,l]=a.useState([]),[y,S]=a.useState(""),[b,j]=a.useState(!1),[k,C]=a.useState(!1),[w,E]=a.useState(!1),[n,c]=a.useState(!1),[m,B]=a.useState(new Set),[D,F]=a.useState(null),M=a.useRef(null),W=a.useRef(null);a.useEffect(()=>{var o;(o=M.current)==null||o.scrollIntoView({behavior:"smooth"})},[u,b]);const I=a.useCallback((o,h)=>new Promise((g,i)=>{p(o,g,i),h(),setTimeout(()=>i(new Error("The request timed out after 2 minutes.")),J)}),[p]),T=a.useCallback(async o=>{if(!o.trim()||b)return;const h=o.trim();S(""),d(i=>[...i,{role:"user",content:h}]),j(!0),F(null);const g=`chat-${Date.now()}-${Math.random().toString(36).slice(2)}`;try{const i=await I(g,()=>_(g,h,x,k));l(i.messages),d(A=>[...A,{role:"assistant",content:i.truncated?`${i.answer}
|
|
2
|
+
|
|
3
|
+
_(Stopped at the tool-call limit for one turn — ask again to continue.)_`:i.answer,changes:i.proposedChanges.length?i.proposedChanges:void 0}]),i.proposedChanges.length&&B(A=>{const z=new Set(A);for(const R of i.proposedChanges)z.add(R.id);return z})}catch(i){d(A=>[...A,{role:"assistant",content:(i==null?void 0:i.message)??"Unknown error",error:!0}])}finally{j(!1)}},[b,x,k,I]),P=o=>{o.key==="Enter"&&!o.shiftKey&&(o.preventDefault(),T(y))},q=o=>{B(h=>{const g=new Set(h);return g.has(o)?g.delete(o):g.add(o),g})},O=a.useCallback(async o=>{const h=o.filter(i=>m.has(i.id));if(h.length===0||n)return;c(!0),F(null);const g=`apply-${Date.now()}-${Math.random().toString(36).slice(2)}`;try{const i=await I(g,()=>G(g,h)),A=new Set(i.applied);d(z=>z.map(R=>R.changes?{...R,changes:R.changes.filter(N=>!A.has(N.id))}:R)),F(i.failed.length?`Applied ${i.applied.length}. Failed: ${i.failed.map(z=>z.error).join("; ")}`:`Applied ${i.applied.length} change${i.applied.length===1?"":"s"} to the model source.`)}catch(i){F((i==null?void 0:i.message)??"The changes could not be applied.")}finally{c(!1)}},[m,n,I]),K=o=>{const h=new Set(o.map(g=>g.id));d(g=>g.map(i=>i.changes?{...i,changes:i.changes.filter(A=>!h.has(A.id))}:i))},H=()=>{d([]),l([]),B(new Set),F(null)};return s?e.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%",background:"#F7F7F5",overflow:"hidden"},children:[e.jsxs("div",{style:{padding:"14px 20px 10px",borderBottom:"1px solid #E5E5E0",background:"#fff",flexShrink:0},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"10px"},children:[e.jsx("span",{style:{fontSize:"16px"},children:"✦"}),e.jsxs("div",{style:{flex:1},children:[e.jsx("div",{style:{fontSize:"14px",fontWeight:700,color:"#1B3A4B"},children:"Model Assistant"}),e.jsx("div",{style:{fontSize:"11px",color:t?"#059669":"#dc2626",marginTop:"1px"},children:t?`${r??"LLM"} · ${f??"unknown model"}`:"No API key configured"})]}),e.jsx("button",{onClick:()=>E(o=>!o),title:"LLM settings",style:{background:w?"#F3F4F6":"none",border:"1px solid #E5E5E0",borderRadius:"6px",padding:"4px 8px",fontSize:"12px",color:"#374151",cursor:"pointer"},children:"⚙ Settings"})]}),e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:"6px",marginTop:"8px",fontSize:"11px",color:"#6B7280",cursor:"pointer"},children:[e.jsx("input",{type:"checkbox",checked:k,onChange:o=>C(o.target.checked),style:{cursor:"pointer"}}),"Suggest edits — the assistant may propose model changes for your approval"]})]}),w&&e.jsx(Q,{onClose:()=>E(!1)}),e.jsxs("div",{style:{flex:1,overflowY:"auto",padding:"16px 20px",display:"flex",flexDirection:"column",gap:"12px"},children:[u.length===0&&e.jsxs("div",{style:{paddingTop:"8px"},children:[e.jsx("div",{style:{fontSize:"12px",color:"#9CA3AF",marginBottom:"12px"},children:"Ask about your model in plain English. The assistant can look up any element, follow traceability chains, and read validation gaps."}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"6px"},children:X.map(o=>e.jsx("button",{onClick:()=>T(o),disabled:!t||b,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:t?1:.5},onMouseEnter:h=>{t&&(h.currentTarget.style.borderColor="#2DD4A8")},onMouseLeave:h=>{h.currentTarget.style.borderColor="#E5E5E0"},children:o},o))})]}),u.map((o,h)=>e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"8px"},children:[e.jsxs("div",{style:{display:"flex",flexDirection:o.role==="user"?"row-reverse":"row",gap:"8px",alignItems:"flex-start"},children:[e.jsx("div",{style:{width:"24px",height:"24px",borderRadius:"50%",flexShrink:0,display:"flex",alignItems:"center",justifyContent:"center",background:o.role==="user"?"#1B3A4B":"#2DD4A815",fontSize:"10px",fontWeight:700,color:o.role==="user"?"#fff":"#2DD4A8",marginTop:"2px"},children:o.role==="user"?"U":"✦"}),e.jsx("div",{style:{maxWidth:"85%",padding:"10px 12px",borderRadius:"10px",background:o.role==="user"?"#1B3A4B":o.error?"#fef2f2":"#fff",color:o.role==="user"?"#fff":o.error?"#dc2626":"#1B3A4B",fontSize:"13px",lineHeight:"1.6",border:o.role==="assistant"?`1px solid ${o.error?"#fecaca":"#E5E5E0"}`:"none",whiteSpace:"pre-wrap"},children:o.content})]}),o.changes&&o.changes.length>0&&e.jsx(ee,{changes:o.changes,approved:m,onToggle:q,onApply:()=>O(o.changes),onDiscard:()=>K(o.changes),applying:n})]},h)),D&&e.jsx("div",{style:{fontSize:"11px",color:"#374151",background:"#fff",border:"1px solid #E5E5E0",borderRadius:"8px",padding:"8px 12px"},children:D}),b&&e.jsxs("div",{style:{display:"flex",gap:"8px",alignItems:"flex-start"},children:[e.jsx("div",{style:{width:"24px",height:"24px",borderRadius:"50%",background:"#2DD4A815",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"10px",color:"#2DD4A8",fontWeight:700},children:"✦"}),e.jsx("div",{style:{padding:"10px 14px",borderRadius:"10px",background:"#fff",border:"1px solid #E5E5E0",display:"flex",gap:"4px",alignItems:"center"},children:e.jsx(ne,{})})]}),e.jsx("div",{ref:M})]}),e.jsxs("div",{style:{padding:"12px 16px",borderTop:"1px solid #E5E5E0",background:"#fff",flexShrink:0},children:[e.jsxs("div",{style:{display:"flex",gap:"8px",alignItems:"flex-end"},children:[e.jsx("textarea",{ref:W,value:y,onChange:o=>S(o.target.value),onKeyDown:P,disabled:!t||b,placeholder:t?"Ask a question… (Enter to send, Shift+Enter for newline)":"Add an API key in Settings to start",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:t?1:.5},onFocus:o=>{o.target.style.borderColor="#2DD4A8"},onBlur:o=>{o.target.style.borderColor="#E5E5E0"}}),e.jsx("button",{onClick:()=>T(y),disabled:!t||b||!y.trim(),style:{padding:"8px 14px",borderRadius:"8px",border:"none",background:"#1B3A4B",color:"#fff",fontSize:"12px",fontWeight:600,cursor:"pointer",flexShrink:0,opacity:!t||!y.trim()?.4:1,transition:"opacity 0.15s"},children:"Send"})]}),u.length>0&&e.jsx("button",{onClick:H,style:{marginTop:"6px",background:"none",border:"none",color:"#9CA3AF",fontSize:"11px",cursor:"pointer",padding:0},children:"Clear conversation"})]})]}):e.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%",color:"#9CA3AF"},children:"Waiting for model data…"})}function ee({changes:t,approved:r,onToggle:f,onApply:s,onDiscard:p,applying:u}){const d=t.filter(x=>r.has(x.id)).length;return e.jsxs("div",{style:{marginLeft:"32px",border:"1px solid #FCD34D",borderRadius:"10px",background:"#FFFBEB",overflow:"hidden"},children:[e.jsxs("div",{style:{padding:"8px 12px",borderBottom:"1px solid #FDE68A",fontSize:"11px",fontWeight:700,color:"#92400E"},children:[t.length," proposed change",t.length===1?"":"s"," — nothing is written until you apply"]}),e.jsx("div",{style:{display:"flex",flexDirection:"column"},children:t.map(x=>e.jsxs("label",{style:{display:"flex",gap:"8px",alignItems:"flex-start",padding:"8px 12px",borderBottom:"1px solid #FDE68A",cursor:"pointer",fontSize:"12px"},children:[e.jsx("input",{type:"checkbox",checked:r.has(x.id),onChange:()=>f(x.id),style:{marginTop:"2px",cursor:"pointer"}}),e.jsxs("div",{style:{flex:1},children:[e.jsx("div",{style:{fontWeight:600,color:"#1B3A4B"},children:te(x)}),e.jsx("div",{style:{color:"#92400E",marginTop:"2px"},children:x.summary}),e.jsx(oe,{change:x})]})]},x.id))}),e.jsxs("div",{style:{padding:"8px 12px",display:"flex",gap:"8px",alignItems:"center"},children:[e.jsx("button",{onClick:s,disabled:d===0||u,style:{padding:"6px 12px",borderRadius:"6px",border:"none",background:"#92400E",color:"#fff",fontSize:"11px",fontWeight:600,cursor:d===0||u?"default":"pointer",opacity:d===0||u?.4:1},children:u?"Applying…":`Apply ${d} selected`}),e.jsx("button",{onClick:p,disabled:u,style:{padding:"6px 12px",borderRadius:"6px",border:"1px solid #FDE68A",background:"transparent",color:"#92400E",fontSize:"11px",cursor:"pointer"},children:"Discard all"})]})]})}function te(t){switch(t.kind){case"create-element":return`Create ${t.elementKind} · ${t.elementId}`;case"update-element":return`Update · ${t.elementId}`;case"create-relationship":return`Relate · ${t.sourceId} → ${t.targetId}`;case"delete-relationship":return`Remove relationship · ${t.relationshipId}`}}function oe({change:t}){const r={fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:"11px",color:"#374151",marginTop:"4px"};if(t.kind==="create-element"){const f=Object.entries(t.attributes??{});return e.jsxs("div",{style:r,children:[e.jsxs("div",{children:["name = ",t.name]}),t.layer&&e.jsxs("div",{children:["layer = ",t.layer]}),f.map(([s,p])=>e.jsxs("div",{children:[s," = ",p]},s))]})}if(t.kind==="update-element"){const f=new Set([...Object.keys(t.changes.attributes??{}),...t.changes.name!==void 0?["name"]:[],...t.changes.doc!==void 0?["doc"]:[]]);return e.jsx("div",{style:r,children:[...f].map(s=>{var d,x;const p=s==="name"?t.before.name:s==="doc"?t.before.doc:(d=t.before.attributes)==null?void 0:d[s],u=s==="name"?t.changes.name:s==="doc"?t.changes.doc:(x=t.changes.attributes)==null?void 0:x[s];return e.jsxs("div",{children:[s,": ",e.jsx("span",{style:{color:"#dc2626",textDecoration:"line-through"},children:p||"∅"})," → ",e.jsx("span",{style:{color:"#059669"},children:u})]},s)})})}return t.kind==="create-relationship"?e.jsxs("div",{style:r,children:[t.sourceId," —",t.relationshipType,"→ ",t.targetId]}):e.jsxs("div",{style:r,children:[t.sourceId," —",t.relationshipType,"→ ",t.targetId]})}function ne(){return e.jsxs("span",{style:{display:"inline-flex",gap:"3px",alignItems:"center"},children:[[0,1,2].map(t=>e.jsx("span",{style:{width:"5px",height:"5px",borderRadius:"50%",background:"#9CA3AF",animation:"llm-pulse 1.2s ease-in-out infinite",animationDelay:`${t*.2}s`}},t)),e.jsx("style",{children:"@keyframes llm-pulse{0%,80%,100%{opacity:0.3}40%{opacity:1}}"})]})}const re=["Add a PressureSensor component with a USB interface and a power port.","Create a hazard: AlarmFailure that causes patient harm in ICU setting.","Define a software item InfusionController with a requirement for dose limit checking.","Add a RiskControlMeasure that mitigates OverInfusion by adding a flow rate sensor."];function se(){const t=v(n=>n.llmAvailable),r=v(n=>n.llmProvider),f=v(n=>n.llmModel),s=v(n=>n.registerLlmRequest),[p,u]=a.useState(""),[d,x]=a.useState(!1),[l,y]=a.useState(null),[S,b]=a.useState(null),[j,k]=a.useState(!1),C=a.useCallback(async n=>{if(!n.trim()||d)return;x(!0),y(null),b(null),k(!1);const c=`gen-${Date.now()}-${Math.random().toString(36).slice(2)}`;try{const m=await new Promise((B,D)=>{s(c,B,D),U(c,n.trim()),setTimeout(()=>D(new Error("Request timed out after 60 seconds.")),6e4)});y(m)}catch(m){b((m==null?void 0:m.message)??"Unknown error")}finally{x(!1)}},[d,s]),w=()=>{l!=null&&l.sysml&&navigator.clipboard.writeText(l.sysml).then(()=>{k(!0),setTimeout(()=>k(!1),2e3)})},E=n=>(l==null?void 0:l.diagnostics.filter(c=>c.domain===n))??[];return e.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%",background:"#F7F7F5",overflow:"hidden"},children:[e.jsx("div",{style:{padding:"14px 20px 10px",borderBottom:"1px solid #E5E5E0",background:"#fff",flexShrink:0},children:e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"10px"},children:[e.jsx("span",{style:{fontSize:"16px"},children:"⟨/⟩"}),e.jsxs("div",{children:[e.jsx("div",{style:{fontSize:"14px",fontWeight:700,color:"#1B3A4B"},children:"SysML Generator"}),e.jsx("div",{style:{fontSize:"11px",color:t?"#059669":"#dc2626",marginTop:"1px"},children:t?`${r??"LLM"} · ${f??"unknown model"} · natural language → SysML v2`:"No LLM provider — set ANTHROPIC_API_KEY or OPENAI_API_KEY"})]})]})}),e.jsxs("div",{style:{flex:1,overflowY:"auto",padding:"20px"},children:[e.jsxs("div",{style:{marginBottom:"16px"},children:[e.jsx("label",{style:{fontSize:"12px",fontWeight:600,color:"#374151",display:"block",marginBottom:"6px"},children:"Describe what to generate"}),e.jsx("textarea",{value:p,onChange:n=>u(n.target.value),disabled:!t||d,rows:4,placeholder:"Describe the element(s) to generate in plain English…",style:{width:"100%",padding:"10px 12px",border:"1px solid #E5E5E0",borderRadius:"8px",fontSize:"13px",resize:"vertical",fontFamily:"inherit",outline:"none",background:"#fff",color:"#1B3A4B",lineHeight:"1.5",boxSizing:"border-box",opacity:t?1:.5},onFocus:n=>{n.target.style.borderColor="#2DD4A8"},onBlur:n=>{n.target.style.borderColor="#E5E5E0"},onKeyDown:n=>{n.key==="Enter"&&(n.metaKey||n.ctrlKey)&&(n.preventDefault(),C(p))}}),e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginTop:"8px"},children:[e.jsx("span",{style:{fontSize:"11px",color:"#9CA3AF"},children:"Cmd+Enter to generate"}),e.jsx("button",{onClick:()=>C(p),disabled:!t||d||!p.trim(),style:{padding:"6px 16px",borderRadius:"8px",border:"none",background:"#1B3A4B",color:"#fff",fontSize:"12px",fontWeight:600,cursor:"pointer",opacity:!t||!p.trim()?.4:1},children:d?"Generating…":"Generate SysML"})]})]}),!l&&!d&&e.jsxs("div",{style:{marginBottom:"16px"},children:[e.jsx("div",{style:{fontSize:"11px",fontWeight:600,color:"#9CA3AF",textTransform:"uppercase",letterSpacing:"0.06em",marginBottom:"8px"},children:"Examples"}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"5px"},children:re.map(n=>e.jsx("button",{onClick:()=>{u(n)},disabled:!t,style:{textAlign:"left",padding:"7px 11px",borderRadius:"6px",background:"#fff",border:"1px solid #E5E5E0",fontSize:"12px",color:"#374151",cursor:"pointer",opacity:t?1:.5},onMouseEnter:c=>{t&&(c.currentTarget.style.borderColor="#2DD4A8")},onMouseLeave:c=>{c.currentTarget.style.borderColor="#E5E5E0"},children:n},n))})]}),d&&e.jsxs("div",{style:{background:"#fff",border:"1px solid #E5E5E0",borderRadius:"10px",padding:"20px",textAlign:"center",color:"#9CA3AF",fontSize:"13px"},children:[e.jsx("div",{style:{marginBottom:"8px",fontSize:"20px"},children:"⟨/⟩"}),"Generating SysML v2…"]}),S&&e.jsxs("div",{style:{background:"#fef2f2",border:"1px solid #fecaca",borderRadius:"8px",padding:"12px",color:"#dc2626",fontSize:"13px"},children:[e.jsx("strong",{children:"Error:"})," ",S]}),l&&!d&&e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"12px"},children:[e.jsxs("div",{style:{background:"#F0FDF9",border:"1px solid #A7F3D0",borderRadius:"8px",padding:"12px"},children:[e.jsx("div",{style:{fontSize:"11px",fontWeight:600,color:"#065F46",marginBottom:"4px",textTransform:"uppercase",letterSpacing:"0.06em"},children:"Explanation"}),e.jsx("p",{style:{fontSize:"13px",color:"#1B3A4B",margin:0,lineHeight:"1.6"},children:l.explanation}),l.suggestedFile&&e.jsxs("div",{style:{marginTop:"8px",fontSize:"11px",color:"#6B7280"},children:["Suggested file: ",e.jsx("code",{style:{background:"#D1FAE5",padding:"1px 5px",borderRadius:"3px"},children:l.suggestedFile})]})]}),e.jsxs("div",{style:{background:"#1e293b",borderRadius:"10px",overflow:"hidden"},children:[e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"8px 14px",borderBottom:"1px solid #334155"},children:[e.jsx("span",{style:{fontSize:"11px",color:"#94a3b8",fontWeight:600},children:"SysML v2"}),e.jsx("button",{onClick:w,style:{padding:"3px 10px",borderRadius:"4px",border:"none",background:j?"#059669":"#334155",color:"#fff",fontSize:"11px",cursor:"pointer",fontWeight:500},children:j?"Copied!":"Copy"})]}),e.jsx("pre",{style:{margin:0,padding:"14px 16px",fontSize:"12px",lineHeight:"1.6",color:"#e2e8f0",overflowX:"auto",fontFamily:"'SF Mono', 'Fira Code', 'Consolas', monospace"},children:e.jsx("code",{children:l.sysml})})]}),e.jsxs("details",{style:{background:"#fff",border:"1px solid #E5E5E0",borderRadius:"8px",padding:"10px 12px"},children:[e.jsxs("summary",{style:{cursor:"pointer",fontSize:"12px",fontWeight:600},children:["Source diff",l.initialSysml===l.sysml?" (no repair changes)":""]}),e.jsxs("pre",{style:{margin:"8px 0 0",fontSize:"11px",whiteSpace:"pre-wrap"},children:[l.initialSysml??l.sysml,l.initialSysml!==l.sysml?`
|
|
4
|
+
|
|
5
|
+
→ repaired to →
|
|
6
|
+
|
|
7
|
+
${l.sysml}`:""]})]}),e.jsx($,{title:"Standards diagnostics",diagnostics:E("sysml"),empty:"No standards diagnostics."}),e.jsx($,{title:"MEMO diagnostics",diagnostics:[...E("memo-ingest"),...E("memo-methodology")],empty:"No MEMO diagnostics."}),l.changeRecord&&e.jsxs("div",{style:{fontSize:"11px",color:"#6B7280"},children:["Change record: guidance ",l.changeRecord.guidanceVersion," · compiler ",l.changeRecord.compiler.id,l.changeRecord.compiler.version?` ${l.changeRecord.compiler.version}`:""]}),e.jsxs("div",{style:{fontSize:"11px",color:"#9CA3AF",padding:"4px 0"},children:["Review the generated SysML before saving. Copy it into your project's ",e.jsx("code",{children:".sysml"})," files. The dev server will pick up the changes automatically."]}),e.jsx("button",{onClick:()=>{y(null),u("")},style:{padding:"6px 14px",borderRadius:"6px",border:"1px solid #E5E5E0",background:"#fff",color:"#374151",fontSize:"12px",cursor:"pointer",alignSelf:"flex-start"},children:"Generate another"})]})]})]})}function $(t){return e.jsxs("div",{style:{background:"#fff",border:"1px solid #E5E5E0",borderRadius:"8px",padding:"10px 12px"},children:[e.jsx("div",{style:{fontSize:"12px",fontWeight:600,marginBottom:"5px"},children:t.title}),t.diagnostics.length===0?e.jsx("div",{style:{fontSize:"12px",color:"#6B7280"},children:t.empty}):t.diagnostics.map((r,f)=>e.jsxs("div",{style:{fontSize:"12px",color:r.severity==="error"?"#B91C1C":"#92400E",marginTop:"4px"},children:[r.code?`[${r.code}] `:"",r.message]},`${r.code??r.message}-${f}`))]})}const ie=[{view:"ask",label:"Model Assistant",description:"Ask questions and propose edits"},{view:"sysml-generator",label:"SysML Generator",description:"Natural language → SysML v2"}];function ce(){const t=v(s=>s.activeView),r=v(s=>s.setActiveView),f=t.type==="sysml-generator"?"sysml-generator":"ask";return e.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%",overflow:"hidden"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px",padding:"10px 16px",borderBottom:"1px solid #E5E7EB",background:"#fff",flexShrink:0,flexWrap:"wrap"},children:[e.jsxs("span",{style:{fontSize:"10px",fontWeight:700,color:"#065F46",textTransform:"uppercase",letterSpacing:"0.06em",display:"flex",alignItems:"center",gap:"4px",marginRight:"4px"},children:[e.jsx("span",{children:"✦"})," AI Tools"]}),ie.map(s=>{const p=f===s.view;return e.jsx("button",{onClick:()=>r({type:s.view}),title:s.description,"aria-current":p?"page":void 0,style:{padding:"5px 12px",borderRadius:"6px",fontSize:"13px",fontWeight:p?600:400,cursor:"pointer",background:p?"#F0FDF9":"transparent",border:`1px solid ${p?"#A7F3D0":"transparent"}`,color:p?"#065F46":"#6B7280"},children:s.label},s.view)}),e.jsx("span",{style:{flex:1}}),e.jsx("span",{title:"Enabled by --experimental. Generated content is unreviewed and carries no design-control provenance.",style:{fontSize:"10px",fontWeight:700,textTransform:"uppercase",letterSpacing:"0.06em",color:"#92400E",background:"#FEF3C7",border:"1px solid #FDE68A",borderRadius:"4px",padding:"2px 6px"},children:"Experimental"})]}),e.jsx("div",{style:{flex:1,minHeight:0,overflow:"hidden"},children:f==="ask"?e.jsx(Z,{}):e.jsx(se,{})})]})}export{ce as AiWorkspace};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import{j as e}from"./reactflow-s7jmJtXx.js";import{a as l}from"./zustand-CrhqMOHB.js";import{u as O,M as N}from"./index-Bij8Q4Kg.js";const _="memo.analysis.notebooks.v1",I="root",k={folders:[{id:I,name:"Notebooks"}],notebooks:[]};function R(){try{const n=localStorage.getItem(_);if(!n)return k;const o=JSON.parse(n);return!Array.isArray(o.folders)||!Array.isArray(o.notebooks)?k:o}catch{return k}}const C=[{template:"part-inventory",title:"Part inventory",description:"List part usages and their owners.",icon:"▦"},{template:"requirements-review",title:"Requirements review",description:"List requirements and their declared text.",icon:"☑"},{template:"ownership-tree",title:"Ownership tree",description:"Print the model hierarchy for review.",icon:"⌘"},{template:"syside-part-api",title:"Syside live model API",description:"Query typed PartUsage elements directly from SysML v2 files.",icon:"⌁"}];function z(n){switch(n){case"part-inventory":return[`# Part inventory from the current MEMO model snapshot
|
|
2
|
+
`,`parts = [element for element in elements if 'part' in (element.get('kind', '') + ' ' + element.get('construct', '')).lower()]
|
|
3
|
+
`,`[(part.get('shortId'), part.get('name'), part.get('kind')) for part in parts[:100]]
|
|
4
|
+
`];case"requirements-review":return[`# Requirements review from the current MEMO model snapshot
|
|
5
|
+
`,`requirements = [element for element in elements if 'requirement' in element.get('kind', '').lower()]
|
|
6
|
+
`,`[(requirement.get('shortId'), requirement.get('name'), requirement.get('documentation', ''))
|
|
7
|
+
`,` for requirement in requirements[:100]]
|
|
8
|
+
`];case"ownership-tree":return[`# Ownership/containment relationships in the current model
|
|
9
|
+
`,`ownership = [relationship for relationship in relationships
|
|
10
|
+
`,` if any(term in relationship.get('type', '').lower() for term in ('contain', 'own', 'compose'))]
|
|
11
|
+
`,`[(relationship.get('sourceId'), relationship.get('targetId'), relationship.get('type'))
|
|
12
|
+
`,` for relationship in ownership[:100]]
|
|
13
|
+
`];case"syside-part-api":return[`# Licensed Syside Automator: query the textual SysML v2 model directly
|
|
14
|
+
`,`from pathlib import Path
|
|
15
|
+
`,`import syside
|
|
16
|
+
`,`
|
|
17
|
+
`,`MODEL_ROOT = Path('../model')
|
|
18
|
+
`,`sysml_paths = [str(path) for path in MODEL_ROOT.rglob('*.sysml')]
|
|
19
|
+
`,`# GPCA currently has semantic diagnostics, so use Syside’s tolerant loader.
|
|
20
|
+
`,`sysml_model, diagnostics = syside.try_load_model(sysml_paths)
|
|
21
|
+
`,`part_usages = list(sysml_model.elements(syside.PartUsage))
|
|
22
|
+
`,`print(f'Loaded {len(sysml_model.user_docs)} documents and {len(part_usages)} PartUsage elements')
|
|
23
|
+
`,`[(part.name, part.owner.name if part.owner else None) for part in part_usages[:100]]
|
|
24
|
+
`];default:return[`# Query the current MEMO model snapshot
|
|
25
|
+
`,`[(element.get('shortId'), element.get('name'), element.get('kind')) for element in elements[:100]]
|
|
26
|
+
`]}}function P(n,o,c){const i=new TextEncoder().encode(JSON.stringify(c));let p="";for(let a=0;a<i.length;a+=32768)p+=String.fromCharCode(...i.subarray(a,a+32768));const h=btoa(p);return{nbformat:4,nbformat_minor:5,metadata:{kernelspec:{display_name:"Python 3",language:"python",name:"python3"},language_info:{name:"python",version:"3.12"}},cells:[{cell_type:"markdown",metadata:{},source:[`# ${n}
|
|
27
|
+
`,`
|
|
28
|
+
`,`This live notebook was generated by MEMO Architect with a snapshot of the currently loaded model. The starter cells require only Python and run without a commercial license.
|
|
29
|
+
`,`
|
|
30
|
+
`,"> For direct textual SysML v2 access, add the optional licensed Syside Automator adapter after configuring `SYSIDE_LICENSE_KEY`.\n"]},{cell_type:"code",execution_count:null,metadata:{},outputs:[],source:[`import base64
|
|
31
|
+
`,`import json
|
|
32
|
+
`,`
|
|
33
|
+
`,`model = json.loads(base64.b64decode('${h}').decode('utf-8'))
|
|
34
|
+
`,`elements = list(model.get('elements', {}).values())
|
|
35
|
+
`,`relationships = list(model.get('relationships', []))
|
|
36
|
+
`,`print(f'Loaded {len(elements)} elements and {len(relationships)} relationships')
|
|
37
|
+
`]},{cell_type:"code",execution_count:null,metadata:{},outputs:[],source:z(o)}]}}function S(n){return`${n.title.replace(/[^a-z0-9_-]+/gi,"-")||"memo-analysis"}.ipynb`}async function j(n,o){const c=S(n),i=P(n.title,n.template??"custom",o);if(!(await fetch(`http://127.0.0.1:8888/api/contents/${encodeURIComponent(c)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:"notebook",format:"json",content:i})})).ok)throw new Error("JupyterLab is not available at 127.0.0.1:8888.")}async function L(n){const o=await fetch(`http://127.0.0.1:8888/api/contents/${encodeURIComponent(S(n))}?content=0`);if(o.status===404)return!1;if(!o.ok)throw new Error("JupyterLab is not available at 127.0.0.1:8888.");return!0}function U(){var F;const n=O(t=>t.model),[o,c]=l.useState(R),[i,p]=l.useState(I),[h,a]=l.useState(()=>{var t;return((t=R().notebooks.at(-1))==null?void 0:t.id)??null}),[B,m]=l.useState(null),[w,s]=l.useState(null);l.useEffect(()=>{localStorage.setItem(_,JSON.stringify(o))},[o]);const E=l.useMemo(()=>o.notebooks.filter(t=>t.folderId===i),[o.notebooks,i]),r=o.notebooks.find(t=>t.id===h)??null;l.useEffect(()=>{r&&(s(null),m(null),L(r).then(t=>t?s(r.id):j(r,n).then(()=>s(r.id))).catch(t=>m(t.message)))},[h]);function D(){const t=window.prompt("Folder name");if(!(t!=null&&t.trim()))return;const d={id:`folder-${crypto.randomUUID()}`,name:t.trim()};c(f=>({...f,folders:[...f.folders,d]})),p(d.id)}function g(t="custom",d="Model analysis",f=!0){const x=f?window.prompt("Notebook title",d):d;if(!(x!=null&&x.trim()))return;const v=x.trim(),A=o.notebooks.filter(u=>u.title===v).length,M=A?`${v} ${A+1}`:v,b={id:`notebook-${crypto.randomUUID()}`,title:M,folderId:i,createdAt:Date.now(),template:t};c(u=>({...u,notebooks:[...u.notebooks,b]})),a(b.id),s(null),m(null),j(b,n).then(()=>s(b.id)).catch(u=>m(u.message))}function T(){r&&(m(null),s(null),L(r).then(t=>t?s(r.id):j(r,n).then(()=>s(r.id))).catch(t=>m(t.message)))}const y={border:"1px solid #BFE6D9",background:"#F2FCF8",color:"#176B55",borderRadius:6,padding:"7px 10px",cursor:"pointer",fontSize:12,fontWeight:600};return e.jsxs("div",{className:"flex flex-1 overflow-hidden",style:{background:"#F7F7F5"},children:[e.jsxs("aside",{style:{width:280,flexShrink:0,borderRight:"1px solid #D9E2E7",background:"#FFF",padding:16,overflow:"auto"},children:[e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:14},children:[e.jsxs("div",{children:[e.jsx("div",{style:{fontWeight:700,color:"#173B4E"},children:"Jupyter notebooks"}),e.jsx("div",{style:{fontSize:12,color:"#71889A",marginTop:3},children:"Python analysis workspace"})]}),e.jsx("button",{title:"New folder",onClick:D,style:y,children:"+ Folder"})]}),e.jsx("div",{style:{marginBottom:14},children:o.folders.map(t=>e.jsxs("button",{onClick:()=>p(t.id),style:{display:"block",width:"100%",textAlign:"left",border:"none",borderRadius:6,padding:"8px 10px",cursor:"pointer",background:i===t.id?"#E2F7F0":"transparent",color:"#1B3A4B",fontWeight:i===t.id?700:500},children:["▾ ",t.name]},t.id))}),e.jsx("button",{onClick:()=>g(),style:{...y,width:"100%",marginBottom:12},children:"+ New notebook"}),e.jsxs("div",{style:{borderTop:"1px solid #E3ECEF",margin:"4px 0 10px",paddingTop:12},children:[e.jsx("div",{style:{color:"#71889A",fontSize:10,fontWeight:700,letterSpacing:".07em",textTransform:"uppercase",margin:"0 0 7px 10px"},children:"Starter examples"}),C.map(t=>e.jsxs("button",{onClick:()=>g(t.template,t.title,!1),title:t.description,style:{display:"block",width:"100%",textAlign:"left",border:"none",borderRadius:6,padding:"8px 10px",cursor:"pointer",background:"transparent",color:"#244D63",fontSize:12},children:[e.jsx("span",{style:{color:"#2D8D70",marginRight:7},children:t.icon}),t.title]},t.template))]}),E.map(t=>e.jsxs("button",{onClick:()=>a(t.id),style:{display:"block",width:"100%",textAlign:"left",border:"none",borderRadius:6,padding:"9px 10px",cursor:"pointer",background:h===t.id?"#EEF7FB":"transparent",color:"#244D63",fontSize:13},children:["◫ ",t.title]},t.id)),E.length===0&&e.jsx("div",{style:{color:"#8AA0AE",fontSize:12,lineHeight:1.5,padding:"8px 10px"},children:"No notebooks in this folder yet."})]}),e.jsx("main",{style:{flex:1,minWidth:0,overflow:"auto",padding:"32px clamp(24px, 5vw, 72px)"},children:e.jsxs("div",{style:{maxWidth:960},children:[e.jsxs("div",{style:{display:"flex",alignItems:"start",justifyContent:"space-between",gap:20,marginBottom:26},children:[e.jsxs("div",{children:[e.jsx("div",{style:{color:"#2D8D70",fontSize:12,fontWeight:700,letterSpacing:".08em",textTransform:"uppercase"},children:"Model analysis"}),e.jsx("h1",{style:{color:"#173B4E",fontSize:28,margin:"6px 0 8px"},children:"Analysis"}),e.jsx("p",{style:{color:"#587487",margin:0,lineHeight:1.55,maxWidth:620},children:"Create live Jupyter notebooks that query the currently loaded MEMO model with Python. A licensed Syside adapter can be added for direct textual SysML v2 access."})]}),e.jsxs("div",{style:{display:"flex",alignItems:"flex-start",gap:12},children:[e.jsx(N,{size:118}),e.jsx("button",{onClick:()=>g(),style:{...y,whiteSpace:"nowrap"},children:"+ New notebook"})]})]}),e.jsx("section",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(210px, 1fr))",gap:12,marginBottom:24},children:[["Elements",Object.keys((n==null?void 0:n.elements)??{}).length],["Relationships",((F=n==null?void 0:n.relationships)==null?void 0:F.length)??0],["Kernel","Python 3.12"]].map(([t,d])=>e.jsxs("div",{style:{background:"#FFF",border:"1px solid #D9E6E9",borderRadius:10,padding:"15px 17px"},children:[e.jsx("div",{style:{color:"#7892A1",fontSize:11,fontWeight:700,textTransform:"uppercase",letterSpacing:".06em"},children:t}),e.jsx("div",{style:{color:"#173B4E",fontSize:20,fontWeight:700,marginTop:5},children:d})]},String(t)))}),e.jsxs("section",{style:{marginBottom:24},children:[e.jsx("div",{style:{color:"#587487",fontSize:12,fontWeight:700,textTransform:"uppercase",letterSpacing:".06em",marginBottom:9},children:"Starter notebooks"}),e.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(210px, 1fr))",gap:12},children:C.map(t=>e.jsxs("button",{onClick:()=>g(t.template,t.title,!1),style:{textAlign:"left",background:"#FFF",border:"1px solid #D9E6E9",borderRadius:10,padding:16,cursor:"pointer",color:"#173B4E"},children:[e.jsx("div",{style:{fontSize:20,color:"#2D8D70",marginBottom:8},children:t.icon}),e.jsx("div",{style:{fontWeight:700,fontSize:14},children:t.title}),e.jsx("div",{style:{color:"#7892A1",fontSize:12,lineHeight:1.45,marginTop:4},children:t.description})]},t.template))})]}),e.jsx("section",{style:{background:"#FFF",border:"1px solid #D9E6E9",borderRadius:10,padding:20},children:r?e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",gap:16,alignItems:"center"},children:[e.jsxs("div",{children:[e.jsx("h2",{style:{margin:0,color:"#173B4E",fontSize:18},children:r.title}),e.jsx("div",{style:{color:"#7892A1",fontSize:12,marginTop:5},children:w===r.id?"Saved and ready in local JupyterLab":"Preparing live notebook…"})]}),w===r.id?e.jsx("a",{href:`http://127.0.0.1:8888/lab/tree/${encodeURIComponent(S(r))}`,target:"_blank",rel:"noopener noreferrer",style:{...y,textDecoration:"none"},children:"▶ Open live JupyterLab"}):e.jsx("button",{disabled:!0,style:{...y,opacity:.55,cursor:"wait"},children:"Preparing…"})]}),B&&e.jsxs("div",{style:{marginTop:12,padding:"10px 12px",borderRadius:7,background:"#FFFBEB",border:"1px solid #FDE68A",color:"#92400E",fontSize:12,lineHeight:1.55},children:[e.jsx("strong",{children:"Start JupyterLab first."})," From the project’s ",e.jsx("code",{children:"analysis"})," folder, run ",e.jsx("code",{style:{padding:"1px 4px",borderRadius:3,background:"#FEF3C7"},children:"jupyter lab --port 8888"}),", then return here and retry. Architect cannot start a local process from the browser automatically. ",e.jsx("button",{onClick:T,style:{marginLeft:8,border:"none",background:"none",color:"#176B55",fontWeight:700,cursor:"pointer"},children:"Retry connection"})]}),e.jsx("pre",{style:{whiteSpace:"pre-wrap",margin:"18px 0 0",padding:14,borderRadius:7,background:"#102A3A",color:"#BDEFE1",fontSize:12,lineHeight:1.55},children:`elements = list(model.get('elements', {}).values())
|
|
38
|
+
parts = [e for e in elements if 'part' in (e.get('kind', '') + ' ' + e.get('construct', '')).lower()]
|
|
39
|
+
[(p.get('shortId'), p.get('name'), p.get('kind')) for p in parts[:100]]`})]}):e.jsxs("div",{style:{color:"#587487",lineHeight:1.6},children:[e.jsx("strong",{style:{color:"#173B4E"},children:"Start an analysis notebook."}),e.jsx("br",{}),"Choose a starter to create it instantly, then open it in live JupyterLab."]})})]})})]})}export{U as AnalysisWorkspace};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./reactflow-CsCqNKB-.js";import{a as g}from"./zustand-CrhqMOHB.js";import{u as j,f as k}from"./index-D0vtjNjX.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
|
+
import{j as e}from"./reactflow-s7jmJtXx.js";import{a as g}from"./zustand-CrhqMOHB.js";import{u as j,h as k}from"./index-Bij8Q4Kg.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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as t}from"./reactflow-s7jmJtXx.js";import{a}from"./zustand-CrhqMOHB.js";import{C as l,F as N,S as we,u as O,r as T}from"./index-Bij8Q4Kg.js";import{l as Se,r as ke,e as ee,d as ve,c as je,s as Ce,a as W,A as te,T as B,H as Ee}from"./element-options-B7AgTB8R.js";const ne=new Set(["Function","Function","UserActivity"]),se=new Set(["System","Subsystem","Component","LogicalComponent","SoftwareComponent","SoftwareModule","Software"]);function Ie(o){var S,y;const x=[],u=[];for(const n of Object.values(o.elements))ne.has(n.kind)&&x.push(n),se.has(n.kind)&&u.push(n);const g=[],h=new Set,c=new Map;for(const n of u)c.set(n.id,[]);for(const n of o.relationships){if(n.type!=="allocateTo")continue;const i=o.elements[n.sourceId],p=o.elements[n.targetId];!i||!p||ne.has(i.kind)&&se.has(p.kind)&&(g.push({functionId:i.id,functionName:i.name,targetId:p.id,targetName:p.name}),h.add(i.id),c.has(p.id)||c.set(p.id,[]),c.get(p.id).push(i.id))}for(const n of x)if(n.allocatedTo&&!h.has(n.id)){const i=u.find(p=>p.name===n.allocatedTo||p.id===n.allocatedTo);i&&(g.push({functionId:n.id,functionName:n.name,targetId:i.id,targetName:i.name}),h.add(n.id),c.has(i.id)||c.set(i.id,[]),c.get(i.id).push(n.id))}const m=[];let b=0;for(const n of x)h.has(n.id)||m.push({id:`ci-${b++}`,type:"unallocated-function",severity:"warning",elementId:n.id,elementName:n.name,message:`Function "${n.name}" is not allocated to any component`});for(const n of u){const i=c.get(n.id);(!i||i.length===0)&&m.push({id:`ci-${b++}`,type:"no-functions-allocated",severity:"info",elementId:n.id,elementName:n.name,message:`Component "${n.name}" has no functions allocated to it`})}const f=new Map;for(const n of g)f.set(n.functionId,n.targetId);for(const n of o.relationships){if(n.type!=="flow")continue;const i=f.get(n.sourceId),p=f.get(n.targetId);if(i&&p&&i!==p){const k=o.elements[n.sourceId],M=o.elements[n.targetId];k&&M&&m.push({id:`ci-${b++}`,type:"cross-component-flow",severity:"info",elementId:n.sourceId,elementName:k.name,message:`Flow from "${k.name}" to "${M.name}" crosses component boundary (${(S=o.elements[i])==null?void 0:S.name} → ${(y=o.elements[p])==null?void 0:y.name})`,relatedIds:[n.targetId,i,p]})}}return{allocations:g,componentFunctions:c,issues:m,functions:x,structures:u}}function Re({label:o,children:x,badge:u,title:g,width:h=260}){const[c,m]=a.useState(!1),b=a.useRef(null);return a.useEffect(()=>{if(!c)return;const f=y=>{var n;(n=b.current)!=null&&n.contains(y.target)||m(!1)},S=y=>{y.key==="Escape"&&m(!1)};return document.addEventListener("mousedown",f),document.addEventListener("keydown",S),()=>{document.removeEventListener("mousedown",f),document.removeEventListener("keydown",S)}},[c]),t.jsxs("div",{ref:b,style:{position:"relative"},children:[t.jsxs("button",{type:"button","aria-haspopup":"dialog","aria-expanded":c,title:g,onClick:()=>m(f=>!f),style:{display:"flex",alignItems:"center",gap:"5px",padding:"3px 8px",borderRadius:"5px",border:`1px solid ${c||u?l.accent:l.border}`,background:c?"#E8F8F3":l.surface,fontSize:N.xs,color:l.secondary,cursor:"pointer",whiteSpace:"nowrap"},children:[o,u&&t.jsx("span",{style:{fontSize:"10px",padding:"0 4px",borderRadius:"7px",background:l.accent,color:"#08331F",fontWeight:700},children:u}),t.jsx("span",{style:{fontSize:"9px",color:l.faint},children:"▾"})]}),c&&t.jsx("div",{role:"dialog","aria-label":o,style:{position:"absolute",top:"calc(100% + 4px)",right:0,zIndex:60,width:h,padding:"10px 12px",background:l.surface,border:`1px solid ${l.border}`,borderRadius:"7px",boxShadow:we.lg,display:"flex",flexDirection:"column",gap:"9px"},children:x})]})}const oe=[{value:"natural",label:"Name",title:"Alphabetical inside every parent"},{value:"kind",label:"Element type",title:"Grouped by element type, then name"},{value:"partition",label:"Partition",title:"Sequence siblings so dependencies sit above the diagonal, leaving only real cycles as feedback"},{value:"cluster",label:"Cluster",title:"Keep mutually dependent siblings adjacent"}];function Ne(o){return o.types.length>0?T(o.types[0]):"#475569"}function ze(){var Y;const o=O(e=>e.model),x=O(e=>e.selectElement),u=O(e=>e.selectedElementId),g=O(e=>e.setAnalysisIssues),[h,c]=a.useState({}),[m,b]=a.useState({}),[f,S]=a.useState([]),[y,n]=a.useState([]),[i,p]=a.useState([]),[k,M]=a.useState(null),[$,ae]=a.useState(!1),[A,le]=a.useState("natural"),[F,ie]=a.useState(!1),[G,re]=a.useState(!0),[_,ce]=a.useState(26),[v,de]=a.useState(!0),[q,j]=a.useState(new Set),[V,C]=a.useState(new Set),[w,Z]=a.useState(null),J=a.useMemo(()=>o?Se(o):[],[o]),H=a.useMemo(()=>{if(!o)return[];const e=new Map;for(const s of o.relationships)e.set(s.type,(e.get(s.type)??0)+1);return ke(o).map(s=>({value:s,hint:String(e.get(s)??0),color:T(s)}))},[o]),z=a.useMemo(()=>ee(o,h),[o,h]),L=a.useMemo(()=>ee(o,m),[o,m]);a.useEffect(()=>{const e=new Set(z.map(s=>s.value));S(s=>s.length===0||s.every(r=>e.has(r))?s:s.filter(r=>e.has(r)))},[z]),a.useEffect(()=>{const e=new Set(L.map(s=>s.value));n(s=>s.length===0||s.every(r=>e.has(r))?s:s.filter(r=>e.has(r)))},[L]);const E=a.useMemo(()=>k??(o?ve(o):[]),[k,o]),pe=a.useMemo(()=>{const e=new Set(E);return H.map(s=>e.has(s.value)?{...s,label:`${s.value} (nesting)`,hint:"builds the tree"}:s)},[H,E]),Q=[k!==null,!v,!G,$,F].filter(Boolean).length,d=a.useMemo(()=>o?je(o,{rows:{layer:h.layer,kinds:h.kind?[h.kind]:[],elementIds:f,expanded:q},columns:{layer:m.layer,kinds:m.kind?[m.kind]:[],elementIds:y,expanded:V},dependencyTypes:i,containmentTypes:E,groupByPackage:$,ordering:A,symmetric:F}):null,[o,h,m,f,y,i,E,$,A,F,q,V]),[D,ue]=a.useState(!1);a.useEffect(()=>{if(D||!o)return;const e=Ce(o,E);e&&(c({layer:e}),b({layer:e}),ue(!0))},[o,E,D]);const[X,me]=a.useState(!1);a.useEffect(()=>{if(X||!D||!d)return;const e=d.rowRoots.filter(r=>r.children.length>0).map(r=>r.id),s=d.columnRoots.filter(r=>r.children.length>0).map(r=>r.id);e.length===0&&s.length===0||(j(new Set(e)),C(new Set(s)),me(!0))},[d,D,X]);const he=a.useCallback(e=>{j(s=>P(s,e)),v&&C(s=>P(s,e))},[v]),xe=a.useCallback(e=>{C(s=>P(s,e)),v&&j(s=>P(s,e))},[v]),fe=a.useCallback(()=>{d&&(j(new Set(W(d.rowRoots))),C(new Set(W(d.columnRoots))))},[d]),ge=a.useCallback(()=>{j(new Set),C(new Set)},[]),ye=a.useCallback(e=>{d&&(j(new Set(W(d.rowRoots,e))),C(new Set(W(d.columnRoots,e))))},[d]),K=a.useMemo(()=>o?Ie(o):null,[o]);a.useEffect(()=>{if(K)return g(K.issues.map(e=>({id:e.id,source:"DSM",severity:e.severity,elementId:e.elementId,elementName:e.elementName,message:e.message,tag:e.type==="unallocated-function"?"unallocated":e.type==="cross-component-flow"?"cross-boundary":"no functions"}))),()=>g([])},[K,g]);const be=a.useCallback(e=>{if(!e)return{};if(e.diagonal)return{text:String(e.strength),color:l.muted,background:"#E3E8EE"};const s=Ne(e),r=Math.min(.14+e.strength*.13,.55);return{text:String(e.strength),color:s,background:`${s}${Math.round(r*255).toString(16).padStart(2,"0")}`}},[]);if(!o||!d)return t.jsx("div",{className:"flex-1 flex items-center justify-center",style:{color:l.faint,fontSize:N.sm},children:"No model loaded"});const{stats:I}=d;return t.jsxs("div",{className:"flex-1 flex flex-col overflow-hidden",style:{background:"#F7F7F5"},children:[t.jsxs("div",{style:{borderBottom:`1px solid ${l.border}`,background:l.surface},children:[t.jsxs("div",{className:"flex items-center gap-3 px-4 py-2",style:{flexWrap:"wrap"},children:[t.jsx("span",{style:{fontSize:N.sm,fontWeight:600,color:l.primary},children:"Design Structure Matrix"}),t.jsxs("span",{style:{fontSize:"11px",color:l.faint},children:[d.rows.length," ","×"," ",d.columns.length," ","·"," ",d.totalDependencies," dependencies",I.internal>0&&` · ${I.internal} internal`]}),t.jsx("div",{className:"flex-1"}),t.jsx(te,{label:"Rows",layers:J,value:h,onChange:c,describedAs:"row scope",title:"What the rows list — one architecture layer, or one element type within it. An axis holds one semantic type so the marks between rows and columns can be read as a structure."}),t.jsx(B,{label:"of",allLabel:`all ${z.length}`,options:z,selected:f,onChange:S,width:110,describedAs:"row elements",placeholder:"Filter by name, kind or id…",title:"The individual elements listed down the side. Type to narrow; each word narrows further."}),t.jsx(te,{label:"Columns",layers:J,value:m,onChange:b,describedAs:"column scope",title:"What the columns list — one architecture layer, or one element type within it."}),t.jsx(B,{label:"of",allLabel:`all ${L.length}`,options:L,selected:y,onChange:n,width:110,describedAs:"column elements",placeholder:"Filter by name, kind or id…",title:"The individual elements listed across the top. Type to narrow; each word narrows further."}),t.jsx(B,{label:"Dependency",allLabel:"Any relationship",options:pe,width:140,selected:i,onChange:p,describedAs:"dependency relationships",title:"Relationships that put a mark in a cell — flow, trace, allocation, …"})]}),t.jsxs("div",{className:"flex items-center gap-3 px-4 pb-2",style:{flexWrap:"wrap"},children:[t.jsxs("div",{className:"flex items-center gap-1",children:[t.jsx("button",{onClick:fe,style:U,title:"Expand every subsystem on both axes",children:"Expand all"}),t.jsx("button",{onClick:ge,style:U,title:"Collapse back to the top-level subsystems",children:"Collapse all"}),[1,2,3].map(e=>t.jsxs("button",{onClick:()=>ye(e),style:U,title:`Expand ${e} level${e>1?"s":""} deep`,children:["L",e]},e))]}),t.jsxs("label",{style:{...R,gap:"5px"},children:["Order",t.jsx("select",{value:A,onChange:e=>le(e.target.value),title:(Y=oe.find(e=>e.value===A))==null?void 0:Y.title,style:Te,children:oe.map(e=>t.jsx("option",{value:e.value,title:e.title,children:e.label},e.value))})]}),t.jsxs("label",{style:{...R,gap:"5px"},title:"Cell size",children:["Zoom",t.jsx("input",{type:"range",min:14,max:44,step:2,value:_,onChange:e=>ce(Number(e.target.value)),style:{width:"76px",accentColor:l.accent}})]}),t.jsxs(Re,{label:"Options",badge:Q>0?String(Q):void 0,title:"Settings you set once: how nesting is derived, how the axes are grouped, what the header shows",children:[t.jsx(B,{label:"Nesting",allLabel:"Auto (composition)",options:H,width:150,selected:k??[],onChange:e=>M(e.length===0?null:e),describedAs:"nesting relationships",title:"Relationships read as parent → child containment, which is what builds the tree"}),t.jsxs("label",{style:R,title:"Expanding a subsystem on one axis expands the same one on the other",children:[t.jsx("input",{type:"checkbox",checked:v,onChange:e=>de(e.target.checked),style:{accentColor:l.accent}}),"Linked axes"]}),t.jsxs("label",{style:R,title:"Show column names above the grid as well as their numbers",children:[t.jsx("input",{type:"checkbox",checked:G,onChange:e=>re(e.target.checked),style:{accentColor:l.accent}}),"Column names"]}),t.jsxs("label",{style:R,title:"Group top-level elements under their SysML package",children:[t.jsx("input",{type:"checkbox",checked:$,onChange:e=>ae(e.target.checked),style:{accentColor:l.accent}}),"Group by package"]}),t.jsxs("label",{style:R,title:"Count every dependency in both directions, making the matrix symmetric",children:[t.jsx("input",{type:"checkbox",checked:F,onChange:e=>ie(e.target.checked),style:{accentColor:l.accent}}),"Both directions"]})]}),t.jsx("div",{className:"flex-1"}),t.jsx("div",{style:{fontSize:"11px",color:l.muted,display:"flex",gap:"10px",whiteSpace:"nowrap"},children:[["feedback",I.feedback,"Marks below the diagonal — candidates for rework loops"],["coupled",I.couplings,"Pairs that depend on each other in both directions"],["isolated",I.isolated,"Lines with no dependency either way"],["max degree",I.maxDegree,"Most dependencies touching one line"]].map(([e,s,r])=>t.jsxs("span",{title:r,children:[t.jsx("strong",{style:{color:l.primary},children:s})," ",e]},e))})]})]}),t.jsx(Ee,{result:d,onToggleRow:he,onToggleColumn:xe,onSelectElement:x,selectedElementId:u,renderCell:be,onCellClick:(e,s,r)=>{r&&Z({row:e,column:s,cell:r}),x(e.node.id)},cellSize:_,showColumnNames:G,footer:t.jsxs("div",{style:{marginTop:"18px",display:"flex",gap:"14px",flexWrap:"wrap",fontSize:"11px",color:l.muted},children:[[...new Set(d.matrix.flat().flatMap(e=>(e==null?void 0:e.types)??[]))].sort().map(e=>t.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[t.jsx("span",{style:{width:"10px",height:"10px",borderRadius:"2px",background:T(e)}}),e]},e)),t.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[t.jsx("span",{style:{width:"10px",height:"10px",borderRadius:"2px",background:"#E3E8EE"}}),"diagonal: dependencies inside the subsystem"]}),t.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[t.jsx("span",{style:{width:"10px",height:"2px",background:"#94A3B8"}}),"subsystem boundary"]})]})}),w&&t.jsxs("div",{style:{position:"fixed",bottom:"76px",right:"20px",zIndex:100,width:"300px",padding:"12px 14px",borderRadius:"9px",background:l.surface,border:`1px solid ${l.border}`,boxShadow:"0 6px 22px rgba(0,0,0,0.14)",fontSize:N.xs},children:[t.jsxs("div",{className:"flex items-start justify-between gap-2",children:[t.jsxs("div",{style:{fontWeight:600,color:l.primary},children:[w.row.node.name," ","→"," ",w.column.node.name]}),t.jsx("button",{onClick:()=>Z(null),style:{color:l.faint,background:"none",border:"none",cursor:"pointer"},children:"✕"})]}),t.jsxs("div",{style:{color:l.muted,margin:"6px 0"},children:[w.cell.strength," dependenc",w.cell.strength===1?"y":"ies",w.cell.aggregated&&" · rolled up from collapsed parts",w.cell.diagonal&&" · internal to this subsystem"]}),t.jsx("div",{style:{display:"flex",gap:"4px",flexWrap:"wrap"},children:w.cell.types.map(e=>t.jsx("span",{style:{fontSize:"10px",padding:"2px 6px",borderRadius:"4px",background:`${T(e)}20`,color:T(e),fontWeight:500},children:e},e))}),w.cell.aggregated&&t.jsx("div",{style:{marginTop:"8px",fontSize:"11px",color:l.faint},children:"Expand both sides to see which parts are actually joined."})]})]})}function P(o,x){const u=new Set(o);return u.has(x)?u.delete(x):u.add(x),u}const U={padding:"3px 8px",borderRadius:"5px",border:`1px solid ${l.border}`,background:l.surface,fontSize:"11px",color:l.secondary,cursor:"pointer"},R={display:"flex",alignItems:"center",gap:"6px",fontSize:N.xs,color:l.muted,whiteSpace:"nowrap"},Te={border:`1px solid ${l.border}`,borderRadius:"5px",padding:"2px 5px",background:l.surface,fontSize:N.xs,color:l.primary};export{ze as DSMView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e}from"./reactflow-s7jmJtXx.js";import{a as f}from"./zustand-CrhqMOHB.js";import{u as g,h}from"./index-Bij8Q4Kg.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 m({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.jsxs("div",{style:{position:"relative",width:260,height:154,overflow:"hidden",margin:"0 auto -10px",opacity:.62},title:"MEMO Architect","aria-label":"MEMO Architect",children:[e.jsx("img",{src:"/logo.png",alt:"","aria-hidden":"true",style:{width:260,height:260,objectFit:"contain",transform:"translateY(-32px)",mixBlendMode:"multiply"}}),e.jsx("span",{style:{position:"absolute",left:"59%",top:115,color:"#8B949E",fontSize:20,fontWeight:600,letterSpacing:"0.02em",whiteSpace:"nowrap"},children:"Architect"})]}),e.jsxs("div",{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(m,{label:"Elements",value:l.totalElements,color:"#1B3A4B"}),e.jsx(m,{label:"Relationships",value:l.totalRelationships,color:"#4A90D9"}),e.jsx(m,{label:"Completeness",value:`${u}%`,color:u>=70?"#2ECC71":u>=40?"#F39C12":"#E74C3C"}),e.jsx(m,{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:h.requirements,onClick:()=>{o("model"),n({type:"welcome"})}}),e.jsx(y,{layer:"risk",label:"Risk",count:l.riskCount,color:h.risk,onClick:()=>{o("model"),n({type:"welcome"})}}),e.jsx(y,{layer:"logical",label:"Architecture",count:l.architectureCount,color:h.logical,onClick:()=>{o("views"),n({type:"welcome"})}}),e.jsx(y,{layer:"verification",label:"Verification",count:l.verificationCount,color:h.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:"Open Viewpoints",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," model view",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 viewpoints →"})]})})]})})}export{S as Dashboard};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./reactflow-CsCqNKB-.js";import{a as m}from"./zustand-CrhqMOHB.js";import{u as b}from"./index-D0vtjNjX.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:"Documents"}),e.jsxs("p",{style:{color:"#6B7280",fontSize:"13px",marginTop:"4px"},children:["Design history file · ",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
|
+
import{j as e}from"./reactflow-s7jmJtXx.js";import{a as m}from"./zustand-CrhqMOHB.js";import{u as b}from"./index-Bij8Q4Kg.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:"Documents"}),e.jsxs("p",{style:{color:"#6B7280",fontSize:"13px",marginTop:"4px"},children:["Design history file · ",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};
|