Compare commits
	
		
			42 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					5114ff40aa | ||
| 
						 | 
					908b337797 | ||
| 
						 | 
					fea5258903 | ||
| 
						 | 
					5521e4ea3e | ||
| 
						 | 
					6cc01596cb | ||
| 
						 | 
					0694538482 | ||
| 
						 | 
					6ea7c92b20 | ||
| 
						 | 
					ac05ad40c0 | ||
| 
						 | 
					239b0182fb | ||
| 
						 | 
					4c57e5da4b | ||
| 
						 | 
					298d039028 | ||
| 
						 | 
					021a066074 | ||
| 
						 | 
					7dc2f5a658 | ||
| 
						 | 
					57bd8bafac | ||
| 
						 | 
					7d5216aba9 | ||
| 
						 | 
					076ab0c465 | ||
| 
						 | 
					be37e89e16 | ||
| 
						 | 
					0bdc841084 | ||
| 
						 | 
					96086d0b5d | ||
| 
						 | 
					20d534eab0 | ||
| 
						 | 
					1b2286c4f8 | ||
| 
						 | 
					8207f30234 | ||
| 
						 | 
					68036f6837 | ||
| 
						 | 
					03fae45ac5 | ||
| 
						 | 
					c2591c9e7d | ||
| 
						 | 
					7fcbe6fbd8 | ||
| 
						 | 
					a2f472ef9c | ||
| 
						 | 
					8403ac0e93 | ||
| 
						 | 
					b7a91563b0 | ||
| 
						 | 
					ab19afca16 | ||
| 
						 | 
					f24c6a7a80 | ||
| 
						 | 
					99490bf859 | ||
| 
						 | 
					72cdeeaa6a | ||
| 
						 | 
					1eca4d605b | ||
| 
						 | 
					52ee98f6f8 | ||
| 
						 | 
					d270b877c9 | ||
| 
						 | 
					fd8b2a1d98 | ||
| 
						 | 
					f518043d8d | ||
| 
						 | 
					cc2335558d | ||
| 
						 | 
					a8a171ba2c | ||
| 
						 | 
					24a63f477e | ||
| 
						 | 
					ddeb6293a1 | 
							
								
								
									
										5796
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5796
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										19
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								package.json
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "web",
 | 
					  "name": "web",
 | 
				
			||||||
  "version": "0.101.32",
 | 
					  "version": "0.101.35",
 | 
				
			||||||
  "private": true,
 | 
					  "private": true,
 | 
				
			||||||
  "productName": "Tactical RMM",
 | 
					  "productName": "Tactical RMM",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
@@ -11,13 +11,12 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@quasar/extras": "1.16.7",
 | 
					    "@quasar/extras": "1.16.7",
 | 
				
			||||||
    "apexcharts": "3.41.1",
 | 
					    "apexcharts": "3.44.0",
 | 
				
			||||||
    "axios": "1.5.1",
 | 
					    "axios": "1.6.0",
 | 
				
			||||||
    "dotenv": "16.3.1",
 | 
					    "dotenv": "16.3.1",
 | 
				
			||||||
    "qrcode.vue": "3.4.1",
 | 
					    "qrcode.vue": "3.4.1",
 | 
				
			||||||
    "quasar": "2.13.0",
 | 
					    "quasar": "2.13.0",
 | 
				
			||||||
    "vue": "3.3.7",
 | 
					    "vue": "3.3.8",
 | 
				
			||||||
    "vue3-ace-editor": "2.2.3",
 | 
					 | 
				
			||||||
    "vue3-apexcharts": "1.4.4",
 | 
					    "vue3-apexcharts": "1.4.4",
 | 
				
			||||||
    "vuedraggable": "4.1.0",
 | 
					    "vuedraggable": "4.1.0",
 | 
				
			||||||
    "vue-router": "4.2.5",
 | 
					    "vue-router": "4.2.5",
 | 
				
			||||||
