Sai Kumar Taraka commited on
Commit
2b1ea51
·
1 Parent(s): 7192c73

Fix FieldDef missing after bad edit; add Dashboard iframe to FileViewer

Browse files
backend/main.py CHANGED
@@ -266,6 +266,21 @@ async def download_all_files(task_id: str):
266
  )
267
 
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  @app.get("/api/generate/{task_id}/ipxact")
270
  async def download_ipxact(task_id: str):
271
  """Download IP-XACT XML for a completed pipeline."""
 
266
  )
267
 
268
 
269
+ @app.get("/api/generate/{task_id}/dashboard")
270
+ async def get_coverage_dashboard(task_id: str):
271
+ """Get the generated coverage dashboard HTML."""
272
+ pipeline = pipeline_manager.get_pipeline(task_id)
273
+ if not pipeline:
274
+ raise HTTPException(status_code=404, detail=f"Pipeline {task_id} not found")
275
+ repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
276
+ dashboard_path = os.path.join(repo_root, "output", task_id, "coverage_summary.html")
277
+ if not os.path.exists(dashboard_path):
278
+ raise HTTPException(status_code=404, detail="Coverage dashboard not yet generated for this pipeline")
279
+ with open(dashboard_path, "r", encoding="utf-8") as f:
280
+ html = f.read()
281
+ return Response(content=html, media_type="text/html")
282
+
283
+
284
  @app.get("/api/generate/{task_id}/ipxact")
285
  async def download_ipxact(task_id: str):
286
  """Download IP-XACT XML for a completed pipeline."""
frontend/src/components/FileViewer.tsx CHANGED
@@ -1,5 +1,5 @@
1
  import React from 'react'
2
- import { FileCode, FileText, Package, Database, Cpu, ClipboardCheck, ArrowDownToLine } from 'lucide-react'
3
  import useAppStore from '../store/appStore'
4
  import { useGenerationAPI } from '../hooks/useGenerationAPI'
5
  import { useState } from 'react'
@@ -16,6 +16,24 @@ const FileViewer: React.FC = () => {
16
  } = useAppStore()
17
 
18
  const { getFileContent, downloadFile, downloadAll } = useGenerationAPI()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  const [copied, setCopied] = useState(false)
20
 
21
  const handleFileSelect = async (file: string) => {
@@ -131,15 +149,28 @@ const FileViewer: React.FC = () => {
131
  )}
132
  </div>
133
 
134
- {isComplete && taskId && (
135
- <button
136
- onClick={() => downloadAll(taskId)}
137
- className="flex items-center gap-1.5 text-xs text-eda-accent hover:text-eda-accent-hover transition-colors"
138
- >
139
- <ArrowDownToLine className="w-3.5 h-3.5" />
140
- Download ZIP
141
- </button>
142
- )}
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  </div>
144
 
145
  <div className="flex flex-1 overflow-hidden">
@@ -216,7 +247,16 @@ const FileViewer: React.FC = () => {
216
  </div>
217
  )}
218
 
219
- {renderCode()}
 
 
 
 
 
 
 
 
 
220
  </div>
221
  </div>
222
  </div>
 
1
  import React from 'react'
2
+ import { FileCode, FileText, Package, Database, Cpu, ClipboardCheck, ArrowDownToLine, BarChart3 } from 'lucide-react'
3
  import useAppStore from '../store/appStore'
4
  import { useGenerationAPI } from '../hooks/useGenerationAPI'
5
  import { useState } from 'react'
 
16
  } = useAppStore()
17
 
18
  const { getFileContent, downloadFile, downloadAll } = useGenerationAPI()
19
+ const [showDashboard, setShowDashboard] = useState(false)
20
+ const [dashboardHtml, setDashboardHtml] = useState<string | null>(null)
21
+
22
+ const loadDashboard = async () => {
23
+ if (!taskId) return
24
+ setShowDashboard(!showDashboard)
25
+ if (!showDashboard && !dashboardHtml) {
26
+ try {
27
+ const base = window.location.origin
28
+ const resp = await fetch(`${base}/api/generate/${taskId}/dashboard`)
29
+ if (resp.ok) {
30
+ setDashboardHtml(await resp.text())
31
+ }
32
+ } catch {
33
+ // ignore
34
+ }
35
+ }
36
+ }
37
  const [copied, setCopied] = useState(false)
38
 
39
  const handleFileSelect = async (file: string) => {
 
149
  )}
150
  </div>
151
 
152
+ <div className="flex items-center gap-2">
153
+ {isComplete && taskId && (
154
+ <>
155
+ <button
156
+ onClick={loadDashboard}
157
+ className={`flex items-center gap-1.5 text-xs transition-colors ${
158
+ showDashboard ? 'text-eda-accent' : 'text-eda-text-tertiary hover:text-eda-accent'
159
+ }`}
160
+ >
161
+ <BarChart3 className="w-3.5 h-3.5" />
162
+ Dashboard
163
+ </button>
164
+ <button
165
+ onClick={() => downloadAll(taskId)}
166
+ className="flex items-center gap-1.5 text-xs text-eda-accent hover:text-eda-accent-hover transition-colors"
167
+ >
168
+ <ArrowDownToLine className="w-3.5 h-3.5" />
169
+ Download ZIP
170
+ </button>
171
+ </>
172
+ )}
173
+ </div>
174
  </div>
175
 
176
  <div className="flex flex-1 overflow-hidden">
 
247
  </div>
248
  )}
249
 
250
+ {showDashboard && dashboardHtml ? (
251
+ <iframe
252
+ srcDoc={dashboardHtml}
253
+ className="w-full h-full border-0"
254
+ title="Coverage Dashboard"
255
+ sandbox="allow-scripts"
256
+ />
257
+ ) : (
258
+ renderCode()
259
+ )}
260
  </div>
261
  </div>
262
  </div>
src/config.py CHANGED
@@ -32,16 +32,18 @@ class InterfaceDef(BaseModel):
32
  name: str = "bus"
33
  signals: List[SignalDef] = Field(min_length=1)
34
  description: Optional[str] = None
 
 
 
 
 
35
  access: Optional[str] = None
36
  reset: Optional[str] = None
37
 
38
  @model_validator(mode="before")
39
  @classmethod
40
- def alias_width(cls, data):
41
  if isinstance(data, dict):
42
- if "width" in data and "bits" not in data:
43
- w = data.pop("width")
44
- data["bits"] = str(w) if isinstance(w, int) else w
45
  if "reset" in data and isinstance(data["reset"], (int, float)):
46
  val = int(data["reset"])
47
  data["reset"] = str(val) if val == 0 else f"'h{val:X}" if val > 9 else str(val)
 
32
  name: str = "bus"
33
  signals: List[SignalDef] = Field(min_length=1)
34
  description: Optional[str] = None
35
+
36
+ class FieldDef(BaseModel):
37
+ name: str
38
+ bits: str
39
+ description: Optional[str] = None
40
  access: Optional[str] = None
41
  reset: Optional[str] = None
42
 
43
  @model_validator(mode="before")
44
  @classmethod
45
+ def coerce_reset(cls, data):
46
  if isinstance(data, dict):
 
 
 
47
  if "reset" in data and isinstance(data["reset"], (int, float)):
48
  val = int(data["reset"])
49
  data["reset"] = str(val) if val == 0 else f"'h{val:X}" if val > 9 else str(val)