From 513632ce3b47d0c7e46dc58d83c3703b63fd32a3 Mon Sep 17 00:00:00 2001 From: Peter Wielander Date: Fri, 24 Oct 2025 13:23:05 -0700 Subject: [PATCH 01/12] Sort by status --- packages/web/src/components/runs-table.tsx | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/packages/web/src/components/runs-table.tsx b/packages/web/src/components/runs-table.tsx index 3e6939e41..42779d194 100644 --- a/packages/web/src/components/runs-table.tsx +++ b/packages/web/src/components/runs-table.tsx @@ -1,6 +1,7 @@ 'use client'; import { parseWorkflowName } from '@workflow/core/parse-name'; +import type { WorkflowRunStatus } from '@workflow/world'; import { AlertCircle, ArrowDownAZ, @@ -13,6 +14,13 @@ import { useMemo, useState } from 'react'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { Button } from '@/components/ui/button'; import { DocsLink } from '@/components/ui/docs-link'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select'; import { Table, TableBody, @@ -49,6 +57,9 @@ interface RunsTableProps { */ export function RunsTable({ config, onRunClick }: RunsTableProps) { const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc'); + const [statusFilter, setStatusFilter] = useState( + 'any' + ); const [lastRefreshTime, setLastRefreshTime] = useState( () => new Date() ); @@ -65,6 +76,7 @@ export function RunsTable({ config, onRunClick }: RunsTableProps) { pageInfo, } = useWorkflowRuns(env, { sortOrder, + status: statusFilter === 'any' ? undefined : statusFilter, }); const loading = data.isLoading; @@ -99,6 +111,31 @@ export function RunsTable({ config, onRunClick }: RunsTableProps) { type="distance" /> )} + +
+ +
- Note that this resets pages + + {workflowNameFilter === 'any' + ? 'Select a workflow first to filter by status' + : 'Filter runs by status'} +
@@ -172,6 +216,20 @@ export function RunsTable({ config, onRunClick }: RunsTableProps) { : 'Showing oldest first'} + + + + + Note that this resets pages + } From 24c8b83df6c705768b40798eb71c98b5526383f9 Mon Sep 17 00:00:00 2001 From: Peter Wielander Date: Fri, 24 Oct 2025 13:45:32 -0700 Subject: [PATCH 03/12] Changeset --- .changeset/wide-wombats-own.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wide-wombats-own.md diff --git a/.changeset/wide-wombats-own.md b/.changeset/wide-wombats-own.md new file mode 100644 index 000000000..5eabc80f6 --- /dev/null +++ b/.changeset/wide-wombats-own.md @@ -0,0 +1,5 @@ +--- +"@workflow/web": patch +--- + +Web: Allow filtering by workflow name and status on the runs list view From d7c89f73bdc49d57221c2d961a6e646677c9dc5a Mon Sep 17 00:00:00 2001 From: Garrett Tolbert Date: Fri, 24 Oct 2025 15:46:37 -0500 Subject: [PATCH 04/12] updated the select --- packages/web/src/components/runs-table.tsx | 85 ++++++++++++++++------ 1 file changed, 63 insertions(+), 22 deletions(-) diff --git a/packages/web/src/components/runs-table.tsx b/packages/web/src/components/runs-table.tsx index 42779d194..5c90d1e66 100644 --- a/packages/web/src/components/runs-table.tsx +++ b/packages/web/src/components/runs-table.tsx @@ -10,7 +10,8 @@ import { ChevronRight, RefreshCw, } from 'lucide-react'; -import { useMemo, useState } from 'react'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { useCallback, useMemo, useState } from 'react'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { Button } from '@/components/ui/button'; import { DocsLink } from '@/components/ui/docs-link'; @@ -56,10 +57,11 @@ interface RunsTableProps { * which fetches all data upfront and paginates client-side. */ export function RunsTable({ config, onRunClick }: RunsTableProps) { + const router = useRouter(); + const pathname = usePathname(); + const searchParams = useSearchParams(); + const status = searchParams.get('status') as WorkflowRunStatus | undefined; const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc'); - const [statusFilter, setStatusFilter] = useState( - 'any' - ); const [lastRefreshTime, setLastRefreshTime] = useState( () => new Date() ); @@ -74,10 +76,7 @@ export function RunsTable({ config, onRunClick }: RunsTableProps) { hasPreviousPage, reload, pageInfo, - } = useWorkflowRuns(env, { - sortOrder, - status: statusFilter === 'any' ? undefined : statusFilter, - }); + } = useWorkflowRuns(env, { sortOrder, status }); const loading = data.isLoading; @@ -90,6 +89,16 @@ export function RunsTable({ config, onRunClick }: RunsTableProps) { setSortOrder((prev) => (prev === 'desc' ? 'asc' : 'desc')); }; + const createQueryString = useCallback( + (name: string, value: string) => { + const params = new URLSearchParams(searchParams.toString()); + params.set(name, value); + + return params.toString(); + }, + [searchParams] + ); + // Show skeleton for initial load if (loading && !data?.data) { return ; @@ -112,26 +121,33 @@ export function RunsTable({ config, onRunClick }: RunsTableProps) { /> )} { if (value === 'all') { const params = new URLSearchParams( @@ -214,16 +214,18 @@ export function RunsTable({ config, onRunClick }: RunsTableProps) { All - {Object.values(statusMap).map(({ label, color }) => ( - -
- - {label} -
-
- ))} + {Object.entries(statusMap).map( + ([status, { label, color }]) => ( + +
+ + {label} +
+
+ ) + )}
From 1921670e563dcc5df283aed6219b2494796d559c Mon Sep 17 00:00:00 2001 From: Garrett Tolbert Date: Fri, 24 Oct 2025 16:34:19 -0500 Subject: [PATCH 08/12] move workflowFilterName to url --- packages/web/src/components/runs-table.tsx | 27 +++++++++++++--------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/web/src/components/runs-table.tsx b/packages/web/src/components/runs-table.tsx index 7ba692ec1..aed35dc53 100644 --- a/packages/web/src/components/runs-table.tsx +++ b/packages/web/src/components/runs-table.tsx @@ -73,8 +73,8 @@ export function RunsTable({ config, onRunClick }: RunsTableProps) { | WorkflowRunStatus | 'all' | undefined; + const workflowNameFilter = searchParams.get('workflow') as string | 'all'; const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc'); - const [workflowNameFilter, setWorkflowNameFilter] = useState('any'); // TODO: This is a workaround. We should be getting a list of valid workflow names // from the manifest, which we need to put on the World interface. @@ -100,7 +100,7 @@ export function RunsTable({ config, onRunClick }: RunsTableProps) { pageInfo, } = useWorkflowRuns(env, { sortOrder, - workflowName: workflowNameFilter === 'any' ? undefined : workflowNameFilter, + workflowName: workflowNameFilter === 'all' ? undefined : workflowNameFilter, status: status === 'all' ? undefined : status, }); @@ -161,13 +161,18 @@ export function RunsTable({ config, onRunClick }: RunsTableProps) { { <>