mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-20 23:32:19 +00:00
feat(scheduler): group schedule action picker by operator intent (#1446)
* feat(scheduler): group schedule action picker by operator intent Reorganize the New Schedule action picker from a flat dropdown to a category-grouped list (Lifecycle, Updates, Security, Maintenance, Backups). - Extend Combobox component with optional group field on ComboboxOption, rendering grouped sections with non-interactive headers when groups are present. Flat rendering is unchanged for all other callers. - Reorder SCHEDULED_ACTIONS by category group and update seven action labels per the operator-intent spec. - Add DEFAULT_SCHEDULED_ACTION_ID constant so picker order and form defaults are independently controllable. - Wire grouped actionOptions into ScheduledOperationsView. - Update all label references in docs and tests. - Add Combobox grouping tests, registry order test, and default-constant test. * fix(scheduler): correct Combobox grouping for interleaved groups, docs labels - Replace last-group-append with Map-based group partitioning so interleaved or mixed-group options land in the correct group. - Add interleaved-groups test and restore non-interactivity test. - Update stale "Start Stack" references to "Start / Bring Up Stack" in doc action-label contexts. - Update action-picker alt text to describe the new grouped order.
This commit is contained in:
@@ -20,6 +20,7 @@ import {
|
||||
SCHEDULED_ACTION_CATEGORIES,
|
||||
getActionById,
|
||||
resolveTaskAction,
|
||||
DEFAULT_SCHEDULED_ACTION_ID,
|
||||
} from '@/lib/scheduledActions';
|
||||
|
||||
const DEFAULT_PRUNE_TARGETS = ['containers', 'images', 'networks', 'volumes'];
|
||||
@@ -194,7 +195,7 @@ export default function ScheduledOperationsView({ filterNodeId, onClearFilter, p
|
||||
const nodeId = prefillData?.nodeId ?? (filterNodeId != null ? String(filterNodeId) : '');
|
||||
setEditingTask(null);
|
||||
setFormName('');
|
||||
setFormAction(SCHEDULED_ACTIONS[0]?.id ?? 'restart');
|
||||
setFormAction(DEFAULT_SCHEDULED_ACTION_ID);
|
||||
setFormTargetId(prefillData?.stackName ?? '');
|
||||
setFormNodeId(nodeId);
|
||||
setFormCron('0 3 * * *');
|
||||
@@ -342,6 +343,15 @@ export default function ScheduledOperationsView({ filterNodeId, onClearFilter, p
|
||||
const cronDescription = getCronDescription(formCron);
|
||||
const cronFieldError = getCronFieldError(formCron);
|
||||
const nodeOptions = useMemo(() => nodes.map(n => ({ value: String(n.id), label: n.name })), [nodes]);
|
||||
const actionOptions = useMemo(
|
||||
() =>
|
||||
SCHEDULED_ACTIONS.map(o => ({
|
||||
value: o.id,
|
||||
label: o.label,
|
||||
group: SCHEDULED_ACTION_CATEGORIES.find(c => c.key === o.category)?.label,
|
||||
})),
|
||||
[],
|
||||
);
|
||||
// Scan and prune run on the hub-local Docker daemon only; remote nodes are excluded from their pickers.
|
||||
const localNodeOptions = useMemo(
|
||||
() => nodes.filter(n => n.type === 'local').map(n => ({ value: String(n.id), label: n.name })),
|
||||
@@ -670,7 +680,7 @@ export default function ScheduledOperationsView({ filterNodeId, onClearFilter, p
|
||||
<div className="space-y-2">
|
||||
<Label>Action</Label>
|
||||
<Combobox
|
||||
options={SCHEDULED_ACTIONS.map(o => ({ value: o.id, label: o.label }))}
|
||||
options={actionOptions}
|
||||
value={formAction}
|
||||
onValueChange={(val) => { setFormAction(val); setFormTargetId(''); setFormNodeId(''); setFormTargetServices([]); setFormPruneLabelFilter(''); }}
|
||||
placeholder="Select action..."
|
||||
|
||||
Reference in New Issue
Block a user