Followup #3864, rebase for 1.23.x (#4016)

* Fix: Use ActionSelect Docker Host & validate input

* Fix: Handle docker host deleted while editing

* UI: Use add for ActionSelect & prevent delete instead

---------

Co-authored-by: Nelson Chan <chakflying@hotmail.com>
This commit is contained in:
Louis Lam 2023-11-12 20:32:40 +08:00 committed by GitHub
parent 6e80c850f4
commit 8e3ff25f7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 20 deletions

View File

@ -739,8 +739,6 @@ class Monitor extends BeanModel {
} else if (this.type === "docker") { } else if (this.type === "docker") {
log.debug("monitor", `[${this.name}] Prepare Options for Axios`); log.debug("monitor", `[${this.name}] Prepare Options for Axios`);
const dockerHost = await R.load("docker_host", this.docker_host);
const options = { const options = {
url: `/containers/${this.docker_container}/json`, url: `/containers/${this.docker_container}/json`,
timeout: this.interval * 1000 * 0.8, timeout: this.interval * 1000 * 0.8,
@ -757,6 +755,12 @@ class Monitor extends BeanModel {
}), }),
}; };
const dockerHost = await R.load("docker_host", this.docker_host);
if (!dockerHost) {
throw new Error("Failed to load docker host config");
}
if (dockerHost._dockerType === "socket") { if (dockerHost._dockerType === "socket") {
options.socketPath = dockerHost._dockerDaemon; options.socketPath = dockerHost._dockerDaemon;
} else if (dockerHost._dockerType === "tcp") { } else if (dockerHost._dockerType === "tcp") {

View File

@ -1,9 +1,9 @@
<template> <template>
<div class="input-group mb-3"> <div class="input-group mb-3">
<select ref="select" v-model="model" class="form-select" :disabled="disabled"> <select ref="select" v-model="model" class="form-select" :disabled="disabled" :required="required">
<option v-for="option in options" :key="option" :value="option.value">{{ option.label }}</option> <option v-for="option in options" :key="option" :value="option.value" :disabled="option.disabled">{{ option.label }}</option>
</select> </select>
<a class="btn btn-outline-primary" @click="action()"> <a class="btn btn-outline-primary" :class="{ disabled: actionDisabled }" @click="action()">
<font-awesome-icon :icon="icon" /> <font-awesome-icon :icon="icon" />
</a> </a>
</div> </div>
@ -50,6 +50,22 @@ export default {
action: { action: {
type: Function, type: Function,
default: () => {}, default: () => {},
},
/**
* Whether the action button is disabled.
* @example true
*/
actionDisabled: {
type: Boolean,
default: false
},
/**
* Whether the select field is required.
* @example true
*/
required: {
type: Boolean,
default: false,
} }
}, },
emits: [ "update:modelValue" ], emits: [ "update:modelValue" ],

View File

@ -70,7 +70,7 @@ export default {
Confirm, Confirm,
}, },
props: {}, props: {},
emits: [ "added" ], emits: [ "added", "deleted" ],
data() { data() {
return { return {
modal: null, modal: null,
@ -167,6 +167,7 @@ export default {
this.processing = false; this.processing = false;
if (res.ok) { if (res.ok) {
this.$emit("deleted", this.id);
this.modal.hide(); this.modal.hide();
} }
}); });

View File

@ -369,6 +369,8 @@
"Setup Docker Host": "Setup Docker Host", "Setup Docker Host": "Setup Docker Host",
"Connection Type": "Connection Type", "Connection Type": "Connection Type",
"Docker Daemon": "Docker Daemon", "Docker Daemon": "Docker Daemon",
"noDockerHostMsg": "Not Available. Setup a Docker Host First.",
"DockerHostRequired": "Please set the Docker Host for this monitor.",
"deleteDockerHostMsg": "Are you sure want to delete this docker host for all monitors?", "deleteDockerHostMsg": "Are you sure want to delete this docker host for all monitors?",
"socket": "Socket", "socket": "Socket",
"tcp": "TCP / HTTP", "tcp": "TCP / HTTP",

View File

@ -285,22 +285,17 @@
<!-- Docker Host --> <!-- Docker Host -->
<!-- For Docker Type --> <!-- For Docker Type -->
<div v-if="monitor.type === 'docker'" class="my-3"> <div v-if="monitor.type === 'docker'" class="my-3">
<h2 class="mb-2">{{ $t("Docker Host") }}</h2> <div class="mb-3">
<p v-if="$root.dockerHostList.length === 0">
{{ $t("Not available, please setup.") }}
</p>
<div v-else class="mb-3">
<label for="docker-host" class="form-label">{{ $t("Docker Host") }}</label> <label for="docker-host" class="form-label">{{ $t("Docker Host") }}</label>
<select id="docket-host" v-model="monitor.docker_host" class="form-select"> <ActionSelect
<option v-for="host in $root.dockerHostList" :key="host.id" :value="host.id">{{ host.name }}</option> v-model="monitor.docker_host"
</select> :options="dockerHostOptionsList"
<a href="#" @click="$refs.dockerHostDialog.show(monitor.docker_host)">{{ $t("Edit") }}</a> :disabled="$root.dockerHostList == null || $root.dockerHostList.length === 0"
:icon="'plus'"
:action="() => $refs.dockerHostDialog.show()"
:required="true"
/>
</div> </div>
<button class="btn btn-primary me-2" type="button" @click="$refs.dockerHostDialog.show()">
{{ $t("Setup Docker Host") }}
</button>
</div> </div>
<!-- MQTT --> <!-- MQTT -->
@ -1119,6 +1114,21 @@ message HealthCheckResponse {
return list; return list;
}, },
dockerHostOptionsList() {
if (this.$root.dockerHostList && this.$root.dockerHostList.length > 0) {
return this.$root.dockerHostList.map((host) => {
return {
label: host.name,
value: host.id
};
});
} else {
return [{
label: this.$t("noDockerHostMsg"),
value: null,
}];
}
}
}, },
watch: { watch: {
"$root.proxyList"() { "$root.proxyList"() {
@ -1351,6 +1361,12 @@ message HealthCheckResponse {
return false; return false;
} }
} }
if (this.monitor.type === "docker") {
if (this.monitor.docker_host == null) {
toast.error(this.$t("DockerHostRequired"));
return false;
}
}
return true; return true;
}, },