Compare commits

...

35 Commits

Author SHA1 Message Date
wh1te909
c2591c9e7d Release 0.101.22 2023-05-30 22:11:30 +00:00
wh1te909
69403def2a bump version 2023-05-30 22:11:11 +00:00
wh1te909
3fdd8272f6 bump version 2023-05-29 20:36:02 +00:00
wh1te909
339227bedc add cert expiring soon indicator closes amidaware/tacticalrmm#722 2023-05-27 23:31:07 +00:00
wh1te909
17c7c95cc1 group processors for cleaner UI closes amidaware/tacticalrmm#583 2023-05-27 20:05:53 +00:00
wh1te909
a3ceb5e81b add serial number to summary tab closes amidaware/tacticalrmm#389 2023-05-27 19:48:19 +00:00
wh1te909
679d8cab77 add wake-on-lan amidaware/tacticalrmm#1180 2023-05-27 00:38:34 +00:00
wh1te909
c4c1474e09 add serial number to search amidaware/tacticalrmm#1355 2023-05-26 22:54:46 +00:00
wh1te909
82677b0b82 make cmd placeholder text customizable closes #5 2023-05-26 22:18:01 +00:00
wh1te909
b78af07f11 allow customizing dashboard colors closes amidaware/tacticalrmm#1514 2023-05-25 22:31:16 +00:00
wh1te909
24acef19c5 formatting 2023-05-25 22:30:05 +00:00
wh1te909
fee6edb39e update reqs 2023-05-25 22:21:34 +00:00
wh1te909
89e7db905d fix client sorting fixes amidaware/tacticalrmm#1439 2023-05-25 21:27:45 +00:00
wh1te909
827e81dcda don't retry null token fixes amidaware/tacticalrmm#1199 2023-05-17 07:03:13 +00:00
wh1te909
6ea3a053f2 update reqs 2023-05-17 07:00:38 +00:00
sadnub
88d297f7c6 Change the default color of anchor tags to make them look better in dark mode 2023-05-13 00:00:36 -04:00
sadnub
6c57d3e6b1 Make the alert icon menu height fixed 2023-05-12 23:59:18 -04:00
wh1te909
7fcbe6fbd8 Release 0.101.20 2023-05-09 21:09:45 +00:00
wh1te909
0113fbc761 hide openai until next release 2023-05-09 21:06:40 +00:00
wh1te909
a2f472ef9c Release 0.101.18 2023-04-09 03:28:23 +00:00
wh1te909
8403ac0e93 Release 0.101.16 2023-03-22 17:00:29 +00:00
wh1te909
b7a91563b0 Release 0.101.13 2023-01-18 20:05:20 +00:00
wh1te909
ab19afca16 Release 0.101.11 2022-12-21 18:44:46 +00:00
wh1te909
f24c6a7a80 Release 0.101.9 2022-12-04 23:01:59 +00:00
wh1te909
99490bf859 Release 0.101.7 2022-11-13 01:20:33 +00:00
wh1te909
72cdeeaa6a Release 0.101.5 2022-10-25 22:02:34 +00:00
wh1te909
1eca4d605b Release 0.101.3 2022-10-19 22:35:54 +00:00
wh1te909
52ee98f6f8 Release 0.101.0 2022-09-24 02:43:53 +00:00
wh1te909
d270b877c9 Release 0.100.9 2022-08-23 05:04:57 +00:00
wh1te909
fd8b2a1d98 Release 0.100.8 2022-08-09 20:40:48 +00:00
wh1te909
f518043d8d Release 0.100.7 2022-08-01 17:36:11 +00:00
wh1te909
cc2335558d Release 0.100.6 2022-07-27 06:15:49 +00:00
wh1te909
a8a171ba2c Release 0.100.5 2022-07-10 00:00:08 +00:00
wh1te909
24a63f477e Release 0.100.4 2022-07-07 16:38:14 +00:00
wh1te909
ddeb6293a1 init 2022-05-17 20:46:22 +00:00
24 changed files with 739 additions and 385 deletions

407
package-lock.json generated
View File

