From 4d35f5a09eea75ee12258b3a58989615d213a138 Mon Sep 17 00:00:00 2001 From: sadnub Date: Sun, 3 Mar 2024 20:08:28 -0500 Subject: [PATCH] finished fixing up frontend bugs and most typescript rework that was started --- package-lock.json | 359 +++++++++------- src/api/core.ts | 14 +- src/components/agents/AutomatedTasksTab.vue | 12 +- .../automation/PolicyAutomatedTasksTab.vue | 6 +- src/components/checks/ScriptCheck.vue | 3 +- src/components/modals/agents/RunScript.vue | 167 +++----- .../modals/alerts/AlertTemplateForm.vue | 155 +++++-- .../modals/core/RunServerScript.vue | 37 +- src/components/tasks/AutomatedTaskForm.vue | 163 ++++---- src/composables/core.js | 28 -- src/composables/core.ts | 73 ++++ src/composables/script.ts | 76 ---- src/composables/scripts.js | 70 ---- src/composables/scripts.ts | 85 +++- src/types/agents.ts | 1 + src/types/alerts.ts | 4 +- src/types/tasks.ts | 79 ++-- src/utils/format.js | 390 ------------------ src/utils/format.ts | 61 ++- src/utils/{notify.js => notify.ts} | 8 +- src/utils/validation.js | 53 --- 21 files changed, 755 insertions(+), 1089 deletions(-) delete mode 100644 src/composables/core.js create mode 100644 src/composables/core.ts delete mode 100644 src/composables/script.ts delete mode 100644 src/composables/scripts.js delete mode 100644 src/utils/format.js rename src/utils/{notify.js => notify.ts} (61%) delete mode 100644 src/utils/validation.js diff --git a/package-lock.json b/package-lock.json index 15a5375f..091186c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,9 +52,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -196,15 +196,15 @@ "dev": true }, "node_modules/@intlify/bundle-utils": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-7.5.0.tgz", - "integrity": "sha512-6DymqusddBQ8kVtVBsVFFF7arNfIhuLacOmmsqayT2vl427j9m0VX12mMC+cgoVIodSpRfzYPaPTdPuJq7mK0Q==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-7.5.1.tgz", + "integrity": "sha512-UovJl10oBIlmYEcWw+VIHdKY5Uv5sdPG0b/b6bOYxGLln3UwB75+2dlc0F3Fsa0RhoznQ5Rp589/BZpABpE4Xw==", "dev": true, "dependencies": { "@intlify/message-compiler": "^9.4.0", "@intlify/shared": "^9.4.0", "acorn": "^8.8.2", - "escodegen": "^2.0.0", + "escodegen": "^2.1.0", "estree-walker": "^2.0.2", "jsonc-eslint-parser": "^2.3.0", "magic-string": "^0.30.0", @@ -225,12 +225,12 @@ } }, "node_modules/@intlify/message-compiler": { - "version": "9.9.1", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.9.1.tgz", - "integrity": "sha512-zTvP6X6HeumHOXuAE1CMMsV6tTX+opKMOxO1OHTCg5N5Sm/F7d8o2jdT6W6L5oHUsJ/vvkGefHIs7Q3hfowmsA==", + "version": "9.10.1", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.10.1.tgz", + "integrity": "sha512-b68UTmRhgZfswJZI7VAgW6BXZK5JOpoi5swMLGr4j6ss2XbFY13kiw+Hu+xYAfulMPSapcHzdWHnq21VGnMCnA==", "dev": true, "dependencies": { - "@intlify/shared": "9.9.1", + "@intlify/shared": "9.10.1", "source-map-js": "^1.0.2" }, "engines": { @@ -241,9 +241,9 @@ } }, "node_modules/@intlify/shared": { - "version": "9.9.1", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.9.1.tgz", - "integrity": "sha512-b3Pta1nwkz5rGq434v0psHwEwHGy1pYCttfcM22IE//K9owbpkEvFptx9VcuRAxjQdrO2If249cmDDjBu5wMDA==", + "version": "9.10.1", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.10.1.tgz", + "integrity": "sha512-liyH3UMoglHBUn70iCYcy9CQlInx/lp50W2aeSxqqrvmG+LDj/Jj7tBJhBoQL4fECkldGhbmW0g2ommHfL6Wmw==", "dev": true, "engines": { "node": ">= 16" @@ -805,9 +805,9 @@ } }, "node_modules/@types/qs": { - "version": "6.9.11", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", - "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==", + "version": "6.9.12", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.12.tgz", + "integrity": "sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==", "dev": true }, "node_modules/@types/range-parser": { @@ -817,9 +817,9 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", - "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "node_modules/@types/send": { @@ -1058,55 +1058,59 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.19.tgz", - "integrity": "sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz", + "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", + "dev": true, "dependencies": { "@babel/parser": "^7.23.9", - "@vue/shared": "3.4.19", + "@vue/shared": "3.4.21", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz", - "integrity": "sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", + "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", + "dev": true, "dependencies": { - "@vue/compiler-core": "3.4.19", - "@vue/shared": "3.4.19" + "@vue/compiler-core": "3.4.21", + "@vue/shared": "3.4.21" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz", - "integrity": "sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz", + "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==", + "dev": true, "dependencies": { "@babel/parser": "^7.23.9", - "@vue/compiler-core": "3.4.19", - "@vue/compiler-dom": "3.4.19", - "@vue/compiler-ssr": "3.4.19", - "@vue/shared": "3.4.19", + "@vue/compiler-core": "3.4.21", + "@vue/compiler-dom": "3.4.21", + "@vue/compiler-ssr": "3.4.21", + "@vue/shared": "3.4.21", "estree-walker": "^2.0.2", - "magic-string": "^0.30.6", - "postcss": "^8.4.33", + "magic-string": "^0.30.7", + "postcss": "^8.4.35", "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz", - "integrity": "sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz", + "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==", + "dev": true, "dependencies": { - "@vue/compiler-dom": "3.4.19", - "@vue/shared": "3.4.19" + "@vue/compiler-dom": "3.4.21", + "@vue/shared": "3.4.21" } }, "node_modules/@vue/devtools-api": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz", - "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==" + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.1.tgz", + "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==" }, "node_modules/@vue/reactivity": { "version": "3.4.19", @@ -1117,9 +1121,9 @@ } }, "node_modules/@vue/reactivity/node_modules/@vue/shared": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.15.tgz", - "integrity": "sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==" + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz", + "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==" }, "node_modules/@vue/runtime-core": { "version": "3.4.19", @@ -1131,9 +1135,9 @@ } }, "node_modules/@vue/runtime-core/node_modules/@vue/shared": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.15.tgz", - "integrity": "sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==" + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz", + "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==" }, "node_modules/@vue/runtime-dom": { "version": "3.4.19", @@ -1146,9 +1150,9 @@ } }, "node_modules/@vue/runtime-dom/node_modules/@vue/shared": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.15.tgz", - "integrity": "sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==" + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz", + "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==" }, "node_modules/@vue/server-renderer": { "version": "3.4.19", @@ -1162,15 +1166,45 @@ "vue": "3.4.19" } }, - "node_modules/@vue/shared": { + "node_modules/@vue/server-renderer/node_modules/@vue/compiler-core": { + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.19.tgz", + "integrity": "sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==", + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/shared": "3.4.19", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/server-renderer/node_modules/@vue/compiler-dom": { + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz", + "integrity": "sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==", + "dependencies": { + "@vue/compiler-core": "3.4.19", + "@vue/shared": "3.4.19" + } + }, + "node_modules/@vue/server-renderer/node_modules/@vue/compiler-ssr": { + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz", + "integrity": "sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==", + "dependencies": { + "@vue/compiler-dom": "3.4.19", + "@vue/shared": "3.4.19" + } + }, + "node_modules/@vue/server-renderer/node_modules/@vue/shared": { "version": "3.4.19", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz", "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==" }, "node_modules/@vue/shared": { - "version": "3.4.18", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.18.tgz", - "integrity": "sha512-CxouGFxxaW5r1WbrSmWwck3No58rApXgRSBxrqgnY1K+jk20F6DrXJkHdH9n4HVT+/B6G2CAn213Uq3npWiy8Q==", + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz", + "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==", "dev": true }, "node_modules/@vueuse/core": { @@ -1605,13 +1639,13 @@ } }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dev": true, "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -1619,7 +1653,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -1817,9 +1851,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz", - "integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "funding": [ { @@ -1836,8 +1870,8 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001580", - "electron-to-chromium": "^1.4.648", + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, @@ -1933,15 +1967,16 @@ } }, "node_modules/call-bind": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz", - "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { + "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", - "set-function-length": "^1.2.0" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -1982,9 +2017,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001585", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001585.tgz", - "integrity": "sha512-yr2BWR1yLXQ8fMpdS/4ZZXpseBgE7o4g41x3a6AJOqZuOi+iE/WdJYAuZ6Y95i4Ohd2Y+9MzIWRR+uGABH4s3Q==", + "version": "1.0.30001593", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001593.tgz", + "integrity": "sha512-UWM1zlo3cZfkpBysd7AS+z+v007q9G1+fLTUU42rQnY6t2axoogPW/xol6T7juU5EUoOhML4WgBIdG+9yYqAjQ==", "dev": true, "funding": [ { @@ -2591,18 +2626,20 @@ } }, "node_modules/define-data-property": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz", - "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "dependencies": { + "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.2", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-lazy-prop": { @@ -2704,9 +2741,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.665", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.665.tgz", - "integrity": "sha512-UpyCWObBoD+nSZgOC2ToaIdZB0r9GhqT2WahPKiSki6ckkSuKhQNso8V2PrFcHBMleI/eqbKgVQgVC4Wni4ilw==", + "version": "1.4.690", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.690.tgz", + "integrity": "sha512-+2OAGjUx68xElQhydpcbqH50hE8Vs2K6TkAeLhICYfndb67CVH0UsZaijmRUE3rHlIxU1u0jxwhgVe6fK3YANA==", "dev": true }, "node_modules/elementtree": { @@ -2756,6 +2793,18 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", @@ -3499,14 +3548,14 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.18.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz", + "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==", "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", @@ -3753,9 +3802,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/follow-redirects": { @@ -4082,21 +4131,21 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -4654,12 +4703,12 @@ "dev": true }, "node_modules/isbinaryfile": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.0.tgz", - "integrity": "sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", + "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", "dev": true, "engines": { - "node": ">= 14.0.0" + "node": ">= 18.0.0" }, "funding": { "url": "https://github.com/sponsors/gjtorikian/" @@ -4954,9 +5003,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz", - "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==", + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, @@ -5093,9 +5142,9 @@ } }, "node_modules/mlly": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.5.0.tgz", - "integrity": "sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", + "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", "dev": true, "dependencies": { "acorn": "^8.11.3", @@ -5208,9 +5257,9 @@ } }, "node_modules/npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { "path-key": "^4.0.0" @@ -5812,9 +5861,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, "dependencies": { "bytes": "3.1.2", @@ -6272,9 +6321,9 @@ "dev": true }, "node_modules/sass": { - "version": "1.70.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz", - "integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==", + "version": "1.71.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz", + "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -6481,12 +6530,12 @@ } }, "node_modules/side-channel": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", - "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.4", "object-inspect": "^1.13.1" @@ -7002,13 +7051,13 @@ } }, "node_modules/unplugin": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.7.1.tgz", - "integrity": "sha512-JqzORDAPxxs8ErLV4x+LL7bk5pk3YlcWqpSNsIkAZj972KzFZLClc/ekppahKkOczGkwIG6ElFgdOgOlK4tXZw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.8.0.tgz", + "integrity": "sha512-yGEQsodWICmgt7asHF7QzqDZYeEP9h14vyd9Lul98UnYf29pLZZLwI09z2QdTjwU/FCkum1SRvsK7cx232X8NA==", "dev": true, "dependencies": { "acorn": "^8.11.3", - "chokidar": "^3.5.3", + "chokidar": "^3.6.0", "webpack-sources": "^3.2.3", "webpack-virtual-modules": "^0.6.1" } @@ -7227,55 +7276,55 @@ } }, "node_modules/vue/node_modules/@vue/compiler-core": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.15.tgz", - "integrity": "sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.19.tgz", + "integrity": "sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==", "dependencies": { - "@babel/parser": "^7.23.6", - "@vue/shared": "3.4.15", + "@babel/parser": "^7.23.9", + "@vue/shared": "3.4.19", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.0.2" } }, "node_modules/vue/node_modules/@vue/compiler-dom": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.15.tgz", - "integrity": "sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz", + "integrity": "sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==", "dependencies": { - "@vue/compiler-core": "3.4.15", - "@vue/shared": "3.4.15" + "@vue/compiler-core": "3.4.19", + "@vue/shared": "3.4.19" } }, "node_modules/vue/node_modules/@vue/compiler-sfc": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.15.tgz", - "integrity": "sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==", - "dependencies": { - "@babel/parser": "^7.23.6", - "@vue/compiler-core": "3.4.15", - "@vue/compiler-dom": "3.4.15", - "@vue/compiler-ssr": "3.4.15", - "@vue/shared": "3.4.15", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz", + "integrity": "sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==", + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/compiler-core": "3.4.19", + "@vue/compiler-dom": "3.4.19", + "@vue/compiler-ssr": "3.4.19", + "@vue/shared": "3.4.19", "estree-walker": "^2.0.2", - "magic-string": "^0.30.5", + "magic-string": "^0.30.6", "postcss": "^8.4.33", "source-map-js": "^1.0.2" } }, "node_modules/vue/node_modules/@vue/compiler-ssr": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.15.tgz", - "integrity": "sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz", + "integrity": "sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==", "dependencies": { - "@vue/compiler-dom": "3.4.15", - "@vue/shared": "3.4.15" + "@vue/compiler-dom": "3.4.19", + "@vue/shared": "3.4.19" } }, "node_modules/vue/node_modules/@vue/shared": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.15.tgz", - "integrity": "sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==" + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz", + "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==" }, "node_modules/vue3-apexcharts": { "version": "1.5.2", diff --git a/src/api/core.ts b/src/api/core.ts index 878ec9d3..7e6205ae 100644 --- a/src/api/core.ts +++ b/src/api/core.ts @@ -5,6 +5,17 @@ import type { AutomatedTask } from "@/types/tasks"; const baseUrl = "/core"; +export async function fetchCustomFields(params = {}) { + try { + const { data } = await axios.get(`${baseUrl}/customfields/`, { + params: params, + }); + return data; + } catch (e) { + console.error(e); + } +} + export async function fetchURLActions(params = {}) { const { data } = await axios.get(`${baseUrl}/urlaction/`, { params: params, @@ -65,7 +76,6 @@ export async function runServerTask(id: number): Promise { } export interface ServerScriptRunRequest { - id: number; timeout: number; env_vars: string[]; args: string[]; @@ -74,7 +84,7 @@ export interface ServerScriptRunRequest { export async function runServerScript( id: number, payload: ServerScriptRunRequest, -): Promise { +): Promise { const { data } = await axios.post( `${baseUrl}/serverscript/${id}/run/`, payload, diff --git a/src/components/agents/AutomatedTasksTab.vue b/src/components/agents/AutomatedTasksTab.vue index e9a6e1ca..857622eb 100644 --- a/src/components/agents/AutomatedTasksTab.vue +++ b/src/components/agents/AutomatedTasksTab.vue @@ -441,7 +441,7 @@ export default { try { const result = await fetchAgentTasks(selectedAgent.value); tasks.value = result.filter( - (task) => task.sync_status !== "pendingdeletion" + (task) => task.sync_status !== "pendingdeletion", ); } catch (e) { console.error(e); @@ -495,7 +495,7 @@ export default { try { const result = await runTask( task.id, - task.policy ? { agent_id: selectedAgent.value } : {} + task.policy ? { agent_id: selectedAgent.value } : {}, ); notifySuccess(result); } catch (e) { @@ -508,7 +508,9 @@ export default { $q.dialog({ component: AutomatedTaskForm, componentProps: { - parent: { agent: selectedAgent.value }, + type: "agent", + parent: selectedAgent.value, + plat: agentPlatform.value, }, }).onOk(() => { getTasks(); @@ -522,7 +524,9 @@ export default { component: AutomatedTaskForm, componentProps: { task: task, - parent: { agent: selectedAgent.value }, + type: "agent", + parent: selectedAgent.value, + plat: agentPlatform.value, }, }).onOk(() => { getTasks(); diff --git a/src/components/automation/PolicyAutomatedTasksTab.vue b/src/components/automation/PolicyAutomatedTasksTab.vue index 57ffc6a1..acba8ad8 100644 --- a/src/components/automation/PolicyAutomatedTasksTab.vue +++ b/src/components/automation/PolicyAutomatedTasksTab.vue @@ -293,7 +293,8 @@ export default { .dialog({ component: AutomatedTaskForm, componentProps: { - parent: { policy: this.selectedPolicy }, + parent: this.selectedPolicy, + type: "policy", }, }) .onOk(this.getTasks); @@ -304,7 +305,8 @@ export default { component: AutomatedTaskForm, componentProps: { task: task, - parent: { policy: this.selectedPolicy }, + parent: this.selectedPolicy, + type: "policy", }, }) .onOk(this.getTasks); diff --git a/src/components/checks/ScriptCheck.vue b/src/components/checks/ScriptCheck.vue index 38c4e779..9556fdce 100644 --- a/src/components/checks/ScriptCheck.vue +++ b/src/components/checks/ScriptCheck.vue @@ -152,7 +152,8 @@ export default { defaultTimeout, defaultArgs, defaultEnvVars, - } = useScriptDropdown(props.check ? props.check.script : undefined, { + } = useScriptDropdown({ + script: props.check ? props.check.script : undefined, onMount: true, }); diff --git a/src/components/modals/agents/RunScript.vue b/src/components/modals/agents/RunScript.vue index bd47d474..5423e01f 100644 --- a/src/components/modals/agents/RunScript.vue +++ b/src/components/modals/agents/RunScript.vue @@ -41,7 +41,7 @@ - diff --git a/src/components/modals/alerts/AlertTemplateForm.vue b/src/components/modals/alerts/AlertTemplateForm.vue index 871e8074..07ce6870 100644 --- a/src/components/modals/alerts/AlertTemplateForm.vue +++ b/src/components/modals/alerts/AlertTemplateForm.vue @@ -159,19 +159,46 @@ + + + + + + + + 1" flat color="primary" - @click="$refs.stepper.previous()" + @click="stepper?.previous()" label="Back" class="q-mr-xs" /> @@ -688,8 +742,9 @@ diff --git a/src/components/tasks/AutomatedTaskForm.vue b/src/components/tasks/AutomatedTaskForm.vue index 7867905b..975f471a 100644 --- a/src/components/tasks/AutomatedTaskForm.vue +++ b/src/components/tasks/AutomatedTaskForm.vue @@ -106,7 +106,13 @@ class="col-3" label="Select script" v-model="script" - :options="filteredScriptOptions" + :options=" + type === 'policy' + ? scriptOptions + : type === 'server' + ? filterByPlatformOptions('linux') + : filterByPlatformOptions(plat) + " filled mapOptions filterable @@ -659,12 +665,12 @@ placeholder="e.g. 6h (6 hours) or 1d (1 day)" lazy-rules :rules="[ - (val) => + (val: string) => validateTimePeriod(val) || 'Valid values are 1-3 digits followed by (D|d|H|h|M|m|S|s)', - (val) => + (val: string) => localTask.task_repetition_interval ? !!val : true, // field is required if repetition interval is set - (val) => + (val: string) => convertPeriodToSeconds(val) >= convertPeriodToSeconds( localTask?.task_repetition_interval, @@ -760,12 +766,7 @@ /> // composition imports -import { ref, watch, onMounted, computed, reactive } from "vue"; +import { ref, watch, onMounted, reactive } from "vue"; import { QForm, QStepper, useDialogPluginComponent } from "quasar"; import draggable from "vuedraggable"; import { saveTask, updateTask } from "@/api/tasks"; -import { useScriptDropdown } from "@/composables/scripts.ts"; +import { useScriptDropdown } from "@/composables/scripts"; import { useCheckDropdown } from "@/composables/checks"; import { useCustomFieldDropdown } from "@/composables/core"; import { notifySuccess, notifyError } from "@/utils/notify"; @@ -802,7 +803,7 @@ import { convertToBitArray, convertFromBitArray, formatDateInputField, - removeExtraOptionCategories, + copyObjectWithoutKeys, } from "@/utils/format"; // ui imports @@ -815,6 +816,7 @@ import type { AutomatedTaskForDB, AutomatedTaskCommandActionShellType, } from "@/types/tasks"; +import type { AgentPlatformType } from "@/types/agents"; // static data const severityOptions = [ @@ -884,6 +886,17 @@ const taskInstancePolicyOptions = [ { label: "Stop Existing", value: 3 }, ]; +// emits +defineEmits([...useDialogPluginComponent.emits]); + +// props +const props = defineProps<{ + parent?: number | string; // parent policy or agent for task + type: "agent" | "policy" | "server"; + task?: AutomatedTaskForDB; // only for editing + plat?: AgentPlatformType; // filters scripts options base on plat +}>(); + // setup quasar dialog const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent(); @@ -891,40 +904,15 @@ const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent(); const { script, scriptOptions, + filterByPlatformOptions, defaultTimeout, defaultArgs, defaultEnvVars, scriptName, -} = useScriptDropdown(undefined, { +} = useScriptDropdown({ onMount: true, }); -const filteredScriptOptions = computed(() => { - if (props.type !== "server") { - return scriptOptions.value; - } else { - return removeExtraOptionCategories( - scriptOptions.value.filter( - (script) => - script.category || - !script.supported_platforms || - script.supported_platforms.length === 0 || - script.supported_platforms.includes("linux"), - ), - ); - } -}); - -// emits -defineEmits([...useDialogPluginComponent.emits]); - -// props -const props = defineProps<{ - parent?: number; // parent policy or agent for task - type: "agent" | "policy" | "server"; - task?: AutomatedTask; // only for editing -}>(); - // set defaultTimeout to 30 defaultTimeout.value = 30; @@ -932,38 +920,38 @@ const { checkOptions, getCheckOptions } = useCheckDropdown(); const { customFieldOptions } = useCustomFieldDropdown({ onMount: true }); // add task logic -const localTask = props.task - ? reactive(Object.assign({}, props.task)) - : reactive({ +const localTask: AutomatedTask = props.task + ? reactive(Object.assign({}, processTaskDatafromDB(props.task))) + : (reactive({ id: 0, policy: props.type === "policy" ? props.parent : undefined, agent: props.type === "agent" ? props.parent : undefined, server_task: props.type === "server", crontab_schedule: "", actions: [] as AutomatedTaskAction[], - assigned_check: null, - custom_field: null, - name: null, - expire_date: null, + assigned_check: undefined, + custom_field: undefined, + name: "", + expire_date: undefined, run_time_date: formatDateInputField(Date.now()), - run_time_bit_weekdays: [], + run_time_bit_weekdays: [] as number[], weekly_interval: 1, daily_interval: 1, - monthly_months_of_year: [], - monthly_days_of_month: [], - monthly_weeks_of_month: [], + monthly_months_of_year: [] as number[], + monthly_days_of_month: [] as number[], + monthly_weeks_of_month: [] as number[], task_instance_policy: 0, - task_repetition_interval: null, - task_repetition_duration: null, + task_repetition_interval: undefined, + task_repetition_duration: undefined, stop_task_at_duration_end: false, - random_task_delay: null, + random_task_delay: undefined, remove_if_not_scheduled: false, run_asap_after_missed: true, task_type: "daily", alert_severity: "info", collector_all_output: false, continue_on_error: true, - }); + }) as AutomatedTask); const actionType = ref("script"); const command = ref(""); @@ -1078,7 +1066,7 @@ function processTaskDataforDB(taskData: AutomatedTask): AutomatedTaskForDB { }, } as AutomatedTaskForDB; // Add Z back to run_time_date and expires_date - data.run_time_date += "Z"; + if (!taskData.server_task) data.run_time_date += "Z"; if (taskData.expire_date) data.expire_date += "Z"; @@ -1091,32 +1079,48 @@ function processTaskDataforDB(taskData: AutomatedTask): AutomatedTaskForDB { } // runs when editing a task to convert values to be compatible with quasar -function processTaskDatafromDB() { +function processTaskDatafromDB(task: AutomatedTaskForDB) { + const convertedTask = copyObjectWithoutKeys(task, [ + "run_time_bit_weekdays", + "monthly_months_of_year", + "monthly_days_of_month", + "monthly_weeks_of_month", + ]) as AutomatedTask; + // converts fields from integers to arrays - localTask.run_time_bit_weekdays = localTask.run_time_bit_weekdays - ? convertToBitArray(localTask.run_time_bit_weekdays) + convertedTask.run_time_bit_weekdays = task.run_time_bit_weekdays + ? convertToBitArray(task.run_time_bit_weekdays) : []; - localTask.monthly_months_of_year = localTask.monthly_months_of_year - ? convertToBitArray(localTask.monthly_months_of_year) + convertedTask.monthly_months_of_year = task.monthly_months_of_year + ? convertToBitArray(task.monthly_months_of_year) : []; - localTask.monthly_days_of_month = localTask.monthly_days_of_month - ? convertToBitArray(localTask.monthly_days_of_month) + convertedTask.monthly_days_of_month = task.monthly_days_of_month + ? convertToBitArray(task.monthly_days_of_month) : []; - localTask.monthly_weeks_of_month = localTask.monthly_weeks_of_month - ? convertToBitArray(localTask.monthly_weeks_of_month) + convertedTask.monthly_weeks_of_month = task.monthly_weeks_of_month + ? convertToBitArray(task.monthly_weeks_of_month) : []; // remove milliseconds and Z to work with native date input - localTask.run_time_date = formatDateInputField(localTask.run_time_date, true); + if (!task.server_task) + convertedTask.run_time_date = formatDateInputField( + convertedTask.run_time_date, + true, + ); - if (localTask.expire_date) - localTask.expire_date = formatDateInputField(localTask.expire_date, true); + if (convertedTask.expire_date) + convertedTask.expire_date = formatDateInputField( + convertedTask.expire_date, + true, + ); // set task type if monthlydow is being used - if (localTask.task_type === "monthlydow") { - localTask.task_type = "monthly"; + if (task.task_type === "monthlydow") { + convertedTask.task_type = "monthly"; monthlyType.value = "weeks"; } + + return convertedTask; } async function submit() { @@ -1133,26 +1137,23 @@ async function submit() { loading.value = false; } -// format task data to match what quasar expects if editing -if (props.task) processTaskDatafromDB(); - watch( () => localTask.task_type, () => { - localTask.assigned_check = null; + localTask.assigned_check = undefined; localTask.run_time_bit_weekdays = []; localTask.remove_if_not_scheduled = false; - localTask.task_repetition_interval = null; - localTask.task_repetition_duration = null; + localTask.task_repetition_interval = undefined; + localTask.task_repetition_duration = undefined; localTask.stop_task_at_duration_end = false; - localTask.random_task_delay = null; + localTask.random_task_delay = undefined; localTask.weekly_interval = 1; localTask.daily_interval = 1; localTask.monthly_months_of_year = []; localTask.monthly_days_of_month = []; localTask.monthly_weeks_of_month = []; localTask.task_instance_policy = 0; - localTask.expire_date = null; + localTask.expire_date = undefined; }, ); @@ -1168,7 +1169,9 @@ const isValidStep1 = ref(true); const isValidStep2 = ref(true); const isValidStep3 = ref(true); -function validateStep(form: QForm, stepper: QStepper) { +function validateStep(form: QForm | null, stepper: QStepper | null) { + if (!stepper) return; + if (step.value === 2) { if (localTask.actions.length > 0) { isValidStep2.value = true; @@ -1180,7 +1183,7 @@ function validateStep(form: QForm, stepper: QStepper) { // steps 1 or 3 } else { - form.validate().then((result: boolean) => { + form?.validate().then((result: boolean) => { if (step.value === 1) { isValidStep1.value = result; if (result) stepper.next(); diff --git a/src/composables/core.js b/src/composables/core.js deleted file mode 100644 index 0df7b09f..00000000 --- a/src/composables/core.js +++ /dev/null @@ -1,28 +0,0 @@ -import { ref, onMounted } from "vue"; -import { fetchCustomFields } from "@/api/core"; -import { formatCustomFieldOptions } from "@/utils/format"; - -export function useCustomFieldDropdown({ onMount = false }) { - const customFieldOptions = ref([]); - - // type can be "client", "site", or "agent" - async function getCustomFieldOptions(model = null, flat = false) { - const params = {}; - - if (model) params[model] = model; - customFieldOptions.value = formatCustomFieldOptions( - await fetchCustomFields(params), - flat - ); - } - - if (onMount) onMounted(getCustomFieldOptions); - - return { - //data - customFieldOptions, - - //methods - getCustomFieldOptions, - }; -} diff --git a/src/composables/core.ts b/src/composables/core.ts new file mode 100644 index 00000000..a7a60173 --- /dev/null +++ b/src/composables/core.ts @@ -0,0 +1,73 @@ +import { ref, computed, onMounted } from "vue"; +import { fetchCustomFields, fetchURLActions } from "@/api/core"; +import { + formatCustomFieldOptions, + formatURLActionOptions, +} from "@/utils/format"; +import type { CustomField } from "@/types/core/customfields"; +import type { URLAction } from "@/types/core/urlactions"; + +export interface UseCustomFieldDropdownParams { + onMount?: boolean; +} + +export function useCustomFieldDropdown(opts: UseCustomFieldDropdownParams) { + const customFieldOptions = ref([] as CustomField[]); + + // type can be "client", "site", or "agent" + async function getCustomFieldOptions(model = null, flat = false) { + const params = {}; + + if (model) params[model] = model; + customFieldOptions.value = formatCustomFieldOptions( + await fetchCustomFields(params), + flat, + ); + } + + const restActionOptions = computed(() => + customFieldOptions.value.filter((option) => option.type === "rest"), + ); + + if (opts.onMount) onMounted(getCustomFieldOptions); + + return { + customFieldOptions, + restActionOptions, + + //methods + getCustomFieldOptions, + }; +} + +export interface UseURLActionDropdownParams { + onMount?: boolean; +} + +export function useURLActionDropdown(opts: UseURLActionDropdownParams) { + const urlActionOptions = ref([] as URLAction[]); + + // type can be "client", "site", or "agent" + async function getURLActionOptions(flat = false) { + const params = {}; + + urlActionOptions.value = formatURLActionOptions( + await fetchURLActions(params), + flat, + ); + } + + const restActionOptions = computed(() => + urlActionOptions.value.filter((action) => action.action_type === "rest"), + ); + + if (opts.onMount) onMounted(getURLActionOptions); + + return { + urlActionOptions, + restActionOptions, + + //methods + getURLActionOptions, + }; +} diff --git a/src/composables/script.ts b/src/composables/script.ts deleted file mode 100644 index da172d29..00000000 --- a/src/composables/script.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { ref, watch, computed, onMounted } from "vue"; -import { useStore } from "vuex"; -import { fetchScripts } from "@/api/scripts"; -import { formatScriptOptions } from "@/utils/format"; - -export interface useScriptDropdownParams { - script?: number; // set a selected script on init - onMount?: boolean; // loads script options on mount - onlyServerScripts?: boolean; // only return scripts that can be run on the server -} - -// script dropdown -export function useScriptDropdown(opts: useScriptDropdownParams) { - const scriptOptions = ref([]); - const defaultTimeout = ref(30); - const defaultArgs = ref([] as string[]); - const defaultEnvVars = ref([] as string[]); - const script = ref(opts.script); - const syntax = ref(""); - const link = ref(""); - const baseUrl = - "https://github.com/amidaware/community-scripts/blob/main/scripts/"; - - // specify parameters to filter out community scripts - async function getScriptOptions(showCommunityScripts = false) { - scriptOptions.value = Object.freeze( - formatScriptOptions(await fetchScripts({ showCommunityScripts })), - ); - } - - // watch scriptPk for changes and update the default timeout and args - watch([script, scriptOptions], () => { - if (script.value && scriptOptions.value.length > 0) { - const tmpScript = scriptOptions.value.find( - (i) => i.value === script.value, - ); - defaultTimeout.value = tmpScript.timeout; - defaultArgs.value = tmpScript.args; - defaultEnvVars.value = tmpScript.env_vars; - syntax.value = tmpScript.syntax; - link.value = - tmpScript.script_type === "builtin" - ? `${baseUrl}${tmpScript.filename}` - : null; - } - }); - - // vuex show community scripts - const store = useStore(); - const showCommunityScripts = computed(() => store.state.showCommunityScripts); - - function filterOptions({ communityScripts, serverScripts }); - if (opts.onMount) - onMounted(() => getScriptOptions(showCommunityScripts.value)); - - return { - //data - script, - scriptOptions, - defaultTimeout, - defaultArgs, - defaultEnvVars, - syntax, - link, - - //methods - getScriptOptions, - }; -} - -export const shellOptions = [ - { label: "Powershell", value: "powershell" }, - { label: "Batch", value: "cmd" }, - { label: "Python", value: "python" }, - { label: "Shell", value: "shell" }, -]; diff --git a/src/composables/scripts.js b/src/composables/scripts.js deleted file mode 100644 index 031b21e6..00000000 --- a/src/composables/scripts.js +++ /dev/null @@ -1,70 +0,0 @@ -import { ref, watch, computed, onMounted } from "vue"; -import { useStore } from "vuex"; -import { fetchScripts } from "@/api/scripts"; -import { formatScriptOptions } from "@/utils/format"; - -// script dropdown -export function useScriptDropdown(setScript = null, { onMount = false } = {}) { - const scriptOptions = ref([]); - const defaultTimeout = ref(30); - const defaultArgs = ref([]); - const defaultEnvVars = ref([]); - const script = ref(setScript); - const syntax = ref(""); - const link = ref(""); - const baseUrl = - "https://github.com/amidaware/community-scripts/blob/main/scripts/"; - - // specify parameters to filter out community scripts - async function getScriptOptions(showCommunityScripts = false) { - scriptOptions.value = Object.freeze( - formatScriptOptions(await fetchScripts({ showCommunityScripts })), - ); - } - - // watch scriptPk for changes and update the default timeout and args - watch([script, scriptOptions], () => { - if (script.value && scriptOptions.value.length > 0) { - const tmpScript = scriptOptions.value.find( - (i) => i.value === script.value, - ); - defaultTimeout.value = tmpScript.timeout; - defaultArgs.value = tmpScript.args; - defaultEnvVars.value = tmpScript.env_vars; - syntax.value = tmpScript.syntax; - link.value = - tmpScript.script_type === "builtin" - ? `${baseUrl}${tmpScript.filename}` - : null; - } - }); - - // vuex show community scripts - const store = useStore(); - const showCommunityScripts = computed(() => store.state.showCommunityScripts); - - if (onMount) onMounted(() => getScriptOptions(showCommunityScripts.value)); - - return { - //data - script, - scriptOptions, - defaultTimeout, - defaultArgs, - defaultEnvVars, - syntax, - link, - - //methods - getScriptOptions, - }; -} - -export const shellOptions = [ - { label: "Powershell", value: "powershell" }, - { label: "Batch", value: "cmd" }, - { label: "Python", value: "python" }, - { label: "Shell", value: "shell" }, - { label: "Nushell", value: "nushell" }, - { label: "Deno", value: "deno" }, -]; diff --git a/src/composables/scripts.ts b/src/composables/scripts.ts index 412b2955..0faff2ad 100644 --- a/src/composables/scripts.ts +++ b/src/composables/scripts.ts @@ -1,26 +1,31 @@ import { ref, watch, computed, onMounted } from "vue"; import { useStore } from "vuex"; import { fetchScripts } from "@/api/scripts"; -import { formatScriptOptions } from "@/utils/format.ts"; - +import { + formatScriptOptions, + removeExtraOptionCategories, +} from "@/utils/format"; import type { Script } from "@/types/scripts"; +import { AgentPlatformType } from "@/types/agents"; export interface ScriptOption extends Script { label: string; value: number; } +export interface useScriptDropdownParams { + script?: number; // set a selected script on init + onMount?: boolean; // loads script options on mount +} + // script dropdown -export function useScriptDropdown( - setScript = undefined, - { onMount = false } = {}, -) { - const scriptOptions = ref([] as readonly ScriptOption[]); - const scriptName = ref(""); +export function useScriptDropdown(opts: useScriptDropdownParams) { + const scriptOptions = ref([] as ScriptOption[]); const defaultTimeout = ref(30); const defaultArgs = ref([] as string[]); const defaultEnvVars = ref([] as string[]); - const script = ref(setScript); + const script = ref(opts.script); + const scriptName = ref(""); const syntax = ref(""); const link = ref(""); const baseUrl = @@ -29,10 +34,8 @@ export function useScriptDropdown( // specify parameters to filter out community scripts async function getScriptOptions(showCommunityScripts = false) { scriptOptions.value = Object.freeze( - formatScriptOptions( - await fetchScripts({ showCommunityScripts }), - ) as ScriptOption[], - ); + formatScriptOptions(await fetchScripts({ showCommunityScripts })), + ) as ScriptOption[]; } // watch scriptPk for changes and update the default timeout and args @@ -41,12 +44,13 @@ export function useScriptDropdown( const tmpScript = scriptOptions.value.find( (i) => i.value === script.value, ); + if (tmpScript) { - scriptName.value = tmpScript.label; defaultTimeout.value = tmpScript.default_timeout; defaultArgs.value = tmpScript.args; defaultEnvVars.value = tmpScript.env_vars; - syntax.value = tmpScript?.syntax; + syntax.value = tmpScript.syntax; + scriptName.value = tmpScript.name; link.value = tmpScript.script_type === "builtin" ? `${baseUrl}${tmpScript.filename}` @@ -59,21 +63,64 @@ export function useScriptDropdown( const store = useStore(); const showCommunityScripts = computed(() => store.state.showCommunityScripts); - if (onMount) onMounted(() => getScriptOptions(showCommunityScripts.value)); + // filter for only getting server tasks + const serverScriptOptions = computed(() => + removeExtraOptionCategories( + scriptOptions.value.filter( + (script) => + script.category || + !script.supported_platforms || + script.supported_platforms.length === 0 || + script.supported_platforms.includes("linux"), + ), + ), + ); + + const filterByPlatformOptions = (plat: AgentPlatformType | undefined) => { + if (!plat) { + return scriptOptions.value; + } + + return removeExtraOptionCategories( + scriptOptions.value.filter( + (script) => + script.category || + !script.supported_platforms || + script.supported_platforms.length === 0 || + script.supported_platforms.includes(plat), + ), + ); + }; + + function reset() { + defaultTimeout.value = 30; + defaultArgs.value = []; + defaultEnvVars.value = []; + script.value = undefined; + syntax.value = ""; + link.value = ""; + } + + if (opts.onMount) + onMounted(() => getScriptOptions(showCommunityScripts.value)); return { //data script, - scriptOptions, defaultTimeout, defaultArgs, defaultEnvVars, + scriptName, syntax, link, - scriptName, + + scriptOptions, // unfiltered options + serverScriptOptions, //only scripts that can run on server //methods getScriptOptions, + filterByPlatformOptions, + reset, }; } @@ -82,4 +129,6 @@ export const shellOptions = [ { label: "Batch", value: "cmd" }, { label: "Python", value: "python" }, { label: "Shell", value: "shell" }, + { label: "Nushell", value: "nushell" }, + { label: "Deno", value: "deno" }, ]; diff --git a/src/types/agents.ts b/src/types/agents.ts index 59e73420..f6cc6986 100644 --- a/src/types/agents.ts +++ b/src/types/agents.ts @@ -6,4 +6,5 @@ export interface Agent { hostname: string; client: string; site: string; + plat: AgentPlatformType; } diff --git a/src/types/alerts.ts b/src/types/alerts.ts index 98a6a18e..d47c5406 100644 --- a/src/types/alerts.ts +++ b/src/types/alerts.ts @@ -1,4 +1,4 @@ -export type AlertSeverity = "error" | "warning" | "informational"; +export type AlertSeverity = "error" | "warning" | "info"; export type ActionType = "script" | "server" | "rest"; export interface AlertTemplate { id: number; @@ -6,11 +6,13 @@ export interface AlertTemplate { is_active: boolean; action_type: ActionType; action?: number; + action_rest?: number; action_args: string[]; action_env_vars: string[]; action_timeout: number; resolved_action_type: ActionType; resolved_action?: number; + resolved_action_rest?: number; resolved_action_args: string[]; resolved_action_env_vars: string[]; resolved_action_timeout: number; diff --git a/src/types/tasks.ts b/src/types/tasks.ts index e7c12ea8..117898dc 100644 --- a/src/types/tasks.ts +++ b/src/types/tasks.ts @@ -62,12 +62,8 @@ export interface AutomatedTaskBase { win_task_name?: string; run_time_date: string; expire_date?: string; - daily_interval?: string; - run_time_bit_weekdays: number[]; + daily_interval?: number; weekly_interval?: number; - monthly_days_of_month: number[]; - monthly_months_of_year: number[]; - monthly_weeks_of_month: number[]; task_repetition_duration?: string; task_repetition_interval?: string; stop_task_at_duration_end?: boolean; @@ -76,22 +72,29 @@ export interface AutomatedTaskBase { run_asap_after_missed?: boolean; task_instance_policy?: number; crontab_schedule?: string; - task_result: TaskResult; + task_result?: TaskResult; } -export interface AutomatedTaskPolicy extends AutomatedTaskBase { +export interface AutomatedTaskForUIBase extends AutomatedTaskBase { + run_time_bit_weekdays: number[]; + monthly_days_of_month: number[]; + monthly_months_of_year: number[]; + monthly_weeks_of_month: number[]; +} + +export interface AutomatedTaskPolicy extends AutomatedTaskForUIBase { policy: number; task_type: AgentTaskType; server_task: false; } -export interface AutomatedTaskAgent extends AutomatedTaskBase { +export interface AutomatedTaskAgent extends AutomatedTaskForUIBase { agent: number; task_type: AgentTaskType; server_task: false; } -export interface AutomatedTaskServer extends AutomatedTaskBase { +export interface AutomatedTaskServer extends AutomatedTaskForUIBase { task_type: ServerTaskType; server_task: true; } @@ -101,37 +104,31 @@ export type AutomatedTask = | AutomatedTaskPolicy | AutomatedTaskServer; -export interface AutomatedTaskForDB { - id: number; - policy?: number; - agent?: number; +export interface AutomatedTaskForDBBase extends AutomatedTaskBase { + run_time_bit_weekdays: number; + monthly_days_of_month: number; + monthly_months_of_year: number; + monthly_weeks_of_month: number; +} + +export interface AutomatedTaskPolicyForDB extends AutomatedTaskForDBBase { + policy: number; task_type: AgentTaskType; - server_task: boolean; - crontab_schedule?: string; - custom_field?: number; - actions: AutomatedTaskAction[]; - assigned_check?: number; - name: string; - collector_all_output: boolean; - continue_on_error: boolean; - alert_severity: AlertSeverity; - email_alert: boolean; - text_alert: boolean; - dashboard_alert: boolean; - win_task_name: string; - run_time_date: string; - expire_date?: string; - daily_interval?: string; - run_time_bit_weekdays?: number; - weekly_interval?: number; - monthly_days_of_month?: number; - monthly_months_of_year?: number; - monthly_weeks_of_month?: number; - task_repetition_duration?: string; - task_repetition_interval?: string; - stop_task_at_duration_end?: boolean; - random_task_delay?: string; - remove_if_not_scheduled?: boolean; - run_asap_after_missed?: boolean; - task_instance_policy?: number; + server_task: false; } + +export interface AutomatedTaskAgentForDB extends AutomatedTaskForDBBase { + agent: number; + task_type: AgentTaskType; + server_task: false; +} + +export interface AutomatedTaskServerForDB extends AutomatedTaskForDBBase { + task_type: ServerTaskType; + server_task: true; +} + +export type AutomatedTaskForDB = + | AutomatedTaskAgentForDB + | AutomatedTaskPolicyForDB + | AutomatedTaskServerForDB; diff --git a/src/utils/format.js b/src/utils/format.js deleted file mode 100644 index a54288a5..00000000 --- a/src/utils/format.js +++ /dev/null @@ -1,390 +0,0 @@ -import { date } from "quasar"; -import { validateTimePeriod } from "@/utils/validation"; -import trmmLogo from "@/assets/trmm_256.png"; -// dropdown options formatting - -export function removeExtraOptionCategories(array) { - let tmp = []; - // loop through options and if two categories are next to each other remove the top one - for (let i = 0; i < array.length; i++) { - if (i === array.length - 1) { - // check if last item is not a category and add it - if (!array[i].category) tmp.push(array[i]); - } else if (!(array[i].category && array[i + 1].category)) { - tmp.push(array[i]); - } - } - return tmp; -} - -function _formatOptions( - data, - { - label, - value = "id", - flat = false, - allowDuplicates = true, - appendToOptionObject = {}, - }, -) { - if (!flat) - // returns array of options in object format [{label: label, value: 1}] - return data.map((i) => ({ - label: i[label], - value: i[value], - ...appendToOptionObject, - })); - // returns options as an array of strings ["label", "label1"] - else if (!allowDuplicates) return data.map((i) => i[label]); - else { - const options = []; - data.forEach((i) => { - if (!options.includes(i[label])) options.push(i[label]); - }); - return options; - } -} - -export function formatScriptOptions(data) { - let options = []; - let categories = []; - let create_unassigned = false; - data.forEach((script) => { - if (!!script.category && !categories.includes(script.category)) { - categories.push(script.category); - } else if (!script.category) { - create_unassigned = true; - } - }); - - if (create_unassigned) categories.push("Unassigned"); - - categories.sort().forEach((cat) => { - options.push({ category: cat }); - let tmp = []; - data.forEach((script) => { - if (script.category === cat) { - tmp.push({ - img_right: script.script_type === "builtin" ? trmmLogo : undefined, - label: script.name, - value: script.id, - timeout: script.default_timeout, - args: script.args, - env_vars: script.env_vars, - filename: script.filename, - syntax: script.syntax, - script_type: script.script_type, - shell: script.shell, - supported_platforms: script.supported_platforms, - }); - } else if (cat === "Unassigned" && !script.category) { - tmp.push({ - label: script.name, - value: script.id, - timeout: script.default_timeout, - args: script.args, - env_vars: script.env_vars, - filename: script.filename, - syntax: script.syntax, - script_type: script.script_type, - shell: script.shell, - supported_platforms: script.supported_platforms, - }); - } - }); - const sorted = tmp.sort((a, b) => a.label.localeCompare(b.label)); - options.push(...sorted); - }); - - return options; -} - -export function formatAgentOptions( - data, - flat = false, - value_field = "agent_id", -) { - if (flat) { - // returns just agent hostnames in array - return _formatOptions(data, { - label: "hostname", - value: value_field, - flat: true, - allowDuplicates: false, - }); - } else { - // returns options with categories in object format - let options = []; - const agents = data.map((agent) => ({ - label: agent.hostname, - value: agent[value_field], - cat: `${agent.client} > ${agent.site}`, - })); - - let categories = []; - agents.forEach((option) => { - if (!categories.includes(option.cat)) { - categories.push(option.cat); - } - }); - - categories.sort().forEach((cat) => { - options.push({ category: cat }); - let tmp = []; - agents.forEach((agent) => { - if (agent.cat === cat) { - tmp.push(agent); - } - }); - - const sorted = tmp.sort((a, b) => a.label.localeCompare(b.label)); - options.push(...sorted); - }); - - return options; - } -} - -export function formatCustomFieldOptions(data, flat = false) { - if (flat) { - return _formatOptions(data, { label: "name", flat: true }); - } else { - const categories = ["Client", "Site", "Agent"]; - const options = []; - - categories.forEach((cat) => { - options.push({ category: cat }); - const tmp = []; - data.forEach((custom_field) => { - if (custom_field.model === cat.toLowerCase()) { - tmp.push({ - label: custom_field.name, - value: custom_field.id, - cat: cat, - }); - } - }); - - const sorted = tmp.sort((a, b) => a.label.localeCompare(b.label)); - options.push(...sorted); - }); - - return options; - } -} - -export function formatClientOptions(data, flat = false) { - return _formatOptions(data, { label: "name", flat: flat }); -} - -export function formatSiteOptions(data, flat = false) { - const options = []; - - data.forEach((client) => { - options.push({ category: client.name }); - options.push( - ..._formatOptions(client.sites, { - label: "name", - flat: flat, - appendToOptionObject: { cat: client.name }, - }), - ); - }); - - return options; -} - -export function formatUserOptions(data, flat = false) { - return _formatOptions(data, { label: "username", flat: flat }); -} - -export function formatCheckOptions(data, flat = false) { - return _formatOptions(data, { label: "readable_desc", flat: flat }); -} - -export function formatCustomFields(fields, values) { - let tempArray = []; - - for (let field of fields) { - if (field.type === "multiple") { - tempArray.push({ multiple_value: values[field.name], field: field.id }); - } else if (field.type === "checkbox") { - tempArray.push({ bool_value: values[field.name], field: field.id }); - } else { - tempArray.push({ string_value: values[field.name], field: field.id }); - } - } - return tempArray; -} - -export function formatScriptSyntax(syntax) { - let temp = syntax; - temp = temp.replaceAll("<", "<").replaceAll(">", ">"); - temp = temp - .replaceAll("<", '<') - .replaceAll(">", '>'); - temp = temp - .replaceAll("[", '[') - .replaceAll("]", ']'); - temp = temp - .replaceAll("(", '(') - .replaceAll(")", ')'); - temp = temp - .replaceAll("{", '{') - .replaceAll("}", '}'); - temp = temp.replaceAll("\n", "
"); - return temp; -} - -// date formatting - -export function getTimeLapse(unixtime) { - if (date.inferDateFormat(unixtime) === "string") { - unixtime = date.formatDate(unixtime, "X"); - } - var previous = unixtime * 1000; - var current = new Date(); - var msPerMinute = 60 * 1000; - var msPerHour = msPerMinute * 60; - var msPerDay = msPerHour * 24; - var msPerMonth = msPerDay * 30; - var msPerYear = msPerDay * 365; - var elapsed = current - previous; - if (elapsed < msPerMinute) { - return Math.round(elapsed / 1000) + " seconds ago"; - } else if (elapsed < msPerHour) { - return Math.round(elapsed / msPerMinute) + " minutes ago"; - } else if (elapsed < msPerDay) { - return Math.round(elapsed / msPerHour) + " hours ago"; - } else if (elapsed < msPerMonth) { - return Math.round(elapsed / msPerDay) + " days ago"; - } else if (elapsed < msPerYear) { - return Math.round(elapsed / msPerMonth) + " months ago"; - } else { - return Math.round(elapsed / msPerYear) + " years ago"; - } -} - -export function formatDate(dateString, format = "MMM-DD-YYYY HH:mm") { - if (!dateString) return ""; - return date.formatDate(dateString, format); -} - -export function getNextAgentUpdateTime() { - const d = new Date(); - let ret; - if (d.getMinutes() <= 35) { - ret = d.setMinutes(35); - } else { - ret = date.addToDate(d, { hours: 1 }); - ret.setMinutes(35); - } - const a = date.formatDate(ret, "MMM D, YYYY"); - const b = date.formatDate(ret, "h:mm A"); - return `${a} at ${b}`; -} - -// converts a date with timezone to local for html native datetime fields -> YYYY-MM-DD HH:mm:ss -export function formatDateInputField(isoDateString, noTimezone = false) { - if (noTimezone) { - isoDateString = isoDateString.replace("Z", ""); - } - return date.formatDate(isoDateString, "YYYY-MM-DDTHH:mm"); -} - -// converts a local date string "YYYY-MM-DDTHH:mm:ss" to an iso date string with the local timezone -export function formatDateStringwithTimezone(localDateString) { - return date.formatDate(localDateString, "YYYY-MM-DDTHH:mm:ssZ"); -} -// string formatting - -export function capitalize(string) { - return string[0].toUpperCase() + string.substring(1); -} - -export function formatTableColumnText(text) { - let string = ""; - // split at underscore if exists - const words = text.split("_"); - words.forEach((word) => (string = string + " " + capitalize(word))); - - return string.trim(); -} - -export function truncateText(txt, chars) { - if (!txt) return; - - return txt.length >= chars ? txt.substring(0, chars) + "..." : txt; -} - -export function bytes2Human(bytes) { - if (bytes == 0) return "0B"; - const k = 1024; - const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; -} - -export function convertMemoryToPercent(percent, memory) { - const mb = memory * 1024; - return Math.ceil((percent * mb) / 100).toLocaleString(); -} - -// convert time period(str) to seconds(int) (3h -> 10800) used for comparing time intervals -export function convertPeriodToSeconds(period) { - if (!validateTimePeriod(period)) { - console.error("Time Period is invalid"); - return NaN; - } - - if (period.toUpperCase().includes("S")) - // remove last letter from string and return since already in seconds - return parseInt(period.slice(0, -1)); - else if (period.toUpperCase().includes("M")) - // remove last letter from string and multiple by 60 to get seconds - return parseInt(period.slice(0, -1)) * 60; - else if (period.toUpperCase().includes("H")) - // remove last letter from string and multiple by 60 twice to get seconds - return parseInt(period.slice(0, -1)) * 60 * 60; - else if (period.toUpperCase().includes("D")) - // remove last letter from string and multiply by 24 and 60 twice to get seconds - return parseInt(period.slice(0, -1)) * 24 * 60 * 60; -} - -// takes an integer and converts it to an array in binary format. i.e: 13 -> [8, 4, 1] -// Needed to work with multi-select fields in tasks form -export function convertToBitArray(number) { - let bitArray = []; - let binary = number.toString(2); - for (let i = 0; i < binary.length; ++i) { - if (binary[i] !== "0") { - // last binary digit - if (binary.slice(i).length === 1) { - bitArray.push(1); - } else { - bitArray.push( - parseInt(binary.slice(i), 2) - parseInt(binary.slice(i + 1), 2), - ); - } - } - } - return bitArray; -} - -// takes an array of integers and adds them together -export function convertFromBitArray(array) { - let result = 0; - for (let i = 0; i < array.length; i++) { - result += array[i]; - } - return result; -} - -export function convertCamelCase(str) { - return str - .replace(/[^a-zA-Z0-9]+/g, " ") - .replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) { - return index == 0 ? word.toLowerCase() : word.toUpperCase(); - }) - .replace(/\s+/g, ""); -} diff --git a/src/utils/format.ts b/src/utils/format.ts index 1b7290cc..eea3b044 100644 --- a/src/utils/format.ts +++ b/src/utils/format.ts @@ -8,6 +8,7 @@ import type { Client } from "@/types/clients"; import type { User } from "@/types/accounts"; import type { Check } from "@/types/checks"; import { CustomField, CustomFieldValue } from "@/types/core/customfields"; +import { URLAction } from "@/types/core/urlactions"; // dropdown options formatting export interface SelectOptionCategory { category: string; @@ -15,8 +16,10 @@ export interface SelectOptionCategory { export interface OptionWithoutCategory { label: string; - value: unknown; - [x: string]: unknown; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + value: any; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [x: string]: any; } export type Option = OptionWithoutCategory | SelectOptionCategory; @@ -40,10 +43,12 @@ export interface FormatOptionsParams { value?: string; flat?: boolean; allowDuplicates?: boolean; - appendToOptionObject?: object; + appendToOptionObject?: { [x: string]: never }; + copyPropertiesList?: string[]; } -function _formatOptions( +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function _formatOptions( data: T[], { label, @@ -51,15 +56,25 @@ function _formatOptions( flat = false, allowDuplicates = true, appendToOptionObject = {}, + copyPropertiesList = [], }: FormatOptionsParams, -) { +): Option[] | string[] { if (!flat) // returns array of options in object format [{label: label, value: 1}] - return data.map((i) => ({ - label: i[label], - value: i[value], - ...appendToOptionObject, // will add properties to the options object - })); + return data.map((i) => { + const option = { + label: i[label], + value: i[value], + ...appendToOptionObject, // will add properties to the options object + } as Option; + + copyPropertiesList.forEach((prop) => { + if (Object.hasOwn(i, prop)) { + option[prop] = i[prop]; + } + }); + return option; + }); // returns options as an array of strings ["label", "label1"] else if (!allowDuplicates) return data.map((i) => i[label]); else { @@ -228,6 +243,14 @@ export function formatCheckOptions(data: Check[], flat = false) { return _formatOptions(data, { label: "readable_desc", flat: flat }); } +export function formatURLActionOptions(data: URLAction[], flat = false) { + return _formatOptions(data, { + label: "name", + flat: flat, + copyPropertiesList: ["action_type"], + }); +} + export function formatCustomFields( fields: CustomField[], values: CustomFieldValue[], @@ -369,7 +392,7 @@ export function convertMemoryToPercent(percent: number, memory: number) { export function convertPeriodToSeconds(period: string) { if (!validateTimePeriod(period)) { console.error("Time Period is invalid"); - return NaN; + return 0; } if (period.toUpperCase().includes("S")) @@ -384,6 +407,8 @@ export function convertPeriodToSeconds(period: string) { else if (period.toUpperCase().includes("D")) // remove last letter from string and multiply by 24 and 60 twice to get seconds return parseInt(period.slice(0, -1)) * 24 * 60 * 60; + + return 0; } // takes an integer and converts it to an array in binary format. i.e: 13 -> [8, 4, 1] @@ -423,3 +448,17 @@ export function convertCamelCase(str: string) { }) .replace(/\s+/g, ""); } + +export function copyObjectWithoutKeys( + objToCopy: object, + keysToExclude: string[], +): object { + const copied = Object.entries(objToCopy).reduce((obj, [key, value]) => { + if (!keysToExclude.includes(key)) { + obj[key] = value; + } + return obj; + }, {}); + + return copied; +} diff --git a/src/utils/notify.js b/src/utils/notify.ts similarity index 61% rename from src/utils/notify.js rename to src/utils/notify.ts index 29c5f81e..bc497634 100644 --- a/src/utils/notify.js +++ b/src/utils/notify.ts @@ -1,6 +1,6 @@ import { Notify } from "quasar"; -export function notifySuccess(msg, timeout = 2000) { +export function notifySuccess(msg: string, timeout = 2000) { Notify.create({ type: "positive", message: msg, @@ -8,7 +8,7 @@ export function notifySuccess(msg, timeout = 2000) { }); } -export function notifyError(msg, timeout = 2000) { +export function notifyError(msg: string, timeout = 2000) { Notify.create({ type: "negative", message: msg, @@ -16,7 +16,7 @@ export function notifyError(msg, timeout = 2000) { }); } -export function notifyWarning(msg, timeout = 2000) { +export function notifyWarning(msg: string, timeout = 2000) { Notify.create({ type: "warning", message: msg, @@ -24,7 +24,7 @@ export function notifyWarning(msg, timeout = 2000) { }); } -export function notifyInfo(msg, timeout = 2000) { +export function notifyInfo(msg: string, timeout = 2000) { Notify.create({ type: "info", message: msg, diff --git a/src/utils/validation.js b/src/utils/validation.js deleted file mode 100644 index 9a1904f8..00000000 --- a/src/utils/validation.js +++ /dev/null @@ -1,53 +0,0 @@ -import { Notify } from "quasar"; - -export function isValidThreshold(warning, error, diskcheck = false) { - if (warning === 0 && error === 0) { - Notify.create({ - type: "negative", - timeout: 2000, - message: "Warning Threshold or Error Threshold need to be set", - }); - return false; - } - - if (!diskcheck && warning > error && warning > 0 && error > 0) { - Notify.create({ - type: "negative", - timeout: 2000, - message: "Warning Threshold must be less than Error Threshold", - }); - return false; - } - - if (diskcheck && warning < error && warning > 0 && error > 0) { - Notify.create({ - type: "negative", - timeout: 2000, - message: "Warning Threshold must be more than Error Threshold", - }); - return false; - } - - return true; -} - -export function validateEventID(val) { - if (val === null || val.toString().replace(/\s/g, "") === "") { - return false; - } else if (val === "*") { - return true; - } else if (!isNaN(val)) { - return true; - } else { - return false; - } -} - -// validate script return code -export function validateRetcode(val, done) { - /^\d+$/.test(val) ? done(val) : done(); -} - -export function validateTimePeriod(val) { - return /^\d{1,3}(H|h|M|m|S|s|d|D)$/.test(val); -}