From caa82bbad52a9f956ceedce84fbaabe535796f99 Mon Sep 17 00:00:00 2001 From: Louis Lam Date: Sat, 11 Nov 2023 19:14:27 +0800 Subject: [PATCH] wip --- backend/dockge-server.ts | 15 ++ .../socket-handlers/docker-socket-handler.ts | 14 ++ frontend/components.d.ts | 1 + frontend/src/components/ArraySelect.vue | 125 ++++++++++++++ frontend/src/components/Container.vue | 15 +- frontend/src/components/NetworkInput.vue | 161 +++++++++++++++--- frontend/src/lang/en.json | 6 +- frontend/src/pages/Compose.vue | 12 +- package.json | 2 +- pnpm-lock.yaml | 14 +- 10 files changed, 329 insertions(+), 36 deletions(-) create mode 100644 frontend/src/components/ArraySelect.vue diff --git a/backend/dockge-server.ts b/backend/dockge-server.ts index 9d6fc43..ca081b5 100644 --- a/backend/dockge-server.ts +++ b/backend/dockge-server.ts @@ -29,6 +29,7 @@ import { Stack } from "./stack"; import { Cron } from "croner"; import gracefulShutdown from "http-graceful-shutdown"; import User from "./models/user"; +import childProcess from "child_process"; export class DockgeServer { app : Express; @@ -516,6 +517,20 @@ export class DockgeServer { } } + getDockerNetworkList() : string[] { + let res = childProcess.spawnSync("docker", [ "network", "ls", "--format", "{{.Name}}" ]); + let list = res.stdout.toString().split("\n"); + + // Remove empty string item + list = list.filter((item) => { + return item !== ""; + }).sort((a, b) => { + return a.localeCompare(b); + }); + + return list; + } + get stackDirFullPath() { return path.resolve(this.stacksDir); } diff --git a/backend/socket-handlers/docker-socket-handler.ts b/backend/socket-handlers/docker-socket-handler.ts index 557f5f0..e1049e8 100644 --- a/backend/socket-handlers/docker-socket-handler.ts +++ b/backend/socket-handlers/docker-socket-handler.ts @@ -203,6 +203,20 @@ export class DockerSocketHandler extends SocketHandler { callbackError(e, callback); } }); + + // getExternalNetworkList + socket.on("getDockerNetworkList", async (callback) => { + try { + checkLogin(socket); + const dockerNetworkList = server.getDockerNetworkList(); + callback({ + ok: true, + dockerNetworkList, + }); + } catch (e) { + callbackError(e, callback); + } + }); } saveStack(socket : DockgeSocket, server : DockgeServer, name : unknown, composeYAML : unknown, isAdd : unknown) : Stack { diff --git a/frontend/components.d.ts b/frontend/components.d.ts index f2e49e3..bafec4c 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -10,6 +10,7 @@ declare module 'vue' { About: typeof import('./src/components/settings/About.vue')['default'] Appearance: typeof import('./src/components/settings/Appearance.vue')['default'] ArrayInput: typeof import('./src/components/ArrayInput.vue')['default'] + ArraySelect: typeof import('./src/components/ArraySelect.vue')['default'] BModal: typeof import('bootstrap-vue-next')['BModal'] Confirm: typeof import('./src/components/Confirm.vue')['default'] Container: typeof import('./src/components/Container.vue')['default'] diff --git a/frontend/src/components/ArraySelect.vue b/frontend/src/components/ArraySelect.vue new file mode 100644 index 0000000..563bcbd --- /dev/null +++ b/frontend/src/components/ArraySelect.vue @@ -0,0 +1,125 @@ + + + + + diff --git a/frontend/src/components/Container.vue b/frontend/src/components/Container.vue index 57b3843..3e242ec 100644 --- a/frontend/src/components/Container.vue +++ b/frontend/src/components/Container.vue @@ -114,7 +114,12 @@ - + +
+ No networks available. You need to add internal networks or enable external networks in the right side first. +
+ + @@ -165,6 +170,14 @@ export default defineComponent({ }, computed: { + networkList() { + let list = []; + for (const networkName in this.jsonObject.networks) { + list.push(networkName); + } + return list; + }, + bgStyle() { if (this.status === "running") { return "bg-primary"; diff --git a/frontend/src/components/NetworkInput.vue b/frontend/src/components/NetworkInput.vue index 2788dc0..57f3c3f 100644 --- a/frontend/src/components/NetworkInput.vue +++ b/frontend/src/components/NetworkInput.vue @@ -1,69 +1,157 @@ @@ -103,4 +214,10 @@ export default { } } } + +.delete { + text-decoration: underline; + font-size: 13px; + cursor: pointer; +} diff --git a/frontend/src/lang/en.json b/frontend/src/lang/en.json index 1f48588..2df544b 100644 --- a/frontend/src/lang/en.json +++ b/frontend/src/lang/en.json @@ -45,5 +45,9 @@ "disableauth.message1": "Are you sure want to disable authentication?", "disableauth.message2": "It is designed for scenarios where you intend to implement third-party authentication in front of Uptime Kuma such as Cloudflare Access, Authelia or other authentication mechanisms.", "passwordNotMatchMsg": "The repeat password does not match.", - "autoGet": "Auto Get" + "autoGet": "Auto Get", + "add": "Add", + "applyToYAML": "Apply to YAML", + "createExternalNetwork": "Create", + "addInternalNetwork": "Add" } diff --git a/frontend/src/pages/Compose.vue b/frontend/src/pages/Compose.vue index 3d87034..1a12e78 100644 --- a/frontend/src/pages/Compose.vue +++ b/frontend/src/pages/Compose.vue @@ -137,14 +137,18 @@
+ +
+

{{ $tc("volume", 2) }}

+
+
+
+ +

{{ $tc("network", 2) }}

- -

{{ $tc("volume", 2) }}

-
-