tangled
alpha
login
or
join now
nonbinary.computer
/
or1-design
0
fork
atom
OR-1 dataflow CPU sketch
0
fork
atom
overview
issues
pulls
pipelines
feat: add error panel display and parse error overlay
Orual
3 weeks ago
4520b798
6f0233b3
+117
-2
2 changed files
expand all
collapse all
unified
split
dfgraph
frontend
index.html
src
main.ts
+59
-2
dfgraph/frontend/index.html
···
11
11
#toolbar h1 { font-size: 14px; font-weight: 600; }
12
12
#view-toggle { padding: 6px 12px; background: #5c6bc0; color: #eee; border: none; border-radius: 4px; cursor: pointer; font-size: 12px; font-weight: 500; }
13
13
#view-toggle:hover { background: #3f51b5; }
14
14
-
#graph { flex: 1; }
14
14
+
#graph { flex: 1; position: relative; }
15
15
+
#error-panel {
16
16
+
max-height: 200px;
17
17
+
overflow-y: auto;
18
18
+
background: #1a1a2e;
19
19
+
border-top: 2px solid #e53935;
20
20
+
color: #eee;
21
21
+
font-family: monospace;
22
22
+
font-size: 12px;
23
23
+
display: none;
24
24
+
}
25
25
+
#error-panel.visible { display: block; }
26
26
+
#error-panel .error-header {
27
27
+
padding: 6px 16px;
28
28
+
background: #e53935;
29
29
+
color: #fff;
30
30
+
font-weight: 600;
31
31
+
cursor: pointer;
32
32
+
display: flex;
33
33
+
justify-content: space-between;
34
34
+
}
35
35
+
#error-panel .error-list { padding: 0; margin: 0; list-style: none; }
36
36
+
#error-panel .error-item {
37
37
+
padding: 4px 16px;
38
38
+
border-bottom: 1px solid rgba(255,255,255,0.05);
39
39
+
cursor: pointer;
40
40
+
}
41
41
+
#error-panel .error-item:hover { background: rgba(255,255,255,0.05); }
42
42
+
#error-panel .error-line { color: #ff9800; margin-right: 8px; }
43
43
+
#error-panel .error-category { color: #9e9e9e; margin-right: 8px; }
44
44
+
#error-panel .error-suggestion { color: #4caf50; font-style: italic; display: block; padding-left: 16px; }
45
45
+
#parse-error-overlay {
46
46
+
position: absolute;
47
47
+
top: 50%;
48
48
+
left: 50%;
49
49
+
transform: translate(-50%, -50%);
50
50
+
background: rgba(26, 26, 46, 0.95);
51
51
+
padding: 24px 32px;
52
52
+
border-radius: 8px;
53
53
+
border: 2px solid #e53935;
54
54
+
color: #eee;
55
55
+
font-family: monospace;
56
56
+
font-size: 13px;
57
57
+
max-width: 600px;
58
58
+
white-space: pre-wrap;
59
59
+
display: none;
60
60
+
z-index: 10;
61
61
+
}
62
62
+
#parse-error-overlay.visible { display: block; }
15
63
</style>
16
64
</head>
17
65
<body>
···
19
67
<h1>dfgraph</h1>
20
68
<button id="view-toggle">Physical View</button>
21
69
</div>
22
22
-
<div id="graph"></div>
70
70
+
<div id="graph">
71
71
+
<div id="parse-error-overlay" aria-live="polite"></div>
72
72
+
</div>
73
73
+
<div id="error-panel">
74
74
+
<div class="error-header">
75
75
+
<span id="error-count"></span>
76
76
+
<span>▼</span>
77
77
+
</div>
78
78
+
<ul class="error-list" id="error-list"></ul>
79
79
+
</div>
23
80
<script type="module" src="dist/bundle.js"></script>
24
81
</body>
25
82
</html>
+58
dfgraph/frontend/src/main.ts
···
153
153
return elements;
154
154
}
155
155
156
156
+
function updateErrorPanel(update: GraphUpdate): void {
157
157
+
const panel = document.getElementById("error-panel")!;
158
158
+
const list = document.getElementById("error-list")!;
159
159
+
const count = document.getElementById("error-count")!;
160
160
+
const overlay = document.getElementById("parse-error-overlay")!;
161
161
+
162
162
+
// Handle parse error (AC5.5)
163
163
+
if (update.parse_error) {
164
164
+
overlay.textContent = update.parse_error;
165
165
+
overlay.classList.add("visible");
166
166
+
panel.classList.remove("visible");
167
167
+
return;
168
168
+
}
169
169
+
overlay.classList.remove("visible");
170
170
+
171
171
+
// Handle pipeline errors
172
172
+
if (update.errors.length === 0) {
173
173
+
panel.classList.remove("visible");
174
174
+
list.innerHTML = "";
175
175
+
return;
176
176
+
}
177
177
+
178
178
+
count.textContent = `${update.errors.length} error${update.errors.length > 1 ? "s" : ""}`;
179
179
+
list.innerHTML = "";
180
180
+
181
181
+
for (const error of update.errors) {
182
182
+
const li = document.createElement("li");
183
183
+
li.className = "error-item";
184
184
+
li.innerHTML = `<span class="error-line">L${error.line}:${error.column}</span>`
185
185
+
+ `<span class="error-category">[${error.category}]</span>`
186
186
+
+ error.message;
187
187
+
188
188
+
if (error.suggestions.length > 0) {
189
189
+
for (const suggestion of error.suggestions) {
190
190
+
const span = document.createElement("span");
191
191
+
span.className = "error-suggestion";
192
192
+
span.textContent = `→ ${suggestion}`;
193
193
+
li.appendChild(span);
194
194
+
}
195
195
+
}
196
196
+
197
197
+
li.addEventListener("click", () => {
198
198
+
// Highlight related nodes in the graph
199
199
+
cy.nodes().unselect();
200
200
+
cy.nodes().forEach((node) => {
201
201
+
if (node.hasClass("error")) {
202
202
+
node.select();
203
203
+
}
204
204
+
});
205
205
+
});
206
206
+
207
207
+
list.appendChild(li);
208
208
+
}
209
209
+
210
210
+
panel.classList.add("visible");
211
211
+
}
212
212
+
156
213
type ViewMode = "logical" | "physical";
157
214
let currentView: ViewMode = "logical";
158
215
let latestUpdate: GraphUpdate | null = null;
···
189
246
} else {
190
247
renderPhysical(update);
191
248
}
249
249
+
updateErrorPanel(update);
192
250
}
193
251
194
252
function setupToggleButton(): void {