fix(schedules): filter auto-update policies from Scheduled Operations view (#420)

* fix(schedules): filter auto-update policies from Scheduled Operations view

Auto-update policies (action=update) were appearing in both the
Auto-Update tab and the Scheduled Operations tab. Added server-side
action/exclude_action query params to GET /api/scheduled-tasks.
ScheduledOperationsView now requests ?exclude_action=update and
AutoUpdatePoliciesView requests ?action=update, so each view only
shows its relevant tasks.

* fix(schedules): use typeof guard for query param type safety

Express can parse ?action[]=x as an array. Use typeof === 'string'
guard instead of unsafe type assertion.
This commit is contained in:
Anso
2026-04-07 01:49:22 -04:00
committed by GitHub
parent ca8f22734d
commit 455bfa8734
4 changed files with 12 additions and 4 deletions
+1
View File
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
* **auto-update:** resolve failure when executing auto-update policies on remote Distributed API nodes. Previously, the scheduler tried to access the remote Docker daemon directly, which is not supported. Now the update execution is proxied to the remote Sencho instance via HTTP, matching the existing Distributed API architecture.
* **schedules:** auto-update policies no longer appear in the Scheduled Operations list. Each view now fetches only its relevant task type via server-side action filtering.
## [0.39.6](https://github.com/AnsoCode/Sencho/compare/v0.39.5...v0.39.6) (2026-04-07)
+8
View File
@@ -4518,6 +4518,14 @@ app.get('/api/scheduled-tasks', (req: Request, res: Response): void => {
if (ls.getVariant() !== 'admiral') {
tasks = tasks.filter(t => t.action === 'update');
}
// Separate Auto-Update and Scheduled Operations into distinct views
const actionFilter = typeof req.query.action === 'string' ? req.query.action : undefined;
const excludeAction = typeof req.query.exclude_action === 'string' ? req.query.exclude_action : undefined;
if (actionFilter) {
tasks = tasks.filter(t => t.action === actionFilter);
} else if (excludeAction) {
tasks = tasks.filter(t => t.action !== excludeAction);
}
res.json(tasks);
} catch (error) {
console.error('[ScheduledTasks] List error:', error);
@@ -115,10 +115,9 @@ function AutoUpdatePoliciesContent({ filterNodeId, onClearFilter }: AutoUpdatePo
const fetchPolicies = useCallback(async () => {
setLoading(true);
try {
const res = await apiFetch('/scheduled-tasks', { localOnly: true });
const res = await apiFetch('/scheduled-tasks?action=update', { localOnly: true });
if (res.ok) {
const all: ScheduledTask[] = await res.json();
setPolicies(all.filter(t => t.action === 'update'));
setPolicies(await res.json());
}
} catch {
// Non-critical
@@ -118,7 +118,7 @@ export default function ScheduledOperationsView({ filterNodeId, onClearFilter }:
const fetchTasks = useCallback(async () => {
setLoading(true);
try {
const res = await apiFetch('/scheduled-tasks', { localOnly: true });
const res = await apiFetch('/scheduled-tasks?exclude_action=update', { localOnly: true });
if (res.ok) {
setTasks(await res.json());
}