@@ -1,18 +1,18 @@
{
"name": "web",
"version": "0.101.18",
"version": "0.101.20",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "web",
"version": "0.101.18",
"version": "0.101.20",
"dependencies": {
"@quasar/extras": "1.16.3",
"@quasar/extras": "1.16.4",
"apexcharts": "3.40.0",
"axios": "1.4.0",
"dotenv": "16.0.3",
"qrcode.vue": "3.3.4",
"qrcode.vue": "3.4.0",
"quasar": "2.12.0",
"vue": "3.2.47",
"vue-router": "4.1.6",
@@ -23,13 +23,13 @@
},
"devDependencies": {
"@intlify/unplugin-vue-i18n": "^0.10.0",
"@quasar/app-vite": "^1.3.0",
"@quasar/cli": "^2.1.0",
"@types/node": "^18.16.5",
"@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "^5.59.2",
"@quasar/app-vite": "^1.4.3",
"@quasar/cli": "^2.2.1",
"@types/node": "^20.2.4",
"@typescript-eslint/eslint-plugin": "^5.59.7",
"@typescript-eslint/parser": "^5.59.7",
"autoprefixer": "10.4.14",
"eslint": "8.40.0",
"eslint": "8.41.0",
"eslint-config-prettier": "8.8.0",
"eslint-plugin-vue": "8.7.1",
"prettier": "2.8.8",
@@ -95,9 +95,9 @@
}
},
"node_modules/@eslint/js": {
"version": "8.40.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
"integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==",
"version": "8.41.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz",
"integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -332,14 +332,13 @@
}
},
"node_modules/@quasar/app-vite": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.3.0.tgz",
"integrity": "sha512-2ZkFuWzMCJmy8ve8zguYzNX3uALKbKeGQ3jQ6GDnCCNEt6yO8dBeWIqJ/epFv0/1TXYRYFCeGONmdSHDMiy2NA==",
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.4.3.tgz",
"integrity": "sha512-5iMs1sk6fyYTFoRVySwFXWL/PS23UEsdk+YSFejhXnSs5fVDmb2GQMguCHwDl3jPIHjZ7A+XKkb2iWx9pjiPXw==",
"dev": true,
"dependencies": {
"@quasar/fastclick": "1.1.5",
"@quasar/render-ssr-error": "^1.0.0",
"@quasar/vite-plugin": "^1.3.1",
"@quasar/render-ssr-error": "^1.0.1",
"@quasar/vite-plugin": "^1.3.3",
"@rollup/pluginutils": "^4.1.2",
"@types/chrome": "^0.0.208",
"@types/compression": "^1.7.2",
@@ -386,8 +385,8 @@
"url": "https://donate.quasar.dev"
},
"peerDependencies": {
"electron-builder": "^22.0.0",
"electron-packager": "^15.0.0",
"electron-builder": ">= 22",
"electron-packager": ">= 15",
"eslint": "^8.11.0",
"pinia": "^2.0.0",
"quasar": "^2.8.0",
@@ -427,11 +426,12 @@
}
},
"node_modules/@quasar/cli": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@quasar/cli/-/cli-2.1.0.tgz",
"integrity": "sha512-LMBJoVHjWl6dcgLX9MDJ7J4iHp0tep0R6R8yIeg1zVbJOjDNkYRpJZWgq/Wado7VVqObHayt5mEN3pEqu+rM2g==",
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@quasar/cli/-/cli-2.2.1.tgz",
"integrity": "sha512-PMwJ76IeeNRRBw+08hUMjhqGC6JKJ/t1zIb+IOiyR5D4rkBR26Ha/Z46OD3KfwUprq4Q8s4ieB1+d3VY8FhPKg==",
"dev": true,
"dependencies": {
"@quasar/ssl-certificate": "^1.0.0",
"ci-info": "^3.8.0",
"compression": "^1.7.4",
"connect-history-api-fallback": "^2.0.0",
@@ -451,7 +451,7 @@
"quasar": "bin/quasar.js"
},
"engines": {
"node": ">= 14.15.0",
"node": ">= 16",
"npm": ">= 5.6.0",
"yarn": ">= 1.6.0"
},
@@ -491,28 +491,18 @@
}
},
"node_modules/@quasar/extras": {
"version": "1.16.3",
"resolved": "https://registry.npmjs.org/@quasar/extras/-/extras-1.16.3.tgz",
"integrity": "sha512-c9p2j4KWrWqOcCcCD9IMjgPZzAiXKSMEMc3uYbqa5mHlEJ1kl88OMaeJUcmP+INRQ29AFSEQ9tZE20jLmdnLXw==",
"funding": {
"type": "github",
"url": "https://donate.quasar.dev"
}
},
"node_modules/@quasar/fastclick": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/@quasar/fastclick/-/fastclick-1.1.5.tgz",
"integrity": "sha512-p3JKgTjRlJ1YQXbqTw3Bsa4j0mQdt5dq+WfYvyb7MgKGdephHCKdR/kxA5PCTAmJanGJuDKqRdyGYX/hYN4KGw==",
"dev": true,
"version": "1.16.4",
"resolved": "https://registry.npmjs.org/@quasar/extras/-/extras-1.16.4.tgz",
"integrity": "sha512-q2kPTNHI5aprgE2yQfRIf6aud+qSXH3YTNmhcfRp/rENh7kRjoM+b5BBPxgHlO1si1ARddbmr+Fxu/L05hfXnQ==",
"funding": {
"type": "github",
"url": "https://donate.quasar.dev"
}
},
"node_modules/@quasar/render-ssr-error": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@quasar/render-ssr-error/-/render-ssr-error-1.0.0.tgz",
"integrity": "sha512-UoZqXCOS4ixpxFG6xZmd+sLAVCYgRD0VPElHfovvhfvNBn2RsTrKo8DFlLpAxsB/Ebb5QzZG7vsiuWEpKGzPhA==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@quasar/render-ssr-error/-/render-ssr-error-1.0.1.tgz",
"integrity": "sha512-4Shxl079hew/yZnIsDtWpRD8enOmqMjMu/s2bkGN0QBvlsRkpWv9pwOz5geJXZxBa17q1S4txvByBxkhPfhWaQ==",
"dev": true,
"dependencies": {
"stack-trace": "^1.0.0-pre2"
@@ -525,10 +515,27 @@
"url": "https://donate.quasar.dev"
}
},
"node_modules/@quasar/ssl-certificate": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@quasar/ssl-certificate/-/ssl-certificate-1.0.0.tgz",
"integrity": "sha512-RhZF7rO76T7Ywer1/5lCe7xl3CIiXxSAH1xgwOj0wcHTityDxJqIN/5YIj6BxMvlFw8XkJDoB1udEQafoVFA4g==",
"dev": true,
"dependencies": {
"fs-extra": "^11.1.1",
"selfsigned": "^2.1.1"
},
"engines": {
"node": ">= 16"
},
"funding": {
"type": "github",
"url": "https://donate.quasar.dev"
}
},
"node_modules/@quasar/vite-plugin": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@quasar/vite-plugin/-/vite-plugin-1.3.1.tgz",
"integrity": "sha512-TOkCgsoxDxdRwzO05SMJgb1ICK1F3FeYE0MFoKukJ0KwKi17WSjIZGfxltShJ9x4ZtNezhVLjFN9MXbQgXFZwQ==",
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@quasar/vite-plugin/-/vite-plugin-1.3.3.tgz",
"integrity": "sha512-HSX/Vgec5/Y8fiJRfpf1MR7+um+rdpbilktBGQkYOKw4A9d0smGq4jtSS/K4O2GTXRYqDmZ/5sgCeBcmhB3OCw==",
"dev": true,
"engines": {
"node": ">=12"
@@ -703,9 +710,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "18.16.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.5.tgz",
"integrity": "sha512-seOA34WMo9KB+UA78qaJoCO20RJzZGVXQ5Sh6FWu0g/hfT44nKXnej3/tCQl7FL97idFpBhisLYCTB50S0EirA==",
"version": "20.2.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.4.tgz",
"integrity": "sha512-ni5f8Xlf4PwnT/Z3f0HURc3ZSw8UyrqMqmM3L5ysa7VjHu8c3FOmIo1nKCcLrV/OAmtf3N4kFna/aJqxsfEtnA==",
"dev": true
},
"node_modules/@types/qs": {
@@ -721,9 +728,9 @@
"dev": true
},
"node_modules/@types/semver": {
"version": "7.3.13",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
"integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz",
"integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==",
"dev": true
},
"node_modules/@types/serve-static": {
@@ -737,15 +744,15 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz",
"integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz",
"integrity": "sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.4.0",
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/type-utils": "5.59.2",
"@typescript-eslint/utils": "5.59.2",
"@typescript-eslint/scope-manager": "5.59.7",
"@typescript-eslint/type-utils": "5.59.7",
"@typescript-eslint/utils": "5.59.7",
"debug": "^4.3.4",
"grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0",
@@ -771,14 +778,14 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz",
"integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz",
"integrity": "sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/typescript-estree": "5.59.2",
"@typescript-eslint/scope-manager": "5.59.7",
"@typescript-eslint/types": "5.59.7",
"@typescript-eslint/typescript-estree": "5.59.7",
"debug": "^4.3.4"
},
"engines": {
@@ -798,13 +805,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz",
"integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz",
"integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/visitor-keys": "5.59.2"
"@typescript-eslint/types": "5.59.7",
"@typescript-eslint/visitor-keys": "5.59.7"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -815,13 +822,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz",
"integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz",
"integrity": "sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "5.59.2",
"@typescript-eslint/utils": "5.59.2",
"@typescript-eslint/typescript-estree": "5.59.7",
"@typescript-eslint/utils": "5.59.7",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
@@ -842,9 +849,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz",
"integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz",
"integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -855,13 +862,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz",
"integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz",
"integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/visitor-keys": "5.59.2",
"@typescript-eslint/types": "5.59.7",
"@typescript-eslint/visitor-keys": "5.59.7",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -882,17 +889,17 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz",
"integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz",
"integrity": "sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/typescript-estree": "5.59.2",
"@typescript-eslint/scope-manager": "5.59.7",
"@typescript-eslint/types": "5.59.7",
"@typescript-eslint/typescript-estree": "5.59.7",
"eslint-scope": "^5.1.1",
"semver": "^7.3.7"
},
@@ -908,12 +915,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz",
"integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz",
"integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/types": "5.59.7",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -2919,15 +2926,15 @@
}
},
"node_modules/eslint": {
"version": "8.40.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz",
"integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==",
"version": "8.41.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz",
"integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.3",
"@eslint/js": "8.40.0",
"@eslint/js": "8.41.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@@ -2947,13 +2954,12 @@
"find-up": "^5.0.0",
"glob-parent": "^6.0.2",
"globals": "^13.19.0",
"grapheme-splitter": "^1.0.4",
"graphemer": "^1.4.0",
"ignore": "^5.2.0",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
"is-path-inside": "^3.0.3",
"js-sdsl": "^4.1.4",
"js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
@@ -3775,6 +3781,12 @@
"integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
"dev": true
},
"node_modules/graphemer": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -4375,12 +4387,6 @@
"node": ">=0.10.0"
}
},
"node_modules/js-sdsl": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz",
"integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==",
"dev": true
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@@ -5366,9 +5372,9 @@
}
},
"node_modules/qrcode.vue": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/qrcode.vue/-/qrcode.vue-3.3.4.tgz",
"integrity": "sha512-ZVPmKZUUqM/wZ19mIhecFJs7mO6KXFiZZmBZyU6wiB2aXZfYc/VpolXakQcKw/9aGFEmSHHVKfgNwyxtw/Q2Sw==",
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/qrcode.vue/-/qrcode.vue-3.4.0.tgz",
"integrity": "sha512-4XeImbv10Fin16Fl2DArCMhGyAdvIg2jb7vDT+hZiIAMg/6H6mz9nUZr/dR8jBcun5VzNzkiwKhiqOGbloinwA==",
"peerDependencies": {
"vue": "^3.0.0"
}
@@ -5922,9 +5928,9 @@
"dev": true
},
"node_modules/selfsigned": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz",
"integrity": "sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz",
"integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==",
"dev": true,
"dependencies": {
"node-forge": "^1"
@@ -7244,9 +7250,9 @@
}
},
"@eslint/js": {
"version": "8.40.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
"integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==",
"version": "8.41.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz",
"integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==",
"dev": true
},
"@humanwhocodes/config-array": {
@@ -7401,14 +7407,13 @@
}
},
"@quasar/app-vite": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.3.0.tgz",
"integrity": "sha512-2ZkFuWzMCJmy8ve8zguYzNX3uALKbKeGQ3jQ6GDnCCNEt6yO8dBeWIqJ/epFv0/1TXYRYFCeGONmdSHDMiy2NA==",
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.4.3.tgz",
"integrity": "sha512-5iMs1sk6fyYTFoRVySwFXWL/PS23UEsdk+YSFejhXnSs5fVDmb2GQMguCHwDl3jPIHjZ7A+XKkb2iWx9pjiPXw==",
"dev": true,
"requires": {
"@quasar/fastclick": "1.1.5",
"@quasar/render-ssr-error": "^1.0.0",
"@quasar/vite-plugin": "^1.3.1",
"@quasar/render-ssr-error": "^1.0.1",
"@quasar/vite-plugin": "^1.3.3",
"@rollup/pluginutils": "^4.1.2",
"@types/chrome": "^0.0.208",
"@types/compression": "^1.7.2",
@@ -7455,11 +7460,12 @@
}
},
"@quasar/cli": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@quasar/cli/-/cli-2.1.0.tgz",
"integrity": "sha512-LMBJoVHjWl6dcgLX9MDJ7J4iHp0tep0R6R8yIeg1zVbJOjDNkYRpJZWgq/Wado7VVqObHayt5mEN3pEqu+rM2g==",
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@quasar/cli/-/cli-2.2.1.tgz",
"integrity": "sha512-PMwJ76IeeNRRBw+08hUMjhqGC6JKJ/t1zIb+IOiyR5D4rkBR26Ha/Z46OD3KfwUprq4Q8s4ieB1+d3VY8FhPKg==",
"dev": true,
"requires": {
"@quasar/ssl-certificate": "^1.0.0",
"ci-info": "^3.8.0",
"compression": "^1.7.4",
"connect-history-api-fallback": "^2.0.0",
@@ -7497,29 +7503,33 @@
}
},
"@quasar/extras": {
"version": "1.16.3",
"resolved": "https://registry.npmjs.org/@quasar/extras/-/extras-1.16.3.tgz",
"integrity": "sha512-c9p2j4KWrWqOcCcCD9IMjgPZzAiXKSMEMc3uYbqa5mHlEJ1kl88OMaeJUcmP+INRQ29AFSEQ9tZE20jLmdnLXw=="
},
"@quasar/fastclick": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/@quasar/fastclick/-/fastclick-1.1.5.tgz",
"integrity": "sha512-p3JKgTjRlJ1YQXbqTw3Bsa4j0mQdt5dq+WfYvyb7MgKGdephHCKdR/kxA5PCTAmJanGJuDKqRdyGYX/hYN4KGw==",
"dev": true
"version": "1.16.4",
"resolved": "https://registry.npmjs.org/@quasar/extras/-/extras-1.16.4.tgz",
"integrity": "sha512-q2kPTNHI5aprgE2yQfRIf6aud+qSXH3YTNmhcfRp/rENh7kRjoM+b5BBPxgHlO1si1ARddbmr+Fxu/L05hfXnQ=="
},
"@quasar/render-ssr-error": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@quasar/render-ssr-error/-/render-ssr-error-1.0.0.tgz",
"integrity": "sha512-UoZqXCOS4ixpxFG6xZmd+sLAVCYgRD0VPElHfovvhfvNBn2RsTrKo8DFlLpAxsB/Ebb5QzZG7vsiuWEpKGzPhA==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@quasar/render-ssr-error/-/render-ssr-error-1.0.1.tgz",
"integrity": "sha512-4Shxl079hew/yZnIsDtWpRD8enOmqMjMu/s2bkGN0QBvlsRkpWv9pwOz5geJXZxBa17q1S4txvByBxkhPfhWaQ==",
"dev": true,
"requires": {
"stack-trace": "^1.0.0-pre2"
}
},
"@quasar/ssl-certificate": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@quasar/ssl-certificate/-/ssl-certificate-1.0.0.tgz",
"integrity": "sha512-RhZF7rO76T7Ywer1/5lCe7xl3CIiXxSAH1xgwOj0wcHTityDxJqIN/5YIj6BxMvlFw8XkJDoB1udEQafoVFA4g==",
"dev": true,
"requires": {
"fs-extra": "^11.1.1",
"selfsigned": "^2.1.1"
}
},
"@quasar/vite-plugin": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@quasar/vite-plugin/-/vite-plugin-1.3.1.tgz",
"integrity": "sha512-TOkCgsoxDxdRwzO05SMJgb1ICK1F3FeYE0MFoKukJ0KwKi17WSjIZGfxltShJ9x4ZtNezhVLjFN9MXbQgXFZwQ==",
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@quasar/vite-plugin/-/vite-plugin-1.3.3.tgz",
"integrity": "sha512-HSX/Vgec5/Y8fiJRfpf1MR7+um+rdpbilktBGQkYOKw4A9d0smGq4jtSS/K4O2GTXRYqDmZ/5sgCeBcmhB3OCw==",
"dev": true,
"requires": {}
},
@@ -7670,9 +7680,9 @@
"dev": true
},
"@types/node": {
"version": "18.16.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.5.tgz",
"integrity": "sha512-seOA34WMo9KB+UA78qaJoCO20RJzZGVXQ5Sh6FWu0g/hfT44nKXnej3/tCQl7FL97idFpBhisLYCTB50S0EirA==",
"version": "20.2.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.4.tgz",
"integrity": "sha512-ni5f8Xlf4PwnT/Z3f0HURc3ZSw8UyrqMqmM3L5ysa7VjHu8c3FOmIo1nKCcLrV/OAmtf3N4kFna/aJqxsfEtnA==",
"dev": true
},
"@types/qs": {
@@ -7688,9 +7698,9 @@
"dev": true
},
"@types/semver": {
"version": "7.3.13",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
"integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz",
"integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==",
"dev": true
},
"@types/serve-static": {
@@ -7704,15 +7714,15 @@
}
},
"@typescript-eslint/eslint-plugin": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz",
"integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz",
"integrity": "sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==",
"dev": true,
"requires": {
"@eslint-community/regexpp": "^4.4.0",
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/type-utils": "5.59.2",
"@typescript-eslint/utils": "5.59.2",
"@typescript-eslint/scope-manager": "5.59.7",
"@typescript-eslint/type-utils": "5.59.7",
"@typescript-eslint/utils": "5.59.7",
"debug": "^4.3.4",
"grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0",
@@ -7722,53 +7732,53 @@
}
},
"@typescript-eslint/parser": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz",
"integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz",
"integrity": "sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/typescript-estree": "5.59.2",
"@typescript-eslint/scope-manager": "5.59.7",
"@typescript-eslint/types": "5.59.7",
"@typescript-eslint/typescript-estree": "5.59.7",
"debug": "^4.3.4"
}
},
"@typescript-eslint/scope-manager": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz",
"integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz",
"integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/visitor-keys": "5.59.2"
"@typescript-eslint/types": "5.59.7",
"@typescript-eslint/visitor-keys": "5.59.7"
}
},
"@typescript-eslint/type-utils": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz",
"integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.7.tgz",
"integrity": "sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==",
"dev": true,
"requires": {
"@typescript-eslint/typescript-estree": "5.59.2",
"@typescript-eslint/utils": "5.59.2",
"@typescript-eslint/typescript-estree": "5.59.7",
"@typescript-eslint/utils": "5.59.7",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/types": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz",
"integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz",
"integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz",
"integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz",
"integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/visitor-keys": "5.59.2",
"@typescript-eslint/types": "5.59.7",
"@typescript-eslint/visitor-keys": "5.59.7",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -7777,28 +7787,28 @@
}
},
"@typescript-eslint/utils": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz",
"integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.7.tgz",
"integrity": "sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/typescript-estree": "5.59.2",
"@typescript-eslint/scope-manager": "5.59.7",
"@typescript-eslint/types": "5.59.7",
"@typescript-eslint/typescript-estree": "5.59.7",
"eslint-scope": "^5.1.1",
"semver": "^7.3.7"
}
},
"@typescript-eslint/visitor-keys": {
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz",
"integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==",
"version": "5.59.7",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz",
"integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/types": "5.59.7",
"eslint-visitor-keys": "^3.3.0"
}
},
@@ -9176,15 +9186,15 @@
}
},
"eslint": {
"version": "8.40.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz",
"integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==",
"version": "8.41.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz",
"integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.3",
"@eslint/js": "8.40.0",
"@eslint/js": "8.41.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@@ -9204,13 +9214,12 @@
"find-up": "^5.0.0",
"glob-parent": "^6.0.2",
"globals": "^13.19.0",
"grapheme-splitter": "^1.0.4",
"graphemer": "^1.4.0",
"ignore": "^5.2.0",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
"is-path-inside": "^3.0.3",
"js-sdsl": "^4.1.4",
"js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
@@ -9800,6 +9809,12 @@
"integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
"dev": true
},
"graphemer": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -10202,12 +10217,6 @@
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
"dev": true
},
"js-sdsl": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz",
"integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==",
"dev": true
},
"js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@@ -10938,9 +10947,9 @@
}
},
"qrcode.vue": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/qrcode.vue/-/qrcode.vue-3.3.4.tgz",
"integrity": "sha512-ZVPmKZUUqM/wZ19mIhecFJs7mO6KXFiZZmBZyU6wiB2aXZfYc/VpolXakQcKw/9aGFEmSHHVKfgNwyxtw/Q2Sw==",
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/qrcode.vue/-/qrcode.vue-3.4.0.tgz",
"integrity": "sha512-4XeImbv10Fin16Fl2DArCMhGyAdvIg2jb7vDT+hZiIAMg/6H6mz9nUZr/dR8jBcun5VzNzkiwKhiqOGbloinwA==",
"requires": {}
},
"qs": {
@@ -11332,9 +11341,9 @@
"dev": true
},
"selfsigned": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz",
"integrity": "sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz",
"integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==",
"dev": true,
"requires": {
"node-forge": "^1"

View File

@@ -1,6 +1,6 @@
{
"name": "web",
"version": "0.101.19-dev",
"version": "0.101.22",
"private": true,
"productName": "Tactical RMM",
"scripts": {
@@ -10,11 +10,11 @@
"format": "prettier --write \"**/*.{js,ts,vue,,html,md,json}\" --ignore-path .gitignore"
},
"dependencies": {
"@quasar/extras": "1.16.3",
"@quasar/extras": "1.16.4",
"apexcharts": "3.40.0",
"axios": "1.4.0",
"dotenv": "16.0.3",
"qrcode.vue": "3.3.4",
"qrcode.vue": "3.4.0",
"quasar": "2.12.0",
"vue": "3.2.47",
"vue3-ace-editor": "2.2.2",
@@ -24,14 +24,14 @@
"vuex": "4.1.0"
},
"devDependencies": {
"@quasar/cli": "^2.1.0",
"@quasar/cli": "^2.2.1",
"@intlify/unplugin-vue-i18n": "^0.10.0",
"@quasar/app-vite": "^1.3.0",
"@types/node": "^18.16.5",
"@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "^5.59.2",
"@quasar/app-vite": "^1.4.3",
"@types/node": "^20.2.4",
"@typescript-eslint/eslint-plugin": "^5.59.7",
"@typescript-eslint/parser": "^5.59.7",
"autoprefixer": "10.4.14",
"eslint": "8.40.0",
"eslint": "8.41.0",
"eslint-config-prettier": "8.8.0",
"eslint-plugin-vue": "8.7.1",
"prettier": "2.8.8",

View File

@@ -12,6 +12,9 @@ export default {
body
overflow-y: hidden
a
color: #1976D2
.tbl-sticky
thead tr th
position: sticky

View File

@@ -232,3 +232,8 @@ export async function removeAgentNote(pk) {
const { data } = await axios.delete(`${baseUrl}/notes/${pk}/`);
return data;
}
export async function wakeUpWOL(agent_id) {
const { data } = await axios.post(`${baseUrl}/${agent_id}/wol/`);
return data;
}

View File

@@ -211,7 +211,7 @@
v-if="props.row.maintenance_mode"
name="construction"
size="1.2em"
color="green"
:color="dash_positive_color"
>
<q-tooltip>Maintenance Mode Enabled</q-tooltip>
</q-icon>
@@ -219,7 +219,7 @@
v-else-if="props.row.checks.failing > 0"
name="fas fa-check-double"
size="1.2em"
color="negative"
:color="dash_negative_color"
>
<q-tooltip>Checks failing</q-tooltip>
</q-icon>
@@ -227,7 +227,7 @@
v-else-if="props.row.checks.warning > 0"
name="fas fa-check-double"
size="1.2em"
color="warning"
:color="dash_warning_color"
>
<q-tooltip>Checks warning</q-tooltip>
</q-icon>
@@ -235,7 +235,7 @@
v-else-if="props.row.checks.info > 0"
name="fas fa-check-double"
size="1.2em"
color="info"
:color="dash_info_color"
>
<q-tooltip>Checks info</q-tooltip>
</q-icon>
@@ -243,7 +243,7 @@
v-else
name="fas fa-check-double"
size="1.2em"
color="positive"
:color="dash_positive_color"
>
<q-tooltip>Checks passing</q-tooltip>
</q-icon>
@@ -279,7 +279,7 @@
@click="showPendingActionsModal(props.row)"
name="far fa-clock"
size="1.4em"
color="warning"
:color="dash_warning_color"
class="cursor-pointer"
>
<q-tooltip
@@ -303,7 +303,7 @@
v-if="props.row.status === 'overdue'"
name="fas fa-signal"
size="1.2em"
color="negative"
:color="dash_negative_color"
>
<q-tooltip>Agent overdue</q-tooltip>
</q-icon>
@@ -311,11 +311,16 @@
v-else-if="props.row.status === 'offline'"
name="fas fa-signal"
size="1.2em"
color="warning"
:color="dash_warning_color"
>
<q-tooltip>Agent offline</q-tooltip>
</q-icon>
<q-icon v-else name="fas fa-signal" size="1.2em" color="positive">
<q-icon
v-else
name="fas fa-signal"
size="1.2em"
:color="dash_positive_color"
>
<q-tooltip>Agent online</q-tooltip>
</q-icon>
</q-td>
@@ -373,7 +378,8 @@ export default {
"local_ips",
"make_model",
"physical_disks",
"custom_fields"
"custom_fields",
"serial_number",
];
// 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
@@ -435,7 +441,7 @@ export default {
return allColumns.some((col) => {
let valObj = cellValue(col, row);
if (Array.isArray(valObj)) {
valObj = valObj.map((item) => item.value ? item.value : item);
valObj = valObj.map((item) => (item.value ? item.value : item));
}
const val = valObj + "";
const haystack =
@@ -488,7 +494,9 @@ export default {
const data = {
[db_field]: !alert_action,
};
const alertColor = !alert_action ? "positive" : "info";
const alertColor = !alert_action
? this.dash_positive_color
: this.dash_info_color;
this.$axios.put(`/agents/${agent.agent_id}/`, data).then(() => {
this.$q.notify({
color: alertColor,
@@ -532,7 +540,13 @@ export default {
},
},
computed: {
...mapState(["tableHeight"]),
...mapState([
"tableHeight",
"dash_info_color",
"dash_positive_color",
"dash_negative_color",
"dash_warning_color",
]),
agentDblClickAction() {
return this.$store.state.agentDblClickAction;
},

View File

@@ -3,7 +3,7 @@
<q-badge v-if="alertsCount > 0" :color="badgeColor" floating transparent>{{
alertsCountText()
}}</q-badge>
<q-menu style="max-height: 30vh">
<q-menu :style="{ 'max-height': `${$q.screen.height - 100}px` }">
<q-list separator>
<q-item v-if="alertsCount === 0">No New Alerts</q-item>
<q-item v-for="alert in topAlerts" :key="alert.id">
@@ -59,6 +59,7 @@
</template>
<script>
import { mapState } from "vuex";
import mixins from "@/mixins/mixins";
import AlertsOverview from "@/components/modals/alerts/AlertsOverview.vue";
import { getTimeLapse } from "@/utils/format";
@@ -75,19 +76,21 @@ export default {
return {
alertsCount: 0,
topAlerts: [],
errorColor: "red",
warningColor: "orange",
infoColor: "blue",
poll: null,
};
},
computed: {
...mapState([
"dash_info_color",
"dash_warning_color",
"dash_negative_color",
]),
badgeColor() {
const severities = this.topAlerts.map((alert) => alert.severity);
if (severities.includes("error")) return this.errorColor;
else if (severities.includes("warning")) return this.warningColor;
else return this.infoColor;
if (severities.includes("error")) return this.dash_negative_color;
else if (severities.includes("warning")) return this.dash_warning_color;
else return this.dash_info_color;
},
},
methods: {
@@ -159,9 +162,9 @@ export default {
});
},
alertIconColor(severity) {
if (severity === "error") return this.errorColor;
else if (severity === "warning") return this.warningColor;
else return this.infoColor;
if (severity === "error") return this.dash_negative_color;
else if (severity === "warning") return this.dash_warning_color;
else return this.dash_info_color;
},
alertsCountText() {
if (this.alertsCount > 99) return "99+";

View File

@@ -98,6 +98,10 @@
v-model="localRole.can_reboot_agents"
label="Reboot Agents"
/>
<q-checkbox
v-model="localRole.can_send_wol"
label="Wake-Up (WoL) Agents"
/>
<q-checkbox
v-model="localRole.can_install_agents"
label="Install Agents"
@@ -437,8 +441,8 @@ export default {
can_run_scripts: false,
can_run_bulk: false,
can_manage_winsvcs: false,
can_recover_agents: false,
can_list_agent_history: false,
can_send_wol: false,
// software perms
can_list_software: false,
can_manage_software: false,

View File

@@ -146,6 +146,13 @@
<q-item-section>Run Checks</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="wakeUp(agent)">
<q-item-section side>
<q-icon size="xs" name="offline_bolt" />
</q-item-section>
<q-item-section>Wake-Up (WoL)</q-item-section>
</q-item>
<q-item clickable>
<q-item-section side>
<q-icon size="xs" name="power_settings_new" />
@@ -210,6 +217,7 @@ import {
removeAgent,
runRemoteBackground,
runTakeControl,
wakeUpWOL,
} from "@/api/agents";
import { runAgentUpdateScan, runAgentUpdateInstall } from "@/api/winupdates";
import { runAgentChecks } from "@/api/checks";
@@ -370,6 +378,15 @@ export default {
}
}
async function wakeUp(agent) {
try {
const data = await wakeUpWOL(agent.agent_id);
notifySuccess(data);
} catch (e) {
console.error(e);
}
}
function showRebootLaterModal(agent) {
$q.dialog({
component: RebootLater,
@@ -498,6 +515,7 @@ export default {
showPolicyAdd,
showAgentRecovery,
pingAgent,
wakeUp,
};
},
};

View File

@@ -261,7 +261,7 @@
<q-td v-else-if="props.row.task_result.status === 'passing'">
<q-icon
style="font-size: 1.3rem"
color="positive"
:color="dash_positive_color"
name="check_circle"
>
<q-tooltip>Passing</q-tooltip>
@@ -271,7 +271,7 @@
<q-icon
v-if="props.row.alert_severity === 'info'"
style="font-size: 1.3rem"
color="info"
:color="dash_info_color"
name="info"
>
<q-tooltip>Informational</q-tooltip>
@@ -279,7 +279,7 @@
<q-icon
v-else-if="props.row.alert_severity === 'warning'"
style="font-size: 1.3rem"
color="warning"
:color="dash_warning_color"
name="warning"
>
<q-tooltip>Warning</q-tooltip>
@@ -287,7 +287,7 @@
<q-icon
v-else
style="font-size: 1.3rem"
color="negative"
:color="dash_negative_color"
name="error"
>
<q-tooltip>Error</q-tooltip>
@@ -418,6 +418,10 @@ export default {
const tabHeight = computed(() => store.state.tabHeight);
const agentPlatform = computed(() => store.state.agentPlatform);
const formatDate = computed(() => store.getters.formatDate);
const dash_info_color = computed(() => store.state.dash_info_color);
const dash_positive_color = computed(() => store.state.dash_positive_color);
const dash_negative_color = computed(() => store.state.dash_negative_color);
const dash_warning_color = computed(() => store.state.dash_warning_color);
// setup quasar
const $q = useQuasar();
@@ -552,6 +556,10 @@ export default {
selectedAgent,
tabHeight,
agentPlatform,
dash_info_color,
dash_positive_color,
dash_warning_color,
dash_negative_color,
// non-reactive data
columns,

View File

@@ -301,7 +301,7 @@
<q-td v-else-if="props.row.check_result.status === 'passing'">
<q-icon
style="font-size: 1.3rem"
color="positive"
:color="dash_positive_color"
name="check_circle"
>
<q-tooltip>Passing</q-tooltip>
@@ -311,7 +311,7 @@
<q-icon
v-if="getAlertSeverity(props.row) === 'info'"
style="font-size: 1.3rem"
color="info"
:color="dash_info_color"
name="info"
>
<q-tooltip>Informational</q-tooltip>
@@ -319,7 +319,7 @@
<q-icon
v-else-if="getAlertSeverity(props.row) === 'warning'"
style="font-size: 1.3rem"
color="warning"
:color="dash_warning_color"
name="warning"
>
<q-tooltip>Warning</q-tooltip>
@@ -327,7 +327,7 @@
<q-icon
v-else
style="font-size: 1.3rem"
color="negative"
:color="dash_negative_color"
name="error"
>
<q-tooltip>Error</q-tooltip>
@@ -479,6 +479,10 @@ export default {
const tabHeight = computed(() => store.state.tabHeight);
const agentPlatform = computed(() => store.state.agentPlatform);
const formatDate = computed(() => store.getters.formatDate);
const dash_info_color = computed(() => store.state.dash_info_color);
const dash_positive_color = computed(() => store.state.dash_positive_color);
const dash_negative_color = computed(() => store.state.dash_negative_color);
const dash_warning_color = computed(() => store.state.dash_warning_color);
// setup quasar
const $q = useQuasar();
@@ -653,6 +657,10 @@ export default {
tabHeight,
selectedAgent,
agentPlatform,
dash_info_color,
dash_positive_color,
dash_warning_color,
dash_negative_color,
// non-reactive data
columns,

View File

@@ -18,6 +18,33 @@
icon="refresh"
@click="refreshSummary"
/>
<q-icon
v-if="summary.status === 'overdue'"
name="fas fa-signal"
size="1.2em"
:color="dash_negative_color"
class="q-mr-sm"
>
<q-tooltip>Agent overdue</q-tooltip>
</q-icon>
<q-icon
v-else-if="summary.status === 'offline'"
name="fas fa-signal"
size="1.2em"
:color="dash_warning_color"
class="q-mr-sm"
>
<q-tooltip>Agent offline</q-tooltip>
</q-icon>
<q-icon
v-else
name="fas fa-signal"
size="1.2em"
:color="dash_positive_color"
class="q-mr-sm"
>
<q-tooltip>Agent online</q-tooltip>
</q-icon>
<b>{{ summary.hostname }}</b>
<span v-if="summary.maintenance_mode">
&bull; <q-badge color="green"> Maintenance Mode </q-badge>
@@ -60,7 +87,7 @@
</q-item-section>
<q-item-section>{{ summary.make_model }}</q-item-section>
</q-item>
<q-item v-for="(cpu, i) in summary.cpu_model" :key="cpu + i">
<q-item>
<q-item-section avatar>
<q-icon name="fas fa-microchip" />
</q-item-section>
@@ -87,6 +114,13 @@
</q-item-section>
<q-item-section>{{ summary.graphics }}</q-item-section>
</q-item>
<!-- serial -->
<q-item v-if="serial_number">
<q-item-section avatar>
<q-icon name="fa-solid fa-barcode" />
</q-item-section>
<q-item-section>{{ serial_number }}</q-item-section>
</q-item>
<q-item>
<q-item-section avatar>
<q-icon name="fas fa-globe-americas" />
@@ -110,7 +144,7 @@
size="lg"
square
icon="done"
color="green"
:color="dash_positive_color"
text-color="white"
/>
<small>{{ summary.checks.passing }} checks passing</small>
@@ -120,7 +154,7 @@
size="lg"
square
icon="cancel"
color="red"
:color="dash_negative_color"
text-color="white"
/>
<small>{{ summary.checks.failing }} checks failing</small>
@@ -130,7 +164,7 @@
size="lg"
square
icon="warning"
color="warning"
:color="dash_warning_color"
text-color="white"
/>
<small>{{ summary.checks.warning }} checks warning</small>
@@ -140,7 +174,7 @@
size="lg"
square
icon="info"
color="info"
:color="dash_info_color"
text-color="white"
/>
<small>{{ summary.checks.info }} checks info</small>
@@ -222,19 +256,34 @@ export default {
const store = useStore();
const selectedAgent = computed(() => store.state.selectedRow);
const refreshSummaryTab = computed(() => store.state.refreshSummaryTab);
const dash_info_color = computed(() => store.state.dash_info_color);
const dash_positive_color = computed(() => store.state.dash_positive_color);
const dash_negative_color = computed(() => store.state.dash_negative_color);
const dash_warning_color = computed(() => store.state.dash_warning_color);
// summary tab logic
const summary = ref(null);
const customFieldsDefinitions = ref(null);
const loading = ref(false);
const serial_number = computed(() => {
return summary.value.wmi_detail.bios?.[0]?.[0]?.SerialNumber;
});
const cpu = computed(() => {
if (summary.value.cpu_model?.length > 1) {
return `${summary.value.cpu_model.length}x ${summary.value.cpu_model[0]}`;
}
return summary.value.cpu_model[0];
});
function diskBarColor(percent) {
if (percent < 80) {
return "positive";
return dash_positive_color.value;
} else if (percent > 80 && percent < 95) {
return "warning";
return dash_warning_color.value;
} else {
return "negative";
return dash_negative_color.value;
}
}
@@ -290,6 +339,7 @@ export default {
async function refreshSummary() {
loading.value = true;
summary.value = await fetchAgent(selectedAgent.value);
try {
const result = await refreshAgentWMI(selectedAgent.value);
await getSummary();
@@ -325,6 +375,12 @@ export default {
loading,
selectedAgent,
disks,
dash_info_color,
dash_positive_color,
dash_warning_color,
dash_negative_color,
serial_number,
cpu,
// methods
getSummary,

View File

@@ -128,7 +128,7 @@
<q-icon
v-else-if="props.row.action === 'ignore'"
name="fas fa-check"
color="negative"
:color="dash_negative_color"
>
<q-tooltip>Ignore</q-tooltip>
</q-icon>
@@ -144,7 +144,7 @@
<q-icon
v-if="props.row.installed"
name="fas fa-check"
color="positive"
:color="dash_positive_color"
>
<q-tooltip>Installed</q-tooltip>
</q-icon>
@@ -158,11 +158,15 @@
<q-icon
v-else-if="props.row.action == 'ignore'"
name="fas fa-ban"
color="negative"
:color="dash_negative_color"
>
<q-tooltip>Ignored</q-tooltip>
</q-icon>
<q-icon v-else name="fas fa-exclamation" color="warning">
<q-icon
v-else
name="fas fa-exclamation"
:color="dash_warning_color"
>
<q-tooltip>Missing</q-tooltip>
</q-icon>
</q-td>
@@ -251,6 +255,9 @@ export default {
const tabHeight = computed(() => store.state.tabHeight);
const agentPlatform = computed(() => store.state.agentPlatform);
const formatDate = computed(() => store.getters.formatDate);
const dash_positive_color = computed(() => store.state.dash_positive_color);
const dash_negative_color = computed(() => store.state.dash_negative_color);
const dash_warning_color = computed(() => store.state.dash_warning_color);
// setup quasar
const $q = useQuasar();
@@ -348,6 +355,9 @@ export default {
selectedAgent,
tabHeight,
agentPlatform,
dash_positive_color,
dash_warning_color,
dash_negative_color,
// non-reactive data
columns,

View File

@@ -217,6 +217,7 @@
</template>
<script>
import { mapState } from "vuex";
import mixins from "@/mixins/mixins";
import PolicyStatus from "@/components/automation/modals/PolicyStatus.vue";
import DiskSpaceCheck from "@/components/checks/DiskSpaceCheck.vue";
@@ -268,6 +269,9 @@ export default {
if (newValue !== oldValue) this.getChecks();
},
},
computed: {
...mapState(["dash_positive_color", "dash_warning_color"]),
},
methods: {
getChecks() {
this.$q.loading.show();
@@ -295,7 +299,9 @@ export default {
data.check_alert = true;
const act = !action ? "enabled" : "disabled";
const color = !action ? "positive" : "warning";
const color = !action
? this.dash_positive_color
: this.dash_warning_color;
this.$axios
.put(`/checks/${id}/`, data)
.then(() => {

View File

@@ -41,7 +41,7 @@
<q-td v-if="props.row.status === 'passing'">
<q-icon
style="font-size: 1.3rem"
color="positive"
:color="dash_positive_color"
name="check_circle"
>
<q-tooltip>Passing</q-tooltip>
@@ -51,7 +51,7 @@
<q-icon
v-if="props.row.alert_severity === 'info'"
style="font-size: 1.3rem"
color="info"
:color="dash_info_color"
name="info"
>
<q-tooltip>Informational</q-tooltip>
@@ -59,7 +59,7 @@
<q-icon
v-else-if="props.row.alert_severity === 'warning'"
style="font-size: 1.3rem"
color="warning"
:color="dash_warning_color"
name="warning"
>
<q-tooltip>Warning</q-tooltip>
@@ -67,7 +67,7 @@
<q-icon
v-else
style="font-size: 1.3rem"
color="negative"
:color="dash_negative_color"
name="error"
>
<q-tooltip>Error</q-tooltip>
@@ -148,7 +148,7 @@
<script>
import { computed } from "vue";
import { useStore } from "vuex";
import { useStore, mapState } from "vuex";
import ScriptOutput from "@/components/checks/ScriptOutput.vue";
import EventLogCheckOutput from "@/components/checks/EventLogCheckOutput.vue";
@@ -220,6 +220,12 @@ export default {
};
},
computed: {
...mapState([
"dash_info_color",
"dash_positive_color",
"dash_negative_color",
"dash_warning_color",
]),
title() {
return !!this.item.readable_desc
? this.item.readable_desc + " Status"

View File

@@ -304,6 +304,9 @@ export default {
// setup vuex
const store = useStore();
const formatDate = computed(() => store.getters.formatDate);
const dash_positive_color = computed(() => store.state.dash_positive_color);
const dash_negative_color = computed(() => store.state.dash_negative_color);
const dash_warning_color = computed(() => store.state.dash_warning_color);
// setup dropdowns
const { clientOptions, getClientOptions } = useClientDropdown();
@@ -381,12 +384,18 @@ export default {
}
function formatActionColor(action) {
if (action === "add") return "success";
else if (action === "agent_install") return "success";
else if (action === "modify") return "warning";
else if (action === "delete") return "negative";
else if (action === "failed_login") return "negative";
else return "primary";
switch (action.toLowerCase()) {
case "modify":
return dash_warning_color.value;
case "add":
case "agent_install":
return dash_positive_color.value;
case "delete":
case "failed_login":
return dash_negative_color.value;
default:
return "primary";
}
}
// watchers

View File

@@ -68,25 +68,25 @@
/>
<q-radio
v-model="logLevelFilter"
color="cyan"
:color="dash_info_color"
val="info"
label="Info"
/>
<q-radio
v-model="logLevelFilter"
color="red"
:color="dash_negative_color"
val="critical"
label="Critical"
/>
<q-radio
v-model="logLevelFilter"
color="red"
:color="dash_negative_color"
val="error"
label="Error"
/>
<q-radio
v-model="logLevelFilter"
color="yellow"
:color="dash_warning_color"
val="warning"
label="Warning"
/>
@@ -109,7 +109,7 @@
<template v-slot:top-row>
<q-tr v-if="Array.isArray(debugLog) && debugLog.length === 1000">
<q-td colspan="100%">
<q-icon name="warning" color="warning" />
<q-icon name="warning" :color="dash_warning_color" />
Results are limited to 1000 rows.
</q-td>
</q-tr>
@@ -203,6 +203,10 @@ export default {
const store = useStore();
const formatDate = computed(() => store.getters.formatDate);
const dash_info_color = computed(() => store.state.dash_info_color);
const dash_positive_color = computed(() => store.state.dash_positive_color);
const dash_negative_color = computed(() => store.state.dash_negative_color);
const dash_warning_color = computed(() => store.state.dash_warning_color);
// setup dropdowns
const { agentOptions, getAgentOptions } = useAgentDropdown();
@@ -261,6 +265,10 @@ export default {
agentOptions,
loading,
filter,
dash_info_color,
dash_positive_color,
dash_warning_color,
dash_negative_color,
// non-reactive data
columns,

View File

@@ -94,7 +94,7 @@
class="q-pr-sm"
name="fas fa-signal"
size="1.2em"
color="warning"
:color="dash_warning_color"
/>
Mark an agent as
<span class="text-weight-bold">offline</span> if it has
@@ -120,7 +120,7 @@
class="q-pr-sm"
name="fas fa-signal"
size="1.2em"
color="negative"
:color="dash_negative_color"
/>
Mark an agent as
<span class="text-weight-bold">overdue</span> if it has
@@ -373,6 +373,7 @@
</template>
<script>
import { mapState } from "vuex";
import { useDialogPluginComponent } from "quasar";
import mixins from "@/mixins/mixins";
import PatchPolicyForm from "@/components/modals/agents/PatchPolicyForm.vue";
@@ -549,6 +550,9 @@ export default {
return result.trimEnd(",");
},
},
computed: {
...mapState(["dash_warning_color", "dash_negative_color"]),
},
mounted() {
// Get custom fields
this.getCustomFields("agent").then((r) => {

View File

@@ -12,7 +12,7 @@
<q-tab name="urlactions" label="URL Actions" />
<q-tab name="retention" label="Retention" />
<q-tab name="apikeys" label="API Keys" />
<q-tab name="openai" label="Open AI" />
<!-- <q-tab name="openai" label="Open AI" /> -->
</q-tabs>
</template>
<template v-slot:after>
@@ -511,7 +511,7 @@
</q-tab-panel>
<!-- Open AI -->
<q-tab-panel name="openai">
<!-- <q-tab-panel name="openai">
<div class="text-subtitle2">Open AI</div>
<q-separator />
<q-card-section class="row">
@@ -551,7 +551,7 @@
</template>
</q-input>
</q-card-section>
</q-tab-panel>
</q-tab-panel> -->
</q-tab-panels>
</q-scroll-area>
<q-card-section class="row items-center">

View File

@@ -82,6 +82,98 @@
class="col-4"
/>
</q-card-section>
<q-card-section class="row">
<div class="col-2">Dashboard Info Color:</div>
<div class="col-2"></div>
<q-input
outlined
dense
v-model="dash_info_color"
class="col-8"
>
<template v-slot:after>
<q-btn
round
dense
flat
size="sm"
icon="info"
@click="openURL(quasar_color_url)"
>
<q-tooltip>Click to see color options</q-tooltip>
</q-btn>
</template>
</q-input>
</q-card-section>
<q-card-section class="row">
<div class="col-2">Dashboard Positive Color:</div>
<div class="col-2"></div>
<q-input
outlined
dense
v-model="dash_positive_color"
class="col-8"
>
<template v-slot:after>
<q-btn
round
dense
flat
size="sm"
icon="info"
@click="openURL(quasar_color_url)"
>
<q-tooltip>Click to see color options</q-tooltip>
</q-btn>
</template>
</q-input>
</q-card-section>
<q-card-section class="row">
<div class="col-2">Dashboard Negative Color:</div>
<div class="col-2"></div>
<q-input
outlined
dense
v-model="dash_negative_color"
class="col-8"
>
<template v-slot:after>
<q-btn
round
dense
flat
size="sm"
icon="info"
@click="openURL(quasar_color_url)"
>
<q-tooltip>Click to see color options</q-tooltip>
</q-btn>
</template>
</q-input>
</q-card-section>
<q-card-section class="row">
<div class="col-2">Dashboard Warning Color:</div>
<div class="col-2"></div>
<q-input
outlined
dense
v-model="dash_warning_color"
class="col-8"
>
<template v-slot:after>
<q-btn
round
dense
flat
size="sm"
icon="info"
@click="openURL(quasar_color_url)"
>
<q-tooltip>Click to see color options</q-tooltip>
</q-btn>
</template>
</q-input>
</q-card-section>
<q-card-section class="row">
<div class="col-2">Client Sort:</div>
<div class="col-2"></div>
@@ -156,9 +248,14 @@ export default {
tab: "ui",
splitterModel: 20,
loading_bar_color: "",
dash_info_color: "",
dash_positive_color: "",
dash_negative_color: "",
dash_warning_color: "",
urlActions: [],
clear_search_when_switching: true,
date_format: "",
quasar_color_url: "https://quasar.dev/style/color-palette",
clientTreeSortOptions: [
{
label: "Sort alphabetically, moving failing clients to the top",
@@ -235,6 +332,10 @@ export default {
this.defaultAgentTblTab = r.data.default_agent_tbl_tab;
this.clientTreeSort = r.data.client_tree_sort;
this.loading_bar_color = r.data.loading_bar_color;
this.dash_info_color = r.data.dash_info_color;
this.dash_positive_color = r.data.dash_positive_color;
this.dash_negative_color = r.data.dash_negative_color;
this.dash_warning_color = r.data.dash_warning_color;
this.clear_search_when_switching = r.data.clear_search_when_switching;
this.date_format = r.data.date_format;
});
@@ -253,6 +354,10 @@ export default {
default_agent_tbl_tab: this.defaultAgentTblTab,
client_tree_sort: this.clientTreeSort,
loading_bar_color: this.loading_bar_color,
dash_info_color: this.dash_info_color,
dash_positive_color: this.dash_positive_color,
dash_negative_color: this.dash_negative_color,
dash_warning_color: this.dash_warning_color,
clear_search_when_switching: this.clear_search_when_switching,
date_format: this.date_format,
};

View File

@@ -1,4 +1,5 @@
import { ref } from "vue";
import { computed, ref } from "vue";
import { useStore } from "vuex";
import { fetchAgents } from "@/api/agents";
import { formatAgentOptions } from "@/utils/format";
@@ -28,10 +29,12 @@ export function useAgentDropdown() {
}
export function cmdPlaceholder(shell) {
if (shell === "cmd") return "rmdir /S /Q C:\\Windows\\System32";
else if (shell === "powershell")
return "Remove-Item -Recurse -Force C:\\Windows\\System32";
else return "rm -rf --no-preserve-root /";
const store = useStore();
const placeholders = computed(() => store.state.run_cmd_placeholder_text);
if (shell === "cmd") return placeholders.value.cmd;
else if (shell === "powershell") return placeholders.value.powershell;
else return placeholders.value.shell;
}
export const agentPlatformOptions = [

View File

@@ -56,15 +56,27 @@
Tactical RMM<span class="text-overline q-ml-sm"
>v{{ currentTRMMVersion }}</span
>
<span class="text-overline q-ml-md" v-if="updateAvailable()"
><q-badge color="warning"
><a :href="latestReleaseURL" target="_blank"
>v{{ latestTRMMVersion }} available</a
></q-badge
></span
<!-- update check -->
<q-chip
v-if="updateAvailable"
class="text-overline q-ml-sm"
:color="dash_warning_color"
icon="update"
dense
><a :href="latestReleaseURL" target="_blank"
>v{{ latestTRMMVersion }} available</a
></q-chip
>
<!-- cert expiring soon check -->
<q-chip
v-if="daysUntilCertExpires <= 15"
dense
:color="dash_negative_color"
text-color="black"
icon="warning"
>Certificate expires in {{ daysUntilCertExpires }} days</q-chip
>
</q-toolbar-title>
<!-- temp dark mode toggle -->
<q-toggle
v-model="darkMode"
@@ -94,7 +106,11 @@
</q-item>
<q-item>
<q-item-section avatar>
<q-icon name="power_off" size="sm" color="negative" />
<q-icon
name="power_off"
size="sm"
:color="dash_negative_color"
/>
</q-item-section>
<q-item-section no-wrap>
@@ -113,7 +129,11 @@
</q-item>
<q-item>
<q-item-section avatar>
<q-icon name="power_off" size="sm" color="negative" />
<q-icon
name="power_off"
size="sm"
:color="dash_negative_color"
/>
</q-item-section>
<q-item-section no-wrap>
@@ -218,6 +238,8 @@ export default {
const user = computed(() => store.state.username);
const hosted = computed(() => store.state.hosted);
const tokenExpired = computed(() => store.state.tokenExpired);
const dash_warning_color = computed(() => store.state.dash_warning_color);
const dash_negative_color = computed(() => store.state.dash_negative_color);
const latestReleaseURL = computed(() => {
return latestTRMMVersion.value
@@ -255,6 +277,7 @@ export default {
const serverOfflineCount = ref(0);
const workstationCount = ref(0);
const workstationOfflineCount = ref(0);
const daysUntilCertExpires = ref(100);
const ws = ref(null);
@@ -262,6 +285,13 @@ export default {
// moved computed token inside the function since it is not refreshing
// when ws is closed causing ws to connect with expired token
const token = computed(() => store.state.token);
if (!token.value) {
console.log(
"Access token is null or invalid, not setting up WebSocket"
);
return;
}
console.log("Starting websocket");
let url = getWSUrl("dashinfo", token.value);
ws.value = new WebSocket(url);
@@ -274,6 +304,7 @@ export default {
serverOfflineCount.value = data.total_server_offline_count;
workstationCount.value = data.total_workstation_count;
workstationOfflineCount.value = data.total_workstation_offline_count;
daysUntilCertExpires.value = data.days_until_cert_expires;
};
ws.value.onclose = (e) => {
try {
@@ -297,13 +328,18 @@ export default {
poll.value = setInterval(() => {
store.dispatch("checkVer");
store.dispatch("getDashInfo", false);
}, 60 * 5 * 1000);
}, 60 * 4 * 1000);
}
function updateAvailable() {
if (latestTRMMVersion.value === "error" || hosted.value) return false;
const updateAvailable = computed(() => {
if (
latestTRMMVersion.value === "error" ||
hosted.value ||
currentTRMMVersion.value?.includes("-dev")
)
return false;
return currentTRMMVersion.value !== latestTRMMVersion.value;
}
});
onMounted(() => {
setupWS();
@@ -324,6 +360,7 @@ export default {
serverOfflineCount,
workstationCount,
workstationOfflineCount,
daysUntilCertExpires,
latestReleaseURL,
currentTRMMVersion,
latestTRMMVersion,
@@ -332,6 +369,8 @@ export default {
darkMode,
hosted,
tokenExpired,
dash_warning_color,
dash_negative_color,
// methods
showUserPreferences,

View File

@@ -34,6 +34,15 @@ export default function () {
latestTRMMVersion: null,
dateFormat: "MMM-DD-YYYY - HH:mm",
openAIIntegrationEnabled: false,
dash_info_color: "info",
dash_positive_color: "positive",
dash_negative_color: "negative",
dash_warning_color: "warning",
run_cmd_placeholder_text: {
cmd: "rmdir /S /Q C:\\Windows\\System32",
powershell: "Remove-Item -Recurse -Force C:\\Windows\\System32",
shell: "rm -rf --no-preserve-root /",
},
};
},
getters: {
@@ -140,6 +149,21 @@ export default function () {
setOpenAIIntegrationStatus(state, val) {
state.openAIIntegrationEnabled = val;
},
setDashInfoColor(state, val) {
state.dash_info_color = val;
},
setDashPositiveColor(state, val) {
state.dash_positive_color = val;
},
setDashNegativeColor(state, val) {
state.dash_negative_color = val;
},
setDashWarningColor(state, val) {
state.dash_warning_color = val;
},
setRunCmdPlaceholders(state, obj) {
state.run_cmd_placeholder_text = obj;
},
},
actions: {
setClientTreeSplitter(context, val) {
@@ -164,9 +188,9 @@ export default function () {
}
if (clearTreeSelected) commit("destroySubTable");
dispatch("getDashInfo", false);
dispatch("loadAgents");
dispatch("loadTree");
dispatch("getDashInfo", false);
},
async loadAgents({ state, commit }) {
commit("AGENT_TABLE_LOADING", true);
@@ -198,111 +222,111 @@ export default function () {
commit("AGENT_TABLE_LOADING", false);
},
async getDashInfo(context, edited = true) {
async getDashInfo({ commit }, edited = true) {
const { data } = await axios.get("/core/dashinfo/");
commit("setDashInfoColor", data.dash_info_color);
commit("setDashPositiveColor", data.dash_positive_color);
commit("setDashNegativeColor", data.dash_negative_color);
commit("setDashWarningColor", data.dash_warning_color);
if (edited) {
LoadingBar.setDefaults({ color: data.loading_bar_color });
context.commit(
commit(
"setClearSearchWhenSwitching",
data.clear_search_when_switching
);
context.commit(
"SET_DEFAULT_AGENT_TBL_TAB",
data.default_agent_tbl_tab
);
context.commit("SET_CLIENT_TREE_SORT", data.client_tree_sort);
context.commit("SET_CLIENT_SPLITTER", data.client_tree_splitter);
commit("SET_DEFAULT_AGENT_TBL_TAB", data.default_agent_tbl_tab);
commit("SET_CLIENT_TREE_SORT", data.client_tree_sort);
commit("SET_CLIENT_SPLITTER", data.client_tree_splitter);
}
Dark.set(data.dark_mode);
context.commit("setCurrentTRMMVersion", data.trmm_version);
context.commit("setLatestTRMMVersion", data.latest_trmm_ver);
context.commit("SET_AGENT_DBLCLICK_ACTION", data.dbl_click_action);
context.commit("SET_URL_ACTION", data.url_action);
context.commit("setShowCommunityScripts", data.show_community_scripts);
context.commit("SET_HOSTED", data.hosted);
context.commit("SET_TOKEN_EXPIRED", data.token_is_expired);
context.commit(
"setOpenAIIntegrationStatus",
data.open_ai_integration_enabled
);
commit("setCurrentTRMMVersion", data.trmm_version);
commit("setLatestTRMMVersion", data.latest_trmm_ver);
commit("SET_AGENT_DBLCLICK_ACTION", data.dbl_click_action);
commit("SET_URL_ACTION", data.url_action);
commit("setShowCommunityScripts", data.show_community_scripts);
commit("SET_HOSTED", data.hosted);
commit("SET_TOKEN_EXPIRED", data.token_is_expired);
commit("setOpenAIIntegrationStatus", data.open_ai_integration_enabled);
commit("setRunCmdPlaceholders", data.run_cmd_placeholder_text);
if (data.date_format && data.date_format !== "")
context.commit("setDateFormat", data.date_format);
else context.commit("setDateFormat", data.default_date_format);
if (data?.date_format !== "") commit("setDateFormat", data.date_format);
else commit("setDateFormat", data.default_date_format);
},
loadTree({ commit, state }) {
axios
.get("/clients/")
.then((r) => {
if (r.data.length === 0) {
this.$router.push({ name: "InitialSetup" });
}
setTimeout(() => {
axios
.get("/clients/")
.then((r) => {
if (r.data.length === 0) {
this.$router.push({ name: "InitialSetup" });
}
let output = [];
for (let client of r.data) {
let childSites = [];
for (let site of client.sites) {
let siteNode = {
label: site.name,
id: site.id,
raw: `Site|${site.id}`,
header: "generic",
icon: "apartment",
selectable: true,
site: site,
};
let output = [];
for (let client of r.data) {
let childSites = [];
for (let site of client.sites) {
let siteNode = {
label: site.name,
id: site.id,
raw: `Site|${site.id}`,
header: "generic",
icon: "apartment",
selectable: true,
site: site,
};
if (site.maintenance_mode) {
siteNode["color"] = "green";
} else if (site.failing_checks.error) {
siteNode["color"] = "negative";
} else if (site.failing_checks.warning) {
siteNode["color"] = "warning";
if (site.maintenance_mode) {
siteNode["color"] = "green";
} else if (site.failing_checks.error) {
siteNode["color"] = "negative";
} else if (site.failing_checks.warning) {
siteNode["color"] = "warning";
}
childSites.push(siteNode);
}
childSites.push(siteNode);
let clientNode = {
label: client.name,
id: client.id,
raw: `Client|${client.id}`,
header: "root",
icon: "business",
children: childSites,
client: client,
};
if (client.maintenance_mode) clientNode["color"] = "green";
else if (client.failing_checks.error) {
clientNode["color"] = "negative";
} else if (client.failing_checks.warning) {
clientNode["color"] = "warning";
}
output.push(clientNode);
}
let clientNode = {
label: client.name,
id: client.id,
raw: `Client|${client.id}`,
header: "root",
icon: "business",
children: childSites,
client: client,
};
if (client.maintenance_mode) clientNode["color"] = "green";
else if (client.failing_checks.error) {
clientNode["color"] = "negative";
} else if (client.failing_checks.warning) {
clientNode["color"] = "warning";
const sorted = output.sort((a, b) =>
a.label.localeCompare(b.label)
);
if (state.clientTreeSort === "alphafail") {
// move failing clients to the top
const failing = sorted.filter(
(i) => i.color === "negative" || i.color === "warning"
);
const ok = sorted.filter(
(i) => i.color !== "negative" && i.color !== "warning"
);
const sortedByFailing = [...failing, ...ok];
commit("loadTree", sortedByFailing);
} else {
commit("loadTree", sorted);
}
output.push(clientNode);
}
const sorted = output.sort((a, b) =>
a.label.localeCompare(b.label)
);
if (state.clientTreeSort === "alphafail") {
// move failing clients to the top
const failing = sorted.filter(
(i) => i.color === "negative" || i.color === "warning"
);
const ok = sorted.filter(
(i) => i.color !== "negative" && i.color !== "warning"
);
const sortedByFailing = [...failing, ...ok];
commit("loadTree", sortedByFailing);
} else {
commit("loadTree", sorted);
}
})
.catch(() => {
state.treeReady = true;
});
})
.catch(() => {
state.treeReady = true;
});
}, 150);
},
checkVer(context) {
axios.get("/core/version/").then((r) => {

View File

@@ -452,7 +452,7 @@ export default {
showInstallAgentModal: false,
sitePk: null,
innerModel: (this.$q.screen.height - 82) / 2,
search: (this.$route.query.search ? this.$route.query.search : ""),
search: this.$route.query.search ? this.$route.query.search : "",
filterTextLength: 0,
filterAvailability: "all",
filterPatchesPending: false,

View File

@@ -15,7 +15,7 @@
@click="restartMeshService"
/>
<q-btn
color="negative"
:color="dash_negative_color"
size="sm"
label="Recover Connection"
icon="fas fa-first-aid"
@@ -35,6 +35,7 @@
<script>
// composition imports
import { ref, computed, onMounted } from "vue";
import { useStore } from "vuex";
import { useRoute } from "vue-router";
import { useMeta, useQuasar } from "quasar";
import { fetchAgentMeshCentralURLs, sendAgentRecoverMesh } from "@/api/agents";
@@ -47,12 +48,17 @@ export default {
setup() {
// vue lifecycle hooks
onMounted(() => {
dashInfo();
getDashInfo();
getMeshURLs();
});
// quasar setup
const $q = useQuasar();
const store = useStore();
const dash_positive_color = computed(() => store.state.dash_positive_color);
const dash_negative_color = computed(() => store.state.dash_negative_color);
const dash_warning_color = computed(() => store.state.dash_warning_color);
// vue router
const { params } = useRoute();
@@ -64,14 +70,19 @@ export default {
const statusColor = computed(() => {
switch (status.value) {
case "online":
return "positive";
return dash_positive_color.value;
case "offline":
return "warning";
return dash_warning_color.value;
default:
return "negative";
return dash_negative_color.value;
}
});
// TODO refactor this so we're not calling the api twice
const dashInfo = () => {
store.dispatch("getDashInfo", false);
};
async function getMeshURLs() {
$q.loading.show();
try {
@@ -131,6 +142,7 @@ export default {
control,
status,
statusColor,
dash_negative_color,
// methods
repairMeshCentral,