phase 5
This commit is contained in:
@@ -11,3 +11,4 @@ export { default as LayoutGrid } from './components/LayoutGrid.vue'
|
||||
// Renderers
|
||||
export { default as LogRenderer } from './renderers/LogRenderer.vue'
|
||||
export { default as TimeSeriesRenderer } from './renderers/TimeSeriesRenderer.vue'
|
||||
export { default as GraphRenderer } from './renderers/GraphRenderer.vue'
|
||||
|
||||
80
ui/framework/src/renderers/GraphRenderer.vue
Normal file
80
ui/framework/src/renderers/GraphRenderer.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { VueFlow } from '@vue-flow/core'
|
||||
import '@vue-flow/core/dist/style.css'
|
||||
import '@vue-flow/core/dist/theme-default.css'
|
||||
|
||||
export interface GraphNode {
|
||||
id: string
|
||||
status: 'pending' | 'running' | 'done' | 'error'
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
nodes: GraphNode[]
|
||||
}>()
|
||||
|
||||
const statusColors: Record<string, string> = {
|
||||
pending: 'var(--status-idle)',
|
||||
running: 'var(--status-processing)',
|
||||
done: 'var(--status-live)',
|
||||
error: 'var(--status-error)',
|
||||
}
|
||||
|
||||
const flowNodes = computed(() =>
|
||||
props.nodes.map((n, i) => ({
|
||||
id: n.id,
|
||||
label: n.id.replace(/_/g, ' '),
|
||||
position: { x: 20, y: i * 70 },
|
||||
style: {
|
||||
background: statusColors[n.status] ?? statusColors.pending,
|
||||
color: n.status === 'pending' ? '#ccc' : '#000',
|
||||
border: 'none',
|
||||
borderRadius: 'var(--panel-radius)',
|
||||
fontFamily: 'var(--font-mono)',
|
||||
fontSize: 'var(--font-size-sm)',
|
||||
fontWeight: '600',
|
||||
padding: '8px 16px',
|
||||
},
|
||||
}))
|
||||
)
|
||||
|
||||
const flowEdges = computed(() => {
|
||||
const edges = []
|
||||
for (let i = 0; i < props.nodes.length - 1; i++) {
|
||||
edges.push({
|
||||
id: `${props.nodes[i].id}->${props.nodes[i + 1].id}`,
|
||||
source: props.nodes[i].id,
|
||||
target: props.nodes[i + 1].id,
|
||||
animated: props.nodes[i].status === 'running',
|
||||
style: { stroke: '#555568' },
|
||||
})
|
||||
}
|
||||
return edges
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="graph-renderer">
|
||||
<VueFlow
|
||||
:nodes="flowNodes"
|
||||
:edges="flowEdges"
|
||||
:fit-view-on-init="true"
|
||||
:nodes-draggable="false"
|
||||
:nodes-connectable="false"
|
||||
:zoom-on-scroll="false"
|
||||
:pan-on-scroll="false"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.graph-renderer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.graph-renderer :deep(.vue-flow__background) {
|
||||
background: transparent;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user