Overview alerts (#313)
* `chore: Uncomment bucket creation during initialization` * refactor: Remove requirement for CUSTOMER_CODE field in CustomMonitoringAlertProvisionModel * chore: update dependencies in frontend * refactor: remove CustomerCode check on alert creation dialog * refactor: update template * refactor: update template * refactor: lint * `chore: Update MINIO_ROOT_PASSWORD in .env.example` * feat: add incident overview cards * refactor: update style of incident overview cards * refactor: update labels of incident overview cards * precommit fixes --------- Co-authored-by: Davide Di Modica <webmaster.ddm@gmail.com>
taylor_socfortress committed
Oct 1, 2024 at 13:06 UTC
ec3fe390df6ad1f9804eaceb162a8833ffe97244
63 files changed
+1439
-1185
.env.example
+1
@@ -8,6 +8,7 @@ MYSQL_PASSWORD=REPLACE_WITH_PASSWORD
8
9
MINIO_URL=copilot-minio
10
MINIO_ROOT_USER=admin
11
+# ! Make the password at least 8 characters long ! #
12
MINIO_ROOT_PASSWORD=REPLACE_ME
13
MINIO_SECURE=False
14
backend/app/integrations/monitoring_alert/schema/provision.py
+17
-15
@@ -6,7 +6,6 @@ from typing import Optional
6
from fastapi import HTTPException
7
from pydantic import BaseModel
8
from pydantic import Field
9
-from pydantic import root_validator
9
from pydantic import validator
10
11
@@ -254,17 +253,20 @@ class CustomMonitoringAlertProvisionModel(BaseModel):
253
example=300000,
254
)
255
257
- @root_validator
258
- def check_customer_code(cls, values):
259
- custom_fields = values.get("custom_fields")
260
- if custom_fields is None:
261
- raise HTTPException(
262
- status_code=400,
263
- detail="At least one custom field with name CUSTOMER_CODE is required",
264
- )
265
- if not any(field.name == "CUSTOMER_CODE" for field in custom_fields):
266
- raise HTTPException(
267
- status_code=400,
268
- detail="At least one custom field with name CUSTOMER_CODE is required",
269
- )
270
- return values
256
+ # ! I think I can remove the requirement for the CUSTOMER_CODE field.
257
+ # ! The new incident management doesnt require the CUSTOMER_CODE to be preset but
258
+ # ! rather looks for valid CustomerCodeKeys(Enum) # !
259
+ # @root_validator
260
+ # def check_customer_code(cls, values):
261
+ # custom_fields = values.get("custom_fields")
262
+ # if custom_fields is None:
263
+ # raise HTTPException(
264
+ # status_code=400,
265
+ # detail="At least one custom field with name CUSTOMER_CODE is required",
266
+ # )
267
+ # if not any(field.name == "CUSTOMER_CODE" for field in custom_fields):
268
+ # raise HTTPException(
269
+ # status_code=400,
270
+ # detail="At least one custom field with name CUSTOMER_CODE is required",
271
+ # )
272
+ # return values
backend/copilot.py
+1
-1
@@ -83,7 +83,7 @@ load_dotenv()
83
server_ip = os.getenv("SERVER_IP", "localhost")
84
environment = os.getenv("ENVIRONMENT", "PRODUCTION")
85
86
-# Not needed for now
86
+# ! Not needed for now maybe revist later ! #
87
# ssl_keyfile = os.path.join(os.path.dirname(__file__), "../nginx/server.key")
88
# ssl_certfile = os.path.join(os.path.dirname(__file__), "../nginx/server.crt")
89
frontend/eslint.config.mjs
+2
-1
@@ -43,6 +43,7 @@ export default antfu({
43
"vue/html-self-closing": "off",
44
"vue/singleline-html-element-content-newline": "off",
45
"vue/comma-dangle": "off",
46
- "vue/quote-props": "off"
46
+ "vue/quote-props": "off",
47
+ "vue/one-component-per-file": "off"
48
}
49
})
frontend/index.html
+1
-4
@@ -5,10 +5,7 @@
5
6
<meta charset="UTF-8" />
7
<link rel="icon" href="/favicon.ico" />
8
- <meta
9
- name="viewport"
10
- content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height"
11
- />
8
+ <meta name="viewport" content="initial-scale=1, minimum-scale=1, width=device-width, height=device-height" />
9
<meta name="mobile-web-app-capable" content="yes" />
10
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
11
<meta name="apple-mobile-web-app-title" content="SOCFortress CoPilot" />
frontend/package-lock.json
+420
-430
@@ -14,10 +14,10 @@
14
"@fontsource/lexend": "^5.1.0",
15
"@fontsource/public-sans": "^5.1.0",
16
"@popperjs/core": "^2.11.8",
17
- "@shikijs/markdown-it": "^1.18.0",
17
+ "@shikijs/markdown-it": "^1.21.0",
18
"@vueuse/components": "^11.1.0",
19
"@vueuse/core": "^11.1.0",
20
- "apexcharts": "^3.53.0",
20
+ "apexcharts": "^3.54.0",
21
"axios": "^1.7.7",
22
"bytes": "^3.1.2",
23
"colord": "^2.9.3",
@@ -31,14 +31,14 @@
31
"js-md5": "^0.8.3",
32
"lodash": "^4.17.21",
33
"mitt": "^3.0.1",
34
- "naive-ui": "^2.39.0",
34
+ "naive-ui": "^2.40.1",
35
"password-validator": "^5.3.0",
36
- "pinia": "^2.2.2",
36
+ "pinia": "^2.2.4",
37
"pinia-plugin-persistedstate": "^4.0.2",
38
"secure-ls": "^2.0.0",
39
- "shiki": "^1.18.0",
39
+ "shiki": "^1.21.0",
40
"validator": "^13.12.0",
41
- "vue": "^3.5.8",
41
+ "vue": "^3.5.10",
42
"vue-advanced-cropper": "^2.8.9",
43
"vue-highlight-words": "^3.0.1",
44
"vue-i18n": "^10.0.3",
@@ -49,7 +49,7 @@
49
"vuedraggable": "^4.1.0"
50
},
51
"devDependencies": {
52
- "@antfu/eslint-config": "^3.7.1",
52
+ "@antfu/eslint-config": "^3.7.3",
53
"@clack/prompts": "^0.7.0",
54
"@iconify/vue": "^4.1.2",
55
"@tsconfig/node20": "^20.1.4",
@@ -58,16 +58,16 @@
58
"@types/fs-extra": "^11.0.4",
59
"@types/inquirer": "^9.0.7",
60
"@types/jsdom": "^21.1.7",
61
- "@types/lodash": "^4.17.7",
62
- "@types/node": "^22.5.5",
61
+ "@types/lodash": "^4.17.9",
62
+ "@types/node": "^22.7.4",
63
"@types/validator": "^13.12.2",
64
"@vitejs/plugin-vue": "^5.1.4",
65
"@vitejs/plugin-vue-jsx": "^4.0.1",
66
"@vue/test-utils": "^2.4.6",
67
"@vue/tsconfig": "^0.5.1",
68
"autoprefixer": "^10.4.20",
69
- "cypress": "^13.14.2",
70
- "eslint": "^9.11.0",
69
+ "cypress": "^13.15.0",
70
+ "eslint": "^9.11.1",
71
"flourite": "^1.3.0",
72
"fs-extra": "^11.2.0",
73
"globals": "^15.9.0",
@@ -77,18 +77,18 @@
77
"picocolors": "^1.1.0",
78
"postcss": "^8.4.47",
79
"prettier": "^3.3.3",
80
- "sass": "^1.79.3",
80
+ "sass": "^1.79.4",
81
"start-server-and-test": "^2.0.8",
82
"tailwind-config-viewer": "^2.0.4",
83
- "tailwindcss": "^3.4.12",
84
- "taze": "^0.16.9",
83
+ "tailwindcss": "^3.4.13",
84
+ "taze": "^0.17.2",
85
"type-fest": "^4.26.1",
86
"typescript": "~5.5.4",
87
"unplugin-vue-components": "^0.27.4",
88
- "vite": "^5.4.7",
89
- "vite-bundle-analyzer": "^0.11.1",
88
+ "vite": "^5.4.8",
89
+ "vite-bundle-analyzer": "^0.12.1",
90
"vite-bundle-visualizer": "^1.2.1",
91
- "vite-plugin-vue-devtools": "^7.4.5",
91
+ "vite-plugin-vue-devtools": "^7.4.6",
92
"vite-svg-loader": "^5.1.0",
93
"vitest": "^2.1.1",
94
"vue-tsc": "^2.1.6"
@@ -97,7 +97,7 @@
97
"node": ">=18.0.0"
98
},
99
"optionalDependencies": {
100
- "@rollup/rollup-linux-x64-gnu": "^4.22.4"
100
+ "@rollup/rollup-linux-x64-gnu": "^4.23.0"
101
}
102
},
103
"node_modules/@ajoelp/json-to-formdata": {
@@ -133,9 +133,9 @@
133
}
134
},
135
"node_modules/@antfu/eslint-config": {
136
- "version": "3.7.1",
137
- "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-3.7.1.tgz",
138
- "integrity": "sha512-cDBAj+Le9XakAK83ZWVNxxyBJKeBfQ6H3VkUGnJPkXn/KJEzXC0fcHDtbu9k633hasLba5gXN5pjm4C70ik+Fg==",
136
+ "version": "3.7.3",
137
+ "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-3.7.3.tgz",
138
+ "integrity": "sha512-vzhKtzQT+f/xBV8T5U8SFy3D7uAqL2CEcjsJVqtA7F8tdKvGuC/96uWeEKMHk5lRfijgj+xRvb+c4qQn60YlIA==",
139
"dev": true,
140
"dependencies": {
141
"@antfu/install-pkg": "^0.4.1",
@@ -143,20 +143,20 @@
143
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",
144
"@eslint/markdown": "^6.1.0",
145
"@stylistic/eslint-plugin": "^2.8.0",
146
- "@typescript-eslint/eslint-plugin": "^8.6.0",
147
- "@typescript-eslint/parser": "^8.6.0",
146
+ "@typescript-eslint/eslint-plugin": "^8.7.0",
147
+ "@typescript-eslint/parser": "^8.7.0",
148
"@vitest/eslint-plugin": "^1.1.4",
149
"eslint-config-flat-gitignore": "^0.3.0",
150
"eslint-flat-config-utils": "^0.4.0",
151
"eslint-merge-processors": "^0.1.0",
152
"eslint-plugin-antfu": "^2.7.0",
153
- "eslint-plugin-command": "^0.2.5",
154
- "eslint-plugin-import-x": "^4.2.1",
155
- "eslint-plugin-jsdoc": "^50.2.4",
153
+ "eslint-plugin-command": "^0.2.6",
154
+ "eslint-plugin-import-x": "^4.3.0",
155
+ "eslint-plugin-jsdoc": "^50.3.0",
156
"eslint-plugin-jsonc": "^2.16.0",
157
"eslint-plugin-n": "^17.10.3",
158
"eslint-plugin-no-only-tests": "^3.3.0",
159
- "eslint-plugin-perfectionist": "^3.6.0",
159
+ "eslint-plugin-perfectionist": "^3.7.0",
160
"eslint-plugin-regexp": "^2.6.0",
161
"eslint-plugin-toml": "^0.11.1",
162
"eslint-plugin-unicorn": "^55.0.0",
@@ -687,17 +687,6 @@
687
"@babel/core": "^7.0.0-0"
688
}
689
},
690
- "node_modules/@babel/runtime": {
691
- "version": "7.25.6",
692
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz",
693
- "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==",
694
- "dependencies": {
695
- "regenerator-runtime": "^0.14.0"
696
- },
697
- "engines": {
698
- "node": ">=6.9.0"
699
- }
700
- },
690
"node_modules/@babel/standalone": {
691
"version": "7.25.6",
692
"resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.25.6.tgz",
@@ -784,7 +773,6 @@
773
},
774
"node_modules/@clack/prompts/node_modules/is-unicode-supported": {
775
"version": "1.3.0",
787
- "dev": true,
776
"inBundle": true,
777
"license": "MIT",
778
"engines": {
@@ -1365,6 +1353,14 @@
1353
"node": "*"
1354
}
1355
},
1356
+ "node_modules/@eslint/core": {
1357
+ "version": "0.6.0",
1358
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz",
1359
+ "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==",
1360
+ "engines": {
1361
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
1362
+ }
1363
+ },
1364
"node_modules/@eslint/eslintrc": {
1365
"version": "3.1.0",
1366
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
@@ -1427,20 +1423,18 @@
1423
}
1424
},
1425
"node_modules/@eslint/markdown": {
1430
- "version": "6.1.0",
1431
- "resolved": "https://registry.npmjs.org/@eslint/markdown/-/markdown-6.1.0.tgz",
1432
- "integrity": "sha512-cX1tyD+aIbhzKrCKe/9M5s2jZhldWGOR+cy7cIVpxG9RkoaN4XU+gG3dy6oEKtBFXjDx06GtP0OGO7jgbqa2DA==",
1426
+ "version": "6.1.1",
1427
+ "resolved": "https://registry.npmjs.org/@eslint/markdown/-/markdown-6.1.1.tgz",
1428
+ "integrity": "sha512-Z+1js5AeqidwhNBbnIPM6Fn4eY9D5i1NleamS0UBW6BG0J4lpvhIVOKVIi22kmH5gvxDmHUp5MHkkkjda0TehA==",
1429
"dev": true,
1430
"dependencies": {
1431
+ "@eslint/plugin-kit": "^0.2.0",
1432
"mdast-util-from-markdown": "^2.0.1",
1433
"mdast-util-gfm": "^3.0.0",
1434
"micromark-extension-gfm": "^3.0.0"
1435
},
1436
"engines": {
1437
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
1441
- },
1442
- "peerDependencies": {
1443
- "eslint": ">=9"
1438
}
1439
},
1440
"node_modules/@eslint/object-schema": {
@@ -2181,9 +2175,9 @@
2175
}
2176
},
2177
"node_modules/@rollup/pluginutils": {
2184
- "version": "5.1.1",
2185
- "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.1.tgz",
2186
- "integrity": "sha512-bVRmQqBIyGD+VMihdEV2IBurfIrdW9tD9yzJUL3CBRDbyPBVzQnBSMSgyUZHl1E335rpMRj7r4o683fXLYw8iw==",
2178
+ "version": "5.1.2",
2179
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz",
2180
+ "integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==",
2181
"dependencies": {
2182
"@types/estree": "^1.0.0",
2183
"estree-walker": "^2.0.2",
@@ -2213,9 +2207,9 @@
2207
}
2208
},
2209
"node_modules/@rollup/rollup-android-arm-eabi": {
2216
- "version": "4.22.4",
2217
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz",
2218
- "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==",
2210
+ "version": "4.22.5",
2211
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.5.tgz",
2212
+ "integrity": "sha512-SU5cvamg0Eyu/F+kLeMXS7GoahL+OoizlclVFX3l5Ql6yNlywJJ0OuqTzUx0v+aHhPHEB/56CT06GQrRrGNYww==",
2213
"cpu": [
2214
"arm"
2215
],
@@ -2226,9 +2220,9 @@
2220
]
2221
},
2222
"node_modules/@rollup/rollup-android-arm64": {
2229
- "version": "4.22.4",
2230
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz",
2231
- "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==",
2223
+ "version": "4.22.5",
2224
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.5.tgz",
2225
+ "integrity": "sha512-S4pit5BP6E5R5C8S6tgU/drvgjtYW76FBuG6+ibG3tMvlD1h9LHVF9KmlmaUBQ8Obou7hEyS+0w+IR/VtxwNMQ==",
2226
"cpu": [
2227
"arm64"
2228
],
@@ -2239,9 +2233,9 @@
2233
]
2234
},
2235
"node_modules/@rollup/rollup-darwin-arm64": {
2242
- "version": "4.22.4",
2243
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz",
2244
- "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==",
2236
+ "version": "4.22.5",
2237
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.5.tgz",
2238
+ "integrity": "sha512-250ZGg4ipTL0TGvLlfACkIxS9+KLtIbn7BCZjsZj88zSg2Lvu3Xdw6dhAhfe/FjjXPVNCtcSp+WZjVsD3a/Zlw==",
2239
"cpu": [
2240
"arm64"
2241
],
@@ -2252,9 +2246,9 @@
2246
]
2247
},
2248
"node_modules/@rollup/rollup-darwin-x64": {
2255
- "version": "4.22.4",
2256
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz",
2257
- "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==",
2249
+ "version": "4.22.5",
2250
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.5.tgz",
2251
+ "integrity": "sha512-D8brJEFg5D+QxFcW6jYANu+Rr9SlKtTenmsX5hOSzNYVrK5oLAEMTUgKWYJP+wdKyCdeSwnapLsn+OVRFycuQg==",
2252
"cpu": [
2253
"x64"
2254
],
@@ -2265,9 +2259,9 @@
2259
]
2260
},
2261
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
2268
- "version": "4.22.4",
2269
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz",
2270
- "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==",
2262
+ "version": "4.22.5",
2263
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.5.tgz",
2264
+ "integrity": "sha512-PNqXYmdNFyWNg0ma5LdY8wP+eQfdvyaBAojAXgO7/gs0Q/6TQJVXAXe8gwW9URjbS0YAammur0fynYGiWsKlXw==",
2265
"cpu": [
2266
"arm"
2267
],
@@ -2278,9 +2272,9 @@
2272
]
2273
},
2274
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
2281
- "version": "4.22.4",
2282
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz",
2283
- "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==",
2275
+ "version": "4.22.5",
2276
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.5.tgz",
2277
+ "integrity": "sha512-kSSCZOKz3HqlrEuwKd9TYv7vxPYD77vHSUvM2y0YaTGnFc8AdI5TTQRrM1yIp3tXCKrSL9A7JLoILjtad5t8pQ==",
2278
"cpu": [
2279
"arm"
2280
],
@@ -2291,9 +2285,9 @@
2285
]
2286
},
2287
"node_modules/@rollup/rollup-linux-arm64-gnu": {
2294
- "version": "4.22.4",
2295
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz",
2296
- "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==",
2288
+ "version": "4.22.5",
2289
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.5.tgz",
2290
+ "integrity": "sha512-oTXQeJHRbOnwRnRffb6bmqmUugz0glXaPyspp4gbQOPVApdpRrY/j7KP3lr7M8kTfQTyrBUzFjj5EuHAhqH4/w==",
2291
"cpu": [
2292
"arm64"
2293
],
@@ -2304,9 +2298,9 @@
2298
]
2299
},
2300
"node_modules/@rollup/rollup-linux-arm64-musl": {
2307
- "version": "4.22.4",
2308
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz",
2309
- "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==",
2301
+ "version": "4.22.5",
2302
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.5.tgz",
2303
+ "integrity": "sha512-qnOTIIs6tIGFKCHdhYitgC2XQ2X25InIbZFor5wh+mALH84qnFHvc+vmWUpyX97B0hNvwNUL4B+MB8vJvH65Fw==",
2304
"cpu": [
2305
"arm64"
2306
],
@@ -2317,9 +2311,9 @@
2311
]
2312
},
2313
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
2320
- "version": "4.22.4",
2321
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz",
2322
- "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==",
2314
+ "version": "4.22.5",
2315
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.5.tgz",
2316
+ "integrity": "sha512-TMYu+DUdNlgBXING13rHSfUc3Ky5nLPbWs4bFnT+R6Vu3OvXkTkixvvBKk8uO4MT5Ab6lC3U7x8S8El2q5o56w==",
2317
"cpu": [
2318
"ppc64"
2319
],
@@ -2330,9 +2324,9 @@
2324
]
2325
},
2326
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
2333
- "version": "4.22.4",
2334
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz",
2335
- "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==",
2327
+ "version": "4.22.5",
2328
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.5.tgz",
2329
+ "integrity": "sha512-PTQq1Kz22ZRvuhr3uURH+U/Q/a0pbxJoICGSprNLAoBEkyD3Sh9qP5I0Asn0y0wejXQBbsVMRZRxlbGFD9OK4A==",
2330
"cpu": [
2331
"riscv64"
2332
],
@@ -2343,9 +2337,9 @@
2337
]
2338
},
2339
"node_modules/@rollup/rollup-linux-s390x-gnu": {
2346
- "version": "4.22.4",
2347
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz",
2348
- "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==",
2340
+ "version": "4.22.5",
2341
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.5.tgz",
2342
+ "integrity": "sha512-bR5nCojtpuMss6TDEmf/jnBnzlo+6n1UhgwqUvRoe4VIotC7FG1IKkyJbwsT7JDsF2jxR+NTnuOwiGv0hLyDoQ==",
2343
"cpu": [
2344
"s390x"
2345
],
@@ -2356,9 +2350,9 @@
2350
]
2351
},
2352
"node_modules/@rollup/rollup-linux-x64-gnu": {
2359
- "version": "4.22.4",
2360
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz",
2361
- "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==",
2353
+ "version": "4.23.0",
2354
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.23.0.tgz",
2355
+ "integrity": "sha512-I/eXsdVoCKtSgK9OwyQKPAfricWKUMNCwJKtatRYMmDo5N859tbO3UsBw5kT3dU1n6ZcM1JDzPRSGhAUkxfLxw==",
2356
"cpu": [
2357
"x64"
2358
],
@@ -2368,9 +2362,9 @@
2362
]
2363
},
2364
"node_modules/@rollup/rollup-linux-x64-musl": {
2371
- "version": "4.22.4",
2372
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz",
2373
- "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==",
2365
+ "version": "4.22.5",
2366
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.5.tgz",
2367
+ "integrity": "sha512-uBa2e28ohzNNwjr6Uxm4XyaA1M/8aTgfF2T7UIlElLaeXkgpmIJ2EitVNQxjO9xLLLy60YqAgKn/AqSpCUkE9g==",
2368
"cpu": [
2369
"x64"
2370
],
@@ -2381,9 +2375,9 @@
2375
]
2376
},
2377
"node_modules/@rollup/rollup-win32-arm64-msvc": {
2384
- "version": "4.22.4",
2385
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz",
2386
- "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==",
2378
+ "version": "4.22.5",
2379
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.5.tgz",
2380
+ "integrity": "sha512-RXT8S1HP8AFN/Kr3tg4fuYrNxZ/pZf1HemC5Tsddc6HzgGnJm0+Lh5rAHJkDuW3StI0ynNXukidROMXYl6ew8w==",
2381
"cpu": [
2382
"arm64"
2383
],
@@ -2394,9 +2388,9 @@
2388
]
2389
},
2390
"node_modules/@rollup/rollup-win32-ia32-msvc": {
2397
- "version": "4.22.4",
2398
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz",
2399
- "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==",
2391
+ "version": "4.22.5",
2392
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.5.tgz",
2393
+ "integrity": "sha512-ElTYOh50InL8kzyUD6XsnPit7jYCKrphmddKAe1/Ytt74apOxDq5YEcbsiKs0fR3vff3jEneMM+3I7jbqaMyBg==",
2394
"cpu": [
2395
"ia32"
2396
],
@@ -2407,9 +2401,9 @@
2401
]
2402
},
2403
"node_modules/@rollup/rollup-win32-x64-msvc": {
2410
- "version": "4.22.4",
2411
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz",
2412
- "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==",
2404
+ "version": "4.22.5",
2405
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.5.tgz",
2406
+ "integrity": "sha512-+lvL/4mQxSV8MukpkKyyvfwhH266COcWlXE/1qxwN08ajovta3459zrjLghYMgDerlzNwLAcFpvU+WWE5y6nAQ==",
2407
"cpu": [
2408
"x64"
2409
],
@@ -2420,50 +2414,50 @@
2414
]
2415
},
2416
"node_modules/@shikijs/core": {
2423
- "version": "1.18.0",
2424
- "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.18.0.tgz",
2425
- "integrity": "sha512-VK4BNVCd2leY62Nm2JjyxtRLkyrZT/tv104O81eyaCjHq4Adceq2uJVFJJAIof6lT1mBwZrEo2qT/T+grv3MQQ==",
2417
+ "version": "1.21.0",
2418
+ "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.21.0.tgz",
2419
+ "integrity": "sha512-zAPMJdiGuqXpZQ+pWNezQAk5xhzRXBNiECFPcJLtUdsFM3f//G95Z15EHTnHchYycU8kIIysqGgxp8OVSj1SPQ==",
2420
"dependencies": {
2427
- "@shikijs/engine-javascript": "1.18.0",
2428
- "@shikijs/engine-oniguruma": "1.18.0",
2429
- "@shikijs/types": "1.18.0",
2421
+ "@shikijs/engine-javascript": "1.21.0",
2422
+ "@shikijs/engine-oniguruma": "1.21.0",
2423
+ "@shikijs/types": "1.21.0",
2424
"@shikijs/vscode-textmate": "^9.2.2",
2425
"@types/hast": "^3.0.4",
2426
"hast-util-to-html": "^9.0.3"
2427
}
2428
},
2429
"node_modules/@shikijs/engine-javascript": {
2436
- "version": "1.18.0",
2437
- "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.18.0.tgz",
2438
- "integrity": "sha512-qoP/aO/ATNwYAUw1YMdaip/YVEstMZEgrwhePm83Ll9OeQPuxDZd48szZR8oSQNQBT8m8UlWxZv8EA3lFuyI5A==",
2430
+ "version": "1.21.0",
2431
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.21.0.tgz",
2432
+ "integrity": "sha512-jxQHNtVP17edFW4/0vICqAVLDAxmyV31MQJL4U/Kg+heQALeKYVOWo0sMmEZ18FqBt+9UCdyqGKYE7bLRtk9mg==",
2433
"dependencies": {
2440
- "@shikijs/types": "1.18.0",
2434
+ "@shikijs/types": "1.21.0",
2435
"@shikijs/vscode-textmate": "^9.2.2",
2436
"oniguruma-to-js": "0.4.3"
2437
}
2438
},
2439
"node_modules/@shikijs/engine-oniguruma": {
2446
- "version": "1.18.0",
2447
- "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.18.0.tgz",
2448
- "integrity": "sha512-B9u0ZKI/cud+TcmF8Chyh+R4V5qQVvyDOqXC2l2a4x73PBSBc6sZ0JRAX3eqyJswqir6ktwApUUGBYePdKnMJg==",
2440
+ "version": "1.21.0",
2441
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.21.0.tgz",
2442
+ "integrity": "sha512-AIZ76XocENCrtYzVU7S4GY/HL+tgHGbVU+qhiDyNw1qgCA5OSi4B4+HY4BtAoJSMGuD/L5hfTzoRVbzEm2WTvg==",
2443
"dependencies": {
2450
- "@shikijs/types": "1.18.0",
2444
+ "@shikijs/types": "1.21.0",
2445
"@shikijs/vscode-textmate": "^9.2.2"
2446
}
2447
},
2448
"node_modules/@shikijs/markdown-it": {
2455
- "version": "1.18.0",
2456
- "resolved": "https://registry.npmjs.org/@shikijs/markdown-it/-/markdown-it-1.18.0.tgz",
2457
- "integrity": "sha512-acU44AAYYk7cESJbpEmcmLP5KJzuIUBzuCHcVd4glJPRK1UYc7Pqfg/chKv0DFYsC0u5BdFT15Od959tPA3xJQ==",
2449
+ "version": "1.21.0",
2450
+ "resolved": "https://registry.npmjs.org/@shikijs/markdown-it/-/markdown-it-1.21.0.tgz",
2451
+ "integrity": "sha512-wNvze11LNnhNc3NpGG7Y2Jxlecta85bd1QRltB+oqtug4w63BtjzTQubpB3NWwXTWXf91iVlmbo8Sp9mrmZVGQ==",
2452
"dependencies": {
2453
"markdown-it": "^14.1.0",
2460
- "shiki": "1.18.0"
2454
+ "shiki": "1.21.0"
2455
}
2456
},
2457
"node_modules/@shikijs/types": {
2464
- "version": "1.18.0",
2465
- "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.18.0.tgz",
2466
- "integrity": "sha512-O9N36UEaGGrxv1yUrN2nye7gDLG5Uq0/c1LyfmxsvzNPqlHzWo9DI0A4+fhW2y3bGKuQu/fwS7EPdKJJCowcVA==",
2458
+ "version": "1.21.0",
2459
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.21.0.tgz",
2460
+ "integrity": "sha512-tzndANDhi5DUndBtpojEq/42+dpUF2wS7wdCDQaFtIXm3Rd1QkrcVgSSRLOvEwexekihOXfbYJINW37g96tJRw==",
2461
"dependencies": {
2462
"@shikijs/vscode-textmate": "^9.2.2",
2463
"@types/hast": "^3.0.4"
@@ -2625,9 +2619,9 @@
2619
"integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ=="
2620
},
2621
"node_modules/@types/lodash": {
2628
- "version": "4.17.7",
2629
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz",
2630
- "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA=="
2622
+ "version": "4.17.9",
2623
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.9.tgz",
2624
+ "integrity": "sha512-w9iWudx1XWOHW5lQRS9iKpK/XuRhnN+0T7HvdCCd802FYkT1AMTnxndJHGrNJwRoRHkslGr4S29tjm1cT7x/7w=="
2625
},
2626
"node_modules/@types/lodash-es": {
2627
"version": "4.17.12",
@@ -2652,9 +2646,9 @@
2646
"dev": true
2647
},
2648
"node_modules/@types/node": {
2655
- "version": "22.5.5",
2656
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz",
2657
- "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==",
2649
+ "version": "22.7.4",
2650
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz",
2651
+ "integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==",
2652
"dev": true,
2653
"dependencies": {
2654
"undici-types": "~6.19.2"
@@ -2725,16 +2719,16 @@
2719
}
2720
},
2721
"node_modules/@typescript-eslint/eslint-plugin": {
2728
- "version": "8.6.0",
2729
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.6.0.tgz",
2730
- "integrity": "sha512-UOaz/wFowmoh2G6Mr9gw60B1mm0MzUtm6Ic8G2yM1Le6gyj5Loi/N+O5mocugRGY+8OeeKmkMmbxNqUCq3B4Sg==",
2722
+ "version": "8.7.0",
2723
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz",
2724
+ "integrity": "sha512-RIHOoznhA3CCfSTFiB6kBGLQtB/sox+pJ6jeFu6FxJvqL8qRxq/FfGO/UhsGgQM9oGdXkV4xUgli+dt26biB6A==",
2725
"dev": true,
2726
"dependencies": {
2727
"@eslint-community/regexpp": "^4.10.0",
2734
- "@typescript-eslint/scope-manager": "8.6.0",
2735
- "@typescript-eslint/type-utils": "8.6.0",
2736
- "@typescript-eslint/utils": "8.6.0",
2737
- "@typescript-eslint/visitor-keys": "8.6.0",
2728
+ "@typescript-eslint/scope-manager": "8.7.0",
2729
+ "@typescript-eslint/type-utils": "8.7.0",
2730
+ "@typescript-eslint/utils": "8.7.0",
2731
+ "@typescript-eslint/visitor-keys": "8.7.0",
2732
"graphemer": "^1.4.0",
2733
"ignore": "^5.3.1",
2734
"natural-compare": "^1.4.0",
@@ -2758,15 +2752,15 @@
2752
}
2753
},
2754
"node_modules/@typescript-eslint/parser": {
2761
- "version": "8.6.0",
2762
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.6.0.tgz",
2763
- "integrity": "sha512-eQcbCuA2Vmw45iGfcyG4y6rS7BhWfz9MQuk409WD47qMM+bKCGQWXxvoOs1DUp+T7UBMTtRTVT+kXr7Sh4O9Ow==",
2755
+ "version": "8.7.0",
2756
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.7.0.tgz",
2757
+ "integrity": "sha512-lN0btVpj2unxHlNYLI//BQ7nzbMJYBVQX5+pbNXvGYazdlgYonMn4AhhHifQ+J4fGRYA/m1DjaQjx+fDetqBOQ==",
2758
"dev": true,
2759
"dependencies": {
2766
- "@typescript-eslint/scope-manager": "8.6.0",
2767
- "@typescript-eslint/types": "8.6.0",
2768
- "@typescript-eslint/typescript-estree": "8.6.0",
2769
- "@typescript-eslint/visitor-keys": "8.6.0",
2760
+ "@typescript-eslint/scope-manager": "8.7.0",
2761
+ "@typescript-eslint/types": "8.7.0",
2762
+ "@typescript-eslint/typescript-estree": "8.7.0",
2763
+ "@typescript-eslint/visitor-keys": "8.7.0",
2764
"debug": "^4.3.4"
2765
},
2766
"engines": {
@@ -2786,13 +2780,13 @@
2780
}
2781
},
2782
"node_modules/@typescript-eslint/scope-manager": {
2789
- "version": "8.6.0",
2790
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.6.0.tgz",
2791
- "integrity": "sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==",
2783
+ "version": "8.7.0",
2784
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz",
2785
+ "integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==",
2786
"dev": true,
2787
"dependencies": {
2794
- "@typescript-eslint/types": "8.6.0",
2795
- "@typescript-eslint/visitor-keys": "8.6.0"
2788
+ "@typescript-eslint/types": "8.7.0",
2789
+ "@typescript-eslint/visitor-keys": "8.7.0"
2790
},
2791
"engines": {
2792
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2803,13 +2797,13 @@
2797
}
2798
},
2799
"node_modules/@typescript-eslint/type-utils": {
2806
- "version": "8.6.0",
2807
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.6.0.tgz",
2808
- "integrity": "sha512-dtePl4gsuenXVwC7dVNlb4mGDcKjDT/Ropsk4za/ouMBPplCLyznIaR+W65mvCvsyS97dymoBRrioEXI7k0XIg==",
2800
+ "version": "8.7.0",
2801
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.7.0.tgz",
2802
+ "integrity": "sha512-tl0N0Mj3hMSkEYhLkjREp54OSb/FI6qyCzfiiclvJvOqre6hsZTGSnHtmFLDU8TIM62G7ygEa1bI08lcuRwEnQ==",
2803
"dev": true,
2804
"dependencies": {
2811
- "@typescript-eslint/typescript-estree": "8.6.0",
2812
- "@typescript-eslint/utils": "8.6.0",
2805
+ "@typescript-eslint/typescript-estree": "8.7.0",
2806
+ "@typescript-eslint/utils": "8.7.0",
2807
"debug": "^4.3.4",
2808
"ts-api-utils": "^1.3.0"
2809
},
@@ -2827,9 +2821,9 @@
2821
}
2822
},
2823
"node_modules/@typescript-eslint/types": {
2830
- "version": "8.6.0",
2831
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.6.0.tgz",
2832
- "integrity": "sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==",
2824
+ "version": "8.7.0",
2825
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz",
2826
+ "integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==",
2827
"dev": true,
2828
"engines": {
2829
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2840,13 +2834,13 @@
2834
}
2835
},
2836
"node_modules/@typescript-eslint/typescript-estree": {
2843
- "version": "8.6.0",
2844
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.6.0.tgz",
2845
- "integrity": "sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==",
2837
+ "version": "8.7.0",
2838
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz",
2839
+ "integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==",
2840
"dev": true,
2841
"dependencies": {
2848
- "@typescript-eslint/types": "8.6.0",
2849
- "@typescript-eslint/visitor-keys": "8.6.0",
2842
+ "@typescript-eslint/types": "8.7.0",
2843
+ "@typescript-eslint/visitor-keys": "8.7.0",
2844
"debug": "^4.3.4",
2845
"fast-glob": "^3.3.2",
2846
"is-glob": "^4.0.3",
@@ -2868,15 +2862,15 @@
2862
}
2863
},
2864
"node_modules/@typescript-eslint/utils": {
2871
- "version": "8.6.0",
2872
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.6.0.tgz",
2873
- "integrity": "sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==",
2865
+ "version": "8.7.0",
2866
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz",
2867
+ "integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==",
2868
"dev": true,
2869
"dependencies": {
2870
"@eslint-community/eslint-utils": "^4.4.0",
2877
- "@typescript-eslint/scope-manager": "8.6.0",
2878
- "@typescript-eslint/types": "8.6.0",
2879
- "@typescript-eslint/typescript-estree": "8.6.0"
2871
+ "@typescript-eslint/scope-manager": "8.7.0",
2872
+ "@typescript-eslint/types": "8.7.0",
2873
+ "@typescript-eslint/typescript-estree": "8.7.0"
2874
},
2875
"engines": {
2876
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2890,12 +2884,12 @@
2884
}
2885
},
2886
"node_modules/@typescript-eslint/visitor-keys": {
2893
- "version": "8.6.0",
2894
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.6.0.tgz",
2895
- "integrity": "sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==",
2887
+ "version": "8.7.0",
2888
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz",
2889
+ "integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==",
2890
"dev": true,
2891
"dependencies": {
2898
- "@typescript-eslint/types": "8.6.0",
2892
+ "@typescript-eslint/types": "8.7.0",
2893
"eslint-visitor-keys": "^3.4.3"
2894
},
2895
"engines": {
@@ -3648,36 +3642,36 @@
3642
}
3643
},
3644
"node_modules/@vue/compiler-core": {
3651
- "version": "3.5.8",
3652
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.8.tgz",
3653
- "integrity": "sha512-Uzlxp91EPjfbpeO5KtC0KnXPkuTfGsNDeaKQJxQN718uz+RqDYarEf7UhQJGK+ZYloD2taUbHTI2J4WrUaZQNA==",
3645
+ "version": "3.5.10",
3646
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.10.tgz",
3647
+ "integrity": "sha512-iXWlk+Cg/ag7gLvY0SfVucU8Kh2CjysYZjhhP70w9qI4MvSox4frrP+vDGvtQuzIcgD8+sxM6lZvCtdxGunTAA==",
3648
"dependencies": {
3649
"@babel/parser": "^7.25.3",
3656
- "@vue/shared": "3.5.8",
3650
+ "@vue/shared": "3.5.10",
3651
"entities": "^4.5.0",
3652
"estree-walker": "^2.0.2",
3653
"source-map-js": "^1.2.0"
3654
}
3655
},
3656
"node_modules/@vue/compiler-dom": {
3663
- "version": "3.5.8",
3664
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.8.tgz",
3665
- "integrity": "sha512-GUNHWvoDSbSa5ZSHT9SnV5WkStWfzJwwTd6NMGzilOE/HM5j+9EB9zGXdtu/fCNEmctBqMs6C9SvVPpVPuk1Eg==",
3657
+ "version": "3.5.10",
3658
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.10.tgz",
3659
+ "integrity": "sha512-DyxHC6qPcktwYGKOIy3XqnHRrrXyWR2u91AjP+nLkADko380srsC2DC3s7Y1Rk6YfOlxOlvEQKa9XXmLI+W4ZA==",
3660
"dependencies": {
3667
- "@vue/compiler-core": "3.5.8",
3668
- "@vue/shared": "3.5.8"
3661
+ "@vue/compiler-core": "3.5.10",
3662
+ "@vue/shared": "3.5.10"
3663
}
3664
},
3665
"node_modules/@vue/compiler-sfc": {
3672
- "version": "3.5.8",
3673
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.8.tgz",
3674
- "integrity": "sha512-taYpngQtSysrvO9GULaOSwcG5q821zCoIQBtQQSx7Uf7DxpR6CIHR90toPr9QfDD2mqHQPCSgoWBvJu0yV9zjg==",
3666
+ "version": "3.5.10",
3667
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.10.tgz",
3668
+ "integrity": "sha512-to8E1BgpakV7224ZCm8gz1ZRSyjNCAWEplwFMWKlzCdP9DkMKhRRwt0WkCjY7jkzi/Vz3xgbpeig5Pnbly4Tow==",
3669
"dependencies": {
3670
"@babel/parser": "^7.25.3",
3677
- "@vue/compiler-core": "3.5.8",
3678
- "@vue/compiler-dom": "3.5.8",
3679
- "@vue/compiler-ssr": "3.5.8",
3680
- "@vue/shared": "3.5.8",
3671
+ "@vue/compiler-core": "3.5.10",
3672
+ "@vue/compiler-dom": "3.5.10",
3673
+ "@vue/compiler-ssr": "3.5.10",
3674
+ "@vue/shared": "3.5.10",
3675
"estree-walker": "^2.0.2",
3676
"magic-string": "^0.30.11",
3677
"postcss": "^8.4.47",
@@ -3685,12 +3679,12 @@
3679
}
3680
},
3681
"node_modules/@vue/compiler-ssr": {
3688
- "version": "3.5.8",
3689
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.8.tgz",
3690
- "integrity": "sha512-W96PtryNsNG9u0ZnN5Q5j27Z/feGrFV6zy9q5tzJVyJaLiwYxvC0ek4IXClZygyhjm+XKM7WD9pdKi/wIRVC/Q==",
3682
+ "version": "3.5.10",
3683
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.10.tgz",
3684
+ "integrity": "sha512-hxP4Y3KImqdtyUKXDRSxKSRkSm1H9fCvhojEYrnaoWhE4w/y8vwWhnosJoPPe2AXm5sU7CSbYYAgkt2ZPhDz+A==",
3685
"dependencies": {
3692
- "@vue/compiler-dom": "3.5.8",
3693
- "@vue/shared": "3.5.8"
3686
+ "@vue/compiler-dom": "3.5.10",
3687
+ "@vue/shared": "3.5.10"
3688
}
3689
},
3690
"node_modules/@vue/compiler-vue2": {
@@ -3709,13 +3703,13 @@
3703
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="
3704
},
3705
"node_modules/@vue/devtools-core": {
3712
- "version": "7.4.5",
3713
- "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.4.5.tgz",
3714
- "integrity": "sha512-QwrgKYxwafJUJrKRvJGbzQLuGt0BC1P4qTr4qlEKgOOs+GV0n6zTry2oeHiwmj5H6pOkLoHnwFMOTB9rFtn9QQ==",
3706
+ "version": "7.4.6",
3707
+ "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.4.6.tgz",
3708
+ "integrity": "sha512-7ATNPEbVqThOOAp2bg/YUIm9MqqgimbSk24D05hdXUp89JlXX12aTzdrWd9xZRwS78hDR+wCToHl1C/8sopBrg==",
3709
"dev": true,
3710
"dependencies": {
3717
- "@vue/devtools-kit": "^7.4.5",
3718
- "@vue/devtools-shared": "^7.4.5",
3711
+ "@vue/devtools-kit": "^7.4.6",
3712
+ "@vue/devtools-shared": "^7.4.6",
3713
"mitt": "^3.0.1",
3714
"nanoid": "^3.3.4",
3715
"pathe": "^1.1.2",
@@ -3726,12 +3720,12 @@
3720
}
3721
},
3722
"node_modules/@vue/devtools-kit": {
3729
- "version": "7.4.5",
3730
- "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.4.5.tgz",
3731
- "integrity": "sha512-Uuki4Z6Bc/ExvtlPkeDNGSAe4580R+HPcVABfTE9TF7BTz3Nntk7vxIRUyWblZkUEcB/x+wn2uofyt5i2LaUew==",
3723
+ "version": "7.4.6",
3724
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.4.6.tgz",
3725
+ "integrity": "sha512-NbYBwPWgEic1AOd9bWExz9weBzFdjiIfov0yRn4DrRfR+EQJCI9dn4I0XS7IxYGdkmUJi8mFW42LLk18WsGqew==",
3726
"dev": true,
3727
"dependencies": {
3734
- "@vue/devtools-shared": "^7.4.5",
3728
+ "@vue/devtools-shared": "^7.4.6",
3729
"birpc": "^0.2.17",
3730
"hookable": "^5.5.3",
3731
"mitt": "^3.0.1",
@@ -3741,9 +3735,9 @@
3735
}
3736
},
3737
"node_modules/@vue/devtools-shared": {
3744
- "version": "7.4.5",
3745
- "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.4.5.tgz",
3746
- "integrity": "sha512-2XgUOkL/7QDmyYI9J7cm+rz/qBhcGv+W5+i1fhwdQ0HQ1RowhdK66F0QBuJSz/5k12opJY8eN6m03/XZMs7imQ==",
3738
+ "version": "7.4.6",
3739
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.4.6.tgz",
3740
+ "integrity": "sha512-rPeSBzElnHYMB05Cc056BQiJpgocQjY8XVulgni+O9a9Gr9tNXgPteSzFFD+fT/iWMxNuUgGKs9CuW5DZewfIg==",
3741
"dev": true,
3742
"dependencies": {
3743
"rfdc": "^1.4.1"
@@ -3774,49 +3768,49 @@
3768
}
3769
},
3770
"node_modules/@vue/reactivity": {
3777
- "version": "3.5.8",
3778
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.8.tgz",
3779
- "integrity": "sha512-mlgUyFHLCUZcAYkqvzYnlBRCh0t5ZQfLYit7nukn1GR96gc48Bp4B7OIcSfVSvlG1k3BPfD+p22gi1t2n9tsXg==",
3771
+ "version": "3.5.10",
3772
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.10.tgz",
3773
+ "integrity": "sha512-kW08v06F6xPSHhid9DJ9YjOGmwNDOsJJQk0ax21wKaUYzzuJGEuoKNU2Ujux8FLMrP7CFJJKsHhXN9l2WOVi2g==",
3774
"dependencies": {
3781
- "@vue/shared": "3.5.8"
3775
+ "@vue/shared": "3.5.10"
3776
}
3777
},
3778
"node_modules/@vue/runtime-core": {
3785
- "version": "3.5.8",
3786
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.8.tgz",
3787
- "integrity": "sha512-fJuPelh64agZ8vKkZgp5iCkPaEqFJsYzxLk9vSC0X3G8ppknclNDr61gDc45yBGTaN5Xqc1qZWU3/NoaBMHcjQ==",
3779
+ "version": "3.5.10",
3780
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.10.tgz",
3781
+ "integrity": "sha512-9Q86I5Qq3swSkFfzrZ+iqEy7Vla325M7S7xc1NwKnRm/qoi1Dauz0rT6mTMmscqx4qz0EDJ1wjB+A36k7rl8mA==",
3782
"dependencies": {
3789
- "@vue/reactivity": "3.5.8",
3790
- "@vue/shared": "3.5.8"
3783
+ "@vue/reactivity": "3.5.10",
3784
+ "@vue/shared": "3.5.10"
3785
}
3786
},
3787
"node_modules/@vue/runtime-dom": {
3794
- "version": "3.5.8",
3795
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.8.tgz",
3796
- "integrity": "sha512-DpAUz+PKjTZPUOB6zJgkxVI3GuYc2iWZiNeeHQUw53kdrparSTG6HeXUrYDjaam8dVsCdvQxDz6ZWxnyjccUjQ==",
3788
+ "version": "3.5.10",
3789
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.10.tgz",
3790
+ "integrity": "sha512-t3x7ht5qF8ZRi1H4fZqFzyY2j+GTMTDxRheT+i8M9Ph0oepUxoadmbwlFwMoW7RYCpNQLpP2Yx3feKs+fyBdpA==",
3791
"dependencies": {
3798
- "@vue/reactivity": "3.5.8",
3799
- "@vue/runtime-core": "3.5.8",
3800
- "@vue/shared": "3.5.8",
3792
+ "@vue/reactivity": "3.5.10",
3793
+ "@vue/runtime-core": "3.5.10",
3794
+ "@vue/shared": "3.5.10",
3795
"csstype": "^3.1.3"
3796
}
3797
},
3798
"node_modules/@vue/server-renderer": {
3805
- "version": "3.5.8",
3806
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.8.tgz",
3807
- "integrity": "sha512-7AmC9/mEeV9mmXNVyUIm1a1AjUhyeeGNbkLh39J00E7iPeGks8OGRB5blJiMmvqSh8SkaS7jkLWSpXtxUCeagA==",
3799
+ "version": "3.5.10",
3800
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.10.tgz",
3801
+ "integrity": "sha512-IVE97tt2kGKwHNq9yVO0xdh1IvYfZCShvDSy46JIh5OQxP1/EXSpoDqetVmyIzL7CYOWnnmMkVqd7YK2QSWkdw==",
3802
"dependencies": {
3809
- "@vue/compiler-ssr": "3.5.8",
3810
- "@vue/shared": "3.5.8"
3803
+ "@vue/compiler-ssr": "3.5.10",
3804
+ "@vue/shared": "3.5.10"
3805
},
3806
"peerDependencies": {
3813
- "vue": "3.5.8"
3807
+ "vue": "3.5.10"
3808
}
3809
},
3810
"node_modules/@vue/shared": {
3817
- "version": "3.5.8",
3818
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.8.tgz",
3819
- "integrity": "sha512-mJleSWbAGySd2RJdX1RBtcrUBX6snyOc0qHpgk3lGi4l9/P/3ny3ELqFWqYdkXIwwNN/kdm8nD9ky8o6l/Lx2A=="
3811
+ "version": "3.5.10",
3812
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.10.tgz",
3813
+ "integrity": "sha512-VkkBhU97Ki+XJ0xvl4C9YJsIZ2uIlQ7HqPpZOS3m9VCvmROPaChZU6DexdMJqvz9tbgG+4EtFVrSuailUq5KGQ=="
3814
},
3815
"node_modules/@vue/test-utils": {
3816
"version": "2.4.6",
@@ -4123,9 +4117,9 @@
4117
}
4118
},
4119
"node_modules/apexcharts": {
4126
- "version": "3.53.0",
4127
- "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.53.0.tgz",
4128
- "integrity": "sha512-QESZHZY3w9LPQ64PGh1gEdfjYjJ5Jp+Dfy0D/CLjsLOPTpXzdxwlNMqRj+vPbTcP0nAHgjWv1maDqcEq6u5olw==",
4120
+ "version": "3.54.0",
4121
+ "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.54.0.tgz",
4122
+ "integrity": "sha512-ZgI/seScffjLpwNRX/gAhIkAhpCNWiTNsdICv7qxnF0xisI23XSsaENUKIcMlyP1rbe8ECgvybDnp7plZld89A==",
4123
"dependencies": {
4124
"@yr/monotone-cubic-spline": "^1.0.3",
4125
"svg.draggable.js": "^2.2.2",
@@ -4398,9 +4392,9 @@
4392
}
4393
},
4394
"node_modules/browserslist": {
4401
- "version": "4.23.3",
4402
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
4403
- "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==",
4395
+ "version": "4.24.0",
4396
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz",
4397
+ "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==",
4398
"funding": [
4399
{
4400
"type": "opencollective",
@@ -4416,8 +4410,8 @@
4410
}
4411
],
4412
"dependencies": {
4419
- "caniuse-lite": "^1.0.30001646",
4420
- "electron-to-chromium": "^1.5.4",
4413
+ "caniuse-lite": "^1.0.30001663",
4414
+ "electron-to-chromium": "^1.5.28",
4415
"node-releases": "^2.0.18",
4416
"update-browserslist-db": "^1.1.0"
4417
},
@@ -4606,9 +4600,9 @@
4600
}
4601
},
4602
"node_modules/caniuse-lite": {
4609
- "version": "1.0.30001663",
4610
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz",
4611
- "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==",
4603
+ "version": "1.0.30001664",
4604
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz",
4605
+ "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==",
4606
"funding": [
4607
{
4608
"type": "opencollective",
@@ -5263,13 +5257,13 @@
5257
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
5258
},
5259
"node_modules/cypress": {
5266
- "version": "13.14.2",
5267
- "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.14.2.tgz",
5268
- "integrity": "sha512-lsiQrN17vHMB2fnvxIrKLAjOr9bPwsNbPZNrWf99s4u+DVmCY6U+w7O3GGG9FvP4EUVYaDu+guWeNLiUzBrqvA==",
5260
+ "version": "13.15.0",
5261
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.15.0.tgz",
5262
+ "integrity": "sha512-53aO7PwOfi604qzOkCSzNlWquCynLlKE/rmmpSPcziRH6LNfaDUAklQT6WJIsD8ywxlIy+uVZsnTMCCQVd2kTw==",
5263
"dev": true,
5264
"hasInstallScript": true,
5265
"dependencies": {
5272
- "@cypress/request": "^3.0.1",
5266
+ "@cypress/request": "^3.0.4",
5267
"@cypress/xvfb": "^1.2.4",
5268
"@types/sinonjs__fake-timers": "8.1.1",
5269
"@types/sizzle": "^2.3.2",
@@ -5451,26 +5445,20 @@
5445
}
5446
},
5447
"node_modules/date-fns": {
5454
- "version": "2.30.0",
5455
- "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
5456
- "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
5457
- "dependencies": {
5458
- "@babel/runtime": "^7.21.0"
5459
- },
5460
- "engines": {
5461
- "node": ">=0.11"
5462
- },
5448
+ "version": "3.6.0",
5449
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
5450
+ "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
5451
"funding": {
5464
- "type": "opencollective",
5465
- "url": "https://opencollective.com/date-fns"
5452
+ "type": "github",
5453
+ "url": "https://github.com/sponsors/kossnocorp"
5454
}
5455
},
5456
"node_modules/date-fns-tz": {
5469
- "version": "2.0.1",
5470
- "resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-2.0.1.tgz",
5471
- "integrity": "sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA==",
5457
+ "version": "3.2.0",
5458
+ "resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-3.2.0.tgz",
5459
+ "integrity": "sha512-sg8HqoTEulcbbbVXeg84u5UnlsQa8GS5QXMqjjYIhS4abEVVKIUwe0/l/UhrZdKaL/W5eWZNlbTeEIiOXTcsBQ==",
5460
"peerDependencies": {
5473
- "date-fns": "2.x"
5461
+ "date-fns": "^3.0.0 || ^4.0.0"
5462
}
5463
},
5464
"node_modules/dayjs": {
@@ -5864,9 +5852,9 @@
5852
"dev": true
5853
},
5854
"node_modules/electron-to-chromium": {
5867
- "version": "1.5.27",
5868
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz",
5869
- "integrity": "sha512-o37j1vZqCoEgBuWWXLHQgTN/KDKe7zwpiY5CPeq2RvUqOyJw9xnrULzZAEVQ5p4h+zjMk7hgtOoPdnLxr7m/jw=="
5855
+ "version": "1.5.29",
5856
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.29.tgz",
5857
+ "integrity": "sha512-PF8n2AlIhCKXQ+gTpiJi0VhcHDb69kYX4MtCiivctc2QD3XuNZ/XIOlbGzt7WAjjEev0TtaH6Cu3arZExm5DOw=="
5858
},
5859
"node_modules/emoji-regex": {
5860
"version": "8.0.0",
@@ -6038,19 +6026,22 @@
6026
}
6027
},
6028
"node_modules/eslint": {
6041
- "version": "9.11.0",
6042
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.0.tgz",
6043
- "integrity": "sha512-yVS6XODx+tMFMDFcG4+Hlh+qG7RM6cCJXtQhCKLSsr3XkLvWggHjCqjfh0XsPPnt1c56oaT6PMgW9XWQQjdHXA==",
6029
+ "version": "9.11.1",
6030
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.1.tgz",
6031
+ "integrity": "sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==",
6032
"dependencies": {
6033
"@eslint-community/eslint-utils": "^4.2.0",
6034
"@eslint-community/regexpp": "^4.11.0",
6035
"@eslint/config-array": "^0.18.0",
6036
+ "@eslint/core": "^0.6.0",
6037
"@eslint/eslintrc": "^3.1.0",
6049
- "@eslint/js": "9.11.0",
6038
+ "@eslint/js": "9.11.1",
6039
"@eslint/plugin-kit": "^0.2.0",
6040
"@humanwhocodes/module-importer": "^1.0.1",
6041
"@humanwhocodes/retry": "^0.3.0",
6042
"@nodelib/fs.walk": "^1.2.8",
6043
+ "@types/estree": "^1.0.6",
6044
+ "@types/json-schema": "^7.0.15",
6045
"ajv": "^6.12.4",
6046
"chalk": "^4.0.0",
6047
"cross-spawn": "^7.0.2",
@@ -6217,9 +6208,9 @@
6208
}
6209
},
6210
"node_modules/eslint-plugin-command": {
6220
- "version": "0.2.5",
6221
- "resolved": "https://registry.npmjs.org/eslint-plugin-command/-/eslint-plugin-command-0.2.5.tgz",
6222
- "integrity": "sha512-mbCaSHD37MT8nVJnJUz2oeDfhz0wdOjfrqQVWkSpXuj3uU8m7/FK/niV2bL922af3M1js5x7Xcu3PwqWsrahfA==",
6211
+ "version": "0.2.6",
6212
+ "resolved": "https://registry.npmjs.org/eslint-plugin-command/-/eslint-plugin-command-0.2.6.tgz",
6213
+ "integrity": "sha512-T0bHZ1oblW1xUHUVoBKZJR2osSNNGkfZuK4iqboNwuNS/M7tdp3pmURaJtTi/XDzitxaQ02lvOdFH0mUd5QLvQ==",
6214
"dev": true,
6215
"dependencies": {
6216
"@es-joy/jsdoccomment": "^0.48.0"
@@ -6253,9 +6244,9 @@
6244
}
6245
},
6246
"node_modules/eslint-plugin-import-x": {
6256
- "version": "4.3.0",
6257
- "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.3.0.tgz",
6258
- "integrity": "sha512-PxGzP7gAjF2DLeRnQtbYkkgZDg1intFyYr/XS1LgTYXUDrSXMHGkXx8++6i2eDv2jMs0jfeO6G6ykyeWxiFX7w==",
6247
+ "version": "4.3.1",
6248
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.3.1.tgz",
6249
+ "integrity": "sha512-5TriWkXulDl486XnYYRgsL+VQoS/7mhN/2ci02iLCuL7gdhbiWxnsuL/NTcaKY9fpMgsMFjWZBtIGW7pb+RX0g==",
6250
"dev": true,
6251
"dependencies": {
6252
"@typescript-eslint/utils": "^8.1.0",
@@ -6283,9 +6274,9 @@
6274
"dev": true
6275
},
6276
"node_modules/eslint-plugin-jsdoc": {
6286
- "version": "50.2.4",
6287
- "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.2.4.tgz",
6288
- "integrity": "sha512-020jA+dXaXdb+TML3ZJBvpPmzwbNROjnYuTYi/g6A5QEmEjhptz4oPJDKkOGMIByNxsPpdTLzSU1HYVqebOX1w==",
6277
+ "version": "50.3.0",
6278
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.3.0.tgz",
6279
+ "integrity": "sha512-P7qDB/RckdKETpBM4CtjHRQ5qXByPmFhRi86sN3E+J+tySchq+RSOGGhI2hDIefmmKFuTi/1ACjqsnDJDDDfzg==",
6280
"dev": true,
6281
"dependencies": {
6282
"@es-joy/jsdoccomment": "~0.48.0",
@@ -6435,13 +6426,13 @@
6426
}
6427
},
6428
"node_modules/eslint-plugin-perfectionist": {
6438
- "version": "3.6.0",
6439
- "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-3.6.0.tgz",
6440
- "integrity": "sha512-sA6ljy6dL/9cM5ruZ/pMqRVt0FQ4Z7mbQWlBYpyX9941LVfm65d2jl2k1ZbWD3ud9Wm+/NKgOvRnAatsKhMJbA==",
6429
+ "version": "3.7.0",
6430
+ "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-3.7.0.tgz",
6431
+ "integrity": "sha512-pemhfcR3LDbYVWeveHok9u048yR7GpsnfyPvn6RsDkp/UV7iqBV0y5K0aGb9ZJMsemOyWok7akxGzPLsz+mHKQ==",
6432
"dev": true,
6433
"dependencies": {
6443
- "@typescript-eslint/types": "^8.5.0",
6444
- "@typescript-eslint/utils": "^8.5.0",
6434
+ "@typescript-eslint/types": "^8.7.0",
6435
+ "@typescript-eslint/utils": "^8.7.0",
6436
"minimatch": "^9.0.5",
6437
"natural-compare-lite": "^1.4.0"
6438
},
@@ -6703,9 +6694,9 @@
6694
}
6695
},
6696
"node_modules/eslint-scope": {
6706
- "version": "8.0.2",
6707
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
6708
- "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==",
6697
+ "version": "8.1.0",
6698
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz",
6699
+ "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==",
6700
"dependencies": {
6701
"esrecurse": "^4.3.0",
6702
"estraverse": "^5.2.0"
@@ -6718,9 +6709,9 @@
6709
}
6710
},
6711
"node_modules/eslint-visitor-keys": {
6721
- "version": "4.0.0",
6722
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
6723
- "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
6712
+ "version": "4.1.0",
6713
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz",
6714
+ "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==",
6715
"engines": {
6716
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
6717
},
@@ -6729,9 +6720,9 @@
6720
}
6721
},
6722
"node_modules/eslint/node_modules/@eslint/js": {
6732
- "version": "9.11.0",
6733
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.0.tgz",
6734
- "integrity": "sha512-LPkkenkDqyzTFauZLLAPhIb48fj6drrfMvRGSL9tS3AcZBSVTllemLSNyCvHNNL2t797S/6DJNSIwRwXgMO/eQ==",
6723
+ "version": "9.11.1",
6724
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz",
6725
+ "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==",
6726
"engines": {
6727
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
6728
}
@@ -6821,13 +6812,13 @@
6812
}
6813
},
6814
"node_modules/espree": {
6824
- "version": "10.1.0",
6825
- "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz",
6826
- "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==",
6815
+ "version": "10.2.0",
6816
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz",
6817
+ "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==",
6818
"dependencies": {
6819
"acorn": "^8.12.0",
6820
"acorn-jsx": "^5.3.2",
6830
- "eslint-visitor-keys": "^4.0.0"
6821
+ "eslint-visitor-keys": "^4.1.0"
6822
},
6823
"engines": {
6824
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -7645,9 +7636,9 @@
7636
}
7637
},
7638
"node_modules/highlight-words-core": {
7648
- "version": "1.2.2",
7649
- "resolved": "https://registry.npmjs.org/highlight-words-core/-/highlight-words-core-1.2.2.tgz",
7650
- "integrity": "sha512-BXUKIkUuh6cmmxzi5OIbUJxrG8OAk2MqoL1DtO3Wo9D2faJg2ph5ntyuQeLqaHJmzER6H5tllCDA9ZnNe9BVGg=="
7639
+ "version": "1.2.3",
7640
+ "resolved": "https://registry.npmjs.org/highlight-words-core/-/highlight-words-core-1.2.3.tgz",
7641
+ "integrity": "sha512-m1O9HW3/GNHxzSIXWw1wCNXXsgLlxrP0OI6+ycGUhiUHkikqW3OrwVHz+lxeNBe5yqLESdIcj8PowHQ2zLvUvQ=="
7642
},
7643
"node_modules/highlight.js": {
7644
"version": "11.10.0",
@@ -7913,27 +7904,26 @@
7904
}
7905
},
7906
"node_modules/importx": {
7916
- "version": "0.4.4",
7917
- "resolved": "https://registry.npmjs.org/importx/-/importx-0.4.4.tgz",
7918
- "integrity": "sha512-Lo1pukzAREqrBnnHC+tj+lreMTAvyxtkKsMxLY8H15M/bvLl54p3YuoTI70Tz7Il0AsgSlD7Lrk/FaApRcBL7w==",
7907
+ "version": "0.5.0",
7908
+ "resolved": "https://registry.npmjs.org/importx/-/importx-0.5.0.tgz",
7909
+ "integrity": "sha512-qROz3rSOjQYclmEQAajH9RhBuqpAGHM+5CNd9fk+TsF4JKmQsAI1egafW8XZZv8vARCo4nAmmt5d0eI2B8GUsA==",
7910
"dev": true,
7911
"dependencies": {
7912
"bundle-require": "^5.0.0",
7922
- "debug": "^4.3.6",
7913
+ "debug": "^4.3.7",
7914
"esbuild": "^0.20.2 || ^0.21.0 || ^0.22.0 || ^0.23.0",
7924
- "jiti": "2.0.0-beta.3",
7925
- "jiti-v1": "npm:jiti@^1.21.6",
7915
+ "jiti": "^2.0.0",
7916
"pathe": "^1.1.2",
7927
- "tsx": "^4.19.0"
7917
+ "tsx": "^4.19.1"
7918
},
7919
"funding": {
7920
"url": "https://github.com/sponsors/antfu"
7921
}
7922
},
7923
"node_modules/importx/node_modules/jiti": {
7934
- "version": "2.0.0-beta.3",
7935
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.0.0-beta.3.tgz",
7936
- "integrity": "sha512-pmfRbVRs/7khFrSAYnSiJ8C0D5GvzkE4Ey2pAvUcJsw1ly/p+7ut27jbJrjY79BpAJQJ4gXYFtK6d1Aub+9baQ==",
7924
+ "version": "2.0.0",
7925
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.0.0.tgz",
7926
+ "integrity": "sha512-CJ7e7Abb779OTRv3lomfp7Mns/Sy1+U4pcAx5VbjxCZD5ZM/VJaXPpPjNKjtSvWQy/H86E49REXR34dl1JEz9w==",
7927
"dev": true,
7928
"bin": {
7929
"jiti": "lib/jiti-cli.mjs"
@@ -8271,16 +8261,6 @@
8261
"jiti": "bin/jiti.js"
8262
}
8263
},
8274
- "node_modules/jiti-v1": {
8275
- "name": "jiti",
8276
- "version": "1.21.6",
8277
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
8278
- "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
8279
- "dev": true,
8280
- "bin": {
8281
- "jiti": "bin/jiti.js"
8282
- }
8283
- },
8264
"node_modules/joi": {
8265
"version": "17.13.3",
8266
"resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz",
@@ -10198,20 +10178,20 @@
10178
}
10179
},
10180
"node_modules/naive-ui": {
10201
- "version": "2.39.0",
10202
- "resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.39.0.tgz",
10203
- "integrity": "sha512-5oUJzRG+rtLSH8eRU+fJvVYiQids2BxF9jp+fwGoAqHOptEINrBlgBu9uy+95RHE5FLJ7Q/z41o+qkoGnUrKxQ==",
10181
+ "version": "2.40.1",
10182
+ "resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.40.1.tgz",
10183
+ "integrity": "sha512-3NkL+vLRQZKQxCHXa+7xiD6oM74OrQELaehDkGYRYpr6kjT+JJB+Z7h+5LC70gn8VkbgCAETv0+uRWF+6MLlgQ==",
10184
"dependencies": {
10205
- "@css-render/plugin-bem": "^0.15.12",
10206
- "@css-render/vue3-ssr": "^0.15.12",
10185
+ "@css-render/plugin-bem": "^0.15.14",
10186
+ "@css-render/vue3-ssr": "^0.15.14",
10187
"@types/katex": "^0.16.2",
10188
"@types/lodash": "^4.14.198",
10189
"@types/lodash-es": "^4.17.9",
10190
"async-validator": "^4.2.5",
10211
- "css-render": "^0.15.12",
10191
+ "css-render": "^0.15.14",
10192
"csstype": "^3.1.3",
10213
- "date-fns": "^2.30.0",
10214
- "date-fns-tz": "^2.0.0",
10193
+ "date-fns": "^3.6.0",
10194
+ "date-fns-tz": "^3.1.3",
10195
"evtd": "^0.2.4",
10196
"highlight.js": "^11.8.0",
10197
"lodash": "^4.17.21",
@@ -10220,7 +10200,7 @@
10200
"treemate": "^0.3.11",
10201
"vdirs": "^0.1.8",
10202
"vooks": "^0.2.12",
10223
- "vueuc": "^0.4.58"
10203
+ "vueuc": "^0.4.63"
10204
},
10205
"peerDependencies": {
10206
"vue": "^3.0.0"
@@ -10396,15 +10376,15 @@
10376
}
10377
},
10378
"node_modules/nwsapi": {
10399
- "version": "2.2.12",
10400
- "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz",
10401
- "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==",
10379
+ "version": "2.2.13",
10380
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.13.tgz",
10381
+ "integrity": "sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==",
10382
"dev": true
10383
},
10384
"node_modules/nypm": {
10405
- "version": "0.3.11",
10406
- "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.11.tgz",
10407
- "integrity": "sha512-E5GqaAYSnbb6n1qZyik2wjPDZON43FqOJO59+3OkWrnmQtjggrMOVnsyzfjxp/tS6nlYJBA4zRA5jSM2YaadMg==",
10385
+ "version": "0.3.12",
10386
+ "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.12.tgz",
10387
+ "integrity": "sha512-D3pzNDWIvgA+7IORhD/IuWzEk4uXv6GsgOxiid4UU3h9oq5IqV1KtPDi63n4sZJ/xcWlr88c0QM2RgN5VbOhFA==",
10388
"dependencies": {
10389
"citty": "^0.1.6",
10390
"consola": "^3.2.3",
@@ -10733,9 +10713,9 @@
10713
}
10714
},
10715
"node_modules/package-json-from-dist": {
10736
- "version": "1.0.0",
10737
- "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
10738
- "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
10716
+ "version": "1.0.1",
10717
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
10718
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
10719
"dev": true
10720
},
10721
"node_modules/package-manager-detector": {
@@ -10984,9 +10964,9 @@
10964
}
10965
},
10966
"node_modules/pinia": {
10987
- "version": "2.2.2",
10988
- "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.2.2.tgz",
10989
- "integrity": "sha512-ja2XqFWZC36mupU4z1ZzxeTApV7DOw44cV4dhQ9sGwun+N89v/XP7+j7q6TanS1u1tdbK4r+1BUx7heMaIdagA==",
10967
+ "version": "2.2.4",
10968
+ "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.2.4.tgz",
10969
+ "integrity": "sha512-K7ZhpMY9iJ9ShTC0cR2+PnxdQRuwVIsXDO/WIEV/RnMC/vmSoKDTKW/exNQYPI+4ij10UjXqdNiEHwn47McANQ==",
10970
"dependencies": {
10971
"@vue/devtools-api": "^6.6.3",
10972
"vue-demi": "^0.14.10"
@@ -11597,11 +11577,6 @@
11577
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
11578
}
11579
},
11600
- "node_modules/regenerator-runtime": {
11601
- "version": "0.14.1",
11602
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
11603
- "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
11604
- },
11580
"node_modules/regex": {
11581
"version": "4.3.2",
11582
"resolved": "https://registry.npmjs.org/regex/-/regex-4.3.2.tgz",
@@ -11984,12 +11959,12 @@
11959
}
11960
},
11961
"node_modules/rollup": {
11987
- "version": "4.22.4",
11988
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz",
11989
- "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==",
11962
+ "version": "4.22.5",
11963
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.5.tgz",
11964
+ "integrity": "sha512-WoinX7GeQOFMGznEcWA1WrTQCd/tpEbMkc3nuMs9BT0CPjMdSjPMTVClwWd4pgSQwJdP65SK9mTCNvItlr5o7w==",
11965
"devOptional": true,
11966
"dependencies": {
11992
- "@types/estree": "1.0.5"
11967
+ "@types/estree": "1.0.6"
11968
},
11969
"bin": {
11970
"rollup": "dist/bin/rollup"
@@ -11999,22 +11974,22 @@
11974
"npm": ">=8.0.0"
11975
},
11976
"optionalDependencies": {
12002
- "@rollup/rollup-android-arm-eabi": "4.22.4",
12003
- "@rollup/rollup-android-arm64": "4.22.4",
12004
- "@rollup/rollup-darwin-arm64": "4.22.4",
12005
- "@rollup/rollup-darwin-x64": "4.22.4",
12006
- "@rollup/rollup-linux-arm-gnueabihf": "4.22.4",
12007
- "@rollup/rollup-linux-arm-musleabihf": "4.22.4",
12008
- "@rollup/rollup-linux-arm64-gnu": "4.22.4",
12009
- "@rollup/rollup-linux-arm64-musl": "4.22.4",
12010
- "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4",
12011
- "@rollup/rollup-linux-riscv64-gnu": "4.22.4",
12012
- "@rollup/rollup-linux-s390x-gnu": "4.22.4",
12013
- "@rollup/rollup-linux-x64-gnu": "4.22.4",
12014
- "@rollup/rollup-linux-x64-musl": "4.22.4",
12015
- "@rollup/rollup-win32-arm64-msvc": "4.22.4",
12016
- "@rollup/rollup-win32-ia32-msvc": "4.22.4",
12017
- "@rollup/rollup-win32-x64-msvc": "4.22.4",
11977
+ "@rollup/rollup-android-arm-eabi": "4.22.5",
11978
+ "@rollup/rollup-android-arm64": "4.22.5",
11979
+ "@rollup/rollup-darwin-arm64": "4.22.5",
11980
+ "@rollup/rollup-darwin-x64": "4.22.5",
11981
+ "@rollup/rollup-linux-arm-gnueabihf": "4.22.5",
11982
+ "@rollup/rollup-linux-arm-musleabihf": "4.22.5",
11983
+ "@rollup/rollup-linux-arm64-gnu": "4.22.5",
11984
+ "@rollup/rollup-linux-arm64-musl": "4.22.5",
11985
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.22.5",
11986
+ "@rollup/rollup-linux-riscv64-gnu": "4.22.5",
11987
+ "@rollup/rollup-linux-s390x-gnu": "4.22.5",
11988
+ "@rollup/rollup-linux-x64-gnu": "4.22.5",
11989
+ "@rollup/rollup-linux-x64-musl": "4.22.5",
11990
+ "@rollup/rollup-win32-arm64-msvc": "4.22.5",
11991
+ "@rollup/rollup-win32-ia32-msvc": "4.22.5",
11992
+ "@rollup/rollup-win32-x64-msvc": "4.22.5",
11993
"fsevents": "~2.3.2"
11994
}
11995
},
@@ -12073,11 +12048,18 @@
12048
"url": "https://github.com/sponsors/jonschlinkert"
12049
}
12050
},
12076
- "node_modules/rollup/node_modules/@types/estree": {
12077
- "version": "1.0.5",
12078
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
12079
- "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
12080
- "devOptional": true
12051
+ "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-gnu": {
12052
+ "version": "4.22.5",
12053
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.5.tgz",
12054
+ "integrity": "sha512-N0jPPhHjGShcB9/XXZQWuWBKZQnC1F36Ce3sDqWpujsGjDz/CQtOL9LgTrJ+rJC8MJeesMWrMWVLKKNR/tMOCA==",
12055
+ "cpu": [
12056
+ "x64"
12057
+ ],
12058
+ "dev": true,
12059
+ "optional": true,
12060
+ "os": [
12061
+ "linux"
12062
+ ]
12063
},
12064
"node_modules/rrweb-cssom": {
12065
"version": "0.7.1",
@@ -12155,9 +12137,9 @@
12137
"dev": true
12138
},
12139
"node_modules/sass": {
12158
- "version": "1.79.3",
12159
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.79.3.tgz",
12160
- "integrity": "sha512-m7dZxh0W9EZ3cw50Me5GOuYm/tVAJAn91SUnohLRo9cXBixGUOdvmryN+dXpwR831bhoY3Zv7rEFt85PUwTmzA==",
12140
+ "version": "1.79.4",
12141
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.79.4.tgz",
12142
+ "integrity": "sha512-K0QDSNPXgyqO4GZq2HO5Q70TLxTH6cIT59RdoCHMivrC8rqzaTw5ab9prjz9KUN1El4FLXrBXJhik61JR4HcGg==",
12143
"dev": true,
12144
"dependencies": {
12145
"chokidar": "^4.0.0",
@@ -12310,14 +12292,14 @@
12292
}
12293
},
12294
"node_modules/shiki": {
12313
- "version": "1.18.0",
12314
- "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.18.0.tgz",
12315
- "integrity": "sha512-8jo7tOXr96h9PBQmOHVrltnETn1honZZY76YA79MHheGQg55jBvbm9dtU+MI5pjC5NJCFuA6rvVTLVeSW5cE4A==",
12316
- "dependencies": {
12317
- "@shikijs/core": "1.18.0",
12318
- "@shikijs/engine-javascript": "1.18.0",
12319
- "@shikijs/engine-oniguruma": "1.18.0",
12320
- "@shikijs/types": "1.18.0",
12295
+ "version": "1.21.0",
12296
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.21.0.tgz",
12297
+ "integrity": "sha512-apCH5BoWTrmHDPGgg3RF8+HAAbEL/CdbYr8rMw7eIrdhCkZHdVGat5mMNlRtd1erNG01VPMIKHNQ0Pj2HMAiog==",
12298
+ "dependencies": {
12299
+ "@shikijs/core": "1.21.0",
12300
+ "@shikijs/engine-javascript": "1.21.0",
12301
+ "@shikijs/engine-oniguruma": "1.21.0",
12302
+ "@shikijs/types": "1.21.0",
12303
"@shikijs/vscode-textmate": "^9.2.2",
12304
"@types/hast": "^3.0.4"
12305
}
@@ -13029,9 +13011,9 @@
13011
}
13012
},
13013
"node_modules/tailwindcss": {
13032
- "version": "3.4.12",
13033
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.12.tgz",
13034
- "integrity": "sha512-Htf/gHj2+soPb9UayUNci/Ja3d8pTmu9ONTfh4QY8r3MATTZOzmv6UYWF7ZwikEIC8okpfqmGqrmDehua8mF8w==",
13014
+ "version": "3.4.13",
13015
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz",
13016
+ "integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==",
13017
"dev": true,
13018
"dependencies": {
13019
"@alloc/quick-lru": "^5.2.0",
@@ -13115,17 +13097,17 @@
13097
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
13098
},
13099
"node_modules/taze": {
13118
- "version": "0.16.9",
13119
- "resolved": "https://registry.npmjs.org/taze/-/taze-0.16.9.tgz",
13120
- "integrity": "sha512-5dROtuXIaP3HOHy7f2jTvnfHbHO8ubCoqfv1At3UOo7QB63y8oLNwpuj7w/4IdVY+lkzQSDV6f5L5Bhl3kq9QQ==",
13100
+ "version": "0.17.2",
13101
+ "resolved": "https://registry.npmjs.org/taze/-/taze-0.17.2.tgz",
13102
+ "integrity": "sha512-VZvB2PfuIXVQdgEnjqg1NLAnxzEv28ypxTLpbtSs8rO0gdZbFRwRj3ES9QXneo112rdIwx1SM2QcIL83EfNBdg==",
13103
"dev": true,
13104
"dependencies": {
13105
"@antfu/ni": "^0.23.0",
13106
"js-yaml": "^4.1.0",
13125
- "ofetch": "^1.3.4",
13107
+ "ofetch": "^1.4.0",
13108
"package-manager-detector": "^0.2.0",
13109
"tinyexec": "^0.3.0",
13128
- "unconfig": "^0.5.5",
13110
+ "unconfig": "^0.6.0",
13111
"yargs": "^17.7.2"
13112
},
13113
"bin": {
@@ -13136,14 +13118,14 @@
13118
}
13119
},
13120
"node_modules/taze/node_modules/unconfig": {
13139
- "version": "0.5.5",
13140
- "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-0.5.5.tgz",
13141
- "integrity": "sha512-VQZ5PT9HDX+qag0XdgQi8tJepPhXiR/yVOkn707gJDKo31lGjRilPREiQJ9Z6zd/Ugpv6ZvO5VxVIcatldYcNQ==",
13121
+ "version": "0.6.0",
13122
+ "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-0.6.0.tgz",
13123
+ "integrity": "sha512-4C67J0nIF2QwSXty2kW3zZx1pMZ3iXabylvJWWgHybWVUcMf9pxwsngoQt0gC+AVstRywFqrRBp3qOXJayhpOw==",
13124
"dev": true,
13125
"dependencies": {
13126
"@antfu/utils": "^0.7.10",
13127
"defu": "^6.1.4",
13146
- "importx": "^0.4.3"
13128
+ "importx": "^0.5.0"
13129
},
13130
"funding": {
13131
"url": "https://github.com/sponsors/antfu"
@@ -13230,21 +13212,21 @@
13212
}
13213
},
13214
"node_modules/tldts": {
13233
- "version": "6.1.47",
13234
- "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.47.tgz",
13235
- "integrity": "sha512-R/K2tZ5MiY+mVrnSkNJkwqYT2vUv1lcT6wJvd2emGaMJ7PHUGRY4e3tUsdFCXgqxi2QgbHjL3yJgXCo40v9Hxw==",
13215
+ "version": "6.1.48",
13216
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.48.tgz",
13217
+ "integrity": "sha512-SPbnh1zaSzi/OsmHb1vrPNnYuwJbdWjwo5TbBYYMlTtH3/1DSb41t8bcSxkwDmmbG2q6VLPVvQc7Yf23T+1EEw==",
13218
"dev": true,
13219
"dependencies": {
13238
- "tldts-core": "^6.1.47"
13220
+ "tldts-core": "^6.1.48"
13221
},
13222
"bin": {
13223
"tldts": "bin/cli.js"
13224
}
13225
},
13226
"node_modules/tldts-core": {
13245
- "version": "6.1.47",
13246
- "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.47.tgz",
13247
- "integrity": "sha512-6SWyFMnlst1fEt7GQVAAu16EGgFK0cLouH/2Mk6Ftlwhv3Ol40L0dlpGMcnnNiiOMyD2EV/aF3S+U2nKvvLvrA==",
13227
+ "version": "6.1.48",
13228
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.48.tgz",
13229
+ "integrity": "sha512-3gD9iKn/n2UuFH1uilBviK9gvTNT6iYwdqrj1Vr5mh8FuelvpRNaYVH4pNYqUgOGU4aAdL9X35eLuuj0gRsx+A==",
13230
"dev": true
13231
},
13232
"node_modules/tmp": {
@@ -13958,11 +13940,11 @@
13940
}
13941
},
13942
"node_modules/unimport": {
13961
- "version": "3.12.0",
13962
- "resolved": "https://registry.npmjs.org/unimport/-/unimport-3.12.0.tgz",
13963
- "integrity": "sha512-5y8dSvNvyevsnw4TBQkIQR1Rjdbb+XjVSwQwxltpnVZrStBvvPkMPcZrh1kg5kY77kpx6+D4Ztd3W6FOBH/y2Q==",
13943
+ "version": "3.13.1",
13944
+ "resolved": "https://registry.npmjs.org/unimport/-/unimport-3.13.1.tgz",
13945
+ "integrity": "sha512-nNrVzcs93yrZQOW77qnyOVHtb68LegvhYFwxFMfuuWScmwQmyVCG/NBuN8tYsaGzgQUVYv34E/af+Cc9u4og4A==",
13946
"dependencies": {
13965
- "@rollup/pluginutils": "^5.1.0",
13947
+ "@rollup/pluginutils": "^5.1.2",
13948
"acorn": "^8.12.1",
13949
"escape-string-regexp": "^5.0.0",
13950
"estree-walker": "^3.0.3",
@@ -14135,26 +14117,34 @@
14117
}
14118
},
14119
"node_modules/untyped": {
14138
- "version": "1.4.2",
14139
- "resolved": "https://registry.npmjs.org/untyped/-/untyped-1.4.2.tgz",
14140
- "integrity": "sha512-nC5q0DnPEPVURPhfPQLahhSTnemVtPzdx7ofiRxXpOB2SYnb3MfdU3DVGyJdS8Lx+tBWeAePO8BfU/3EgksM7Q==",
14120
+ "version": "1.5.0",
14121
+ "resolved": "https://registry.npmjs.org/untyped/-/untyped-1.5.0.tgz",
14122
+ "integrity": "sha512-o2Vjmn2dal08BzCcINxSmWuAteReUUiXseii5VRhmxyLF0b21K0iKZQ9fMYK7RWspVkY+0saqaVQNq4roe3Efg==",
14123
"dependencies": {
14142
- "@babel/core": "^7.23.7",
14143
- "@babel/standalone": "^7.23.8",
14144
- "@babel/types": "^7.23.6",
14124
+ "@babel/core": "^7.25.2",
14125
+ "@babel/standalone": "^7.25.6",
14126
+ "@babel/types": "^7.25.6",
14127
"defu": "^6.1.4",
14146
- "jiti": "^1.21.0",
14128
+ "jiti": "^2.0.0",
14129
"mri": "^1.2.0",
14148
- "scule": "^1.2.0"
14130
+ "scule": "^1.3.0"
14131
},
14132
"bin": {
14133
"untyped": "dist/cli.mjs"
14134
}
14135
},
14136
+ "node_modules/untyped/node_modules/jiti": {
14137
+ "version": "2.0.0",
14138
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.0.0.tgz",
14139
+ "integrity": "sha512-CJ7e7Abb779OTRv3lomfp7Mns/Sy1+U4pcAx5VbjxCZD5ZM/VJaXPpPjNKjtSvWQy/H86E49REXR34dl1JEz9w==",
14140
+ "bin": {
14141
+ "jiti": "lib/jiti-cli.mjs"
14142
+ }
14143
+ },
14144
"node_modules/update-browserslist-db": {
14155
- "version": "1.1.0",
14156
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
14157
- "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
14145
+ "version": "1.1.1",
14146
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
14147
+ "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
14148
"funding": [
14149
{
14150
"type": "opencollective",
@@ -14170,8 +14160,8 @@
14160
}
14161
],
14162
"dependencies": {
14173
- "escalade": "^3.1.2",
14174
- "picocolors": "^1.0.1"
14163
+ "escalade": "^3.2.0",
14164
+ "picocolors": "^1.1.0"
14165
},
14166
"bin": {
14167
"update-browserslist-db": "cli.js"
@@ -14301,9 +14291,9 @@
14291
}
14292
},
14293
"node_modules/vite": {
14304
- "version": "5.4.7",
14305
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz",
14306
- "integrity": "sha512-5l2zxqMEPVENgvzTuBpHer2awaetimj2BGkhBPdnwKbPNOlHsODU+oiazEZzLK7KhAnOrO+XGYJYn4ZlUhDtDQ==",
14294
+ "version": "5.4.8",
14295
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
14296
+ "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
14297
"dev": true,
14298
"dependencies": {
14299
"esbuild": "^0.21.3",
@@ -14360,9 +14350,9 @@
14350
}
14351
},
14352
"node_modules/vite-bundle-analyzer": {
14363
- "version": "0.11.1",
14364
- "resolved": "https://registry.npmjs.org/vite-bundle-analyzer/-/vite-bundle-analyzer-0.11.1.tgz",
14365
- "integrity": "sha512-0GptL3zHh36t5Gp+W1PAU3CiRU7tA0NS0XJhS2YFX6RtIs7oltdMDqLBKjSXCUJRWa3zki+oASfbE6ssAsf1PA==",
14353
+ "version": "0.12.1",
14354
+ "resolved": "https://registry.npmjs.org/vite-bundle-analyzer/-/vite-bundle-analyzer-0.12.1.tgz",
14355
+ "integrity": "sha512-mIYwsDvTYCqXAUtOZIL3f7NdwWUeL/MlNFhOJzlTdcZE4pye6h06IEnOvWhnc/e+HM4oVVNxuRHZt0Rz6VO7EA==",
14356
"dev": true
14357
},
14358
"node_modules/vite-bundle-visualizer": {
@@ -14493,14 +14483,14 @@
14483
}
14484
},
14485
"node_modules/vite-plugin-vue-devtools": {
14496
- "version": "7.4.5",
14497
- "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.4.5.tgz",
14498
- "integrity": "sha512-8D9Dv7uw620r96uI45M7hCyfsBA9KwttdmxA/DAd0/1KpuGmrFEhNwo4ob/sjaou1noAeK2TrnKdW+sFMR6aKQ==",
14486
+ "version": "7.4.6",
14487
+ "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.4.6.tgz",
14488
+ "integrity": "sha512-lOKur3qovCB3BQStL0qfHEoIusqya1ngfxfWuqn9DTa6h9rlw6+S3PV4geOP5YBGYQ4NW1hRX70OD8I+sYr1dA==",
14489
"dev": true,
14490
"dependencies": {
14501
- "@vue/devtools-core": "^7.4.5",
14502
- "@vue/devtools-kit": "^7.4.5",
14503
- "@vue/devtools-shared": "^7.4.5",
14491
+ "@vue/devtools-core": "^7.4.6",
14492
+ "@vue/devtools-kit": "^7.4.6",
14493
+ "@vue/devtools-shared": "^7.4.6",
14494
"execa": "^8.0.1",
14495
"sirv": "^2.0.4",
14496
"vite-plugin-inspect": "^0.8.7",
@@ -14761,15 +14751,15 @@
14751
"dev": true
14752
},
14753
"node_modules/vue": {
14764
- "version": "3.5.8",
14765
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.8.tgz",
14766
- "integrity": "sha512-hvuvuCy51nP/1fSRvrrIqTLSvrSyz2Pq+KQ8S8SXCxTWVE0nMaOnSDnSOxV1eYmGfvK7mqiwvd1C59CEEz7dAQ==",
14754
+ "version": "3.5.10",
14755
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.10.tgz",
14756
+ "integrity": "sha512-Vy2kmJwHPlouC/tSnIgXVg03SG+9wSqT1xu1Vehc+ChsXsRd7jLkKgMltVEFOzUdBr3uFwBCG+41LJtfAcBRng==",
14757
"dependencies": {
14768
- "@vue/compiler-dom": "3.5.8",
14769
- "@vue/compiler-sfc": "3.5.8",
14770
- "@vue/runtime-dom": "3.5.8",
14771
- "@vue/server-renderer": "3.5.8",
14772
- "@vue/shared": "3.5.8"
14758
+ "@vue/compiler-dom": "3.5.10",
14759
+ "@vue/compiler-sfc": "3.5.10",
14760
+ "@vue/runtime-dom": "3.5.10",
14761
+ "@vue/server-renderer": "3.5.10",
14762
+ "@vue/shared": "3.5.10"
14763
},
14764
"peerDependencies": {
14765
"typescript": "*"
@@ -14969,9 +14959,9 @@
14959
}
14960
},
14961
"node_modules/vueuc": {
14972
- "version": "0.4.63",
14973
- "resolved": "https://registry.npmjs.org/vueuc/-/vueuc-0.4.63.tgz",
14974
- "integrity": "sha512-QJT0z9yYWXdKpUq6f6IrAgJ83e34iTYMCVHjcAP8lCjldG0JzHnDfJYMpPWkNuLB5SdBZCbYGmYTKnTR+ff7CQ==",
14962
+ "version": "0.4.64",
14963
+ "resolved": "https://registry.npmjs.org/vueuc/-/vueuc-0.4.64.tgz",
14964
+ "integrity": "sha512-wlJQj7fIwKK2pOEoOq4Aro8JdPOGpX8aWQhV8YkTW9OgWD2uj2O8ANzvSsIGjx7LTOc7QbS7sXdxHi6XvRnHPA==",
14965
"dependencies": {
14966
"@css-render/vue3-ssr": "^0.15.10",
14967
"@juggle/resize-observer": "^3.3.1",
frontend/package.json
+22
-22
@@ -41,10 +41,10 @@
41
"@fontsource/lexend": "^5.1.0",
42
"@fontsource/public-sans": "^5.1.0",
43
"@popperjs/core": "^2.11.8",
44
- "@shikijs/markdown-it": "^1.18.0",
44
+ "@shikijs/markdown-it": "^1.21.0",
45
"@vueuse/components": "^11.1.0",
46
"@vueuse/core": "^11.1.0",
47
- "apexcharts": "^3.53.0",
47
+ "apexcharts": "^3.54.0",
48
"axios": "^1.7.7",
49
"bytes": "^3.1.2",
50
"colord": "^2.9.3",
@@ -58,14 +58,14 @@
58
"js-md5": "^0.8.3",
59
"lodash": "^4.17.21",
60
"mitt": "^3.0.1",
61
- "naive-ui": "^2.39.0",
61
+ "naive-ui": "^2.40.1",
62
"password-validator": "^5.3.0",
63
- "pinia": "^2.2.2",
63
+ "pinia": "^2.2.4",
64
"pinia-plugin-persistedstate": "^4.0.2",
65
"secure-ls": "^2.0.0",
66
- "shiki": "^1.18.0",
66
+ "shiki": "^1.21.0",
67
"validator": "^13.12.0",
68
- "vue": "^3.5.8",
68
+ "vue": "^3.5.10",
69
"vue-advanced-cropper": "^2.8.9",
70
"vue-highlight-words": "^3.0.1",
71
"vue-i18n": "^10.0.3",
@@ -76,10 +76,10 @@
76
"vuedraggable": "^4.1.0"
77
},
78
"optionalDependencies": {
79
- "@rollup/rollup-linux-x64-gnu": "^4.22.4"
79
+ "@rollup/rollup-linux-x64-gnu": "^4.23.0"
80
},
81
"devDependencies": {
82
- "@antfu/eslint-config": "^3.7.1",
82
+ "@antfu/eslint-config": "^3.7.3",
83
"@clack/prompts": "^0.7.0",
84
"@iconify/vue": "^4.1.2",
85
"@tsconfig/node20": "^20.1.4",
@@ -88,16 +88,16 @@
88
"@types/fs-extra": "^11.0.4",
89
"@types/inquirer": "^9.0.7",
90
"@types/jsdom": "^21.1.7",
91
- "@types/lodash": "^4.17.7",
92
- "@types/node": "^22.5.5",
91
+ "@types/lodash": "^4.17.9",
92
+ "@types/node": "^22.7.4",
93
"@types/validator": "^13.12.2",
94
"@vitejs/plugin-vue": "^5.1.4",
95
"@vitejs/plugin-vue-jsx": "^4.0.1",
96
"@vue/test-utils": "^2.4.6",
97
"@vue/tsconfig": "^0.5.1",
98
"autoprefixer": "^10.4.20",
99
- "cypress": "^13.14.2",
100
- "eslint": "^9.11.0",
99
+ "cypress": "^13.15.0",
100
+ "eslint": "^9.11.1",
101
"flourite": "^1.3.0",
102
"fs-extra": "^11.2.0",
103
"globals": "^15.9.0",
@@ -107,37 +107,37 @@
107
"picocolors": "^1.1.0",
108
"postcss": "^8.4.47",
109
"prettier": "^3.3.3",
110
- "sass": "^1.79.3",
110
+ "sass": "^1.79.4",
111
"start-server-and-test": "^2.0.8",
112
"tailwind-config-viewer": "^2.0.4",
113
- "tailwindcss": "^3.4.12",
114
- "taze": "^0.16.9",
113
+ "tailwindcss": "^3.4.13",
114
+ "taze": "^0.17.2",
115
"type-fest": "^4.26.1",
116
"typescript": "~5.5.4",
117
"unplugin-vue-components": "^0.27.4",
118
- "vite": "^5.4.7",
119
- "vite-bundle-analyzer": "^0.11.1",
118
+ "vite": "^5.4.8",
119
+ "vite-bundle-analyzer": "^0.12.1",
120
"vite-bundle-visualizer": "^1.2.1",
121
- "vite-plugin-vue-devtools": "^7.4.5",
121
+ "vite-plugin-vue-devtools": "^7.4.6",
122
"vite-svg-loader": "^5.1.0",
123
"vitest": "^2.1.1",
124
"vue-tsc": "^2.1.6"
125
},
126
"pnpm": {
127
"overrides": {
128
- "@typescript-eslint/eslint-plugin": "^8.6.0",
128
+ "@typescript-eslint/eslint-plugin": "^8.8.0",
129
"@typescript-eslint/eslint-plugin>eslint": "$eslint",
130
- "@typescript-eslint/parser": "^8.6.0",
130
+ "@typescript-eslint/parser": "^8.8.0",
131
"@typescript-eslint/parser>eslint": "$eslint",
132
"eslint": "$eslint"
133
}
134
},
135
"overrides": {
136
"@typescript-eslint/eslint-plugin": {
137
- "eslint": "9.11.0"
137
+ "eslint": "9.11.1"
138
},
139
"@typescript-eslint/parser": {
140
- "eslint": "9.11.0"
140
+ "eslint": "9.11.1"
141
}
142
}
143
}
frontend/src/App.vue
+4
-4
@@ -22,11 +22,11 @@
22
23
<script lang="ts" setup>
24
import type { Layout, RouterTransition, ThemeName } from "@/types/theme.d"
25
+import Blank from "@/app-layouts/Blank/index.vue"
26
+import Provider from "@/app-layouts/common/Provider.vue"
27
+import SplashScreen from "@/app-layouts/common/SplashScreen.vue"
28
+import HorizontalNav from "@/app-layouts/HorizontalNav/index.vue"
29
import SearchDialog from "@/components/common/SearchDialog.vue"
26
-import Blank from "@/layouts/Blank/index.vue"
27
-import Provider from "@/layouts/common/Provider.vue"
28
-import SplashScreen from "@/layouts/common/SplashScreen.vue"
29
-import HorizontalNav from "@/layouts/HorizontalNav/index.vue"
30
import { useAuthStore } from "@/stores/auth"
31
import { useMainStore } from "@/stores/main"
32
import { useThemeStore } from "@/stores/theme"
frontend/src/app-layouts/Blank/MainContainer.vue
renamed
+2
-2
@@ -2,7 +2,7 @@
2
<div class="main">
3
<n-scrollbar ref="scrollbar">
4
<div class="view" :class="[{ boxed }, `route-${routeName}`]">
5
- <slot></slot>
5
+ <slot />
6
</div>
7
</n-scrollbar>
8
</div>
@@ -24,7 +24,7 @@ const scrollbar = ref()
24
onMounted(() => {
25
router.afterEach(() => {
26
if (scrollbar?.value?.scrollTo) {
27
- scrollbar?.value.scrollTo({ top: 0 })
27
+ scrollbar?.value.scrollTo({ top: 0, behavior: "smooth" })
28
}
29
})
30
})
frontend/src/app-layouts/Blank/index.vue
renamed
+1
-1
@@ -1,7 +1,7 @@
1
<template>
2
<div class="layout flex">
3
<MainContainer class="grow">
4
- <slot></slot>
4
+ <slot />
5
</MainContainer>
6
</div>
7
</template>
frontend/src/app-layouts/HorizontalNav/HeaderBar.vue
renamed
+3
-3
@@ -2,14 +2,14 @@
2
<div class="header-bar flex items-center gap-3">
3
<Logo :mini="false" :dark="isDark" class="anim-wrap" />
4
<n-scrollbar class="grow" x-scrollable>
5
- <Navbar :collapsed="false" mode="horizontal"></Navbar>
5
+ <Navbar :collapsed="false" mode="horizontal" />
6
</n-scrollbar>
7
</div>
8
</template>
9
10
<script lang="ts" setup>
11
-import Logo from "@/layouts/common/Logo.vue"
12
-import Navbar from "@/layouts/common/Navbar/index.vue"
11
+import Logo from "@/app-layouts/common/Logo.vue"
12
+import Navbar from "@/app-layouts/common/Navbar/index.vue"
13
import { useThemeStore } from "@/stores/theme"
14
import { NScrollbar } from "naive-ui"
15
import { computed } from "vue"
frontend/src/app-layouts/HorizontalNav/MainContainer.vue
renamed
+4
-4
@@ -3,7 +3,7 @@
3
<n-scrollbar ref="scrollbar">
4
<Toolbar :boxed="toolbarBoxed" class="gradient-bg-sidebar" />
5
<div class="view" :class="[{ boxed }, `route-${routeName}`]">
6
- <slot></slot>
6
+ <slot />
7
</div>
8
<MainFooter v-if="footerShown" :boxed="boxed" />
9
</n-scrollbar>
@@ -11,8 +11,8 @@
11
</template>
12
13
<script lang="ts" setup>
14
-import MainFooter from "@/layouts/common/MainFooter.vue"
15
-import Toolbar from "@/layouts/common/Toolbar/index.vue"
14
+import MainFooter from "@/app-layouts/common/MainFooter.vue"
15
+import Toolbar from "@/app-layouts/common/Toolbar/index.vue"
16
import { useThemeStore } from "@/stores/theme"
17
import { NScrollbar } from "naive-ui"
18
import { computed, onMounted, ref } from "vue"
@@ -31,7 +31,7 @@ const scrollbar = ref()
31
onMounted(() => {
32
router.afterEach(() => {
33
if (scrollbar?.value?.scrollTo) {
34
- scrollbar?.value.scrollTo({ top: 0 })
34
+ scrollbar?.value.scrollTo({ top: 0, behavior: "smooth" })
35
}
36
})
37
})
frontend/src/app-layouts/HorizontalNav/Sidebar.vue
renamed
+2
-2
@@ -7,7 +7,7 @@
7
<div ref="sidebar" class="sidebar-wrap grow flex flex-col">
8
<SidebarHeader :logo-mini="sidebarClosed" />
9
<n-scrollbar>
10
- <Navbar :collapsed="sidebarClosed"></Navbar>
10
+ <Navbar :collapsed="sidebarClosed" />
11
</n-scrollbar>
12
<SidebarFooter :collapsed="sidebarClosed" />
13
</div>
@@ -15,7 +15,7 @@
15
</template>
16
17
<script lang="ts" setup>
18
-import Navbar from "@/layouts/common/Navbar/index.vue"
18
+import Navbar from "@/app-layouts/common/Navbar/index.vue"
19
import { useThemeStore } from "@/stores/theme"
20
import { isMobile } from "@/utils"
21
import { onClickOutside, useElementHover } from "@vueuse/core"
frontend/src/app-layouts/HorizontalNav/SidebarFooter.vue
renamed
frontend/src/app-layouts/HorizontalNav/SidebarHeader.vue
renamed
+1
-1
@@ -25,8 +25,8 @@
25
</template>
26
27
<script lang="ts" setup>
28
+import Logo from "@/app-layouts/common/Logo.vue"
29
import Icon from "@/components/common/Icon.vue"
29
-import Logo from "@/layouts/common/Logo.vue"
30
import { useThemeStore } from "@/stores/theme"
31
import { Icon as Iconify } from "@iconify/vue"
32
import { computed, toRefs } from "vue"
frontend/src/app-layouts/HorizontalNav/_variables.scss
renamed
frontend/src/app-layouts/HorizontalNav/index.vue
renamed
+1
-1
@@ -3,7 +3,7 @@
3
<HeaderBar />
4
<Sidebar />
5
<MainContainer class="grow">
6
- <slot></slot>
6
+ <slot />
7
</MainContainer>
8
</div>
9
</template>
frontend/src/app-layouts/HorizontalNav/main.scss
renamed
frontend/src/app-layouts/common/GlobalListener.vue
renamed
+1
-1
@@ -2,7 +2,7 @@
2
<slot />
3
</template>
4
5
-<script setup>
5
+<script setup lang="ts">
6
import { useGlobalActions } from "@/composables/useGlobalActions"
7
import { useMessage, useNotification } from "naive-ui"
8
frontend/src/app-layouts/common/Logo.vue
renamed
+4
-4
@@ -1,15 +1,15 @@
1
<template>
2
<div v-if="isDark && !mini" class="logo">
3
- <img src="@/assets/images/socfortress_logo.svg?url" />
3
+ <img alt="logo" src="@/assets/images/socfortress_logo.svg?url" />
4
</div>
5
<div v-else-if="isLight && !mini" class="logo">
6
- <img src="@/assets/images/socfortress_logo.svg?url" />
6
+ <img alt="logo" src="@/assets/images/socfortress_logo.svg?url" />
7
</div>
8
<div v-else-if="isDark && mini" class="logo">
9
- <img src="@/assets/images/socfortress_logo.svg?url" />
9
+ <img alt="logo" src="@/assets/images/socfortress_logo.svg?url" />
10
</div>
11
<div v-else-if="isLight && mini" class="logo">
12
- <img src="@/assets/images/socfortress_logo.svg?url" />
12
+ <img alt="logo" src="@/assets/images/socfortress_logo.svg?url" />
13
</div>
14
</template>
15
frontend/src/app-layouts/common/MainFooter.vue
renamed
+1
-1
@@ -10,7 +10,7 @@
10
<a
11
href="https://www.socfortress.co/"
12
target="_blank"
13
- alt="D*VERSE"
13
+ alt="SOCFortress"
14
rel="noopener noreferrer"
15
class="mx-1"
16
>
frontend/src/app-layouts/common/Navbar/index.vue
renamed
frontend/src/app-layouts/common/Navbar/items.tsx
renamed
frontend/src/app-layouts/common/Provider.vue
renamed
+17
-23
@@ -24,7 +24,7 @@
24
<script lang="ts" setup>
25
import type { ThemeName } from "@/types/theme.d"
26
import type { RtlItem } from "naive-ui/es/config-provider/src/internal-interface"
27
-import GlobalListener from "@/layouts/common/GlobalListener.vue"
27
+import GlobalListener from "@/app-layouts/common/GlobalListener.vue"
28
import { useThemeStore } from "@/stores/theme"
29
import { useWindowSize } from "@vueuse/core"
30
import {
@@ -36,7 +36,7 @@ import {
36
NMessageProvider,
37
NNotificationProvider
38
} from "naive-ui"
39
-import { computed, watch } from "vue"
39
+import { computed, onBeforeMount, watch } from "vue"
40
import { rtlStyles } from "./rtlProvider"
41
42
const { width } = useWindowSize()
@@ -48,29 +48,17 @@ const style = computed(() => themeStore.style)
48
const isRTL = computed(() => themeStore.isRTL)
49
const rtlOptions = computed<RtlItem[] | undefined>(() => (isRTL.value ? rtlStyles : undefined))
50
51
-watch(
52
- [isRTL, style],
53
- () => {
54
- setGlobalVars()
55
- },
56
- { immediate: true }
57
-)
51
+watch([isRTL, style], () => {
52
+ setGlobalVars()
53
+})
54
59
-watch(
60
- themeName,
61
- (val, old) => {
62
- setThemeName(val, old)
63
- },
64
- { immediate: true }
65
-)
55
+watch(themeName, (val, old) => {
56
+ setThemeName(val, old)
57
+})
58
67
-watch(
68
- width,
69
- () => {
70
- themeStore.updateVars()
71
- },
72
- { immediate: true }
73
-)
59
+watch(width, () => {
60
+ themeStore.updateVars()
61
+})
62
63
// This function allows you to utilize the values in the style object as variables within your CSS/SCSS code like: var(-–bg-color)
64
function setGlobalVars() {
@@ -101,4 +89,10 @@ function setThemeName(val: ThemeName, old?: ThemeName) {
89
html.classList.add(`theme-${val}`)
90
}
91
}
92
+
93
+onBeforeMount(() => {
94
+ themeStore.updateVars()
95
+ setGlobalVars()
96
+ setThemeName(themeName.value)
97
+})
98
</script>
frontend/src/app-layouts/common/SplashScreen.vue
renamed
frontend/src/app-layouts/common/Toolbar/Avatar.vue
renamed
+1
-1
@@ -1,6 +1,6 @@
1
<template>
2
<n-dropdown :options="options" placement="bottom-end" @select="handleSelect">
3
- <n-avatar round :size="32" :src="userPic" />
3
+ <n-avatar round :size="32" :src="userPic" :img-props="{ alt: 'avatar' }" />
4
</n-dropdown>
5
</template>
6
frontend/src/app-layouts/common/Toolbar/Breadcrumb.vue
renamed
+1
-1
@@ -1,7 +1,7 @@
1
<template>
2
<n-breadcrumb class="breadcrumb">
3
<n-breadcrumb-item @click="goto({ path: '/' })">
4
- <Icon :size="16" :name="HomeIcon"></Icon>
4
+ <Icon :size="16" :name="HomeIcon" />
5
</n-breadcrumb-item>
6
<TransitionGroup name="anim">
7
<n-breadcrumb-item
frontend/src/app-layouts/common/Toolbar/FullscreenSwitch.vue
renamed
+2
-2
@@ -1,7 +1,7 @@
1
<template>
2
<button class="fullscreen-switch" alt="fullscreen-switch" aria-label="fullscreen-switch" @click="toggleFullscreen">
3
- <Icon v-if="isFullscreen" :size="20" :name="CloseIcon"></Icon>
4
- <Icon v-else :size="20" :name="OpenIcon"></Icon>
3
+ <Icon v-if="isFullscreen" :size="20" :name="CloseIcon" />
4
+ <Icon v-else :size="20" :name="OpenIcon" />
5
</button>
6
</template>
7
frontend/src/app-layouts/common/Toolbar/LocaleSwitch.vue
renamed
+1
-1
@@ -1,6 +1,6 @@
1
<template>
2
<n-popselect v-model:value="currentLocale" :options="list" :render-label="renderLabel">
3
- <Icon :size="19" :name="MultiLanguageIcon"></Icon>
3
+ <Icon :size="19" :name="MultiLanguageIcon" />
4
</n-popselect>
5
</template>
6
frontend/src/app-layouts/common/Toolbar/Notifications.vue
renamed
+1
-1
@@ -2,7 +2,7 @@
2
<n-popover :show-arrow="false" placement="bottom" content-class="!p-0 w-72">
3
<template #trigger>
4
<n-badge :show="hasUnread" dot :color="primaryColor">
5
- <Icon :name="BellIcon" :size="21" class="trigger-icon"></Icon>
5
+ <Icon :name="BellIcon" :size="21" class="trigger-icon" />
6
</n-badge>
7
</template>
8
<template #header>
frontend/src/app-layouts/common/Toolbar/PinnedPages.vue
renamed
+46
-26
@@ -1,28 +1,20 @@
1
<template>
2
- <div class="pinned-pages flex items-center gap-5 relative overflow-hidden py-2 justify-end w-full">
3
- <TransitionGroup name="anim" tag="div" class="flex items-center gap-4 overflow-hidden latest-list">
2
+ <div class="flex pinned-pages items-center gap-5">
3
+ <TransitionGroup name="anim" tag="div" class="latest-list flex items-center gap-4 overflow-hidden">
4
<n-tag
5
v-for="page of latestSanitized"
6
:key="page.name"
7
round
8
:bordered="false"
9
:closable="false"
10
- class="bg-transparent flex-shrink overflow-hidden p-0 transition-all duration-300"
10
@close="removeLatestPage(page.name)"
11
>
13
- <span
14
- :title="page.title"
15
- class="cursor-pointer ml-0.5 overflow-hidden text-ellipsis hover:underline hover:decoration-2 hover:decoration-[var(--primary-color)]"
16
- @click="gotoPage(page.name)"
17
- >
12
+ <span class="page-name" :title="page.title" @click="gotoPage(page.name)">
13
{{ page.title }}
14
</span>
15
<template #icon>
21
- <div
22
- class="cursor-pointer transition-colors duration-300 mr-0.5 hover:text-[var(--primary-color)]"
23
- @click="pinPage(page)"
24
- >
25
- <Icon :size="14" :name="PinnedIcon"></Icon>
16
+ <div class="icon-box" @click="pinPage(page)">
17
+ <Icon :size="14" :name="PinnedIcon" />
18
</div>
19
</template>
20
</n-tag>
@@ -33,7 +25,7 @@
25
<n-popover :show-arrow="false" placement="bottom-end" trigger="hover" class="!p-1">
26
<template #trigger>
27
<n-button size="small" class="!h-8">
36
- <span class="flex items-center gap-3">
28
+ <span class="flex items-center gap-2">
29
Shortcuts
30
<n-badge :value="pinned.length" :color="style['divider-030-color']" />
31
</span>
@@ -48,15 +40,17 @@
40
class="!justify-start"
41
@click="gotoPage(page.name)"
42
>
51
- <template #icon>
43
+ <span class="flex items-center gap-1">
44
<Icon
45
:size="20"
46
:name="CloseIcon"
47
class="opacity-50 hover:text-red-500 hover:opacity-100"
48
@click.stop="removePinnedPage(page.name)"
57
- ></Icon>
58
- </template>
59
- {{ page.title }}
49
+ />
50
+ <span class="px-2">
51
+ {{ page.title }}
52
+ </span>
53
+ </span>
54
</n-button>
55
</div>
56
</n-popover>
@@ -89,6 +83,12 @@ const themeStore = useThemeStore()
83
const style = computed(() => themeStore.style)
84
const latest: RemovableRef<Page[]> = useStorage<Page[]>("latest-pages", [], sessionStorage)
85
const pinned: RemovableRef<Page[]> = useStorage<Page[]>("pinned-pages", [], localStorage)
86
+const latestSanitized: ComputedRef<Page[]> = computed(() => {
87
+ return _takeRight(
88
+ latest.value.filter(page => pinned.value.findIndex(p => p.name === page.name) === -1).reverse(),
89
+ 3
90
+ ) as Page[]
91
+})
92
93
function removeLatestPage(pageName: RouteRecordName | string) {
94
latest.value = latest.value.filter(page => page.name !== pageName)
@@ -111,13 +111,6 @@ function pinPage(page: Page) {
111
return true
112
}
113
114
-const latestSanitized: ComputedRef<Page[]> = computed(() => {
115
- return _takeRight(
116
- latest.value.filter(page => pinned.value.findIndex(p => p.name === page.name) === -1).reverse(),
117
- 3
118
- ) as Page[]
119
-})
120
-
114
function checkRoute(route: RouteLocationNormalized) {
115
const title = route.meta?.title || _split(route.name?.toString(), "-").at(-1)
116
@@ -138,16 +131,22 @@ router.afterEach(route => {
131
132
<style lang="scss" scoped>
133
.pinned-pages {
134
+ position: relative;
135
+ overflow: hidden;
136
+ padding: 8px 0;
137
container-type: inline-size;
138
+ justify-content: flex-end;
139
+ width: 100%;
140
141
:deep() {
142
.n-tag {
143
background-color: transparent;
144
flex-shrink: 1;
145
overflow: hidden;
146
+ gap: 4px;
147
148
&.n-tag--round {
150
- padding: 0;
149
+ padding: 0 !important;
150
transition: all 0.3s;
151
}
152
.n-tag__icon {
@@ -182,6 +181,27 @@ router.afterEach(route => {
181
}
182
}
183
184
+ .page-name {
185
+ cursor: pointer;
186
+ overflow: hidden;
187
+ text-overflow: ellipsis;
188
+
189
+ &:hover {
190
+ text-decoration: underline;
191
+ text-decoration-thickness: 2px;
192
+ text-decoration-color: var(--primary-color);
193
+ }
194
+ }
195
+
196
+ .icon-box {
197
+ cursor: pointer;
198
+ transition: color 0.3s;
199
+
200
+ &:hover {
201
+ color: var(--primary-color);
202
+ }
203
+ }
204
+
205
.anim-move,
206
.anim-enter-active,
207
.anim-leave-active {
frontend/src/app-layouts/common/Toolbar/Search.vue
renamed
+1
-1
@@ -1,6 +1,6 @@
1
<template>
2
<div class="flex items-center search-btn" @click="openBox">
3
- <Icon :name="SearchIcon" :size="16" class="search-btn-icon"></Icon>
3
+ <Icon :name="SearchIcon" :size="16" class="search-btn-icon" />
4
<span>Search</span>
5
<n-text code class="search-command">
6
<span :class="{ win: commandIcon === 'CTRL' }">{{ commandIcon }}</span>
frontend/src/app-layouts/common/Toolbar/ThemeSwitch.vue
renamed
+6
-6
@@ -2,12 +2,12 @@
2
<button class="theme-switch" alt="theme-switch" aria-label="theme-switch" @click="toggleTheme">
3
<Transition name="rotate">
4
<Icon v-if="isThemeDark" :size="20">
5
- <Iconify :icon="Sunny" class="hover"></Iconify>
6
- <Iconify :icon="SunnyOutline"></Iconify>
5
+ <Iconify :icon="Sunny" class="hover" />
6
+ <Iconify :icon="SunnyOutline" />
7
</Icon>
8
<Icon v-else :size="20">
9
- <Iconify :icon="Moon" class="hover"></Iconify>
10
- <Iconify :icon="MoonOutline"></Iconify>
9
+ <Iconify :icon="Moon" class="hover" />
10
+ <Iconify :icon="MoonOutline" />
11
</Icon>
12
</Transition>
13
</button>
@@ -29,8 +29,8 @@ const isThemeDark = computed<boolean>(() => themeStore.isThemeDark)
29
function toggleTheme(event?: MouseEvent) {
30
const isAppearanceTransition =
31
typeof document !== "undefined" &&
32
- document?.startViewTransition &&
33
- !window?.matchMedia("(prefers-reduced-motion: reduce)").matches
32
+ document.startViewTransition &&
33
+ !window.matchMedia("(prefers-reduced-motion: reduce)").matches
34
35
if (!isAppearanceTransition || !event) {
36
themeStore.toggleTheme()
frontend/src/app-layouts/common/Toolbar/index.vue
renamed
+1
-1
@@ -3,7 +3,7 @@
3
<div class="wrap flex items-center justify-end gap-3">
4
<div class="logo-box flex items-center gap-2 cursor-pointer" @click="openNav()">
5
<Logo mini />
6
- <Icon :size="20" name="carbon:chevron-right"></Icon>
6
+ <Icon :size="20" name="carbon:chevron-right" />
7
</div>
8
9
<Breadcrumb class="grow" />
frontend/src/app-layouts/common/rtlProvider.ts
renamed
frontend/src/assets/scss/naive-override.scss
+19
-7
@@ -19,32 +19,43 @@
19
}
20
}
21
22
-.n-image-preview-overlay {
23
- backdrop-filter: blur(3px);
24
-}
25
-.n-image-preview-toolbar {
26
- box-sizing: content-box;
27
-
28
- * {
22
+.n-image-preview-container {
23
+ .n-image-preview-overlay {
24
+ backdrop-filter: blur(3px);
25
+ }
26
+ .n-image-preview-toolbar {
27
box-sizing: content-box;
28
+
29
+ * {
30
+ box-sizing: content-box;
31
+ }
32
+
33
+ & > i {
34
+ font-size: clamp(18px, 5.5vw, 28px);
35
+ }
36
}
37
}
38
+
39
.n-slider {
40
box-sizing: content-box;
41
}
42
+
43
.n-calendar * {
44
box-sizing: content-box;
45
}
46
+
47
.n-badge {
48
.n-badge-sup {
49
top: inherit;
50
}
51
}
52
+
53
.n-dropdown-menu {
54
&.n-dropdown-menu--scrollable {
55
max-height: 60vh;
56
}
57
}
58
+
59
.n-card {
60
& > .n-card-header {
61
div.n-card-header__main {
@@ -56,6 +67,7 @@
67
max-height: 100%;
68
}
69
}
70
+
71
.n-avatar .n-avatar__text {
72
transform: translateX(-50%) translateY(-50%) scale(1);
73
}
frontend/src/components/auth/AuthForm.vue
+1
-1
@@ -32,7 +32,7 @@
32
33
<script lang="ts" setup>
34
import type { FormType } from "./types.d"
35
-import Logo from "@/layouts/common/Logo.vue"
35
+import Logo from "@/app-layouts/common/Logo.vue"
36
import { useThemeStore } from "@/stores/theme"
37
import { NButton } from "naive-ui"
38
import { computed, onBeforeMount, ref } from "vue"
frontend/src/components/common/CardStatsBars.vue
new
+221
@@ -0,0 +1,221 @@
1
+<template>
2
+ <n-card content-style="padding:0" :class="{ hovered }">
3
+ <div class="flex flex-col overflow-hidden">
4
+ <div class="card-header flex gap-4 items-center justify-between">
5
+ <div class="title flex items-center gap-2 grow">
6
+ <span class="truncate">{{ title }}</span>
7
+ <Icon v-if="hovered" :name="ArrowRightIcon" :size="12"></Icon>
8
+ </div>
9
+ <div class="icon">
10
+ <slot name="icon"></slot>
11
+ </div>
12
+ </div>
13
+ <div class="flex flex-col gap-3 card-content">
14
+ <div class="bars flex">
15
+ <div
16
+ v-for="item of barValues"
17
+ :key="JSON.stringify(item)"
18
+ :class="item.status"
19
+ class="bar"
20
+ :style="{ width: `${item.percentage}%` }"
21
+ >
22
+ <div class="fill"></div>
23
+ </div>
24
+ </div>
25
+ <div class="list flex flex-col">
26
+ <div
27
+ v-for="item of sanitizedValues"
28
+ :key="JSON.stringify(item)"
29
+ class="flex items-center item gap-3"
30
+ :class="item.status"
31
+ >
32
+ <div class="label flex gap-2 items-center truncate">
33
+ <span class="badge"></span>
34
+ <span class="font-mono truncate">{{ item.label }}</span>
35
+ </div>
36
+ <div class="divider grow"></div>
37
+ <div class="value flex gap-3 font-mono whitespace-nowrap">
38
+ <span v-if="!item.isTotal" class="opacity-50">{{ item.percentage }}%</span>
39
+ <strong>{{ item.value }}</strong>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </n-card>
46
+</template>
47
+
48
+<script setup lang="ts">
49
+import Icon from "@/components/common/Icon.vue"
50
+import _round from "lodash/round"
51
+import { NCard } from "naive-ui"
52
+import { computed, toRefs } from "vue"
53
+
54
+export interface ItemProps {
55
+ value: number
56
+ label: string
57
+ isTotal?: boolean
58
+ status?: "success" | "warning" | "error" | "muted" | "primary"
59
+}
60
+
61
+interface ItemPropsExt extends ItemProps {
62
+ percentage: number
63
+}
64
+
65
+const props = defineProps<{
66
+ title: string
67
+ values: ItemProps[]
68
+ showZeroItems?: boolean
69
+ hovered?: boolean
70
+}>()
71
+const { title, values, showZeroItems, hovered } = toRefs(props)
72
+
73
+const ArrowRightIcon = "carbon:arrow-right"
74
+const totItem = computed(
75
+ () =>
76
+ values.value.find(item => item.isTotal) || {
77
+ value: values.value.reduce((acc, cur) => {
78
+ return acc + cur.value
79
+ }, 0),
80
+ isTotal: true,
81
+ label: "Total"
82
+ }
83
+)
84
+
85
+const sanitizedValues = computed<ItemPropsExt[]>(() => {
86
+ const list: ItemPropsExt[] = values.value
87
+ .filter(o => !o.isTotal)
88
+ .map(o => ({ ...o, percentage: _round((o.value / totItem.value.value) * 100, 2) }))
89
+ .filter(o => o.value || (!o.value && showZeroItems.value))
90
+
91
+ return [{ ...totItem.value, percentage: 100 }, ...list]
92
+})
93
+
94
+const barValues = computed<ItemPropsExt[]>(() => sanitizedValues.value.filter(o => !o.isTotal && o.percentage))
95
+</script>
96
+
97
+<style scoped lang="scss">
98
+.n-card {
99
+ overflow: hidden;
100
+
101
+ .card-header {
102
+ border-bottom: var(--border-small-050);
103
+ overflow: hidden;
104
+ padding: 10px 16px;
105
+
106
+ .title {
107
+ font-size: 16px;
108
+ text-overflow: ellipsis;
109
+ white-space: nowrap;
110
+ overflow: hidden;
111
+ }
112
+ }
113
+
114
+ .card-content {
115
+ padding: 10px 16px;
116
+
117
+ .bars {
118
+ height: 10px;
119
+
120
+ .bar {
121
+ padding: 0 2px;
122
+
123
+ &:first-child {
124
+ padding-left: 0;
125
+ }
126
+ &:last-child {
127
+ padding-right: 0;
128
+ }
129
+
130
+ .fill {
131
+ border-radius: var(--border-radius-small);
132
+ background-color: var(--fg-color);
133
+ height: 100%;
134
+ width: 100%;
135
+ }
136
+
137
+ &.success {
138
+ .fill {
139
+ background-color: var(--success-color);
140
+ }
141
+ }
142
+ &.warning {
143
+ .fill {
144
+ background-color: var(--warning-color);
145
+ }
146
+ }
147
+ &.error {
148
+ .fill {
149
+ background-color: var(--error-color);
150
+ }
151
+ }
152
+ &.muted {
153
+ .fill {
154
+ background-color: var(--fg-secondary-color);
155
+ }
156
+ }
157
+ &.primary {
158
+ .fill {
159
+ background-color: var(--primary-color);
160
+ }
161
+ }
162
+ }
163
+ }
164
+
165
+ .list {
166
+ font-size: 13px;
167
+ gap: 4px;
168
+
169
+ .item {
170
+ line-height: 1;
171
+ padding: 3px 4px;
172
+
173
+ .badge {
174
+ height: 10px;
175
+ width: 10px;
176
+ min-width: 10px;
177
+ border-radius: var(--border-radius-small);
178
+ background-color: var(--fg-color);
179
+ }
180
+
181
+ .divider {
182
+ height: 1px;
183
+ background-color: var(--hover-010-color);
184
+ }
185
+
186
+ &.success {
187
+ .badge {
188
+ background-color: var(--success-color);
189
+ }
190
+ }
191
+ &.warning {
192
+ .badge {
193
+ background-color: var(--warning-color);
194
+ }
195
+ }
196
+ &.error {
197
+ .badge {
198
+ background-color: var(--error-color);
199
+ }
200
+ }
201
+ &.muted {
202
+ .badge {
203
+ background-color: var(--fg-secondary-color);
204
+ }
205
+ }
206
+ &.primary {
207
+ .badge {
208
+ background-color: var(--primary-color);
209
+ }
210
+ }
211
+ }
212
+ }
213
+ }
214
+
215
+ &.hovered {
216
+ &:hover {
217
+ border-color: var(--primary-color);
218
+ }
219
+ }
220
+}
221
+</style>
frontend/src/components/common/CardStatsMulti.vue
renamed
+23
-25
@@ -1,30 +1,27 @@
1
<template>
2
<n-card content-style="padding:0" :class="{ hovered }">
3
- <div class="flex flex-col overflow-hidden">
3
+ <div class="flex flex-col overflow-hidden h-full">
4
<div class="card-header flex gap-4 items-center justify-between">
5
- <div class="title flex items-center gap-2">
6
- {{ title }}
5
+ <div class="title flex items-center gap-2 grow">
6
+ <span class="truncate">{{ title }}</span>
7
<Icon v-if="hovered" :name="ArrowRightIcon" :size="12"></Icon>
8
</div>
9
<div class="icon">
10
<slot name="icon"></slot>
11
</div>
12
</div>
13
- <div class="flex card-content">
14
- <div class="flex flex-col basis-1/2 value-box" :class="firstStatus">
15
- <div class="value">
16
- {{ value }}
13
+ <div class="flex card-content grow">
14
+ <div
15
+ v-for="item of values"
16
+ :key="JSON.stringify(item)"
17
+ class="flex flex-col value-box"
18
+ :class="[item.status, values.length !== 1 ? `basis-1/${values.length}` : 'grow']"
19
+ >
20
+ <div class="value grow flex justify-center items-center">
21
+ {{ item.value }}
22
</div>
18
- <div v-if="firstLabel" class="label">
19
- {{ firstLabel }}
20
- </div>
21
- </div>
22
- <div class="flex flex-col basis-1/2 value-box" :class="secondStatus">
23
- <div class="value">
24
- {{ subValue }}
25
- </div>
26
- <div v-if="secondLabel" class="label">
27
- {{ secondLabel }}
23
+ <div v-if="item.label" class="label">
24
+ {{ item.label }}
25
</div>
26
</div>
27
</div>
@@ -37,17 +34,18 @@ import Icon from "@/components/common/Icon.vue"
34
import { NCard } from "naive-ui"
35
import { toRefs } from "vue"
36
37
+export interface ItemProps {
38
+ value: number | string
39
+ label?: string
40
+ status?: "success" | "warning" | "error"
41
+}
42
+
43
const props = defineProps<{
44
title: string
42
- value?: number | string
43
- subValue?: number | string
44
- firstLabel?: string
45
- secondLabel?: string
46
- firstStatus?: "success" | "warning" | "error"
47
- secondStatus?: "success" | "warning" | "error"
45
+ values: ItemProps[]
46
hovered?: boolean
47
}>()
50
-const { title, value, subValue, firstLabel, secondLabel, firstStatus, secondStatus, hovered } = toRefs(props)
48
+const { title, values, hovered } = toRefs(props)
49
50
const ArrowRightIcon = "carbon:arrow-right"
51
</script>
@@ -74,7 +72,7 @@ const ArrowRightIcon = "carbon:arrow-right"
72
text-align: center;
73
overflow: hidden;
74
77
- &:first-child {
75
+ &:not(:last-child) {
76
border-right: var(--border-small-050);
77
}
78
frontend/src/components/common/FileDrop.vue
deleted
-54
@@ -1,54 +0,0 @@
1
-<template>
2
- <form class="file-drop">
3
- <label>
4
- <slot />
5
- <input type="file" :multiple="multiple" :accept @change="onChange" />
6
- </label>
7
- </form>
8
-</template>
9
-
10
-<script lang="ts" setup>
11
-import { toRefs } from "vue"
12
-
13
-const props = withDefaults(
14
- defineProps<{
15
- accept: string
16
- multiple: boolean
17
- }>(),
18
- { accept: ".jpg,.jpeg,.png,.webp", multiple: false }
19
-)
20
-const emit = defineEmits<{
21
- (e: "change-file", value: FileList | File | null): void
22
-}>()
23
-
24
-const { accept, multiple } = toRefs(props)
25
-
26
-function onChange(event: Event) {
27
- const input = event.target as HTMLInputElement
28
- if (multiple.value) {
29
- emit("change-file", input?.files)
30
- } else {
31
- if (input?.files?.length) {
32
- emit("change-file", input?.files[0])
33
- }
34
- }
35
- input?.form?.reset()
36
-}
37
-</script>
38
-
39
-<style lang="scss" scoped>
40
-.file-drop {
41
- label {
42
- display: flex;
43
- align-items: center;
44
- justify-content: center;
45
- width: 100%;
46
- height: 100%;
47
- cursor: pointer;
48
-
49
- input {
50
- display: none;
51
- }
52
- }
53
-}
54
-</style>
frontend/src/components/common/ImageLoader.vue
deleted
-109
@@ -1,109 +0,0 @@
1
-<template>
2
- <img
3
- v-if="isImageError && fallback"
4
- :src="fallback"
5
- class="image-fallback"
6
- draggable="false"
7
- :class="imageClass"
8
- @load="imageFallback"
9
- />
10
- <img
11
- v-if="!isImageError"
12
- :src="mainSrc"
13
- draggable="false"
14
- class="image-loading"
15
- :class="imageClass"
16
- @load="imageLoading"
17
- />
18
-</template>
19
-
20
-<script setup lang="ts">
21
-import { ref, watch } from "vue"
22
-
23
-export interface ImageEvent {
24
- height: number
25
-}
26
-export interface ImageLoadEvent extends Event {
27
- path?: HTMLElement[]
28
-}
29
-
30
-const props = defineProps({
31
- src: {
32
- type: String,
33
- required: true
34
- },
35
- fallback: {
36
- type: String
37
- },
38
- loading: {
39
- type: String
40
- },
41
- imageClass: {
42
- type: String,
43
- default: ""
44
- }
45
-})
46
-
47
-const emit = defineEmits(["image-error", "image-loading", "image-loaded", "image-fallback"])
48
-
49
-const isImageLoaded = ref(false)
50
-const isImageError = ref(false)
51
-const mainSrc = ref(props.loading)
52
-
53
-function imageLoading(e: ImageLoadEvent) {
54
- const elPath: HTMLElement | undefined = e.path && e.path[0]
55
- const el = (e.target || elPath || null) as HTMLImageElement | null
56
-
57
- emit("image-loading", { height: el?.offsetHeight || 0 } as ImageEvent)
58
- return e
59
-}
60
-function imageFallback(e: ImageLoadEvent) {
61
- const elPath: HTMLElement | undefined = e.path && e.path[0]
62
- const el = (e.target || elPath || null) as HTMLImageElement | null
63
-
64
- emit("image-fallback", { height: el?.offsetHeight || 0 } as ImageEvent)
65
- return e
66
-}
67
-function imageLoaded(e: ImageLoadEvent) {
68
- mainSrc.value = props.src
69
- const elPath: HTMLElement | undefined = e.path && e.path[0]
70
- const el = (e.target || elPath || null) as HTMLImageElement | null
71
- isImageLoaded.value = true
72
-
73
- emit("image-loaded", { height: el?.offsetHeight || 0 } as ImageEvent)
74
-}
75
-function imageError() {
76
- isImageError.value = true
77
- emit("image-error")
78
-}
79
-
80
-function createLoader() {
81
- const img = new Image()
82
- img.onload = imageLoaded
83
- img.onerror = imageError
84
- img.src = props.src
85
-}
86
-
87
-watch(
88
- () => props.src,
89
- () => {
90
- createLoader()
91
- }
92
-)
93
-
94
-createLoader()
95
-</script>
96
-
97
-<style lang="scss" scoped>
98
-img {
99
- opacity: 1;
100
- display: block;
101
- transition: opacity 0.8s;
102
-
103
- &.hide {
104
- opacity: 0;
105
- max-height: 0;
106
- //transform: scale(0);
107
- }
108
-}
109
-</style>
frontend/src/components/common/SearchDialog.vue
+32
-45
@@ -12,9 +12,7 @@
12
<n-scrollbar ref="scrollContent" class="!h-96">
13
<div class="conten-wrap">
14
<div v-for="group of filteredGroups" :key="group.name" class="group">
15
- <div class="group-title">
16
- {{ group.name }}
17
- </div>
15
+ <div class="group-title">{{ group.name }}</div>
16
<div class="group-list">
17
<button
18
v-for="item of group.items"
@@ -25,7 +23,13 @@
23
@click="callAction(item.action)"
24
>
25
<div class="icon">
28
- <n-avatar v-if="item.iconImage" round :size="28" :src="item.iconImage" />
26
+ <n-avatar
27
+ v-if="item.iconImage"
28
+ round
29
+ :size="28"
30
+ :src="item.iconImage"
31
+ :img-props="{ alt: 'avatar' }"
32
+ />
33
<Icon v-if="item.iconName" :name="item.iconName" :size="16" />
34
</div>
35
<div class="title grow">
@@ -36,9 +40,7 @@
40
:text-to-highlight="item.title"
41
/>
42
</div>
39
- <div class="label">
40
- {{ item.label }}
41
- </div>
43
+ <div class="label">{{ item.label }}</div>
44
</button>
45
</div>
46
</div>
@@ -86,7 +88,7 @@ interface GroupItem {
88
key: number | string
89
title: string
90
label: string
89
- tags?: string
91
+ tags?: string[]
92
action: () => void
93
}
94
@@ -190,53 +192,32 @@ const groups = ref<Groups>([
192
])
193
194
const keywords = computed<string[]>(() => {
193
- if (search.value.length > 1) {
194
- return search.value.split(" ").filter(k => k)
195
- } else {
196
- return []
197
- }
195
+ return search.value.length > 1 ? search.value.split(" ").filter(k => k) : []
196
})
197
+
198
const filteredGroups = computed<Groups>(() => {
200
- if (keywords.value.length === 0) {
201
- return groups.value
202
- }
203
- const newGroups: Groups = []
204
- for (const group of groups.value) {
205
- const items = group.items.filter(item => {
206
- if (keywords.value.filter(k => item.title.toLowerCase().includes(k.toLowerCase())).length !== 0) {
207
- return true
208
- }
209
- if (
210
- item.tags &&
211
- keywords.value.filter(k => item.tags?.toLowerCase().indexOf(k.toLowerCase()) !== -1).length !== 0
212
- ) {
213
- return true
214
- }
215
- return false
216
- })
217
- if (items.length) {
218
- newGroups.push({
219
- name: group.name,
220
- items
221
- })
222
- }
223
- }
224
- return newGroups
199
+ if (!keywords.value.length) return groups.value
200
+
201
+ return groups.value
202
+ .map(group => ({
203
+ name: group.name,
204
+ items: group.items.filter(
205
+ item =>
206
+ keywords.value.some(k => item.title.toLowerCase().includes(k.toLowerCase())) ||
207
+ item.tags?.some(t => keywords.value.some(k => t.toLowerCase().includes(k.toLowerCase())))
208
+ )
209
+ }))
210
+ .filter(group => group.items.length)
211
})
212
213
const filteredFlattenItems = computed<GroupItem[]>(() => {
228
- const items = []
229
-
230
- for (const group of filteredGroups.value) {
231
- items.push(...group.items)
232
- }
233
-
234
- return items
214
+ return filteredGroups.value.reduce((acc, group) => [...acc, ...group.items], [] as GroupItem[])
215
})
216
217
function openBox(e?: MouseEvent) {
218
if (!showSearchBox.value) {
219
showSearchBox.value = true
220
+
221
setTimeout(() => {
222
search.value = ""
223
activeItem.value = null
@@ -244,15 +225,18 @@ function openBox(e?: MouseEvent) {
225
}
226
return e
227
}
228
+
229
function closeBox() {
230
showSearchBox.value = false
231
search.value = ""
232
activeItem.value = null
233
}
234
+
235
function callAction(action: () => void) {
236
action()
237
closeBox()
238
}
239
+
240
function nextItem() {
241
const currentIndex = filteredFlattenItems.value.findIndex(item => item.key === activeItem.value)
242
if (currentIndex === filteredFlattenItems.value.length - 1 || activeItem.value === null) {
@@ -262,6 +246,7 @@ function nextItem() {
246
}
247
centerItem()
248
}
249
+
250
function prevItem() {
251
const currentIndex = filteredFlattenItems.value.findIndex(item => item.key === activeItem.value)
252
if (currentIndex === 0 || activeItem.value === null) {
@@ -271,12 +256,14 @@ function prevItem() {
256
}
257
centerItem()
258
}
259
+
260
function performAction() {
261
const item = filteredFlattenItems.value.find(item => item.key === activeItem.value)
262
if (item) {
263
callAction(item.action)
264
}
265
}
266
+
267
function centerItem() {
268
const element = document.getElementById(activeItem.value?.toString() || "")
269
if (element && scrollContent.value) {
frontend/src/components/common/SegmentedPage.vue
+42
-42
@@ -2,15 +2,16 @@
2
<n-split
3
ref="splitPane"
4
direction="horizontal"
5
- :default-size="splitDefault"
5
+ :default-size="sanitizedDefaultSplit"
6
:min="0"
7
:max="1"
8
:resize-trigger-size="0"
9
:disabled="!enableResize || splitDisabled"
10
class="wrapper flex grow"
11
:class="[{ 'sidebar-open': sidebarOpen }, `sidebar-position-${sidebarPosition}`]"
12
+ :pane1-style="pane1Style"
13
>
13
- <template #1>
14
+ <template #[tplNameSide]>
15
<div v-if="sidebarAvailable" ref="sidebar" class="sidebar flex flex-col">
16
<div v-if="$slots['sidebar-header']" class="sidebar-header flex items-center">
17
<slot name="sidebar-header" />
@@ -36,7 +37,7 @@
37
</div>
38
</template>
39
39
- <template #2>
40
+ <template #[tplNameMain]>
41
<div class="main flex-grow flex flex-col">
42
<div v-if="$slots['main-toolbar']" class="main-toolbar flex items-center">
43
<div v-if="sidebarAvailable && !hideMenuBtn" class="menu-btn flex justify-center opacity-50">
@@ -96,8 +97,11 @@ const props = withDefaults(
97
sidebarContentClass?: string
98
enableResize?: boolean
99
disableContainerQuery?: boolean
100
+ defaultSplit?: number
101
+ maxSidebarWidth?: number
102
+ minSidebarWidth?: number
103
}>(),
100
- { sidebarPosition: "left", useMainScroll: true }
104
+ { sidebarPosition: "left", useMainScroll: true, defaultSplit: 0.3, maxSidebarWidth: 450, minSidebarWidth: 250 }
105
)
106
107
const emit = defineEmits<{
@@ -112,25 +116,36 @@ const {
116
mainContentStyle,
117
mainContentClass,
118
sidebarContentStyle,
115
- sidebarContentClass
119
+ sidebarContentClass,
120
+ enableResize,
121
+ disableContainerQuery,
122
+ defaultSplit,
123
+ maxSidebarWidth,
124
+ minSidebarWidth
125
} = toRefs(props)
126
127
const MenuIcon = "ph:list-light"
128
const SplitIcon = "carbon:draggable"
129
130
const splitPane = ref()
122
-const splitDefault = ref(0.3)
131
+const sanitizedDefaultSplit = ref(defaultSplit.value)
132
const splitDisabled = ref(false)
133
134
const slots = useSlots()
135
const sidebarOpen = ref(false)
136
const sidebar = ref(null)
137
const mainScrollbar = ref<typeof NScrollbar | null>(null)
138
+const { width } = useWindowSize()
139
const sidebarAvailable = computed(
140
() => !!slots["sidebar-header"] || !!slots["sidebar-content"] || !!slots["sidebar-footer"]
141
)
132
-
133
-onClickOutside(sidebar, () => closeSidebar())
142
+const isSidebarLeft = computed<boolean>(() => sidebarPosition.value === "left")
143
+const tplNameMain = computed<1 | 2>(() => (isSidebarLeft.value ? 2 : 1))
144
+const tplNameSide = computed<1 | 2>(() => (isSidebarLeft.value ? 1 : 2))
145
+const pane1Style = computed(() => ({
146
+ maxWidth: isSidebarLeft.value ? `${maxSidebarWidth.value}px` : `calc(100% - ${minSidebarWidth.value}px)`,
147
+ minWidth: isSidebarLeft.value ? `${minSidebarWidth.value}px` : `calc(100% - ${maxSidebarWidth.value}px)`
148
+}))
149
150
function closeSidebar() {
151
sidebarOpen.value = false
@@ -140,6 +155,8 @@ function openSidebar() {
155
sidebarOpen.value = true
156
}
157
158
+onClickOutside(sidebar, () => closeSidebar())
159
+
160
watch(
161
sidebarOpen,
162
val => {
@@ -148,12 +165,10 @@ watch(
165
{ immediate: true }
166
)
167
151
-const { width } = useWindowSize()
152
-
168
watch(
169
width,
170
val => {
156
- splitDefault.value = val <= 700 ? 0 : 0.3
171
+ sanitizedDefaultSplit.value = val <= 700 ? 0 : isSidebarLeft.value ? defaultSplit.value : 1 - defaultSplit.value
172
splitDisabled.value = val <= 700
173
},
174
{ immediate: true }
@@ -179,18 +194,6 @@ onMounted(() => {
194
background-color: var(--bg-color);
195
direction: ltr;
196
182
- :deep() {
183
- .n-split-pane-1,
184
- .n-split-pane-2 {
185
- overflow: hidden;
186
- height: 100%;
187
- }
188
- .n-split-pane-1 {
189
- min-width: 250px;
190
- max-width: min(450px, calc(100% - 400px));
191
- }
192
- }
193
-
197
.split-trigger {
198
height: 100%;
199
width: 3px;
@@ -225,9 +228,6 @@ onMounted(() => {
228
229
.sidebar {
230
background-color: var(--bg-secondary-color);
228
- min-width: 250px;
229
- //max-width: calc(100% - 400px);
230
- //width: 35%;
231
height: 100%;
232
overflow: hidden;
233
border-right: 1px solid var(--border-color);
@@ -307,15 +307,6 @@ onMounted(() => {
307
}
308
}
309
310
- &.sidebar-position-right {
311
- flex-direction: row-reverse;
312
-
313
- .sidebar {
314
- border-right: none;
315
- border-left: 1px solid var(--border-color);
316
- }
317
- }
318
-
310
@media (max-width: 700px) {
311
--mb-toolbar-height: 62px;
312
height: 100%;
@@ -323,13 +314,6 @@ onMounted(() => {
314
border-radius: 0;
315
border: none;
316
326
- :deep() {
327
- .n-split-pane-1 {
328
- min-width: 0;
329
- max-width: 0;
330
- }
331
- }
332
-
317
&::before {
318
content: "";
319
width: 100vw;
@@ -399,7 +383,23 @@ onMounted(() => {
383
}
384
}
385
386
+ &.sidebar-position-left {
387
+ :deep() {
388
+ .n-split-pane-1 {
389
+ min-width: 0 !important;
390
+ max-width: 0 !important;
391
+ }
392
+ }
393
+ }
394
+
395
&.sidebar-position-right {
396
+ :deep() {
397
+ .n-split-pane-1 {
398
+ min-width: 100% !important;
399
+ max-width: 100% !important;
400
+ }
401
+ }
402
+
403
&::before,
404
.sidebar {
405
left: initial;
frontend/src/components/customers/provision/CustomerProvisionWizard.vue
+1
-1
@@ -563,7 +563,7 @@ function toggleDashboards() {
563
form.value.dashboards_to_include.dashboards = dashboardOptions.value
564
.filter(
565
o =>
566
- !["EDR_WAZUH_INVENOTRY", "EDR_WAZUH_INVENTORY", "EDR_AGENT_INVENTORY"]
566
+ !["EDR_WAZUH_INVENTORY", "EDR_AGENT_INVENTORY"]
567
.map(d => d.toLowerCase())
568
.includes(o.value.toLowerCase())
569
)
frontend/src/components/graylog/MonitoringAlerts/CustomAlertForm.vue
+12
-1
@@ -214,11 +214,14 @@ const areAllCustomerFieldsUniques = computed(() => {
214
return uniques.length === form.value.custom_fields.length
215
})
216
217
-const isCustomerCodePresent = computed(() => {
217
+/** @deprecated */
218
+/*
219
+ const isCustomerCodePresent = computed(() => {
220
const field = form.value.custom_fields.filter(o => o.name === "CUSTOMER_CODE" && !!o.value)
221
222
return !!field.length
223
})
224
+*/
225
226
const alertPriorityOptions: { label: string; value: CustomProvisionPriority }[] = [
227
{ label: "Low", value: CustomProvisionPriority.LOW },
@@ -261,6 +264,7 @@ const rules: FormRules = {
264
},
265
custom_fields: {
266
required: true,
267
+ // eslint-disable-next-line unused-imports/no-unused-vars
268
validator(rule: FormItemRule, value: string) {
269
if (!areAllCustomerFieldsFilled.value) {
270
return new Error(`Please fill all customer fields`)
@@ -270,9 +274,13 @@ const rules: FormRules = {
274
return new Error(`There are duplicated fields`)
275
}
276
277
+ /** @deprecated */
278
+ /*
279
if (!value.length || !isCustomerCodePresent.value) {
280
return new Error(`At least one custom field with name CUSTOMER_CODE is required`)
281
}
282
+ */
283
+
284
return true
285
},
286
trigger: ["input", "blur"]
@@ -284,9 +292,12 @@ const isValid = computed(() => {
292
return false
293
}
294
295
+ /** @deprecated */
296
+ /*
297
if (!isCustomerCodePresent.value) {
298
return false
299
}
300
+ */
301
302
if (!areAllCustomerFieldsUniques.value) {
303
return false
frontend/src/components/graylog/Pipelines/PipeList.vue
+5
-1
@@ -3,6 +3,7 @@
3
<n-card>
4
<n-spin :show="loading">
5
<n-collapse
6
+ v-if="pipelines.length"
7
v-model:expanded-names="selectedPipeline"
8
accordion
9
:style="minHeight ? `min-height: ${minHeight}` : ''"
@@ -23,6 +24,9 @@
24
</div>
25
</n-collapse-item>
26
</n-collapse>
27
+ <template v-else>
28
+ <n-empty v-if="!loading" description="No pipelines found" class="justify-center h-32" />
29
+ </template>
30
</n-spin>
31
</n-card>
32
@@ -47,7 +51,7 @@ import Icon from "@/components/common/Icon.vue"
51
import PipeDetails from "@/components/graylog/Pipelines/PipeDetails.vue"
52
import PipeInfo from "@/components/graylog/Pipelines/PipeInfo.vue"
53
import PipeTitle from "@/components/graylog/Pipelines/PipeTitle.vue"
50
-import { NButton, NCard, NCollapse, NCollapseItem, NModal, NSpin, useMessage } from "naive-ui"
54
+import { NButton, NCard, NCollapse, NCollapseItem, NEmpty, NModal, NSpin, useMessage } from "naive-ui"
55
import { onBeforeMount, ref, toRefs, watch } from "vue"
56
57
const props = defineProps<{
frontend/src/components/indices/ClusterHealth.vue
+4
-1
@@ -29,6 +29,9 @@
29
</div>
30
</n-scrollbar>
31
</div>
32
+ <template v-else>
33
+ <n-empty v-if="!loading" description="No cluster found" class="justify-center h-48" />
34
+ </template>
35
</n-spin>
36
</n-card>
37
</template>
@@ -37,7 +40,7 @@
40
import type { ClusterHealth } from "@/types/indices.d"
41
import Api from "@/api"
42
import IndexIcon from "@/components/indices/IndexIcon.vue"
40
-import { NCard, NScrollbar, NSpin, useMessage } from "naive-ui"
43
+import { NCard, NEmpty, NScrollbar, NSpin, useMessage } from "naive-ui"
44
import { onBeforeMount, ref } from "vue"
45
46
const message = useMessage()
frontend/src/components/indices/Marquee.vue
+24
-12
@@ -1,8 +1,9 @@
1
<template>
2
<div class="indices-marquee">
3
- <n-card content-style="padding:0; " class="overflow-hidden">
4
- <n-spin :show="loading">
3
+ <n-card content-class="!p-0" class="overflow-hidden">
4
+ <n-spin :show="loading" content-class="h-12">
5
<Vue3Marquee
6
+ v-if="list?.length"
7
class="marquee-wrap"
8
:duration="(list?.length || 0) * 1"
9
:pause-on-hover="true"
@@ -12,7 +13,7 @@
13
gradient-length="10%"
14
>
15
<span
15
- v-for="item in list"
16
+ v-for="item of list"
17
:key="item.index"
18
class="item flex items-center gap-2"
19
:class="item.health"
@@ -23,6 +24,14 @@
24
{{ item.index }}
25
</span>
26
</Vue3Marquee>
27
+ <template v-else>
28
+ <n-empty
29
+ v-if="!loading"
30
+ class="h-full justify-center"
31
+ description="No indices found"
32
+ :show-icon="false"
33
+ />
34
+ </template>
35
</n-spin>
36
</n-card>
37
<div v-if="list?.length" class="info">
@@ -37,7 +46,7 @@ import type { IndexStats } from "@/types/indices.d"
46
import Api from "@/api"
47
import IndexIcon from "@/components/indices/IndexIcon.vue"
48
import { useThemeStore } from "@/stores/theme"
40
-import { NCard, NSpin, useMessage } from "naive-ui"
49
+import { NCard, NEmpty, NSpin, useMessage } from "naive-ui"
50
import { computed, onBeforeMount, ref, toRefs, watch } from "vue"
51
import { Vue3Marquee } from "vue3-marquee"
52
@@ -50,19 +59,15 @@ const emit = defineEmits<{
59
}>()
60
61
const { indices } = toRefs(props)
53
-
62
const list = ref(indices.value)
55
-
56
-watch(indices, val => {
57
- list.value = val
58
-})
59
-
63
const message = useMessage()
64
const style = computed(() => useThemeStore().style)
65
const gradientColor = computed(() => style.value["bg-color-rgb"].split(", "))
63
-const loading = computed(() => !list?.value || list.value === null)
66
+const loading = ref(false)
67
68
function getIndices() {
69
+ loading.value = true
70
+
71
Api.indices
72
.getIndices()
73
.then(res => {
@@ -84,8 +89,15 @@ function getIndices() {
89
message.error(err.response?.data?.message || "An error occurred. Please try again later.")
90
}
91
})
92
+ .finally(() => {
93
+ loading.value = false
94
+ })
95
}
96
97
+watch(indices, val => {
98
+ list.value = val
99
+})
100
+
101
onBeforeMount(() => {
102
if (indices.value === undefined) {
103
getIndices()
@@ -101,7 +113,7 @@ onBeforeMount(() => {
113
margin-top: 5px;
114
}
115
.marquee-wrap {
104
- height: 45px;
116
+ height: 100%;
117
transform: translate3d(0, 0, 0);
118
119
:deep() {
frontend/src/components/indices/NodeAllocation.vue
+7
-2
@@ -3,7 +3,9 @@
3
<template #header>
4
<div class="flex align-center justify-between">
5
<span>Nodes Allocation</span>
6
- <span class="text-secondary-color font-mono">{{ indicesAllocation.length }}</span>
6
+ <span v-if="indicesAllocation.length" class="text-secondary-color font-mono">
7
+ {{ indicesAllocation.length }}
8
+ </span>
9
</div>
10
</template>
11
<n-spin :show="loading">
@@ -59,6 +61,9 @@
61
</div>
62
</n-scrollbar>
63
</template>
64
+ <template v-else>
65
+ <n-empty v-if="!loading" description="No allocations found" class="justify-center h-48" />
66
+ </template>
67
</div>
68
</n-spin>
69
</n-card>
@@ -67,7 +72,7 @@
72
<script setup lang="ts">
73
import type { IndexAllocation } from "@/types/indices.d"
74
import Api from "@/api"
70
-import { NCard, NProgress, NScrollbar, NSpin, useMessage } from "naive-ui"
75
+import { NCard, NEmpty, NProgress, NScrollbar, NSpin, useMessage } from "naive-ui"
76
import { nanoid } from "nanoid"
77
import { onBeforeMount, ref } from "vue"
78
frontend/src/components/overview/AgentsCard.vue
+7
-15
@@ -1,27 +1,17 @@
1
<template>
2
<n-spin :show="loading">
3
- <CardStatsDouble
4
- title="Agents"
5
- first-label="Total"
6
- hovered
7
- class="cursor-pointer"
8
- :value="total"
9
- second-label="Online"
10
- :sub-value="onlineTotal"
11
- :second-status="onlineTotal ? 'success' : undefined"
12
- @click="gotoAgent()"
13
- >
3
+ <CardStatsMulti title="Agents" hovered class="cursor-pointer h-full" :values @click="gotoAgent()">
4
<template #icon>
5
<CardStatsIcon :icon-name="AgentsIcon" boxed :box-size="30"></CardStatsIcon>
6
</template>
17
- </CardStatsDouble>
7
+ </CardStatsMulti>
8
</n-spin>
9
</template>
10
11
<script setup lang="ts">
12
import Api from "@/api"
23
-import CardStatsDouble from "@/components/common/CardStatsDouble.vue"
13
import CardStatsIcon from "@/components/common/CardStatsIcon.vue"
14
+import CardStatsMulti, { type ItemProps } from "@/components/common/CardStatsMulti.vue"
15
import { useGoto } from "@/composables/useGoto"
16
import { type Agent, AgentStatus } from "@/types/agents.d"
17
import { NSpin, useMessage } from "naive-ui"
@@ -32,14 +22,16 @@ const { gotoAgent } = useGoto()
22
const message = useMessage()
23
const loading = ref(false)
24
const agents = ref<Agent[]>([])
35
-
25
const total = computed<number>(() => {
26
return agents.value.length || 0
27
})
39
-
28
const onlineTotal = computed(() => {
29
return agents.value.filter(({ wazuh_agent_status }) => wazuh_agent_status === AgentStatus.Active).length || 0
30
})
31
+const values = computed<ItemProps[]>(() => [
32
+ { value: total.value, label: "Total" },
33
+ { value: onlineTotal.value, label: "Online", status: onlineTotal.value ? "success" : undefined }
34
+])
35
36
function getData() {
37
loading.value = true
frontend/src/components/overview/CustomersCard.vue
+6
-12
@@ -1,33 +1,27 @@
1
<template>
2
<n-spin :show="loading">
3
- <CardStats
3
+ <CardStatsMulti
4
title="Customers"
5
- :value="total"
6
- :vertical="vertical"
5
hovered
6
class="cursor-pointer h-full"
7
+ :values="[{ value: total, label: 'Total' }]"
8
@click="gotoCustomer()"
9
>
10
<template #icon>
12
- <CardStatsIcon :icon-name="CustomersIcon" boxed :box-size="40"></CardStatsIcon>
11
+ <CardStatsIcon :icon-name="CustomersIcon" boxed :box-size="30"></CardStatsIcon>
12
</template>
14
- </CardStats>
13
+ </CardStatsMulti>
14
</n-spin>
15
</template>
16
17
<script setup lang="ts">
18
import type { Customer } from "@/types/customers.d"
19
import Api from "@/api"
21
-import CardStats from "@/components/common/CardStats.vue"
20
import CardStatsIcon from "@/components/common/CardStatsIcon.vue"
21
+import CardStatsMulti from "@/components/common/CardStatsMulti.vue"
22
import { useGoto } from "@/composables/useGoto"
23
import { NSpin, useMessage } from "naive-ui"
25
-import { computed, onBeforeMount, ref, toRefs } from "vue"
26
-
27
-const props = defineProps<{
28
- vertical?: boolean
29
-}>()
30
-const { vertical } = toRefs(props)
24
+import { computed, onBeforeMount, ref } from "vue"
25
26
const CustomersIcon = "carbon:user-multiple"
27
const { gotoCustomer } = useGoto()
frontend/src/components/overview/HealthcheckCard.vue
+7
-16
@@ -1,16 +1,6 @@
1
<template>
2
<n-spin :show="loading">
3
- <CardStatsDouble
4
- title="Healthcheck"
5
- first-label="Total"
6
- :value="total"
7
- hovered
8
- class="cursor-pointer"
9
- second-label="Critical"
10
- :sub-value="criticalTotal"
11
- :second-status="criticalTotal ? 'warning' : undefined"
12
- @click="gotoHealthcheck()"
13
- >
3
+ <CardStatsMulti title="Healthcheck" hovered class="cursor-pointer h-full" :values @click="gotoHealthcheck()">
4
<template #icon>
5
<CardStatsIcon
6
:icon-name="HealthcheckIcon"
@@ -19,14 +9,14 @@
9
:color="criticalTotal ? style['warning-color'] : undefined"
10
></CardStatsIcon>
11
</template>
22
- </CardStatsDouble>
12
+ </CardStatsMulti>
13
</n-spin>
14
</template>
15
16
<script setup lang="ts">
17
import Api from "@/api"
28
-import CardStatsDouble from "@/components/common/CardStatsDouble.vue"
18
import CardStatsIcon from "@/components/common/CardStatsIcon.vue"
19
+import CardStatsMulti, { type ItemProps } from "@/components/common/CardStatsMulti.vue"
20
import { useGoto } from "@/composables/useGoto"
21
import { useThemeStore } from "@/stores/theme"
22
import { type InfluxDBAlert, InfluxDBAlertLevel } from "@/types/healthchecks.d"
@@ -38,16 +28,17 @@ const { gotoHealthcheck } = useGoto()
28
const message = useMessage()
29
const loading = ref(false)
30
const healthcheck = ref<InfluxDBAlert[]>([])
41
-
31
const style = computed(() => useThemeStore().style)
43
-
32
const total = computed<number>(() => {
33
return healthcheck.value.length || 0
34
})
47
-
35
const criticalTotal = computed<number>(() => {
36
return healthcheck.value.filter(o => o.level === InfluxDBAlertLevel.Crit).length || 0
37
})
38
+const values = computed<ItemProps[]>(() => [
39
+ { value: total.value, label: "Total" },
40
+ { value: criticalTotal.value, label: "Critical", status: criticalTotal.value ? "warning" : undefined }
41
+])
42
43
function getData() {
44
loading.value = true
frontend/src/components/overview/IncidentAlerts.vue
new
+80
@@ -0,0 +1,80 @@
1
+<template>
2
+ <n-spin :show="loading">
3
+ <CardStatsBars
4
+ title="Alerts"
5
+ hovered
6
+ class="cursor-pointer h-full"
7
+ :values
8
+ @click="gotoIncidentManagementAlerts()"
9
+ >
10
+ <template #icon>
11
+ <CardStatsIcon :icon-name="AlertsIcon" boxed :box-size="30"></CardStatsIcon>
12
+ </template>
13
+ </CardStatsBars>
14
+ </n-spin>
15
+</template>
16
+
17
+<script setup lang="ts">
18
+import Api from "@/api"
19
+import CardStatsBars, { type ItemProps } from "@/components/common/CardStatsBars.vue"
20
+import CardStatsIcon from "@/components/common/CardStatsIcon.vue"
21
+import { useGoto } from "@/composables/useGoto"
22
+import { NSpin, useMessage } from "naive-ui"
23
+import { computed, onBeforeMount, ref } from "vue"
24
+
25
+const AlertsIcon = "carbon:warning-hex"
26
+const { gotoIncidentManagementAlerts } = useGoto()
27
+const message = useMessage()
28
+const loading = ref(false)
29
+const total = ref(0)
30
+const openedCount = ref(0)
31
+const inProgressCount = ref(0)
32
+const closedCount = ref(0)
33
+const values = computed<ItemProps[]>(() => [
34
+ { value: total.value, label: "Total", isTotal: true },
35
+ { value: openedCount.value, label: "Open", status: "error" },
36
+ { value: inProgressCount.value, label: "In Progress", status: "warning" },
37
+ { value: closedCount.value, label: "Closed", status: "success" }
38
+])
39
+
40
+function getData() {
41
+ loading.value = true
42
+
43
+ Api.incidentManagement
44
+ .getAlertsList({
45
+ page: 0,
46
+ pageSize: 0
47
+ })
48
+ .then(res => {
49
+ if (res.data.success) {
50
+ total.value = res.data.total || 0
51
+ closedCount.value = res.data.closed || 0
52
+ inProgressCount.value = res.data.in_progress || 0
53
+ openedCount.value = res.data.open || 0
54
+ } else {
55
+ message.warning(res.data?.message || "An error occurred. Please try again later.")
56
+ }
57
+ loading.value = false
58
+ })
59
+ .catch(err => {
60
+ message.error(err.response?.data?.message || "An error occurred. Please try again later.")
61
+ })
62
+ .finally(() => {
63
+ loading.value = false
64
+ })
65
+}
66
+
67
+onBeforeMount(() => {
68
+ getData()
69
+})
70
+</script>
71
+
72
+<style lang="scss" scoped>
73
+.n-spin-container {
74
+ :deep() {
75
+ .n-spin-content {
76
+ height: 100%;
77
+ }
78
+ }
79
+}
80
+</style>
frontend/src/components/overview/IncidentCases.vue
new
+90
@@ -0,0 +1,90 @@
1
+<template>
2
+ <n-spin :show="loading">
3
+ <CardStatsBars
4
+ title="Cases"
5
+ hovered
6
+ class="cursor-pointer h-full"
7
+ :values
8
+ @click="gotoIncidentManagementCases()"
9
+ >
10
+ <template #icon>
11
+ <CardStatsIcon :icon-name="CasesIcon" boxed :box-size="30"></CardStatsIcon>
12
+ </template>
13
+ </CardStatsBars>
14
+ </n-spin>
15
+</template>
16
+
17
+<script setup lang="ts">
18
+import type { Case } from "@/types/incidentManagement/cases"
19
+import Api from "@/api"
20
+import CardStatsBars, { type ItemProps } from "@/components/common/CardStatsBars.vue"
21
+import CardStatsIcon from "@/components/common/CardStatsIcon.vue"
22
+import { useGoto } from "@/composables/useGoto"
23
+import { NSpin, useMessage } from "naive-ui"
24
+import { computed, onBeforeMount, ref } from "vue"
25
+
26
+const CasesIcon = "carbon:ibm-secure-infrastructure-on-vpc-for-regulated-industries"
27
+const { gotoIncidentManagementCases } = useGoto()
28
+const message = useMessage()
29
+const loading = ref(false)
30
+const casesList = ref<Case[]>([])
31
+
32
+const total = computed<number>(() => {
33
+ return casesList.value.length || 0
34
+})
35
+const openedCount = computed<number>(() => {
36
+ return casesList.value.filter(o => o.case_status === "OPEN").length || 0
37
+})
38
+const inProgressCount = computed<number>(() => {
39
+ return casesList.value.filter(o => o.case_status === "IN_PROGRESS").length || 0
40
+})
41
+const closedCount = computed<number>(() => {
42
+ return casesList.value.filter(o => o.case_status === "CLOSED").length || 0
43
+})
44
+const undefinedCount = computed<number>(() => {
45
+ return casesList.value.filter(o => o.case_status === null).length || 0
46
+})
47
+
48
+const values = computed<ItemProps[]>(() => [
49
+ { value: total.value, label: "Total", isTotal: true },
50
+ { value: openedCount.value, label: "Open", status: "error" },
51
+ { value: inProgressCount.value, label: "In Progress", status: "warning" },
52
+ { value: closedCount.value, label: "Closed", status: "success" },
53
+ { value: undefinedCount.value, label: "N/D", status: "muted" }
54
+])
55
+
56
+function getData() {
57
+ loading.value = true
58
+
59
+ Api.incidentManagement
60
+ .getCasesList()
61
+ .then(res => {
62
+ if (res.data.success) {
63
+ casesList.value = res.data?.cases || []
64
+ } else {
65
+ message.warning(res.data?.message || "An error occurred. Please try again later.")
66
+ }
67
+ loading.value = false
68
+ })
69
+ .catch(err => {
70
+ message.error(err.response?.data?.message || "An error occurred. Please try again later.")
71
+ })
72
+ .finally(() => {
73
+ loading.value = false
74
+ })
75
+}
76
+
77
+onBeforeMount(() => {
78
+ getData()
79
+})
80
+</script>
81
+
82
+<style lang="scss" scoped>
83
+.n-spin-container {
84
+ :deep() {
85
+ .n-spin-content {
86
+ height: 100%;
87
+ }
88
+ }
89
+}
90
+</style>
frontend/src/composables/useGoto.ts
+5
@@ -61,6 +61,10 @@ export function useGoto() {
61
router.push({ name: "Soc-Users", query: userId ? { user_id: userId } : {} })
62
}
63
64
+ function gotoIncidentManagementAlerts(alertId?: number) {
65
+ router.push({ name: "IncidentManagement-Alerts", query: alertId ? { alert_id: alertId } : {} })
66
+ }
67
+
68
function gotoIncidentManagementCases(caseId?: number) {
69
router.push({ name: "IncidentManagement-Cases", query: caseId ? { case_id: caseId } : {} })
70
}
@@ -78,6 +82,7 @@ export function useGoto() {
82
gotoSocUsers,
83
gotoAlerts,
84
gotoConnectors,
85
+ gotoIncidentManagementAlerts,
86
gotoIncidentManagementCases
87
}
88
}
frontend/src/main.ts
-1
@@ -2,7 +2,6 @@ import App from "@/App.vue"
2
import { getI18NConf, type Locales, type MessageSchema } from "@/lang/config"
3
import router from "@/router"
4
import { createPinia } from "pinia"
5
-
5
import { createPersistedState } from "pinia-plugin-persistedstate"
6
import { createApp } from "vue"
7
import { createI18n } from "vue-i18n"
frontend/src/stores/theme.ts
+8
-233
@@ -1,62 +1,16 @@
1
+import type { ColorType, Layout, RouterTransition, ThemeName } from "@/types/theme.d"
2
import type { BuiltInGlobalTheme } from "naive-ui/es/themes/interface"
2
-import tokens from "@/design-tokens.json"
3
-import { type ColorType, Layout, RouterTransition, ThemeEnum, type ThemeName } from "@/types/theme.d"
4
-import { exportPrimaryShades, getThemeColors, getTypeValue, hex2rgb, type PrimaryShade } from "@/utils/theme"
3
+import { getCssVars, getDefaultState } from "@/theme"
4
+import { ThemeEnum } from "@/types/theme.d"
5
+import { exportPrimaryShades, getThemeColors, getTypeValue, type PrimaryShade } from "@/utils/theme"
6
import _get from "lodash/get"
7
import _pick from "lodash/pick"
8
import _set from "lodash/set"
8
-import { darkTheme, type GlobalThemeOverrides, lightTheme, type ThemeCommonVars, useOsTheme } from "naive-ui"
9
+import { darkTheme, type GlobalThemeOverrides, lightTheme, type ThemeCommonVars } from "naive-ui"
10
import { acceptHMRUpdate, defineStore } from "pinia"
11
11
-const osTheme = useOsTheme()
12
-
12
export const useThemeStore = defineStore("theme", {
14
- state: () => ({
15
- layout: Layout.HorizontalNav,
16
- themeName: osTheme.value || ThemeEnum.Dark,
17
- routerTransition: RouterTransition.FadeUp,
18
- routerTransitionDuration: 0.3,
19
- rtl: false,
20
- boxed: {
21
- enabled: false,
22
- toolbar: true,
23
- width: 1600
24
- },
25
- sidebar: {
26
- autoClose: true,
27
- collapsed: false,
28
- autoCloseBreakpoint: 1000,
29
- animEase: "ease-in-out",
30
- animDuration: 0.3,
31
- openWidth: 300,
32
- closeWidth: 64
33
- },
34
- footer: {
35
- show: true
36
- },
37
- responsive: {
38
- breakpoint: 700,
39
- override: {
40
- viewPadding: {
41
- desk: 40,
42
- mobile: 20
43
- },
44
- toolbarHeight: {
45
- desk: 80,
46
- mobile: 70
47
- }
48
- }
49
- },
50
- toolbarHeight: 80,
51
- viewPadding: 40,
52
- headerBarHeight: 60,
53
- colors: tokens.colors,
54
- borderRadius: tokens.borderRadius,
55
- lineHeight: tokens.lineHeight,
56
- fontSize: tokens.fontSize,
57
- fontFamily: tokens.fontFamily,
58
- typography: tokens.typography
59
- }),
13
+ state: () => getDefaultState(),
14
actions: {
15
setLayout(layout: Layout): void {
16
this.layout = layout
@@ -278,187 +232,7 @@ export const useThemeStore = defineStore("theme", {
232
return { ...this.naiveTheme.common, ...this.themeOverrides.common }
233
},
234
style(state): { [key: string]: string } {
281
- const naive = this.naiveCommon
282
-
283
- const bgColor = naive.baseColor
284
- const bgColorRGB = hex2rgb(bgColor).join(", ")
285
- const bgSecondaryColor = this.backgroundSecondaryColor
286
- const fgColor = naive.textColorBase
287
- const fgSecondaryColor = naive.textColor3
288
-
289
- const tabFgColorActive = naive.textColor2
290
- const borderColor = naive.dividerColor
291
- const primaryColor = naive.primaryColor
292
-
293
- const successColor = naive.successColor
294
- const errorColor = naive.errorColor
295
- const warningColor = naive.warningColor
296
- const infoColor = naive.infoColor
297
- const successColorRGB = hex2rgb(successColor).join(", ")
298
- const errorColorRGB = hex2rgb(errorColor).join(", ")
299
- const warningColorRGB = hex2rgb(warningColor).join(", ")
300
- const infoColorRGB = hex2rgb(infoColor).join(", ")
301
-
302
- const { success005, warning005, error005, info005 } = state.colors[state.themeName]
303
-
304
- const modalColor = naive.modalColor
305
- const modalColorRGB = hex2rgb(modalColor).join(", ")
306
- const codeColor = naive.codeColor
307
- const tabColor = naive.tabColor
308
- const tabColorActive = naive.inputColor
309
- const bezierEase = naive.cubicBezierEaseInOut
310
-
311
- const buttonColorSecondary = naive.buttonColor2
312
- const buttonColorSecondaryHover = naive.buttonColor2Hover
313
- const buttonColorSecondaryPressed = naive.buttonColor2Pressed
314
-
315
- const bgSidebar = this.sidebarBackground
316
- const bgSidebarRGB = hex2rgb(bgSidebar).join(", ")
317
- const bgBody = this.bodyBackground
318
- const bgBodyRGB = hex2rgb(bgBody).join(", ")
319
-
320
- const boxedWidth = state.boxed.width
321
- const routerTransitionDuration = state.routerTransitionDuration
322
- const sidebarAnimEase = state.sidebar.animEase
323
- const sidebarAnimDuration = state.sidebar.animDuration
324
- const sidebarOpenWidth = state.sidebar.openWidth
325
- const sidebarCloseWidth = state.sidebar.closeWidth
326
- const toolbarHeight = state.toolbarHeight
327
- const viewPadding = state.viewPadding
328
- const headerBarHeight = state.headerBarHeight
329
- const fontFamily = state.fontFamily.base
330
- const fontFamilyDisplay = state.fontFamily.display
331
- const fontFamilyMono = state.fontFamily.mono
332
-
333
- const borderRadius = state.borderRadius.base
334
- const borderRadiusSmall = state.borderRadius.small
335
-
336
- const { divider005, divider010, divider020, divider030 } = this.dividerColors
337
- const { hover005, hover010, hover050 } = this.hoverColors
338
- const { primary005, primary010, primary015, primary020, primary030, primary040, primary050, primary060 } =
339
- this.primaryColors
340
- const {
341
- secondary1Opacity005,
342
- secondary1Opacity010,
343
- secondary1Opacity020,
344
- secondary1Opacity030,
345
- secondary2Opacity005,
346
- secondary2Opacity010,
347
- secondary2Opacity020,
348
- secondary2Opacity030,
349
- secondary3Opacity005,
350
- secondary3Opacity010,
351
- secondary3Opacity020,
352
- secondary3Opacity030,
353
- secondary4Opacity005,
354
- secondary4Opacity010,
355
- secondary4Opacity020,
356
- secondary4Opacity030
357
- } = this.secondaryOpacityColors
358
-
359
- const { secondary1, secondary2, secondary3, secondary4 } = this.secondaryColors
360
- const secondary1RGB = hex2rgb(secondary1).join(", ")
361
- const secondary2RGB = hex2rgb(secondary2).join(", ")
362
- const secondary3RGB = hex2rgb(secondary3).join(", ")
363
- const secondary4RGB = hex2rgb(secondary4).join(", ")
364
-
365
- return {
366
- "bg-body": `${bgBody}`,
367
- "bg-body-rgb": `${bgBodyRGB}`,
368
- "bg-sidebar": `${bgSidebar}`,
369
- "bg-sidebar-rgb": `${bgSidebarRGB}`,
370
-
371
- "fg-color": `${fgColor}`,
372
- "fg-secondary-color": `${fgSecondaryColor}`,
373
- "bg-color": `${bgColor}`,
374
- "bg-color-rgb": `${bgColorRGB}`,
375
- "bg-secondary-color": `${bgSecondaryColor}`,
376
-
377
- "border-color": `${borderColor}`,
378
- "bezier-ease": `${bezierEase}`,
379
- "router-transition-duration": `${routerTransitionDuration}s`,
380
- "sidebar-anim-ease": `${sidebarAnimEase}`,
381
- "sidebar-anim-duration": `${sidebarAnimDuration}s`,
382
- "sidebar-open-width": `${sidebarOpenWidth}px`,
383
- "sidebar-close-width": `${sidebarCloseWidth}px`,
384
- "boxed-width": `${boxedWidth}px`,
385
- "toolbar-height": `${toolbarHeight}px`,
386
- "header-bar-height": `${headerBarHeight}px`,
387
- "view-padding": `${viewPadding}px`,
388
- "border-radius": `${borderRadius}`,
389
- "border-radius-small": `${borderRadiusSmall}`,
390
- "font-family": `${fontFamily}`,
391
- "font-family-display": `${fontFamilyDisplay}`,
392
- "font-family-mono": `${fontFamilyMono}`,
393
- "code-color": `${codeColor}`,
394
- "primary-color": `${primaryColor}`,
395
- "tab-color": `${tabColor}`,
396
- "tab-color-active": `${tabColorActive}`,
397
- "tab-fg-color-active": `${tabFgColorActive}`,
398
- "modal-color": `${modalColor}`,
399
- "modal-color-rgb": `${modalColorRGB}`,
400
-
401
- "button-color-secondary": `${buttonColorSecondary}`,
402
- "button-color-secondary-hover": `${buttonColorSecondaryHover}`,
403
- "button-color-secondary-pressed": `${buttonColorSecondaryPressed}`,
404
-
405
- "primary-005-color": `${primary005}`,
406
- "primary-010-color": `${primary010}`,
407
- "primary-015-color": `${primary015}`,
408
- "primary-020-color": `${primary020}`,
409
- "primary-030-color": `${primary030}`,
410
- "primary-040-color": `${primary040}`,
411
- "primary-050-color": `${primary050}`,
412
- "primary-060-color": `${primary060}`,
413
-
414
- "hover-005-color": `${hover005}`,
415
- "hover-010-color": `${hover010}`,
416
- "hover-050-color": `${hover050}`,
417
-
418
- "divider-005-color": `${divider005}`,
419
- "divider-010-color": `${divider010}`,
420
- "divider-020-color": `${divider020}`,
421
- "divider-030-color": `${divider030}`,
422
-
423
- "success-color": `${successColor}`,
424
- "error-color": `${errorColor}`,
425
- "warning-color": `${warningColor}`,
426
- "info-color": `${infoColor}`,
427
- "success-005-color": `${success005}`,
428
- "error-005-color": `${error005}`,
429
- "warning-005-color": `${warning005}`,
430
- "info-005-color": `${info005}`,
431
- "success-color-rgb": `${successColorRGB}`,
432
- "error-color-rgb": `${errorColorRGB}`,
433
- "warning-color-rgb": `${warningColorRGB}`,
434
- "info-color-rgb": `${infoColorRGB}`,
435
-
436
- "secondary1-color": `${secondary1}`,
437
- "secondary1-color-rgb": `${secondary1RGB}`,
438
- "secondary2-color": `${secondary2}`,
439
- "secondary2-color-rgb": `${secondary2RGB}`,
440
- "secondary3-color": `${secondary3}`,
441
- "secondary3-color-rgb": `${secondary3RGB}`,
442
- "secondary4-color": `${secondary4}`,
443
- "secondary4-color-rgb": `${secondary4RGB}`,
444
-
445
- "secondary1-opacity-005-color": `${secondary1Opacity005}`,
446
- "secondary1-opacity-010-color": `${secondary1Opacity010}`,
447
- "secondary1-opacity-020-color": `${secondary1Opacity020}`,
448
- "secondary1-opacity-030-color": `${secondary1Opacity030}`,
449
- "secondary2-opacity-005-color": `${secondary2Opacity005}`,
450
- "secondary2-opacity-010-color": `${secondary2Opacity010}`,
451
- "secondary2-opacity-020-color": `${secondary2Opacity020}`,
452
- "secondary2-opacity-030-color": `${secondary2Opacity030}`,
453
- "secondary3-opacity-005-color": `${secondary3Opacity005}`,
454
- "secondary3-opacity-010-color": `${secondary3Opacity010}`,
455
- "secondary3-opacity-020-color": `${secondary3Opacity020}`,
456
- "secondary3-opacity-030-color": `${secondary3Opacity030}`,
457
- "secondary4-opacity-005-color": `${secondary4Opacity005}`,
458
- "secondary4-opacity-010-color": `${secondary4Opacity010}`,
459
- "secondary4-opacity-020-color": `${secondary4Opacity020}`,
460
- "secondary4-opacity-030-color": `${secondary4Opacity030}`
461
- }
235
+ return getCssVars(state, this)
236
},
237
isThemeDark(state): boolean {
238
return state.themeName === ThemeEnum.Dark
@@ -480,6 +254,7 @@ export const useThemeStore = defineStore("theme", {
254
}
255
},
256
persist: {
257
+ // use this param to save specific state chunk on localStorage
258
pick: ["layout", "themeName", "routerTransition", "boxed", "sidebar.collapsed"]
259
}
260
})
frontend/src/theme/index.ts
new
+255
@@ -0,0 +1,255 @@
1
+import tokens from "@/design-tokens.json"
2
+import { Layout, RouterTransition, ThemeEnum } from "@/types/theme.d"
3
+import { hex2rgb } from "@/utils/theme"
4
+import { type ThemeCommonVars, useOsTheme } from "naive-ui"
5
+
6
+type ThemeState = ReturnType<typeof getDefaultState>
7
+
8
+interface ThemeGetters {
9
+ dividerColors: { [key: string]: string }
10
+ hoverColors: { [key: string]: string }
11
+ primaryColors: { [key: string]: string }
12
+ secondaryOpacityColors: { [key: string]: string }
13
+ secondaryColors: { [key: string]: string }
14
+ sidebarBackground: string
15
+ bodyBackground: string
16
+ backgroundSecondaryColor: string
17
+ naiveCommon: ThemeCommonVars
18
+}
19
+
20
+const osTheme = useOsTheme()
21
+
22
+export function getDefaultState() {
23
+ return {
24
+ layout: Layout.HorizontalNav, // Type of layout, with vertical or horizontal navigation
25
+ themeName: osTheme.value || ThemeEnum.Light, // Theme name (Dark, Light), with fallback to the light theme
26
+ routerTransition: RouterTransition.FadeUp, // Type of transition for the router
27
+ routerTransitionDuration: 0.3, // Duration of the router transition in seconds
28
+ rtl: false, // RTL (right to left) mode toggle
29
+ boxed: {
30
+ enabled: true, // Choose whether to apply a maximum width to the page
31
+ toolbar: true, // Choose whether to apply the maximum width to the toolbar as well
32
+ width: 1600 // Maximum width size in pixels
33
+ },
34
+ sidebar: {
35
+ autoClose: true, // Choose whether to automatically close the sidebar when the view goes below the "autoCloseBreakpoint" value
36
+ collapsed: false, // Indicates if the sidebar is collapsed
37
+ autoCloseBreakpoint: 1000, // Breakpoint for the automatic closing of the sidebar (in pixels)
38
+ animEase: "ease-in-out", // Type of easing for animations
39
+ animDuration: 0.3, // Duration of sidebar animations (in seconds)
40
+ openWidth: 300, // Width of the open sidebar (in pixels)
41
+ closeWidth: 64 // Width of the closed sidebar (in pixels)
42
+ },
43
+ footer: {
44
+ show: true // Show or hide the footer
45
+ },
46
+ responsive: {
47
+ breakpoint: 700, // Breakpoint in pixels (Desk -> Mobile)
48
+ // Parameters to be adjusted based on the breakpoint
49
+ override: {
50
+ viewPadding: {
51
+ desk: 40, // View padding for desktop
52
+ mobile: 20 // View padding for mobile devices
53
+ },
54
+ toolbarHeight: {
55
+ desk: 80, // Height of the toolbar for desktop
56
+ mobile: 70 // Height of the toolbar for mobile devices
57
+ }
58
+ }
59
+ },
60
+ toolbarHeight: 80, // Default toolbar height (in pixels)
61
+ viewPadding: 40, // Default view padding (in pixels)
62
+ headerBarHeight: 60, // Height of the header bar (in pixels)
63
+ colors: tokens.colors, // Color definitions from the token
64
+ borderRadius: tokens.borderRadius, // Border radius from the token
65
+ lineHeight: tokens.lineHeight, // Line height from the token
66
+ fontSize: tokens.fontSize, // Font size from the token
67
+ fontFamily: tokens.fontFamily, // Font family from the token
68
+ typography: tokens.typography // Typography configurations from the token
69
+ }
70
+}
71
+
72
+export function getCssVars(state: ThemeState, getters: ThemeGetters): { [key: string]: string } {
73
+ const naive = getters.naiveCommon
74
+
75
+ const bgColor = naive.baseColor
76
+ const bgColorRGB = hex2rgb(bgColor).join(", ")
77
+ const bgSecondaryColor = getters.backgroundSecondaryColor
78
+ const fgColor = naive.textColorBase
79
+ const fgSecondaryColor = naive.textColor3
80
+
81
+ const tabFgColorActive = naive.textColor2
82
+ const borderColor = naive.dividerColor
83
+ const primaryColor = naive.primaryColor
84
+
85
+ const successColor = naive.successColor
86
+ const errorColor = naive.errorColor
87
+ const warningColor = naive.warningColor
88
+ const infoColor = naive.infoColor
89
+ const successColorRGB = hex2rgb(successColor).join(", ")
90
+ const errorColorRGB = hex2rgb(errorColor).join(", ")
91
+ const warningColorRGB = hex2rgb(warningColor).join(", ")
92
+ const infoColorRGB = hex2rgb(infoColor).join(", ")
93
+
94
+ const { success005, warning005, error005, info005 } = state.colors[state.themeName]
95
+
96
+ const modalColor = naive.modalColor
97
+ const modalColorRGB = hex2rgb(modalColor).join(", ")
98
+ const codeColor = naive.codeColor
99
+ const tabColor = naive.tabColor
100
+ const tabColorActive = naive.inputColor
101
+ const bezierEase = naive.cubicBezierEaseInOut
102
+
103
+ const buttonColorSecondary = naive.buttonColor2
104
+ const buttonColorSecondaryHover = naive.buttonColor2Hover
105
+ const buttonColorSecondaryPressed = naive.buttonColor2Pressed
106
+
107
+ const bgSidebar = getters.sidebarBackground
108
+ const bgSidebarRGB = hex2rgb(bgSidebar).join(", ")
109
+ const bgBody = getters.bodyBackground
110
+ const bgBodyRGB = hex2rgb(bgBody).join(", ")
111
+
112
+ const boxedWidth = state.boxed.width
113
+ const routerTransitionDuration = state.routerTransitionDuration
114
+ const sidebarAnimEase = state.sidebar.animEase
115
+ const sidebarAnimDuration = state.sidebar.animDuration
116
+ const sidebarOpenWidth = state.sidebar.openWidth
117
+ const sidebarCloseWidth = state.sidebar.closeWidth
118
+ const toolbarHeight = state.toolbarHeight
119
+ const viewPadding = state.viewPadding
120
+ const headerBarHeight = state.headerBarHeight
121
+ const fontFamily = state.fontFamily.base
122
+ const fontFamilyDisplay = state.fontFamily.display
123
+ const fontFamilyMono = state.fontFamily.mono
124
+
125
+ const borderRadius = state.borderRadius.base
126
+ const borderRadiusSmall = state.borderRadius.small
127
+
128
+ const { divider005, divider010, divider020, divider030 } = getters.dividerColors
129
+ const { hover005, hover010, hover050 } = getters.hoverColors
130
+ const { primary005, primary010, primary015, primary020, primary030, primary040, primary050, primary060 } =
131
+ getters.primaryColors
132
+ const {
133
+ secondary1Opacity005,
134
+ secondary1Opacity010,
135
+ secondary1Opacity020,
136
+ secondary1Opacity030,
137
+ secondary2Opacity005,
138
+ secondary2Opacity010,
139
+ secondary2Opacity020,
140
+ secondary2Opacity030,
141
+ secondary3Opacity005,
142
+ secondary3Opacity010,
143
+ secondary3Opacity020,
144
+ secondary3Opacity030,
145
+ secondary4Opacity005,
146
+ secondary4Opacity010,
147
+ secondary4Opacity020,
148
+ secondary4Opacity030
149
+ } = getters.secondaryOpacityColors
150
+
151
+ const { secondary1, secondary2, secondary3, secondary4 } = getters.secondaryColors
152
+ const secondary1RGB = hex2rgb(secondary1).join(", ")
153
+ const secondary2RGB = hex2rgb(secondary2).join(", ")
154
+ const secondary3RGB = hex2rgb(secondary3).join(", ")
155
+ const secondary4RGB = hex2rgb(secondary4).join(", ")
156
+
157
+ // This style object, imported via the themeStore, will be available application-wide and is exposed in the HTML tag as a list of CSS variables, which you can use in your CSS/SCSS code like: var(-–bg-color)
158
+ return {
159
+ "bg-body": `${bgBody}`,
160
+ "bg-body-rgb": `${bgBodyRGB}`,
161
+ "bg-sidebar": `${bgSidebar}`,
162
+ "bg-sidebar-rgb": `${bgSidebarRGB}`,
163
+
164
+ "fg-color": `${fgColor}`,
165
+ "fg-secondary-color": `${fgSecondaryColor}`,
166
+ "bg-color": `${bgColor}`,
167
+ "bg-color-rgb": `${bgColorRGB}`,
168
+ "bg-secondary-color": `${bgSecondaryColor}`,
169
+
170
+ "border-color": `${borderColor}`,
171
+ "bezier-ease": `${bezierEase}`,
172
+ "router-transition-duration": `${routerTransitionDuration}s`,
173
+ "sidebar-anim-ease": `${sidebarAnimEase}`,
174
+ "sidebar-anim-duration": `${sidebarAnimDuration}s`,
175
+ "sidebar-open-width": `${sidebarOpenWidth}px`,
176
+ "sidebar-close-width": `${sidebarCloseWidth}px`,
177
+ "boxed-width": `${boxedWidth}px`,
178
+ "toolbar-height": `${toolbarHeight}px`,
179
+ "header-bar-height": `${headerBarHeight}px`,
180
+ "view-padding": `${viewPadding}px`,
181
+ "border-radius": `${borderRadius}`,
182
+ "border-radius-small": `${borderRadiusSmall}`,
183
+ "font-family": `${fontFamily}`,
184
+ "font-family-display": `${fontFamilyDisplay}`,
185
+ "font-family-mono": `${fontFamilyMono}`,
186
+ "code-color": `${codeColor}`,
187
+ "primary-color": `${primaryColor}`,
188
+ "tab-color": `${tabColor}`,
189
+ "tab-color-active": `${tabColorActive}`,
190
+ "tab-fg-color-active": `${tabFgColorActive}`,
191
+ "modal-color": `${modalColor}`,
192
+ "modal-color-rgb": `${modalColorRGB}`,
193
+
194
+ "button-color-secondary": `${buttonColorSecondary}`,
195
+ "button-color-secondary-hover": `${buttonColorSecondaryHover}`,
196
+ "button-color-secondary-pressed": `${buttonColorSecondaryPressed}`,
197
+
198
+ "primary-005-color": `${primary005}`,
199
+ "primary-010-color": `${primary010}`,
200
+ "primary-015-color": `${primary015}`,
201
+ "primary-020-color": `${primary020}`,
202
+ "primary-030-color": `${primary030}`,
203
+ "primary-040-color": `${primary040}`,
204
+ "primary-050-color": `${primary050}`,
205
+ "primary-060-color": `${primary060}`,
206
+
207
+ "hover-005-color": `${hover005}`,
208
+ "hover-010-color": `${hover010}`,
209
+ "hover-050-color": `${hover050}`,
210
+
211
+ "divider-005-color": `${divider005}`,
212
+ "divider-010-color": `${divider010}`,
213
+ "divider-020-color": `${divider020}`,
214
+ "divider-030-color": `${divider030}`,
215
+
216
+ "success-color": `${successColor}`,
217
+ "error-color": `${errorColor}`,
218
+ "warning-color": `${warningColor}`,
219
+ "info-color": `${infoColor}`,
220
+ "success-005-color": `${success005}`,
221
+ "error-005-color": `${error005}`,
222
+ "warning-005-color": `${warning005}`,
223
+ "info-005-color": `${info005}`,
224
+ "success-color-rgb": `${successColorRGB}`,
225
+ "error-color-rgb": `${errorColorRGB}`,
226
+ "warning-color-rgb": `${warningColorRGB}`,
227
+ "info-color-rgb": `${infoColorRGB}`,
228
+
229
+ "secondary1-color": `${secondary1}`,
230
+ "secondary1-color-rgb": `${secondary1RGB}`,
231
+ "secondary2-color": `${secondary2}`,
232
+ "secondary2-color-rgb": `${secondary2RGB}`,
233
+ "secondary3-color": `${secondary3}`,
234
+ "secondary3-color-rgb": `${secondary3RGB}`,
235
+ "secondary4-color": `${secondary4}`,
236
+ "secondary4-color-rgb": `${secondary4RGB}`,
237
+
238
+ "secondary1-opacity-005-color": `${secondary1Opacity005}`,
239
+ "secondary1-opacity-010-color": `${secondary1Opacity010}`,
240
+ "secondary1-opacity-020-color": `${secondary1Opacity020}`,
241
+ "secondary1-opacity-030-color": `${secondary1Opacity030}`,
242
+ "secondary2-opacity-005-color": `${secondary2Opacity005}`,
243
+ "secondary2-opacity-010-color": `${secondary2Opacity010}`,
244
+ "secondary2-opacity-020-color": `${secondary2Opacity020}`,
245
+ "secondary2-opacity-030-color": `${secondary2Opacity030}`,
246
+ "secondary3-opacity-005-color": `${secondary3Opacity005}`,
247
+ "secondary3-opacity-010-color": `${secondary3Opacity010}`,
248
+ "secondary3-opacity-020-color": `${secondary3Opacity020}`,
249
+ "secondary3-opacity-030-color": `${secondary3Opacity030}`,
250
+ "secondary4-opacity-005-color": `${secondary4Opacity005}`,
251
+ "secondary4-opacity-010-color": `${secondary4Opacity010}`,
252
+ "secondary4-opacity-020-color": `${secondary4Opacity020}`,
253
+ "secondary4-opacity-030-color": `${secondary4Opacity030}`
254
+ }
255
+}
frontend/src/views/AlertsGraylog.vue
+1
-1
@@ -4,7 +4,7 @@
4
</div>
5
</template>
6
7
-<script setup>
7
+<script setup lang="ts">
8
import AlertsGraylogList from "@/components/alerts/AlertsGraylogList.vue"
9
</script>
10
frontend/src/views/AlertsOld.vue
+1
-1
@@ -4,7 +4,7 @@
4
</div>
5
</template>
6
7
-<script setup>
7
+<script setup lang="ts">
8
import AlertsList from "@/components/alerts/AlertsList.vue"
9
</script>
10
frontend/src/views/Overview.vue
+19
-43
@@ -20,22 +20,21 @@
20
</div>
21
</div>
22
<div class="section">
23
- <div class="columns column-800 overflow-hidden">
24
- <div class="basis-2/5">
25
- <AgentsCard />
23
+ <div class="grid grid-flow-row-dense grid-cols-12 gap-6">
24
+ <div class="col-span-12 xs:col-span-12 sm:col-span-4 lg:col-span-2">
25
+ <AgentsCard class="h-full" />
26
</div>
27
- <div class="basis-2/5">
28
- <HealthcheckCard />
27
+ <div class="col-span-12 xs:col-span-6 sm:col-span-4 lg:col-span-2">
28
+ <HealthcheckCard class="h-full" />
29
</div>
30
- <div class="basis-1/5 flex gap-6">
31
- <!--
32
- <div class="grow overflow-hidden">
33
- <SocAlertsCard class="h-full" :vertical="cardDirection === 'vertical'" />
34
- </div>
35
- -->
36
- <div class="grow overflow-hidden">
37
- <CustomersCard class="h-full" :vertical="cardDirection === 'vertical'" />
38
- </div>
30
+ <div class="col-span-12 xs:col-span-6 sm:col-span-4 lg:col-span-2">
31
+ <CustomersCard class="h-full" />
32
+ </div>
33
+ <div class="col-span-12 lg:col-span-3">
34
+ <IncidentAlerts class="h-full" />
35
+ </div>
36
+ <div class="col-span-12 lg:col-span-3">
37
+ <IncidentCases class="h-full" />
38
</div>
39
</div>
40
</div>
@@ -43,7 +42,7 @@
42
<IndicesMarquee @click="gotoIndex($event.index)" />
43
</div>
44
<div class="section">
46
- <div class="columns">
45
+ <div class="columns flex-col lg:flex-row">
46
<div class="col basis-1/2">
47
<ClusterHealth class="stretchy" />
48
</div>
@@ -85,15 +84,16 @@ import ClusterHealth from "@/components/indices/ClusterHealth.vue"
84
import IndicesMarquee from "@/components/indices/Marquee.vue"
85
import NodeAllocation from "@/components/indices/NodeAllocation.vue"
86
import AgentsCard from "@/components/overview/AgentsCard.vue"
87
+import CustomersCard from "@/components/overview/CustomersCard.vue"
88
import HealthcheckCard from "@/components/overview/HealthcheckCard.vue"
89
+import IncidentAlerts from "@/components/overview/IncidentAlerts.vue"
90
+import IncidentCases from "@/components/overview/IncidentCases.vue"
91
import StackProvisioningButton from "@/components/stackProvisioning/StackProvisioningButton.vue"
92
import WebVulnerabilityAssessmentButton from "@/components/webVulnerabilityAssessment/WebVulnerabilityAssessmentButton.vue"
91
-import { NButton, NDrawer, NDrawerContent } from "naive-ui"
92
-import { defineAsyncComponent, ref } from "vue"
93
-// import SocAlertsCard from "@/components/overview/SocAlertsCard.vue"
94
-import CustomersCard from "@/components/overview/CustomersCard.vue"
93
import { useGoto } from "@/composables/useGoto"
94
import { useResizeObserver } from "@vueuse/core"
95
+import { NButton, NDrawer, NDrawerContent } from "naive-ui"
96
+import { defineAsyncComponent, ref } from "vue"
97
98
const ThreatIntelButton = defineAsyncComponent(() => import("@/components/threatIntel/ThreatIntelButton.vue"))
99
@@ -125,29 +125,5 @@ useResizeObserver(page, entries => {
125
}
126
}
127
}
128
-
129
- @media (max-width: 1000px) {
130
- .section {
131
- .columns {
132
- &:not(.column-1200, .column-800) {
133
- flex-direction: column;
134
- }
135
- }
136
- }
137
- }
138
- @media (max-width: 800px) {
139
- .section {
140
- .columns.column-800 {
141
- flex-direction: column;
142
- }
143
- }
144
- }
145
- @media (max-width: 1200px) {
146
- .section {
147
- .columns.column-1200 {
148
- flex-direction: column;
149
- }
150
- }
151
- }
128
}
129
</style>
frontend/src/views/ReportCreation.vue
+1
-1
@@ -39,7 +39,7 @@ const panels = ref<Panel[]>([])
39
</script>
40
41
<style lang="scss" scoped>
42
-@import "../layouts/HorizontalNav/_variables.scss";
42
+@import "../app-layouts/HorizontalNav/_variables.scss";
43
44
.page {
45
overflow: hidden;
frontend/tailwind.config.js
+3
-1
@@ -58,7 +58,9 @@ export default {
58
"w-72",
59
"max-h-50vh",
60
"max-w-90vw",
61
- "!h-0.75"
61
+ "!h-0.75",
62
+ "basis-1/4",
63
+ "basis-1/5"
64
],
65
plugins: [
66
plugin(({ addBase, theme }) => {