mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-29 19:57:12 +00:00
feat: add confirmed Take down stack action with optional volume removal (#1599)
* feat: add confirmed Take down stack action with optional volume removal Expose Take down in the stack header and sidebar with a confirmation dialog that runs compose down while keeping the stack definition on disk. Optional volume removal is gated by node capability and stack:deploy permission, with remote gateway preflight before proxying removeVolumes requests. Closes #1582 * fix: reset take-down volume checkbox when dialog closes * test: align getStackMenuVisibility assertions with showTakeDown key getStackMenuVisibility now returns a fifth lifecycle flag, showTakeDown, but three exhaustive toEqual assertions still listed only the prior four keys and failed. Add the expected showTakeDown value to each: true for the partial and exited running-stack cases, false for the self stack. * test: cover Take down visibility for running non-self stacks The getStackMenuVisibility assertions exercised the partial and exited branches and the self-stack guard, but not the raw === 'running' literal that drives showTakeDown for a normal running stack. Add a case so a regression dropping 'running' from that check is caught. * fix: drop Take down from header overflow and wire activity shortcut Remove duplicate Take down from More actions. Keep inline button when running, sidebar menu, and Cmd+ArrowDown. Record stack_taken_down in activity on successful POST /down.
This commit is contained in:
@@ -18,6 +18,7 @@ import { isDockerUnavailableError } from '../routes/stacks';
|
||||
const {
|
||||
mockDeployStack,
|
||||
mockRunCommand,
|
||||
mockRunDown,
|
||||
mockUpdateStack,
|
||||
mockGetContainersByStack,
|
||||
mockRestartContainer,
|
||||
@@ -26,6 +27,7 @@ const {
|
||||
} = vi.hoisted(() => ({
|
||||
mockDeployStack: vi.fn(),
|
||||
mockRunCommand: vi.fn(),
|
||||
mockRunDown: vi.fn(),
|
||||
mockUpdateStack: vi.fn(),
|
||||
mockGetContainersByStack: vi.fn(),
|
||||
mockRestartContainer: vi.fn(),
|
||||
@@ -44,6 +46,7 @@ vi.mock('../services/ComposeService', async () => {
|
||||
getInstance: () => ({
|
||||
deployStack: mockDeployStack,
|
||||
runCommand: mockRunCommand,
|
||||
runDown: mockRunDown,
|
||||
updateStack: mockUpdateStack,
|
||||
}),
|
||||
},
|
||||
@@ -98,6 +101,7 @@ afterAll(() => {
|
||||
beforeEach(() => {
|
||||
mockDeployStack.mockReset();
|
||||
mockRunCommand.mockReset();
|
||||
mockRunDown.mockReset();
|
||||
mockUpdateStack.mockReset();
|
||||
mockGetContainersByStack.mockReset();
|
||||
mockRestartContainer.mockReset();
|
||||
@@ -211,8 +215,8 @@ describe('POST /api/stacks/:name/deploy with daemon down', () => {
|
||||
});
|
||||
|
||||
describe('POST /api/stacks/:name/down with daemon down', () => {
|
||||
it('returns 503 with code: docker_unavailable when runCommand surfaces the daemon error', async () => {
|
||||
mockRunCommand.mockRejectedValue(composeDaemonDownError());
|
||||
it('returns 503 with code: docker_unavailable when runDown surfaces the daemon error', async () => {
|
||||
mockRunDown.mockRejectedValue(composeDaemonDownError());
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/stacks/web/down')
|
||||
|
||||
Reference in New Issue
Block a user