[eric] workflows: header counted 0 over a real workflow, monitor claimed a schedule while paused, restore lost run history

This commit is contained in:
ciregenz
2026-07-31 21:32:52 -07:00
parent 05132c7ace
commit 37ba03316c
3 changed files with 11 additions and 5 deletions
@@ -31,8 +31,6 @@ const LeftRail: React.FC<{ nav: AppNav }> = ({ nav }) => {
return workflows.filter((w) => w.title.toLowerCase().includes(q));
}, [workflows, query]);
const activeCount = workflows.filter((w) => isScheduleActive(w.schedule)).length;
const onDelete = (id: string) => {
// Soft-delete: moves to Trash (recoverable), so no scary confirm.
dispatch(deleteWorkflow(id));
@@ -84,7 +82,8 @@ const LeftRail: React.FC<{ nav: AppNav }> = ({ nav }) => {
<div style={{ padding: '14px 16px 6px', flex: 'none', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<span style={{ fontFamily: "'JetBrains Mono',monospace", fontSize: 10.5, letterSpacing: '0.08em', textTransform: 'uppercase', color: WC.muted2 }}>Workflows</span>
<span style={{ fontFamily: "'JetBrains Mono',monospace", fontSize: 10.5, color: WC.muted2 }}>{activeCount}</span>
{/* Counts what the list below is actually showing. It used to count only the scheduled ones, so a real workflow sat under a header that said 0. */}
<span style={{ fontFamily: "'JetBrains Mono',monospace", fontSize: 10.5, color: WC.muted2 }}>{filtered.length}</span>
</div>
<div style={{ flex: 1, overflowY: 'auto', padding: '0 8px', minHeight: 0 }}>
@@ -11,6 +11,7 @@ import {
} from '@/shared/state/dashboardLayoutSlice';
import type { CardType } from '@/shared/state/dashboardLayoutSlice';
import WorkflowTitle from './WorkflowTitle';
import { isScheduleActive } from '@/app/pages/Workflows/scheduleUtils';
const DRAG_THRESHOLD = 3;
@@ -231,7 +232,10 @@ const RunMonitor: React.FC<Props> = ({ workflow, cardX, cardY, cardWidth, cardHe
<div style={{ flex: 1, minHeight: 0, overflow: 'auto', padding: '16px 18px', display: 'flex', flexDirection: 'column', gap: 16 }}>
<div>
<div style={{ fontSize: 10.5, fontWeight: 700, letterSpacing: '0.07em', textTransform: 'uppercase', color: c.text.tertiary, marginBottom: 6 }}>Schedule</div>
<div style={{ fontSize: 14, fontWeight: 600, color: c.text.primary }}>{formatSchedule(workflow.schedule)}</div>
{/* A paused workflow fell through formatSchedule to "Scheduled for 9:00 AM", so this card announced a schedule while the panel beside it said Not scheduled. */}
<div style={{ fontSize: 14, fontWeight: 600, color: c.text.primary }}>
{isScheduleActive(workflow.schedule) ? formatSchedule(workflow.schedule) : 'Not scheduled'}
</div>
{workflow.next_run_at && (
<div style={{ fontSize: 12, color: c.text.tertiary, marginTop: 3 }}>
Next run {new Date(workflow.next_run_at).toLocaleString([], { weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' })}
+4 -1
View File
@@ -414,9 +414,12 @@ export const fetchDeletedWorkflows = createAsyncThunk('workflows/fetchDeleted',
return data.workflows as Workflow[];
});
export const restoreWorkflow = createAsyncThunk('workflows/restore', async (id: string) => {
export const restoreWorkflow = createAsyncThunk('workflows/restore', async (id: string, { dispatch }) => {
const res = await fetch(`${API}/${id}/restore`, { method: 'POST' });
if (!res.ok) throw new Error(`restore failed ${res.status}`);
// Trashing drops the run rows from the store; the server kept them, so pull them back or a restored workflow claims "No runs yet" over a real history.
void dispatch(fetchRuns(id));
void dispatch(fetchAllRuns(200));
return (await res.json()) as Workflow;
});