add checkbox to confirm stack files deletion

This commit is contained in:
husa 2025-01-17 15:33:29 +02:00
parent d451e06e84
commit 4b6c44f99f
4 changed files with 23 additions and 10 deletions

View File

@ -1,7 +1,7 @@
import { AgentSocketHandler } from "../agent-socket-handler";
import { DockgeServer } from "../dockge-server";
import { callbackError, callbackResult, checkLogin, DockgeSocket, ValidationError } from "../util-server";
import { Stack } from "../stack";
import { DeleteOptions, Stack } from "../stack";
import { AgentSocket } from "../../common/agent-socket";
export class DockerSocketHandler extends AgentSocketHandler {
@ -40,7 +40,7 @@ export class DockerSocketHandler extends AgentSocketHandler {
}
});
agentSocket.on("deleteStack", async (name : unknown, callback) => {
agentSocket.on("deleteStack", async (name : unknown, deleteOptions: unknown, callback) => {
try {
checkLogin(socket);
if (typeof(name) !== "string") {
@ -49,7 +49,7 @@ export class DockerSocketHandler extends AgentSocketHandler {
const stack = await Stack.getStack(server, name);
try {
await stack.delete(socket);
await stack.delete(socket, deleteOptions as DeleteOptions);
} catch (e) {
server.sendStackList();
throw e;

View File

@ -20,6 +20,10 @@ import { InteractiveTerminal, Terminal } from "./terminal";
import childProcessAsync from "promisify-child-process";
import { Settings } from "./settings";
export interface DeleteOptions {
deleteStackFiles: boolean
}
export class Stack {
name: string;
@ -215,18 +219,20 @@ export class Stack {
return exitCode;
}
async delete(socket: DockgeSocket) : Promise<number> {
async delete(socket: DockgeSocket, options: DeleteOptions) : Promise<number> {
const terminalName = getComposeTerminalName(socket.endpoint, this.name);
let exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", [ "compose", "down", "--remove-orphans" ], this.path);
if (exitCode !== 0) {
throw new Error("Failed to delete, please check the terminal output for more information.");
}
// Remove the stack folder
await fsAsync.rm(this.path, {
recursive: true,
force: true
});
if (options.deleteStackFiles) {
// Remove the stack folder
await fsAsync.rm(this.path, {
recursive: true,
force: true
});
}
return exitCode;
}

View File

@ -25,6 +25,7 @@
"saveStackDraft": "Save",
"notAvailableShort": "N/A",
"deleteStackMsg": "Are you sure you want to delete this stack?",
"deleteStackFilesConfirmation": "delete all stack files",
"stackNotManagedByDockgeMsg": "This stack is not managed by Dockge.",
"primaryHostname": "Primary Hostname",
"general": "General",

View File

@ -55,6 +55,7 @@
</div>
<button v-if="isEditMode && !isAdd" class="btn btn-normal" :disabled="processing" @click="discardStack">{{ $t("discardStack") }}</button>
<button v-if="!isEditMode" class="btn btn-danger" :disabled="processing" @click="showDeleteDialog = !showDeleteDialog">
<font-awesome-icon icon="trash" class="me-1" />
{{ $t("deleteStack") }}
@ -231,6 +232,10 @@
<!-- Delete Dialog -->
<BModal v-model="showDeleteDialog" :okTitle="$t('deleteStack')" okVariant="danger" @ok="deleteDialog">
{{ $t("deleteStackMsg") }}
<div class="form-check mt-4">
<label><input v-model="deleteStackFiles" class="form-check-input" type="checkbox" />{{
$t("deleteStackFilesConfirmation") }}</label>
</div>
</BModal>
</div>
</transition>
@ -309,6 +314,7 @@ export default {
isEditMode: false,
submitted: false,
showDeleteDialog: false,
deleteStackFiles: false,
newContainerName: "",
stopServiceStatusTimeout: false,
};
@ -646,7 +652,7 @@ export default {
},
deleteDialog() {
this.$root.emitAgent(this.endpoint, "deleteStack", this.stack.name, (res) => {
this.$root.emitAgent(this.endpoint, "deleteStack", this.stack.name, { deleteStackFiles: this.deleteStackFiles }, (res) => {
this.$root.toastRes(res);
if (res.ok) {
this.$router.push("/");