Compare commits
	
		
			14 Commits
		
	
	
		
			v0.101.17-
			...
			v0.101.13
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					b7a91563b0 | ||
| 
						 | 
					ab19afca16 | ||
| 
						 | 
					f24c6a7a80 | ||
| 
						 | 
					99490bf859 | ||
| 
						 | 
					72cdeeaa6a | ||
| 
						 | 
					1eca4d605b | ||
| 
						 | 
					52ee98f6f8 | ||
| 
						 | 
					d270b877c9 | ||
| 
						 | 
					fd8b2a1d98 | ||
| 
						 | 
					f518043d8d | ||
| 
						 | 
					cc2335558d | ||
| 
						 | 
					a8a171ba2c | ||
| 
						 | 
					24a63f477e | ||
| 
						 | 
					ddeb6293a1 | 
							
								
								
									
										5463
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5463
									
								
								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.17-dev",
 | 
					  "version": "0.101.13",
 | 
				
			||||||
  "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.2",
 | 
					    "@quasar/extras": "1.15.9",
 | 
				
			||||||
    "apexcharts": "3.37.3",
 | 
					    "apexcharts": "3.36.3",
 | 
				
			||||||
    "axios": "1.3.5",
 | 
					    "axios": "0.27.2",
 | 
				
			||||||
    "dotenv": "16.0.3",
 | 
					    "dotenv": "16.0.3",
 | 
				
			||||||
    "qrcode.vue": "3.3.4",
 | 
					    "qrcode.vue": "3.3.3",
 | 
				
			||||||
    "quasar": "2.11.10",
 | 
					    "quasar": "2.11.5",
 | 
				
			||||||
    "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.0.0",
 | 
					    "@quasar/cli": "^1.4.0",
 | 
				
			||||||
    "@intlify/unplugin-vue-i18n": "^0.10.0",
 | 
					    "@intlify/vite-plugin-vue-i18n": "^6.0.3",
 | 
				
			||||||
    "@quasar/app-vite": "^1.2.1",
 | 
					    "@quasar/app-vite": "^1.2.0",
 | 
				
			||||||
    "@types/node": "^18.15.11",
 | 
					    "@types/node": "^18.11.18",
 | 
				
			||||||
    "@typescript-eslint/eslint-plugin": "^5.57.1",
 | 
					    "@typescript-eslint/eslint-plugin": "^5.48.2",
 | 
				
			||||||
    "@typescript-eslint/parser": "^5.57.1",
 | 
					    "@typescript-eslint/parser": "^5.48.2",
 | 
				
			||||||
    "autoprefixer": "10.4.14",
 | 
					    "autoprefixer": "10.4.13",
 | 
				
			||||||
    "eslint": "8.37.0",
 | 
					    "eslint": "8.32.0",
 | 
				
			||||||
    "eslint-config-prettier": "8.8.0",
 | 
					    "eslint-config-prettier": "8.6.0",
 | 
				
			||||||
    "eslint-plugin-vue": "8.7.1",
 | 
					    "eslint-plugin-vue": "8.7.1",
 | 
				
			||||||
    "prettier": "2.8.7",
 | 
					    "prettier": "2.8.3",
 | 
				
			||||||
    "typescript": "5.0.4"
 | 
					    "typescript": "4.9.4"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -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,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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