mirror of
https://github.com/jpros/tacticalrmm-web.git
synced 2026-02-25 13:51:28 +00:00
Merge pull request #16 from sadnub/feature-policies-alerts
More Tests, Finished Task and Check policy tables, many fixes and ref…
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<div style="width: 900px; max-width: 90vw;">
|
||||
<q-card>
|
||||
<q-bar>
|
||||
<q-btn ref="refresh" @click="clearRow" class="q-mr-sm" dense flat push icon="refresh" />Automation Manager
|
||||
<q-btn ref="refresh" @click="refresh" class="q-mr-sm" dense flat push icon="refresh" />Automation Manager
|
||||
<q-space />
|
||||
<q-btn dense flat icon="close" v-close-popup>
|
||||
<q-tooltip content-class="bg-white text-primary">Close</q-tooltip>
|
||||
@@ -21,6 +21,30 @@
|
||||
icon="add"
|
||||
@click="showAddPolicyModal"
|
||||
/>
|
||||
<q-btn
|
||||
ref="edit"
|
||||
label="Edit"
|
||||
:disable="selectedRow === null"
|
||||
dense
|
||||
flat
|
||||
push
|
||||
unelevated
|
||||
no-caps
|
||||
icon="edit"
|
||||
@click="showEditPolicyModal(selectedRow)"
|
||||
/>
|
||||
<q-btn
|
||||
ref="delete"
|
||||
label="Delete"
|
||||
:disable="selectedRow === null"
|
||||
dense
|
||||
flat
|
||||
push
|
||||
unelevated
|
||||
no-caps
|
||||
icon="delete"
|
||||
@click="deletePolicy(selectedRow)"
|
||||
/>
|
||||
<q-btn
|
||||
ref="overview"
|
||||
label="Policy Overview"
|
||||
@@ -30,7 +54,7 @@
|
||||
unelevated
|
||||
no-caps
|
||||
icon="remove_red_eye"
|
||||
@click="showPolicyOverviewModal = true"
|
||||
@click="showPolicyOverview"
|
||||
/>
|
||||
</div>
|
||||
<q-table
|
||||
@@ -106,16 +130,12 @@
|
||||
<q-td>{{ props.row.desc }}</q-td>
|
||||
<q-td>{{ props.row.active }}</q-td>
|
||||
<q-td>
|
||||
<q-btn
|
||||
:label="`See Related (${props.row.clients.length + props.row.sites.length + props.row.agents.length}+)`"
|
||||
color="primary"
|
||||
dense
|
||||
flat
|
||||
unelevated
|
||||
no-caps
|
||||
<span
|
||||
style="cursor:pointer;color:blue;text-decoration:underline"
|
||||
@click="showRelationsModal(props.row)"
|
||||
size="sm"
|
||||
/>
|
||||
>
|
||||
{{ `See Related (${props.row.clients.length + props.row.sites.length + props.row.agents.length}+)` }}
|
||||
</span>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
@@ -123,29 +143,41 @@
|
||||
</div>
|
||||
|
||||
<q-card-section>
|
||||
<PolicySubTableTabs :policypk="selectedRow" />
|
||||
<PolicySubTableTabs />
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<q-dialog v-model="showPolicyFormModal">
|
||||
|
||||
<!-- policy form modal -->
|
||||
<q-dialog
|
||||
v-model="showPolicyFormModal"
|
||||
@hide="closePolicyFormModal"
|
||||
>
|
||||
<PolicyForm
|
||||
:pk="editPolicyId"
|
||||
@close="closeEditPolicyModal"
|
||||
@refresh="clearRow" />
|
||||
@close="closePolicyFormModal"
|
||||
/>
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showPolicyOverviewModal">
|
||||
<PolicyOverview
|
||||
@close="showPolicyOverviewModal = false" />
|
||||
|
||||
<!-- policy overview modal -->
|
||||
<q-dialog
|
||||
v-model="showPolicyOverviewModal"
|
||||
@hide="clearRow"
|
||||
>
|
||||
<PolicyOverview />
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showRelationsViewModal">
|
||||
<RelationsView
|
||||
:policy="policy"
|
||||
@close="closeRelationsModal" />
|
||||
|
||||
<!-- policy relations modal -->
|
||||
<q-dialog
|
||||
v-model="showRelationsViewModal"
|
||||
@hide="closeRelationsModal"
|
||||
>
|
||||
<RelationsView :policy="policy" />
|
||||
</q-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixins from "@/mixins/mixins";
|
||||
import mixins, { notifySuccessConfig, notifyErrorConfig } from "@/mixins/mixins";
|
||||
import { mapState } from "vuex";
|
||||
import PolicyForm from "@/components/automation/modals/PolicyForm";
|
||||
import PolicyOverview from "@/components/automation/PolicyOverview";
|
||||
@@ -208,17 +240,20 @@ export default {
|
||||
this.$store.dispatch("automation/loadPolicies");
|
||||
},
|
||||
policyRowSelected({ added, keys, rows }) {
|
||||
// First key of the array is the selected row pk
|
||||
// First item of the keys array is the selected policy pk
|
||||
this.$store.commit("automation/setSelectedPolicy", keys[0]);
|
||||
this.$store.dispatch("automation/loadPolicyChecks", keys[0]);
|
||||
this.$store.dispatch("automation/loadPolicyAutomatedTasks", keys[0]);
|
||||
},
|
||||
clearRow() {
|
||||
this.getPolicies();
|
||||
this.$store.commit("automation/setSelectedPolicy", null);
|
||||
this.$store.commit("automation/setPolicyChecks", {});
|
||||
this.$store.commit("automation/setPolicyAutomatedTasks", {});
|
||||
},
|
||||
refresh() {
|
||||
this.getPolicies();
|
||||
this.clearRow();
|
||||
},
|
||||
deletePolicy(id) {
|
||||
this.$q
|
||||
.dialog({
|
||||
@@ -230,10 +265,10 @@ export default {
|
||||
this.$store
|
||||
.dispatch("automation/deletePolicy", id)
|
||||
.then(response => {
|
||||
this.notifySuccess(`Policy was deleted!`);
|
||||
this.$q.notify(notifySuccessConfig("Policy was deleted!"));
|
||||
})
|
||||
.catch(error => {
|
||||
this.notifyError(`An Error occured while deleting policy`);
|
||||
this.$q.notify(notifyErrorConfig("An Error occured while deleting policy"));
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -249,12 +284,17 @@ export default {
|
||||
this.editPolicyId = id;
|
||||
this.showPolicyFormModal = true;
|
||||
},
|
||||
closeEditPolicyModal() {
|
||||
closePolicyFormModal() {
|
||||
this.showPolicyFormModal = false;
|
||||
this.editPolicyId = null;
|
||||
this.refresh();
|
||||
},
|
||||
showAddPolicyModal() {
|
||||
this.showPolicyFormModal = true;
|
||||
},
|
||||
showPolicyOverview() {
|
||||
this.showPolicyOverviewModal = true
|
||||
this.clearRow();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -264,7 +304,7 @@ export default {
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
this.clearRow();
|
||||
this.refresh();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,120 +0,0 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<template v-if="tasks === undefined || tasks.length === 0">
|
||||
<p>No Tasks on this policy</p>
|
||||
</template>
|
||||
<template v-else>
|
||||
<q-table
|
||||
dense
|
||||
class="tabs-tbl-sticky"
|
||||
:data="tasks"
|
||||
:columns="columns"
|
||||
:row-key="row => row.id"
|
||||
binary-state-sort
|
||||
:pagination.sync="pagination"
|
||||
hide-bottom
|
||||
>
|
||||
<!-- header slots -->
|
||||
<template v-slot:header-cell-enabled="props">
|
||||
<q-th auto-width :props="props">
|
||||
<small>Enabled</small>
|
||||
</q-th>
|
||||
</template>
|
||||
<!-- body slots -->
|
||||
<template slot="body" slot-scope="props" :props="props">
|
||||
<q-tr>
|
||||
<!-- tds -->
|
||||
<q-td>
|
||||
<q-checkbox disabled dense v-model="props.row.enabled" />
|
||||
</q-td>
|
||||
<q-td>{{ props.row.name }}</q-td>
|
||||
<q-td v-if="props.row.retcode || props.row.stdout || props.row.stderr">
|
||||
<span style="cursor:pointer;color:blue;text-decoration:underline">output</span>
|
||||
</q-td>
|
||||
<q-td v-else>Awaiting output</q-td>
|
||||
<q-td v-if="props.row.last_run">{{ props.row.last_run }}</q-td>
|
||||
<q-td v-else>Has not run yet</q-td>
|
||||
<q-td>{{ props.row.schedule }}</q-td>
|
||||
<q-td>{{ props.row.assigned_check }}</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import mixins from "@/mixins/mixins";
|
||||
|
||||
export default {
|
||||
name: "OverviewAutomatedTasksTab",
|
||||
props: ["policypk"],
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
automatedTasks: {},
|
||||
columns: [
|
||||
{ name: "enabled", align: "left", field: "enabled" },
|
||||
{ name: "name", label: "Name", field: "name", align: "left" },
|
||||
{
|
||||
name: "moreinfo",
|
||||
label: "More Info",
|
||||
field: "more_info",
|
||||
align: "left"
|
||||
},
|
||||
{
|
||||
name: "datetime",
|
||||
label: "Last Run Time",
|
||||
field: "last_run",
|
||||
align: "left"
|
||||
},
|
||||
{
|
||||
name: "schedule",
|
||||
label: "Schedule",
|
||||
field: "schedule",
|
||||
align: "left"
|
||||
},
|
||||
{
|
||||
name: "assignedcheck",
|
||||
label: "Assigned Check",
|
||||
field: "assigned_check",
|
||||
align: "left"
|
||||
}
|
||||
],
|
||||
pagination: {
|
||||
rowsPerPage: 9999
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getPolicyTasks();
|
||||
},
|
||||
watch: {
|
||||
policypk: function() {
|
||||
this.getPolicyTasks();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getPolicyTasks() {
|
||||
axios
|
||||
.get(`/automation/${this.policypk}/policyautomatedtasks/`)
|
||||
.then(r => {
|
||||
this.automatedTasks = r.data;
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tasks() {
|
||||
return this.automatedTasks.autotasks;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<template v-if="Object.keys(checks).length === 0 || allChecks.length === 0">
|
||||
<p>No checks on this policy</p>
|
||||
</template>
|
||||
<template v-else>
|
||||
<q-table
|
||||
dense
|
||||
class="tabs-tbl-sticky"
|
||||
:data="allChecks"
|
||||
:columns="columns"
|
||||
:row-key="row => row.id + row.check_type"
|
||||
binary-state-sort
|
||||
:pagination.sync="pagination"
|
||||
hide-bottom
|
||||
>
|
||||
<!-- header slots -->
|
||||
<template v-slot:header-cell-smsalert="props">
|
||||
<q-th auto-width :props="props">
|
||||
<q-icon name="phone_android" size="1.5em">
|
||||
<q-tooltip>SMS Alert</q-tooltip>
|
||||
</q-icon>
|
||||
</q-th>
|
||||
</template>
|
||||
<template v-slot:header-cell-emailalert="props">
|
||||
<q-th auto-width :props="props">
|
||||
<q-icon name="email" size="1.5em">
|
||||
<q-tooltip>Email Alert</q-tooltip>
|
||||
</q-icon>
|
||||
</q-th>
|
||||
</template>
|
||||
<template v-slot:header-cell-statusicon="props">
|
||||
<q-th auto-width :props="props"></q-th>
|
||||
</template>
|
||||
<!-- body slots -->
|
||||
<template slot="body" slot-scope="props" :props="props">
|
||||
<q-tr>
|
||||
<!-- tds -->
|
||||
<q-td>
|
||||
<q-checkbox disabled dense v-model="props.row.text_alert" />
|
||||
</q-td>
|
||||
<q-td>
|
||||
<q-checkbox disabled dense v-model="props.row.email_alert" />
|
||||
</q-td>
|
||||
<q-td v-if="props.row.status === 'pending'"></q-td>
|
||||
<q-td v-else-if="props.row.status === 'passing'">
|
||||
<q-icon style="font-size: 1.3rem;" color="positive" name="check_circle" />
|
||||
</q-td>
|
||||
<q-td v-else-if="props.row.status === 'failing'">
|
||||
<q-icon style="font-size: 1.3rem;" color="negative" name="error" />
|
||||
</q-td>
|
||||
<q-td
|
||||
v-if="props.row.check_type === 'diskspace'"
|
||||
>Disk Space Drive {{ props.row.disk }} > {{props.row.threshold }}%</q-td>
|
||||
<q-td
|
||||
v-else-if="props.row.check_type === 'cpuload'"
|
||||
>Avg CPU Load > {{ props.row.cpuload }}%</q-td>
|
||||
<q-td
|
||||
v-else-if="props.row.check_type === 'script'"
|
||||
>Script check: {{ props.row.script.name }}</q-td>
|
||||
<q-td
|
||||
v-else-if="props.row.check_type === 'ping'"
|
||||
>Ping {{ props.row.name }} ({{ props.row.ip }})</q-td>
|
||||
<q-td
|
||||
v-else-if="props.row.check_type === 'memory'"
|
||||
>Avg memory usage > {{ props.row.threshold }}%</q-td>
|
||||
<q-td
|
||||
v-else-if="props.row.check_type === 'winsvc'"
|
||||
>Service Check - {{ props.row.svc_display_name }}</q-td>
|
||||
<q-td
|
||||
v-else-if="props.row.check_type === 'eventlog'"
|
||||
>Event Log Check - {{ props.row.desc }}</q-td>
|
||||
<q-td v-if="props.row.status === 'pending'">Awaiting First Synchronization</q-td>
|
||||
<q-td v-else-if="props.row.status === 'passing'">
|
||||
<q-badge color="positive">Passing</q-badge>
|
||||
</q-td>
|
||||
<q-td v-else-if="props.row.status === 'failing'">
|
||||
<q-badge color="negative">Failing</q-badge>
|
||||
</q-td>
|
||||
<q-td v-if="props.row.check_type === 'ping'">
|
||||
<span style="cursor:pointer;color:blue;text-decoration:underline">output</span>
|
||||
</q-td>
|
||||
<q-td v-else-if="props.row.check_type === 'script'">
|
||||
<span style="cursor:pointer;color:blue;text-decoration:underline">output</span>
|
||||
</q-td>
|
||||
<q-td v-else>{{ props.row.more_info }}</q-td>
|
||||
<q-td>{{ props.row.last_run }}</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import mixins from "@/mixins/mixins";
|
||||
|
||||
export default {
|
||||
name: "OverviewChecksTab",
|
||||
props: ["policypk"],
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
checks: {},
|
||||
columns: [
|
||||
{ name: "smsalert", field: "text_alert", align: "left" },
|
||||
{ name: "emailalert", field: "email_alert", align: "left" },
|
||||
{ name: "statusicon", align: "left" },
|
||||
{ name: "desc", label: "Description", align: "left" },
|
||||
{ name: "status", label: "Status", field: "status", align: "left" },
|
||||
{
|
||||
name: "moreinfo",
|
||||
label: "More Info",
|
||||
field: "more_info",
|
||||
align: "left"
|
||||
},
|
||||
{
|
||||
name: "datetime",
|
||||
label: "Date / Time",
|
||||
field: "last_run",
|
||||
align: "left"
|
||||
}
|
||||
],
|
||||
pagination: {
|
||||
rowsPerPage: 9999
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getPolicyChecks();
|
||||
},
|
||||
watch: {
|
||||
policypk: function() {
|
||||
this.getPolicyChecks();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getPolicyChecks() {
|
||||
axios
|
||||
.get(`/checks/${this.policypk}/loadpolicychecks/`)
|
||||
.then(r => {
|
||||
this.checks = r.data;
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
allChecks() {
|
||||
return [
|
||||
...this.checks.diskchecks,
|
||||
...this.checks.cpuloadchecks,
|
||||
...this.checks.memchecks,
|
||||
...this.checks.scriptchecks,
|
||||
...this.checks.winservicechecks,
|
||||
...this.checks.pingchecks,
|
||||
...this.checks.eventlogchecks
|
||||
];
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
text-color="black"
|
||||
@click="showAddAutomatedTask = true"
|
||||
/>
|
||||
<q-btn dense flat push @click="refreshTasks(automatedTasks.pk)" icon="refresh" />
|
||||
<q-btn dense flat push @click="refreshTasks(automatedTasks.id)" icon="refresh" />
|
||||
<template v-if="tasks === undefined || tasks.length === 0">
|
||||
<p>No Tasks</p>
|
||||
</template>
|
||||
@@ -70,13 +70,12 @@
|
||||
/>
|
||||
</q-td>
|
||||
<q-td>{{ props.row.name }}</q-td>
|
||||
<q-td v-if="props.row.retcode || props.row.stdout || props.row.stderr">
|
||||
<q-td>
|
||||
<span
|
||||
style="cursor:pointer;color:blue;text-decoration:underline"
|
||||
@click="scriptMoreInfo(props.row)"
|
||||
>output</span>
|
||||
@click="showStatus(props.row)"
|
||||
>See Status</span>
|
||||
</q-td>
|
||||
<q-td v-else>Awaiting output</q-td>
|
||||
<q-td v-if="props.row.last_run">{{ props.row.last_run }}</q-td>
|
||||
<q-td v-else>Has not run yet</q-td>
|
||||
<q-td>{{ props.row.schedule }}</q-td>
|
||||
@@ -88,39 +87,48 @@
|
||||
</div>
|
||||
<!-- modals -->
|
||||
<q-dialog v-model="showAddAutomatedTask" position="top">
|
||||
<AddAutomatedTask @close="showAddAutomatedTask = false" />
|
||||
<AddAutomatedTask
|
||||
:policypk="automatedTasks.id"
|
||||
@close="showAddAutomatedTask = false"
|
||||
/>
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog v-model="showScriptOutput">
|
||||
<ScriptOutput @close="showScriptOutput = false; scriptInfo = {}" :scriptInfo="scriptInfo" />
|
||||
<!-- policy task status -->
|
||||
<q-dialog v-model="showPolicyTaskStatus">
|
||||
<PolicyStatus
|
||||
type="task"
|
||||
:item="statusTask"
|
||||
:description="`${statusTask.name} Agent Status`"
|
||||
/>
|
||||
</q-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import { mapState } from "vuex";
|
||||
import mixins from "@/mixins/mixins";
|
||||
import mixins, { notifySuccessConfig, notifyErrorConfig } from "@/mixins/mixins";
|
||||
import AddAutomatedTask from "@/components/modals/tasks/AddAutomatedTask";
|
||||
import ScriptOutput from "@/components/modals/checks/ScriptOutput";
|
||||
import PolicyStatus from "@/components/automation/modals/PolicyStatus";
|
||||
|
||||
export default {
|
||||
name: "PolicyAutomatedTasksTab",
|
||||
components: { AddAutomatedTask, ScriptOutput },
|
||||
components: {
|
||||
AddAutomatedTask,
|
||||
PolicyStatus
|
||||
},
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
showAddAutomatedTask: false,
|
||||
showEditAutomatedTask: false,
|
||||
showScriptOutput: false,
|
||||
showPolicyTaskStatus: false,
|
||||
statusTask: {},
|
||||
editTaskPk: null,
|
||||
showScriptOutput: false,
|
||||
scriptInfo: {},
|
||||
columns: [
|
||||
{ name: "enabled", align: "left", field: "enabled" },
|
||||
{ name: "name", label: "Name", field: "name", align: "left" },
|
||||
{
|
||||
name: "moreinfo",
|
||||
name: "status",
|
||||
label: "More Info",
|
||||
field: "more_info",
|
||||
align: "left"
|
||||
@@ -151,31 +159,32 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
taskEnableorDisable(pk, action) {
|
||||
const data = { enableordisable: action };
|
||||
axios
|
||||
.patch(`/tasks/${pk}/automatedtasks/`, data)
|
||||
const data = { id: pk, enableordisable: action };
|
||||
this.$store
|
||||
.dispatch("editAutoTask", data)
|
||||
.then(r => {
|
||||
this.$store.dispatch("automation/loadPolicyAutomatedTasks", this.automatedTasks.pk);
|
||||
this.notifySuccess(r.data);
|
||||
this.$store.dispatch("automation/loadPolicyAutomatedTasks", this.automatedTasks.id
|
||||
);
|
||||
this.$q.notify(notifySuccessConfig(r.data));
|
||||
})
|
||||
.catch(e => this.notifyError("Something went wrong"));
|
||||
.catch(e => this.$q.notify(notifySuccessConfig("Something went wrong")));
|
||||
},
|
||||
showStatus(task) {
|
||||
this.statusTask = task;
|
||||
this.showPolicyTaskStatus = true
|
||||
},
|
||||
refreshTasks(id) {
|
||||
this.$store.dispatch("automation/loadPolicyAutomatedTasks", id);
|
||||
},
|
||||
scriptMoreInfo(props) {
|
||||
this.scriptInfo = props;
|
||||
this.showScriptOutput = true;
|
||||
},
|
||||
runTask(pk, enabled) {
|
||||
if (!enabled) {
|
||||
this.notifyError("Task cannot be run when it's disabled. Enable it first.");
|
||||
this.$q.notify(notifyErrorConfig("Task cannot be run when it's disabled. Enable it first."));
|
||||
return;
|
||||
}
|
||||
axios
|
||||
.get(`/automation/runwintask/${pk}/`)
|
||||
.then(r => this.notifySuccess(r.data))
|
||||
.catch(() => this.notifyError("Something went wrong"));
|
||||
this.$store
|
||||
.dispatch("automation/runPolicyTask", pk)
|
||||
.then(r => this.$q.notify(notifySuccessConfig(r.data)))
|
||||
.catch(() => this.$q.notify(notifyErrorConfig("Something went wrong")));
|
||||
},
|
||||
deleteTask(name, pk) {
|
||||
this.$q
|
||||
@@ -186,13 +195,13 @@ export default {
|
||||
persistent: true
|
||||
})
|
||||
.onOk(() => {
|
||||
axios
|
||||
.delete(`/automation/${pk}/automatedtasks/`)
|
||||
this.$store
|
||||
.dispatch("deleteAutoTask", pk)
|
||||
.then(r => {
|
||||
this.$store.dispatch("automation/loadPolicyChecks", this.automatedTasks.pk);
|
||||
this.notifySuccess(r.data);
|
||||
this.$store.dispatch("automation/loadPolicyAutomatedTasks", this.automatedTasks.id);
|
||||
this.$q.notify(notifySuccessConfig(r.data));
|
||||
})
|
||||
.catch(e => this.notifyError("Something went wrong"));
|
||||
.catch(e => this.$q.notify(notifyErrorConfig("Something went wrong")));
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -2,46 +2,52 @@
|
||||
<div v-if="Object.keys(checks).length === 0">No Policy Selected</div>
|
||||
<div class="row" v-else>
|
||||
<div class="col-12">
|
||||
<q-btn size="sm" color="grey-5" icon="fas fa-plus" label="Add Check" text-color="black">
|
||||
<q-btn
|
||||
size="sm"
|
||||
color="grey-5"
|
||||
icon="fas fa-plus"
|
||||
label="Add Check"
|
||||
text-color="black"
|
||||
>
|
||||
<q-menu>
|
||||
<q-list dense style="min-width: 200px">
|
||||
<q-item clickable v-close-popup @click="showAddDiskSpaceCheck = true">
|
||||
<q-item clickable v-close-popup @click="showAddDialog('AddDiskSpaceCheck')">
|
||||
<q-item-section side>
|
||||
<q-icon size="xs" name="far fa-hdd" />
|
||||
</q-item-section>
|
||||
<q-item-section>Disk Space Check</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="showAddPingCheck = true">
|
||||
<q-item clickable v-close-popup @click="showAddDialog('AddPingCheck')">
|
||||
<q-item-section side>
|
||||
<q-icon size="xs" name="fas fa-network-wired" />
|
||||
</q-item-section>
|
||||
<q-item-section>Ping Check</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="showAddCpuLoadCheck = true">
|
||||
<q-item clickable v-close-popup @click="showAddDialog('AddCpuLoadCheck')">
|
||||
<q-item-section side>
|
||||
<q-icon size="xs" name="fas fa-microchip" />
|
||||
</q-item-section>
|
||||
<q-item-section>CPU Load Check</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="showAddMemCheck = true">
|
||||
<q-item clickable v-close-popup @click="showAddDialog('AddMemCheck')">
|
||||
<q-item-section side>
|
||||
<q-icon size="xs" name="fas fa-memory" />
|
||||
</q-item-section>
|
||||
<q-item-section>Memory Check</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="showAddWinSvcCheck = true">
|
||||
<q-item clickable v-close-popup @click="showAddDialog('AddWinSvcCheck')">
|
||||
<q-item-section side>
|
||||
<q-icon size="xs" name="fas fa-cogs" />
|
||||
</q-item-section>
|
||||
<q-item-section>Windows Service Check</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="showAddScriptCheck = true">
|
||||
<q-item clickable v-close-popup @click="showAddDialog('AddScriptCheck')">
|
||||
<q-item-section side>
|
||||
<q-icon size="xs" name="fas fa-terminal" />
|
||||
</q-item-section>
|
||||
<q-item-section>Script Check</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="showAddEventLogCheck = true">
|
||||
<q-item clickable v-close-popup @click="showAddDialog('AddEventLogCheck')">
|
||||
<q-item-section side>
|
||||
<q-icon size="xs" name="fas fa-clipboard-list" />
|
||||
</q-item-section>
|
||||
@@ -50,7 +56,13 @@
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
<q-btn dense flat push @click="onRefresh(checks.id)" icon="refresh" />
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
push
|
||||
@click="onRefresh(checks.id)"
|
||||
icon="refresh"
|
||||
/>
|
||||
<template v-if="allChecks === undefined || allChecks.length === 0">
|
||||
<p>No Checks</p>
|
||||
</template>
|
||||
@@ -84,12 +96,16 @@
|
||||
<q-th auto-width :props="props"></q-th>
|
||||
</template>
|
||||
<!-- body slots -->
|
||||
<template slot="body" slot-scope="props" :props="props">
|
||||
<q-tr @contextmenu="editCheckPK = props.row.id">
|
||||
<template v-slot:body="props">
|
||||
<q-tr @contextmenu="editCheckPK = props.row.id" :props="props">
|
||||
<!-- context menu -->
|
||||
<q-menu context-menu>
|
||||
<q-list dense style="min-width: 200px">
|
||||
<q-item clickable v-close-popup @click="editCheck(props.row.check_type)">
|
||||
<q-item
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="showEditDialog(props.row.check_type)"
|
||||
>
|
||||
<q-item-section side>
|
||||
<q-icon name="edit" />
|
||||
</q-item-section>
|
||||
@@ -110,9 +126,9 @@
|
||||
|
||||
<q-item clickable v-close-popup @click="showPolicyCheckStatusModal(props.row)">
|
||||
<q-item-section side>
|
||||
<q-icon name="remove_red_eye" />
|
||||
<q-icon name="sync" />
|
||||
</q-item-section>
|
||||
<q-item-section>Status</q-item-section>
|
||||
<q-item-section>Policy Status</q-item-section>
|
||||
</q-item>
|
||||
|
||||
<q-separator></q-separator>
|
||||
@@ -137,182 +153,58 @@
|
||||
v-model="props.row.email_alert"
|
||||
/>
|
||||
</q-td>
|
||||
<q-td
|
||||
v-if="props.row.check_type === 'diskspace'"
|
||||
>Disk Space Drive {{ props.row.disk }} > {{props.row.threshold }}%</q-td>
|
||||
<q-td
|
||||
v-else-if="props.row.check_type === 'cpuload'"
|
||||
>Avg CPU Load > {{ props.row.cpuload }}%</q-td>
|
||||
<q-td
|
||||
v-else-if="props.row.check_type === 'script'"
|
||||
>Script check: {{ props.row.script.name }}</q-td>
|
||||
<q-td
|
||||
v-else-if="props.row.check_type === 'ping'"
|
||||
>Ping {{ props.row.name }} ({{ props.row.ip }})</q-td>
|
||||
<q-td
|
||||
v-else-if="props.row.check_type === 'memory'"
|
||||
>Avg memory usage > {{ props.row.threshold }}%</q-td>
|
||||
<q-td
|
||||
v-else-if="props.row.check_type === 'winsvc'"
|
||||
>Service Check - {{ props.row.svc_display_name }}</q-td>
|
||||
<q-td
|
||||
v-else-if="props.row.check_type === 'eventlog'"
|
||||
>Event Log Check - {{ props.row.desc }}</q-td>
|
||||
<q-td>{{ getDescription(props.row) }}</q-td>
|
||||
<q-td>
|
||||
<q-btn
|
||||
label="See Status"
|
||||
color="primary"
|
||||
dense
|
||||
flat
|
||||
unelevated
|
||||
no-caps
|
||||
<span
|
||||
style="cursor:pointer;color:blue;text-decoration:underline"
|
||||
@click="showPolicyCheckStatusModal(props.row)"
|
||||
size="sm"
|
||||
/>
|
||||
>
|
||||
See Status
|
||||
</span>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
</template>
|
||||
</div>
|
||||
<!-- modals -->
|
||||
<q-dialog v-model="showAddDiskSpaceCheck">
|
||||
<AddDiskSpaceCheck @close="showAddDiskSpaceCheck = false" :policypk="checks.id" />
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showEditDiskSpaceCheck">
|
||||
<EditDiskSpaceCheck
|
||||
@close="showEditDiskSpaceCheck = false"
|
||||
:editCheckPK="editCheckPK"
|
||||
:policypk="checks.id"
|
||||
/>
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showAddPingCheck">
|
||||
<AddPingCheck @close="showAddPingCheck = false" :policypk="checks.id" />
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showEditPingCheck">
|
||||
<EditPingCheck
|
||||
@close="showEditPingCheck = false"
|
||||
:editCheckPK="editCheckPK"
|
||||
:policypk="checks.id"
|
||||
/>
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showAddCpuLoadCheck">
|
||||
<AddCpuLoadCheck @close="showAddCpuLoadCheck = false" :policypk="checks.id" />
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showEditCpuLoadCheck">
|
||||
<EditCpuLoadCheck
|
||||
@close="showEditCpuLoadCheck = false"
|
||||
:editCheckPK="editCheckPK"
|
||||
:policypk="checks.id"
|
||||
/>
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showAddMemCheck">
|
||||
<AddMemCheck @close="showAddMemCheck = false" :policypk="checks.id" />
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showEditMemCheck">
|
||||
<EditMemCheck
|
||||
@close="showEditMemCheck = false"
|
||||
:editCheckPK="editCheckPK"
|
||||
:policypk="checks.id"
|
||||
/>
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showAddWinSvcCheck">
|
||||
<AddWinSvcCheck @close="showAddWinSvcCheck = false" :policypk="checks.id" />
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showEditWinSvcCheck">
|
||||
<EditWinSvcCheck
|
||||
@close="showEditWinSvcCheck = false"
|
||||
:editCheckPK="editCheckPK"
|
||||
:policypk="checks.id"
|
||||
/>
|
||||
</q-dialog>
|
||||
<!-- script check -->
|
||||
<q-dialog v-model="showAddScriptCheck">
|
||||
<AddScriptCheck @close="showAddScriptCheck = false" :policypk="checks.id" />
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showEditScriptCheck">
|
||||
<EditScriptCheck
|
||||
@close="showEditScriptCheck = false"
|
||||
:editCheckPK="editCheckPK"
|
||||
:policypk="checks.id"
|
||||
/>
|
||||
</q-dialog>
|
||||
<!-- event log check -->
|
||||
<q-dialog v-model="showAddEventLogCheck">
|
||||
<AddEventLogCheck @close="showAddEventLogCheck = false" :policypk="checks.id" />
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showEditEventLogCheck">
|
||||
<EditEventLogCheck
|
||||
@close="showEditEventLogCheck = false"
|
||||
:editCheckPK="editCheckPK"
|
||||
:policypk="checks.id"
|
||||
/>
|
||||
</q-dialog>
|
||||
|
||||
<!-- policy status -->
|
||||
<q-dialog v-model="showPolicyCheckStatus">
|
||||
<PolicyCheckStatus :check="statusCheck" @close="closePolicyCheckStatusModal" />
|
||||
<PolicyStatus
|
||||
type="check"
|
||||
:item="statusCheck"
|
||||
:description="getDescription(statusCheck)"
|
||||
/>
|
||||
</q-dialog>
|
||||
|
||||
<!-- add/edit modals -->
|
||||
<q-dialog v-model="showDialog">
|
||||
<component
|
||||
:is="dialogComponent"
|
||||
@close="hideDialog"
|
||||
:policypk="checks.id"
|
||||
:editCheckPK="editCheckPK"
|
||||
/>
|
||||
</q-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import { mapState } from "vuex";
|
||||
import mixins from "@/mixins/mixins";
|
||||
import AddDiskSpaceCheck from "@/components/modals/checks/AddDiskSpaceCheck";
|
||||
import EditDiskSpaceCheck from "@/components/modals/checks/EditDiskSpaceCheck";
|
||||
import AddPingCheck from "@/components/modals/checks/AddPingCheck";
|
||||
import EditPingCheck from "@/components/modals/checks/EditPingCheck";
|
||||
import AddCpuLoadCheck from "@/components/modals/checks/AddCpuLoadCheck";
|
||||
import EditCpuLoadCheck from "@/components/modals/checks/EditCpuLoadCheck";
|
||||
import AddMemCheck from "@/components/modals/checks/AddMemCheck";
|
||||
import EditMemCheck from "@/components/modals/checks/EditMemCheck";
|
||||
import AddWinSvcCheck from "@/components/modals/checks/AddWinSvcCheck";
|
||||
import EditWinSvcCheck from "@/components/modals/checks/EditWinSvcCheck";
|
||||
import AddScriptCheck from "@/components/modals/checks/AddScriptCheck";
|
||||
import EditScriptCheck from "@/components/modals/checks/EditScriptCheck";
|
||||
import PolicyCheckStatus from "@/components/automation/modals/PolicyCheckStatus";
|
||||
import AddEventLogCheck from "@/components/modals/checks/AddEventLogCheck";
|
||||
import EditEventLogCheck from "@/components/modals/checks/EditEventLogCheck";
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import mixins, { notifySuccessConfig, notifyErrorConfig } from "@/mixins/mixins";
|
||||
import PolicyStatus from "@/components/automation/modals/PolicyStatus";
|
||||
|
||||
export default {
|
||||
name: "PolicyChecksTab",
|
||||
props: ["policypk"],
|
||||
components: {
|
||||
AddDiskSpaceCheck,
|
||||
EditDiskSpaceCheck,
|
||||
AddPingCheck,
|
||||
EditPingCheck,
|
||||
AddCpuLoadCheck,
|
||||
EditCpuLoadCheck,
|
||||
AddMemCheck,
|
||||
EditMemCheck,
|
||||
AddWinSvcCheck,
|
||||
EditWinSvcCheck,
|
||||
AddScriptCheck,
|
||||
EditScriptCheck,
|
||||
PolicyCheckStatus,
|
||||
AddEventLogCheck,
|
||||
EditEventLogCheck
|
||||
PolicyStatus
|
||||
},
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
showAddDiskSpaceCheck: false,
|
||||
showEditDiskSpaceCheck: false,
|
||||
showAddPingCheck: false,
|
||||
showEditPingCheck: false,
|
||||
showAddCpuLoadCheck: false,
|
||||
showEditCpuLoadCheck: false,
|
||||
showAddMemCheck: false,
|
||||
showEditMemCheck: false,
|
||||
showAddWinSvcCheck: false,
|
||||
showEditWinSvcCheck: false,
|
||||
showAddScriptCheck: false,
|
||||
showEditScriptCheck: false,
|
||||
dialogComponent: null,
|
||||
showDialog: false,
|
||||
showPolicyCheckStatus: false,
|
||||
showAddEventLogCheck: false,
|
||||
showEditEventLogCheck: false,
|
||||
editCheckPK: null,
|
||||
statusCheck: {},
|
||||
columns: [
|
||||
@@ -336,43 +228,58 @@ export default {
|
||||
action: action
|
||||
};
|
||||
const alertColor = alert_action ? "positive" : "warning";
|
||||
axios.patch("/checks/checkalert/", data).then(r => {
|
||||
this.$q.notify({
|
||||
color: alertColor,
|
||||
icon: "fas fa-check-circle",
|
||||
message: `${alert_type} alerts ${action}`
|
||||
this.$store
|
||||
.dispatch("editCheckAlertAction", data)
|
||||
.then(r => {
|
||||
this.$q.notify({
|
||||
color: alertColor,
|
||||
icon: "fas fa-check-circle",
|
||||
message: `${alert_type} alerts ${action}`
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
onRefresh(id) {
|
||||
this.$store.dispatch("automation/loadPolicyChecks", id);
|
||||
},
|
||||
editCheck(category) {
|
||||
showAddDialog(component) {
|
||||
this.dialogComponent = () => import(`@/components/modals/checks/${component}`);
|
||||
this.showDialog = true;
|
||||
},
|
||||
showEditDialog(category) {
|
||||
let component = null;
|
||||
|
||||
switch (category) {
|
||||
case "diskspace":
|
||||
this.showEditDiskSpaceCheck = true;
|
||||
component = "EditDiskSpaceCheck";
|
||||
break;
|
||||
case "ping":
|
||||
this.showEditPingCheck = true;
|
||||
component = "EditPingCheck";
|
||||
break;
|
||||
case "cpuload":
|
||||
this.showEditCpuLoadCheck = true;
|
||||
tcomponent = "EditCpuLoadCheck";
|
||||
break;
|
||||
case "memory":
|
||||
this.showEditMemCheck = true;
|
||||
component = "EditMemCheck";
|
||||
break;
|
||||
case "winsvc":
|
||||
this.showEditWinSvcCheck = true;
|
||||
component = "EditWinSvcCheck";
|
||||
break;
|
||||
case "script":
|
||||
this.showEditScriptCheck = true;
|
||||
component = "EditScriptCheck";
|
||||
break;
|
||||
case "eventlog":
|
||||
this.showEditEventLogCheck = true;
|
||||
component = "EditEventLogCheck";
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
this.dialogComponent = () => import(`@/components/modals/checks/${component}`);
|
||||
this.showDialog = true;
|
||||
},
|
||||
hideDialog(component) {
|
||||
this.showDialog = false;
|
||||
this.dialogComponent = null;
|
||||
},
|
||||
deleteCheck(pk, check_type) {
|
||||
this.$q
|
||||
@@ -384,13 +291,13 @@ export default {
|
||||
})
|
||||
.onOk(() => {
|
||||
const data = { pk: pk, checktype: check_type };
|
||||
axios
|
||||
.delete("checks/deletestandardcheck/", { data: data })
|
||||
this.$store
|
||||
.dispatch("deleteCheck", data)
|
||||
.then(r => {
|
||||
this.$store.dispatch("automation/loadPolicyChecks", this.policypk);
|
||||
this.notifySuccess("Check was deleted!");
|
||||
this.$store.dispatch("automation/loadPolicyChecks", this.checks.id);
|
||||
this.$q.notify(notifySuccessConfig);
|
||||
})
|
||||
.catch(e => this.notifyError(e.response.data.error));
|
||||
.catch(e => this.$q.notify(notifyErrorConfig));
|
||||
});
|
||||
},
|
||||
showPolicyCheckStatusModal(check) {
|
||||
@@ -400,23 +307,31 @@ export default {
|
||||
closePolicyCheckStatusModal() {
|
||||
this.showPolicyCheckStatus = false;
|
||||
this.statusCheck = {};
|
||||
},
|
||||
getDescription(check) {
|
||||
if (check.check_type === "diskspace")
|
||||
return `Disk Space Drive ${check.disk} > ${check.threshold}%`;
|
||||
else if (check.check_type === "cpuload")
|
||||
return `Avg CPU Load > ${check.cpuload}%`;
|
||||
else if (check.check_type === "script")
|
||||
return `Script check: ${check.script.name}`;
|
||||
else if (check.check_type === "ping")
|
||||
return `Ping ${check.name} (${check.ip})`;
|
||||
else if (check.check_type === "memory")
|
||||
return `Avg memory usage > ${check.threshold}%`;
|
||||
else if (check.check_type === "winsvc")
|
||||
return `Service Check - ${check.svc_display_name}`;
|
||||
else if (check.check_type === "eventlog")
|
||||
return `Event Log Check - ${check.desc}`
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
checks: state => state.automation.checks
|
||||
}),
|
||||
allChecks() {
|
||||
return [
|
||||
...this.checks.diskchecks,
|
||||
...this.checks.cpuloadchecks,
|
||||
...this.checks.memchecks,
|
||||
...this.checks.scriptchecks,
|
||||
...this.checks.winservicechecks,
|
||||
...this.checks.pingchecks,
|
||||
...this.checks.eventlogchecks
|
||||
];
|
||||
}
|
||||
...mapGetters({
|
||||
allChecks: "automation/allChecks"
|
||||
})
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<template v-slot:before>
|
||||
<div class="q-pa-md">
|
||||
<q-tree
|
||||
ref="Tree"
|
||||
ref="tree"
|
||||
:nodes="clientSiteTree"
|
||||
node-key="id"
|
||||
:selected.sync="selected"
|
||||
@@ -44,16 +44,10 @@
|
||||
transition-next="jump-up"
|
||||
>
|
||||
<q-tab-panel name="checks">
|
||||
<template v-if="Object.keys(selectedPolicy).length === 0">
|
||||
<p>Select a Policy</p>
|
||||
</template>
|
||||
<OverviewChecksTab v-else :policypk="policypk" />
|
||||
<PolicyChecksTab :readonly="true" />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="tasks">
|
||||
<template v-if="Object.keys(selectedPolicy).length === 0">
|
||||
<p>Select a Policy</p>
|
||||
</template>
|
||||
<OverviewAutomatedTasksTab v-else :policypk="policypk" />
|
||||
<PolicyAutomatedTasksTab/>
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</template>
|
||||
@@ -62,16 +56,15 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import mixins from "@/mixins/mixins";
|
||||
import OverviewChecksTab from "@/components/automation/OverviewChecksTab";
|
||||
import OverviewAutomatedTasksTab from "@/components/automation/OverviewAutomatedTasksTab";
|
||||
import mixins, { notifyErrorConfig } from "@/mixins/mixins";
|
||||
import PolicyChecksTab from "@/components/automation/PolicyChecksTab";
|
||||
import PolicyAutomatedTasksTab from "@/components/automation/PolicyAutomatedTasksTab";
|
||||
|
||||
export default {
|
||||
name: "PolicyOverview",
|
||||
components: {
|
||||
OverviewChecksTab,
|
||||
OverviewAutomatedTasksTab
|
||||
PolicyAutomatedTasksTab,
|
||||
PolicyChecksTab
|
||||
},
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
@@ -83,26 +76,28 @@ export default {
|
||||
clientSiteTree: []
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.getPolicyTree();
|
||||
},
|
||||
methods: {
|
||||
getPolicyTree() {
|
||||
axios
|
||||
.get(`/automation/policies/overview/`)
|
||||
this.$store
|
||||
.dispatch("automation/loadPolicyTreeData")
|
||||
.then(r => {
|
||||
this.processTreeDataFromApi(r.data);
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
this.$q.notify(notifyErrorConfig(e.response.data));
|
||||
});
|
||||
},
|
||||
loadPolicyDetails(key) {
|
||||
if (key === undefined) {
|
||||
if (key === undefined || key === null) {
|
||||
return;
|
||||
}
|
||||
this.selectedPolicy = this.$refs.Tree.getNodeByKey(key);
|
||||
|
||||
this.selectedPolicy = this.$refs.tree.getNodeByKey(key);
|
||||
|
||||
this.$store.dispatch("automation/loadPolicyChecks", this.selectedPolicy.id);
|
||||
this.$store.dispatch("automation/loadPolicyAutomatedTasks", this.selectedPolicy.id);
|
||||
|
||||
},
|
||||
processTreeDataFromApi(data) {
|
||||
/* Structure
|
||||
@@ -110,12 +105,14 @@ export default {
|
||||
* "client_name_1": {
|
||||
* "policies": [
|
||||
* {
|
||||
* id: 1
|
||||
* id: 1,
|
||||
* name: "Policy Name 1"
|
||||
* }
|
||||
* ]
|
||||
* "site_name_1": {
|
||||
* "policies": []
|
||||
* ],
|
||||
* sites: {
|
||||
* "site_name_1": {
|
||||
* "policies": []
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }]
|
||||
@@ -138,13 +135,22 @@ export default {
|
||||
unique_id--;
|
||||
|
||||
// Add any policies assigned to client
|
||||
|
||||
if (data[client].policies.length > 0) {
|
||||
for (let policy in data[client].policies)
|
||||
for (let policy in data[client].policies) {
|
||||
let disabled = "";
|
||||
|
||||
// Indicate if the policy is active or not
|
||||
if (!data[client].policies[policy].active) {
|
||||
disabled = " (disabled)";
|
||||
}
|
||||
|
||||
client_temp["children"].push({
|
||||
label: data[client].policies[policy].name,
|
||||
label: data[client].policies[policy].name + disabled,
|
||||
icon: "policy",
|
||||
id: data[client].policies[policy].id
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate through Sites
|
||||
@@ -162,8 +168,15 @@ export default {
|
||||
site_temp["children"] = [];
|
||||
|
||||
for (let policy in data[client].sites[site].policies) {
|
||||
|
||||
// Indicate if the policy is active or not
|
||||
let disabled = "";
|
||||
if (!data[client].sites[site].policies[policy].active) {
|
||||
disabled = " (disabled)";
|
||||
}
|
||||
|
||||
site_temp["children"].push({
|
||||
label: data[client].sites[site].policies[policy].name,
|
||||
label: data[client].sites[site].policies[policy].name + disabled,
|
||||
icon: "policy",
|
||||
id: data[client].sites[site].policies[policy].id
|
||||
});
|
||||
@@ -181,10 +194,8 @@ export default {
|
||||
this.clientSiteTree = result;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
policypk() {
|
||||
return this.selectedPolicy.id;
|
||||
}
|
||||
}
|
||||
mounted() {
|
||||
this.getPolicyTree();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<q-separator />
|
||||
<q-tab-panels v-model="subtab" :animated="false">
|
||||
<q-tab-panel name="checks">
|
||||
<PolicyChecksTab :policypk="policypk" />
|
||||
<PolicyChecksTab />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="tasks">
|
||||
<PolicyAutomatedTasksTab />
|
||||
@@ -32,7 +32,6 @@ import PolicyAutomatedTasksTab from "@/components/automation/PolicyAutomatedTask
|
||||
|
||||
export default {
|
||||
name: "PolicySubTableTabs",
|
||||
props: ["policypk"],
|
||||
components: {
|
||||
PolicyChecksTab,
|
||||
PolicyAutomatedTasksTab
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<template>
|
||||
<q-card style="width: 60vw" >
|
||||
<q-card-section class="row items-center">
|
||||
<div class="text-h6">Policy Name Status</div>
|
||||
<div class="text-subtitle1">{{ this.check.desc }}</div>
|
||||
<q-space />
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-list bordered separator>
|
||||
<q-item>
|
||||
<q-item-section>Single line item</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "PolicyCheckStatus",
|
||||
props: {
|
||||
check: {
|
||||
required: true,
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -98,7 +98,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixins from "@/mixins/mixins";
|
||||
import mixins, { notifySuccessConfig, notifyErrorConfig } from "@/mixins/mixins";
|
||||
import dropdown_formatter from "@/mixins/dropdown_formatter";
|
||||
|
||||
export default {
|
||||
@@ -146,7 +146,7 @@ export default {
|
||||
},
|
||||
submit() {
|
||||
if (!this.name) {
|
||||
this.notifyError("Name is required!");
|
||||
this.$q.notify(notifySuccessConfig("Name is required!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -167,12 +167,11 @@ export default {
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$emit("close");
|
||||
this.$emit("refresh");
|
||||
this.notifySuccess("Policy edited!");
|
||||
this.$q.notify(notifySuccessConfig("Policy edited!"));
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
this.$q.notify(notifyErrorConfig(e.response.data));
|
||||
});
|
||||
} else {
|
||||
this.$store
|
||||
@@ -180,12 +179,11 @@ export default {
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$emit("close");
|
||||
this.$emit("refresh");
|
||||
this.notifySuccess("Policy added! Now you can add Tasks and Checks!");
|
||||
this.$q.notify(notifySuccessConfig("Policy added! Now you can add Tasks and Checks!"));
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
this.$q.notify(notifyErrorConfig(e.response.data));
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
59
src/components/automation/modals/PolicyStatus.vue
Normal file
59
src/components/automation/modals/PolicyStatus.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<q-card style="width: 60vw" >
|
||||
<q-card-section class="row items-center">
|
||||
<div class="text-h6">{{ this.description }}</div>
|
||||
<q-space />
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-list bordered separator>
|
||||
<q-item>
|
||||
<q-item-section>Single line item</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "PolicyStatus",
|
||||
props: {
|
||||
item: {
|
||||
required: true,
|
||||
type: Object
|
||||
},
|
||||
type: {
|
||||
required: true,
|
||||
type: String,
|
||||
validator: function (value) {
|
||||
// The value must match one of these strings
|
||||
return ["task", "check"].includes(value);
|
||||
}
|
||||
},
|
||||
description: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
checkData: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCheckData() {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
selectedPolicyId: state => state.automation.selectedPolicyId
|
||||
}),
|
||||
},
|
||||
mounted() {
|
||||
this.getCheckData();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -108,12 +108,14 @@
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import { mapState } from "vuex";
|
||||
import { mapGetters } from "vuex";
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import mixins from "@/mixins/mixins";
|
||||
|
||||
export default {
|
||||
name: "AddAutomatedTask",
|
||||
props: {
|
||||
policypk: Number
|
||||
},
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
@@ -141,8 +143,10 @@ export default {
|
||||
if (!this.step1Done || !this.step2Done) {
|
||||
this.notifyError("Some steps incomplete");
|
||||
} else {
|
||||
const pk = this.policypk ? { policy: this.policypk } : { agent: this.selectedAgentPk };
|
||||
|
||||
const data = {
|
||||
agent: this.selectedAgentPk,
|
||||
...pk,
|
||||
name: this.taskName,
|
||||
script: this.scriptPk,
|
||||
trigger: this.trigger,
|
||||
@@ -151,12 +155,20 @@ export default {
|
||||
days: this.days,
|
||||
timeout: this.timeout
|
||||
};
|
||||
|
||||
console.log(data)
|
||||
axios
|
||||
.post(`/tasks/${this.selectedAgentPk}/automatedtasks/`, data)
|
||||
.post("tasks/automatedtasks/", data)
|
||||
.then(r => {
|
||||
this.$emit("close");
|
||||
this.$store.dispatch("loadAutomatedTasks", this.selectedAgentPk);
|
||||
this.$store.dispatch("loadChecks", this.selectedAgentPk);
|
||||
|
||||
if (!this.policypk) {
|
||||
this.$store.dispatch("loadAutomatedTasks", this.selectedAgentPk);
|
||||
this.$store.dispatch("loadChecks", this.selectedAgentPk);
|
||||
} else {
|
||||
this.$store.dispatch("automation/loadPolicyAutomatedTasks", this.policypk);
|
||||
this.$store.dispatch("automation/loadPolicyChecks", this.policypk);
|
||||
}
|
||||
this.notifySuccess(r.data);
|
||||
})
|
||||
.catch(e => this.notifyError(e.response.data));
|
||||
@@ -169,7 +181,7 @@ export default {
|
||||
computed: {
|
||||
...mapGetters(["selectedAgentPk", "scripts"]),
|
||||
...mapState({
|
||||
checks: state => state.agentChecks
|
||||
checks: state => this.policypk ? state.automation.checks : state.agentChecks
|
||||
}),
|
||||
allChecks() {
|
||||
return [
|
||||
|
||||
@@ -1,5 +1,37 @@
|
||||
import { Notify } from "quasar";
|
||||
|
||||
export function notifySuccessConfig(msg, timeout = 2000) {
|
||||
return {
|
||||
type: "positive",
|
||||
message: msg,
|
||||
timeout: timeout
|
||||
}
|
||||
};
|
||||
|
||||
export function notifyErrorConfig(msg, timeout = 2000) {
|
||||
return {
|
||||
type: "negative",
|
||||
message: msg,
|
||||
timeout: timeout
|
||||
}
|
||||
};
|
||||
|
||||
export function notifyWarningConfig(msg, timeout = 2000) {
|
||||
return {
|
||||
type: "warning",
|
||||
message: msg,
|
||||
timeout: timeout
|
||||
}
|
||||
};
|
||||
|
||||
export function notifyInfoConfig(msg, timeout = 2000) {
|
||||
return {
|
||||
type: "info",
|
||||
message: msg,
|
||||
timeout: timeout
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
bootTime(unixtime) {
|
||||
@@ -26,32 +58,16 @@ export default {
|
||||
}
|
||||
},
|
||||
notifySuccess(msg, timeout = 2000) {
|
||||
Notify.create({
|
||||
type: "positive",
|
||||
message: msg,
|
||||
timeout: timeout
|
||||
});
|
||||
Notify.create(notifySuccessConfig(msg, timeout));
|
||||
},
|
||||
notifyError(msg, timeout = 2000) {
|
||||
Notify.create({
|
||||
type: "negative",
|
||||
message: msg,
|
||||
timeout: timeout
|
||||
});
|
||||
Notify.create(notifyErrorConfig(msg, timeout));
|
||||
},
|
||||
notifyWarning(msg, timeout = 2000) {
|
||||
Notify.create({
|
||||
type: "warning",
|
||||
message: msg,
|
||||
timeout: timeout
|
||||
});
|
||||
Notify.create(notifyWarningConfig(msg, timeout));
|
||||
},
|
||||
notifyInfo(msg, timeout = 2000) {
|
||||
Notify.create({
|
||||
type: "info",
|
||||
message: msg,
|
||||
timeout: timeout
|
||||
});
|
||||
Notify.create(notifyInfoConfig(msg, timeout));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,6 +10,17 @@ export default {
|
||||
},
|
||||
|
||||
getters: {
|
||||
allChecks(state) {
|
||||
return [
|
||||
...state.checks.diskchecks,
|
||||
...state.checks.cpuloadchecks,
|
||||
...state.checks.memchecks,
|
||||
...state.checks.scriptchecks,
|
||||
...state.checks.winservicechecks,
|
||||
...state.checks.pingchecks,
|
||||
...state.checks.eventlogchecks
|
||||
];
|
||||
},
|
||||
selectedPolicyPk(state) {
|
||||
return state.selectedPolicy;
|
||||
},
|
||||
@@ -63,8 +74,14 @@ export default {
|
||||
context.dispatch("loadPolicies");
|
||||
});
|
||||
},
|
||||
runPolicyTask(context, pk) {
|
||||
return axios.get(`/automation/runwintask/${pk}/`);
|
||||
},
|
||||
getRelated(context, pk) {
|
||||
return axios.get(`/automation/policies/${pk}/related/`);
|
||||
},
|
||||
loadPolicyTreeData(context) {
|
||||
return axios.get("/automation/policies/overview/");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,6 +144,18 @@ export const store = new Vuex.Store({
|
||||
context.commit("setChecks", r.data);
|
||||
});
|
||||
},
|
||||
editCheckAlertAction(context, data) {
|
||||
return axios.patch("/checks/checkalert/", data);
|
||||
},
|
||||
deleteCheck(context, data) {
|
||||
return axios.delete("checks/deletestandardcheck/", { data: data });
|
||||
},
|
||||
editAutoTask(context, data) {
|
||||
return axios.patch(`/tasks/${data.id}/automatedtasks/`, data);
|
||||
},
|
||||
deleteAutoTask(context, pk) {
|
||||
return axios.delete(`/tasks/${pk}/automatedtasks/`);
|
||||
},
|
||||
getUpdatedSites(context) {
|
||||
axios.get("/clients/loadclients/").then(r => {
|
||||
context.commit("getUpdatedSites", r.data);
|
||||
|
||||
@@ -74,10 +74,11 @@ describe("AutomationManager.vue", () => {
|
||||
store,
|
||||
localVue,
|
||||
stubs: [
|
||||
"PolicySubTableTabs",
|
||||
"PolicySubTableTabs",,
|
||||
"PolicyOverview",
|
||||
"PolicyForm",
|
||||
"RelationsView"
|
||||
],
|
||||
]
|
||||
});
|
||||
|
||||
});
|
||||
@@ -97,6 +98,9 @@ describe("AutomationManager.vue", () => {
|
||||
it("calls vuex loadPolicies action on mount", () => {
|
||||
|
||||
expect(actions.loadPolicies).toHaveBeenCalled();
|
||||
expect(mutations.setSelectedPolicy).toHaveBeenCalledWith(expect.anything(), null);
|
||||
expect(mutations.setPolicyChecks).toHaveBeenCalledWith(expect.anything(), {});
|
||||
expect(mutations.setPolicyAutomatedTasks).toHaveBeenCalledWith(expect.anything(), {});
|
||||
|
||||
});
|
||||
|
||||
@@ -146,6 +150,38 @@ describe("AutomationManager.vue", () => {
|
||||
|
||||
});
|
||||
|
||||
it("shows edit policy modal on edit button press", async () => {
|
||||
|
||||
const button = wrapper.findComponent({ ref: "edit" });
|
||||
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
await button.trigger("click")
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
|
||||
//Select Row
|
||||
await wrapper.find("tbody > tr.q-tr").trigger("click");
|
||||
await button.trigger("click");
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it("deletes selected policy on delete button press", async () => {
|
||||
|
||||
const button = wrapper.findComponent({ ref: "delete" });
|
||||
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
// Select Row
|
||||
await wrapper.find("tbody > tr.q-tr").trigger("click");
|
||||
await button.trigger("click");
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(true);
|
||||
|
||||
//Get OK button and click it
|
||||
await bodyWrapper.findAll(".q-btn").wrappers[1].trigger("click");
|
||||
|
||||
expect(actions.deletePolicy).toHaveBeenCalledWith(expect.anything(), 1);
|
||||
|
||||
});
|
||||
|
||||
it("deletes selected policy", async () => {
|
||||
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
@@ -170,6 +206,11 @@ describe("AutomationManager.vue", () => {
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
await button.trigger("click");
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(true);
|
||||
|
||||
expect(mutations.setSelectedPolicy).toHaveBeenCalledWith(expect.anything(), null);
|
||||
expect(mutations.setPolicyChecks).toHaveBeenCalledWith(expect.anything(), {});
|
||||
expect(mutations.setPolicyAutomatedTasks).toHaveBeenCalledWith(expect.anything(), {});
|
||||
|
||||
});
|
||||
|
||||
it("calls vuex loadPolicies action when refresh button clicked and clears selected", () => {
|
||||
@@ -199,4 +240,6 @@ describe("AutomationManager.vue", () => {
|
||||
|
||||
});
|
||||
|
||||
// TODO: Test @close and @hide events
|
||||
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { mount, createLocalVue, createWrapper } from "@vue/test-utils";
|
||||
import { mount, createLocalVue } from "@vue/test-utils";
|
||||
import flushPromises from "flush-promises";
|
||||
import Vuex from "vuex";
|
||||
import PolicyForm from "@/components/automation/modals/PolicyForm";
|
||||
import "@/quasar.js"
|
||||
import "@/quasar.js";
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
@@ -39,22 +39,17 @@ describe("PolicyForm.vue", () => {
|
||||
const policy = {
|
||||
id: 1,
|
||||
name: "Test Policy",
|
||||
desc: "Test Desc",
|
||||
active: true,
|
||||
clients: [],
|
||||
sites: [],
|
||||
agents: []
|
||||
sites: []
|
||||
};
|
||||
|
||||
let methods;
|
||||
let actions, rootActions, store;
|
||||
|
||||
// Runs before every test
|
||||
beforeEach(() => {
|
||||
|
||||
methods = {
|
||||
notifyError: () => jest.fn()
|
||||
};
|
||||
|
||||
rootActions = {
|
||||
loadClients: jest.fn(() => new Promise(res => res({ data: clients }))),
|
||||
loadSites: jest.fn(() => new Promise(res => res({ data: sites }))),
|
||||
@@ -83,7 +78,7 @@ describe("PolicyForm.vue", () => {
|
||||
|
||||
const wrapper = mount(PolicyForm, {
|
||||
localVue,
|
||||
store,
|
||||
store
|
||||
});
|
||||
|
||||
expect(rootActions.loadClients).toHaveBeenCalled();
|
||||
@@ -106,7 +101,7 @@ describe("PolicyForm.vue", () => {
|
||||
|
||||
expect(rootActions.loadClients).toHaveBeenCalled();
|
||||
expect(rootActions.loadSites).toHaveBeenCalled();
|
||||
expect(actions.loadPolicy).toHaveBeenCalled();
|
||||
expect(actions.loadPolicy).toHaveBeenCalledWith(expect.anything(), 1);
|
||||
|
||||
});
|
||||
|
||||
@@ -129,11 +124,10 @@ describe("PolicyForm.vue", () => {
|
||||
|
||||
const wrapper = mount(PolicyForm, {
|
||||
localVue,
|
||||
store,
|
||||
methods: methods
|
||||
store
|
||||
});
|
||||
|
||||
wrapper.setData({name: "Test Name"});
|
||||
wrapper.setData({name: "Test Policy"});
|
||||
const form = wrapper.findComponent({ ref: "form" });
|
||||
form.vm.$emit("submit");
|
||||
await wrapper.vm.$nextTick();
|
||||
@@ -150,17 +144,16 @@ describe("PolicyForm.vue", () => {
|
||||
store,
|
||||
propsData: {
|
||||
pk: 1
|
||||
},
|
||||
methods: methods
|
||||
}
|
||||
});
|
||||
|
||||
wrapper.setData({name: "TestName"})
|
||||
await flushPromises();
|
||||
const form = wrapper.findComponent({ ref: "form" });
|
||||
form.vm.$emit("submit");
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(actions.addPolicy).not.toHaveBeenCalled();
|
||||
expect(actions.editPolicy).toHaveBeenCalled();
|
||||
expect(actions.editPolicy).toHaveBeenCalledWith(expect.anything(), policy);
|
||||
|
||||
});
|
||||
|
||||
@@ -168,8 +161,7 @@ describe("PolicyForm.vue", () => {
|
||||
|
||||
const wrapper = mount(PolicyForm, {
|
||||
localVue,
|
||||
store,
|
||||
methods: methods
|
||||
store
|
||||
});
|
||||
|
||||
const form = wrapper.findComponent({ ref: "form" });
|
||||
|
||||
127
tests/unit/automation/policyoverview.spec.js
Normal file
127
tests/unit/automation/policyoverview.spec.js
Normal file
@@ -0,0 +1,127 @@
|
||||
import { mount, createLocalVue } from "@vue/test-utils";
|
||||
import flushPromises from "flush-promises";
|
||||
import Vuex from "vuex";
|
||||
import PolicyOverview from "@/components/automation/PolicyOverview";
|
||||
import "@/quasar.js";
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
|
||||
describe("PolicyOverview.vue", () => {
|
||||
|
||||
const policyTreeData = {
|
||||
// node 0
|
||||
"Client Name 1": {
|
||||
policies: [
|
||||
{
|
||||
id: 1,
|
||||
name: "Policy Name 1",
|
||||
active: true
|
||||
}
|
||||
],
|
||||
sites: {
|
||||
// node -1
|
||||
"Site Name 1": { policies: []}
|
||||
}
|
||||
},
|
||||
// node -2
|
||||
"Client Name 2": {
|
||||
policies: [
|
||||
{
|
||||
id: 2,
|
||||
name: "Policy Name 2",
|
||||
active: true
|
||||
}
|
||||
],
|
||||
sites: {
|
||||
// node -3
|
||||
"Site Name 2": {
|
||||
policies: [
|
||||
{
|
||||
id: 3,
|
||||
name: "Policy Name 3",
|
||||
active: false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let wrapper, actions, store;
|
||||
|
||||
// Runs before every test
|
||||
beforeEach(() => {
|
||||
|
||||
actions = {
|
||||
loadPolicyTreeData: jest.fn(() => new Promise(res => res({ data: policyTreeData }))),
|
||||
loadPolicyChecks: jest.fn(),
|
||||
loadPolicyAutomatedTasks: jest.fn()
|
||||
};
|
||||
|
||||
store = new Vuex.Store({
|
||||
modules: {
|
||||
automation: {
|
||||
namespaced: true,
|
||||
actions
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
wrapper = mount(PolicyOverview, {
|
||||
localVue,
|
||||
store,
|
||||
stubs: [
|
||||
"PolicyChecksTab",
|
||||
"PolicyAutomatedTasksTab"
|
||||
]
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// The Tests
|
||||
it("calls vuex actions on mount", () => {
|
||||
|
||||
expect(actions.loadPolicyTreeData).toHaveBeenCalled();
|
||||
|
||||
});
|
||||
|
||||
it("renders tree data", () => {
|
||||
|
||||
const tree = wrapper.findComponent({ ref: "tree" });
|
||||
|
||||
const policy1 = tree.vm.getNodeByKey(1);
|
||||
const policy2 = tree.vm.getNodeByKey(2);
|
||||
const client1 = tree.vm.getNodeByKey(0);
|
||||
const client2 = tree.vm.getNodeByKey(-2);
|
||||
const site1 = tree.vm.getNodeByKey(-1);
|
||||
const site2 = tree.vm.getNodeByKey(-3);
|
||||
|
||||
expect(policy1.label).toBe("Policy Name 1");
|
||||
expect(policy2.label).toBe("Policy Name 2");
|
||||
expect(client1.label).toBe("Client Name 1");
|
||||
expect(client2.label).toBe("Client Name 2");
|
||||
expect(site1.label).toBe("Site Name 1");
|
||||
expect(site2.label).toBe("Site Name 2");
|
||||
});
|
||||
|
||||
it("selects tree node and updates data property with policy",() => {
|
||||
|
||||
// Expected rendered policy node data
|
||||
const returnData = {
|
||||
icon: "policy",
|
||||
id: 1,
|
||||
label: "Policy Name 1"
|
||||
};
|
||||
|
||||
// Get second rree node which should be the first policy
|
||||
wrapper.findAll(".q-tree__node-header").wrappers[1].trigger("click");
|
||||
|
||||
expect(wrapper.vm.selectedPolicy).toStrictEqual(returnData);
|
||||
expect(actions.loadPolicyChecks).toHaveBeenCalledWith(expect.anything(), 1);
|
||||
expect(actions.loadPolicyAutomatedTasks).toHaveBeenCalledWith(expect.anything(), 1);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user