mirror of
https://github.com/louislam/dockge.git
synced 2025-02-26 05:25:56 +00:00
Compare commits
19 commits
9d19c6476a
...
bdbe3d1de2
Author | SHA1 | Date | |
---|---|---|---|
|
bdbe3d1de2 | ||
|
d451e06e84 | ||
|
70bcc3fa77 | ||
|
29cc257717 | ||
|
5b2ac56d53 | ||
|
1c72c23436 | ||
|
49eda70373 | ||
|
825b72761b | ||
|
dcc48d3240 | ||
|
052cf17563 | ||
|
9748469585 | ||
|
a8b75fb65a | ||
|
2b64b3f9dd | ||
|
5885665b4d | ||
|
62ceb44a5e | ||
|
8f142af12e | ||
|
54e158f75a | ||
|
11f5fff65d | ||
|
c0fc76a0c8 |
11 changed files with 352 additions and 179 deletions
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ export class Agent extends BeanModel {
|
|||
url: this.url,
|
||||
username: this.username,
|
||||
endpoint: this.endpoint,
|
||||
name: this.name,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
6
frontend/components.d.ts
vendored
6
frontend/components.d.ts
vendored
|
@ -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']
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -131,10 +131,15 @@ export default defineComponent({
|
|||
methods: {
|
||||
|
||||
endpointDisplayFunction(endpoint : string) {
|
||||
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;
|
||||
} else {
|
||||
return this.$t("currentEndpoint");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
18
package.json
18
package.json
|
@ -40,7 +40,7 @@
|
|||
"dotenv": "~16.3.2",
|
||||
"express": "~4.21.2",
|
||||
"express-static-gzip": "~2.1.8",
|
||||
"http-graceful-shutdown": "~3.1.13",
|
||||
"http-graceful-shutdown": "~3.1.14",
|
||||
"jsonwebtoken": "~9.0.2",
|
||||
"jwt-decode": "~3.1.2",
|
||||
"knex": "~2.5.1",
|
||||
|
@ -49,8 +49,8 @@
|
|||
"promisify-child-process": "~4.1.2",
|
||||
"redbean-node": "~0.3.3",
|
||||
"semver": "^7.6.3",
|
||||
"socket.io": "~4.8.0",
|
||||
"socket.io-client": "~4.8.0",
|
||||
"socket.io": "~4.8.1",
|
||||
"socket.io-client": "~4.8.1",
|
||||
"timezones-list": "~3.0.3",
|
||||
"ts-command-line-args": "~2.5.1",
|
||||
"tsx": "~4.19.2",
|
||||
|
@ -59,7 +59,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@actions/github": "^6.0.0",
|
||||
"@fontsource/jetbrains-mono": "^5.1.1",
|
||||
"@fontsource/jetbrains-mono": "^5.1.2",
|
||||
"@fortawesome/fontawesome-svg-core": "6.4.2",
|
||||
"@fortawesome/free-regular-svg-icons": "6.4.2",
|
||||
"@fortawesome/free-solid-svg-icons": "6.4.2",
|
||||
|
@ -81,19 +81,19 @@
|
|||
"cross-env": "~7.0.3",
|
||||
"eslint": "~8.50.0",
|
||||
"eslint-plugin-jsdoc": "~46.8.2",
|
||||
"eslint-plugin-vue": "~9.17.0",
|
||||
"eslint-plugin-vue": "~9.32.0",
|
||||
"prismjs": "~1.29.0",
|
||||
"sass": "~1.68.0",
|
||||
"typescript": "~5.2.2",
|
||||
"unplugin-vue-components": "~0.25.2",
|
||||
"vite": "~5.4.8",
|
||||
"vite": "~5.4.11",
|
||||
"vite-plugin-compression": "~0.5.1",
|
||||
"vue": "~3.5.12",
|
||||
"vue": "~3.5.13",
|
||||
"vue-eslint-parser": "~9.3.2",
|
||||
"vue-i18n": "~9.5.0",
|
||||
"vue-i18n": "~10.0.5",
|
||||
"vue-prism-editor": "2.0.0-alpha.2",
|
||||
"vue-qrcode": "~2.2.2",
|
||||
"vue-router": "~4.2.5",
|
||||
"vue-router": "~4.5.0",
|
||||
"vue-toastification": "2.0.0-rc.5",
|
||||
"wait-on": "^7.2.0",
|
||||
"xterm-addon-web-links": "~0.9.0"
|
||||
|
|
400
pnpm-lock.yaml
generated
400
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue