mirror of
https://github.com/jpros/tacticalrmm-web.git
synced 2026-01-20 03:50:21 +00:00
rework bulk action modal. start running bulk actions on next agent checkin
This commit is contained in:
@@ -22,3 +22,10 @@ export async function runScript(payload) {
|
||||
return data
|
||||
} catch (e) { }
|
||||
}
|
||||
|
||||
export async function runBulkAction(payload) {
|
||||
|
||||
const { data } = await axios.post("/agents/bulk/", payload)
|
||||
return data
|
||||
|
||||
}
|
||||
@@ -7,4 +7,11 @@ export async function fetchClients() {
|
||||
const { data } = await axios.get(`${baseUrl}/clients/`)
|
||||
return data
|
||||
} catch (e) { }
|
||||
}
|
||||
|
||||
export async function fetchSites() {
|
||||
try {
|
||||
const { data } = await axios.get(`${baseUrl}/sites/`)
|
||||
return data
|
||||
} catch (e) { }
|
||||
}
|
||||
@@ -105,15 +105,15 @@
|
||||
<q-menu auto-close>
|
||||
<q-list dense style="min-width: 100px">
|
||||
<!-- bulk command -->
|
||||
<q-item clickable v-close-popup @click="showBulkActionModal('command')">
|
||||
<q-item clickable v-close-popup @click="showBulkAction('command')">
|
||||
<q-item-section>Bulk Command</q-item-section>
|
||||
</q-item>
|
||||
<!-- bulk script -->
|
||||
<q-item clickable v-close-popup @click="showBulkActionModal('script')">
|
||||
<q-item clickable v-close-popup @click="showBulkAction('script')">
|
||||
<q-item-section>Bulk Script</q-item-section>
|
||||
</q-item>
|
||||
<!-- bulk patch management -->
|
||||
<q-item clickable v-close-popup @click="showBulkActionModal('scan')">
|
||||
<q-item clickable v-close-popup @click="showBulkAction('patch')">
|
||||
<q-item-section>Bulk Patch Management</q-item-section>
|
||||
</q-item>
|
||||
<!-- server maintenance -->
|
||||
@@ -176,10 +176,6 @@
|
||||
<q-dialog v-model="showUploadMesh">
|
||||
<UploadMesh @close="showUploadMesh = false" />
|
||||
</q-dialog>
|
||||
<!-- Bulk action modal -->
|
||||
<q-dialog v-model="showBulkAction" @hide="closeBulkActionModal" position="top">
|
||||
<BulkAction :mode="bulkMode" @close="closeBulkActionModal" />
|
||||
</q-dialog>
|
||||
<!-- Agent Deployment -->
|
||||
<q-dialog v-model="showDeployment">
|
||||
<Deployment @close="showDeployment = false" />
|
||||
@@ -228,7 +224,6 @@ export default {
|
||||
InstallAgent,
|
||||
UploadMesh,
|
||||
AdminManager,
|
||||
BulkAction,
|
||||
Deployment,
|
||||
ServerMaintenance,
|
||||
CodeSign,
|
||||
@@ -242,9 +237,7 @@ export default {
|
||||
showAdminManager: false,
|
||||
showInstallAgent: false,
|
||||
showUploadMesh: false,
|
||||
showBulkAction: false,
|
||||
showPendingActions: false,
|
||||
bulkMode: null,
|
||||
showDeployment: false,
|
||||
showCodeSign: false,
|
||||
};
|
||||
@@ -333,6 +326,14 @@ export default {
|
||||
component: ScriptManager,
|
||||
});
|
||||
},
|
||||
showBulkAction(mode) {
|
||||
this.$q.dialog({
|
||||
component: BulkAction,
|
||||
componentProps: {
|
||||
mode: mode,
|
||||
},
|
||||
});
|
||||
},
|
||||
showDebugLog() {
|
||||
this.$q.dialog({
|
||||
component: DialogWrapper,
|
||||
|
||||
@@ -1,290 +1,293 @@
|
||||
<template>
|
||||
<q-card style="min-width: 50vw">
|
||||
<q-card-section class="row items-center">
|
||||
<div class="text-h6">
|
||||
<q-dialog ref="dialogRef" @hide="onDialogHide">
|
||||
<q-card class="q-dialog-plugin" style="min-width: 50vw">
|
||||
<q-bar>
|
||||
{{ modalTitle }}
|
||||
<div v-if="modalCaption !== null" class="text-caption">{{ modalCaption }}</div>
|
||||
</div>
|
||||
<q-space />
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
<br />
|
||||
</q-card-section>
|
||||
<q-form @submit.prevent="send">
|
||||
<q-card-section>
|
||||
<div class="q-pa-none">
|
||||
<q-space />
|
||||
<q-btn dense flat icon="close" v-close-popup>
|
||||
<q-tooltip class="bg-white text-primary">Close</q-tooltip>
|
||||
</q-btn>
|
||||
</q-bar>
|
||||
<q-form @submit.prevent="submit">
|
||||
<q-card-section>
|
||||
<p>Agent Type</p>
|
||||
<div class="q-gutter-sm">
|
||||
<q-radio dense v-model="monType" val="all" label="All" />
|
||||
<q-radio dense v-model="monType" val="servers" label="Servers" />
|
||||
<q-radio dense v-model="monType" val="workstations" label="Workstations" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<div class="q-pa-none">
|
||||
<q-option-group v-model="monType" :options="monTypeOptions" color="primary" dense inline class="q-pl-sm" />
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<p>Choose Target</p>
|
||||
<div class="q-gutter-sm">
|
||||
<q-radio dense v-model="target" val="client" label="Client" @update:model-value="agentMultiple = []" />
|
||||
<q-radio
|
||||
dense
|
||||
v-model="target"
|
||||
val="site"
|
||||
label="Site"
|
||||
@update:model-value="
|
||||
() => {
|
||||
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" @update:model-value="agentMultiple = []" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-option-group v-model="target" :options="targetOptions" color="primary" dense inline class="q-pl-sm" />
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="target === 'client' || target === 'site'" class="q-pb-none">
|
||||
<q-select
|
||||
dense
|
||||
:rules="[val => !!val || '*Required']"
|
||||
outlined
|
||||
options-dense
|
||||
label="Select client"
|
||||
v-model="client"
|
||||
:options="client_options"
|
||||
@update:model-value="target === 'site' ? (site = sites[0]) : () => {}"
|
||||
/>
|
||||
<q-select
|
||||
v-if="target === 'site'"
|
||||
dense
|
||||
:rules="[val => !!val || '*Required']"
|
||||
outlined
|
||||
options-dense
|
||||
label="Select site"
|
||||
v-model="site"
|
||||
:options="sites"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="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>
|
||||
<tactical-dropdown
|
||||
v-if="target === 'client'"
|
||||
:rules="[val => !!val || '*Required']"
|
||||
v-model="client"
|
||||
:options="clientOptions"
|
||||
label="Select Client"
|
||||
outlined
|
||||
mapOptions
|
||||
filterable
|
||||
/>
|
||||
<tactical-dropdown
|
||||
v-else-if="target === 'site'"
|
||||
:rules="[val => !!val || '*Required']"
|
||||
v-model="site"
|
||||
:options="siteOptions"
|
||||
label="Select Site"
|
||||
outlined
|
||||
mapOptions
|
||||
filterable
|
||||
/>
|
||||
<tactical-dropdown
|
||||
v-else-if="target === 'agents'"
|
||||
v-model="agents"
|
||||
:options="agentOptions"
|
||||
label="Select Agents"
|
||||
filled
|
||||
multiple
|
||||
mapOptions
|
||||
filterable
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="mode === 'script'" class="q-pt-none">
|
||||
<q-select
|
||||
:rules="[val => !!val || '*Required']"
|
||||
dense
|
||||
outlined
|
||||
v-model="scriptPK"
|
||||
:options="scriptOptions"
|
||||
label="Select script"
|
||||
map-options
|
||||
emit-value
|
||||
options-dense
|
||||
@update:model-value="setScriptDefaults"
|
||||
>
|
||||
<template v-slot:option="scope">
|
||||
<q-item v-if="!scope.opt.category" v-bind="scope.itemProps" class="q-pl-lg">
|
||||
<q-item-section>
|
||||
<q-item-label v-html="scope.opt.label"></q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item-label v-if="scope.opt.category" v-bind="scope.itemProps" header class="q-pa-sm">{{
|
||||
scope.opt.category
|
||||
}}</q-item-label>
|
||||
</template>
|
||||
</q-select>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="mode === 'script'" class="q-pt-none">
|
||||
<q-select
|
||||
label="Script Arguments (press Enter after typing each argument)"
|
||||
filled
|
||||
dense
|
||||
v-model="args"
|
||||
use-input
|
||||
use-chips
|
||||
multiple
|
||||
hide-dropdown-icon
|
||||
input-debounce="0"
|
||||
new-value-mode="add"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="mode === 'script'" class="q-pt-none">
|
||||
<tactical-dropdown
|
||||
:rules="[val => !!val || '*Required']"
|
||||
v-model="script"
|
||||
:options="scriptOptions"
|
||||
label="Select Script"
|
||||
outlined
|
||||
mapOptions
|
||||
filterable
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="mode === 'script'" class="q-pt-none">
|
||||
<q-select
|
||||
label="Script Arguments (press Enter after typing each argument)"
|
||||
filled
|
||||
dense
|
||||
v-model="args"
|
||||
use-input
|
||||
use-chips
|
||||
multiple
|
||||
hide-dropdown-icon
|
||||
input-debounce="0"
|
||||
new-value-mode="add"
|
||||
/>
|
||||
</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 === 'command'">
|
||||
<p>Shell</p>
|
||||
<q-option-group v-model="shell" :options="shellOptions" color="primary" dense inline class="q-pl-sm" />
|
||||
</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
|
||||
outlined
|
||||
type="number"
|
||||
style="max-width: 150px"
|
||||
label="Timeout (seconds)"
|
||||
stack-label
|
||||
:rules="[val => !!val || '*Required', val => val >= 5 || 'Minimum is 5 seconds']"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="mode === 'script' || mode === 'command'">
|
||||
<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 >= 5 || 'Minimum is 5 seconds']"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="mode === 'scan'">
|
||||
<div class="q-pa-none">
|
||||
<q-card-section v-if="mode === 'patch'">
|
||||
<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-option-group
|
||||
v-model="patchMode"
|
||||
:options="patchModeOptions"
|
||||
color="primary"
|
||||
dense
|
||||
inline
|
||||
class="q-pl-sm"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="center">
|
||||
<q-btn label="Run" color="primary" class="full-width" type="submit" />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
<q-card-section v-show="false">
|
||||
<q-checkbox v-model="offlineAgents" label="Offline Agents (Run on next checkin)">
|
||||
<q-tooltip>If the agent is offline, a pending action will be created to run on agent checkin</q-tooltip>
|
||||
</q-checkbox>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="Cancel" v-close-popup />
|
||||
<q-btn label="Run" color="primary" type="submit" :disable="loading" :loading="loading" />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
import mixins from "@/mixins/mixins";
|
||||
// composition imports
|
||||
import { ref, computed, watch, onMounted } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import { useDialogPluginComponent } from "quasar";
|
||||
import { useScriptDropdown } from "@/composables/scripts";
|
||||
import { useAgentDropdown } from "@/composables/agents";
|
||||
import { useClientDropdown, useSiteDropdown } from "@/composables/clients";
|
||||
import { runBulkAction } from "@/api/agents";
|
||||
import { notifySuccess } from "@/utils/notify";
|
||||
|
||||
// ui imports
|
||||
import TacticalDropdown from "@/components/ui/TacticalDropdown";
|
||||
|
||||
// static data
|
||||
const monTypeOptions = [
|
||||
{ label: "All", value: "all" },
|
||||
{ label: "Servers", value: "servers" },
|
||||
{ label: "Workstations", value: "workstations" },
|
||||
];
|
||||
|
||||
const targetOptions = [
|
||||
{ label: "Client", value: "client" },
|
||||
{ label: "Site", value: "site" },
|
||||
{ label: "Selected Agents", value: "agents" },
|
||||
{ label: "All", value: "all" },
|
||||
];
|
||||
|
||||
const shellOptions = [
|
||||
{ label: "CMD", value: "cmd" },
|
||||
{ label: "Powershell", value: "powershell" },
|
||||
];
|
||||
|
||||
const patchModeOptions = [
|
||||
{ label: "Scan", value: "scan" },
|
||||
{ label: "Install", value: "install" },
|
||||
];
|
||||
|
||||
export default {
|
||||
name: "BulkAction",
|
||||
emits: ["close"],
|
||||
mixins: [mixins],
|
||||
components: { TacticalDropdown },
|
||||
emits: [...useDialogPluginComponent.emits],
|
||||
props: {
|
||||
mode: !String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
target: "client",
|
||||
monType: "all",
|
||||
selected_mode: null,
|
||||
scriptOptions: [],
|
||||
scriptPK: null,
|
||||
timeout: 900,
|
||||
client: null,
|
||||
client_options: [],
|
||||
site: null,
|
||||
agents: [],
|
||||
agentMultiple: [],
|
||||
args: [],
|
||||
cmd: "",
|
||||
shell: "cmd",
|
||||
modalTitle: null,
|
||||
modalCaption: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["showCommunityScripts"]),
|
||||
sites() {
|
||||
return !!this.client ? this.formatSiteOptions(this.client.sites) : [];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setScriptDefaults() {
|
||||
const script = this.scriptOptions.find(i => i.value === this.scriptPK);
|
||||
setup(props) {
|
||||
// setup vuex store
|
||||
const store = useStore();
|
||||
const showCommunityScripts = computed(() => store.state.showCommunityScripts);
|
||||
|
||||
this.timeout = script.timeout;
|
||||
this.args = script.args;
|
||||
},
|
||||
send() {
|
||||
this.$q.loading.show();
|
||||
const data = {
|
||||
mode: this.selected_mode,
|
||||
monType: this.monType,
|
||||
target: this.target,
|
||||
site: this.site.value,
|
||||
client: this.client.value,
|
||||
agentPKs: this.agentMultiple,
|
||||
scriptPK: this.scriptPK,
|
||||
timeout: this.timeout,
|
||||
args: this.args,
|
||||
shell: this.shell,
|
||||
timeout: this.timeout,
|
||||
cmd: this.cmd,
|
||||
// quasar dialog setup
|
||||
const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
||||
|
||||
// dropdown setup
|
||||
const { script, scriptOptions, defaultTimeout, defaultArgs, getScriptOptions } = useScriptDropdown();
|
||||
const { agents, agentOptions, getAgentOptions } = useAgentDropdown();
|
||||
const { site, siteOptions, getSiteOptions } = useSiteDropdown();
|
||||
const { client, clientOptions, getClientOptions } = useClientDropdown();
|
||||
|
||||
// bulk action logic
|
||||
const target = ref("client");
|
||||
const monType = ref("all");
|
||||
const cmd = ref("");
|
||||
const shell = ref("cmd");
|
||||
const patchMode = ref("scan");
|
||||
const offlineAgents = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
watch(target, () => (agents.value = []));
|
||||
|
||||
async function submit() {
|
||||
loading.value = true;
|
||||
|
||||
const payload = {
|
||||
mode: props.mode,
|
||||
monType: monType.value,
|
||||
target: target.value,
|
||||
site: site.value,
|
||||
client: client.value,
|
||||
agents: agents.value,
|
||||
script: script.value,
|
||||
timeout: defaultTimeout.value,
|
||||
args: defaultArgs.value,
|
||||
shell: shell.value,
|
||||
cmd: cmd.value,
|
||||
patchMode: patchMode.value,
|
||||
offlineAgents: offlineAgents.value,
|
||||
};
|
||||
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();
|
||||
});
|
||||
},
|
||||
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];
|
||||
})
|
||||
.catch(e => {});
|
||||
},
|
||||
getAgents() {
|
||||
this.$axios
|
||||
.get("/agents/listagentsnodetail/")
|
||||
.then(r => {
|
||||
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)));
|
||||
})
|
||||
.catch(e => {});
|
||||
},
|
||||
setTitles() {
|
||||
switch (this.mode) {
|
||||
case "command":
|
||||
this.modalTitle = "Run Bulk Command";
|
||||
this.modalCaption = "Run a shell command on multiple agents in parallel";
|
||||
break;
|
||||
case "script":
|
||||
this.modalTitle = "Run Bulk Script";
|
||||
this.modalCaption = "Run a script on multiple agents in parallel";
|
||||
break;
|
||||
case "scan":
|
||||
this.modalTitle = "Bulk Patch Management";
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setTitles();
|
||||
this.getClients();
|
||||
this.getAgents();
|
||||
this.getScriptOptions(this.showCommunityScripts).then(options => (this.scriptOptions = Object.freeze(options)));
|
||||
try {
|
||||
const data = await runBulkAction(payload);
|
||||
notifySuccess(data);
|
||||
} catch (e) {}
|
||||
|
||||
this.selected_mode = this.mode;
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
// set modal title and caption
|
||||
const modalTitle = computed(() => {
|
||||
return props.mode === "command"
|
||||
? "Run Bulk Command"
|
||||
: props.mode === "script"
|
||||
? "Run Bulk Script"
|
||||
: props.mode === "scan"
|
||||
? "Bulk Patch Management"
|
||||
: "";
|
||||
});
|
||||
|
||||
// component lifecycle hooks
|
||||
onMounted(() => {
|
||||
getAgentOptions();
|
||||
getSiteOptions();
|
||||
getClientOptions();
|
||||
if (props.mode === "script") getScriptOptions(showCommunityScripts);
|
||||
});
|
||||
|
||||
return {
|
||||
// reactive data
|
||||
target,
|
||||
monType,
|
||||
client,
|
||||
site,
|
||||
agents,
|
||||
cmd,
|
||||
shell,
|
||||
patchMode,
|
||||
script,
|
||||
scriptOptions,
|
||||
timeout: defaultTimeout.value,
|
||||
args: defaultArgs.value,
|
||||
agentOptions,
|
||||
clientOptions,
|
||||
siteOptions,
|
||||
offlineAgents,
|
||||
loading,
|
||||
|
||||
// non-reactive data
|
||||
monTypeOptions,
|
||||
targetOptions,
|
||||
shellOptions,
|
||||
patchModeOptions,
|
||||
|
||||
//computed
|
||||
modalTitle,
|
||||
|
||||
//methods
|
||||
submit,
|
||||
|
||||
// quasar dialog plugin
|
||||
dialogRef,
|
||||
onDialogHide,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -5,7 +5,8 @@ import { formatAgentOptions } from "@/utils/format"
|
||||
|
||||
// agent dropdown
|
||||
export function useAgentDropdown() {
|
||||
|
||||
const agent = ref(null)
|
||||
const agents = ref([])
|
||||
const agentOptions = ref([])
|
||||
|
||||
// specifing flat returns an array of hostnames versus {value:id, label: hostname}
|
||||
@@ -15,6 +16,8 @@ export function useAgentDropdown() {
|
||||
|
||||
return {
|
||||
//data
|
||||
agent,
|
||||
agents,
|
||||
agentOptions,
|
||||
|
||||
//methods
|
||||
|
||||
@@ -4,7 +4,8 @@ import { fetchClients } from "@/api/clients"
|
||||
import { formatClientOptions, formatSiteOptions } from "@/utils/format"
|
||||
|
||||
export function useClientDropdown() {
|
||||
|
||||
const client = ref(null)
|
||||
const clients = ref([])
|
||||
const clientOptions = ref([])
|
||||
|
||||
async function getClientOptions(flat = false) {
|
||||
@@ -13,6 +14,8 @@ export function useClientDropdown() {
|
||||
|
||||
return {
|
||||
//data
|
||||
client,
|
||||
clients,
|
||||
clientOptions,
|
||||
|
||||
//methods
|
||||
@@ -21,14 +24,18 @@ export function useClientDropdown() {
|
||||
}
|
||||
|
||||
export function useSiteDropdown() {
|
||||
const site = ref(null)
|
||||
const sites = ref([])
|
||||
const siteOptions = ref([])
|
||||
|
||||
async function getSiteOptions() {
|
||||
siteOptions.value = formatSiteOptions(await fetchSites())
|
||||
siteOptions.value = formatSiteOptions(await fetchClients())
|
||||
}
|
||||
|
||||
return {
|
||||
//data
|
||||
site,
|
||||
sites,
|
||||
siteOptions,
|
||||
|
||||
//methods
|
||||
|
||||
@@ -7,7 +7,7 @@ export function useScriptDropdown() {
|
||||
const scriptOptions = ref([])
|
||||
const defaultTimeout = ref(30)
|
||||
const defaultArgs = ref([])
|
||||
const scriptPK = ref(null)
|
||||
const script = ref(null)
|
||||
|
||||
// specifing flat returns an array of script names versus {value:id, label: hostname}
|
||||
async function getScriptOptions(showCommunityScripts = false, flat = false) {
|
||||
@@ -15,17 +15,17 @@ export function useScriptDropdown() {
|
||||
}
|
||||
|
||||
// watch scriptPk for changes and update the default timeout and args
|
||||
watch(scriptPK, (newValue, oldValue) => {
|
||||
watch(script, (newValue, oldValue) => {
|
||||
if (newValue) {
|
||||
const script = scriptOptions.value.find(i => i.value === newValue);
|
||||
defaultTimeout.value = script.timeout;
|
||||
defaultArgs.value = script.args;
|
||||
const tmpScript = scriptOptions.value.find(i => i.value === newValue);
|
||||
defaultTimeout.value = tmpScript.timeout;
|
||||
defaultArgs.value = tmpScript.args;
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
//data
|
||||
scriptPK,
|
||||
script,
|
||||
scriptOptions,
|
||||
defaultTimeout,
|
||||
defaultArgs,
|
||||
|
||||
Reference in New Issue
Block a user