From bfb8e45750864e346d79eb78ab59b40ee7b055db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=C3=A1nchez?= Date: Sat, 22 Aug 2026 15:33:33 -0600 Subject: [PATCH 1/2] feat[frontend](soar/executions): add origin, agent-source, and time-range filters --- .../soar/components/ExecutionsView.tsx | 67 +++++++++++++++++-- frontend/src/shared/i18n/locales/en.json | 8 +++ 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/frontend/src/features/soar/components/ExecutionsView.tsx b/frontend/src/features/soar/components/ExecutionsView.tsx index 7c3e93025..3dd642fd1 100644 --- a/frontend/src/features/soar/components/ExecutionsView.tsx +++ b/frontend/src/features/soar/components/ExecutionsView.tsx @@ -5,11 +5,14 @@ import { cn } from '@/shared/lib/utils' import { Button } from '@/shared/components/ui/button' import { Input } from '@/shared/components/ui/input' import { InfiniteScrollSentinel } from '@/shared/components/ui/infinite-scroll' +import { presetRange, resolveRange, TimeRangePicker, type TimeRange } from '@/shared/components/ui/time-range-picker' import { useDateFormat } from '@/shared/lib/datetime' +import { datasourcesHttpService } from '@/features/datasources/services/datasources-http.service' import { soarExecutionsService } from '../services/soar-executions.service' -import type { Execution, ExecutionStatus, ExecutionListQuery } from '../types/soar.types' +import type { Execution, ExecutionOrigin, ExecutionStatus, ExecutionListQuery } from '../types/soar.types' const STATUSES: (ExecutionStatus | 'all')[] = ['all', 'EXECUTED', 'PENDING', 'FAILED'] +const ORIGINS: (ExecutionOrigin | 'all')[] = ['all', 'FLOW', 'MANUAL'] const COLS = '90px minmax(160px,1.2fr) minmax(180px,1.6fr) 120px 150px 60px' const STATUS_META: Record = { @@ -24,6 +27,10 @@ export function ExecutionsView() { const [search, setSearch] = useState('') const [debounced, setDebounced] = useState('') const [status, setStatus] = useState('all') + const [origin, setOrigin] = useState('FLOW') + const [agent, setAgent] = useState('') + const [agents, setAgents] = useState([]) + const [range, setRange] = useState(presetRange('7d')) const [items, setItems] = useState([]) const [total, setTotal] = useState(0) const [page, setPage] = useState(0) @@ -39,15 +46,27 @@ export function ExecutionsView() { return () => clearTimeout(h) }, [search]) - const query = useMemo( - () => ({ + // Same source as FlowEditor / InteractiveConsole — Execution.agent stores the datasource name. + useEffect(() => { + datasourcesHttpService + .list({ page: 1, size: 1000, kind: 'agent', sort: 'asset_name.asc' }) + .then((r) => setAgents((r.items ?? []).map((d) => d.name).filter(Boolean))) + .catch(() => {}) + }, []) + + const query = useMemo(() => { + const { from, to } = resolveRange(range) + return { alertId: debounced || undefined, status: status === 'all' ? undefined : status, + origin: origin === 'all' ? undefined : origin, + agent: agent || undefined, + startedAtFrom: from ?? undefined, + startedAtTo: to, page, size: pageSize, - }), - [debounced, status, page, pageSize], - ) + } + }, [debounced, status, origin, agent, range, page, pageSize]) const load = useCallback(() => { setLoading(true) @@ -86,6 +105,42 @@ export function ExecutionsView() { ))} +
+ {ORIGINS.map((o) => ( + + ))} +
+ + { + setRange(r) + setPage(0) + }} + align="right" + /> diff --git a/frontend/src/shared/i18n/locales/en.json b/frontend/src/shared/i18n/locales/en.json index 0d0080a8f..d5bf3a2a5 100644 --- a/frontend/src/shared/i18n/locales/en.json +++ b/frontend/src/shared/i18n/locales/en.json @@ -5134,6 +5134,10 @@ "date": "Date", "retries": "Retries" }, + "filters": { + "source": "Source", + "allSources": "All sources" + }, "manual": "Interactive console" }, "executionStatus": { @@ -5141,6 +5145,10 @@ "PENDING": "Pending", "FAILED": "Failed" }, + "executionOrigin": { + "FLOW": "Flow", + "MANUAL": "Manual" + }, "nonExecutionCause": { "AGENT_OFFLINE": "Agent offline", "AGENT_NOT_FOUND": "Agent not found", From 15bbaa04a74f3a9563291c331a85e9031290b371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=C3=A1nchez?= Date: Sat, 22 Aug 2026 15:36:00 -0600 Subject: [PATCH 2/2] fix[frontend](soar): added all language origin filters --- frontend/src/shared/i18n/locales/es.json | 8 ++++++++ frontend/src/shared/i18n/locales/fr.json | 8 ++++++++ frontend/src/shared/i18n/locales/it.json | 8 ++++++++ frontend/src/shared/i18n/locales/pt.json | 8 ++++++++ 4 files changed, 32 insertions(+) diff --git a/frontend/src/shared/i18n/locales/es.json b/frontend/src/shared/i18n/locales/es.json index 56f684205..c40a19dfc 100644 --- a/frontend/src/shared/i18n/locales/es.json +++ b/frontend/src/shared/i18n/locales/es.json @@ -4870,6 +4870,10 @@ "date": "Fecha", "retries": "Reintentos" }, + "filters": { + "source": "Origen", + "allSources": "Todos los orígenes" + }, "manual": "Consola interactiva" }, "executionStatus": { @@ -4877,6 +4881,10 @@ "PENDING": "Pendiente", "FAILED": "Fallido" }, + "executionOrigin": { + "FLOW": "Flujo", + "MANUAL": "Manual" + }, "nonExecutionCause": { "AGENT_OFFLINE": "Agente offline", "AGENT_NOT_FOUND": "Agente no encontrado", diff --git a/frontend/src/shared/i18n/locales/fr.json b/frontend/src/shared/i18n/locales/fr.json index 9b1fbc506..38647fbb9 100644 --- a/frontend/src/shared/i18n/locales/fr.json +++ b/frontend/src/shared/i18n/locales/fr.json @@ -4748,6 +4748,10 @@ "date": "Date", "retries": "Tentatives" }, + "filters": { + "source": "Source", + "allSources": "Toutes les sources" + }, "manual": "Console interactive" }, "executionStatus": { @@ -4755,6 +4759,10 @@ "PENDING": "En attente", "FAILED": "Échoué" }, + "executionOrigin": { + "FLOW": "Flux", + "MANUAL": "Manuel" + }, "nonExecutionCause": { "AGENT_OFFLINE": "Agent hors ligne", "AGENT_NOT_FOUND": "Agent introuvable", diff --git a/frontend/src/shared/i18n/locales/it.json b/frontend/src/shared/i18n/locales/it.json index 81c8b5245..9be24f67b 100644 --- a/frontend/src/shared/i18n/locales/it.json +++ b/frontend/src/shared/i18n/locales/it.json @@ -4748,6 +4748,10 @@ "date": "Data", "retries": "Tentativi" }, + "filters": { + "source": "Origine", + "allSources": "Tutte le origini" + }, "manual": "Console interattiva" }, "executionStatus": { @@ -4755,6 +4759,10 @@ "PENDING": "In attesa", "FAILED": "Fallito" }, + "executionOrigin": { + "FLOW": "Flusso", + "MANUAL": "Manuale" + }, "nonExecutionCause": { "AGENT_OFFLINE": "Agente offline", "AGENT_NOT_FOUND": "Agente non trovato", diff --git a/frontend/src/shared/i18n/locales/pt.json b/frontend/src/shared/i18n/locales/pt.json index bb569677c..fbdb6e871 100644 --- a/frontend/src/shared/i18n/locales/pt.json +++ b/frontend/src/shared/i18n/locales/pt.json @@ -4870,6 +4870,10 @@ "date": "Data", "retries": "Tentativas" }, + "filters": { + "source": "Origem", + "allSources": "Todas as origens" + }, "manual": "Consola interativa" }, "executionStatus": { @@ -4877,6 +4881,10 @@ "PENDING": "Pendente", "FAILED": "Falhou" }, + "executionOrigin": { + "FLOW": "Fluxo", + "MANUAL": "Manual" + }, "nonExecutionCause": { "AGENT_OFFLINE": "Agente offline", "AGENT_NOT_FOUND": "Agente não encontrado",