feat(scheduler): add helper text and risk badges to scheduled action picker (#1449)

* feat(scheduler): add helper text and risk badges to scheduled action picker

Add a concise helper text and risk level badge to every scheduled action
in the create/edit modal. The six risk levels (Safe, Read-only, Interruptive,
Runtime change, Removes containers, Destructive) map to the four existing
design-system tones and render as a small dot+label chip next to the helper
text, following the same pattern as SeverityBadge.

Fix an ambiguous mobile label: update + target_type: fleet now resolves
through resolveTaskAction and renders 'update node stacks' instead of the
misleading 'update fleet'.

Add exact helper-text and risk-level assertions for all 10 actions, plus
component tests for default modal state, action-switch scenarios, and
mobile update+fleet rendering.

* docs: update stale scheduled-operations alt text for changed helper text
This commit is contained in:
Anso
2026-06-25 02:37:12 -04:00
committed by GitHub
parent 79f840ab6e
commit 7982251dc6
7 changed files with 240 additions and 27 deletions
@@ -454,4 +454,44 @@ describe('ScheduledOperationsView', () => {
});
});
});
describe('risk badge and helper text', () => {
it('shows Interruptive badge and helper for the default action Restart Stack', async () => {
render(<ScheduledOperationsView />);
await userEvent.click(await screen.findByRole('button', { name: /New Schedule/ }));
expect(screen.getByText('Interruptive')).toBeInTheDocument();
expect(screen.getByText(
'Restarts containers in place. Running services are stopped and started again on the same configuration.',
)).toBeInTheDocument();
});
it('shows Safe badge and helper for Create Fleet Snapshot', async () => {
render(<ScheduledOperationsView />);
await userEvent.click(await screen.findByRole('button', { name: /New Schedule/ }));
// Switch action to Create Fleet Snapshot (a non-node, non-stack action).
await userEvent.click(screen.getAllByRole('combobox')[0]);
await userEvent.click(await screen.findByRole('button', { name: 'Create Fleet Snapshot' }));
expect(screen.getByText('Safe')).toBeInTheDocument();
expect(screen.getByText(
'Creates a versioned snapshot of compose and env files across the fleet.',
)).toBeInTheDocument();
});
it('shows Destructive badge and helper for Prune Node Resources', async () => {
render(<ScheduledOperationsView />);
await userEvent.click(await screen.findByRole('button', { name: /New Schedule/ }));
// Switch action to Prune Node Resources.
await userEvent.click(screen.getAllByRole('combobox')[0]);
await userEvent.click(await screen.findByRole('button', { name: 'Prune Node Resources' }));
expect(screen.getByText('Destructive')).toBeInTheDocument();
expect(screen.getByText(
'Removes unused Docker resources on the selected node. Be careful when pruning volumes.',
)).toBeInTheDocument();
});
});
});