@@ -25,17 +24,17 @@
 | 
				
			|||||||
    "@vueuse/shared": "10.5.0",
 | 
					    "@vueuse/shared": "10.5.0",
 | 
				
			||||||
    "monaco-editor": "0.44.0",
 | 
					    "monaco-editor": "0.44.0",
 | 
				
			||||||
    "vuex": "4.1.0",
 | 
					    "vuex": "4.1.0",
 | 
				
			||||||
    "yaml": "2.3.3"
 | 
					    "yaml": "2.3.4"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@quasar/cli": "2.3.0",
 | 
					    "@quasar/cli": "2.3.0",
 | 
				
			||||||
    "@intlify/unplugin-vue-i18n": "1.4.0",
 | 
					    "@intlify/unplugin-vue-i18n": "1.4.0",
 | 
				
			||||||
    "@quasar/app-vite": "1.6.2",
 | 
					    "@quasar/app-vite": "1.6.2",
 | 
				
			||||||
    "@types/node": "20.8.8",
 | 
					    "@types/node": "20.8.10",
 | 
				
			||||||
    "@typescript-eslint/eslint-plugin": "6.9.0",
 | 
					    "@typescript-eslint/eslint-plugin": "6.10.0",
 | 
				
			||||||
    "@typescript-eslint/parser": "6.9.0",
 | 
					    "@typescript-eslint/parser": "6.10.0",
 | 
				
			||||||
    "autoprefixer": "10.4.16",
 | 
					    "autoprefixer": "10.4.16",
 | 
				
			||||||
    "eslint": "8.52.0",
 | 
					    "eslint": "8.53.0",
 | 
				
			||||||
    "eslint-config-prettier": "9.0.0",
 | 
					    "eslint-config-prettier": "9.0.0",
 | 
				
			||||||
    "eslint-plugin-vue": "8.7.1",
 | 
					    "eslint-plugin-vue": "8.7.1",
 | 
				
			||||||
    "prettier": "3.0.3",
 | 
					    "prettier": "3.0.3",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -150,7 +150,7 @@
 | 
				
			|||||||
          </q-menu>
 | 
					          </q-menu>
 | 
				
			||||||
        </q-btn>
 | 
					        </q-btn>
 | 
				
			||||||
        <!-- integrations -->
 | 
					        <!-- integrations -->
 | 
				
			||||||
        <q-btn size="md" dense no-caps flat label="Integrations">
 | 
					        <q-btn size="md" dense no-caps flat label="Reporting">
 | 
				
			||||||
          <q-menu auto-close>
 | 
					          <q-menu auto-close>
 | 
				
			||||||
            <q-list
 | 
					            <q-list
 | 
				
			||||||
              v-if="
 | 
					              v-if="
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,17 +1,12 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <q-dialog
 | 
					  <q-dialog
 | 
				
			||||||
    ref="dialogRef"
 | 
					    ref="dialogRef"
 | 
				
			||||||
    persistent
 | 
					    maximized
 | 
				
			||||||
    @keydown.esc.stop="onDialogHide"
 | 
					    @hide="onDialogHide"
 | 
				
			||||||
    :maximized="maximized"
 | 
					 | 
				
			||||||
    @keydown.esc="unloadEditor"
 | 
					 | 
				
			||||||
    @hide="unloadEditor"
 | 
					 | 
				
			||||||
    @show="loadEditor"
 | 
					    @show="loadEditor"
 | 
				
			||||||
 | 
					    @before-hide="unloadEditor"
 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
    <q-card
 | 
					    <q-card class="q-dialog-plugin">
 | 
				
			||||||
      class="q-dialog-plugin"
 | 
					 | 
				
			||||||
      :style="maximized ? '' : 'width: 90vw; max-width: 90vw'"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      <q-bar>
 | 
					      <q-bar>
 | 
				
			||||||
        <span class="q-pr-sm">{{ title }}</span>
 | 
					        <span class="q-pr-sm">{{ title }}</span>
 | 
				
			||||||
        <q-btn
 | 
					        <q-btn
 | 
				
			||||||
