phase 3
This commit is contained in:
@@ -1,10 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, computed } from 'vue'
|
||||
import { ref, watch, computed, onMounted } from 'vue'
|
||||
import { Panel, GraphRenderer } from 'mpr-ui-framework'
|
||||
import type { GraphNode, GraphMode, DataSource } from 'mpr-ui-framework'
|
||||
import { usePipelineStore } from '../stores/pipeline'
|
||||
import { useStageRegistry } from '../composables/useStageRegistry'
|
||||
|
||||
interface PipelineConfigResponse {
|
||||
name: string
|
||||
profile_name: string
|
||||
stages: { name: string; branch: string; execution_target: string }[]
|
||||
edges: { source: string; target: string; condition: string }[]
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
source: DataSource
|
||||
status?: 'idle' | 'live' | 'processing' | 'error'
|
||||
@@ -14,6 +21,19 @@ const pipeline = usePipelineStore()
|
||||
const { stageNames, editableStages } = useStageRegistry()
|
||||
|
||||
const nodes = ref<GraphNode[]>([])
|
||||
const pipelineConfig = ref<PipelineConfigResponse | null>(null)
|
||||
|
||||
// Fetch pipeline config for a profile
|
||||
async function fetchPipelineConfig(profileName: string) {
|
||||
try {
|
||||
const resp = await fetch(`/api/detect/config/profiles/${profileName}/pipeline`)
|
||||
if (!resp.ok) return
|
||||
pipelineConfig.value = await resp.json()
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
// Load default profile config on mount
|
||||
onMounted(() => fetchPipelineConfig('soccer_broadcast'))
|
||||
|
||||
// Derive graph mode from pipeline layout mode
|
||||
const graphMode = computed<GraphMode>(() => {
|
||||
@@ -23,27 +43,20 @@ const graphMode = computed<GraphMode>(() => {
|
||||
return 'observe'
|
||||
})
|
||||
|
||||
// Initialize nodes from registry when it loads
|
||||
// Initialize nodes from pipeline config when it loads
|
||||
watch(pipelineConfig, (config) => {
|
||||
if (config && config.stages.length > 0 && nodes.value.length === 0) {
|
||||
nodes.value = config.stages.map((s) => ({ id: s.name, status: 'pending' }))
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
// Fallback: init from registry if no config loaded
|
||||
watch(stageNames, (names) => {
|
||||
if (names.length > 0 && nodes.value.length === 0) {
|
||||
nodes.value = names.map((id) => ({ id, status: 'pending' }))
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
// Source selector: placeholders until a chunk is selected, then real stage names
|
||||
const displayNodes = computed<GraphNode[]>(() => {
|
||||
if (pipeline.layoutMode === 'source_selector') {
|
||||
if (pipeline.sourceHasSelection) {
|
||||
return stageNames.value.map((id) => ({ id, status: 'pending' as const }))
|
||||
}
|
||||
return Array.from({ length: 10 }, (_, i) => ({
|
||||
id: `_placeholder_${i}`,
|
||||
status: 'placeholder' as const,
|
||||
}))
|
||||
}
|
||||
return nodes.value
|
||||
})
|
||||
|
||||
props.source.on<{ nodes: GraphNode[] }>('graph_update', (e) => {
|
||||
nodes.value = e.nodes
|
||||
})
|
||||
@@ -63,6 +76,25 @@ props.source.on<{ report?: { status?: string } }>('job_complete', (e) => {
|
||||
}
|
||||
})
|
||||
|
||||
// Source selector: placeholders until a chunk is selected, then real stage names
|
||||
const configStageNames = computed(() =>
|
||||
pipelineConfig.value?.stages.map(s => s.name) ?? stageNames.value
|
||||
)
|
||||
|
||||
const displayNodes = computed<GraphNode[]>(() => {
|
||||
if (pipeline.layoutMode === 'source_selector') {
|
||||
if (pipeline.sourceHasSelection) {
|
||||
return configStageNames.value.map((id) => ({ id, status: 'pending' as const }))
|
||||
}
|
||||
const count = configStageNames.value.length || 10
|
||||
return Array.from({ length: count }, (_, i) => ({
|
||||
id: `_placeholder_${i}`,
|
||||
status: 'placeholder' as const,
|
||||
}))
|
||||
}
|
||||
return nodes.value
|
||||
})
|
||||
|
||||
function onOpenRegionEditor(stage: string) {
|
||||
pipeline.openBBoxEditor(stage)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user