This commit is contained in:
2026-03-23 19:10:55 -03:00
parent 3df9ed5ada
commit 95246c5452
23 changed files with 1361 additions and 107 deletions

View File

@@ -6,6 +6,7 @@ import LogPanel from './panels/LogPanel.vue'
import FunnelPanel from './panels/FunnelPanel.vue'
import PipelineGraphPanel from './panels/PipelineGraphPanel.vue'
import FramePanel from './panels/FramePanel.vue'
import BrandTablePanel from './panels/BrandTablePanel.vue'
import type { StatsUpdate } from './types/sse-contract'
const jobId = ref(new URLSearchParams(window.location.search).get('job') || 'test-job')
@@ -42,7 +43,7 @@ source.connect()
<span class="job-id">job: {{ jobId }}</span>
</header>
<LayoutGrid :columns="3" :rows="2" gap="var(--space-2)">
<LayoutGrid :columns="3" :rows="3" gap="var(--space-2)">
<Panel title="Stats" :status="status">
<div class="stats" v-if="stats">
<div class="stat" v-for="s in [
@@ -66,6 +67,8 @@ source.connect()
<PipelineGraphPanel :source="source" :status="status" />
<BrandTablePanel :source="source" :status="status" />
<LogPanel :source="source" :status="status" />
</LayoutGrid>
</div>

View File

@@ -0,0 +1,57 @@
<script setup lang="ts">
import { ref } from 'vue'
import { Panel } from 'mpr-ui-framework'
import TableRenderer from 'mpr-ui-framework/src/renderers/TableRenderer.vue'
import type { TableColumn } from 'mpr-ui-framework/src/renderers/TableRenderer.vue'
import type { DataSource } from 'mpr-ui-framework'
const props = defineProps<{
source: DataSource
status?: 'idle' | 'live' | 'processing' | 'error'
}>()
const columns: TableColumn[] = [
{ key: 'brand', label: 'Brand', width: '120px' },
{ key: 'confidence', label: 'Conf', width: '60px' },
{ key: 'source', label: 'Source', width: '80px' },
{ key: 'timestamp', label: 'Time', width: '60px' },
{ key: 'content_type', label: 'Type', width: '100px' },
{ key: 'frame_ref', label: 'Frame', width: '50px' },
]
const rows = ref<Record<string, unknown>[]>([])
const sortKey = ref('timestamp')
const sortDir = ref<'asc' | 'desc'>('desc')
props.source.on<Record<string, unknown>>('detection', (e) => {
rows.value.push({
brand: e.brand,
confidence: typeof e.confidence === 'number' ? (e.confidence as number).toFixed(2) : e.confidence,
source: e.source,
timestamp: typeof e.timestamp === 'number' ? (e.timestamp as number).toFixed(1) : e.timestamp,
content_type: e.content_type,
frame_ref: e.frame_ref,
})
})
function onSort(key: string) {
if (sortKey.value === key) {
sortDir.value = sortDir.value === 'asc' ? 'desc' : 'asc'
} else {
sortKey.value = key
sortDir.value = 'desc'
}
}
</script>
<template>
<Panel title="Detections" :status="status">
<TableRenderer
:columns="columns"
:rows="rows"
:sort-key="sortKey"
:sort-dir="sortDir"
@sort="onSort"
/>
</Panel>
</template>