Skip to content

Commit e673bd3

Browse files
committed
feat: final tweaks v2
1 parent cd742df commit e673bd3

File tree

10 files changed

+327
-134
lines changed

10 files changed

+327
-134
lines changed

apps/demo/src/lib/components/CodePanel.svelte

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@
8888
return null;
8989
}
9090
91-
// Only show indicators for started and completed
92-
if (status === 'started' || status === 'completed') {
91+
// Show indicators for started, completed, and failed
92+
if (status === 'started' || status === 'completed' || status === 'failed') {
9393
return status;
9494
}
9595
@@ -464,6 +464,10 @@
464464
background: #3b82f6; /* Blue */
465465
}
466466
467+
.section-status-border.status-failed {
468+
background: #ef4444; /* Red */
469+
}
470+
467471
/* Pulse dot container - centers the dot */
468472
.pulse-dot-container {
469473
position: absolute;
@@ -624,6 +628,10 @@
624628
background: #3b82f6; /* Blue */
625629
}
626630
631+
.step-status-border.status-failed {
632+
background: #ef4444; /* Red */
633+
}
634+
627635
.step-status-border.status-dimmed {
628636
opacity: 0.3;
629637
}

apps/demo/src/lib/components/DAGVisualization.svelte

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@
194194
return '';
195195
}
196196
197+
// Define the actual DAG step slugs
198+
const DAG_STEPS = ['fetchArticle', 'summarize', 'extractKeywords', 'publish'];
199+
197200
function getNodeClass(stepSlug: string): string {
198201
const classes = ['dag-node'];
199202
@@ -207,8 +210,9 @@
207210
classes.push('node-created');
208211
}
209212
210-
// Dimming: dim nodes that aren't selected when something is selected
211-
if (selectedStep && stepSlug !== selectedStep) {
213+
// Dimming: Only dim nodes when a DAG step is selected (not flow_config)
214+
// If selectedStep is not a DAG step, don't dim anything
215+
if (selectedStep && DAG_STEPS.includes(selectedStep) && stepSlug !== selectedStep) {
212216
classes.push('node-dimmed');
213217
}
214218

apps/demo/src/lib/components/EventsPanel.svelte

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script lang="ts">
22
import type { createFlowState } from '$lib/stores/pgflow-state.svelte';
33
import { Card, CardContent, CardHeader, CardTitle } from '$lib/components/ui/card';
4-
import { Play, CheckCircle2 } from '@lucide/svelte';
4+
import { Play, CheckCircle2, XCircle } from '@lucide/svelte';
55
import { codeToHtml } from 'shiki';
66
77
interface Props {
@@ -12,6 +12,21 @@
1212
1313
let expandedEventIdx = $state<number | null>(null);
1414
let highlightedEventJson = $state<Record<number, string>>({});
15+
let isMobile = $state(false);
16+
17+
// Detect mobile viewport
18+
if (typeof window !== 'undefined') {
19+
const mediaQuery = window.matchMedia('(max-width: 767px)');
20+
isMobile = mediaQuery.matches;
21+
22+
const updateMobile = (e: MediaQueryListEvent) => {
23+
isMobile = e.matches;
24+
// Clear cache when switching to force regeneration with new truncation
25+
highlightedEventJson = {};
26+
};
27+
28+
mediaQuery.addEventListener('change', updateMobile);
29+
}
1530
1631
// Helper to get short step name
1732
function getShortStepName(stepSlug: string): string {
@@ -26,7 +41,7 @@
2641
2742
// Helper to get event badge info
2843
function getEventBadgeInfo(event: { event_type: string; step_slug?: string }): {
29-
icon: typeof Play | typeof CheckCircle2;
44+
icon: typeof Play | typeof CheckCircle2 | typeof XCircle;
3045
color: string;
3146
text: string;
3247
} | null {
@@ -44,10 +59,17 @@
4459
text: getShortStepName(event.step_slug)
4560
};
4661
}
62+
if (event.event_type === 'step:failed' && event.step_slug) {
63+
return {
64+
icon: XCircle,
65+
color: 'red',
66+
text: getShortStepName(event.step_slug)
67+
};
68+
}
4769
return null;
4870
}
4971
50-
// Get displayable events (started/completed steps only)
72+
// Get displayable events (started/completed/failed steps only)
5173
const displayableEvents = $derived(
5274
flowState.timeline
5375
.map((e, idx) => ({ event: e, badge: getEventBadgeInfo(e), idx }))
@@ -81,7 +103,9 @@
81103
} else {
82104
// Generate syntax-highlighted JSON if not already cached
83105
if (!highlightedEventJson[idx]) {
84-
const truncated = truncateDeep(event);
106+
// Mobile: 50 chars, Desktop: 500 chars
107+
const maxLength = isMobile ? 50 : 500;
108+
const truncated = truncateDeep(event, maxLength);
85109
const jsonString = JSON.stringify(truncated, null, 2);
86110
const html = await codeToHtml(jsonString, {
87111
lang: 'json',
@@ -93,6 +117,19 @@
93117
expandedEventIdx = idx;
94118
}
95119
}
120+
121+
// Auto-expand failed events
122+
$effect(() => {
123+
// Find the most recent failed event
124+
const failedEvents = displayableEvents.filter((e) => e.event.event_type === 'step:failed');
125+
if (failedEvents.length > 0) {
126+
const mostRecentFailed = failedEvents[failedEvents.length - 1];
127+
// Auto-expand it
128+
if (expandedEventIdx !== mostRecentFailed.idx) {
129+
toggleEventExpanded(mostRecentFailed.idx, mostRecentFailed.event);
130+
}
131+
}
132+
});
96133
</script>
97134

98135
<Card class="h-full flex flex-col">
@@ -166,6 +203,12 @@
166203
color: #2ec184;
167204
}
168205
206+
.event-badge-row.event-badge-red {
207+
background-color: rgba(220, 38, 38, 0.2);
208+
border-color: rgba(239, 68, 68, 0.5);
209+
color: #f87171;
210+
}
211+
169212
/* Event JSON display */
170213
.event-json-display {
171214
max-height: 300px;

0 commit comments

Comments
 (0)