This commit is contained in:
Julian Lohrber 2024-12-28 15:17:44 +01:00 committed by GitHub
commit a5bf872a42
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 102 additions and 11 deletions

View file

@ -76,12 +76,14 @@ export class AgentManager {
* @param url
* @param username
* @param password
* @param name
*/
async add(url : string, username : string, password : string) : Promise<Agent> {
async add(url: string, username: string, password: string, name: string): Promise<Agent> {
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) {

View file

@ -7,6 +7,7 @@ export async function up(knex: Knex): Promise<void> {
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);
});
}

View file

@ -23,6 +23,7 @@ export class Agent extends BeanModel {
url: this.url,
username: this.username,
endpoint: this.endpoint,
name: this.name,
};
}

View file

@ -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);
}
});
}
}

View file

@ -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']
@ -29,4 +32,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']
}
}

View file

@ -114,6 +114,8 @@
"removeAgent": "Remove Agent",
"removeAgentMsg": "Are you sure you want to remove this agent?",
"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",

View file

@ -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;
}
}
}
},

View file

@ -99,7 +99,7 @@
<label for="name" class="form-label">{{ $t("dockgeAgent") }}</label>
<select v-model="stack.endpoint" class="form-select">
<option v-for="(agent, endpoint) in $root.agentList" :key="endpoint" :value="endpoint" :disabled="$root.agentStatusList[endpoint] != 'online'">
({{ $root.agentStatusList[endpoint] }}) {{ (endpoint) ? endpoint : $t("currentEndpoint") }}
({{ $root.agentStatusList[endpoint] }}) {{ (agent.name !== '') ? agent.name : agent.url || $t("Controller") }}
</option>
</select>
</div>

View file

@ -49,13 +49,25 @@
</template>
<!-- Agent Display Name -->
<span v-if="endpoint === ''">{{ $t("currentEndpoint") }}</span>
<a v-else :href="agent.url" target="_blank">{{ endpoint }}</a>
<template v-if="$root.agentStatusList[endpoint]">
<span v-if="endpoint === '' && agent.name === ''" class="badge bg-secondary me-2">Controller</span>
<span v-else-if="agent.name === ''" :href="agent.url" class="me-2">{{ endpoint }}</span>
<span v-else :href="agent.url" class="me-2">{{ agent.name }}</span>
</template>
<!-- Edit Name -->
<font-awesome-icon icon="pen-to-square" @click="showEditAgentNameDialog[agent.name] = !showEditAgentNameDialog[agent.Name]" />
<!-- Edit Dialog -->
<BModal v-model="showEditAgentNameDialog[agent.name]" :no-close-on-backdrop="true" :close-on-esc="true" :okTitle="$t('Update Name')" okVariant="info" @ok="updateName(agent.url, agent.updatedName)">
<label for="Update Name" class="form-label">Current value: {{ $t(agent.name) }}</label>
<input id="updatedName" v-model="agent.updatedName" type="text" class="form-control" optional>
</BModal>
<!-- Remove Button -->
<font-awesome-icon v-if="endpoint !== ''" class="ms-2 remove-agent" icon="trash" @click="showRemoveAgentDialog[agent.url] = !showRemoveAgentDialog[agent.url]" />
<!-- Remoe Agent Dialog -->
<!-- Remove Agent Dialog -->
<BModal v-model="showRemoveAgentDialog[agent.url]" :okTitle="$t('removeAgent')" okVariant="danger" @ok="removeAgent(agent.url)">
<p>{{ agent.url }}</p>
{{ $t("removeAgentMsg") }}
@ -81,6 +93,11 @@
<input id="password" v-model="agent.password" type="password" class="form-control" required autocomplete="new-password">
</div>
<div class="mb-3">
<label for="name" class="form-label">{{ $t("Friendly Name") }}</label>
<input id="name" v-model="agent.name" type="text" class="form-control" optional>
</div>
<button type="submit" class="btn btn-primary" :disabled="connectingAgent">
<template v-if="connectingAgent">{{ $t("connecting") }}</template>
<template v-else>{{ $t("connect") }}</template>
@ -121,11 +138,14 @@ export default {
dockerRunCommand: "",
showAgentForm: false,
showRemoveAgentDialog: {},
showEditAgentNameDialog: {},
connectingAgent: false,
agent: {
url: "http://",
username: "",
password: "",
name: "",
updatedName: "",
}
};
},
@ -199,6 +219,19 @@ export default {
});
},
updateName(url, updatedName) {
this.$root.getSocket().emit("updateAgent", url, updatedName, (res) => {
this.$root.toastRes(res);
if (res.ok) {
this.showAgentForm = false;
this.agent = {
updatedName: "",
};
}
});
},
getStatusNum(statusName) {
let num = 0;
@ -286,7 +319,7 @@ export default {
}
},
},
}
};
</script>