Compare commits
13 Commits
v0.101.19-
...
v0.101.11
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab19afca16 | ||
|
|
f24c6a7a80 | ||
|
|
99490bf859 | ||
|
|
72cdeeaa6a | ||
|
|
1eca4d605b | ||
|
|
52ee98f6f8 | ||
|
|
d270b877c9 | ||
|
|
fd8b2a1d98 | ||
|
|
f518043d8d | ||
|
|
cc2335558d | ||
|
|
a8a171ba2c | ||
|
|
24a63f477e | ||
|
|
ddeb6293a1 |
2
.vscode/extensions.json
vendored
2
.vscode/extensions.json
vendored
@@ -5,7 +5,7 @@
|
|||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"editorconfig.editorconfig",
|
"editorconfig.editorconfig",
|
||||||
"vue.volar",
|
"vue.volar",
|
||||||
"wayou.vscode-todo-highlight"
|
"wayou.vscode-todo-highlight",
|
||||||
],
|
],
|
||||||
"unwantedRecommendations": [
|
"unwantedRecommendations": [
|
||||||
"octref.vetur",
|
"octref.vetur",
|
||||||
|
|||||||
15
.vscode/settings.json
vendored
15
.vscode/settings.json
vendored
@@ -4,9 +4,16 @@
|
|||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"[vue][javascript][typescript][javascriptreact]": {
|
"[vue][javascript][typescript][javascriptreact]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
"editor.codeActionsOnSave": ["source.fixAll.eslint"]
|
"editor.codeActionsOnSave": [
|
||||||
|
"source.fixAll.eslint"
|
||||||
|
],
|
||||||
},
|
},
|
||||||
"eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"],
|
"eslint.validate": [
|
||||||
|
"javascript",
|
||||||
|
"javascriptreact",
|
||||||
|
"typescript",
|
||||||
|
"vue"
|
||||||
|
],
|
||||||
"typescript.tsdk": "node_modules/typescript/lib",
|
"typescript.tsdk": "node_modules/typescript/lib",
|
||||||
"files.watcherExclude": {
|
"files.watcherExclude": {
|
||||||
"files.watcherExclude": {
|
"files.watcherExclude": {
|
||||||
@@ -15,7 +22,7 @@
|
|||||||
"**/node_modules/": true,
|
"**/node_modules/": true,
|
||||||
"/node_modules/**": true,
|
"/node_modules/**": true,
|
||||||
"**/env/": true,
|
"**/env/": true,
|
||||||
"/env/**": true
|
"/env/**": true,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
20
index.html
20
index.html
@@ -1,22 +1,24 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
|
||||||
<title><%= productName %></title>
|
<head>
|
||||||
|
<title>
|
||||||
|
<%= productName %>
|
||||||
|
</title>
|
||||||
|
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="robots" content="noindex" />
|
<meta name="robots" content="noindex" />
|
||||||
<meta name="description" content="<%= productDescription %>" />
|
<meta name="description" content="<%= productDescription %>" />
|
||||||
<meta name="format-detection" content="telephone=no" />
|
<meta name="format-detection" content="telephone=no" />
|
||||||
<meta name="msapplication-tap-highlight" content="no" />
|
<meta name="msapplication-tap-highlight" content="no" />
|
||||||
<meta
|
<meta name="viewport"
|
||||||
name="viewport"
|
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>" />
|
||||||
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>"
|
|
||||||
/>
|
|
||||||
<link rel="icon" type="image/ico" href="favicon.ico" />
|
<link rel="icon" type="image/ico" href="favicon.ico" />
|
||||||
<script src="/env-config.js"></script>
|
<script src="/env-config.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<!-- quasar:entry-point -->
|
<!-- quasar:entry-point -->
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
6892
package-lock.json
generated
6892
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
36
package.json
36
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "web",
|
"name": "web",
|
||||||
"version": "0.101.19-dev",
|
"version": "0.101.11",
|
||||||
"private": true,
|
"private": true,
|
||||||
"productName": "Tactical RMM",
|
"productName": "Tactical RMM",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -10,13 +10,13 @@
|
|||||||
"format": "prettier --write \"**/*.{js,ts,vue,,html,md,json}\" --ignore-path .gitignore"
|
"format": "prettier --write \"**/*.{js,ts,vue,,html,md,json}\" --ignore-path .gitignore"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@quasar/extras": "1.16.3",
|
"@quasar/extras": "1.15.8",
|
||||||
"apexcharts": "3.40.0",
|
"apexcharts": "3.36.3",
|
||||||
"axios": "1.4.0",
|
"axios": "0.27.2",
|
||||||
"dotenv": "16.0.3",
|
"dotenv": "16.0.3",
|
||||||
"qrcode.vue": "3.3.4",
|
"qrcode.vue": "3.3.3",
|
||||||
"quasar": "2.12.0",
|
"quasar": "2.11.1",
|
||||||
"vue": "3.2.47",
|
"vue": "3.2.45",
|
||||||
"vue3-ace-editor": "2.2.2",
|
"vue3-ace-editor": "2.2.2",
|
||||||
"vue3-apexcharts": "1.4.1",
|
"vue3-apexcharts": "1.4.1",
|
||||||
"vuedraggable": "4.1.0",
|
"vuedraggable": "4.1.0",
|
||||||
@@ -24,17 +24,17 @@
|
|||||||
"vuex": "4.1.0"
|
"vuex": "4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@quasar/cli": "^2.1.0",
|
"@quasar/cli": "^1.3.2",
|
||||||
"@intlify/unplugin-vue-i18n": "^0.10.0",
|
"@intlify/vite-plugin-vue-i18n": "^6.0.3",
|
||||||
"@quasar/app-vite": "^1.3.0",
|
"@quasar/app-vite": "^1.1.3",
|
||||||
"@types/node": "^18.16.5",
|
"@types/node": "^18.11.17",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
"@typescript-eslint/eslint-plugin": "^5.47.0",
|
||||||
"@typescript-eslint/parser": "^5.59.2",
|
"@typescript-eslint/parser": "^5.47.0",
|
||||||
"autoprefixer": "10.4.14",
|
"autoprefixer": "10.4.13",
|
||||||
"eslint": "8.40.0",
|
"eslint": "8.30.0",
|
||||||
"eslint-config-prettier": "8.8.0",
|
"eslint-config-prettier": "8.5.0",
|
||||||
"eslint-plugin-vue": "8.7.1",
|
"eslint-plugin-vue": "8.7.1",
|
||||||
"prettier": "2.8.8",
|
"prettier": "2.8.1",
|
||||||
"typescript": "5.0.4"
|
"typescript": "4.9.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,18 +4,18 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: [
|
plugins: [
|
||||||
// https://github.com/postcss/autoprefixer
|
// https://github.com/postcss/autoprefixer
|
||||||
require("autoprefixer")({
|
require('autoprefixer')({
|
||||||
overrideBrowserslist: [
|
overrideBrowserslist: [
|
||||||
"last 4 Chrome versions",
|
'last 4 Chrome versions',
|
||||||
"last 4 Firefox versions",
|
'last 4 Firefox versions',
|
||||||
"last 4 Edge versions",
|
'last 4 Edge versions',
|
||||||
"last 4 Safari versions",
|
'last 4 Safari versions',
|
||||||
"last 4 Android versions",
|
'last 4 Android versions',
|
||||||
"last 4 ChromeAndroid versions",
|
'last 4 ChromeAndroid versions',
|
||||||
"last 4 FirefoxAndroid versions",
|
'last 4 FirefoxAndroid versions',
|
||||||
"last 4 iOS versions",
|
'last 4 iOS versions'
|
||||||
],
|
]
|
||||||
}),
|
})
|
||||||
|
|
||||||
// https://github.com/elchininet/postcss-rtlcss
|
// https://github.com/elchininet/postcss-rtlcss
|
||||||
// If you want to support RTL css, then
|
// If you want to support RTL css, then
|
||||||
@@ -23,5 +23,5 @@ module.exports = {
|
|||||||
// 2. optionally set quasar.config.js > framework > lang to an RTL language
|
// 2. optionally set quasar.config.js > framework > lang to an RTL language
|
||||||
// 3. uncomment the following line:
|
// 3. uncomment the following line:
|
||||||
// require('postcss-rtlcss')
|
// require('postcss-rtlcss')
|
||||||
],
|
]
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -38,8 +38,3 @@ export async function runURLAction(payload) {
|
|||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateScript(payload) {
|
|
||||||
const { data } = await axios.post(`${baseUrl}/openai/generate/`, payload);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -373,12 +373,17 @@ export default {
|
|||||||
"local_ips",
|
"local_ips",
|
||||||
"make_model",
|
"make_model",
|
||||||
"physical_disks",
|
"physical_disks",
|
||||||
"custom_fields"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// quasar filter only does visible columns so this is a hack to add hidden columns we want to filter
|
// quasar filter only does visible columns so this is a hack to add hidden columns we want to filter
|
||||||
// originally I was modifying cols directly but this led to phantom colum so doing it this way now
|
for (const elem of hiddenFields) {
|
||||||
// https://github.com/amidaware/tacticalrmm/issues/1264
|
if (!cols.find((o) => o.name === elem)) {
|
||||||
const allColumns = [...cols, ...hiddenFields.map((field) => ({ field }))];
|
cols.push({
|
||||||
|
name: elem,
|
||||||
|
field: elem,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const lowerTerms = terms ? terms.toLowerCase() : "";
|
const lowerTerms = terms ? terms.toLowerCase() : "";
|
||||||
let advancedFilter = false;
|
let advancedFilter = false;
|
||||||
@@ -432,12 +437,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Normal text filter
|
// Normal text filter
|
||||||
return allColumns.some((col) => {
|
return cols.some((col) => {
|
||||||
let valObj = cellValue(col, row);
|
const val = cellValue(col, row) + "";
|
||||||
if (Array.isArray(valObj)) {
|
|
||||||
valObj = valObj.map((item) => item.value ? item.value : item);
|
|
||||||
}
|
|
||||||
const val = valObj + "";
|
|
||||||
const haystack =
|
const haystack =
|
||||||
val === "undefined" || val === "null" ? "" : val.toLowerCase();
|
val === "undefined" || val === "null" ? "" : val.toLowerCase();
|
||||||
return haystack.indexOf(search) !== -1;
|
return haystack.indexOf(search) !== -1;
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ export default {
|
|||||||
type: "textarea",
|
type: "textarea",
|
||||||
isValid: (val) => !!val,
|
isValid: (val) => !!val,
|
||||||
},
|
},
|
||||||
style: "width: 90vw; max-width: 90vw",
|
style: "width: 30vw; max-width: 50vw;",
|
||||||
ok: { label: "Add" },
|
ok: { label: "Add" },
|
||||||
cancel: true,
|
cancel: true,
|
||||||
}).onOk(async () => {
|
}).onOk(async () => {
|
||||||
@@ -193,7 +193,7 @@ export default {
|
|||||||
type: "textarea",
|
type: "textarea",
|
||||||
isValid: (val) => !!val,
|
isValid: (val) => !!val,
|
||||||
},
|
},
|
||||||
style: "width: 90vw; max-width: 90vw",
|
style: "width: 30vw; max-width: 50vw;",
|
||||||
ok: { label: "Save" },
|
ok: { label: "Save" },
|
||||||
cancel: true,
|
cancel: true,
|
||||||
}).onOk(async (data) => {
|
}).onOk(async (data) => {
|
||||||
|
|||||||
@@ -158,20 +158,6 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>No checks</div>
|
<div v-else>No checks</div>
|
||||||
|
|
||||||
<span
|
|
||||||
v-if="customFields.length > 0"
|
|
||||||
class="text-subtitle2 text-bold block q-mt-xl"
|
|
||||||
>Custom Fields</span
|
|
||||||
>
|
|
||||||
<q-list dense>
|
|
||||||
<q-item v-for="(field, i) in customFields" :key="field + i">
|
|
||||||
<q-item-section thumbnail>
|
|
||||||
<q-icon name="fas fa-user" size="xs" />
|
|
||||||
</q-item-section>
|
|
||||||
<q-item-section>{{ field.name }}: {{ field.value }}</q-item-section>
|
|
||||||
</q-item>
|
|
||||||
</q-list>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-1"></div>
|
<div class="col-1"></div>
|
||||||
<!-- right -->
|
<!-- right -->
|
||||||
@@ -207,7 +193,6 @@ import {
|
|||||||
openAgentWindow,
|
openAgentWindow,
|
||||||
} from "@/api/agents";
|
} from "@/api/agents";
|
||||||
import { notifySuccess } from "@/utils/notify";
|
import { notifySuccess } from "@/utils/notify";
|
||||||
import { fetchCustomFields } from "@/api/core";
|
|
||||||
|
|
||||||
// ui imports
|
// ui imports
|
||||||
import AgentActionMenu from "@/components/agents/AgentActionMenu.vue";
|
import AgentActionMenu from "@/components/agents/AgentActionMenu.vue";
|
||||||
@@ -225,7 +210,6 @@ export default {
|
|||||||
|
|
||||||
// summary tab logic
|
// summary tab logic
|
||||||
const summary = ref(null);
|
const summary = ref(null);
|
||||||
const customFieldsDefinitions = ref(null);
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
function diskBarColor(percent) {
|
function diskBarColor(percent) {
|
||||||
@@ -252,37 +236,9 @@ export default {
|
|||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
|
|
||||||
const customFields = computed(() => {
|
|
||||||
if (!summary.value.custom_fields) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
if (!customFieldsDefinitions.value) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
const ret = [];
|
|
||||||
for (const customField of summary.value.custom_fields) {
|
|
||||||
const definition = customFieldsDefinitions.value.find(
|
|
||||||
(def) => def.id === customField.field
|
|
||||||
);
|
|
||||||
if (
|
|
||||||
definition &&
|
|
||||||
!definition.hide_in_ui &&
|
|
||||||
customField.value?.length > 0
|
|
||||||
) {
|
|
||||||
ret.push({
|
|
||||||
name: definition.name,
|
|
||||||
value: customField.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
});
|
|
||||||
|
|
||||||
async function getSummary() {
|
async function getSummary() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
summary.value = await fetchAgent(selectedAgent.value);
|
summary.value = await fetchAgent(selectedAgent.value);
|
||||||
customFieldsDefinitions.value = await fetchCustomFields();
|
|
||||||
store.commit("setRefreshSummaryTab", false);
|
store.commit("setRefreshSummaryTab", false);
|
||||||
store.commit("setAgentPlatform", summary.value.plat);
|
store.commit("setAgentPlatform", summary.value.plat);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@@ -321,7 +277,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// reactive data
|
// reactive data
|
||||||
summary,
|
summary,
|
||||||
customFields,
|
|
||||||
loading,
|
loading,
|
||||||
selectedAgent,
|
selectedAgent,
|
||||||
disks,
|
disks,
|
||||||
|
|||||||
@@ -42,9 +42,10 @@ export default {
|
|||||||
const tabHeight = computed(() => store.state.tabHeight);
|
const tabHeight = computed(() => store.state.tabHeight);
|
||||||
|
|
||||||
function copyValueToClip(val) {
|
function copyValueToClip(val) {
|
||||||
copyToClipboard(val).then(() => {
|
copyToClipboard(val)
|
||||||
|
.then(() => {
|
||||||
notifySuccess("Copied to clipboard");
|
notifySuccess("Copied to clipboard");
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ import { useDialogPluginComponent } from "quasar";
|
|||||||
import { useCheckModal } from "@/composables/checks";
|
import { useCheckModal } from "@/composables/checks";
|
||||||
import { useScriptDropdown } from "@/composables/scripts";
|
import { useScriptDropdown } from "@/composables/scripts";
|
||||||
import { validateRetcode } from "@/utils/validation";
|
import { validateRetcode } from "@/utils/validation";
|
||||||
import { envVarsLabel } from "@/constants/constants";
|
import { envVarsLabel } from "@/constants/constants"
|
||||||
|
|
||||||
// ui imports
|
// ui imports
|
||||||
import TacticalDropdown from "@/components/ui/TacticalDropdown.vue";
|
import TacticalDropdown from "@/components/ui/TacticalDropdown.vue";
|
||||||
@@ -146,13 +146,8 @@ export default {
|
|||||||
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
||||||
|
|
||||||
// setup script dropdown
|
// setup script dropdown
|
||||||
const {
|
const { script, scriptOptions, defaultTimeout, defaultArgs, defaultEnvVars } =
|
||||||
script,
|
useScriptDropdown(props.check ? props.check.script : undefined, {
|
||||||
scriptOptions,
|
|
||||||
defaultTimeout,
|
|
||||||
defaultArgs,
|
|
||||||
defaultEnvVars,
|
|
||||||
} = useScriptDropdown(props.check ? props.check.script : undefined, {
|
|
||||||
onMount: true,
|
onMount: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -89,8 +89,7 @@
|
|||||||
<p class="text-italic">
|
<p class="text-italic">
|
||||||
Note: the auth token above will be valid for {{ info.expires }} hours.
|
Note: the auth token above will be valid for {{ info.expires }} hours.
|
||||||
</p>
|
</p>
|
||||||
<q-btn
|
<q-btn v-if="info.plat === 'windows'"
|
||||||
v-if="info.plat === 'windows'"
|
|
||||||
type="a"
|
type="a"
|
||||||
:href="info.data.url"
|
:href="info.data.url"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|||||||
@@ -221,15 +221,8 @@ export default {
|
|||||||
const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
||||||
|
|
||||||
// setup dropdowns
|
// setup dropdowns
|
||||||
const {
|
const { script, scriptOptions, defaultTimeout, defaultArgs, defaultEnvVars, syntax, link } =
|
||||||
script,
|
useScriptDropdown(props.script, {
|
||||||
scriptOptions,
|
|
||||||
defaultTimeout,
|
|
||||||
defaultArgs,
|
|
||||||
defaultEnvVars,
|
|
||||||
syntax,
|
|
||||||
link,
|
|
||||||
} = useScriptDropdown(props.script, {
|
|
||||||
onMount: true,
|
onMount: true,
|
||||||
filterByPlatform: props.agent.plat,
|
filterByPlatform: props.agent.plat,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
<q-tab name="urlactions" label="URL Actions" />
|
<q-tab name="urlactions" label="URL Actions" />
|
||||||
<q-tab name="retention" label="Retention" />
|
<q-tab name="retention" label="Retention" />
|
||||||
<q-tab name="apikeys" label="API Keys" />
|
<q-tab name="apikeys" label="API Keys" />
|
||||||
<q-tab name="openai" label="Open AI" />
|
|
||||||
</q-tabs>
|
</q-tabs>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:after>
|
<template v-slot:after>
|
||||||
@@ -509,49 +508,6 @@
|
|||||||
<q-tab-panel name="apikeys">
|
<q-tab-panel name="apikeys">
|
||||||
<APIKeysTable />
|
<APIKeysTable />
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
|
|
||||||
<!-- Open AI -->
|
|
||||||
<q-tab-panel name="openai">
|
|
||||||
<div class="text-subtitle2">Open AI</div>
|
|
||||||
<q-separator />
|
|
||||||
<q-card-section class="row">
|
|
||||||
<div class="col-4">API Key:</div>
|
|
||||||
<div class="col-2"></div>
|
|
||||||
<q-input
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
v-model="settings.open_ai_token"
|
|
||||||
class="col-6"
|
|
||||||
/>
|
|
||||||
</q-card-section>
|
|
||||||
<q-card-section class="row">
|
|
||||||
<div class="col-4">Open AI Model:</div>
|
|
||||||
<div class="col-2"></div>
|
|
||||||
<q-input
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
v-model="settings.open_ai_model"
|
|
||||||
class="col-6"
|
|
||||||
>
|
|
||||||
<template v-slot:after>
|
|
||||||
<q-btn
|
|
||||||
round
|
|
||||||
dense
|
|
||||||
flat
|
|
||||||
icon="info"
|
|
||||||
size="sm"
|
|
||||||
@click="
|
|
||||||
openURL(
|
|
||||||
'https://platform.openai.com/docs/models/overview'
|
|
||||||
)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<q-tooltip>Click to see available options</q-tooltip>
|
|
||||||
</q-btn>
|
|
||||||
</template>
|
|
||||||
</q-input>
|
|
||||||
</q-card-section>
|
|
||||||
</q-tab-panel>
|
|
||||||
</q-tab-panels>
|
</q-tab-panels>
|
||||||
</q-scroll-area>
|
</q-scroll-area>
|
||||||
<q-card-section class="row items-center">
|
<q-card-section class="row items-center">
|
||||||
|
|||||||
@@ -11,17 +11,7 @@
|
|||||||
:style="maximized ? '' : 'width: 90vw; max-width: 90vw'"
|
:style="maximized ? '' : 'width: 90vw; max-width: 90vw'"
|
||||||
>
|
>
|
||||||
<q-bar>
|
<q-bar>
|
||||||
<span class="q-pr-sm">{{ title }}</span>
|
{{ title }}
|
||||||
<q-btn
|
|
||||||
v-if="!script && openAIEnabled"
|
|
||||||
size="xs"
|
|
||||||
:disable="loading"
|
|
||||||
dense
|
|
||||||
label="Generate Script"
|
|
||||||
color="primary"
|
|
||||||
no-caps
|
|
||||||
@click="generateScriptOpenAI"
|
|
||||||
/>
|
|
||||||
<q-space />
|
<q-space />
|
||||||
<q-btn
|
<q-btn
|
||||||
dense
|
dense
|
||||||
@@ -67,23 +57,7 @@
|
|||||||
><br />Add one to get rid of this warning. Ignore if windows.
|
><br />Add one to get rid of this warning. Ignore if windows.
|
||||||
</q-banner>
|
</q-banner>
|
||||||
<div class="row q-pa-sm">
|
<div class="row q-pa-sm">
|
||||||
<q-scroll-area
|
<div class="col-4 q-gutter-sm q-pr-sm">
|
||||||
:thumb-style="{
|
|
||||||
right: '4px',
|
|
||||||
borderRadius: '5px',
|
|
||||||
width: '5px',
|
|
||||||
opacity: 0.75,
|
|
||||||
}"
|
|
||||||
:bar-style="{
|
|
||||||
right: '2px',
|
|
||||||
borderRadius: '9px',
|
|
||||||
width: '9px',
|
|
||||||
opacity: 0.2,
|
|
||||||
}"
|
|
||||||
class="col-4 q-mb-none q-pb-none"
|
|
||||||
:style="{ height: `${maximized ? '82vh' : '64vh'}` }"
|
|
||||||
>
|
|
||||||
<div class="q-gutter-sm q-pr-sm">
|
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
@@ -170,11 +144,11 @@
|
|||||||
label="Run As User (Windows only)"
|
label="Run As User (Windows only)"
|
||||||
>
|
>
|
||||||
<q-tooltip
|
<q-tooltip
|
||||||
>Setting this value on the script model will always override
|
>Setting this value on the script model will always override any
|
||||||
any 'Run As User' checkboxes in the UI and force this script
|
'Run As User' checkboxes in the UI and force this script to
|
||||||
to always be run in the context of the logged in user. If no
|
always be run in the context of the logged in user. If no user
|
||||||
user is logged in, the script will not run and an error will
|
is logged in, the script will not run and an error will be
|
||||||
be returned.
|
returned.
|
||||||
</q-tooltip>
|
</q-tooltip>
|
||||||
</q-checkbox>
|
</q-checkbox>
|
||||||
<q-input
|
<q-input
|
||||||
@@ -187,13 +161,12 @@
|
|||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</q-scroll-area>
|
|
||||||
<v-ace-editor
|
<v-ace-editor
|
||||||
v-model:value="formScript.script_body"
|
v-model:value="formScript.script_body"
|
||||||
class="col-8"
|
class="col-8"
|
||||||
:lang="lang"
|
:lang="lang"
|
||||||
:theme="$q.dark.isActive ? 'tomorrow_night_eighties' : 'tomorrow'"
|
:theme="$q.dark.isActive ? 'tomorrow_night_eighties' : 'tomorrow'"
|
||||||
:style="{ height: `${maximized ? '82vh' : '64vh'}` }"
|
:style="{ height: `${maximized ? '87vh' : '64vh'}` }"
|
||||||
wrap
|
wrap
|
||||||
:printMargin="false"
|
:printMargin="false"
|
||||||
:options="{ fontSize: '14px' }"
|
:options="{ fontSize: '14px' }"
|
||||||
@@ -247,11 +220,9 @@
|
|||||||
<script>
|
<script>
|
||||||
// composable imports
|
// composable imports
|
||||||
import { ref, computed, onMounted } from "vue";
|
import { ref, computed, onMounted } from "vue";
|
||||||
import { useStore } from "vuex";
|
|
||||||
import { useQuasar, useDialogPluginComponent } from "quasar";
|
import { useQuasar, useDialogPluginComponent } from "quasar";
|
||||||
import { saveScript, editScript, downloadScript } from "@/api/scripts";
|
import { saveScript, editScript, downloadScript } from "@/api/scripts";
|
||||||
import { useAgentDropdown, agentPlatformOptions } from "@/composables/agents";
|
import { useAgentDropdown, agentPlatformOptions } from "@/composables/agents";
|
||||||
import { generateScript } from "@/api/core";
|
|
||||||
import { notifySuccess } from "@/utils/notify";
|
import { notifySuccess } from "@/utils/notify";
|
||||||
|
|
||||||
// ui imports
|
// ui imports
|
||||||
@@ -295,10 +266,6 @@ export default {
|
|||||||
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
|
|
||||||
// setup store
|
|
||||||
const store = useStore();
|
|
||||||
const openAIEnabled = computed(() => store.state.openAIIntegrationEnabled);
|
|
||||||
|
|
||||||
// setup agent dropdown
|
// setup agent dropdown
|
||||||
const { agent, agentOptions, getAgentOptions } = useAgentDropdown();
|
const { agent, agentOptions, getAgentOptions } = useAgentDropdown();
|
||||||
|
|
||||||
@@ -388,23 +355,6 @@ export default {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateScriptOpenAI() {
|
|
||||||
$q.dialog({
|
|
||||||
title: "Ask ChatGPT what you need!",
|
|
||||||
prompt: {
|
|
||||||
model: `${lang.value} code that `,
|
|
||||||
type: "text",
|
|
||||||
},
|
|
||||||
cancel: true,
|
|
||||||
persistent: true,
|
|
||||||
}).onOk(async (data) => {
|
|
||||||
const completion = await generateScript({
|
|
||||||
prompt: data,
|
|
||||||
});
|
|
||||||
script.value.script_body = completion;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// component life cycle hooks
|
// component life cycle hooks
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
agentLoading.value = true;
|
agentLoading.value = true;
|
||||||
@@ -430,12 +380,10 @@ export default {
|
|||||||
|
|
||||||
//computed
|
//computed
|
||||||
title,
|
title,
|
||||||
openAIEnabled,
|
|
||||||
|
|
||||||
//methods
|
//methods
|
||||||
submitForm,
|
submitForm,
|
||||||
openTestScriptModal,
|
openTestScriptModal,
|
||||||
generateScriptOpenAI,
|
|
||||||
|
|
||||||
// quasar dialog plugin
|
// quasar dialog plugin
|
||||||
dialogRef,
|
dialogRef,
|
||||||
|
|||||||
@@ -11,17 +11,7 @@
|
|||||||
:style="maximized ? '' : 'width: 70vw; max-width: 90vw'"
|
:style="maximized ? '' : 'width: 70vw; max-width: 90vw'"
|
||||||
>
|
>
|
||||||
<q-bar>
|
<q-bar>
|
||||||
<span class="q-pr-sm">{{ title }}</span>
|
{{ title }}
|
||||||
<q-btn
|
|
||||||
v-if="!snippet && openAIEnabled"
|
|
||||||
:disable="loading"
|
|
||||||
dense
|
|
||||||
size="xs"
|
|
||||||
label="Generate Script"
|
|
||||||
color="primary"
|
|
||||||
no-caps
|
|
||||||
@click="generateScriptOpenAI"
|
|
||||||
/>
|
|
||||||
<q-space />
|
<q-space />
|
||||||
<q-btn
|
<q-btn
|
||||||
dense
|
dense
|
||||||
@@ -107,9 +97,6 @@
|
|||||||
<script>
|
<script>
|
||||||
// composable imports
|
// composable imports
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from "vue";
|
||||||
import { useStore } from "vuex";
|
|
||||||
import { useQuasar } from "quasar";
|
|
||||||
import { generateScript } from "@/api/core";
|
|
||||||
import { useDialogPluginComponent } from "quasar";
|
import { useDialogPluginComponent } from "quasar";
|
||||||
import { saveScriptSnippet, editScriptSnippet } from "@/api/scripts";
|
import { saveScriptSnippet, editScriptSnippet } from "@/api/scripts";
|
||||||
import { notifySuccess } from "@/utils/notify";
|
import { notifySuccess } from "@/utils/notify";
|
||||||
@@ -141,13 +128,6 @@ export default {
|
|||||||
// setup quasar plugins
|
// setup quasar plugins
|
||||||
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
||||||
|
|
||||||
// setup quasar
|
|
||||||
const $q = useQuasar();
|
|
||||||
|
|
||||||
// setup store
|
|
||||||
const store = useStore();
|
|
||||||
const openAIEnabled = computed(() => store.state.openAIIntegrationEnabled);
|
|
||||||
|
|
||||||
// snippet form logic
|
// snippet form logic
|
||||||
const snippet = props.snippet
|
const snippet = props.snippet
|
||||||
? ref(Object.assign({}, props.snippet))
|
? ref(Object.assign({}, props.snippet))
|
||||||
@@ -187,23 +167,6 @@ export default {
|
|||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateScriptOpenAI() {
|
|
||||||
$q.dialog({
|
|
||||||
title: "Ask ChatGPT what you need!",
|
|
||||||
prompt: {
|
|
||||||
model: `${lang.value} code that `,
|
|
||||||
type: "text",
|
|
||||||
},
|
|
||||||
cancel: true,
|
|
||||||
persistent: true,
|
|
||||||
}).onOk(async (data) => {
|
|
||||||
const completion = await generateScript({
|
|
||||||
prompt: data,
|
|
||||||
});
|
|
||||||
snippet.value.code = completion;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// reactive data
|
// reactive data
|
||||||
formSnippet: snippet.value,
|
formSnippet: snippet.value,
|
||||||
@@ -216,11 +179,9 @@ export default {
|
|||||||
|
|
||||||
//computed
|
//computed
|
||||||
title,
|
title,
|
||||||
openAIEnabled,
|
|
||||||
|
|
||||||
//methods
|
//methods
|
||||||
submitForm,
|
submitForm,
|
||||||
generateScriptOpenAI,
|
|
||||||
|
|
||||||
// quasar dialog plugin
|
// quasar dialog plugin
|
||||||
dialogRef,
|
dialogRef,
|
||||||
|
|||||||
@@ -836,13 +836,8 @@ export default {
|
|||||||
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
||||||
|
|
||||||
// setup dropdowns
|
// setup dropdowns
|
||||||
const {
|
const { script, scriptOptions, defaultTimeout, defaultArgs, defaultEnvVars } =
|
||||||
script,
|
useScriptDropdown(undefined, {
|
||||||
scriptOptions,
|
|
||||||
defaultTimeout,
|
|
||||||
defaultArgs,
|
|
||||||
defaultEnvVars,
|
|
||||||
} = useScriptDropdown(undefined, {
|
|
||||||
onMount: true,
|
onMount: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export function useScriptDropdown(setScript = null, { onMount = false } = {}) {
|
|||||||
);
|
);
|
||||||
defaultTimeout.value = tmpScript.timeout;
|
defaultTimeout.value = tmpScript.timeout;
|
||||||
defaultArgs.value = tmpScript.args;
|
defaultArgs.value = tmpScript.args;
|
||||||
defaultEnvVars.value = tmpScript.env_vars;
|
defaultEnvVars.value = tmpScript.env_vars,
|
||||||
syntax.value = tmpScript.syntax;
|
syntax.value = tmpScript.syntax;
|
||||||
link.value =
|
link.value =
|
||||||
tmpScript.script_type === "builtin"
|
tmpScript.script_type === "builtin"
|
||||||
|
|||||||
@@ -7,4 +7,4 @@ export const runAsUserToolTip =
|
|||||||
"Run in the context of the logged in user. If no user is logged in, the script will not run and an error will be returned.";
|
"Run in the context of the logged in user. If no user is logged in, the script will not run and an error will be returned.";
|
||||||
|
|
||||||
export const envVarsLabel =
|
export const envVarsLabel =
|
||||||
"Environment vars (press Enter after typing each key=value pair)";
|
"Environment vars (press Enter after typing each key=value pair)"
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ export default function () {
|
|||||||
currentTRMMVersion: null,
|
currentTRMMVersion: null,
|
||||||
latestTRMMVersion: null,
|
latestTRMMVersion: null,
|
||||||
dateFormat: "MMM-DD-YYYY - HH:mm",
|
dateFormat: "MMM-DD-YYYY - HH:mm",
|
||||||
openAIIntegrationEnabled: false,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
@@ -137,9 +136,6 @@ export default function () {
|
|||||||
setDateFormat(state, val) {
|
setDateFormat(state, val) {
|
||||||
state.dateFormat = val;
|
state.dateFormat = val;
|
||||||
},
|
},
|
||||||
setOpenAIIntegrationStatus(state, val) {
|
|
||||||
state.openAIIntegrationEnabled = val;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setClientTreeSplitter(context, val) {
|
setClientTreeSplitter(context, val) {
|
||||||
@@ -221,10 +217,6 @@ export default function () {
|
|||||||
context.commit("setShowCommunityScripts", data.show_community_scripts);
|
context.commit("setShowCommunityScripts", data.show_community_scripts);
|
||||||
context.commit("SET_HOSTED", data.hosted);
|
context.commit("SET_HOSTED", data.hosted);
|
||||||
context.commit("SET_TOKEN_EXPIRED", data.token_is_expired);
|
context.commit("SET_TOKEN_EXPIRED", data.token_is_expired);
|
||||||
context.commit(
|
|
||||||
"setOpenAIIntegrationStatus",
|
|
||||||
data.open_ai_integration_enabled
|
|
||||||
);
|
|
||||||
|
|
||||||
if (data.date_format && data.date_format !== "")
|
if (data.date_format && data.date_format !== "")
|
||||||
context.commit("setDateFormat", data.date_format);
|
context.commit("setDateFormat", data.date_format);
|
||||||
|
|||||||
@@ -173,18 +173,6 @@
|
|||||||
</q-menu>
|
</q-menu>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
||||||
<!-- Bulk Run Checks -->
|
|
||||||
<q-item
|
|
||||||
clickable
|
|
||||||
v-close-popup
|
|
||||||
@click="runChecks(props.node)"
|
|
||||||
>
|
|
||||||
<q-item-section side>
|
|
||||||
<q-icon name="fas fa-check-double" />
|
|
||||||
</q-item-section>
|
|
||||||
<q-item-section>Run Checks</q-item-section>
|
|
||||||
</q-item>
|
|
||||||
|
|
||||||
<q-separator></q-separator>
|
<q-separator></q-separator>
|
||||||
|
|
||||||
<q-item clickable v-close-popup>
|
<q-item clickable v-close-popup>
|
||||||
@@ -452,7 +440,7 @@ export default {
|
|||||||
showInstallAgentModal: false,
|
showInstallAgentModal: false,
|
||||||
sitePk: null,
|
sitePk: null,
|
||||||
innerModel: (this.$q.screen.height - 82) / 2,
|
innerModel: (this.$q.screen.height - 82) / 2,
|
||||||
search: (this.$route.query.search ? this.$route.query.search : ""),
|
search: "",
|
||||||
filterTextLength: 0,
|
filterTextLength: 0,
|
||||||
filterAvailability: "all",
|
filterAvailability: "all",
|
||||||
filterPatchesPending: false,
|
filterPatchesPending: false,
|
||||||
@@ -702,17 +690,6 @@ export default {
|
|||||||
})
|
})
|
||||||
.onOk(() => this.$store.dispatch("refreshDashboard"));
|
.onOk(() => this.$store.dispatch("refreshDashboard"));
|
||||||
},
|
},
|
||||||
runChecks(node) {
|
|
||||||
const target = node.children ? "client" : "site";
|
|
||||||
this.$axios
|
|
||||||
.post(`/checks/${target}/${node.id}/csbulkrun/`)
|
|
||||||
.then((r) => {
|
|
||||||
this.notifySuccess(r.data);
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.error(e);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showToggleMaintenance(node) {
|
showToggleMaintenance(node) {
|
||||||
let data = {
|
let data = {
|
||||||
id: node.id,
|
id: node.id,
|
||||||
|
|||||||
Reference in New Issue
Block a user