feat(ui): Data Flow tab — live lineage graph + PII overlay + movement triggers
New DataFlowView (topology-style): nodes positioned from /api/dataflow with measured-anchor SVG edges and animated particles (active CDC + running movements). PII overlay shows shield badges + per-column detail inspector. Bottom strip triggers ETL movements and toggles the ETL agent. Wired into SideNav (Data Flow) and App routing; added types + api helpers.
This commit is contained in:
@@ -4,8 +4,11 @@ import type {
|
||||
Approval,
|
||||
CdcChange,
|
||||
CdcStats,
|
||||
DataflowGraph,
|
||||
FeedEntry,
|
||||
GpuStatus,
|
||||
Movement,
|
||||
PiiDataset,
|
||||
StatusData,
|
||||
TerminalLine,
|
||||
WorkloadData,
|
||||
@@ -129,6 +132,37 @@ export function runAgentOpOnce(source?: string, op?: string) {
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchDataflow(refresh = false): Promise<DataflowGraph | null> {
|
||||
return fetchJson<DataflowGraph>(`/api/dataflow${refresh ? '?refresh=true' : ''}`, 25000)
|
||||
}
|
||||
|
||||
export function runDataflowMovement(movementId: string, conf?: Record<string, unknown>) {
|
||||
return fetch(`/api/dataflow/${movementId}/run`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(conf ? { conf } : {}),
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchMovements(): Promise<Movement[]> {
|
||||
const j = await fetchJson<{ movements?: Movement[] }>('/api/movements', 8000)
|
||||
return j?.movements || []
|
||||
}
|
||||
|
||||
export async function fetchPii(refresh = false): Promise<{ datasets: PiiDataset[]; summary: Record<string, number> } | null> {
|
||||
return fetchJson<{ datasets: PiiDataset[]; summary: Record<string, number> }>(
|
||||
`/api/pii${refresh ? '?refresh=true' : ''}`, 15000,
|
||||
)
|
||||
}
|
||||
|
||||
export function toggleEtlAgent(enabled?: boolean) {
|
||||
return fetch('/api/agent-ops/etl/toggle', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(enabled === undefined ? {} : { enabled }),
|
||||
})
|
||||
}
|
||||
|
||||
export async function decideApproval(id: string, approved: boolean, decidedBy: string, note: string) {
|
||||
return fetch(`/api/approvals/${id}/decide`, {
|
||||
method: 'POST',
|
||||
|
||||
Reference in New Issue
Block a user