mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-30 21:52:22 +00:00
fix: keep the schedule's stack selected on prefill and edit (#1496)
Opening the New Schedule modal from a stack's Schedule action, or editing a stack-targeted task, set the node and the stack, but the node-change effect then ran and cleared the stack, forcing the user to reselect it. Move the stack-clear out of that effect into the Node picker's change handler so it only fires on a user-driven node change. A programmatic node set from prefill or edit now preserves the stack.
This commit is contained in:
@@ -201,12 +201,13 @@ export default function ScheduledOperationsView({ filterNodeId, onClearFilter, p
|
||||
return () => { cancelled = true; };
|
||||
}, [formAction, formTargetId, formNodeId]);
|
||||
|
||||
// Re-fetch stacks when node changes
|
||||
// Re-fetch stacks when the node changes. Clearing a stale stack selection is
|
||||
// done in the Node picker's onValueChange (a user-driven change), not here, so
|
||||
// a prefilled or edited node keeps its stack instead of being wiped on open.
|
||||
useEffect(() => {
|
||||
if (!dialogOpen) return;
|
||||
if (formNodeId) {
|
||||
fetchStacks(formNodeId);
|
||||
setFormTargetId('');
|
||||
} else {
|
||||
setStacks([]);
|
||||
}
|
||||
@@ -790,7 +791,7 @@ export default function ScheduledOperationsView({ filterNodeId, onClearFilter, p
|
||||
<Combobox
|
||||
options={nodeOptions}
|
||||
value={formNodeId}
|
||||
onValueChange={setFormNodeId}
|
||||
onValueChange={(val) => { setFormNodeId(val); setFormTargetId(''); }}
|
||||
placeholder="Select node..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -125,6 +125,39 @@ describe('ScheduledOperationsView', () => {
|
||||
expect(onPrefillConsumed).toHaveBeenCalledTimes(1);
|
||||
// The prefilled stack drives a node-scoped stack fetch through the proxy.
|
||||
await waitFor(() => expect(mockedFetchForNode).toHaveBeenCalledWith('/stacks', 1));
|
||||
// The prefilled stack stays selected; the node-change effect must not wipe it.
|
||||
// Comboboxes render in order: action, node, stack.
|
||||
await waitFor(() => expect(screen.getAllByRole('combobox')[2]).toHaveTextContent('web'));
|
||||
});
|
||||
|
||||
it('keeps the stack selected when editing a stack-targeted task', async () => {
|
||||
tasksFixture = [makeTask({
|
||||
id: 9, name: 'restart-web', action: 'restart', target_type: 'stack', target_id: 'web', node_id: 1,
|
||||
})];
|
||||
render(<ScheduledOperationsView />);
|
||||
|
||||
await userEvent.click(await screen.findByRole('button', { name: /All tasks/ }));
|
||||
await userEvent.click(await screen.findByTitle('Edit'));
|
||||
await waitFor(() => expect(screen.getAllByRole('combobox')[2]).toHaveTextContent('web'));
|
||||
});
|
||||
|
||||
it('clears the stale stack when the user changes the node', async () => {
|
||||
render(<ScheduledOperationsView />);
|
||||
|
||||
await userEvent.click(await screen.findByRole('button', { name: /New Schedule/ }));
|
||||
// Default action Restart Stack: choose a node, then a stack on it.
|
||||
await userEvent.click(screen.getAllByRole('combobox')[1]);
|
||||
await userEvent.click(await screen.findByRole('button', { name: 'hub' }));
|
||||
await userEvent.click(screen.getAllByRole('combobox')[2]);
|
||||
await userEvent.click(await screen.findByRole('button', { name: 'web' }));
|
||||
expect(screen.getAllByRole('combobox')[2]).toHaveTextContent('web');
|
||||
|
||||
// Switching node is a user-driven change, so the now-stale stack clears
|
||||
// and the user must re-pick one before the schedule can be saved.
|
||||
await userEvent.click(screen.getAllByRole('combobox')[1]);
|
||||
await userEvent.click(await screen.findByRole('button', { name: 'edge' }));
|
||||
expect(screen.getAllByRole('combobox')[2]).toHaveTextContent('Select stack...');
|
||||
expect(screen.getByRole('button', { name: 'Create' })).toBeDisabled();
|
||||
});
|
||||
|
||||
it('filters the table to the selected node and clears the filter', async () => {
|
||||
|
||||
Reference in New Issue
Block a user