feat(web): live SSE log tail and log retention setting
Server Deploy / deploy (push) Successful in 1m35s

This commit is contained in:
2026-07-20 15:18:36 +01:00
parent 63dadf6239
commit 39348c9491
3 changed files with 112 additions and 23 deletions
+33 -2
View File
@@ -168,6 +168,9 @@ export default function SettingsPage() {
const [toAddrs, setToAddrs] = useState(""); // comma-separated in UI
const [useTLS, setUseTLS] = useState(false);
// Workflow log retention (days). 0 = keep forever.
const [logRetentionDays, setLogRetentionDays] = useState(30);
const [saved, setSaved] = useState(false);
useEffect(() => {
@@ -183,11 +186,15 @@ export default function SettingsPage() {
setFromAddr(settings.email?.from_addr ?? "");
setToAddrs((settings.email?.to_addrs ?? []).join(", "));
setUseTLS(settings.email?.use_tls ?? false);
setLogRetentionDays(settings.workflow_log_retention_days ?? 30);
}, [settings]);
const { mutate: save, isPending } = useMutation({
mutationFn: (payload: { alerts: AlertSettings; email: EmailSettings }) =>
api.saveSettings(payload),
mutationFn: (payload: {
alerts: AlertSettings;
email: EmailSettings;
workflow_log_retention_days?: number | null;
}) => api.saveSettings(payload),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["settings"] });
setSaved(true);
@@ -218,6 +225,7 @@ export default function SettingsPage() {
to_addrs: toList,
use_tls: useTLS,
},
workflow_log_retention_days: logRetentionDays,
});
}
@@ -374,6 +382,29 @@ export default function SettingsPage() {
</div>
</Card>
{/* Workflow logs */}
<Card>
<CardHeader>
<CardTitle>Workflow Logs</CardTitle>
</CardHeader>
<p className="mb-5 text-sm text-text-secondary">
How long to keep workflow run logs on the server before they are
automatically deleted.
</p>
<Field
label="Log retention (days)"
hint="0 = keep forever. Applies to per-run step output logs."
>
<input
type="number"
min={0}
value={logRetentionDays}
onChange={(e) => setLogRetentionDays(Number(e.target.value))}
className="w-32 rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary focus:border-accent/50 focus:outline-none focus:ring-1 focus:ring-accent/30"
/>
</Field>
</Card>
<div className="flex items-center gap-3">
<Button type="submit" variant="primary" loading={isPending}>
{saved ? "Saved!" : "Save Settings"}