From efbd20fed57299acae43ecaee3b1d9ff52da5aae Mon Sep 17 00:00:00 2001 From: Anso Date: Thu, 2 Apr 2026 20:37:53 -0400 Subject: [PATCH] feat(nodes): add per-node scheduling and update visibility (#344) * feat(labels): add stack_labels schema and DatabaseService CRUD methods * feat(labels): add label CRUD, assignment, and bulk action API routes * feat(labels): add oklch label color palette for light and dark themes * feat(labels): add LabelPill and LabelDot reusable components * feat(labels): add LabelAssignPopover component for inline label management * feat(labels): add label pill bar, label dots, and label assignment to sidebar * feat(labels): add label filtering and label dots to fleet view * feat(labels): add label-scoped bulk actions (deploy/stop/restart all) * docs: add Stack Labels feature documentation * fix(labels): use context menu sub-menu for label assignment and add settings integration Replace broken Popover-inside-ContextMenu pattern with native Radix ContextMenuSub for reliable label toggling on right-click. Wrap ContextMenuSubContent in a Portal to prevent overflow clipping. Add "Manage labels..." item that opens Settings directly to Labels section. Fix close button overlap in LabelsSection header. Add LabelsSection settings component with full CRUD, assignment counts, and ProGate. Add initialSection prop to SettingsModal for deep-linking. Include screenshots for documentation. * docs: update stack labels documentation with screenshots and corrected instructions * fix(labels): address security and quality issues from code review - Add NaN validation on parseInt(req.params.id) in label routes - Scope updateLabel/deleteLabel by nodeId to prevent cross-node IDOR - Validate labelIds belong to correct node in setStackLabels - Add requireAdmin check on bulk action endpoint - Replace error: any with error: unknown and proper narrowing - Remove unused Label import from index.ts - Remove unused isPro prop from LabelsSection - Add strokeWidth={1.5} to Check icons per design system * chore: update CHANGELOG with stack labels feature * feat(nodes): add per-node scheduling and update visibility Add Schedules and Updates columns to the Nodes table showing active task counts, next run times, and auto-update status per node. A calendar action button navigates to filtered schedule/auto-update views. Backend changes: - Add node_id to stack_update_status table (migration + unique index) - Cascade cleanup on node deletion (scheduled_tasks + update status) - Pre-check target node existence/status before executing scheduled tasks - New GET /api/nodes/scheduling-summary endpoint - New GET /api/image-updates/fleet endpoint with 2-minute cache - Parallelize remote node fetches with Promise.allSettled - Wrap deleteNode cascade in a transaction Frontend changes: - NodeManager: Schedules/Updates columns with summary data fetch - EditorLayout: sencho-navigate event listener for cross-component nav - ScheduledOperationsView/AutoUpdatePoliciesView: filterNodeId prop, filter bar UI, pre-selected node in create dialog --- CHANGELOG.md | 12 ++ .../src/__tests__/scheduler-service.test.ts | 6 +- backend/src/index.ts | 109 +++++++++++++++- backend/src/services/DatabaseService.ts | 55 ++++++-- backend/src/services/ImageUpdateService.ts | 2 +- backend/src/services/SchedulerService.ts | 12 +- docs/features/auto-update-policies.mdx | 4 + docs/features/multi-node.mdx | 17 +++ docs/features/scheduled-operations.mdx | 9 ++ .../nodes-table-overview.png | Bin 0 -> 87002 bytes .../src/components/AutoUpdatePoliciesView.tsx | 43 +++++-- frontend/src/components/EditorLayout.tsx | 21 ++- frontend/src/components/NodeManager.tsx | 121 +++++++++++++++++- .../components/ScheduledOperationsView.tsx | 39 +++++- 14 files changed, 416 insertions(+), 34 deletions(-) create mode 100644 docs/images/per-node-scheduling/nodes-table-overview.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 507068e7..11d3482c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +* **nodes:** Per-node scheduling and update visibility in the Nodes table + * New "Schedules" and "Updates" columns show active task counts, next run time, and auto-update status per node + * Calendar action button navigates to Schedules/Auto-Update views filtered to that node + * Filter bar in schedule views with pre-selected node when creating tasks +* **nodes:** Fleet-wide image update aggregation endpoint (`/api/image-updates/fleet`) with 2-minute cache +* **nodes:** Node scheduling summary endpoint (`/api/nodes/scheduling-summary`) + +### Fixed + +* **scheduler:** `stack_update_status` table now includes `node_id` — stacks with the same name on different nodes no longer collide +* **scheduler:** Scheduled tasks targeting offline or deleted nodes now fail with clear error messages instead of cryptic Docker connection errors +* **nodes:** Deleting a node now cascades cleanup to its scheduled tasks and update status data (wrapped in a transaction) * **labels:** Stack Labels — organize stacks with custom colored labels for filtering and bulk actions (Pro) * Create, edit, and delete labels from Settings → Labels * Assign labels to stacks via right-click context menu or dropdown menu diff --git a/backend/src/__tests__/scheduler-service.test.ts b/backend/src/__tests__/scheduler-service.test.ts index e98aeea3..71c9656d 100644 --- a/backend/src/__tests__/scheduler-service.test.ts +++ b/backend/src/__tests__/scheduler-service.test.ts @@ -8,7 +8,7 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; const { mockGetDueScheduledTasks, mockCreateScheduledTaskRun, mockUpdateScheduledTaskRun, - mockUpdateScheduledTask, mockCleanupOldTaskRuns, mockGetScheduledTask, mockGetNodes, + mockUpdateScheduledTask, mockCleanupOldTaskRuns, mockGetScheduledTask, mockGetNodes, mockGetNode, mockCreateSnapshot, mockInsertSnapshotFiles, mockClearStackUpdateStatus, mockGetTier, mockGetVariant, mockGetContainersByStack, mockRestartContainer, mockPruneSystem, @@ -24,6 +24,7 @@ const { mockCleanupOldTaskRuns: vi.fn(), mockGetScheduledTask: vi.fn(), mockGetNodes: vi.fn().mockReturnValue([]), + mockGetNode: vi.fn().mockReturnValue({ id: 1, name: 'local', type: 'local', status: 'online' }), mockCreateSnapshot: vi.fn().mockReturnValue(1), mockInsertSnapshotFiles: vi.fn(), mockClearStackUpdateStatus: vi.fn(), @@ -50,6 +51,7 @@ vi.mock('../services/DatabaseService', () => ({ cleanupOldTaskRuns: mockCleanupOldTaskRuns, getScheduledTask: mockGetScheduledTask, getNodes: mockGetNodes, + getNode: mockGetNode, createSnapshot: mockCreateSnapshot, insertSnapshotFiles: mockInsertSnapshotFiles, clearStackUpdateStatus: mockClearStackUpdateStatus, @@ -489,7 +491,7 @@ describe('SchedulerService - executeUpdate', () => { await svc.triggerTask(80); expect(mockUpdateStack).toHaveBeenCalledWith('web-app', undefined, true); - expect(mockClearStackUpdateStatus).toHaveBeenCalledWith('web-app'); + expect(mockClearStackUpdateStatus).toHaveBeenCalledWith(1, 'web-app'); }); it('skips when all images up to date', async () => { diff --git a/backend/src/index.ts b/backend/src/index.ts index 81421572..d943fe05 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -3085,7 +3085,7 @@ app.post('/api/stacks/:stackName/update', async (req: Request, res: Response) => try { const atomic = LicenseService.getInstance().getTier() === 'pro'; await ComposeService.getInstance(req.nodeId).updateStack(stackName, terminalWs || undefined, atomic); - DatabaseService.getInstance().clearStackUpdateStatus(stackName); + DatabaseService.getInstance().clearStackUpdateStatus(req.nodeId, stackName); res.json({ status: 'Update completed' }); } catch (error) { const rolledBack = LicenseService.getInstance().getTier() === 'pro'; @@ -4761,9 +4761,9 @@ app.post('/api/templates/deploy', async (req: Request, res: Response) => { // Image Update Checker API // ========================= -app.get('/api/image-updates', authMiddleware, (_req: Request, res: Response) => { +app.get('/api/image-updates', authMiddleware, (req: Request, res: Response) => { try { - const updates = DatabaseService.getInstance().getStackUpdateStatus(); + const updates = DatabaseService.getInstance().getStackUpdateStatus(req.nodeId); res.json(updates); } catch (error) { console.error('Failed to fetch image update status:', error); @@ -4790,6 +4790,67 @@ app.get('/api/image-updates/status', authMiddleware, (_req: Request, res: Respon res.json({ checking: ImageUpdateService.getInstance().isChecking() }); }); +// Fleet-wide image update aggregation (local DB + remote node APIs) +let fleetUpdateCache: { data: Record>; fetchedAt: number } | null = null; +const FLEET_CACHE_TTL = 120_000; // 2 minutes + +app.get('/api/image-updates/fleet', authMiddleware, async (_req: Request, res: Response) => { + try { + if (fleetUpdateCache && Date.now() - fleetUpdateCache.fetchedAt < FLEET_CACHE_TTL) { + res.json(fleetUpdateCache.data); + return; + } + + const db = DatabaseService.getInstance(); + const nodes = db.getNodes(); + const nr = NodeRegistry.getInstance(); + const result: Record> = {}; + + // Local nodes: synchronous DB reads + for (const node of nodes) { + if (node.type === 'local') { + result[node.id] = db.getStackUpdateStatus(node.id); + } + } + + // Remote nodes: parallel fetches with individual timeouts + const remoteNodes = nodes.filter(n => n.type === 'remote' && n.status === 'online' && n.api_url); + const remoteResults = await Promise.allSettled( + remoteNodes.map(async (node) => { + const proxyTarget = nr.getProxyTarget(node.id); + const baseUrl = node.api_url!.replace(/\/$/, ''); + const controller = new AbortController(); + const timeout = setTimeout(() => controller.abort(), 5000); + try { + const resp = await fetch(`${baseUrl}/api/image-updates`, { + headers: proxyTarget?.apiToken + ? { Authorization: `Bearer ${proxyTarget.apiToken}` } + : {}, + signal: controller.signal, + }); + clearTimeout(timeout); + if (resp.ok) return { nodeId: node.id, data: await resp.json() as Record }; + } catch { + clearTimeout(timeout); + } + return null; + }) + ); + + for (const entry of remoteResults) { + if (entry.status === 'fulfilled' && entry.value) { + result[entry.value.nodeId] = entry.value.data; + } + } + + fleetUpdateCache = { data: result, fetchedAt: Date.now() }; + res.json(result); + } catch (error) { + console.error('Failed to aggregate fleet update status:', error); + res.status(500).json({ error: 'Failed to aggregate fleet update status' }); + } +}); + // ========================= // Node Management API // ========================= @@ -4805,6 +4866,48 @@ app.get('/api/nodes', async (req: Request, res: Response) => { } }); +// Per-node scheduling + update summary (must be before :id route) +app.get('/api/nodes/scheduling-summary', authMiddleware, (_req: Request, res: Response) => { + try { + const db = DatabaseService.getInstance(); + const scheduleSummary = db.getNodeSchedulingSummary(); + const updateSummary = db.getNodeUpdateSummary(); + + const result: Record = {}; + + for (const s of scheduleSummary) { + result[s.node_id] = { + active_tasks: s.active_tasks, + auto_update_enabled: s.auto_update_enabled === 1, + next_run_at: s.next_run_at, + stacks_with_updates: 0, + }; + } + for (const u of updateSummary) { + if (result[u.node_id]) { + result[u.node_id].stacks_with_updates = u.stacks_with_updates; + } else { + result[u.node_id] = { + active_tasks: 0, + auto_update_enabled: false, + next_run_at: null, + stacks_with_updates: u.stacks_with_updates, + }; + } + } + + res.json(result); + } catch (error) { + console.error('Failed to fetch node scheduling summary:', error); + res.status(500).json({ error: 'Failed to fetch node scheduling summary' }); + } +}); + // Get a specific node app.get('/api/nodes/:id', async (req: Request, res: Response) => { try { diff --git a/backend/src/services/DatabaseService.ts b/backend/src/services/DatabaseService.ts index cdc1b200..e4d0cbc9 100644 --- a/backend/src/services/DatabaseService.ts +++ b/backend/src/services/DatabaseService.ts @@ -458,6 +458,13 @@ export class DatabaseService { maybeAddCol('scheduled_tasks', 'target_services', 'TEXT DEFAULT NULL'); maybeAddCol('scheduled_tasks', 'prune_label_filter', 'TEXT DEFAULT NULL'); + // Per-node scoping for stack update status (pre-0.10 had stack_name as sole PK) + maybeAddCol('stack_update_status', 'node_id', 'INTEGER NOT NULL DEFAULT 0'); + this.db.exec(` + CREATE UNIQUE INDEX IF NOT EXISTS idx_stack_update_status_node_stack + ON stack_update_status(node_id, stack_name); + `); + // Drop legacy SSH/TLS columns from pre-0.7 databases (no longer read or written) const legacyCols = ['host', 'port', 'ssh_port', 'ssh_user', 'ssh_password', 'ssh_key', 'tls_ca', 'tls_cert', 'tls_key']; for (const col of legacyCols) { @@ -864,7 +871,11 @@ export class DatabaseService { if (node?.is_default) { throw new Error('Cannot delete the default node'); } - this.db.prepare('DELETE FROM nodes WHERE id = ?').run(id); + this.db.transaction(() => { + this.db.prepare('DELETE FROM nodes WHERE id = ?').run(id); + this.db.prepare('DELETE FROM scheduled_tasks WHERE node_id = ?').run(id); + this.db.prepare('DELETE FROM stack_update_status WHERE node_id = ?').run(id); + })(); } public updateNodeStatus(id: number, status: 'online' | 'offline' | 'unknown'): void { @@ -873,14 +884,18 @@ export class DatabaseService { // --- Stack Update Status --- - public upsertStackUpdateStatus(stackName: string, hasUpdate: boolean, checkedAt: number): void { + public upsertStackUpdateStatus(nodeId: number, stackName: string, hasUpdate: boolean, checkedAt: number): void { this.db.prepare( - 'INSERT OR REPLACE INTO stack_update_status (stack_name, has_update, checked_at) VALUES (?, ?, ?)' - ).run(stackName, hasUpdate ? 1 : 0, checkedAt); + `INSERT INTO stack_update_status (node_id, stack_name, has_update, checked_at) + VALUES (?, ?, ?, ?) + ON CONFLICT(node_id, stack_name) DO UPDATE SET has_update = excluded.has_update, checked_at = excluded.checked_at` + ).run(nodeId, stackName, hasUpdate ? 1 : 0, checkedAt); } - public getStackUpdateStatus(): Record { - const rows = this.db.prepare('SELECT stack_name, has_update FROM stack_update_status').all() as any[]; + public getStackUpdateStatus(nodeId?: number): Record { + const rows = nodeId !== undefined + ? this.db.prepare('SELECT stack_name, has_update FROM stack_update_status WHERE node_id = ?').all(nodeId) as Array<{ stack_name: string; has_update: number }> + : this.db.prepare('SELECT stack_name, has_update FROM stack_update_status').all() as Array<{ stack_name: string; has_update: number }>; const result: Record = {}; for (const row of rows) { result[row.stack_name] = row.has_update === 1; @@ -888,8 +903,32 @@ export class DatabaseService { return result; } - public clearStackUpdateStatus(stackName: string): void { - this.db.prepare('DELETE FROM stack_update_status WHERE stack_name = ?').run(stackName); + public clearStackUpdateStatus(nodeId: number, stackName: string): void { + this.db.prepare('DELETE FROM stack_update_status WHERE node_id = ? AND stack_name = ?').run(nodeId, stackName); + } + + public getNodeUpdateSummary(): Array<{ node_id: number; stacks_with_updates: number }> { + return this.db.prepare( + 'SELECT node_id, SUM(has_update) as stacks_with_updates FROM stack_update_status WHERE has_update = 1 GROUP BY node_id' + ).all() as Array<{ node_id: number; stacks_with_updates: number }>; + } + + public getNodeSchedulingSummary(): Array<{ + node_id: number; + active_tasks: number; + auto_update_enabled: number; + next_run_at: number | null; + }> { + return this.db.prepare(` + SELECT + node_id, + COUNT(*) as active_tasks, + MAX(CASE WHEN action = 'update' AND enabled = 1 THEN 1 ELSE 0 END) as auto_update_enabled, + MIN(next_run_at) as next_run_at + FROM scheduled_tasks + WHERE enabled = 1 AND node_id IS NOT NULL + GROUP BY node_id + `).all() as Array<{ node_id: number; active_tasks: number; auto_update_enabled: number; next_run_at: number | null }>; } // --- Webhooks --- diff --git a/backend/src/services/ImageUpdateService.ts b/backend/src/services/ImageUpdateService.ts index e367c2c5..ed18496e 100644 --- a/backend/src/services/ImageUpdateService.ts +++ b/backend/src/services/ImageUpdateService.ts @@ -276,7 +276,7 @@ export class ImageUpdateService { const now = Date.now(); for (const [stackName, images] of stackImages) { const hasUpdate = Array.from(images).some(img => imageUpdateMap.get(img) === true); - db.upsertStackUpdateStatus(stackName, hasUpdate, now); + db.upsertStackUpdateStatus(nodeId, stackName, hasUpdate, now); } } diff --git a/backend/src/services/SchedulerService.ts b/backend/src/services/SchedulerService.ts index 25149265..104554d7 100644 --- a/backend/src/services/SchedulerService.ts +++ b/backend/src/services/SchedulerService.ts @@ -102,6 +102,13 @@ export class SchedulerService { }); try { + // Pre-check: ensure target node exists and is reachable + if (task.node_id != null && task.action !== 'snapshot') { + const node = db.getNode(task.node_id); + if (!node) throw new Error(`Target node (id=${task.node_id}) no longer exists`); + if (node.status === 'offline') throw new Error(`Target node "${node.name}" is offline`); + } + let output = ''; switch (task.action) { case 'restart': @@ -379,7 +386,7 @@ export class SchedulerService { for (const stackName of stackNames) { try { - const output = await this.executeUpdateForStack(stackName, docker, imageUpdateService, compose, db); + const output = await this.executeUpdateForStack(stackName, task.node_id ?? 0, docker, imageUpdateService, compose, db); results.push(output); } catch (e) { const msg = e instanceof Error ? e.message : String(e); @@ -393,6 +400,7 @@ export class SchedulerService { private async executeUpdateForStack( stackName: string, + nodeId: number, docker: DockerController, imageUpdateService: ImageUpdateService, compose: ComposeService, @@ -432,7 +440,7 @@ export class SchedulerService { } await compose.updateStack(stackName, undefined, true); - db.clearStackUpdateStatus(stackName); + db.clearStackUpdateStatus(nodeId, stackName); NotificationService.getInstance().dispatchAlert( 'info', diff --git a/docs/features/auto-update-policies.mdx b/docs/features/auto-update-policies.mdx index d2c457c6..6d9c9e82 100644 --- a/docs/features/auto-update-policies.mdx +++ b/docs/features/auto-update-policies.mdx @@ -52,6 +52,10 @@ For convenience, Sencho offers common schedule presets: | Weekly (Sunday 3 AM) | `0 3 * * 0` | Minimal disruption for stable stacks | | Custom | User-defined | Any valid cron expression | +## Filtering by Node + +In a multi-node environment, you can filter the policy list to show only policies targeting a specific node. Click the **calendar icon** on any node row in **Settings → Nodes** to jump directly to a filtered view. A filter bar at the top shows the active node, with a **Clear filter** button to return to the full list. + ## Managing Policies Each policy in the list shows: diff --git a/docs/features/multi-node.mdx b/docs/features/multi-node.mdx index 48e380e0..e75e7fb8 100644 --- a/docs/features/multi-node.mdx +++ b/docs/features/multi-node.mdx @@ -73,6 +73,23 @@ Node status indicators: | Red dot | Node is unreachable | | Gray dot | Status not yet checked | +## Per-node scheduling and update indicators + +The Nodes table surfaces scheduling and update status at a glance for each node: + + + Nodes table showing Schedules and Updates columns for each node + + +| Column | What it shows | +|--------|---------------| +| **Schedules** | Number of active scheduled tasks targeting this node, plus a relative countdown to the next run (e.g. "next 2h") | +| **Updates** | Whether auto-update policies are enabled ("Auto" badge), and how many stacks have pending image updates (pulsing blue dot with count) | + +Click the **calendar icon** on any node row to jump directly to the Schedules view filtered to that node. From there you can create, edit, or manage scheduled tasks scoped to the selected node. The filter bar shows which node you're viewing, with a **Clear filter** button to return to the full list. + +When a node is deleted, all scheduled tasks and update status data associated with it are automatically cleaned up. + ## Editing and deleting nodes Click the **pencil icon** on any remote node row to edit its name, URL, or token. Click the **trash icon** to remove it. The local node cannot be edited or deleted. diff --git a/docs/features/scheduled-operations.mdx b/docs/features/scheduled-operations.mdx index f72122a0..dda380ec 100644 --- a/docs/features/scheduled-operations.mdx +++ b/docs/features/scheduled-operations.mdx @@ -87,6 +87,15 @@ Sencho uses standard 5-field cron expressions: | `30 2 1 * *` | 1st of every month at 2:30 AM | | `0 0 * * 1-5` | Midnight on weekdays | +## Filtering by Node + +When managing a multi-node fleet, you can filter the schedule list to show only tasks targeting a specific node. There are two ways to access this: + +- **From the Nodes table:** Click the **calendar icon** on any node row in **Settings → Nodes** to jump directly to the Schedules view filtered to that node. +- **From the Schedules view:** A filter bar appears at the top showing which node you're viewing, with a **Clear filter** button to return to the full list. + +When creating a new task while a node filter is active, Sencho pre-selects that node in the create dialog. + ## Managing Tasks - **Enable/Disable** - Use the toggle switch in the task list to pause or resume a schedule without deleting it. diff --git a/docs/images/per-node-scheduling/nodes-table-overview.png b/docs/images/per-node-scheduling/nodes-table-overview.png new file mode 100644 index 0000000000000000000000000000000000000000..d9a40ff8b7c9423c535a42d19fe665631b76de7d GIT binary patch literal 87002 zcmYIvbzBu&_ctxwjdXWOmlDz_4bmmuU5D;&B&9*Rn?t97ba!`mz2m+2`MrPXN6(p= zz4o`(ntj5)DoCOr5+XuCK%huVi7P=szyg1TCWD6p{)>kPKc*GL}ZF(%%rlkhQD$LBfb4jH}@}ik&?T-*Y+@-N=faoREpV+7+Fi zV$?sBuJ{8EY(a|a8=8Qtqho8WXRE8{ovyp^W_xSxl*@M)*Q|%Ju~}RbKNHQ|wkm5a zV_EHjI9ZbLs7p)o0?~^UFTQ$5QF!veSp7+l?+TLgEh^L?=4bW#0sHal-hPr81U%aT zR3ZB70;?j~`aSi~!@xY9_B}Qi>pk1eY_^*Y#08>K%s}+Nmp~U~KpxpPHuw23kf@Rj zsl1fDTra4||2=k-GiVx@S^@t_316h|J1hfS>kmB=Gj__Z#N_tOlZ?M##)pMoRM;eCon%7LyMPQCs#M!>SX6r zkdqWV`9j_bb(s_U@uU2+Y>D28(QAFs_a_`_&dQ`q^wf8IV+jk6UWw1x`xN9Ut6=1j zBGkXDgeTAcTs8U1S>|1!3*FH6>F#-6)pNGB#%fPwM6u7su*ZK=5pxbR*nBc5p9^*){fEsiOpD!Wgb z-1e6hbf4J02W!!{Ep;LXTKex;OC^n73BwHx)zt%sT1odSwHsdOZsR$>^4qy{bWQ^O zgB}|B4c;}B?%?@mj=%ArhQ&aaR>IH$X9%7BA5TO zicngS_mDoAiD7iuH3fEGBWIzA62i%1`|`EH`Y%Kiv63I{fA|#4@GJ;TT7%6C*M%;5 ztudGe){j!%P6FL3T*}&|J*!UU1FU5U{1W^E8wz%%@ZvW=C=^0jw`OZGX$}3jaI>xtqdM*BX{5Hs@(ec@Q2 zS-*(N1fAm%pKY6n;ktgC6(+~=U!|3Op?S}gcfwPjqv=a*kj}<5(h&trLJKVaAix0iN#*^T~BNGVs8dH>#*{K*Ql4HT1%*|rkps@nW zoYF*gs$TNEaOpS0t6idOh*NPaHGBt(hVO?}`PvfMIhoGvwf4%@w7sXR0!T*e<5cC_ z$w?vO3S*;lW|<&Swor0_9(UkS;kGM(GwV23M=MrF%gDT?`DeBigJqoAUmA`-aJu`r zALuV8IT{?}4n)6ZiQ9yIMl^h1#{PN7dVHhuk1z6lfvA-5c`FsPVCytjx|w;Ly)VZ- zon>~cL*J!Mx;6MPiwtkL#%YZOpA#JEOer;XQ27i!TGa;*K%glc5f zlzgcB_J~#z+M|WVdG7^fF#VCM5T|f1U0vCZs$|`C48@2X%@LRD=HsX+t9!203qs9f z@Rvb_r!D(RNPkJw=X0zUNIdh?Z5w{aW_&GMJ4!S$?eB;4VJ|n~;ki`De5*)of&{j^ z7u?f^HtN)hb0CC1his;XqGr+^3(C>%#ca>q>Q11<+czYo`DKs2imKi4W!`5z-UwzU zxD9na-)xAlDm@_QuL-N_9@S*uhI}ZRi9Tj!Nm83bqLzTl(OvX~veq%LNw|LL8MXBL zdenWkbR4vT86fRnNyqY@tIrwuE>LW}5~Io&Fp%6~@ZeGPvMdx*o;Ka7I8^Km&Fvt~ zo>E0X>q3~`-WV4m$Flk!my>+FQRx(!OC~x+D`@q%ECFM9y@;Gj*);{N5>Cpf>U+Cc zt7`H%oew!6iOVN&OSSsbb0xZYR(sQQnNLkac0v+K`jS?Qcz9{<$Tp`GW*(xmHC=Z1 zhorfsuKE`dnQffT4X!HoOSY}D4O@3LGlFBBRS&+V;enlj9dKEzJdNK`5vV=rjF8c> zd8wi!A~YoyC(aW*Pz-u;ag?TL^BkN*Y&+3QO>2jrs46czW?RtNH8AAFtgk5NEkj>; zKoj$`6J`I7+AaR!BLwh2|+*NTMY?Zpd2M^SCarL0Kw;qOBKFW_`Mjat$+m_Y5 z=H-UmRW5B@owywyEsBaXNp%bR znBYWS<5imTmcO}LMe*p6M<-#i|5w#ai`uH*n)_I?(?zK6N^NOk_jOmdvIo@sz4#r& z(x z-Xjm7)^YI|-+rqf!BNkGfwcF+>v*R4TqJh5n(0tw=sMNfX$dK5@l)0LL`s2fLt}xM z-rv_c?Ak9ry zl50BDjZ?IvVH)S51WlY|O0Rwx2@G*4?)k``6f4aEY!A4tqJ}t0_dlU)gpnuh^JOrYK!< zz4r`JfBEG!Qz?sPjQu;e>dR>NMiGcPh4hPGX>OJHVkufbkKc;+(Hj7l*wionGH+v|xs>M8~)#>K8B6Uy5A-Q^^-(`g0~b`f#PTUo;| z)3UndEL>(ggSj(73%3z#42f{um^I9rIi?22aem#YXNKd_{Ywg|i>}QYI~+)41EifZK`PVlZ+wndH zA7cr-7K+v24Csj?yApJG1$s4Ntke8cJdGGFAm4X1x3a`TT&If3a8;6B9}Q@w!ObRB zo$td`ZcL|E*b6WioRY0NVv|ponLKhU*|jpwJCg{g!I_Q}griVf7o7@>HDu1SQDcsr zENB%C3snjUj_BRBRH$t*&@bWoaeREmFsDx1;Euz$kdiqP+GD|_HVm8oD9+)%*633% zca|Nv%(eaX3SGS&f2$6vd_mK-o-<3oE0l+pyfW?mlUAIEGsT~NOyT(A3r3OtWIg4( ztL5=UiH)SJB=da+UfMW9ul&VEQOk7-pF*vT&ybgi$*V@cUsf$2BK2UN?h?A1u@2}H zjGh&*v<1IVi?kKssSB{v7zi@Ox0B6?D4*7Rv9$EgcUsc-7?94V5maBI@3U+zu$56v zuf=~s#LOD(PEji9fIe1A>ejm>l&|q9hPbi(VAaC0F2Q@KZhaKy!4v3X-AC;!QTP;k zqB$l5f3YL21e&IkKaALM>5Ajj8vkHold@IXm=a%o;ZO z!W1vZb&kWCi;1y1@n;fCz{@5A34ffHXkg7tVK)tQVg2}aYQgHd4iSg|DQWzA#kVXt zlFzcN$(pz8E+N+R+q1D1oIN!Lm((EWBfcc~zFcselpa4$hWD0{nwJwalep5(e=kQl z1G+zQEtP&r&s=tz56J06hQ4QtK=7e?iNp-3SC$i(o5IZ&0oY#K{MeSh@OjCh7vWv%wL1dalWkTB@Fn}=vO^@NTqo38 z&kGAF>jDa7;BT@17Ss;rdurlW!|Khdn$PXrJ>nYp#MGOel?gP63aPkBo|vCg*v1o! zFP0R)hr$@syD}v(ONtl8mQxrX;B0@Z)gEf~AwJ&j_^>ixp=+V^vgnfgRw!;;kJ*lp z_a!&Rl8AFdTAldPq7EOaXc?wT-NJ*b>JN*=0jB=bjH^zx8b1r3_gp%=dX|p#(Wy(* zO?7uK6NhsZ6X{LqJ04U8E#UxmwFd$})rSI^Nu}Mv{C7LKuyU=A8Z0Oo+*mv(a9arx za*fB`#Xlo6BgJdgDWlD|B9qAx8J7h*hv)+B78beiLc~j!TnK8X`ghrZ6_@LYZVj-WpP&CzH%8;*{I!H=2Bwl=ISeF}0n9YT$K^Yyy*h2NpKt>Y~=q!c1t1&!`G(t2^A zA5CJ^-tcSj=YzZAVU|Q$yjYFjN<5vL)0Y*Jd~w6<-!nvv1+GPj-s8J*u9|koR)3G; z5*<9M>rDFz>X6heE6xpbsj3o2#r2wQ~@E~E&U(ko?m!h6xb zBg1HKQ7CsRfi3)751N-q5x)u(JiT0m=N7wOmSG{Dt$C&;&2ktC-mO=N+I6xW^sj1^(I<6AtaO2NBjofMmrL~PzD!dBz7#Xqob z@f}z#b*mMwZ&#Fut!@W1KNsn09k^FLGuzp79dLNPo4=`Imr<^_eyY47T*u@`61gE0`?8Ss+Yg&k+9d^=JG9gA&j9O7-b6RylKi8e4lkn8DGw6|A$*{7R{`sy3u0f!y~RO9{IhR8UzRT7@H|^ zeNP(gNLZ+iL=2%%+cxFcC7ImNHmDt2`oXlkQ6~-?L?WK59mZRhvJiCHIz{M>n+}Id z{{2ooJf{xcr{kf6)6+61IBPL^Lvokx2dBWn7oO>T4~_XnABqBygwl(}}8pGXLZGB5|rZ_=!pCBjt3e?*;=N#^<3!}MDn`IN>8TFl9g*lg=P(5KH0=zCi4*` zcC8&@3+46X*q93Fp)^5NNrJW2k@aaqMKD8C^_^zU_+4mKqLd=m>8kz+OM6FlV$Y>y zEmTo&)xdfBBaVduZd@9=rgCC4L<1)?gI29;v3^eJlRf?KNcO;SUwgJ0+rSy>FlfYB zSD(zmq{KStR_(H~Q=Go9c*z{A9=jXG-nQwSy@t^%m|a1~#4c=wsis!hc<;19;@4&p z2k117t8u~<)iTSdlm;)eO!lKWbT>s_(=HlAI%&hrd)sHHDs?7w1!dHAUq~0iaFm#+ z?YPoyWu9rG+J{KxA6vZec2+uM5}C+}5-d+E7Gv@AWM+R6qbE(Qu(v%vM%^nXQ zlY6Jin&laDDMYEqwurX%sr<}Gk{$Gv82nmoO8KQXT{~(`Du6TA=r$6qaFhIy>H6|# zJdOezh-*v|OzLhSyYW=8;6CCXiPq{y$yysx=ca0}L|O1k?PA@`40cn=Tvh-<&TB#e zlbu<9FBc1~V%=CNfwyiv@gEw#FS|R0XJfkK6?qh;;>_cg)fL6spH*y&BQ=LlKV#is z>=2{sH=ym+|ETRXhI*1)rH6e$IA$z046bzw{@PffqSVaK^nkVGkt zH!tbc`U9U4EuRH_U|J1U{-BZhL&Lb}sR0z>%9UwlXek&o#ap^Jv7iZabl_b4y!I!A zduWhDjcm&Mh4y`8r$*?a08Mv|KpKXwx$pO`1Kp&f(S*%+!I2`BD}CLuH_H8}Lf$oO zd#cEnx@Te1GgK=pE1Uu|5j9E0IHKht1qT{hXl9=ASl=4uo1!0o$B!siCyryAZRz|* zy|};>AkK02y3w(=;XwtkzmM;jqq7A;#3dXLNOFnDWtL`EVR@RVbK;H zr*2TXi+PTp^I-p_=l*dJ&!(PWSbFF%68RoQkw6*a5=EDM`=>vrj^s+^jySQHPO(;9 z1<3jY&U&e(^wCsM9wYPw%&V-h94_`f(3HvY zU=6P(9#>I!#Km1Q1lpD8X{{+Z7h7%UurSJt(#i@l>x^fvvG(+zXctq5w2N%7*ZB{XMsiaJ4-|^Ph86{UG~7(1 zeUr2HlT&plM9JzF=BNe^@B44#V_MjBeIGv?3S6Y$U+8vD5ZkYBanoR|l+dIbjQ7Y0E2wMU6+l5K5ZylV}b;|`Gst@%R076n1nNZ&_2DV6- zSjU-1e-@@wg=Ctvy=Hm#CsHI{K0LJ8I5=CBp03b4?DzUcf@C+?g4~3E>4E2%S$U3( zxKGkXBq2N4zmBH?e|I=GEM%~%LO6e^S2^rry_DR=E@TqN=(0{{H0zdF=EAAk!b9(| zgQ+q0Wzky=X8CgYpa8G<7rOHq@@K$PRu*RRZ(OpKMiy{0lNw)bT(<9xQTEfsPxNpf zbSQki5_9gpDm0cjV07m4ez2Rho}Gh#MYly^y7SmByM4$pZA zYBt!#PY0#BC#f1_HB=|M+vV)Ee!F@}w1-8rU2tf|E)T4TI~r@4qM?e&zfM{qmUTPf zsyX|mi7_2_4P8Q3fi3Y^3U2U_U@7Qp8y<{Sy=b8`fV6r72bD%>fxqhd6@92W`Q#QZ z{BeLH7#MDV^R1^$L)wKoZT4`MKAajpndz^HbvbAx%$t8>sm`IY*!+b%q^>gsP1s<) z=BkTRQjnKx%vspcs<&O?*Roz@dkFev<9Y$?kOJn9c&ys;&El z1x_H)en#s>lu=S-TG4hj@L-lzzT;1)T?&xQ{Fd!>LI_xW1y`gwH?8d;O$tI7jA@Yk z+m7qa$<0GByLqS;XRN!Q9Dcbv{Z??ia+fJ`{~Zmb5`NN%n&GIzb)9(XY%+AYGBJhT zl96n~;2S=rK&oF=&vYo3`Yk~%q>U)9LXxpAb71fJSmSw{gvw&Oc`$O5b}N9-i>jG1 zITqGNvYOvxixs)cgrbHbSrb9C=+yNy%U$Hf5?`bbLN+05k}T^XGqrJGJQSWROB~S% zc`I!MiGkbQvJtK#i3Rytl>4al?Dl-cvD~JjIPE=ujq?Omd^?TpfSfc$ede)>yN;5d z;E-loYk?$PkZb6tsIs#kpu{ZLc~otTG1SBk5TfSUJ5T4#Mf8Ifb+b{~7`5!%vM(Uq z1Lc#Tx2BRzY0L;wp`l|s!g*D*3g6s}KgN|Efo|Hw-QC6=$2W+)Mn( z^c{HTzNnk)fTx*bF8J1)lY(Tks^kghE1QO~ynoBM%8k0? zI;35asEj+IM~%YQ8!a>`~+93FC1j@6jM*lLBLCeC+Amr$_DbccFG~i7B-0LWx*7uN2kwj z*@H;3^jZxfD55*iYGJ(EC@FY?J>*Bvh?^~)3Xt_c-Hb|>upUCq2eE+K0p zy~q3WhfcqLHWx*RB`uW%7jJygQ&qX8VmX!xuj?r0Iw7el>PD>@z;y8R)gwN`gG7~; zPisOiqR_xRoyU!E?fIFb8&=I!P~#;jlP~A(uPusJqJ(O%=kO5?Gn1f`YG|am#P4d| zE37}qqjwD#n$6dt>Zk?uKTJ$?R(M)cB%aCHX2&ob<@XbcH?`U<;`u6T$-prlq`T1J zFl@-@OT_2d{Ko&aUA5KVoN^*h`37UDzZ1_M50MgIn(2$0JR;V0zDim%7C>ya7vp42 zNXcXK^gu5XetTR~yl~79>igW`sETm1AoB)a#a4nZ6#3^#%VKVagdbYhB!7>YchA5p zI3Fe$E=s*g{WAmJ%I4t;x-cvJfsR&QEGKRw*Z_?-wsP?XZryyer!JOpsLQ^*H_m&QG3+*sPn+ zsTuhRc8>KkiM8cx%e89YQ)E2(Mu7owqo(L#|7AuNQfdOhmb4Lg33Ao1_6^m?V=QZX zn{)MS{QWZ!+R+a-X#6|&Z$rvj4CzIYf#Ydzj4bOm>vvV>SUtaJsoHeDfdxGiq+F3J zP9xEN9uNOgVeV`&hijgbpbGhLEH@<)d8iQB)TdQ=7am3VO_JdMW&!Wj;HT;sMK)rB zZG{vshSwwWpbb1^cLJCvbsxFp$S%+{9-At-Hd;tddMEw+Q?Qu4tGn_oW6Ngx$wb>6 za@T(9tQE@+8SLbbthmkC&gQ@m5iYGA64mGZp4EDu_p{6^*1;fd2v_ps67AjsEIKk- zL+5nSphfQo$9fw9t+*&$h5Y_X z!mhJx9U~af7Hr?uaisMJ#RX=Rkl$G-^X5JrMJYI%*ba8Fz8u%>!;`F1IcQJKE?5HQ zdV;f#TdsI){H?*{%1X0bZY4uHI**9i$$E!Ek(UhKgw;IQuq^XR ztRF;d_O1b1FS*M5SkU0~lBHDL4s+EVmi(Pr#75YrIt^ryn&#k@Li+i!^JIH) zf8$5cxrt%_$ch<<%D9z;(Gvv?gx8Ow7wU2>`n^<0#|a~vx$C~vw>@&xM2f1vEcT1p zGme6GP?Vco?gsuz@R9F$$y-a}kBShPye8&hfc|Oa;JV?s(<oBAq{Ihw>nBZsPJyHd*&EP{R$Ngg8Z@$kEI5zN=T!%KVHpfd&c~Y4h}d%e(e%3ly@Zf9{fx;n>n9mK1Epzm zj1cDbSXUBJQOwt@%<1J$%7G%xqAVXR?omwI6toM33R5%jCyQtX0XwBoqrPSeB zWwwtC@`7W1msq-wgj=ky=_-Q;>lA_*i0f`c8d*OoJI=W%Xw^bk%~!h1nyI**@pO=j zp6Y}k9jVrcm6goJEfo7Wu~LoY2W5V*l?RvSnr&PK1s36dlO@+fxVWJYk3SBlu_SnJ z?(t>tjygAdBX*l(7h`LR@$*XhnW@Dpt8=?wm=eWZd<<29GOoV$oEIHkf1QX;SpeTa&Dc;|0sBkhh!O$~^O? zZ3i-Cov^u%VSEmCr+6lBgT{Ct)#LhdEmw@Vj^&l2ED7B<0VM}d zFEhVJ@z3#{oC{@e29!KJJq%pLr~9)PT$qXg2?mtK3kJwp4)Xl&Azs)tsMPkOLOafOZA%7Mg(i%*HHzWGz91y)LlrCH$1kJw(lhBoZHT?#EzA0_63~^TvWR$=X zy@W6S_tX-V+B5J;*#Enxw4wIZLMaHq0|t~ibp^XXl^nMKmZDtgn1g(uVSl9yucO~T z_m7q7FAXUbk27-TrU;BWNoPz{`rq9$V9MUKIZHntl{_vf?O^zn{1}a!x5LqP;ocao zrrPry^yPN{TPJi;DV6X;V*PKLe-8lt{TE}g&Qh?204o&l{NtW0(=Q2D$>#U{;spBN zRk}FSC>W>IG<(jX@Z?GU`8GT`mqMLH6{5Ubm*G^#SqWwIou&+*Tm;7o{^MVH0*c5%{D@4)+|*p&bP{_oNfvd?Rf z+~1T@qRm-`-1|zrN4|`uVc~cTs%)!W4h+YplTlV#2G_cBF|9z!O=wZ#>-GO{i#Ost zA9P?BS=oa!zgNmX&v#4S6@IaEaf-3jv(YkN{-a(?vRK~dD3{~;YUd-hPg1D8^u9MK->1;_u`;;I(|138^Y#|6vBa%Qy8Jcn z!Y!qjfWey&!Cm3KlZkZV&EAx2w%laz?96p0{trf}NPh;jk3b&cx!?`1kEZh=iPlhO zXMe)%Zv9wWVXwpZX$0ClA-jD<58-awO#S`XTiW$ZK@H9*R2i23P5E{T$R5rAv0x+R zpVe;@IW?1ellu~VF#C9fG?d1Gfd#sp*x{v`q;Y|EN}>uEkg zu(7-q?z$YzFFnRT;0ddYS8A$JP37)nDLq_SH|Cbzwn8Ges4T`m+ec8)w!kY@|9_Sh z3k7u`i^MjRrewpfHW)zv!sr!P>KeEAGj+sUbuacjLh_$d=AR$0wx<&-#&f~eLM(kk zb@}Ndp!ECT$iO6aD0(2gaR>9Cr%__C!=xArdj95nBD5wrsqWpN9nyX|%}vsvGw`xT z60M-3RdGW0A3FmRv8y$GlW3g6#I$5)x4W*z(gG}dT!>u=BBx@gK0 zAwT_p7Ss&_gjV|TEt**4;OoeiWW|xy(HfM?`=qgYrffVD>_uAJ#AYcn&V3Z=UIM zvjH-iR+^#*S_A9{WUj;orQ1~x%Afns@DEs6P?+L5G{Ou-T6z9c!&pN~J>2!{MxO$Q z8_hX}9J7Re9WEpOjkOx9Z0u`@=)@#}S&|1!P0=Ckoj&XP8|CuPly;xT|CLg7(eNJ` zFjY&FrLBVp0|zea*e#BtLkt^?GnG;VK~srN-P4Tmv+L7krsjw);uXl&3(3sKv3#z? zGd$YhmIt0l(f>({67seMBUX$>&8EhS)Ut^6Q#d z)|X#{(8hM1((XLGdq4hVx2Q~7o1C9Z$!4J1HD?n|Sx53~g>4I_!c(5?+H{M0G>!({ z%aL40@*6djMt6aK58eE_bJg>2@O1xwt56E;CG(B?t{adiiBrh>&bp{%Ezxx3W{!K_ zZ>G-Npt)@1uwCyg@faOuJO~vPbNxRdC(l3MzT=dVUaCwiO!HhMeb-~q6Mb#bDiTDM zGVh?)A;XlmgONFelOus0>6ioU@;?K@X2yW2T0?685wmz0wd(XNURlsuau+t$MpIBp z9bald5D9MiAn!#ctwB+SF@Ha!Cn9Zy{NFu?-YFKj#2?d%_$gCcpf6pGuiLb~nd=rL zsLT&h4ymS{)S=z}GCTQ01y#WMRQ7%*XL{l5%fArMoye1nF^UnIJreHzgsx;qfux^u z$VpN!QD>4eYBA@j0BFkOKj)BDu|7sd#x<)?B2bcVCwPzaBgo0ZWq8E=l} z)>@oP|H`G5=J`QU_9h-7K3Fz|1xNbEb6n_-Nu%ncF%m!WQll+i{^j{EIqE?j@Nm&7 zON}nf2&xw;?@mvq00yxb{*rU2!b|mxzg9y>g;TPJVB{Z^hLHahg(3Crc~69*#1H&@ zDO&N(Pub*})2?;9*rd&JqcB3= z@cyT`iMW3{_qRVnE5F1O($Yd&NqUpdj-6(oG-4-bzOLGSq;VwAa->BSd7Ox;=y*I- z$mBm+ZTFlilwWGFwp^?`_+gsmKBwavG~LGAvMge2)om4O)Dd>9t(Eug>ZmAYs`*MFjk1%QhHh**!b??St zP-$6qS+aij-mVicz3-!G)c**dR8;QjQ<97RR?DA2>|mxf$k}Sn4zvtf4)b-lTJec= z0k#>#-?o7HR?V_#HOTR=I!(z#!y)@(_E%m$Y>~d*Zzp`QnfZky*Na|#x90Qa4~z6O zc4NN9+0qSP$m4qIi%2`@Kxelvk{dLF5oSHNc`B$A#uRPqTeq z`Nl40wQO$W)2dx36d)MIPx4i@Vz6KLdFnz!S3N7H*m8pxB#&A@Lj zXGoHMMvX2fi&6^wqIunWxe^g}Dkk3noD43-l8brV9*2>=-4BR}iyObHRwT*-{KOGEF6ofI#ERO~DV+|Jy>pi*^^ zWPNf<_BjanD8I`wJi$XZ606sF*Sq_m2w}yC49777ekVE=_Qbsv*R>U}&l_W9+vR!y zS}^uAPzBE=>&7loq&_4^7OHAw4y$>#RB5d`Gj@|0!6qZgpOVGmL@AvQ zrw_JbL|h8|d1>WR$s8cQKxH(22&SZcN9=_Dd-1*iVk{aU4)GTJ#+>Lq)srmFhM?$?)U zu~|cP#PuK~JP;rwv1=*19tQxw?#2Ypey6f;g)>&1%bEZ}8ha|>a{QI03PNl<;*ZzM z%^dn611+1B%l@AnomLlr@plb+#d_G3{a;1lKBbGt4v_j}xct*DsgQvVDcca~UU~fJ zeWf?dR$6X;ehR3%*iE*zTP+k-L*oa@~#8h;B{O*pl{!20?m$0T?TdP6ndxC zg{k2h#Cf6N8c3B)^he?AF0f4QK##N4b_0T}59XMWb;^Zu4@+yWyHVDF6#uo48-kTN zJs)o>NI63oN*eqv-^V1ZEis3SK0L~GV87P)HdZ~)hyj#;L*;%w4-uieGm7ThJuIz! zy;^2MIW znnj-T-Uc7A*8R*SK~-~QHI81BteED zU%@-cT0o%%Q_Ccy-@9K9(TbJ60ng)g)_&*k){hz9t(xzAG&@79&SO3a0|o*+1{Dw6 zw14hx$NMbUOEK+v-q-uBiLXg2{qynwu1iZxYhNGhB7dy;1Cx_B2Y}&OfH~q%&x(|2 zRR3JN0hT9nIY`N~=2c79n_cX(V%Pwka_s6WjlcouEw}!^ISgc6-z*Q(^wc6%>ce(=PiI8c$=!Is$%y{ir#sT>% zn*GE7ay=#Bv=8CkVLXKSDLe-F<{O|%7=U!k1hVL~{LU1(3nsGp$P;j=?(gu?{HNSk z4m#3LQn0ZFu&HW#@v!OK)_^v=!cN)5kO&pZr^8JxJl-5tuXK1n0YLpk($mv}CL(C| zhYTJJV8L!8R{{`tq5Yo$KQZ+{4<_dJFTg(jjLMM$+$Ln5XT=H2n6vk)v4-GxyVD9k_Twz)SxvSiN+LJ1PgG(r!WX?*{@ZZD zisEHVdL3;5qC)^Nz>s`@vFtcb@bdF9_S7JRxBeHUPy>DQONrM34}J%<9OAIZ>jhfs2cOG??2qq$h5Tt;10e}L102I$+TZyry&aq3 zj6f&tbiWaTv_EnQ-)y)Xk9Am?43ZCW;NJhbEP~-6az69R6C*FYF z;-h~WVMo-LngV2>py$Kf> zir3M{0YM?)vPiUpGfCsIt#~JytFGgW!vcvsOvamb1e7=GB9ZiEUvj!L5Zw?aZ(If3 z_0#LCOa_wta269vbAcsf#rq}aj)CuKT$afrGR*)p6KX?qZ1sFzoNX)HZPz-g;&L6) zdP<&|z6$$7`Q;YtfnPISSLsFCJ^&Gh$fgO>1A3O*YX1jD^a>iG>b7qOX6l;zPVc~#4$V&{$&%ZPHu#(-2zb-4Wxj+wKDeyw}P@4_?%}0Ne)Ra6= zj`Id#Gaxmmt!KjcR_viu^_J?>Pj}!qZ#vT^qc%9zzrZm1uC@pixG>rqA~mq+aKc&+B(UcIbt>4CXcA1lqt&!_(zv z>`sEeaa*PjJ`y!R*iH^n+AS##O=wfqF*$%gAC&ZEMduHccE1!>E}a^OOlu!1#kk

p*{!;F<5Ul8|T?tG#g_V3}xw=O2-K-@D8kpb&9m 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 adE%iK+!|;EShm!VzfqJ`l_`)m_WM7c4!GU` literal 0 HcmV?d00001 diff --git a/frontend/src/components/AutoUpdatePoliciesView.tsx b/frontend/src/components/AutoUpdatePoliciesView.tsx index 24693ddb..2544a342 100644 --- a/frontend/src/components/AutoUpdatePoliciesView.tsx +++ b/frontend/src/components/AutoUpdatePoliciesView.tsx @@ -73,7 +73,12 @@ function formatTimestamp(ts: number | null): string { return new Date(ts).toLocaleString(); } -function AutoUpdatePoliciesContent() { +interface AutoUpdatePoliciesProps { + filterNodeId?: number | null; + onClearFilter?: () => void; +} + +function AutoUpdatePoliciesContent({ filterNodeId, onClearFilter }: AutoUpdatePoliciesProps) { const [policies, setPolicies] = useState([]); const [loading, setLoading] = useState(true); const [dialogOpen, setDialogOpen] = useState(false); @@ -100,6 +105,13 @@ function AutoUpdatePoliciesContent() { const [stacks, setStacks] = useState([]); const [nodes, setNodes] = useState([]); + const filteredPolicies = filterNodeId != null + ? policies.filter(p => p.node_id === filterNodeId) + : policies; + const filterNodeName = filterNodeId != null + ? nodes.find(n => n.id === filterNodeId)?.name + : null; + const fetchPolicies = useCallback(async () => { setLoading(true); try { @@ -153,11 +165,14 @@ function AutoUpdatePoliciesContent() { setEditingPolicy(null); setFormName(''); setFormTargetId(''); - setFormNodeId(''); + setFormNodeId(filterNodeId != null ? String(filterNodeId) : ''); setFormCron('0 3 * * *'); setFormCronPreset('0 3 * * *'); setFormEnabled(true); setDialogOpen(true); + if (filterNodeId != null) { + fetchStacks(String(filterNodeId)); + } }; const openEdit = (policy: ScheduledTask) => { @@ -297,11 +312,23 @@ function AutoUpdatePoliciesContent() {

- {loading && policies.length === 0 ? ( + {filterNodeId != null && filterNodeName && ( +
+ + Filtered to node: {filterNodeName} + + +
+ )} + {loading && filteredPolicies.length === 0 ? (
Loading...
- ) : policies.length === 0 ? ( + ) : filteredPolicies.length === 0 ? (
- No auto-update policies yet. Create one to keep your stacks up to date automatically. + {filterNodeId != null + ? 'No auto-update policies for this node. Create one to keep your stacks up to date automatically.' + : 'No auto-update policies yet. Create one to keep your stacks up to date automatically.'}
) : ( @@ -318,7 +345,7 @@ function AutoUpdatePoliciesContent() { - {policies.map((policy) => ( + {filteredPolicies.map((policy) => ( {policy.name} {policy.target_id === '*' ? 'All Stacks' : policy.target_id} @@ -561,10 +588,10 @@ function AutoUpdatePoliciesContent() { ); } -export default function AutoUpdatePoliciesView() { +export default function AutoUpdatePoliciesView({ filterNodeId, onClearFilter }: AutoUpdatePoliciesProps) { return ( - + ); } diff --git a/frontend/src/components/EditorLayout.tsx b/frontend/src/components/EditorLayout.tsx index d9d78c3e..7eaaae92 100644 --- a/frontend/src/components/EditorLayout.tsx +++ b/frontend/src/components/EditorLayout.tsx @@ -46,6 +46,8 @@ import { FleetView } from './FleetView'; import { AuditLogView } from './AuditLogView'; import ScheduledOperationsView from './ScheduledOperationsView'; import AutoUpdatePoliciesView from './AutoUpdatePoliciesView'; +import { SENCHO_NAVIGATE_EVENT } from './NodeManager'; +import type { SenchoNavigateDetail } from './NodeManager'; import { useNodes } from '@/context/NodeContext'; import type { Node } from '@/context/NodeContext'; import { useAuth } from '@/context/AuthContext'; @@ -131,6 +133,7 @@ export default function EditorLayout() { ); const isDarkMode = theme === 'dark' || (theme === 'auto' && systemDark); const [activeView, setActiveView] = useState<'dashboard' | 'editor' | 'host-console' | 'resources' | 'templates' | 'global-observability' | 'fleet' | 'audit-log' | 'scheduled-ops' | 'auto-updates'>('dashboard'); + const [filterNodeId, setFilterNodeId] = useState(null); const [isEditing, setIsEditing] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [stackStatuses, setStackStatuses] = useState({}); @@ -218,6 +221,7 @@ export default function EditorLayout() { setActiveView('dashboard'); } else { setActiveView(value as typeof activeView); + setFilterNodeId(null); } }; @@ -235,6 +239,19 @@ export default function EditorLayout() { localStorage.setItem('sencho-theme', theme); }, [isDarkMode, theme]); + // Listen for cross-component navigation (e.g., NodeManager → Schedules) + useEffect(() => { + const handler = (e: Event) => { + const detail = (e as CustomEvent).detail; + if (detail?.view) { + setActiveView(detail.view); + setFilterNodeId(detail.nodeId ?? null); + } + }; + window.addEventListener(SENCHO_NAVIGATE_EVENT, handler); + return () => window.removeEventListener(SENCHO_NAVIGATE_EVENT, handler); + }, []); + // Force Monaco to re-measure its container after the tab switch DOM settles. // Monaco's internal child is position:static with an explicit pixel height that // creates a circular CSS dependency (Monaco drives card height → grid height → Monaco). @@ -2017,9 +2034,9 @@ export default function EditorLayout() { ) : activeView === 'audit-log' ? ( ) : activeView === 'auto-updates' ? ( - + setFilterNodeId(null)} /> ) : activeView === 'scheduled-ops' ? ( - + setFilterNodeId(null)} /> ) : ( )} diff --git a/frontend/src/components/NodeManager.tsx b/frontend/src/components/NodeManager.tsx index 238f91fc..1c48de89 100644 --- a/frontend/src/components/NodeManager.tsx +++ b/frontend/src/components/NodeManager.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useState, useEffect, useCallback, useMemo } from 'react'; import { useNodes } from '@/context/NodeContext'; import type { Node } from '@/context/NodeContext'; import { apiFetch } from '@/lib/api'; @@ -13,7 +13,30 @@ import { Separator } from './ui/separator'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './ui/table'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './ui/tooltip'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select'; -import { Plus, Trash2, Wifi, WifiOff, Star, Pencil, Server, Monitor, Globe, Copy, KeyRound, Check, AlertTriangle } from 'lucide-react'; +import { Plus, Trash2, Wifi, WifiOff, Star, Pencil, Server, Monitor, Globe, Copy, KeyRound, Check, AlertTriangle, Calendar, RefreshCw } from 'lucide-react'; + +interface NodeSchedulingSummary { + active_tasks: number; + auto_update_enabled: boolean; + next_run_at: number | null; + stacks_with_updates: number; +} + +export const SENCHO_NAVIGATE_EVENT = 'sencho-navigate'; +export interface SenchoNavigateDetail { + view: 'scheduled-ops' | 'auto-updates'; + nodeId: number; +} + +function formatRelativeTime(timestamp: number): string { + const diff = timestamp - Date.now(); + if (diff < 0) return 'overdue'; + const mins = Math.floor(diff / 60000); + if (mins < 60) return `${mins}m`; + const hrs = Math.floor(mins / 60); + if (hrs < 24) return `${hrs}h`; + return `${Math.floor(hrs / 24)}d`; +} interface NodeFormData { name: string; @@ -49,6 +72,24 @@ export function NodeManager() { const [generatingToken, setGeneratingToken] = useState(false); const [tokenCopied, setTokenCopied] = useState(false); + // Per-node scheduling summary + const [nodeSummary, setNodeSummary] = useState>({}); + + const fetchSchedulingSummary = useCallback(async () => { + try { + const res = await apiFetch('/nodes/scheduling-summary', { localOnly: true }); + if (res.ok) setNodeSummary(await res.json()); + } catch { + // Non-fatal — summary is supplementary info + } + }, []); + + const nodeIdKey = useMemo(() => nodes.map(n => n.id).join(','), [nodes]); + + useEffect(() => { + fetchSchedulingSummary(); + }, [nodeIdKey, fetchSchedulingSummary]); + const handleCreate = async () => { try { const res = await apiFetch('/nodes', { @@ -407,6 +448,8 @@ export function NodeManager() { Type Endpoint Status + Schedules + Updates Actions @@ -438,8 +481,82 @@ export function NodeManager() { {node.type === 'local' ? 'docker.sock' : (node.api_url || '-')} {getStatusBadge(node.status)} + + {(() => { + const summary = nodeSummary[node.id]; + if (!summary || summary.active_tasks === 0) { + return ; + } + return ( +
+ + {summary.active_tasks} + + {summary.next_run_at && ( + + + + + next {formatRelativeTime(summary.next_run_at)} + + + + {new Date(summary.next_run_at).toLocaleString()} + + + + )} +
+ ); + })()} +
+ + {(() => { + const summary = nodeSummary[node.id]; + return ( +
+ {summary?.auto_update_enabled ? ( + + + Auto + + ) : ( + Off + )} + {(summary?.stacks_with_updates ?? 0) > 0 && ( + + + + {summary!.stacks_with_updates} + + + )} +
+ ); + })()} +
+ + + + + + View Schedules + + + diff --git a/frontend/src/components/ScheduledOperationsView.tsx b/frontend/src/components/ScheduledOperationsView.tsx index 881162a7..f140a597 100644 --- a/frontend/src/components/ScheduledOperationsView.tsx +++ b/frontend/src/components/ScheduledOperationsView.tsx @@ -72,7 +72,12 @@ function formatTimestamp(ts: number | null): string { return new Date(ts).toLocaleString(); } -export default function ScheduledOperationsView() { +interface ScheduledOperationsViewProps { + filterNodeId?: number | null; + onClearFilter?: () => void; +} + +export default function ScheduledOperationsView({ filterNodeId, onClearFilter }: ScheduledOperationsViewProps) { const [tasks, setTasks] = useState([]); const [loading, setLoading] = useState(true); const [dialogOpen, setDialogOpen] = useState(false); @@ -103,6 +108,13 @@ export default function ScheduledOperationsView() { const [stacks, setStacks] = useState([]); const [nodes, setNodes] = useState([]); + const filteredTasks = filterNodeId != null + ? tasks.filter(t => t.node_id === filterNodeId) + : tasks; + const filterNodeName = filterNodeId != null + ? nodes.find(n => n.id === filterNodeId)?.name + : null; + const fetchTasks = useCallback(async () => { setLoading(true); try { @@ -184,13 +196,16 @@ export default function ScheduledOperationsView() { setFormName(''); setFormAction('restart'); setFormTargetId(''); - setFormNodeId(''); + setFormNodeId(filterNodeId != null ? String(filterNodeId) : ''); setFormCron('0 3 * * *'); setFormEnabled(true); setFormPruneTargets(['containers', 'images', 'networks', 'volumes']); setFormTargetServices([]); setFormPruneLabelFilter(''); setDialogOpen(true); + if (filterNodeId != null) { + fetchStacks(String(filterNodeId)); + } }; const openEdit = (task: ScheduledTask) => { @@ -352,11 +367,23 @@ export default function ScheduledOperationsView() {
- {loading && tasks.length === 0 ? ( + {filterNodeId != null && filterNodeName && ( +
+ + Filtered to node: {filterNodeName} + + +
+ )} + {loading && filteredTasks.length === 0 ? (
Loading...
- ) : tasks.length === 0 ? ( + ) : filteredTasks.length === 0 ? (
- No scheduled tasks yet. Create one to automate recurring operations. + {filterNodeId != null + ? 'No scheduled tasks for this node. Create one to automate recurring operations.' + : 'No scheduled tasks yet. Create one to automate recurring operations.'}
) : (
@@ -373,7 +400,7 @@ export default function ScheduledOperationsView() { - {tasks.map((task) => ( + {filteredTasks.map((task) => ( {task.name}