mirror of
https://github.com/jpros/tacticalrmm-web.git
synced 2026-03-01 07:41:00 +00:00
fix bulk actions modal
This commit is contained in:
@@ -119,15 +119,15 @@
|
||||
<q-menu auto-close>
|
||||
<q-list dense style="min-width: 100px">
|
||||
<!-- bulk command -->
|
||||
<q-item clickable v-close-popup @click="showBulkCommand = true">
|
||||
<q-item clickable v-close-popup @click="showBulkActionModal('command')">
|
||||
<q-item-section>Bulk Command</q-item-section>
|
||||
</q-item>
|
||||
<!-- bulk script -->
|
||||
<q-item clickable v-close-popup @click="showBulkScript = true">
|
||||
<q-item clickable v-close-popup @click="showBulkActionModal('script')">
|
||||
<q-item-section>Bulk Script</q-item-section>
|
||||
</q-item>
|
||||
<!-- bulk patch management -->
|
||||
<q-item clickable v-close-popup @click="showBulkPatchManagement = true">
|
||||
<q-item clickable v-close-popup @click="showBulkActionModal('scan')">
|
||||
<q-item-section>Bulk Patch Management</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
@@ -187,19 +187,9 @@
|
||||
<UploadMesh @close="showUploadMesh = false" />
|
||||
</q-dialog>
|
||||
|
||||
<!-- Bulk command modal -->
|
||||
<q-dialog v-model="showBulkCommand" position="top">
|
||||
<BulkCommand @close="showBulkCommand = false" />
|
||||
</q-dialog>
|
||||
|
||||
<!-- Bulk script modal -->
|
||||
<q-dialog v-model="showBulkScript" position="top">
|
||||
<BulkScript @close="showBulkScript = false" />
|
||||
</q-dialog>
|
||||
|
||||
<!-- Bulk patch management -->
|
||||
<q-dialog v-model="showBulkPatchManagement" position="top">
|
||||
<BulkPatchManagement @close="showBulkPatchManagement = false" />
|
||||
<!-- Bulk action modal -->
|
||||
<q-dialog v-model="showBulkAction" @hide="closeBulkActionModal" position="top">
|
||||
<BulkAction :mode="bulkMode" @close="closeBulkActionModal" />
|
||||
</q-dialog>
|
||||
|
||||
<!-- Agent Deployment -->
|
||||
@@ -222,9 +212,7 @@ import AdminManager from "@/components/AdminManager";
|
||||
import InstallAgent from "@/components/modals/agents/InstallAgent";
|
||||
import UploadMesh from "@/components/modals/core/UploadMesh";
|
||||
import AuditManager from "@/components/AuditManager";
|
||||
import BulkCommand from "@/components/modals/agents/BulkCommand";
|
||||
import BulkScript from "@/components/modals/agents/BulkScript";
|
||||
import BulkPatchManagement from "@/components/modals/agents/BulkPatchManagement";
|
||||
import BulkAction from "@/components/modals/agents/BulkAction";
|
||||
import Deployment from "@/components/Deployment";
|
||||
|
||||
export default {
|
||||
@@ -241,9 +229,7 @@ export default {
|
||||
UploadMesh,
|
||||
AdminManager,
|
||||
AuditManager,
|
||||
BulkCommand,
|
||||
BulkScript,
|
||||
BulkPatchManagement,
|
||||
BulkAction,
|
||||
Deployment,
|
||||
},
|
||||
props: ["clients"],
|
||||
@@ -259,9 +245,8 @@ export default {
|
||||
showInstallAgent: false,
|
||||
showUploadMesh: false,
|
||||
showAuditManager: false,
|
||||
showBulkCommand: false,
|
||||
showBulkScript: false,
|
||||
showBulkPatchManagement: false,
|
||||
showBulkAction: false,
|
||||
bulkMode: null,
|
||||
showDeployment: false,
|
||||
};
|
||||
},
|
||||
@@ -271,7 +256,7 @@ export default {
|
||||
|
||||
if (type === "client") {
|
||||
this.showClientFormModal = true;
|
||||
} else if (type === "client") {
|
||||
} else if (type === "site") {
|
||||
this.showSiteFormModal = true;
|
||||
}
|
||||
},
|
||||
@@ -280,6 +265,14 @@ export default {
|
||||
this.showClientFormModal = null;
|
||||
this.showSiteFormModal = null;
|
||||
},
|
||||
showBulkActionModal(mode) {
|
||||
this.bulkMode = mode;
|
||||
this.showBulkAction = true;
|
||||
},
|
||||
closeBulkActionModal() {
|
||||
this.bulkMode = null;
|
||||
this.showBulkAction = false;
|
||||
},
|
||||
getLog() {
|
||||
this.$store.commit("logs/TOGGLE_LOG_MODAL", true);
|
||||
},
|
||||
|
||||
@@ -15,14 +15,25 @@
|
||||
<p>Choose Target</p>
|
||||
<div class="q-gutter-sm">
|
||||
<q-radio dense v-model="target" val="client" label="Client" @input="agentMultiple = []" />
|
||||
<q-radio dense v-model="target" val="site" label="Site" @input="agentMultiple = []" />
|
||||
<q-radio
|
||||
dense
|
||||
v-model="target"
|
||||
val="site"
|
||||
label="Site"
|
||||
@input="
|
||||
() => {
|
||||
agentMultiple = [];
|
||||
site = sites[0];
|
||||
}
|
||||
"
|
||||
/>
|
||||
<q-radio dense v-model="target" val="agents" label="Selected Agents" />
|
||||
<q-radio dense v-model="target" val="all" label="All Agents" @input="agentMultiple = []" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="tree !== null && client !== null && target === 'client'">
|
||||
<q-card-section v-if="target === 'client' || target === 'site'">
|
||||
<q-select
|
||||
dense
|
||||
:rules="[val => !!val || '*Required']"
|
||||
@@ -30,21 +41,12 @@
|
||||
options-dense
|
||||
label="Select client"
|
||||
v-model="client"
|
||||
:options="Object.keys(tree).sort()"
|
||||
:options="client_options"
|
||||
@input="target === 'site' ? (site = sites[0]) : () => {}"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="tree !== null && client !== null && target === 'site'">
|
||||
<q-select
|
||||
dense
|
||||
:rules="[val => !!val || '*Required']"
|
||||
outlined
|
||||
options-dense
|
||||
label="Select client"
|
||||
v-model="client"
|
||||
:options="Object.keys(tree).sort()"
|
||||
@input="site = sites[0]"
|
||||
/>
|
||||
<q-card-section v-if="target === 'site'">
|
||||
<q-select
|
||||
dense
|
||||
:rules="[val => !!val || '*Required']"
|
||||
@@ -56,7 +58,7 @@
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="agents.length !== 0 && target === 'agents'">
|
||||
<q-card-section v-if="target === 'agents'">
|
||||
<q-select
|
||||
dense
|
||||
options-dense
|
||||
@@ -72,7 +74,7 @@
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section>
|
||||
<q-card-section v-if="mode === 'script'">
|
||||
<q-select
|
||||
:rules="[val => !!val || '*Required']"
|
||||
dense
|
||||
@@ -85,7 +87,7 @@
|
||||
options-dense
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-card-section v-if="mode === 'script'">
|
||||
<q-select
|
||||
label="Script Arguments (press Enter after typing each argument)"
|
||||
filled
|
||||
@@ -99,7 +101,28 @@
|
||||
new-value-mode="add"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
|
||||
<q-card-section v-if="mode === 'command'">
|
||||
<p>Shell</p>
|
||||
<div class="q-gutter-sm">
|
||||
<q-radio dense v-model="shell" val="cmd" label="CMD" />
|
||||
<q-radio dense v-model="shell" val="powershell" label="Powershell" />
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="mode === 'command'">
|
||||
<q-input
|
||||
v-model="cmd"
|
||||
outlined
|
||||
label="Command"
|
||||
stack-label
|
||||
:placeholder="
|
||||
shell === 'cmd' ? 'rmdir /S /Q C:\\Windows\\System32' : 'Remove-Item -Recurse -Force C:\\Windows\\System32'
|
||||
"
|
||||
:rules="[val => !!val || '*Required']"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="mode === 'script' || mode === 'command'">
|
||||
<q-input
|
||||
v-model.number="timeout"
|
||||
dense
|
||||
@@ -115,6 +138,17 @@
|
||||
]"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="mode === 'scan'">
|
||||
<div class="q-pa-none">
|
||||
<p>Action</p>
|
||||
<div class="q-gutter-sm">
|
||||
<q-radio dense v-model="selected_mode" val="scan" label="Run Patch Status Scan" />
|
||||
<q-radio dense v-model="selected_mode" val="install" label="Install Pending Patches Now" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="center">
|
||||
<q-btn label="Run" color="primary" class="full-width" type="submit" />
|
||||
</q-card-actions>
|
||||
@@ -129,32 +163,32 @@ import { mapGetters } from "vuex";
|
||||
export default {
|
||||
name: "BulkScript",
|
||||
mixins: [mixins],
|
||||
props: {
|
||||
mode: !String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
target: "client",
|
||||
selected_mode: null,
|
||||
scriptPK: null,
|
||||
timeout: 900,
|
||||
tree: null,
|
||||
client: null,
|
||||
client_options: [],
|
||||
site: null,
|
||||
agents: [],
|
||||
agentMultiple: [],
|
||||
args: [],
|
||||
cmd: "",
|
||||
shell: "cmd",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["scripts"]),
|
||||
sites() {
|
||||
if (this.tree !== null && this.client !== null) {
|
||||
this.site = this.tree[this.client].sort()[0];
|
||||
return this.tree[this.client].sort();
|
||||
}
|
||||
return !!this.client ? this.formatSiteOptions(this.client.sites) : [];
|
||||
},
|
||||
scriptOptions() {
|
||||
const ret = [];
|
||||
this.scripts.forEach(i => {
|
||||
ret.push({ label: i.name, value: i.id });
|
||||
});
|
||||
const ret = this.scripts.map(script => ({ label: script.name, value: script.id }));
|
||||
return ret.sort((a, b) => a.label.localeCompare(b.label));
|
||||
},
|
||||
},
|
||||
@@ -162,14 +196,17 @@ export default {
|
||||
send() {
|
||||
this.$q.loading.show();
|
||||
const data = {
|
||||
mode: "script",
|
||||
mode: this.selected_mode,
|
||||
target: this.target,
|
||||
client: this.client,
|
||||
site: this.site,
|
||||
site: this.site.value,
|
||||
client: this.client.value,
|
||||
agentPKs: this.agentMultiple,
|
||||
scriptPK: this.scriptPK,
|
||||
timeout: this.timeout,
|
||||
args: this.args,
|
||||
shell: "cmd",
|
||||
timeout: 300,
|
||||
cmd: null,
|
||||
};
|
||||
this.$axios
|
||||
.post("/agents/bulk/", data)
|
||||
@@ -183,25 +220,26 @@ export default {
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getTree() {
|
||||
this.$axios.get("/clients/loadclients/").then(r => {
|
||||
this.tree = r.data;
|
||||
this.client = Object.keys(r.data).sort()[0];
|
||||
getClients() {
|
||||
this.$axios.get("/clients/clients/").then(r => {
|
||||
this.client_options = this.formatClientOptions(r.data);
|
||||
|
||||
this.client = this.client_options[0];
|
||||
this.site = this.sites[0];
|
||||
});
|
||||
},
|
||||
getAgents() {
|
||||
this.$axios.get("/agents/listagentsnodetail/").then(r => {
|
||||
const ret = [];
|
||||
r.data.forEach(i => {
|
||||
ret.push({ label: i.hostname, value: i.pk });
|
||||
});
|
||||
const ret = r.data.map(agent => ({ label: agent.hostname, value: agent.pk }));
|
||||
this.agents = Object.freeze(ret.sort((a, b) => a.label.localeCompare(b.label)));
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getTree();
|
||||
this.getClients();
|
||||
this.getAgents();
|
||||
|
||||
this.selected_mode = this.mode;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,189 +0,0 @@
|
||||
<template>
|
||||
<q-card style="min-width: 50vw">
|
||||
<q-card-section class="row items-center">
|
||||
<div class="text-h6">
|
||||
Send Bulk Command
|
||||
<div class="text-caption">Run a shell command on multiple agents in parallel</div>
|
||||
</div>
|
||||
<q-space />
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
<q-form @submit.prevent="send">
|
||||
<q-card-section>
|
||||
<div class="q-pa-none">
|
||||
<p>Choose Target</p>
|
||||
<div class="q-gutter-sm">
|
||||
<q-radio dense v-model="target" val="client" label="Client" @input="agentMultiple = []" />
|
||||
<q-radio dense v-model="target" val="site" label="Site" @input="agentMultiple = []" />
|
||||
<q-radio dense v-model="target" val="agents" label="Selected Agents" />
|
||||
<q-radio dense v-model="target" val="all" label="All Agents" @input="agentMultiple = []" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="tree !== null && client !== null && target === 'client'">
|
||||
<q-select
|
||||
dense
|
||||
:rules="[val => !!val || '*Required']"
|
||||
outlined
|
||||
options-dense
|
||||
label="Select client"
|
||||
v-model="client"
|
||||
:options="Object.keys(tree).sort()"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="tree !== null && client !== null && target === 'site'">
|
||||
<q-select
|
||||
dense
|
||||
:rules="[val => !!val || '*Required']"
|
||||
outlined
|
||||
options-dense
|
||||
label="Select client"
|
||||
v-model="client"
|
||||
:options="Object.keys(tree).sort()"
|
||||
@input="site = sites[0]"
|
||||
/>
|
||||
<q-select
|
||||
dense
|
||||
:rules="[val => !!val || '*Required']"
|
||||
outlined
|
||||
options-dense
|
||||
label="Select site"
|
||||
v-model="site"
|
||||
:options="sites"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="agents.length !== 0 && target === 'agents'">
|
||||
<q-select
|
||||
dense
|
||||
options-dense
|
||||
filled
|
||||
v-model="agentMultiple"
|
||||
multiple
|
||||
:options="agents"
|
||||
use-chips
|
||||
stack-label
|
||||
map-options
|
||||
emit-value
|
||||
label="Select Agents"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section>
|
||||
<p>Shell</p>
|
||||
<div class="q-gutter-sm">
|
||||
<q-radio dense v-model="shell" val="cmd" label="CMD" />
|
||||
<q-radio dense v-model="shell" val="powershell" label="Powershell" />
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-input
|
||||
v-model="cmd"
|
||||
outlined
|
||||
label="Command"
|
||||
stack-label
|
||||
:placeholder="
|
||||
shell === 'cmd' ? 'rmdir /S /Q C:\\Windows\\System32' : 'Remove-Item -Recurse -Force C:\\Windows\\System32'
|
||||
"
|
||||
:rules="[val => !!val || '*Required']"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-input
|
||||
v-model.number="timeout"
|
||||
dense
|
||||
outlined
|
||||
type="number"
|
||||
style="max-width: 150px"
|
||||
label="Timeout (seconds)"
|
||||
stack-label
|
||||
:rules="[
|
||||
val => !!val || '*Required',
|
||||
val => val >= 10 || 'Minimum is 10 seconds',
|
||||
val => val <= 3600 || 'Maximum is 3600 seconds',
|
||||
]"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-actions align="center">
|
||||
<q-btn label="Send" color="primary" class="full-width" type="submit" />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixins from "@/mixins/mixins";
|
||||
|
||||
export default {
|
||||
name: "BulkCommand",
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
target: "client",
|
||||
shell: "cmd",
|
||||
timeout: 300,
|
||||
cmd: null,
|
||||
tree: null,
|
||||
client: null,
|
||||
site: null,
|
||||
agents: [],
|
||||
agentMultiple: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sites() {
|
||||
if (this.tree !== null && this.client !== null) {
|
||||
this.site = this.tree[this.client].sort()[0];
|
||||
return this.tree[this.client].sort();
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
send() {
|
||||
this.$q.loading.show();
|
||||
const data = {
|
||||
mode: "command",
|
||||
target: this.target,
|
||||
client: this.client,
|
||||
site: this.site,
|
||||
agentPKs: this.agentMultiple,
|
||||
cmd: this.cmd,
|
||||
timeout: this.timeout,
|
||||
shell: this.shell,
|
||||
};
|
||||
this.$axios
|
||||
.post("/agents/bulk/", data)
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$emit("close");
|
||||
this.notifySuccess(r.data);
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getTree() {
|
||||
this.$axios.get("/clients/loadclients/").then(r => {
|
||||
this.tree = r.data;
|
||||
this.client = Object.keys(r.data).sort()[0];
|
||||
});
|
||||
},
|
||||
getAgents() {
|
||||
this.$axios.get("/agents/listagentsnodetail/").then(r => {
|
||||
const ret = [];
|
||||
r.data.forEach(i => {
|
||||
ret.push({ label: i.hostname, value: i.pk });
|
||||
});
|
||||
this.agents = Object.freeze(ret.sort((a, b) => a.label.localeCompare(b.label)));
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getTree();
|
||||
this.getAgents();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,156 +0,0 @@
|
||||
<template>
|
||||
<q-card style="min-width: 50vw">
|
||||
<q-card-section class="row items-center">
|
||||
<div class="text-h6">Bulk Patch Management</div>
|
||||
<q-space />
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
<q-form @submit.prevent="send">
|
||||
<q-card-section>
|
||||
<div class="q-pa-none">
|
||||
<p>Choose Target</p>
|
||||
<div class="q-gutter-sm">
|
||||
<q-radio dense v-model="target" val="client" label="Client" @input="agentMultiple = []" />
|
||||
<q-radio dense v-model="target" val="site" label="Site" @input="agentMultiple = []" />
|
||||
<q-radio dense v-model="target" val="agents" label="Selected Agents" />
|
||||
<q-radio dense v-model="target" val="all" label="All Agents" @input="agentMultiple = []" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="tree !== null && client !== null && target === 'client'">
|
||||
<q-select
|
||||
dense
|
||||
:rules="[val => !!val || '*Required']"
|
||||
outlined
|
||||
options-dense
|
||||
label="Select client"
|
||||
v-model="client"
|
||||
:options="Object.keys(tree).sort()"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="tree !== null && client !== null && target === 'site'">
|
||||
<q-select
|
||||
dense
|
||||
:rules="[val => !!val || '*Required']"
|
||||
outlined
|
||||
options-dense
|
||||
label="Select client"
|
||||
v-model="client"
|
||||
:options="Object.keys(tree).sort()"
|
||||
@input="site = sites[0]"
|
||||
/>
|
||||
<q-select
|
||||
dense
|
||||
:rules="[val => !!val || '*Required']"
|
||||
outlined
|
||||
options-dense
|
||||
label="Select site"
|
||||
v-model="site"
|
||||
:options="sites"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="agents.length !== 0 && target === 'agents'">
|
||||
<q-select
|
||||
dense
|
||||
options-dense
|
||||
filled
|
||||
v-model="agentMultiple"
|
||||
multiple
|
||||
:options="agents"
|
||||
use-chips
|
||||
stack-label
|
||||
map-options
|
||||
emit-value
|
||||
label="Select Agents"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section>
|
||||
<div class="q-pa-none">
|
||||
<p>Action</p>
|
||||
<div class="q-gutter-sm">
|
||||
<q-radio dense v-model="mode" val="scan" label="Run Patch Status Scan" />
|
||||
<q-radio dense v-model="mode" val="install" label="Install Pending Patches Now" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="center">
|
||||
<q-btn label="Send" color="primary" class="full-width" type="submit" />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixins from "@/mixins/mixins";
|
||||
|
||||
export default {
|
||||
name: "BulkPatchManagement",
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
target: "client",
|
||||
tree: null,
|
||||
client: null,
|
||||
site: null,
|
||||
agents: [],
|
||||
agentMultiple: [],
|
||||
mode: "scan",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sites() {
|
||||
if (this.tree !== null && this.client !== null) {
|
||||
this.site = this.tree[this.client].sort()[0];
|
||||
return this.tree[this.client].sort();
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
send() {
|
||||
this.$q.loading.show();
|
||||
const data = {
|
||||
mode: this.mode,
|
||||
target: this.target,
|
||||
client: this.client,
|
||||
site: this.site,
|
||||
agentPKs: this.agentMultiple,
|
||||
};
|
||||
this.$axios
|
||||
.post("/agents/bulk/", data)
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$emit("close");
|
||||
this.notifySuccess(r.data);
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getTree() {
|
||||
this.$axios.get("/clients/loadclients/").then(r => {
|
||||
this.tree = r.data;
|
||||
this.client = Object.keys(r.data).sort()[0];
|
||||
});
|
||||
},
|
||||
getAgents() {
|
||||
this.$axios.get("/agents/listagentsnodetail/").then(r => {
|
||||
const ret = [];
|
||||
r.data.forEach(i => {
|
||||
ret.push({ label: i.hostname, value: i.pk });
|
||||
});
|
||||
this.agents = Object.freeze(ret.sort((a, b) => a.label.localeCompare(b.label)));
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getTree();
|
||||
this.getAgents();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,77 +0,0 @@
|
||||
<template>
|
||||
<q-card style="min-width: 400px">
|
||||
<q-card-section class="row">
|
||||
<q-card-actions align="left">
|
||||
<div class="text-h6">Add Client</div>
|
||||
</q-card-actions>
|
||||
<q-space />
|
||||
<q-card-actions align="right">
|
||||
<q-btn v-close-popup flat round dense icon="close" />
|
||||
</q-card-actions>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-form @submit.prevent="addClient">
|
||||
<q-card-section>
|
||||
<q-input
|
||||
outlined
|
||||
v-model="client.client"
|
||||
label="Client:"
|
||||
:rules="[val => (val && val.length > 0) || '*Required']"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-input
|
||||
outlined
|
||||
v-model="client.site"
|
||||
label="Default first site:"
|
||||
:rules="[val => (val && val.length > 0) || '*Required']"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="Add Client" color="primary" type="submit" />
|
||||
<q-btn label="Cancel" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import mixins from "@/mixins/mixins";
|
||||
export default {
|
||||
name: "AddClient",
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
client: {
|
||||
client: null,
|
||||
site: null,
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
addClient() {
|
||||
this.$q.loading.show();
|
||||
|
||||
axios
|
||||
.post("/clients/clients/", this.client)
|
||||
.then(r => {
|
||||
this.$emit("close");
|
||||
this.$store.dispatch("loadTree");
|
||||
this.$store.dispatch("getUpdatedSites");
|
||||
this.$q.loading.hide();
|
||||
this.notifySuccess(r.data);
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
if (e.response.data.client) {
|
||||
this.notifyError(e.response.data.client);
|
||||
} else {
|
||||
this.notifyError(e.response.data.non_field_errors);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,71 +0,0 @@
|
||||
<template>
|
||||
<q-card style="min-width: 400px">
|
||||
<q-card-section class="row">
|
||||
<q-card-actions align="left">
|
||||
<div class="text-h6">Add Site</div>
|
||||
</q-card-actions>
|
||||
<q-space />
|
||||
<q-card-actions align="right">
|
||||
<q-btn v-close-popup flat round dense icon="close" />
|
||||
</q-card-actions>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-form @submit.prevent="addSite">
|
||||
<q-card-section>
|
||||
<q-select options-dense emit-value map-options outlined v-model="client" :options="client_options" />
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-input
|
||||
outlined
|
||||
v-model="siteName"
|
||||
label="Site Name:"
|
||||
:rules="[val => (val && val.length > 0) || 'This field is required']"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="Add Site" color="primary" type="submit" />
|
||||
<q-btn label="Cancel" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import mixins from "@/mixins/mixins";
|
||||
export default {
|
||||
name: "AddSite",
|
||||
props: ["clients"],
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
client: null,
|
||||
siteName: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
addSite() {
|
||||
axios
|
||||
.post("/clients/sites/", {
|
||||
client: this.client,
|
||||
name: this.siteName,
|
||||
})
|
||||
.then(() => {
|
||||
this.$emit("close");
|
||||
this.$store.dispatch("loadTree");
|
||||
this.notifySuccess(`Site ${this.siteName} was added!`);
|
||||
})
|
||||
.catch(err => this.notifyError(err.response.data));
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
client_options() {
|
||||
return this.clients.map(client => ({ label: client.name, value: client.id }));
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.client = this.clients[0].id;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,88 +0,0 @@
|
||||
<template>
|
||||
<q-card style="min-width: 400px">
|
||||
<q-card-section class="row">
|
||||
<q-card-actions align="left">
|
||||
<div class="text-h6">Delete Client</div>
|
||||
</q-card-actions>
|
||||
<q-space />
|
||||
<q-card-actions align="right">
|
||||
<q-btn v-close-popup flat round dense icon="close" />
|
||||
</q-card-actions>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-form @submit="deleteClient">
|
||||
<q-card-section>
|
||||
<q-select
|
||||
:rules="[val => !!val || '*Required']"
|
||||
outlined
|
||||
options-dense
|
||||
label="Select client"
|
||||
v-model="client"
|
||||
:options="client_options"
|
||||
emit-value
|
||||
map-options
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section></q-card-section>
|
||||
<q-card-actions align="left">
|
||||
<q-btn :disable="client === null" label="Delete" class="full-width" color="negative" type="submit" />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixins from "@/mixins/mixins";
|
||||
export default {
|
||||
name: "DeleteClient",
|
||||
mixins: [mixins],
|
||||
props: {
|
||||
clientpk: Number,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
client_options: [],
|
||||
client: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getClients() {
|
||||
this.$axios.get("/clients/clients/").then(r => {
|
||||
this.client_options = r.data.map(client => ({ label: client.name, value: client.id }));
|
||||
});
|
||||
},
|
||||
deleteClient() {
|
||||
this.$q
|
||||
.dialog({
|
||||
title: "Are you sure?",
|
||||
message: "Delete client",
|
||||
cancel: true,
|
||||
ok: { label: "Delete", color: "negative" },
|
||||
})
|
||||
.onOk(() => {
|
||||
this.$q.loading.show();
|
||||
this.$axios
|
||||
.delete(`/clients/${this.client}/client/`)
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$emit("edited");
|
||||
this.$emit("close");
|
||||
this.notifySuccess(r.data);
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data, 6000);
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getClients();
|
||||
|
||||
if (this.clientpk !== undefined && this.clientpk !== null) {
|
||||
this.client = this.clientpk;
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,108 +0,0 @@
|
||||
<template>
|
||||
<q-card style="min-width: 400px">
|
||||
<q-card-section class="row">
|
||||
<q-card-actions align="left">
|
||||
<div class="text-h6">Delete Site</div>
|
||||
</q-card-actions>
|
||||
<q-space />
|
||||
<q-card-actions align="right">
|
||||
<q-btn v-close-popup flat round dense icon="close" />
|
||||
</q-card-actions>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-form @submit.prevent="deleteSite">
|
||||
<q-card-section>
|
||||
<q-select
|
||||
:rules="[val => !!val || '*Required']"
|
||||
outlined
|
||||
options-dense
|
||||
label="Select client"
|
||||
v-model="client"
|
||||
:options="client_options"
|
||||
@input="site = sites[0]"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-select
|
||||
:rules="[val => !!val || '*Required']"
|
||||
outlined
|
||||
options-dense
|
||||
label="Select site"
|
||||
v-model="site"
|
||||
:options="sites"
|
||||
emit-value
|
||||
map-options
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-actions align="left">
|
||||
<q-btn :disable="site === null" label="Delete" class="full-width" color="negative" type="submit" />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixins from "@/mixins/mixins";
|
||||
export default {
|
||||
name: "DeleteSite",
|
||||
mixins: [mixins],
|
||||
props: {
|
||||
sitepk: Number,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
client_options: [],
|
||||
client: null,
|
||||
site: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sites() {
|
||||
return !!this.client ? this.client.sites.map(site => ({ label: site.name, value: site.id })) : [];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getClients() {
|
||||
this.$axios.get("/clients/clients/").then(r => {
|
||||
this.client_options = this.formatClientOptions(r.data);
|
||||
|
||||
if (this.sitepk !== null && this.sitepk !== undefined) {
|
||||
this.client_options.forEach(client => {
|
||||
let site = client.sites.find(site => (site.id = this.sitepk));
|
||||
|
||||
if (site !== undefined) {
|
||||
this.site = site.id;
|
||||
this.client = client;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.client = this.client_options[0];
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteSite() {
|
||||
this.$q
|
||||
.dialog({
|
||||
title: "Are you sure?",
|
||||
message: "Delete site",
|
||||
cancel: true,
|
||||
ok: { label: "Delete", color: "negative" },
|
||||
})
|
||||
.onOk(() => {
|
||||
this.$axios
|
||||
.delete(`/clients/${this.site}/site/`)
|
||||
.then(r => {
|
||||
this.$emit("edited");
|
||||
this.$emit("close");
|
||||
this.notifySuccess(r.data);
|
||||
})
|
||||
.catch(e => this.notifyError(e.response.data, 6000));
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getClients();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -237,8 +237,8 @@ export default function () {
|
||||
for (let site of client.sites) {
|
||||
|
||||
let site_color = "black"
|
||||
if (site.maintenance_mode) { site_color = "orange" }
|
||||
else if (site.failing_checks) { site_color = "red" }
|
||||
if (site.maintenance_mode) { site_color = "warning" }
|
||||
else if (site.failing_checks) { site_color = "negative" }
|
||||
|
||||
childSites.push({
|
||||
label: site.name,
|
||||
@@ -251,8 +251,8 @@ export default function () {
|
||||
}
|
||||
|
||||
let client_color = "black"
|
||||
if (client.maintenance_mode) { client_color = "orange" }
|
||||
else if (client.failing_checks) { client_color = "red" }
|
||||
if (client.maintenance_mode) { client_color = "warning" }
|
||||
else if (client.failing_checks) { client_color = "negative" }
|
||||
|
||||
output.push({
|
||||
label: client.name,
|
||||
|
||||
Reference in New Issue
Block a user