Rework clients app and rename client and site property to name

This commit is contained in:
sadnub
2020-11-03 17:47:24 -05:00
parent 115b37e891
commit c55d166acd
14 changed files with 199 additions and 196 deletions

View File

@@ -255,8 +255,8 @@
<q-tooltip>Checks passing</q-tooltip>
</q-icon>
</q-td>
<q-td key="client" :props="props">{{ props.row.client }}</q-td>
<q-td key="site" :props="props">{{ props.row.site }}</q-td>
<q-td key="client" :props="props">{{ props.row.client_name }}</q-td>
<q-td key="site" :props="props">{{ props.row.site_name }}</q-td>
<q-td key="hostname" :props="props">{{ props.row.hostname }}</q-td>
<q-td key="description" :props="props">{{ props.row.description }}</q-td>

View File

@@ -37,12 +37,7 @@
<q-tab name="checks" icon="fas fa-check-double" label="Checks" />
<q-tab name="tasks" icon="fas fa-tasks" label="Tasks" />
</q-tabs>
<q-tab-panels
v-model="selectedTab"
animated
transition-prev="jump-up"
transition-next="jump-up"
>
<q-tab-panels v-model="selectedTab" animated transition-prev="jump-up" transition-next="jump-up">
<q-tab-panel name="checks">
<PolicyChecksTab />
</q-tab-panel>
@@ -127,7 +122,7 @@ export default {
for (let client in data) {
var client_temp = {};
client_temp["label"] = data[client].client;
client_temp["label"] = data[client].name;
client_temp["id"] = unique_id;
client_temp["icon"] = "business";
client_temp["selectable"] = false;
@@ -170,7 +165,7 @@ export default {
// Iterate through Sites
for (let site in data[client].sites) {
var site_temp = {};
site_temp["label"] = data[client].sites[site].site;
site_temp["label"] = data[client].sites[site].name;
site_temp["id"] = unique_id;
site_temp["icon"] = "apartment";
site_temp["selectable"] = false;

View File

@@ -27,14 +27,23 @@
options-dense
outlined
v-model="agent.client"
:options="Object.keys(tree).sort()"
:options="client_options"
class="col-8"
/>
</q-card-section>
<q-card-section class="row">
<div class="col-2">Site:</div>
<div class="col-2"></div>
<q-select class="col-8" dense options-dense outlined v-model="agent.site" :options="sites" />
<q-select
class="col-8"
dense
options-dense
emit-value
map-options
outlined
v-model="agent.site"
:options="site_options"
/>
</q-card-section>
<q-card-section class="row">
<div class="col-2">Type:</div>
@@ -133,7 +142,7 @@ export default {
clientsLoaded: false,
agent: {},
monTypes: ["server", "workstation"],
tree: {},
client_options: [],
splitterModel: 15,
tab: "general",
timezone: null,
@@ -168,12 +177,13 @@ export default {
this.original_tz = r.data.time_zone;
}
this.agent.client = { label: r.data.client.name, id: r.data.client.id, sites: r.data.client.sites };
this.agentLoaded = true;
});
},
getClientsSites() {
axios.get("/clients/loadclients/").then(r => {
this.tree = r.data;
axios.get("/clients/clients/").then(r => {
this.client_options = this.formatClientOptions(r.data);
this.clientsLoaded = true;
});
},
@@ -201,9 +211,9 @@ export default {
},
computed: {
...mapGetters(["selectedAgentPk"]),
sites() {
site_options() {
if (this.agentLoaded && this.clientsLoaded) {
return this.tree[this.agent.client].sort();
return this.formatSiteOptions(this.agent.client["sites"]);
}
},
},

View File

@@ -16,7 +16,7 @@
outlined
v-model="client.client"
label="Client:"
:rules="[ val => val && val.length > 0 || '*Required']"
:rules="[val => (val && val.length > 0) || '*Required']"
/>
</q-card-section>
<q-card-section>
@@ -24,7 +24,7 @@
outlined
v-model="client.site"
label="Default first site:"
:rules="[ val => val && val.length > 0 || '*Required']"
:rules="[val => (val && val.length > 0) || '*Required']"
/>
</q-card-section>
<q-card-actions align="right">
@@ -52,15 +52,19 @@ export default {
},
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 {

View File

@@ -12,7 +12,7 @@
<q-card-section>
<q-form @submit.prevent="addSite">
<q-card-section>
<q-select options-dense outlined v-model="clientName" :options="Object.keys(clients).sort()" />
<q-select options-dense emit-value map-options outlined v-model="client" :options="client_options" />
</q-card-section>
<q-card-section>
<q-input
@@ -40,32 +40,32 @@ export default {
mixins: [mixins],
data() {
return {
clientName: "",
client: null,
siteName: "",
};
},
methods: {
loadFirstClient() {
axios.get("/clients/listclients/").then(resp => {
this.clientName = resp.data.map(k => k.client).sort()[0];
});
},
addSite() {
axios
.post("/clients/addsite/", {
client: this.clientName,
site: this.siteName,
.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.error));
.catch(err => this.notifyError(err.response.data));
},
},
computed: {
client_options() {
return this.clients.map(client => ({ label: client.name, value: client.id }));
},
},
created() {
this.loadFirstClient();
this.client = this.clients[0].id;
},
};
</script>

View File

@@ -10,29 +10,22 @@
</q-card-actions>
</q-card-section>
<q-card-section>
<q-form @submit.prevent="deleteClient">
<q-form @submit="deleteClient">
<q-card-section>
<q-select
:rules="[val => !!val || '*Required']"
outlined
options-dense
label="Select client"
v-model="client.id"
:options="clients"
@input="onChange"
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.client === null"
:label="deleteLabel"
class="full-width"
color="negative"
type="submit"
/>
<q-btn :disable="client === null" label="Delete" class="full-width" color="negative" type="submit" />
</q-card-actions>
</q-form>
</q-card-section>
@@ -44,54 +37,52 @@ import mixins from "@/mixins/mixins";
export default {
name: "DeleteClient",
mixins: [mixins],
props: {
clientpk: Number,
},
data() {
return {
clients: [],
client: {
client: null,
id: null,
},
client_options: [],
client: null,
};
},
computed: {
deleteLabel() {
return this.client.client !== null ? `Delete ${this.client.client}` : "Delete";
},
},
methods: {
getClients() {
this.$axios.get("/clients/clients/").then(r => {
r.data.forEach(client => {
this.clients.push({ label: client.client, value: client.id });
});
this.clients.sort((a, b) => a.label.localeCompare(b.label));
this.client_options = r.data.map(client => ({ label: client.name, value: client.id }));
});
},
onChange() {
this.client.client = this.clients.find(i => i.value === this.client.id).label;
},
deleteClient() {
this.$q
.dialog({
title: "Are you sure?",
message: `Delete client ${this.client.client}`,
message: "Delete client",
cancel: true,
ok: { label: "Delete", color: "negative" },
})
.onOk(() => {
this.$q.loading.show();
this.$axios
.delete(`/clients/${this.client.id}/client/`)
.delete(`/clients/${this.client}/client/`)
.then(r => {
this.$q.loading.hide();
this.$emit("edited");
this.$emit("close");
this.notifySuccess(r.data);
})
.catch(e => this.notifyError(e.response.data, 6000));
.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>

View File

@@ -11,14 +11,14 @@
</q-card-section>
<q-card-section>
<q-form @submit.prevent="deleteSite">
<q-card-section v-if="tree !== null">
<q-card-section>
<q-select
:rules="[val => !!val || '*Required']"
outlined
options-dense
label="Select client"
v-model="client"
:options="Object.keys(tree).sort()"
:options="client_options"
@input="site = sites[0]"
/>
</q-card-section>
@@ -30,10 +30,12 @@
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 ${site}`" class="full-width" color="negative" type="submit" />
<q-btn :disable="site === null" label="Delete" class="full-width" color="negative" type="submit" />
</q-card-actions>
</q-form>
</q-card-section>
@@ -45,43 +47,51 @@ import mixins from "@/mixins/mixins";
export default {
name: "DeleteSite",
mixins: [mixins],
props: {
sitepk: Number,
},
data() {
return {
tree: null,
client_options: [],
client: null,
site: null,
};
},
computed: {
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.client.sites.map(site => ({ label: site.name, value: site.id })) : [];
},
},
methods: {
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);
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() {
const data = {
client: this.client,
site: this.site,
};
this.$q
.dialog({
title: "Are you sure?",
message: `Delete site ${this.site}`,
message: "Delete site",
cancel: true,
ok: { label: "Delete", color: "negative" },
})
.onOk(() => {
this.$axios
.delete("/clients/deletesite/", { data })
.delete(`/clients/${this.site}/site/`)
.then(r => {
this.$emit("edited");
this.$emit("close");
@@ -92,7 +102,7 @@ export default {
},
},
created() {
this.getTree();
this.getClients();
},
};
</script>

View File

@@ -10,25 +10,22 @@
</q-card-actions>
</q-card-section>
<q-card-section>
<q-form @submit.prevent="editClient">
<q-form @submit="editClient">
<q-card-section>
<q-select
:rules="[val => !!val || '*Required']"
outlined
options-dense
label="Select client"
v-model="client.id"
:options="clients"
@input="onChange"
emit-value
map-options
v-model="client"
:options="client_options"
/>
</q-card-section>
<q-card-section>
<q-input :rules="[val => !!val || '*Required']" outlined v-model="client.client" label="Rename client" />
<q-input :rules="[val => !!val || '*Required']" outlined v-model="client.label" label="Rename client" />
</q-card-section>
<q-card-actions align="left">
<q-btn :disable="!nameChanged" label="Save" color="primary" type="submit" />
<q-btn label="Save" color="primary" type="submit" />
</q-card-actions>
</q-form>
</q-card-section>
@@ -41,38 +38,36 @@ import mixins from "@/mixins/mixins";
export default {
name: "EditClients",
mixins: [mixins],
props: {
clientpk: Number,
},
data() {
return {
clients: [],
client: {
client: null,
id: null,
},
client_options: [],
client: {},
};
},
computed: {
nameChanged() {
if (this.clients.length !== 0 && this.client.client !== null) {
const origName = this.clients.find(i => i.value === this.client.id).label;
return this.client.client === origName ? false : true;
}
},
},
methods: {
getClients() {
axios.get("/clients/clients/").then(r => {
r.data.forEach(client => {
this.clients.push({ label: client.client, value: client.id });
});
this.clients.sort((a, b) => a.label.localeCompare(b.label));
this.client_options = r.data.map(client => ({ label: client.name, value: client.id }));
if (this.clientpk !== undefined && this.clientpk !== null) {
let client = this.client_options.find(client => client.value === this.clientpk);
this.client = client;
} else {
this.client = this.client_options[0];
}
});
},
onChange() {
this.client.client = this.clients.find(i => i.value === this.client.id).label;
},
editClient() {
const data = {
id: this.client.value,
name: this.client.label,
};
axios
.patch(`/clients/${this.client.id}/client/`, this.client)
.put(`/clients/${this.client.value}/client/`, data)
.then(r => {
this.$emit("edited");
this.$emit("close");

View File

@@ -18,11 +18,8 @@
options-dense
label="Select client"
v-model="client"
:options="Object.keys(tree).sort()"
@input="
site = sites[0];
newName = sites[0];
"
:options="client_options"
@input="site = sites[0]"
/>
</q-card-section>
<q-card-section>
@@ -33,11 +30,10 @@
label="Select site"
v-model="site"
:options="sites"
@input="newName = site"
/>
</q-card-section>
<q-card-section>
<q-input :rules="[val => !!val || '*Required']" outlined v-model="newName" label="Rename site" />
<q-input :rules="[val => !!val || '*Required']" outlined v-model="site.label" label="Rename site" />
</q-card-section>
<q-card-actions align="left">
<q-btn :disable="!nameChanged" label="Save" color="primary" type="submit" />
@@ -53,43 +49,47 @@ import mixins from "@/mixins/mixins";
export default {
name: "EditSites",
mixins: [mixins],
props: {
sitepk: Number,
},
data() {
return {
tree: null,
client_options: [],
client: null,
site: null,
newName: null,
site: {},
};
},
computed: {
sites() {
if (this.tree !== null && this.client !== null) {
this.site = this.tree[this.client].sort()[0];
this.newName = this.tree[this.client].sort()[0];
return this.tree[this.client].sort();
}
},
nameChanged() {
if (this.site !== null) {
return this.newName === this.site ? false : true;
}
return !!this.client ? this.client.sites(site => ({ label: site.name, value: site.id })) : [];
},
},
methods: {
getTree() {
axios.get("/clients/loadclients/").then(r => {
this.tree = r.data;
this.client = Object.keys(r.data).sort()[0];
getClients() {
axios.get("/clients/clients/").then(r => {
this.client_options = this.formatClientoptions(r.data);
if (this.sitepk !== undefined && this.sitepk !== null) {
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];
}
});
},
editSite() {
const data = {
client: this.client,
site: this.site,
name: this.newName,
id: this.site.value,
name: this.site.label,
};
axios
.patch("/clients/editsite/", data)
.put(`/clients/${this.site.value}/site/`, data)
.then(() => {
this.$emit("edited");
this.$emit("close");
@@ -99,7 +99,7 @@ export default {
},
},
created() {
this.getTree();
this.getClients();
},
};
</script>

View File

@@ -89,7 +89,7 @@ export default {
this.$store
.dispatch("loadClients")
.then(r => {
this.client_options = r.data.map(client => ({ label: client.client, value: client.id, sites: client.sites }));
this.client_options = this.formatClientOptions(r.data);
})
.catch(e => {
this.$q.notify(notifyErrorConfig("There was an error loading the clients!"));

View File

@@ -1,19 +0,0 @@
export default {
methods: {
formatClients(clients) {
return clients.map(client => ({
label: client.client,
value: client.id
})
);
},
formatSites(sites) {
return sites.map(site => ({
label: site.site,
value: site.id,
client: site.client_name
})
);
}
}
};

View File

@@ -94,6 +94,12 @@ export default {
let formatted = months[dt.getMonth()] + "-" + appendLeadingZeroes(dt.getDate()) + "-" + appendLeadingZeroes(dt.getFullYear()) + " - " + appendLeadingZeroes(dt.getHours()) + ":" + appendLeadingZeroes(dt.getMinutes())
return includeSeconds ? formatted + ":" + appendLeadingZeroes(dt.getSeconds()) : formatted
},
formatClientOptions(clients) {
return clients.map(client => ({ label: client.name, value: client.id, sites: client.sites }))
},
formatSiteOptions(sites) {
return sites.map(site => ({ label: site.name, value: site.id }))
}
}
};

View File

@@ -210,7 +210,7 @@ export default function () {
return axios.delete(`/tasks/${pk}/automatedtasks/`);
},
getUpdatedSites(context) {
axios.get("/clients/loadclients/").then(r => {
axios.get("/clients/clients/").then(r => {
context.commit("getUpdatedSites", r.data);
});
},
@@ -218,53 +218,54 @@ export default function () {
return axios.get("/clients/clients/");
},
loadSites(context) {
return axios.get("/clients/listsites/");
return axios.get("/clients/sites/");
},
loadAgents(context) {
return axios.get("/agents/listagents/");
},
loadTree({ commit }) {
axios.get("/clients/loadtree/").then(r => {
const input = r.data;
if (
Object.entries(input).length === 0 &&
input.constructor === Object
) {
axios.get("/clients/tree/").then(r => {
if (r.data.length === 0) {
this.$router.push({ name: "InitialSetup" });
}
const output = [];
for (let prop in input) {
let sites_arr = input[prop];
let child_single = [];
for (let i = 0; i < sites_arr.length; i++) {
child_single.push({
label: sites_arr[i].split("|")[0],
id: sites_arr[i].split("|")[1],
raw: `Site|${sites_arr[i]}`,
let output = [];
for (let client of r.data) {
let childSites = [];
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" }
childSites.push({
label: site.name,
id: site.id,
raw: `Site|${site.id}`,
header: "generic",
icon: "apartment",
color: sites_arr[i].split("|")[2]
color: site_color
});
}
// sort alphabetically by site name
let alphaSort = child_single.sort((a, b) => a.label.toLowerCase() > b.label.toLowerCase() ? 1 : -1);
let client_color = "black"
if (client.maintenance_mode) { client_color = "orange" }
else if (client.failing_checks) { client_color = "red" }
output.push({
label: prop.split("|")[0],
id: prop.split("|")[1],
raw: `Client|${prop}`,
label: client.name,
id: client.id,
raw: `Client|${client.id}`,
header: "root",
icon: "business",
color: prop.split("|")[2],
children: alphaSort
color: client_color,
children: childSites
});
}
// first sort alphabetically, then move failing clients to the top
const sortedAlpha = output.sort((a, b) => (a.label.toLowerCase() > b.label.toLowerCase() ? 1 : -1));
const sortedByFailing = sortedAlpha.sort(a =>
a.color === "negative" ? -1 : 1
);
commit("loadTree", sortedByFailing);
commit("loadTree", output);
//commit("destroySubTable");
});
},

View File

@@ -198,19 +198,19 @@
<!-- edit client modal -->
<q-dialog v-model="showEditClientModal">
<EditClients @close="showEditClientModal = false" @edited="refreshEntireSite" />
<EditClients @close="closeDeleteEditModal" :clientpk="deleteEditModalPk" @edited="refreshEntireSite" />
</q-dialog>
<!-- edit site modal -->
<q-dialog v-model="showEditSiteModal">
<EditSites @close="showEditSiteModal = false" @edited="refreshEntireSite" />
<EditSites @close="closeDeleteEditModal" :sitepk="deleteEditModalPk" @edited="refreshEntireSite" />
</q-dialog>
<!-- delete client modal -->
<q-dialog v-model="showDeleteClientModal">
<DeleteClient @close="showDeleteClientModal = false" @edited="refreshEntireSite" />
<DeleteClient @close="closeDeleteEditModal" :clientpk="deleteEditModalPk" @edited="refreshEntireSite" />
</q-dialog>
<!-- delete site modal -->
<q-dialog v-model="showDeleteSiteModal">
<DeleteSite @close="showDeleteSiteModal = false" @edited="refreshEntireSite" />
<DeleteSite @close="closeDeleteEditModal" :sitepk="deleteEditModalPk" @edited="refreshEntireSite" />
</q-dialog>
<!-- add policy modal -->
<q-dialog v-model="showPolicyAddModal">
@@ -268,6 +268,7 @@ export default {
poll: null,
search: null,
currentTRMMVersion: null,
deleteEditModalPk: null,
columns: [
{
name: "smsalert",
@@ -396,11 +397,11 @@ export default {
let client_id, site_id, url;
try {
site_id = activenode.split("|")[2];
site_id = activenode.split("|")[1];
url = `/agents/bysite/${site_id}/`;
} catch (e) {
try {
client_id = activenode.split("|")[2];
client_id = activenode.split("|")[1];
} catch (e) {
return false;
}
@@ -452,18 +453,27 @@ export default {
},
showEditModal(node) {
if (node.children) {
this.deleteEditModalPk = node.id;
this.showEditClientModal = true;
} else {
this.showEditSiteModal = true;
}
},
showDeleteModal(node) {
this.deleteEditModalPk = node.id;
if (node.children) {
this.showDeleteClientModal = true;
} else {
this.showDeleteSiteModal = true;
}
},
closeDeleteEditModal() {
this.showDeleteClientModal = false;
this.showDeleteSiteModal = false;
this.showEditSiteModal = false;
this.showEditClientModal = false;
this.deleteEditModalPk = null;
},
reload() {
this.$store.dispatch("reload");
},