From e589d4ec7e3e4e879f6a5d93f7ac5e9fa24659a4 Mon Sep 17 00:00:00 2001 From: Julian Date: Sat, 11 Apr 2026 21:46:45 +0200 Subject: [PATCH] feat: dockge set/update agent friendly name (#414) Co-authored-by: cmcooper1980 <31871143+cmcooper1980@users.noreply.github.com> --- backend/agent-manager.ts | 23 ++++++++++- .../migrations/2023-12-20-2117-agent-table.ts | 1 + backend/models/agent.ts | 1 + .../manage-agent-socket-handler.ts | 24 ++++++++++- frontend/components.d.ts | 6 +++ frontend/src/lang/en.json | 2 + frontend/src/mixins/socket.ts | 13 ++++-- frontend/src/pages/Compose.vue | 4 +- frontend/src/pages/DashboardHome.vue | 41 +++++++++++++++++-- 9 files changed, 103 insertions(+), 12 deletions(-) diff --git a/backend/agent-manager.ts b/backend/agent-manager.ts index d0658f4..50bc1ef 100644 --- a/backend/agent-manager.ts +++ b/backend/agent-manager.ts @@ -76,12 +76,14 @@ export class AgentManager { * @param url * @param username * @param password + * @param name */ - async add(url : string, username : string, password : string) : Promise { + async add(url: string, username: string, password: string, name: string): Promise { let bean = R.dispense("agent") as Agent; bean.url = url; bean.username = username; bean.password = password; + bean.name = name; await R.store(bean); return bean; } @@ -106,6 +108,23 @@ export class AgentManager { } } + /** + * + * @param url + * @param updatedName + */ + async update(url: string, updatedName: string) { + const agent = await R.findOne("agent", " url = ? ", [ + url, + ]); + if (agent) { + agent.name = updatedName; + await R.store(agent); + } else { + throw new Error("Agent not found"); + } + } + connect(url : string, username : string, password : string) { let obj = new URL(url); let endpoint = obj.host; @@ -278,6 +297,8 @@ export class AgentManager { url: "", username: "", endpoint: "", + name: "", + updatedName: "", }; for (let endpoint in list) { diff --git a/backend/migrations/2023-12-20-2117-agent-table.ts b/backend/migrations/2023-12-20-2117-agent-table.ts index ae18d1d..c06f6f7 100644 --- a/backend/migrations/2023-12-20-2117-agent-table.ts +++ b/backend/migrations/2023-12-20-2117-agent-table.ts @@ -7,6 +7,7 @@ export async function up(knex: Knex): Promise { table.string("url", 255).notNullable().unique(); table.string("username", 255).notNullable(); table.string("password", 255).notNullable(); + table.string("name", 255); table.boolean("active").notNullable().defaultTo(true); }); } diff --git a/backend/models/agent.ts b/backend/models/agent.ts index f806a3d..fff3cb6 100644 --- a/backend/models/agent.ts +++ b/backend/models/agent.ts @@ -23,6 +23,7 @@ export class Agent extends BeanModel { url: this.url, username: this.username, endpoint: this.endpoint, + name: this.name, }; } diff --git a/backend/socket-handlers/manage-agent-socket-handler.ts b/backend/socket-handlers/manage-agent-socket-handler.ts index 6f8fef4..13c7e1b 100644 --- a/backend/socket-handlers/manage-agent-socket-handler.ts +++ b/backend/socket-handlers/manage-agent-socket-handler.ts @@ -20,7 +20,7 @@ export class ManageAgentSocketHandler extends SocketHandler { let data = requestData as LooseObject; let manager = socket.instanceManager; await manager.test(data.url, data.username, data.password); - await manager.add(data.url, data.username, data.password); + await manager.add(data.url, data.username, data.password, data.name); // connect to the agent manager.connect(data.url, data.username, data.password); @@ -66,5 +66,27 @@ export class ManageAgentSocketHandler extends SocketHandler { callbackError(e, callback); } }); + + // updateAgent + socket.on("updateAgent", async (name : string, updatedName : string, callback : unknown) => { + try { + log.debug("manage-agent-socket-handler", "updateAgent"); + checkLogin(socket); + + let manager = socket.instanceManager; + await manager.update(name, updatedName); + + server.disconnectAllSocketClients(undefined, socket.id); + manager.sendAgentList(); + + callbackResult({ + ok: true, + msg: "agentUpdatedSuccessfully", + msgi18n: true, + }, callback); + } catch (e) { + callbackError(e, callback); + } + }); } } diff --git a/frontend/components.d.ts b/frontend/components.d.ts index 300dbd7..8ef0c26 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -11,8 +11,11 @@ declare module 'vue' { 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'] + BButton: typeof import('bootstrap-vue-next')['BButton'] BDropdown: typeof import('bootstrap-vue-next')['BDropdown'] BDropdownItem: typeof import('bootstrap-vue-next')['BDropdownItem'] + BFormGroup: typeof import('bootstrap-vue-next')['BFormGroup'] + BFormInput: typeof import('bootstrap-vue-next')['BFormInput'] BModal: typeof import('bootstrap-vue-next')['BModal'] Confirm: typeof import('./src/components/Confirm.vue')['default'] Container: typeof import('./src/components/Container.vue')['default'] @@ -30,4 +33,7 @@ declare module 'vue' { TwoFADialog: typeof import('./src/components/TwoFADialog.vue')['default'] Uptime: typeof import('./src/components/Uptime.vue')['default'] } + export interface ComponentCustomProperties { + vBModal: typeof import('bootstrap-vue-next')['vBModal'] + } } diff --git a/frontend/src/lang/en.json b/frontend/src/lang/en.json index 63d45b4..e703f6d 100644 --- a/frontend/src/lang/en.json +++ b/frontend/src/lang/en.json @@ -116,6 +116,8 @@ "removeAgentMsg": "Are you sure you want to remove this agent?", "GlobalEnv": "Global .env", "LongSyntaxNotSupported": "Long syntax is not supported here. Please use the YAML editor.", + "name": "Dockge Agent Display name", + "updatedName": "New Dockge Agent Display name", "Saved": "Saved", "Deployed": "Deployed", "Deleted": "Deleted", diff --git a/frontend/src/mixins/socket.ts b/frontend/src/mixins/socket.ts index b789ff6..15a140a 100644 --- a/frontend/src/mixins/socket.ts +++ b/frontend/src/mixins/socket.ts @@ -131,10 +131,15 @@ export default defineComponent({ methods: { endpointDisplayFunction(endpoint : string) { - if (endpoint) { - return endpoint; - } else { - return this.$t("currentEndpoint"); + for (const [k, v] of Object.entries(this.$data.agentList)) { + if (endpoint) { + if (endpoint === v["endpoint"] && v["name"] !== "") { + return v["name"]; + } + if (endpoint === v["endpoint"] && v["name"] === "" ) { + return endpoint; + } + } } }, diff --git a/frontend/src/pages/Compose.vue b/frontend/src/pages/Compose.vue index 416b13d..d6750aa 100644 --- a/frontend/src/pages/Compose.vue +++ b/frontend/src/pages/Compose.vue @@ -4,7 +4,7 @@

{{ $t("compose") }}

{{ stack.name }} - + ({{ endpointDisplay }})

@@ -99,7 +99,7 @@ diff --git a/frontend/src/pages/DashboardHome.vue b/frontend/src/pages/DashboardHome.vue index 3923663..f7bda6a 100644 --- a/frontend/src/pages/DashboardHome.vue +++ b/frontend/src/pages/DashboardHome.vue @@ -49,13 +49,25 @@ - {{ $t("currentEndpoint") }} - {{ endpoint }} + + + + + + + + + + - +

{{ agent.url }}

{{ $t("removeAgentMsg") }} @@ -81,6 +93,11 @@ +
+ + +
+