@@ -25,34 +20,12 @@
 | 
				
			|||||||
          @click="generateScriptOpenAI"
 | 
					          @click="generateScriptOpenAI"
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <q-space />
 | 
					        <q-space />
 | 
				
			||||||
        <q-btn
 | 
					 | 
				
			||||||
          dense
 | 
					 | 
				
			||||||
          flat
 | 
					 | 
				
			||||||
          icon="minimize"
 | 
					 | 
				
			||||||
          @click="maximized = false"
 | 
					 | 
				
			||||||
          :disable="!maximized"
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          <q-tooltip v-if="maximized" class="bg-white text-primary"
 | 
					 | 
				
			||||||
            >Minimize</q-tooltip
 | 
					 | 
				
			||||||
          >
 | 
					 | 
				
			||||||
        </q-btn>
 | 
					 | 
				
			||||||
        <q-btn
 | 
					 | 
				
			||||||
          dense
 | 
					 | 
				
			||||||
          flat
 | 
					 | 
				
			||||||
          icon="crop_square"
 | 
					 | 
				
			||||||
          @click="maximized = true"
 | 
					 | 
				
			||||||
          :disable="maximized"
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          <q-tooltip v-if="!maximized" class="bg-white text-primary"
 | 
					 | 
				
			||||||
            >Maximize</q-tooltip
 | 
					 | 
				
			||||||
          >
 | 
					 | 
				
			||||||
        </q-btn>
 | 
					 | 
				
			||||||
        <q-btn dense flat icon="close" v-close-popup>
 | 
					        <q-btn dense flat icon="close" v-close-popup>
 | 
				
			||||||
          <q-tooltip class="bg-white text-primary">Close</q-tooltip>
 | 
					          <q-tooltip class="bg-white text-primary">Close</q-tooltip>
 | 
				
			||||||
        </q-btn>
 | 
					        </q-btn>
 | 
				
			||||||
      </q-bar>
 | 
					      </q-bar>
 | 
				
			||||||
      <q-banner
 | 
					      <q-banner
 | 
				
			||||||
        v-if="missingShebang"
 | 
					        v-if="script.script_body && missingShebang"
 | 
				
			||||||
        dense
 | 
					        dense
 | 
				
			||||||
        inline-actions
 | 
					        inline-actions
 | 
				
			||||||
        class="text-black bg-warning"
 | 
					        class="text-black bg-warning"
 | 
				
			||||||
@@ -78,7 +51,7 @@
 | 
				
			|||||||
            opacity: '0.2',
 | 
					            opacity: '0.2',
 | 
				
			||||||
          }"
 | 
					          }"
 | 
				
			||||||
          class="col-4 q-mb-none q-pb-none"
 | 
					          class="col-4 q-mb-none q-pb-none"
 | 
				
			||||||
          :style="{ height: `${maximized ? '82vh' : '64vh'}` }"
 | 
					          :style="{ height: `${$q.screen.height - 106}px` }"
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          <div class="q-gutter-sm q-pr-sm">
 | 
					          <div class="q-gutter-sm q-pr-sm">
 | 
				
			||||||
            <q-input
 | 
					            <q-input
 | 
				
			||||||
@@ -170,8 +143,7 @@
 | 
				
			|||||||
                >Setting this value on the script model will always override any
 | 
					                >Setting this value on the script model will always override any
 | 
				
			||||||
                'Run As User' checkboxes in the UI and force this script to
 | 
					                'Run As User' checkboxes in the UI and force this script to
 | 
				
			||||||
                always be run in the context of the logged in user. If no user
 | 
					                always be 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
 | 
					                is logged in, the script will run as SYSTEM.
 | 
				
			||||||
                returned.
 | 
					 | 
				
			||||||
              </q-tooltip>
 | 
					              </q-tooltip>
 | 
				
			||||||
            </q-checkbox>
 | 
					            </q-checkbox>
 | 
				
			||||||
            <q-input
 | 
					            <q-input
 | 
				
			||||||
@@ -188,7 +160,7 @@
 | 
				
			|||||||
        <div
 | 
					        <div
 | 
				
			||||||
          ref="scriptEditor"
 | 
					          ref="scriptEditor"
 | 
				
			||||||
          class="col-8 q-mb-none q-pb-none"
 | 
					          class="col-8 q-mb-none q-pb-none"
 | 
				
			||||||
          :style="{ height: `${maximized ? '82vh' : '64vh'}` }"
 | 
					          :style="{ height: `${$q.screen.height - 106}px` }"
 | 
				
			||||||
        ></div>
 | 
					        ></div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <q-card-actions>
 | 
					      <q-card-actions>
 | 
				
			||||||
@@ -235,7 +207,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
// composable imports
 | 
					// composable imports
 | 
				
			||||||
import { ref, reactive, computed, onMounted } from "vue";
 | 
					import { ref, reactive, watch, computed, onMounted } from "vue";
 | 
				
			||||||
import { useStore } from "vuex";
 | 
					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";
 | 
				
			||||||
@@ -266,7 +238,7 @@ const props = withDefaults(
 | 
				
			|||||||
  {
 | 
					  {
 | 
				
			||||||
    clone: false,
 | 
					    clone: false,
 | 
				
			||||||
    readonly: false,
 | 
					    readonly: false,
 | 
				
			||||||
  }
 | 
					  },
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// emits
 | 
					// emits
 | 
				
			||||||
@@ -297,7 +269,6 @@ const script: Script = props.script
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (props.clone) script.name = `(Copy) ${script.name}`;
 | 
					if (props.clone) script.name = `(Copy) ${script.name}`;
 | 
				
			||||||
const maximized = ref(false);
 | 
					 | 
				
			||||||
const loading = ref(false);
 | 
					const loading = ref(false);
 | 
				
			||||||
const agentLoading = ref(false);
 | 
					const agentLoading = ref(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -330,12 +301,6 @@ const lang = computed(() => {
 | 
				
			|||||||
  else return "";
 | 
					  else return "";
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// get code if editing or cloning script
 | 
					 | 
				
			||||||
if (props.script)
 | 
					 | 
				
			||||||
  downloadScript(script.id, { with_snippets: props.readonly }).then((r) => {
 | 
					 | 
				
			||||||
    script.script_body = r.code;
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async function submit() {
 | 
					async function submit() {
 | 
				
			||||||
  loading.value = true;
 | 
					  loading.value = true;
 | 
				
			||||||
  let result = "";
 | 
					  let result = "";
 | 
				
			||||||
@@ -376,7 +341,7 @@ function loadEditor() {
 | 
				
			|||||||
  var model = monaco.editor.createModel(
 | 
					  var model = monaco.editor.createModel(
 | 
				
			||||||
    script.script_body,
 | 
					    script.script_body,
 | 
				
			||||||
    lang.value,
 | 
					    lang.value,
 | 
				
			||||||
    modelUri
 | 
					    modelUri,
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const theme = $q.dark.isActive ? "vs-dark" : "vs-light";
 | 
					  const theme = $q.dark.isActive ? "vs-dark" : "vs-light";
 | 
				
			||||||
@@ -392,6 +357,18 @@ function loadEditor() {
 | 
				
			|||||||
  editor.onDidChangeModelContent(() => {
 | 
					  editor.onDidChangeModelContent(() => {
 | 
				
			||||||
    script.script_body = editor.getValue();
 | 
					    script.script_body = editor.getValue();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // get code if editing or cloning script
 | 
				
			||||||
 | 
					  if (props.script)
 | 
				
			||||||
 | 
					    downloadScript(script.id, { with_snippets: props.readonly }).then((r) => {
 | 
				
			||||||
 | 
					      script.script_body = r.code;
 | 
				
			||||||
 | 
					      editor.setValue(r.code);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // watch for changes in language
 | 
				
			||||||
 | 
					  watch(lang, () => {
 | 
				
			||||||
 | 
					    monaco.editor.setModelLanguage(model, lang.value);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function unloadEditor() {
 | 
					function unloadEditor() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,16 +1,12 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <q-dialog
 | 
					  <q-dialog
 | 
				
			||||||
    ref="dialogRef"
 | 
					    ref="dialogRef"
 | 
				
			||||||
    persistent
 | 
					    maximized
 | 
				
			||||||
    @keydown.esc="unloadEditor"
 | 
					    @hide="onDialogHide"
 | 
				
			||||||
    :maximized="maximized"
 | 
					 | 
				
			||||||
    @hide="unloadEditor"
 | 
					 | 
				
			||||||
    @show="loadEditor"
 | 
					    @show="loadEditor"
 | 
				
			||||||
 | 
					    @before-hide="unloadEditor"
 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
    <q-card
 | 
					    <q-card class="q-dialog-plugin">
 | 
				
			||||||
      class="q-dialog-plugin"
 | 
					 | 
				
			||||||
      :style="maximized ? '' : 'width: 70vw; max-width: 90vw'"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      <q-bar>
 | 
					      <q-bar>
 | 
				
			||||||
        <span class="q-pr-sm">{{ title }}</span>
 | 
					        <span class="q-pr-sm">{{ title }}</span>
 | 
				
			||||||
        <q-btn
 | 
					        <q-btn
 | 
				
			||||||
@@ -24,35 +20,13 @@
 | 
				
			|||||||
          @click="generateScriptOpenAI"
 | 
					          @click="generateScriptOpenAI"
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <q-space />
 | 
					        <q-space />
 | 
				
			||||||
        <q-btn
 | 
					 | 
				
			||||||
          dense
 | 
					 | 
				
			||||||
          flat
 | 
					 | 
				
			||||||
          icon="minimize"
 | 
					 | 
				
			||||||
          @click="maximized = false"
 | 
					 | 
				
			||||||
          :disable="!maximized"
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          <q-tooltip v-if="maximized" class="bg-white text-primary"
 | 
					 | 
				
			||||||
            >Minimize</q-tooltip
 | 
					 | 
				
			||||||
          >
 | 
					 | 
				
			||||||
        </q-btn>
 | 
					 | 
				
			||||||
        <q-btn
 | 
					 | 
				
			||||||
          dense
 | 
					 | 
				
			||||||
          flat
 | 
					 | 
				
			||||||
          icon="crop_square"
 | 
					 | 
				
			||||||
          @click="maximized = true"
 | 
					 | 
				
			||||||
          :disable="maximized"
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          <q-tooltip v-if="!maximized" class="bg-white text-primary"
 | 
					 | 
				
			||||||
            >Maximize</q-tooltip
 | 
					 | 
				
			||||||
          >
 | 
					 | 
				
			||||||
        </q-btn>
 | 
					 | 
				
			||||||
        <q-btn dense flat icon="close" v-close-popup>
 | 
					        <q-btn dense flat icon="close" v-close-popup>
 | 
				
			||||||
          <q-tooltip class="bg-white text-primary">Close</q-tooltip>
 | 
					          <q-tooltip class="bg-white text-primary">Close</q-tooltip>
 | 
				
			||||||
        </q-btn>
 | 
					        </q-btn>
 | 
				
			||||||
      </q-bar>
 | 
					      </q-bar>
 | 
				
			||||||
      <div class="row">
 | 
					      <div class="row">
 | 
				
			||||||
        <q-input
 | 
					        <q-input
 | 
				
			||||||
          :rules="[(val) => !!val || '*Required']"
 | 
					          :rules="[(val: string) => !!val || '*Required']"
 | 
				
			||||||
          class="q-pa-sm col-4"
 | 
					          class="q-pa-sm col-4"
 | 
				
			||||||
          v-model="snippet.name"
 | 
					          v-model="snippet.name"
 | 
				
			||||||
          label="Name"
 | 
					          label="Name"
 | 
				
			||||||
@@ -81,7 +55,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      <div
 | 
					      <div
 | 
				
			||||||
        ref="snippetEditor"
 | 
					        ref="snippetEditor"
 | 
				
			||||||
        :style="{ height: `${maximized ? '82vh' : '64vh'}` }"
 | 
					        :style="{ height: `${$q.screen.height - 132}px` }"
 | 
				
			||||||
      ></div>
 | 
					      ></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <q-card-actions align="right">
 | 
					      <q-card-actions align="right">
 | 
				
			||||||
@@ -101,7 +75,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
// composable imports
 | 
					// composable imports
 | 
				
			||||||
import { ref, reactive, computed } from "vue";
 | 
					import { ref, watch, reactive, computed } from "vue";
 | 
				
			||||||
import { useStore } from "vuex";
 | 
					import { useStore } from "vuex";
 | 
				
			||||||
import { useQuasar } from "quasar";
 | 
					import { useQuasar } from "quasar";
 | 
				
			||||||
import { generateScript } from "@/api/core";
 | 
					import { generateScript } from "@/api/core";
 | 
				
			||||||
@@ -138,7 +112,6 @@ const openAIEnabled = computed(() => store.state.openAIIntegrationEnabled);
 | 
				
			|||||||
const snippet: ScriptSnippet = props.snippet
 | 
					const snippet: ScriptSnippet = props.snippet
 | 
				
			||||||
  ? reactive(Object.assign({}, props.snippet))
 | 
					  ? reactive(Object.assign({}, props.snippet))
 | 
				
			||||||
  : reactive({ name: "", code: "", shell: "powershell" });
 | 
					  : reactive({ name: "", code: "", shell: "powershell" });
 | 
				
			||||||
const maximized = ref(false);
 | 
					 | 
				
			||||||
const loading = ref(false);
 | 
					const loading = ref(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const title = computed(() => {
 | 
					const title = computed(() => {
 | 
				
			||||||
@@ -177,7 +150,7 @@ const snippetEditor = ref<HTMLElement | null>(null);
 | 
				
			|||||||
let editor: monaco.editor.IStandaloneCodeEditor;
 | 
					let editor: monaco.editor.IStandaloneCodeEditor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function loadEditor() {
 | 
					function loadEditor() {
 | 
				
			||||||
  var modelUri = monaco.Uri.parse("model://new"); // a made up unique URI for our model
 | 
					  var modelUri = monaco.Uri.parse("model://snippet"); // a made up unique URI for our model
 | 
				
			||||||
  var model = monaco.editor.createModel(snippet.code, lang.value, modelUri);
 | 
					  var model = monaco.editor.createModel(snippet.code, lang.value, modelUri);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const theme = $q.dark.isActive ? "vs-dark" : "vs-light";
 | 
					  const theme = $q.dark.isActive ? "vs-dark" : "vs-light";
 | 
				
			||||||
@@ -192,6 +165,11 @@ function loadEditor() {
 | 
				
			|||||||
  editor.onDidChangeModelContent(() => {
 | 
					  editor.onDidChangeModelContent(() => {
 | 
				
			||||||
    snippet.code = editor.getValue();
 | 
					    snippet.code = editor.getValue();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // watch for changes in language
 | 
				
			||||||
 | 
					  watch(lang, () => {
 | 
				
			||||||
 | 
					    monaco.editor.setModelLanguage(model, lang.value);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function unloadEditor() {
 | 
					function unloadEditor() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -302,7 +302,10 @@ export function useReportTemplates(): useReportingTemplates {
 | 
				
			|||||||
    axios
 | 
					    axios
 | 
				
			||||||
      .post(`${baseUrl}/templates/${id}/export/`)
 | 
					      .post(`${baseUrl}/templates/${id}/export/`)
 | 
				
			||||||
      .then(({ data }) => {
 | 
					      .then(({ data }) => {
 | 
				
			||||||
        exportFile(`${data.template.name}-export.json`, JSON.stringify(data));
 | 
					        exportFile(
 | 
				
			||||||
 | 
					          `${data.template.name}-export.json`,
 | 
				
			||||||
 | 
					          JSON.stringify(data, null, 2),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      .catch(() => (isError.value = true))
 | 
					      .catch(() => (isError.value = true))
 | 
				
			||||||
      .finally(() => (isLoading.value = false));
 | 
					      .finally(() => (isLoading.value = false));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,7 +34,7 @@ For details, see: https://license.tacticalrmm.com/ee
 | 
				
			|||||||
          class="q-pr-sm"
 | 
					          class="q-pr-sm"
 | 
				
			||||||
          filled
 | 
					          filled
 | 
				
			||||||
          dense
 | 
					          dense
 | 
				
			||||||
          style="width: 250px"
 | 
					          style="width: 425px"
 | 
				
			||||||
          :error="!isNameValid"
 | 
					          :error="!isNameValid"
 | 
				
			||||||
          hide-bottom-space
 | 
					          hide-bottom-space
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,6 +54,9 @@ For details, see: https://license.tacticalrmm.com/ee
 | 
				
			|||||||
                clickable
 | 
					                clickable
 | 
				
			||||||
                @click="openNewReportTemplateForm('markdown')"
 | 
					                @click="openNewReportTemplateForm('markdown')"
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
 | 
					                <q-item-section avatar>
 | 
				
			||||||
 | 
					                  <q-icon name="fa-brands fa-markdown" />
 | 
				
			||||||
 | 
					                </q-item-section>
 | 
				
			||||||
                <q-item-section>
 | 
					                <q-item-section>
 | 
				
			||||||
                  <q-item-label>Markdown Template</q-item-label>
 | 
					                  <q-item-label>Markdown Template</q-item-label>
 | 
				
			||||||
                </q-item-section>
 | 
					                </q-item-section>
 | 
				
			||||||
@@ -64,8 +67,11 @@ For details, see: https://license.tacticalrmm.com/ee
 | 
				
			|||||||
                clickable
 | 
					                clickable
 | 
				
			||||||
                @click="openNewReportTemplateForm('html')"
 | 
					                @click="openNewReportTemplateForm('html')"
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
 | 
					                <q-item-section avatar>
 | 
				
			||||||
 | 
					                  <q-icon name="fa-brands fa-html5" />
 | 
				
			||||||
 | 
					                </q-item-section>
 | 
				
			||||||
                <q-item-section>
 | 
					                <q-item-section>
 | 
				
			||||||
                  <q-item-label>Html Template</q-item-label>
 | 
					                  <q-item-label>HTML Template</q-item-label>
 | 
				
			||||||
                </q-item-section>
 | 
					                </q-item-section>
 | 
				
			||||||
              </q-item>
 | 
					              </q-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -74,6 +80,9 @@ For details, see: https://license.tacticalrmm.com/ee
 | 
				
			|||||||
                clickable
 | 
					                clickable
 | 
				
			||||||
                @click="openNewReportTemplateForm('plaintext')"
 | 
					                @click="openNewReportTemplateForm('plaintext')"
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
 | 
					                <q-item-section avatar>
 | 
				
			||||||
 | 
					                  <q-icon name="fa-solid fa-file-csv" />
 | 
				
			||||||
 | 
					                </q-item-section>
 | 
				
			||||||
                <q-item-section>
 | 
					                <q-item-section>
 | 
				
			||||||
                  <q-item-label>Plain Text Template</q-item-label>
 | 
					                  <q-item-label>Plain Text Template</q-item-label>
 | 
				
			||||||
                </q-item-section>
 | 
					                </q-item-section>
 | 
				
			||||||
@@ -82,6 +91,9 @@ For details, see: https://license.tacticalrmm.com/ee
 | 
				
			|||||||
              <q-separator />
 | 
					              <q-separator />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              <q-item clickable v-close-popup @click="importReportTemplate">
 | 
					              <q-item clickable v-close-popup @click="importReportTemplate">
 | 
				
			||||||
 | 
					                <q-item-section avatar>
 | 
				
			||||||
 | 
					                  <q-icon name="fa-solid fa-file-import" />
 | 
				
			||||||
 | 
					                </q-item-section>
 | 
				
			||||||
                <q-item-section>
 | 
					                <q-item-section>
 | 
				
			||||||
                  <q-item-label>Import Report Template</q-item-label>
 | 
					                  <q-item-label>Import Report Template</q-item-label>
 | 
				
			||||||
                </q-item-section>
 | 
					                </q-item-section>
 | 
				
			||||||
@@ -91,6 +103,7 @@ For details, see: https://license.tacticalrmm.com/ee
 | 
				
			|||||||
          <q-btn
 | 
					          <q-btn
 | 
				
			||||||
            class="q-ml-sm"
 | 
					            class="q-ml-sm"
 | 
				
			||||||
            label="Base Templates"
 | 
					            label="Base Templates"
 | 
				
			||||||
 | 
					            icon="fa-regular fa-file-code"
 | 
				
			||||||
            no-caps
 | 
					            no-caps
 | 
				
			||||||
            dense
 | 
					            dense
 | 
				
			||||||
            flat
 | 
					            flat
 | 
				
			||||||
@@ -99,6 +112,7 @@ For details, see: https://license.tacticalrmm.com/ee
 | 
				
			|||||||
          <q-btn
 | 
					          <q-btn
 | 
				
			||||||
            class="q-ml-sm"
 | 
					            class="q-ml-sm"
 | 
				
			||||||
            label="Report Assets"
 | 
					            label="Report Assets"
 | 
				
			||||||
 | 
					            icon="fa-regular fa-folder-closed"
 | 
				
			||||||
            no-caps
 | 
					            no-caps
 | 
				
			||||||
            dense
 | 
					            dense
 | 
				
			||||||
            flat
 | 
					            flat
 | 
				
			||||||
@@ -107,6 +121,7 @@ For details, see: https://license.tacticalrmm.com/ee
 | 
				
			|||||||
          <q-btn
 | 
					          <q-btn
 | 
				
			||||||
            class="q-ml-sm"
 | 
					            class="q-ml-sm"
 | 
				
			||||||
            label="Data Queries"
 | 
					            label="Data Queries"
 | 
				
			||||||
 | 
					            icon="fa-solid fa-database"
 | 
				
			||||||
            no-caps
 | 
					            no-caps
 | 
				
			||||||
            dense
 | 
					            dense
 | 
				
			||||||
            flat
 | 
					            flat
 | 
				
			||||||
@@ -115,6 +130,7 @@ For details, see: https://license.tacticalrmm.com/ee
 | 
				
			|||||||
          <q-btn
 | 
					          <q-btn
 | 
				
			||||||
            class="q-ml-sm"
 | 
					            class="q-ml-sm"
 | 
				
			||||||
            label="Shared Templates"
 | 
					            label="Shared Templates"
 | 
				
			||||||
 | 
					            icon="fa-solid fa-share"
 | 
				
			||||||
            no-caps
 | 
					            no-caps
 | 
				
			||||||
            dense
 | 
					            dense
 | 
				
			||||||
            flat
 | 
					            flat
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,7 @@ For details, see: https://license.tacticalrmm.com/ee
 | 
				
			|||||||
        :rows="sharedTemplates"
 | 
					        :rows="sharedTemplates"
 | 
				
			||||||
        :columns="columns"
 | 
					        :columns="columns"
 | 
				
			||||||
        :loading="isLoading"
 | 
					        :loading="isLoading"
 | 
				
			||||||
        :pagination="{ rowsPerPage: 0, sortBy: 'name', descending: true }"
 | 
					        :pagination="{ rowsPerPage: 0, sortBy: 'name', descending: false }"
 | 
				
			||||||
        :filter="search"
 | 
					        :filter="search"
 | 
				
			||||||
        selection="multiple"
 | 
					        selection="multiple"
 | 
				
			||||||
        v-model:selected="selected"
 | 
					        v-model:selected="selected"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,11 @@
 | 
				
			|||||||
        >
 | 
					        >
 | 
				
			||||||
          <q-spinner size="40px" color="primary" />
 | 
					          <q-spinner size="40px" color="primary" />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div v-else class="q-pa-sm q-gutter-sm scroll" style="height: 85vh; overflow: initial;">
 | 
					        <div
 | 
				
			||||||
 | 
					          v-else
 | 
				
			||||||
 | 
					          class="q-pa-sm q-gutter-sm scroll"
 | 
				
			||||||
 | 
					          style="height: 85vh; overflow: initial"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
          <q-list dense class="rounded-borders">
 | 
					          <q-list dense class="rounded-borders">
 | 
				
			||||||
            <q-item
 | 
					            <q-item
 | 
				
			||||||
              clickable
 | 
					              clickable
 | 
				
			||||||
@@ -163,7 +167,7 @@
 | 
				
			|||||||
                                runURLAction(
 | 
					                                runURLAction(
 | 
				
			||||||
                                  props.node.id,
 | 
					                                  props.node.id,
 | 
				
			||||||
                                  action.id,
 | 
					                                  action.id,
 | 
				
			||||||
                                  props.node.children ? 'client' : 'site'
 | 
					                                  props.node.children ? 'client' : 'site',
 | 
				
			||||||
                                )
 | 
					                                )
 | 
				
			||||||
                              "
 | 
					                              "
 | 
				
			||||||
                            >
 | 
					                            >
 | 
				
			||||||
@@ -196,9 +200,9 @@
 | 
				
			|||||||
                        "
 | 
					                        "
 | 
				
			||||||
                      >
 | 
					                      >
 | 
				
			||||||
                        <q-item-section side>
 | 
					                        <q-item-section side>
 | 
				
			||||||
                          <q-icon name="integration_instructions" />
 | 
					                          <q-icon name="analytics" />
 | 
				
			||||||
                        </q-item-section>
 | 
					                        </q-item-section>
 | 
				
			||||||
                        <q-item-section>Integrations</q-item-section>
 | 
					                        <q-item-section>Reporting</q-item-section>
 | 
				
			||||||
                        <q-item-section side>
 | 
					                        <q-item-section side>
 | 
				
			||||||
                          <q-icon name="keyboard_arrow_right" />
 | 
					                          <q-icon name="keyboard_arrow_right" />
 | 
				
			||||||
                        </q-item-section>
 | 
					                        </q-item-section>
 | 
				
			||||||
@@ -816,7 +820,7 @@ export default {
 | 
				
			|||||||
      this.$axios.get("/core/urlaction/").then((r) => {
 | 
					      this.$axios.get("/core/urlaction/").then((r) => {
 | 
				
			||||||
        if (r.data.length === 0) {
 | 
					        if (r.data.length === 0) {
 | 
				
			||||||
          this.notifyWarning(
 | 
					          this.notifyWarning(
 | 
				
			||||||
            "No URL Actions configured. Go to Settings > Global Settings > URL Actions"
 | 
					            "No URL Actions configured. Go to Settings > Global Settings > URL Actions",
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
          return;
 | 
					          return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user