@cryptotaxi247 / CoPilot / commits / 550c1956

Template upgrade (#434)

* setup * refactor: migration * lint * chore: update frontend dependencies * Refactors: Uses CSS variables for styling Migrates styling from Tailwind CSS classes to CSS variables for improved consistency and theming control. Replaces hardcoded values with CSS variables to enable easier adjustments and maintainability across the application. This primarily affects spacing, font sizes, and other visual properties in various components. * fix: naive-ui steps * fix: change password form --------- Co-authored-by: Davide Di Modica <webmaster.ddm@gmail.com>

taylor_socfortress committed Apr 3, 2025 at 13:55 UTC 550c195682c961f2a58a096c7290f0ec92aaaffb
96 files changed +1400 -1381
.prettierrc.json
+9
@@ -8,5 +8,14 @@
8 "htmlWhitespaceSensitivity": "ignore",
9 "plugins": [
10 "prettier-plugin-tailwindcss"
11 + ],
12 + "tailwindAttributes": [
13 + "class",
14 + "container-class",
15 + "header-class",
16 + "pane-wrapper-class",
17 + "trigger-class",
18 + "tab-class",
19 + "content-class"
20 ]
21 }
.vscode/settings.json
+24 -3
@@ -75,8 +75,29 @@
75 "xaxis",
76 "zondicons"
77 ],
78 - "i18n-ally.localesPaths": [
79 - "frontend/src/lang"
78 + "i18n-ally.localesPaths": ["frontend/src/lang/locales"],
79 + "i18n-ally.enabledParsers": ["json"],
80 + "i18n-ally.keystyle": "nested",
81 + "i18n-ally.regex.usageMatchAppend": ["[^\\w\\d]t<I18nString>\\(['\"`]({key})['\"`]"],
82 + "i18n-ally.refactor.templates": [
83 + {
84 + "template": "t<I18nString>(\"{key}\")"
85 + }
86 ],
81 - "tailwindCSS.classAttributes": ["class", "className", "ngClass", "class:list", "content-class"]
87 + "i18n-ally.review.enabled": false,
88 + "i18n-ally.review.gutters": false,
89 + "i18n-ally.tabStyle": "tab",
90 + "i18n-ally.indent": 4,
91 + "i18n-ally.translate.deepl.useFreeApiEntry": true,
92 + "i18n-ally.readonly": false,
93 + "tailwindCSS.experimental.configFile": "frontend/src/tailwind.css",
94 + "tailwindCSS.classAttributes": [
95 + "class",
96 + "container-class",
97 + "header-class",
98 + "pane-wrapper-class",
99 + "trigger-class",
100 + "tab-class",
101 + "content-class"
102 + ]
103 }
frontend/.gitignore new
+22
@@ -0,0 +1,22 @@
1 +!frontend/src/components/logs
2 +npm-debug.log*
3 +yarn-debug.log*
4 +yarn-error.log*
5 +pnpm-debug.log*
6 +lerna-debug.log*
7 +
8 +node_modules
9 +.DS_Store
10 +dist
11 +coverage
12 +*.local
13 +
14 +cypress/videos/
15 +cypress/screenshots/
16 +
17 +src/unplugin.components.d.ts
18 +cypress/screenshots/
19 +cypress/downloads/
20 +tsconfig.app.tsbuildinfo
21 +tsconfig.node.tsbuildinfo
22 +tsconfig.vitest.tsbuildinfo
frontend/package.json
+8 -10
@@ -3,7 +3,7 @@
3 "type": "module",
4 "version": "1.0.0",
5 "private": true,
6 - "packageManager": "pnpm@10.7.0+sha512.6b865ad4b62a1d9842b61d674a393903b871d9244954f652b8842c2b553c72176b278f64c463e52d40fff8aba385c235c8c9ecf5cc7de4fd78b8bb6d49633ab6",
6 + "packageManager": "pnpm@10.7.1+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808",
7 "engines": {
8 "node": ">=18.0.0"
9 },
@@ -45,7 +45,6 @@
45 "@fontsource/lexend": "^5.2.6",
46 "@fontsource/public-sans": "^5.2.5",
47 "@shikijs/markdown-it": "^3.2.1",
48 - "@tailwindcss/container-queries": "^0.1.1",
48 "@vueuse/core": "^13.0.0",
49 "axios": "^1.8.4",
50 "bytes": "^3.1.2",
@@ -81,7 +80,7 @@
80 "vuedraggable": "^4.1.0"
81 },
82 "optionalDependencies": {
84 - "@rollup/rollup-linux-x64-gnu": "^4.34.8",
83 + "@rollup/rollup-linux-x64-gnu": "^4.39.0",
84 "treemate": "^0.3.11",
85 "vueuc": "^0.4.64"
86 },
@@ -89,19 +88,19 @@
88 "@antfu/eslint-config": "^4.11.0",
89 "@clack/prompts": "^0.10.0",
90 "@iconify/vue": "^4.3.0",
91 + "@tailwindcss/vite": "^4.1.1",
92 "@tsconfig/node20": "^20.1.5",
93 "@types/bytes": "^3.1.5",
94 "@types/file-saver": "^2.0.7",
95 "@types/fs-extra": "^11.0.4",
96 "@types/jsdom": "^21.1.7",
97 "@types/lodash": "^4.17.16",
98 - "@types/node": "^22.13.14",
98 + "@types/node": "^22.14.0",
99 "@types/validator": "^13.12.3",
100 "@vitejs/plugin-vue": "^5.2.3",
101 "@vitejs/plugin-vue-jsx": "^4.1.2",
102 "@vue/test-utils": "^2.4.6",
103 "@vue/tsconfig": "^0.7.0",
104 - "autoprefixer": "^10.4.21",
104 "cypress": "^14.2.1",
105 "depcheck": "^1.4.7",
106 "eslint": "^9.23.0",
@@ -109,16 +108,15 @@
108 "fs-extra": "^11.3.0",
109 "jsdom": "^26.0.0",
110 "npm-run-all2": "^7.0.2",
112 - "postcss": "^8.5.3",
111 "prettier": "^3.5.3",
112 "prettier-plugin-tailwindcss": "^0.6.11",
115 - "sass": "^1.86.0",
113 + "sass": "^1.86.2",
114 "start-server-and-test": "^2.0.11",
117 - "tailwindcss": "^3.4.17",
115 + "tailwindcss": "^4.1.1",
116 "taze": "^19.0.4",
119 - "type-fest": "^4.38.0",
117 + "type-fest": "^4.39.1",
118 "typescript": "~5.8.2",
121 - "vite": "^6.2.4",
119 + "vite": "^6.2.5",
120 "vite-bundle-visualizer": "^1.2.1",
121 "vite-plugin-vue-devtools": "^7.7.2",
122 "vite-svg-loader": "^5.1.0",
frontend/pnpm-lock.yaml
+335 -360
@@ -38,9 +38,6 @@ importers:
38 '@shikijs/markdown-it':
39 specifier: ^3.2.1
40 version: 3.2.1
41 - '@tailwindcss/container-queries':
42 - specifier: ^0.1.1
43 - version: 0.1.1(tailwindcss@3.4.17)
41 '@vueuse/core':
42 specifier: ^13.0.0
43 version: 13.0.0(vue@3.5.13(typescript@5.8.2))
@@ -143,13 +140,16 @@ importers:
140 devDependencies:
141 '@antfu/eslint-config':
142 specifier: ^4.11.0
146 - version: 4.11.0(@typescript-eslint/utils@8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(@vue/compiler-sfc@3.5.13)(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.86.0)(yaml@2.7.0))
143 + version: 4.11.0(@typescript-eslint/utils@8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(@vue/compiler-sfc@3.5.13)(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.14.0)(jiti@2.4.2)(jsdom@26.0.0)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))
144 '@clack/prompts':
145 specifier: ^0.10.0
146 version: 0.10.0
147 '@iconify/vue':
148 specifier: ^4.3.0
149 version: 4.3.0(vue@3.5.13(typescript@5.8.2))
150 + '@tailwindcss/vite':
151 + specifier: ^4.1.1
152 + version: 4.1.1(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))
153 '@tsconfig/node20':
154 specifier: ^20.1.5
155 version: 20.1.5
@@ -169,26 +169,23 @@ importers:
169 specifier: ^4.17.16
170 version: 4.17.16
171 '@types/node':
172 - specifier: ^22.13.14
173 - version: 22.13.14
172 + specifier: ^22.14.0
173 + version: 22.14.0
174 '@types/validator':
175 specifier: ^13.12.3
176 version: 13.12.3
177 '@vitejs/plugin-vue':
178 specifier: ^5.2.3
179 - version: 5.2.3(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
179 + version: 5.2.3(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
180 '@vitejs/plugin-vue-jsx':
181 specifier: ^4.1.2
182 - version: 4.1.2(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
182 + version: 4.1.2(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
183 '@vue/test-utils':
184 specifier: ^2.4.6
185 version: 2.4.6
186 '@vue/tsconfig':
187 specifier: ^0.7.0
188 version: 0.7.0(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2))
189 - autoprefixer:
190 - specifier: ^10.4.21
191 - version: 10.4.21(postcss@8.5.3)
189 cypress:
190 specifier: ^14.2.1
191 version: 14.2.1
@@ -210,9 +207,6 @@ importers:
207 npm-run-all2:
208 specifier: ^7.0.2
209 version: 7.0.2
213 - postcss:
214 - specifier: ^8.5.3
215 - version: 8.5.3
210 prettier:
211 specifier: ^3.5.3
212 version: 3.5.3
@@ -220,45 +214,45 @@ importers:
214 specifier: ^0.6.11
215 version: 0.6.11(prettier@3.5.3)
216 sass:
223 - specifier: ^1.86.0
224 - version: 1.86.0
217 + specifier: ^1.86.2
218 + version: 1.86.2
219 start-server-and-test:
220 specifier: ^2.0.11
221 version: 2.0.11
222 tailwindcss:
229 - specifier: ^3.4.17
230 - version: 3.4.17
223 + specifier: ^4.1.1
224 + version: 4.1.1
225 taze:
226 specifier: ^19.0.4
227 version: 19.0.4
228 type-fest:
235 - specifier: ^4.38.0
236 - version: 4.38.0
229 + specifier: ^4.39.1
230 + version: 4.39.1
231 typescript:
232 specifier: ~5.8.2
233 version: 5.8.2
234 vite:
241 - specifier: ^6.2.4
242 - version: 6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)
235 + specifier: ^6.2.5
236 + version: 6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
237 vite-bundle-visualizer:
238 specifier: ^1.2.1
239 version: 1.2.1(rollup@4.34.9)
240 vite-plugin-vue-devtools:
241 specifier: ^7.7.2
248 - version: 7.7.2(rollup@4.34.9)(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
242 + version: 7.7.2(rollup@4.34.9)(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
243 vite-svg-loader:
244 specifier: ^5.1.0
245 version: 5.1.0(vue@3.5.13(typescript@5.8.2))
246 vitest:
247 specifier: ^3.1.1
254 - version: 3.1.1(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.86.0)(yaml@2.7.0)
248 + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.14.0)(jiti@2.4.2)(jsdom@26.0.0)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
249 vue-tsc:
250 specifier: ^2.2.8
251 version: 2.2.8(typescript@5.8.2)
252 optionalDependencies:
253 '@rollup/rollup-linux-x64-gnu':
260 - specifier: ^4.34.8
261 - version: 4.34.9
254 + specifier: ^4.39.0
255 + version: 4.39.0
256 treemate:
257 specifier: ^0.3.11
258 version: 0.3.11
@@ -271,10 +265,6 @@ packages:
265 '@ajoelp/json-to-formdata@1.5.0':
266 resolution: {integrity: sha512-nrlfeTSL0X0dtx5r2KpzPiqLSIQquiiJjUKsQAKzWaCmO2QoYZCyb5ENZwF3YoffKronOCJr25mxaD8JRJmK8w==}
267
274 - '@alloc/quick-lru@5.2.0':
275 - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
276 - engines: {node: '>=10'}
277 -
268 '@ampproject/remapping@2.3.0':
269 resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
270 engines: {node: '>=6.0.0'}
@@ -1103,6 +1093,11 @@ packages:
1093 cpu: [x64]
1094 os: [linux]
1095
1096 + '@rollup/rollup-linux-x64-gnu@4.39.0':
1097 + resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==}
1098 + cpu: [x64]
1099 + os: [linux]
1100 +
1101 '@rollup/rollup-linux-x64-musl@4.34.9':
1102 resolution: {integrity: sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==}
1103 cpu: [x64]
@@ -1203,10 +1198,83 @@ packages:
1198 peerDependencies:
1199 '@svgdotjs/svg.js': ^3.2.4
1200
1206 - '@tailwindcss/container-queries@0.1.1':
1207 - resolution: {integrity: sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==}
1201 + '@tailwindcss/node@4.1.1':
1202 + resolution: {integrity: sha512-xvlh4pvfG/bkv0fEtJDABAm1tjtSmSyi2QmS4zyj1EKNI1UiOYiUq1IphSwDsNJ5vJ9cWEGs4rJXpUdCN2kujQ==}
1203 +
1204 + '@tailwindcss/oxide-android-arm64@4.1.1':
1205 + resolution: {integrity: sha512-gTyRzfdParpoCU1yyUC/iN6XK6T0Ra4bDlF8Aeul5NP9cLzKEZDogdNVNGv5WZmCDkVol7qlex7TMmcfytMmmw==}
1206 + engines: {node: '>= 10'}
1207 + cpu: [arm64]
1208 + os: [android]
1209 +
1210 + '@tailwindcss/oxide-darwin-arm64@4.1.1':
1211 + resolution: {integrity: sha512-dI0QbdMWBvLB3MtaTKetzUKG9CUUQow8JSP4Nm+OxVokeZ+N+f1OmZW/hW1LzMxpx9RQCBgSRL+IIvKRat5Wdg==}
1212 + engines: {node: '>= 10'}
1213 + cpu: [arm64]
1214 + os: [darwin]
1215 +
1216 + '@tailwindcss/oxide-darwin-x64@4.1.1':
1217 + resolution: {integrity: sha512-2Y+NPQOTRBCItshPgY/CWg4bKi7E9evMg4bgdb6h9iZObCZLOe3doPcuSxGS3DB0dKyMFKE8pTdWtFUbxZBMSA==}
1218 + engines: {node: '>= 10'}
1219 + cpu: [x64]
1220 + os: [darwin]
1221 +
1222 + '@tailwindcss/oxide-freebsd-x64@4.1.1':
1223 + resolution: {integrity: sha512-N97NGMsB/7CHShbc5ube4dcsW/bYENkBrg8yWi8ieN9boYVRdw3cZviVryV/Nfu9bKbBV9kUvduFF2qBI7rEqg==}
1224 + engines: {node: '>= 10'}
1225 + cpu: [x64]
1226 + os: [freebsd]
1227 +
1228 + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.1':
1229 + resolution: {integrity: sha512-33Lk6KbHnUZbXqza6RWNFo9wqPQ4+H5BAn1CkUUfC1RZ1vYbyDN6+iJPj53wmnWJ3mhRI8jWt3Jt1fO02IVdUQ==}
1230 + engines: {node: '>= 10'}
1231 + cpu: [arm]
1232 + os: [linux]
1233 +
1234 + '@tailwindcss/oxide-linux-arm64-gnu@4.1.1':
1235 + resolution: {integrity: sha512-LyW35RzSUy+80WYScv03HKasAUmMFDaSbNpWfk1gG5gEE9kuRGnDzSrqMoLAmY/kzMCYP/1kqmUiAx8EFLkI2A==}
1236 + engines: {node: '>= 10'}
1237 + cpu: [arm64]
1238 + os: [linux]
1239 +
1240 + '@tailwindcss/oxide-linux-arm64-musl@4.1.1':
1241 + resolution: {integrity: sha512-1KPnDMlHdqjPTUSFjx55pafvs8RZXRgxfeRgUrukwDKkuj7gFk28vW3Mx65YdiugAc9NWs3VgueZWaM1Po6uGw==}
1242 + engines: {node: '>= 10'}
1243 + cpu: [arm64]
1244 + os: [linux]
1245 +
1246 + '@tailwindcss/oxide-linux-x64-gnu@4.1.1':
1247 + resolution: {integrity: sha512-4WdzA+MRlsinEEE6yxNMLJxpw0kE9XVipbAKdTL8BeUpyC2TdA3TL46lBulXzKp3BIxh3nqyR/UCqzl5o+3waQ==}
1248 + engines: {node: '>= 10'}
1249 + cpu: [x64]
1250 + os: [linux]
1251 +
1252 + '@tailwindcss/oxide-linux-x64-musl@4.1.1':
1253 + resolution: {integrity: sha512-q7Ugbw3ARcjCW2VMUYrcMbJ6aMQuWPArBBE2EqC/swPZTdGADvMQSlvR0VKusUM4HoSsO7ZbvcZ53YwR57+AKw==}
1254 + engines: {node: '>= 10'}
1255 + cpu: [x64]
1256 + os: [linux]
1257 +
1258 + '@tailwindcss/oxide-win32-arm64-msvc@4.1.1':
1259 + resolution: {integrity: sha512-0KpqsovgHcIzm7eAGzzEZsEs0/nPYXnRBv+aPq/GehpNQuE/NAQu+YgZXIIof+VflDFuyXOEnaFr7T5MZ1INhA==}
1260 + engines: {node: '>= 10'}
1261 + cpu: [arm64]
1262 + os: [win32]
1263 +
1264 + '@tailwindcss/oxide-win32-x64-msvc@4.1.1':
1265 + resolution: {integrity: sha512-B1mjeXNS26kBOHv5sXARf6Wd0PWHV9x1TDlW0ummrBUOUAxAy5wcy4Nii1wzNvCdvC448hgiL06ylhwAbNthmg==}
1266 + engines: {node: '>= 10'}
1267 + cpu: [x64]
1268 + os: [win32]
1269 +
1270 + '@tailwindcss/oxide@4.1.1':
1271 + resolution: {integrity: sha512-7+YBgnPQ4+jv6B6WVOerJ6WOzDzNJXrRKDts674v6TKAqFqYRr9+EBtSziO7nNcwQ8JtoZNMeqA+WJDjtCM/7w==}
1272 + engines: {node: '>= 10'}
1273 +
1274 + '@tailwindcss/vite@4.1.1':
1275 + resolution: {integrity: sha512-tFTkRZwXq4XKr3S2dUZBxy80wbWYHdDSsu4QOB1yE1HJFKjfxKVpXtup4dyTVdQcLInoHC9lZXFPHnjoBP774g==}
1276 peerDependencies:
1209 - tailwindcss: '>=3.2.0'
1277 + vite: ^5.2.0 || ^6
1278
1279 '@trysound/sax@0.2.0':
1280 resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
@@ -1269,8 +1337,8 @@ packages:
1337 '@types/ms@2.1.0':
1338 resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
1339
1272 - '@types/node@22.13.14':
1273 - resolution: {integrity: sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==}
1340 + '@types/node@22.14.0':
1341 + resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==}
1342
1343 '@types/normalize-package-data@2.4.4':
1344 resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
@@ -1673,13 +1741,6 @@ packages:
1741 resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==}
1742 engines: {node: '>=14'}
1743
1676 - any-promise@1.3.0:
1677 - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
1678 -
1679 - anymatch@3.1.3:
1680 - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
1681 - engines: {node: '>= 8'}
1682 -
1744 apexcharts@4.5.0:
1745 resolution: {integrity: sha512-E7ZkrVqPNBUWy/Rmg8DEIqHNBmElzICE/oxOX5Ekvs2ICQUOK/VkEkMH09JGJu+O/EA0NL31hxlmF+wrwrSLaQ==}
1746
@@ -1739,13 +1800,6 @@ packages:
1800 resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
1801 engines: {node: '>= 4.0.0'}
1802
1742 - autoprefixer@10.4.21:
1743 - resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==}
1744 - engines: {node: ^10 || ^12 || >=14}
1745 - hasBin: true
1746 - peerDependencies:
1747 - postcss: ^8.1.0
1748 -
1803 aws-sign2@0.7.0:
1804 resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==}
1805
@@ -1764,10 +1818,6 @@ packages:
1818 bcrypt-pbkdf@1.0.2:
1819 resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
1820
1767 - binary-extensions@2.3.0:
1768 - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
1769 - engines: {node: '>=8'}
1770 -
1821 birpc@0.2.19:
1822 resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==}
1823
@@ -1844,10 +1894,6 @@ packages:
1894 resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
1895 engines: {node: '>=6'}
1896
1847 - camelcase-css@2.0.1:
1848 - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
1849 - engines: {node: '>= 6'}
1850 -
1897 camelcase@6.3.0:
1898 resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
1899 engines: {node: '>=10'}
@@ -1886,10 +1932,6 @@ packages:
1932 resolution: {integrity: sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==}
1933 engines: {node: '>= 0.8.0'}
1934
1889 - chokidar@3.6.0:
1890 - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
1891 - engines: {node: '>= 8.10.0'}
1892 -
1935 chokidar@4.0.3:
1936 resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
1937 engines: {node: '>= 14.16.0'}
@@ -1962,10 +2004,6 @@ packages:
2004 resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
2005 engines: {node: '>=14'}
2006
1965 - commander@4.1.1:
1966 - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
1967 - engines: {node: '>= 6'}
1968 -
2007 commander@6.2.1:
2008 resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==}
2009 engines: {node: '>= 6'}
@@ -2172,18 +2210,16 @@ packages:
2210 engines: {node: '>=0.10'}
2211 hasBin: true
2212
2213 + detect-libc@2.0.3:
2214 + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
2215 + engines: {node: '>=8'}
2216 +
2217 detect-touch-device@1.1.6:
2218 resolution: {integrity: sha512-9DYLJE05EFGI9f8m/GyJtWjw7aMZMBQM2QVy6bb7zX8uC3iorOE3Erdrk3TWCj5FVOlHTfinU0bATTE9GWYebw==}
2219
2220 devlop@1.1.0:
2221 resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
2222
2181 - didyoumean@1.2.2:
2182 - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
2183 -
2184 - dlv@1.1.3:
2185 - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
2186 -
2223 doctrine@3.0.0:
2224 resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
2225 engines: {node: '>=6.0.0'}
@@ -2640,9 +2676,6 @@ packages:
2676 resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==}
2677 engines: {node: '>= 6'}
2678
2643 - fraction.js@4.3.7:
2644 - resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
2645 -
2679 from@0.1.7:
2680 resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==}
2681
@@ -2897,10 +2930,6 @@ packages:
2930 is-arrayish@0.2.1:
2931 resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
2932
2900 - is-binary-path@2.1.0:
2901 - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
2902 - engines: {node: '>=8'}
2903 -
2933 is-builtin-module@4.0.0:
2934 resolution: {integrity: sha512-rWP3AMAalQSesXO8gleROyL2iKU73SX5Er66losQn9rWOWL4Gef0a/xOEOVqjWGMuR2vHG3FJ8UUmT700O8oFg==}
2935 engines: {node: '>=18.20'}
@@ -3003,10 +3032,6 @@ packages:
3032 jackspeak@3.4.3:
3033 resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
3034
3006 - jiti@1.21.7:
3007 - resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
3008 - hasBin: true
3009 -
3035 jiti@2.4.2:
3036 resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
3037 hasBin: true
@@ -3128,9 +3153,69 @@ packages:
3153 resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
3154 engines: {node: '>= 0.8.0'}
3155
3131 - lilconfig@3.1.3:
3132 - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
3133 - engines: {node: '>=14'}
3156 + lightningcss-darwin-arm64@1.29.2:
3157 + resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==}
3158 + engines: {node: '>= 12.0.0'}
3159 + cpu: [arm64]
3160 + os: [darwin]
3161 +
3162 + lightningcss-darwin-x64@1.29.2:
3163 + resolution: {integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==}
3164 + engines: {node: '>= 12.0.0'}
3165 + cpu: [x64]
3166 + os: [darwin]
3167 +
3168 + lightningcss-freebsd-x64@1.29.2:
3169 + resolution: {integrity: sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==}
3170 + engines: {node: '>= 12.0.0'}
3171 + cpu: [x64]
3172 + os: [freebsd]
3173 +
3174 + lightningcss-linux-arm-gnueabihf@1.29.2:
3175 + resolution: {integrity: sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==}
3176 + engines: {node: '>= 12.0.0'}
3177 + cpu: [arm]
3178 + os: [linux]
3179 +
3180 + lightningcss-linux-arm64-gnu@1.29.2:
3181 + resolution: {integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==}
3182 + engines: {node: '>= 12.0.0'}
3183 + cpu: [arm64]
3184 + os: [linux]
3185 +
3186 + lightningcss-linux-arm64-musl@1.29.2:
3187 + resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==}
3188 + engines: {node: '>= 12.0.0'}
3189 + cpu: [arm64]
3190 + os: [linux]
3191 +
3192 + lightningcss-linux-x64-gnu@1.29.2:
3193 + resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==}
3194 + engines: {node: '>= 12.0.0'}
3195 + cpu: [x64]
3196 + os: [linux]
3197 +
3198 + lightningcss-linux-x64-musl@1.29.2:
3199 + resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==}
3200 + engines: {node: '>= 12.0.0'}
3201 + cpu: [x64]
3202 + os: [linux]
3203 +
3204 + lightningcss-win32-arm64-msvc@1.29.2:
3205 + resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==}
3206 + engines: {node: '>= 12.0.0'}
3207 + cpu: [arm64]
3208 + os: [win32]
3209 +
3210 + lightningcss-win32-x64-msvc@1.29.2:
3211 + resolution: {integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==}
3212 + engines: {node: '>= 12.0.0'}
3213 + cpu: [x64]
3214 + os: [win32]
3215 +
3216 + lightningcss@1.29.2:
3217 + resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==}
3218 + engines: {node: '>= 12.0.0'}
3219
3220 lines-and-columns@1.2.4:
3221 resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
@@ -3435,9 +3520,6 @@ packages:
3520 resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==}
3521 engines: {node: '>=10'}
3522
3438 - mz@2.7.0:
3439 - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
3440 -
3523 naive-ui@2.41.0:
3524 resolution: {integrity: sha512-KnmLg+xPLwXV8QVR7ZZ69eCjvel7R5vru8+eFe4VoAJHEgqAJgVph6Zno9K2IVQRpSF3GBGea3tjavslOR4FAA==}
3525 peerDependencies:
@@ -3478,14 +3560,6 @@ packages:
3560 resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==}
3561 engines: {node: ^16.14.0 || >=18.0.0}
3562
3481 - normalize-path@3.0.0:
3482 - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
3483 - engines: {node: '>=0.10.0'}
3484 -
3485 - normalize-range@0.1.2:
3486 - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
3487 - engines: {node: '>=0.10.0'}
3488 -
3563 npm-normalize-package-bin@4.0.0:
3564 resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==}
3565 engines: {node: ^18.17.0 || >=20.5.0}
@@ -3514,14 +3588,6 @@ packages:
3588 engines: {node: ^14.16.0 || >=16.10.0}
3589 hasBin: true
3590
3517 - object-assign@4.1.1:
3518 - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
3519 - engines: {node: '>=0.10.0'}
3520 -
3521 - object-hash@3.0.0:
3522 - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
3523 - engines: {node: '>= 6'}
3524 -
3591 object-inspect@1.13.4:
3592 resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
3593 engines: {node: '>= 0.4'}
@@ -3712,10 +3778,6 @@ packages:
3778 typescript:
3779 optional: true
3780
3715 - pirates@4.0.6:
3716 - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
3717 - engines: {node: '>= 6'}
3718 -
3781 pkg-types@1.3.1:
3782 resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
3783
@@ -3732,43 +3794,10 @@ packages:
3794 pnpm-workspace-yaml@0.3.1:
3795 resolution: {integrity: sha512-3nW5RLmREmZ8Pm8MbPsO2RM+99RRjYd25ynj3NV0cFsN7CcEl4sDFzgoFmSyduFwxFQ2Qbu3y2UdCh6HlyUOeA==}
3796
3735 - postcss-import@15.1.0:
3736 - resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
3737 - engines: {node: '>=14.0.0'}
3738 - peerDependencies:
3739 - postcss: ^8.0.0
3740 -
3741 - postcss-js@4.0.1:
3742 - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
3743 - engines: {node: ^12 || ^14 || >= 16}
3744 - peerDependencies:
3745 - postcss: ^8.4.21
3746 -
3747 - postcss-load-config@4.0.2:
3748 - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
3749 - engines: {node: '>= 14'}
3750 - peerDependencies:
3751 - postcss: '>=8.0.9'
3752 - ts-node: '>=9.0.0'
3753 - peerDependenciesMeta:
3754 - postcss:
3755 - optional: true
3756 - ts-node:
3757 - optional: true
3758 -
3759 - postcss-nested@6.2.0:
3760 - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
3761 - engines: {node: '>=12.0'}
3762 - peerDependencies:
3763 - postcss: ^8.2.14
3764 -
3797 postcss-selector-parser@6.1.2:
3798 resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
3799 engines: {node: '>=4'}
3800
3769 - postcss-value-parser@4.2.0:
3770 - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
3771 -
3801 postcss@8.5.3:
3802 resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
3803 engines: {node: ^10 || ^12 || >=14}
@@ -3890,9 +3919,6 @@ packages:
3919 rc9@2.1.2:
3920 resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
3921
3893 - read-cache@1.0.0:
3894 - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
3895 -
3922 read-package-json-fast@4.0.0:
3923 resolution: {integrity: sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==}
3924 engines: {node: ^18.17.0 || >=20.5.0}
@@ -4020,8 +4046,8 @@ packages:
4046 safer-buffer@2.1.2:
4047 resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
4048
4023 - sass@1.86.0:
4024 - resolution: {integrity: sha512-zV8vGUld/+mP4KbMLJMX7TyGCuUp7hnkOScgCMsWuHtns8CWBoz+vmEhoGMXsaJrbUP8gj+F1dLvVe79sK8UdA==}
4049 + sass@1.86.2:
4050 + resolution: {integrity: sha512-Rpfn0zAIDqvnSb2DihJTDFjbhqLHu91Wqac9rxontWk7R+2txcPjuujMqu1eeoezh5kAblVCS5EdFdyr0Jmu+w==}
4051 engines: {node: '>=14.0.0'}
4052 hasBin: true
4053
@@ -4220,11 +4246,6 @@ packages:
4246 style-mod@4.1.2:
4247 resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==}
4248
4223 - sucrase@3.35.0:
4224 - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
4225 - engines: {node: '>=16 || 14 >=14.17'}
4226 - hasBin: true
4227 -
4249 superjson@2.2.2:
4250 resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==}
4251 engines: {node: '>=16'}
@@ -4257,10 +4278,8 @@ packages:
4278 resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==}
4279 engines: {node: ^14.18.0 || >=16.0.0}
4280
4260 - tailwindcss@3.4.17:
4261 - resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==}
4262 - engines: {node: '>=14.0.0'}
4263 - hasBin: true
4281 + tailwindcss@4.1.1:
4282 + resolution: {integrity: sha512-QNbdmeS979Efzim2g/bEvfuh+fTcIdp1y7gA+sb6OYSW74rt7Cr7M78AKdf6HqWT3d5AiTb7SwTT3sLQxr4/qw==}
4283
4284 tapable@2.2.1:
4285 resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
@@ -4281,13 +4300,6 @@ packages:
4300 '@codemirror/state': ^6.0.0
4301 '@codemirror/view': ^6.0.0
4302
4284 - thenify-all@1.6.0:
4285 - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
4286 - engines: {node: '>=0.8'}
4287 -
4288 - thenify@3.3.1:
4289 - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
4290 -
4303 throttleit@1.0.1:
4304 resolution: {integrity: sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==}
4305
@@ -4366,9 +4378,6 @@ packages:
4378 peerDependencies:
4379 typescript: '>=4.8.4'
4380
4369 - ts-interface-checker@0.1.13:
4370 - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
4371 -
4381 tslib@2.3.0:
4382 resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==}
4383
@@ -4389,8 +4398,8 @@ packages:
4398 resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
4399 engines: {node: '>=10'}
4400
4392 - type-fest@4.38.0:
4393 - resolution: {integrity: sha512-2dBz5D5ycHIoliLYLi0Q2V7KRaDlH0uWIvmk7TYlAg5slqwiPv1ezJdZm1QEM0xgk29oYWMCbIG7E6gHpvChlg==}
4401 + type-fest@4.39.1:
4402 + resolution: {integrity: sha512-uW9qzd66uyHYxwyVBYiwS4Oi0qZyUqwjU+Oevr6ZogYiXt99EOYtwvzMSLw1c3lYo2HzJsep/NB23iEVEgjG/w==}
4403 engines: {node: '>=16'}
4404
4405 typescript@5.8.2:
@@ -4410,8 +4419,8 @@ packages:
4419 unctx@2.4.1:
4420 resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==}
4421
4413 - undici-types@6.20.0:
4414 - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
4422 + undici-types@6.21.0:
4423 + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
4424
4425 unicorn-magic@0.1.0:
4426 resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
@@ -4542,8 +4551,8 @@ packages:
4551 peerDependencies:
4552 vue: '>=3.2.13'
4553
4545 - vite@6.2.4:
4546 - resolution: {integrity: sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==}
4554 + vite@6.2.5:
4555 + resolution: {integrity: sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==}
4556 engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
4557 hasBin: true
4558 peerDependencies:
@@ -4850,14 +4859,12 @@ snapshots:
4859 dependencies:
4860 lodash: 4.17.21
4861
4853 - '@alloc/quick-lru@5.2.0': {}
4854 -
4862 '@ampproject/remapping@2.3.0':
4863 dependencies:
4864 '@jridgewell/gen-mapping': 0.3.8
4865 '@jridgewell/trace-mapping': 0.3.25
4866
4860 - '@antfu/eslint-config@4.11.0(@typescript-eslint/utils@8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(@vue/compiler-sfc@3.5.13)(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.86.0)(yaml@2.7.0))':
4867 + '@antfu/eslint-config@4.11.0(@typescript-eslint/utils@8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(@vue/compiler-sfc@3.5.13)(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.14.0)(jiti@2.4.2)(jsdom@26.0.0)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))':
4868 dependencies:
4869 '@antfu/install-pkg': 1.0.0
4870 '@clack/prompts': 0.10.0
@@ -4866,7 +4873,7 @@ snapshots:
4873 '@stylistic/eslint-plugin': 4.2.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
4874 '@typescript-eslint/eslint-plugin': 8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
4875 '@typescript-eslint/parser': 8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
4869 - '@vitest/eslint-plugin': 1.1.38(@typescript-eslint/utils@8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.86.0)(yaml@2.7.0))
4876 + '@vitest/eslint-plugin': 1.1.38(@typescript-eslint/utils@8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.14.0)(jiti@2.4.2)(jsdom@26.0.0)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))
4877 ansis: 3.17.0
4878 cac: 6.7.14
4879 eslint: 9.23.0(jiti@2.4.2)
@@ -5707,6 +5714,9 @@ snapshots:
5714 '@rollup/rollup-linux-x64-gnu@4.34.9':
5715 optional: true
5716
5717 + '@rollup/rollup-linux-x64-gnu@4.39.0':
5718 + optional: true
5719 +
5720 '@rollup/rollup-linux-x64-musl@4.34.9':
5721 optional: true
5722
@@ -5802,9 +5812,66 @@ snapshots:
5812 dependencies:
5813 '@svgdotjs/svg.js': 3.2.4
5814
5805 - '@tailwindcss/container-queries@0.1.1(tailwindcss@3.4.17)':
5815 + '@tailwindcss/node@4.1.1':
5816 dependencies:
5807 - tailwindcss: 3.4.17
5817 + enhanced-resolve: 5.18.1
5818 + jiti: 2.4.2
5819 + lightningcss: 1.29.2
5820 + tailwindcss: 4.1.1
5821 +
5822 + '@tailwindcss/oxide-android-arm64@4.1.1':
5823 + optional: true
5824 +
5825 + '@tailwindcss/oxide-darwin-arm64@4.1.1':
5826 + optional: true
5827 +
5828 + '@tailwindcss/oxide-darwin-x64@4.1.1':
5829 + optional: true
5830 +
5831 + '@tailwindcss/oxide-freebsd-x64@4.1.1':
5832 + optional: true
5833 +
5834 + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.1':
5835 + optional: true
5836 +
5837 + '@tailwindcss/oxide-linux-arm64-gnu@4.1.1':
5838 + optional: true
5839 +
5840 + '@tailwindcss/oxide-linux-arm64-musl@4.1.1':
5841 + optional: true
5842 +
5843 + '@tailwindcss/oxide-linux-x64-gnu@4.1.1':
5844 + optional: true
5845 +
5846 + '@tailwindcss/oxide-linux-x64-musl@4.1.1':
5847 + optional: true
5848 +
5849 + '@tailwindcss/oxide-win32-arm64-msvc@4.1.1':
5850 + optional: true
5851 +
5852 + '@tailwindcss/oxide-win32-x64-msvc@4.1.1':
5853 + optional: true
5854 +
5855 + '@tailwindcss/oxide@4.1.1':
5856 + optionalDependencies:
5857 + '@tailwindcss/oxide-android-arm64': 4.1.1
5858 + '@tailwindcss/oxide-darwin-arm64': 4.1.1
5859 + '@tailwindcss/oxide-darwin-x64': 4.1.1
5860 + '@tailwindcss/oxide-freebsd-x64': 4.1.1
5861 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.1
5862 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.1
5863 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.1
5864 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.1
5865 + '@tailwindcss/oxide-linux-x64-musl': 4.1.1
5866 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.1
5867 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.1
5868 +
5869 + '@tailwindcss/vite@4.1.1(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))':
5870 + dependencies:
5871 + '@tailwindcss/node': 4.1.1
5872 + '@tailwindcss/oxide': 4.1.1
5873 + tailwindcss: 4.1.1
5874 + vite: 6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
5875
5876 '@trysound/sax@0.2.0': {}
5877
@@ -5835,7 +5902,7 @@ snapshots:
5902 '@types/fs-extra@11.0.4':
5903 dependencies:
5904 '@types/jsonfile': 6.1.4
5838 - '@types/node': 22.13.14
5905 + '@types/node': 22.14.0
5906
5907 '@types/hast@3.0.4':
5908 dependencies:
@@ -5843,7 +5910,7 @@ snapshots:
5910
5911 '@types/jsdom@21.1.7':
5912 dependencies:
5846 - '@types/node': 22.13.14
5913 + '@types/node': 22.14.0
5914 '@types/tough-cookie': 4.0.5
5915 parse5: 7.2.1
5916
@@ -5851,7 +5918,7 @@ snapshots:
5918
5919 '@types/jsonfile@6.1.4':
5920 dependencies:
5854 - '@types/node': 22.13.14
5921 + '@types/node': 22.14.0
5922
5923 '@types/katex@0.16.7': {}
5924
@@ -5869,9 +5936,9 @@ snapshots:
5936
5937 '@types/ms@2.1.0': {}
5938
5872 - '@types/node@22.13.14':
5939 + '@types/node@22.14.0':
5940 dependencies:
5874 - undici-types: 6.20.0
5941 + undici-types: 6.21.0
5942
5943 '@types/normalize-package-data@2.4.4': {}
5944
@@ -5891,7 +5958,7 @@ snapshots:
5958
5959 '@types/yauzl@2.10.3':
5960 dependencies:
5894 - '@types/node': 22.13.14
5961 + '@types/node': 22.14.0
5962 optional: true
5963
5964 '@typescript-eslint/eslint-plugin@8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)':
@@ -6057,28 +6124,28 @@ snapshots:
6124 '@unrs/resolver-binding-win32-x64-msvc@1.3.3':
6125 optional: true
6126
6060 - '@vitejs/plugin-vue-jsx@4.1.2(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))':
6127 + '@vitejs/plugin-vue-jsx@4.1.2(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))':
6128 dependencies:
6129 '@babel/core': 7.26.9
6130 '@babel/plugin-transform-typescript': 7.26.8(@babel/core@7.26.9)
6131 '@vue/babel-plugin-jsx': 1.3.0(@babel/core@7.26.9)
6065 - vite: 6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)
6132 + vite: 6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
6133 vue: 3.5.13(typescript@5.8.2)
6134 transitivePeerDependencies:
6135 - supports-color
6136
6070 - '@vitejs/plugin-vue@5.2.3(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))':
6137 + '@vitejs/plugin-vue@5.2.3(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))':
6138 dependencies:
6072 - vite: 6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)
6139 + vite: 6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
6140 vue: 3.5.13(typescript@5.8.2)
6141
6075 - '@vitest/eslint-plugin@1.1.38(@typescript-eslint/utils@8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.86.0)(yaml@2.7.0))':
6142 + '@vitest/eslint-plugin@1.1.38(@typescript-eslint/utils@8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.14.0)(jiti@2.4.2)(jsdom@26.0.0)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))':
6143 dependencies:
6144 '@typescript-eslint/utils': 8.28.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)
6145 eslint: 9.23.0(jiti@2.4.2)
6146 optionalDependencies:
6147 typescript: 5.8.2
6081 - vitest: 3.1.1(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.86.0)(yaml@2.7.0)
6148 + vitest: 3.1.1(@types/debug@4.1.12)(@types/node@22.14.0)(jiti@2.4.2)(jsdom@26.0.0)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
6149
6150 '@vitest/expect@3.1.1':
6151 dependencies:
@@ -6087,13 +6154,13 @@ snapshots:
6154 chai: 5.2.0
6155 tinyrainbow: 2.0.0
6156
6090 - '@vitest/mocker@3.1.1(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))':
6157 + '@vitest/mocker@3.1.1(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))':
6158 dependencies:
6159 '@vitest/spy': 3.1.1
6160 estree-walker: 3.0.3
6161 magic-string: 0.30.17
6162 optionalDependencies:
6096 - vite: 6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)
6163 + vite: 6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
6164
6165 '@vitest/pretty-format@3.1.1':
6166 dependencies:
@@ -6202,14 +6269,14 @@ snapshots:
6269 dependencies:
6270 '@vue/devtools-kit': 7.7.2
6271
6205 - '@vue/devtools-core@7.7.2(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))':
6272 + '@vue/devtools-core@7.7.2(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))':
6273 dependencies:
6274 '@vue/devtools-kit': 7.7.2
6275 '@vue/devtools-shared': 7.7.2
6276 mitt: 3.0.1
6277 nanoid: 5.1.5
6278 pathe: 2.0.3
6212 - vite-hot-client: 0.2.4(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))
6279 + vite-hot-client: 0.2.4(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))
6280 vue: 3.5.13(typescript@5.8.2)
6281 transitivePeerDependencies:
6282 - vite
@@ -6332,13 +6399,6 @@ snapshots:
6399
6400 ansis@3.17.0: {}
6401
6335 - any-promise@1.3.0: {}
6336 -
6337 - anymatch@3.1.3:
6338 - dependencies:
6339 - normalize-path: 3.0.0
6340 - picomatch: 2.3.1
6341 -
6402 apexcharts@4.5.0:
6403 dependencies:
6404 '@svgdotjs/svg.draggable.js': 3.0.6(@svgdotjs/svg.js@3.2.4)
@@ -6384,16 +6444,6 @@ snapshots:
6444
6445 at-least-node@1.0.0: {}
6446
6387 - autoprefixer@10.4.21(postcss@8.5.3):
6388 - dependencies:
6389 - browserslist: 4.24.4
6390 - caniuse-lite: 1.0.30001702
6391 - fraction.js: 4.3.7
6392 - normalize-range: 0.1.2
6393 - picocolors: 1.1.1
6394 - postcss: 8.5.3
6395 - postcss-value-parser: 4.2.0
6396 -
6447 aws-sign2@0.7.0: {}
6448
6449 aws4@1.13.2: {}
@@ -6414,8 +6464,6 @@ snapshots:
6464 dependencies:
6465 tweetnacl: 0.14.5
6466
6417 - binary-extensions@2.3.0: {}
6418 -
6467 birpc@0.2.19: {}
6468
6469 blob-util@2.0.2: {}
@@ -6492,8 +6540,6 @@ snapshots:
6540
6541 callsites@3.1.0: {}
6542
6495 - camelcase-css@2.0.1: {}
6496 -
6543 camelcase@6.3.0: {}
6544
6545 caniuse-lite@1.0.30001702: {}
@@ -6525,18 +6571,6 @@ snapshots:
6571
6572 check-more-types@2.24.0: {}
6573
6528 - chokidar@3.6.0:
6529 - dependencies:
6530 - anymatch: 3.1.3
6531 - braces: 3.0.3
6532 - glob-parent: 5.1.2
6533 - is-binary-path: 2.1.0
6534 - is-glob: 4.0.3
6535 - normalize-path: 3.0.0
6536 - readdirp: 3.6.0
6537 - optionalDependencies:
6538 - fsevents: 2.3.3
6539 -
6574 chokidar@4.0.3:
6575 dependencies:
6576 readdirp: 4.1.2
@@ -6612,8 +6646,6 @@ snapshots:
6646
6647 commander@10.0.1: {}
6648
6615 - commander@4.1.1: {}
6616 -
6649 commander@6.2.1: {}
6650
6651 commander@7.2.0: {}
@@ -6850,16 +6882,14 @@ snapshots:
6882 detect-libc@1.0.3:
6883 optional: true
6884
6885 + detect-libc@2.0.3: {}
6886 +
6887 detect-touch-device@1.1.6: {}
6888
6889 devlop@1.1.0:
6890 dependencies:
6891 dequal: 2.0.3
6892
6859 - didyoumean@1.2.2: {}
6860 -
6861 - dlv@1.1.3: {}
6862 -
6893 doctrine@3.0.0:
6894 dependencies:
6895 esutils: 2.0.3
@@ -7459,8 +7489,6 @@ snapshots:
7489 es-set-tostringtag: 2.1.0
7490 mime-types: 2.1.35
7491
7462 - fraction.js@4.3.7: {}
7463 -
7492 from@0.1.7: {}
7493
7494 fs-extra@11.3.0:
@@ -7720,10 +7748,6 @@ snapshots:
7748
7749 is-arrayish@0.2.1: {}
7750
7723 - is-binary-path@2.1.0:
7724 - dependencies:
7725 - binary-extensions: 2.3.0
7726 -
7751 is-builtin-module@4.0.0:
7752 dependencies:
7753 builtin-modules: 4.0.0
@@ -7795,8 +7819,6 @@ snapshots:
7819 optionalDependencies:
7820 '@pkgjs/parseargs': 0.11.0
7821
7798 - jiti@1.21.7: {}
7799 -
7822 jiti@2.4.2: {}
7823
7824 joi@17.13.3:
@@ -7923,7 +7945,50 @@ snapshots:
7945 prelude-ls: 1.2.1
7946 type-check: 0.4.0
7947
7926 - lilconfig@3.1.3: {}
7948 + lightningcss-darwin-arm64@1.29.2:
7949 + optional: true
7950 +
7951 + lightningcss-darwin-x64@1.29.2:
7952 + optional: true
7953 +
7954 + lightningcss-freebsd-x64@1.29.2:
7955 + optional: true
7956 +
7957 + lightningcss-linux-arm-gnueabihf@1.29.2:
7958 + optional: true
7959 +
7960 + lightningcss-linux-arm64-gnu@1.29.2:
7961 + optional: true
7962 +
7963 + lightningcss-linux-arm64-musl@1.29.2:
7964 + optional: true
7965 +
7966 + lightningcss-linux-x64-gnu@1.29.2:
7967 + optional: true
7968 +
7969 + lightningcss-linux-x64-musl@1.29.2:
7970 + optional: true
7971 +
7972 + lightningcss-win32-arm64-msvc@1.29.2:
7973 + optional: true
7974 +
7975 + lightningcss-win32-x64-msvc@1.29.2:
7976 + optional: true
7977 +
7978 + lightningcss@1.29.2:
7979 + dependencies:
7980 + detect-libc: 2.0.3
7981 + optionalDependencies:
7982 + lightningcss-darwin-arm64: 1.29.2
7983 + lightningcss-darwin-x64: 1.29.2
7984 + lightningcss-freebsd-x64: 1.29.2
7985 + lightningcss-linux-arm-gnueabihf: 1.29.2
7986 + lightningcss-linux-arm64-gnu: 1.29.2
7987 + lightningcss-linux-arm64-musl: 1.29.2
7988 + lightningcss-linux-x64-gnu: 1.29.2
7989 + lightningcss-linux-x64-musl: 1.29.2
7990 + lightningcss-win32-arm64-msvc: 1.29.2
7991 + lightningcss-win32-x64-msvc: 1.29.2
7992
7993 lines-and-columns@1.2.4: {}
7994
@@ -8399,12 +8464,6 @@ snapshots:
8464 arrify: 2.0.1
8465 minimatch: 3.1.2
8466
8402 - mz@2.7.0:
8403 - dependencies:
8404 - any-promise: 1.3.0
8405 - object-assign: 4.1.1
8406 - thenify-all: 1.6.0
8407 -
8467 naive-ui@2.41.0(vue@3.5.13(typescript@5.8.2)):
8468 dependencies:
8469 '@css-render/plugin-bem': 0.15.14(css-render@0.15.14)
@@ -8453,10 +8512,6 @@ snapshots:
8512 semver: 7.7.1
8513 validate-npm-package-license: 3.0.4
8514
8456 - normalize-path@3.0.0: {}
8457 -
8458 - normalize-range@0.1.2: {}
8459 -
8515 npm-normalize-package-bin@4.0.0: {}
8516
8517 npm-run-all2@7.0.2:
@@ -8494,10 +8549,6 @@ snapshots:
8549 tinyexec: 0.3.2
8550 ufo: 1.5.4
8551
8497 - object-assign@4.1.1: {}
8498 -
8499 - object-hash@3.0.0: {}
8500 -
8552 object-inspect@1.13.4: {}
8553
8554 ofetch@1.4.1:
@@ -8597,7 +8648,7 @@ snapshots:
8648 dependencies:
8649 '@babel/code-frame': 7.26.2
8650 index-to-position: 0.1.2
8600 - type-fest: 4.38.0
8651 + type-fest: 4.39.1
8652
8653 parse-ms@4.0.0: {}
8654
@@ -8671,8 +8722,6 @@ snapshots:
8722 optionalDependencies:
8723 typescript: 5.8.2
8724
8674 - pirates@4.0.6: {}
8675 -
8725 pkg-types@1.3.1:
8726 dependencies:
8727 confbox: 0.1.8
@@ -8695,37 +8744,11 @@ snapshots:
8744 dependencies:
8745 yaml: 2.7.0
8746
8698 - postcss-import@15.1.0(postcss@8.5.3):
8699 - dependencies:
8700 - postcss: 8.5.3
8701 - postcss-value-parser: 4.2.0
8702 - read-cache: 1.0.0
8703 - resolve: 1.22.10
8704 -
8705 - postcss-js@4.0.1(postcss@8.5.3):
8706 - dependencies:
8707 - camelcase-css: 2.0.1
8708 - postcss: 8.5.3
8709 -
8710 - postcss-load-config@4.0.2(postcss@8.5.3):
8711 - dependencies:
8712 - lilconfig: 3.1.3
8713 - yaml: 2.7.0
8714 - optionalDependencies:
8715 - postcss: 8.5.3
8716 -
8717 - postcss-nested@6.2.0(postcss@8.5.3):
8718 - dependencies:
8719 - postcss: 8.5.3
8720 - postcss-selector-parser: 6.1.2
8721 -
8747 postcss-selector-parser@6.1.2:
8748 dependencies:
8749 cssesc: 3.0.0
8750 util-deprecate: 1.0.2
8751
8727 - postcss-value-parser@4.2.0: {}
8728 -
8752 postcss@8.5.3:
8753 dependencies:
8754 nanoid: 3.3.8
@@ -8782,10 +8805,6 @@ snapshots:
8805 defu: 6.1.4
8806 destr: 2.0.3
8807
8785 - read-cache@1.0.0:
8786 - dependencies:
8787 - pify: 2.3.0
8788 -
8808 read-package-json-fast@4.0.0:
8809 dependencies:
8810 json-parse-even-better-errors: 4.0.0
@@ -8795,14 +8814,14 @@ snapshots:
8814 dependencies:
8815 find-up-simple: 1.0.1
8816 read-pkg: 9.0.1
8798 - type-fest: 4.38.0
8817 + type-fest: 4.39.1
8818
8819 read-pkg@9.0.1:
8820 dependencies:
8821 '@types/normalize-package-data': 2.4.4
8822 normalize-package-data: 6.0.2
8823 parse-json: 8.1.0
8805 - type-fest: 4.38.0
8824 + type-fest: 4.39.1
8825 unicorn-magic: 0.1.0
8826
8827 readdirp@3.6.0:
@@ -8925,7 +8944,7 @@ snapshots:
8944
8945 safer-buffer@2.1.2: {}
8946
8928 - sass@1.86.0:
8947 + sass@1.86.2:
8948 dependencies:
8949 chokidar: 4.0.3
8950 immutable: 5.0.3
@@ -9146,16 +9165,6 @@ snapshots:
9165
9166 style-mod@4.1.2: {}
9167
9149 - sucrase@3.35.0:
9150 - dependencies:
9151 - '@jridgewell/gen-mapping': 0.3.8
9152 - commander: 4.1.1
9153 - glob: 10.4.5
9154 - lines-and-columns: 1.2.4
9155 - mz: 2.7.0
9156 - pirates: 4.0.6
9157 - ts-interface-checker: 0.1.13
9158 -
9168 superjson@2.2.2:
9169 dependencies:
9170 copy-anything: 3.0.5
@@ -9191,32 +9200,7 @@ snapshots:
9200 '@pkgr/core': 0.1.1
9201 tslib: 2.8.1
9202
9194 - tailwindcss@3.4.17:
9195 - dependencies:
9196 - '@alloc/quick-lru': 5.2.0
9197 - arg: 5.0.2
9198 - chokidar: 3.6.0
9199 - didyoumean: 1.2.2
9200 - dlv: 1.1.3
9201 - fast-glob: 3.3.3
9202 - glob-parent: 6.0.2
9203 - is-glob: 4.0.3
9204 - jiti: 1.21.7
9205 - lilconfig: 3.1.3
9206 - micromatch: 4.0.8
9207 - normalize-path: 3.0.0
9208 - object-hash: 3.0.0
9209 - picocolors: 1.1.1
9210 - postcss: 8.5.3
9211 - postcss-import: 15.1.0(postcss@8.5.3)
9212 - postcss-js: 4.0.1(postcss@8.5.3)
9213 - postcss-load-config: 4.0.2(postcss@8.5.3)
9214 - postcss-nested: 6.2.0(postcss@8.5.3)
9215 - postcss-selector-parser: 6.1.2
9216 - resolve: 1.22.10
9217 - sucrase: 3.35.0
9218 - transitivePeerDependencies:
9219 - - ts-node
9203 + tailwindcss@4.1.1: {}
9204
9205 tapable@2.2.1: {}
9206
@@ -9250,14 +9234,6 @@ snapshots:
9234 '@codemirror/state': 6.5.2
9235 '@codemirror/view': 6.36.4
9236
9253 - thenify-all@1.6.0:
9254 - dependencies:
9255 - thenify: 3.3.1
9256 -
9257 - thenify@3.3.1:
9258 - dependencies:
9259 - any-promise: 1.3.0
9260 -
9237 throttleit@1.0.1: {}
9238
9239 through@2.3.8: {}
@@ -9315,8 +9291,6 @@ snapshots:
9291 dependencies:
9292 typescript: 5.8.2
9293
9318 - ts-interface-checker@0.1.13: {}
9319 -
9294 tslib@2.3.0: {}
9295
9296 tslib@2.8.1: {}
@@ -9333,7 +9307,7 @@ snapshots:
9307
9308 type-fest@0.21.3: {}
9309
9336 - type-fest@4.38.0: {}
9310 + type-fest@4.39.1: {}
9311
9312 typescript@5.8.2: {}
9313
@@ -9355,7 +9329,7 @@ snapshots:
9329 magic-string: 0.30.17
9330 unplugin: 2.2.0
9331
9358 - undici-types@6.20.0: {}
9332 + undici-types@6.21.0: {}
9333
9334 unicorn-magic@0.1.0: {}
9335
@@ -9499,17 +9473,17 @@ snapshots:
9473 - rollup
9474 - supports-color
9475
9502 - vite-hot-client@0.2.4(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)):
9476 + vite-hot-client@0.2.4(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)):
9477 dependencies:
9504 - vite: 6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)
9478 + vite: 6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
9479
9506 - vite-node@3.1.1(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0):
9480 + vite-node@3.1.1(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0):
9481 dependencies:
9482 cac: 6.7.14
9483 debug: 4.4.0(supports-color@8.1.1)
9484 es-module-lexer: 1.6.0
9485 pathe: 2.0.3
9512 - vite: 6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)
9486 + vite: 6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
9487 transitivePeerDependencies:
9488 - '@types/node'
9489 - jiti
@@ -9524,7 +9498,7 @@ snapshots:
9498 - tsx
9499 - yaml
9500
9527 - vite-plugin-inspect@0.8.9(rollup@4.34.9)(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)):
9501 + vite-plugin-inspect@0.8.9(rollup@4.34.9)(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)):
9502 dependencies:
9503 '@antfu/utils': 0.7.10
9504 '@rollup/pluginutils': 5.1.4(rollup@4.34.9)
@@ -9535,28 +9509,28 @@ snapshots:
9509 perfect-debounce: 1.0.0
9510 picocolors: 1.1.1
9511 sirv: 3.0.1
9538 - vite: 6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)
9512 + vite: 6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
9513 transitivePeerDependencies:
9514 - rollup
9515 - supports-color
9516
9543 - vite-plugin-vue-devtools@7.7.2(rollup@4.34.9)(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)):
9517 + vite-plugin-vue-devtools@7.7.2(rollup@4.34.9)(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)):
9518 dependencies:
9545 - '@vue/devtools-core': 7.7.2(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
9519 + '@vue/devtools-core': 7.7.2(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
9520 '@vue/devtools-kit': 7.7.2
9521 '@vue/devtools-shared': 7.7.2
9522 execa: 9.5.2
9523 sirv: 3.0.1
9550 - vite: 6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)
9551 - vite-plugin-inspect: 0.8.9(rollup@4.34.9)(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))
9552 - vite-plugin-vue-inspector: 5.3.1(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))
9524 + vite: 6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
9525 + vite-plugin-inspect: 0.8.9(rollup@4.34.9)(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))
9526 + vite-plugin-vue-inspector: 5.3.1(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))
9527 transitivePeerDependencies:
9528 - '@nuxt/kit'
9529 - rollup
9530 - supports-color
9531 - vue
9532
9559 - vite-plugin-vue-inspector@5.3.1(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)):
9533 + vite-plugin-vue-inspector@5.3.1(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)):
9534 dependencies:
9535 '@babel/core': 7.26.9
9536 '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.9)
@@ -9567,7 +9541,7 @@ snapshots:
9541 '@vue/compiler-dom': 3.5.13
9542 kolorist: 1.8.0
9543 magic-string: 0.30.17
9570 - vite: 6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)
9544 + vite: 6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
9545 transitivePeerDependencies:
9546 - supports-color
9547
@@ -9576,22 +9550,23 @@ snapshots:
9550 svgo: 3.3.2
9551 vue: 3.5.13(typescript@5.8.2)
9552
9579 - vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0):
9553 + vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0):
9554 dependencies:
9555 esbuild: 0.25.0
9556 postcss: 8.5.3
9557 rollup: 4.34.9
9558 optionalDependencies:
9585 - '@types/node': 22.13.14
9559 + '@types/node': 22.14.0
9560 fsevents: 2.3.3
9561 jiti: 2.4.2
9588 - sass: 1.86.0
9562 + lightningcss: 1.29.2
9563 + sass: 1.86.2
9564 yaml: 2.7.0
9565
9591 - vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.13.14)(jiti@2.4.2)(jsdom@26.0.0)(sass@1.86.0)(yaml@2.7.0):
9566 + vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.14.0)(jiti@2.4.2)(jsdom@26.0.0)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0):
9567 dependencies:
9568 '@vitest/expect': 3.1.1
9594 - '@vitest/mocker': 3.1.1(vite@6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0))
9569 + '@vitest/mocker': 3.1.1(vite@6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0))
9570 '@vitest/pretty-format': 3.1.1
9571 '@vitest/runner': 3.1.1
9572 '@vitest/snapshot': 3.1.1
@@ -9607,12 +9582,12 @@ snapshots:
9582 tinyexec: 0.3.2
9583 tinypool: 1.0.2
9584 tinyrainbow: 2.0.0
9610 - vite: 6.2.4(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)
9611 - vite-node: 3.1.1(@types/node@22.13.14)(jiti@2.4.2)(sass@1.86.0)(yaml@2.7.0)
9585 + vite: 6.2.5(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
9586 + vite-node: 3.1.1(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.86.2)(yaml@2.7.0)
9587 why-is-node-running: 2.3.0
9588 optionalDependencies:
9589 '@types/debug': 4.1.12
9615 - '@types/node': 22.13.14
9590 + '@types/node': 22.14.0
9591 jsdom: 26.0.0
9592 transitivePeerDependencies:
9593 - jiti
frontend/postcss.config.js deleted
-6
@@ -1,6 +0,0 @@
1 -export default {
2 - plugins: {
3 - tailwindcss: {},
4 - autoprefixer: {}
5 - }
6 -}
frontend/src/App.vue
-1
@@ -36,7 +36,6 @@ import { useMainStore } from "@/stores/main"
36 import { useThemeStore } from "@/stores/theme"
37 import { computed, onBeforeMount, ref, watch } from "vue"
38 import { useRoute, useRouter } from "vue-router"
39 -import "@/assets/scss/index.scss"
39
40 const router = useRouter()
41 const route = useRoute()
frontend/src/app-layouts/HorizontalNav/MainContainer.vue
+2 -2
@@ -8,13 +8,13 @@
8 ref="scrollbar"
9 trigger="none"
10 :y-placement="isRTL ? 'left' : 'right'"
11 - content-class="min-h-full flex flex-col"
11 + content-class="flex min-h-full flex-col"
12 :theme-overrides="{
13 railInsetVerticalRight: `${toolbarHeight}px 4px 4px auto`,
14 railInsetVerticalLeft: `${toolbarHeight}px auto 4px 4px`
15 }"
16 >
17 - <Toolbar :boxed="toolbarBoxed" class="gradient-bg-sidebar" />
17 + <Toolbar :boxed="toolbarBoxed" gradient="sidebar" />
18 <div
19 id="app-view"
20 class="view"
frontend/src/app-layouts/HorizontalNav/Sidebar.vue
+10 -4
@@ -5,11 +5,17 @@
5 :class="{ collapsed: sidebarCollapsed, opened: !sidebarCollapsed }"
6 >
7 <div ref="sidebar" class="sidebar-wrap flex grow flex-col">
8 - <SidebarHeader :logo-mini="sidebarClosed" />
8 + <div :class="{ 'px-7': !sidebarClosed, 'px-2': sidebarClosed }" class="transition-all">
9 + <SidebarHeader :logo-mini="sidebarClosed" />
10 + </div>
11 <n-scrollbar>
10 - <Navbar :collapsed="sidebarClosed" mode="vertical" />
12 + <div :class="{ 'px-2': !sidebarClosed }" class="transition-all">
13 + <Navbar :collapsed="sidebarClosed" mode="vertical" />
14 + </div>
15 </n-scrollbar>
12 - <SidebarFooter :collapsed="sidebarClosed" />
16 + <div class="p-2">
17 + <SidebarFooter :collapsed="sidebarClosed" />
18 + </div>
19 </div>
20 </aside>
21 </template>
@@ -90,7 +96,7 @@ onMounted(() => {
96
97 @media (max-width: $sidebar-bp) {
98 &.opened {
93 - z-index: 4;
99 + z-index: 2100;
100 transform: translateX(0);
101 box-shadow: 0px 0px 80px 0px rgba(0, 0, 0, 0.2);
102 }
frontend/src/app-layouts/HorizontalNav/SidebarFooter.vue
+2 -20
@@ -1,6 +1,6 @@
1 <template>
2 - <div class="sidebar-footer" :class="{ collapsed }">
3 - <n-menu :options="menuOptions" :collapsed="collapsed" :collapsed-width="collapsedWidth" />
2 + <div class="bg-body rounded-lg py-0.5" :class="{ collapsed }">
3 + <n-menu :options="menuOptions" :collapsed :collapsed-width :indent="18" />
4 </div>
5 </template>
6
@@ -33,21 +33,3 @@ const menuOptions = ref([
33 const themeStore = useThemeStore()
34 const collapsedWidth = computed<number>(() => themeStore.sidebar.closeWidth - 16)
35 </script>
36 -
37 -<style lang="scss" scoped>
38 -.sidebar-footer {
39 - margin: 8px;
40 - background-color: var(--bg-body-color);
41 - border-radius: var(--border-radius);
42 - padding: 3px 0;
43 - transition: all 0.3s;
44 -
45 - :deep() {
46 - .n-menu {
47 - .n-menu-item-content.n-menu-item-content--selected::before {
48 - background-color: transparent !important;
49 - }
50 - }
51 - }
52 -}
53 -</style>
frontend/src/app-layouts/HorizontalNav/SidebarHeader.vue
+13 -3
@@ -1,7 +1,17 @@
1 <template>
2 - <div class="sidebar-header flex items-center justify-between gap-4 px-4">
3 - <div class="grow">
4 - <Logo :mini="logoMini" :dark="isDark" />
2 + <div class="sidebar-header flex items-center justify-between gap-4">
3 + <div class="flex grow" :class="{ 'justify-center': logoMini }">
4 + <Logo
5 + v-if="logoMini"
6 + mini
7 + :dark="isDark"
8 + class="animate-[fade_calc(var(--sidebar-anim-duration)_*_2)_forwards_calc(var(--sidebar-anim-duration)_/_2)] opacity-0"
9 + />
10 + <Logo
11 + v-if="!logoMini"
12 + :dark="isDark"
13 + class="animate-[fade_calc(var(--sidebar-anim-duration)_*_2)_forwards_calc(var(--sidebar-anim-duration)_/_2)] opacity-0"
14 + />
15 </div>
16 <Transition name="fade" mode="out-in">
17 <div v-if="showPin" class="sidebar-pin flex items-center">
frontend/src/app-layouts/common/Logo.vue
+1 -11
@@ -22,7 +22,7 @@ const {
22 dark,
23 maxHeight = "32px"
24 } = defineProps<{
25 - mini: boolean
25 + mini?: boolean
26 dark?: boolean
27 maxHeight?: string
28 }>()
@@ -42,15 +42,5 @@ const isLight = computed<boolean>(() => !dark || themeStore.isThemeLight)
42 display: block;
43 height: 100%;
44 }
45 -
46 - &.fade-enter-active,
47 - &.fade-leave-active {
48 - transition: opacity var(--sidebar-anim-ease) var(--sidebar-anim-duration);
49 - }
50 -
51 - &.fade-enter-from,
52 - &.fade-leave-to {
53 - opacity: 0;
54 - }
45 }
46 </style>
frontend/src/app-layouts/common/Navbar/Navbar.vue
+6 -106
@@ -6,8 +6,9 @@
6 :options="menuOptions"
7 :collapsed
8 :mode
9 + :indent="18"
10 accordion
10 - :collapsed-width="collapsedWidth"
11 + :collapsed-width
12 :dropdown-props="{
13 scrollable: true,
14 menuProps: () => ({
@@ -95,75 +96,18 @@ function handleUpdateExpandedKeys(value: string[]) {
96 }
97
98 :deep() {
98 - .n-menu-item {
99 - .n-menu-item-content {
100 - gap: 8px;
101 -
102 - .n-menu-item-content__icon {
103 - margin-right: 0 !important;
104 - }
105 - }
106 - }
107 - .n-menu-item-content,
108 - .n-menu-item-group {
109 - .item-badge {
110 - display: flex;
111 - justify-content: space-between;
112 - align-items: center;
113 - gap: 10px;
114 -
115 - :nth-child(1) {
116 - overflow: hidden;
117 - white-space: nowrap;
118 - text-overflow: ellipsis;
119 - }
120 -
121 - :nth-child(2) {
122 - color: var(--fg-default-color);
123 - background: var(--hover-color);
124 - height: 22px;
125 - line-height: 24px;
126 - border-radius: 15px;
127 - padding: 0 7px;
128 - font-weight: bold;
129 - font-size: 13px;
130 - font-family: var(--font-family-mono);
131 - }
132 - }
133 -
134 - &.n-menu-item-content--selected,
135 - &.n-menu-item-content--child-active {
136 - .item-badge {
137 - :nth-child(2) {
138 - color: var(--n-item-text-color-active);
139 - background: var(--n-item-color-active);
140 - }
141 - }
142 - }
143 - }
144 -
99 .n-menu-item-group {
100 .n-menu-item-group-title {
101 white-space: nowrap;
102 overflow: hidden;
103 text-overflow: ellipsis;
104 }
151 - .item-badge {
152 - :nth-child(2) {
153 - font-size: 10px;
154 - margin-right: 0px;
155 - height: 20px;
156 - line-height: 20px;
157 - border-radius: 8px;
158 - padding: 0 6px;
159 - }
160 - }
105 }
106
107 .n-submenu-children {
164 - --dash-width: 12px;
108 + --dash-width: 8px;
109 --dash-height: 2px;
166 - --dash-offset: 43px;
110 + --dash-offset: 29px;
111
112 position: relative;
113
@@ -194,7 +138,7 @@ function handleUpdateExpandedKeys(value: string[]) {
138
139 .n-menu-item-group {
140 .n-menu-item-group-title {
197 - padding-left: 64px !important;
141 + padding-left: 44px !important;
142 }
143 }
144
@@ -231,51 +175,7 @@ function handleUpdateExpandedKeys(value: string[]) {
175 .nav {
176 :deep() {
177 .n-submenu-children {
234 - --dash-offset: 39px;
235 - }
236 - }
237 - }
238 -}
239 -</style>
240 -
241 -<style lang="scss">
242 -.main-nav {
243 - .n-dropdown-option-body,
244 - .n-dropdown-option-body--group,
245 - .n-dropdown-option-body__label {
246 - .item-badge {
247 - display: flex;
248 - justify-content: space-between;
249 - align-items: center;
250 - gap: 12px;
251 -
252 - :nth-child(1) {
253 - overflow: hidden;
254 - white-space: nowrap;
255 - text-overflow: ellipsis;
256 - }
257 -
258 - :nth-child(2) {
259 - color: var(--fg-default-color);
260 - background: var(--hover-color);
261 - font-weight: bold;
262 - font-family: var(--font-family-mono);
263 - font-size: 10px;
264 - margin-right: 0px;
265 - height: 20px;
266 - line-height: 20px;
267 - border-radius: 8px;
268 - padding: 0 6px;
269 - }
270 - }
271 -
272 - &.n-dropdown-option-body--selected,
273 - &.n-dropdown-option-body--child-active {
274 - .item-badge {
275 - :nth-child(2) {
276 - color: var(--n-item-text-color-active);
277 - background: rgba(var(--primary-color-rgb) / 0.1);
278 - }
178 + --dash-offset: 25px;
179 }
180 }
181 }
frontend/src/app-layouts/common/Provider.vue
+3 -3
@@ -1,14 +1,14 @@
1 <template>
2 <n-config-provider
3 :rtl="rtlOptions"
4 - :theme="theme"
5 - :theme-overrides="themeOverrides"
4 + :theme
5 + :theme-overrides
6 :locale="providerLocale"
7 :date-locale="providerDateLocale"
8 preflight-style-disabled
9 inline-theme-disabled
10 >
11 - <n-loading-bar-provider container-class="!h-0.75">
11 + <n-loading-bar-provider container-class="h-0.75!">
12 <n-message-provider>
13 <n-notification-provider>
14 <n-dialog-provider>
frontend/src/app-layouts/common/Toolbar/Avatar.vue
+1 -1
@@ -1,5 +1,5 @@
1 <template>
2 - <n-dropdown :options="options" placement="bottom-end" @select="handleSelect">
2 + <n-dropdown :options placement="bottom-end" @select="handleSelect">
3 <n-avatar round :size="32" :src="userPic" :img-props="{ alt: 'avatar' }" />
4 </n-dropdown>
5 </template>
frontend/src/app-layouts/common/Toolbar/BlurEffect.vue new
+52
@@ -0,0 +1,52 @@
1 +<template>
2 + <div class="blur-effect">
3 + <div v-for="n in 8" :key="n"></div>
4 + </div>
5 +</template>
6 +
7 +<style lang="scss" scoped>
8 +.blur-effect {
9 + position: absolute;
10 + width: 100%;
11 + height: 100%;
12 + top: 0;
13 + left: 0;
14 + z-index: 0;
15 +
16 + // Function to generate blur gradient
17 + @function blur-gradient($start, $mid1, $mid2, $end) {
18 + @return linear-gradient(
19 + to top,
20 + rgba(0, 0, 0, 0) $start,
21 + rgba(0, 0, 0, 1) $mid1,
22 + rgba(0, 0, 0, 1) $mid2,
23 + rgba(0, 0, 0, 0) $end
24 + );
25 + }
26 +
27 + & > div {
28 + position: absolute;
29 + inset: 0;
30 + z-index: 1;
31 + pointer-events: none;
32 + }
33 +
34 + // Generate blur effects with incremental values
35 + @for $i from 1 through 8 {
36 + $blur: 1px * pow(1.6, $i - 1);
37 + $start: ($i - 1) * 12.5%;
38 + $mid1: $i * 12.5%;
39 + $mid2: ($i + 1) * 12.5%;
40 + $end: ($i + 2) * 12.5%;
41 +
42 + & > div:nth-child(#{$i}) {
43 + backdrop-filter: blur($blur);
44 + @if $i < 8 {
45 + mask-image: blur-gradient($start, $mid1, $mid2, $end);
46 + } @else {
47 + mask-image: linear-gradient(to top, rgba(0, 0, 0, 0) 87.5%, rgba(0, 0, 0, 1) 100%);
48 + }
49 + }
50 + }
51 +}
52 +</style>
frontend/src/app-layouts/common/Toolbar/FullscreenSwitch.vue
+6 -21
@@ -1,5 +1,10 @@
1 <template>
2 - <button class="fullscreen-switch" alt="fullscreen-switch" aria-label="fullscreen-switch" @click="toggleFullscreen">
2 + <button
3 + class="hidden cursor-pointer items-center justify-center lg:flex"
4 + alt="fullscreen-switch"
5 + aria-label="fullscreen-switch"
6 + @click="toggle()"
7 + >
8 <Icon v-if="isFullscreen" :size="20" :name="CloseIcon" />
9 <Icon v-else :size="20" :name="OpenIcon" />
10 </button>
@@ -12,24 +17,4 @@ import { useFullscreenSwitch } from "@/composables/useFullscreenSwitch"
17 const { isFullscreen, toggle } = useFullscreenSwitch()
18 const OpenIcon = "fluent:full-screen-maximize-24-regular"
19 const CloseIcon = "fluent:full-screen-minimize-24-regular"
15 -
16 -function toggleFullscreen(e?: MouseEvent) {
17 - toggle()
18 - return e
19 -}
20 </script>
21 -
22 -<style scoped lang="scss">
23 -.fullscreen-switch {
24 - position: relative;
25 - width: 20px;
26 - height: 20px;
27 - overflow: hidden;
28 - outline: none;
29 - border: none;
30 -
31 - @media (max-width: 1000px) {
32 - display: none;
33 - }
34 -}
35 -</style>
frontend/src/app-layouts/common/Toolbar/LocaleSwitch.vue
+4 -21
@@ -11,12 +11,12 @@ import Icon from "@/components/common/Icon.vue"
11 import { useLocalesStore } from "@/stores/i18n"
12 import { NPopselect } from "naive-ui"
13 import { computed, h } from "vue"
14 +import { useI18n } from "vue-i18n"
15
16 const MultiLanguageIcon = "ion:language-outline"
16 -
17 const localesStore = useLocalesStore()
18 -
19 -const { setLocale, t } = localesStore
18 +const { setLocale } = localesStore
19 +const { t } = useI18n()
20
21 const list = computed(() =>
22 localesStore.availableLocales.map(i => ({
@@ -44,24 +44,7 @@ function renderLabel(option: SelectOption): VNodeChild {
44 "span",
45 {},
46 {
47 - default: () => {
48 - switch (option.label) {
49 - case "it":
50 - return t("italian")
51 - case "en":
52 - return t("english")
53 - case "es":
54 - return t("spanish")
55 - case "fr":
56 - return t("french")
57 - case "de":
58 - return t("german")
59 - case "jp":
60 - return t("japanese")
61 - default:
62 - return option.label
63 - }
64 - }
47 + default: () => t(`locales.${option.label}`, `${option.label}`)
48 }
49 )
50 ]
frontend/src/app-layouts/common/Toolbar/Notifications.vue
+6 -6
@@ -1,15 +1,15 @@
1 <template>
2 - <n-popover :show-arrow="false" placement="bottom" content-class="!p-0 w-72">
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="text-default" />
6 </n-badge>
7 </template>
8 <template #header>
9 - <n-text strong depth="1">Notifications</n-text>
9 + <div class="font-semibold">Notifications</div>
10 </template>
11 <template #default>
12 - <NotificationsList :max-items="MAX_ITEMS" class="max-h-50vh">
12 + <NotificationsList :max-items="MAX_ITEMS" class="max-h-[50vh]">
13 <template #last>
14 <div v-if="list.length > MAX_ITEMS" class="flex justify-center p-4">
15 <n-button text @click="showDrawer = true">View all</n-button>
@@ -22,8 +22,8 @@
22 </template>
23 </n-popover>
24
25 - <n-drawer v-model:show="showDrawer" :width="400" class="max-w-90vw" :trap-focus="false">
26 - <n-drawer-content title="Notifications" closable body-content-class="!p-0">
25 + <n-drawer v-model:show="showDrawer" :width="400" class="max-w-[90vw]" :trap-focus="false">
26 + <n-drawer-content title="Notifications" closable body-content-class="p-0!">
27 <NotificationsList />
28 <template #footer>
29 <NotificationsToolbar />
@@ -39,7 +39,7 @@ import NotificationsToolbar from "@/components/common/Notifications/Toolbar.vue"
39 import { useHealthchecksNotify } from "@/composables/useHealthchecksNotify"
40 import { useNotifications } from "@/composables/useNotifications"
41 import { useThemeStore } from "@/stores/theme"
42 -import { NBadge, NButton, NDrawer, NDrawerContent, NPopover, NText } from "naive-ui"
42 +import { NBadge, NButton, NDrawer, NDrawerContent, NPopover } from "naive-ui"
43 import { computed, onBeforeMount, ref } from "vue"
44
45 const MAX_ITEMS = 7
frontend/src/app-layouts/common/Toolbar/PillWrapper.vue new
+17
@@ -0,0 +1,17 @@
1 +<template>
2 + <div class="pill-wrapper flex items-center">
3 + <slot />
4 + </div>
5 +</template>
6 +
7 +<style lang="scss" scoped>
8 +.pill-wrapper {
9 + background-color: var(--bg-sidebar-color);
10 + border: 1px solid var(--border-color);
11 + color: var(--fg-default-color);
12 + border-radius: 50px;
13 + padding: 6px;
14 + transition: all 0.3s;
15 + gap: 14px;
16 +}
17 +</style>
frontend/src/app-layouts/common/Toolbar/PinnedPagesV2.vue renamed
frontend/src/app-layouts/common/Toolbar/Toolbar.vue
+57 -109
@@ -9,51 +9,44 @@
9 <Breadcrumb class="grow" />
10 <PinnedPages />
11
12 - <div class="bubble flex items-center">
12 + <PillWrapper>
13 <Search />
14 <FullscreenSwitch />
15 <ThemeSwitch />
16 <Notifications />
17 <Avatar />
18 - </div>
18 + </PillWrapper>
19 </div>
20 +
21 + <BlurEffect />
22 + <div v-if="gradient" :class="`gradient-${gradient}`"></div>
23 </header>
24 </template>
25
26 <script lang="ts" setup>
27 import Icon from "@/components/common/Icon.vue"
25 -import { useMainStore } from "@/stores/main"
28 +import { useLoadingBarSetup } from "@/composables/useLoadingBarSetup"
29 import { useThemeStore } from "@/stores/theme"
27 -import { useLoadingBar } from "naive-ui"
28 -import { onMounted } from "vue"
29 -import { useRouter } from "vue-router"
30 import Logo from "../Logo.vue"
31 import Avatar from "./Avatar.vue"
32 +import BlurEffect from "./BlurEffect.vue"
33 import Breadcrumb from "./Breadcrumb.vue"
34 import FullscreenSwitch from "./FullscreenSwitch.vue"
35 import Notifications from "./Notifications.vue"
35 -import PinnedPages from "./PinnedPages.vue"
36 +import PillWrapper from "./PillWrapper.vue"
37 +import PinnedPages from "./PinnedPagesV2.vue"
38 import Search from "./Search.vue"
39 import ThemeSwitch from "./ThemeSwitch.vue"
40
39 -const { boxed } = defineProps<{
41 +const { boxed, gradient } = defineProps<{
42 boxed: boolean
43 + gradient?: "body" | "sidebar"
44 }>()
45
43 -const router = useRouter()
46 const themeStore = useThemeStore()
45 -const mainStore = useMainStore()
47 +const openNav = () => themeStore.openSidebar()
48
47 -function openNav() {
48 - themeStore.openSidebar()
49 -}
50 -
51 -onMounted(() => {
52 - const loadingBar = useLoadingBar()
53 - router.beforeEach(() => loadingBar?.start())
54 - router.afterEach(() => loadingBar?.finish())
55 - mainStore.setLoadingBar(loadingBar)
56 -})
49 +useLoadingBarSetup()
50 </script>
51
52 <style lang="scss" scoped>
@@ -68,42 +61,13 @@ onMounted(() => {
61 z-index: 3;
62 overflow: hidden;
63
71 - &::after {
72 - content: "";
73 - width: 100%;
74 - height: 100%;
75 - position: absolute;
76 - display: block;
77 - top: 0;
78 - left: 0;
79 - z-index: -2;
80 - backdrop-filter: blur(20px);
81 - mask-image: linear-gradient(
82 - to bottom,
83 - rgba(0, 0, 0, 1) 0%,
84 - rgba(0, 0, 0, 0.96) 70%,
85 - rgba(0, 0, 0, 0.8) 80%,
86 - rgba(0, 0, 0, 0) 100%
87 - );
88 - }
89 -
64 .wrap {
65 height: var(--toolbar-height);
66 overflow: hidden;
67 width: 100%;
68 max-width: 100%;
69 position: relative;
96 - z-index: 0;
97 -
98 - .bubble {
99 - background-color: var(--bg-sidebar-color);
100 - border: 1px solid var(--border-color);
101 - color: var(--fg-default-color);
102 - border-radius: 50px;
103 - padding: 6px;
104 - transition: all 0.3s;
105 - gap: 14px;
106 - }
70 + z-index: 1;
71
72 @media (max-width: 850px) {
73 .pinned-pages {
@@ -128,66 +92,50 @@ onMounted(() => {
92 }
93 }
94
131 - &.gradient-bg-sidebar {
132 - &::before {
133 - content: "";
134 - width: 100%;
135 - height: 100%;
136 - position: absolute;
137 - display: block;
138 - top: 0;
139 - left: 0;
140 - z-index: -1;
141 - background-color: var(--bg-sidebar-color);
142 - background: linear-gradient(
143 - to bottom,
144 - rgba(var(--bg-sidebar-color-rgb) / 1) 0%,
145 - rgba(var(--bg-sidebar-color-rgb) / 0.945) 8.6%,
146 - rgba(var(--bg-sidebar-color-rgb) / 0.888) 16.2%,
147 - rgba(var(--bg-sidebar-color-rgb) / 0.83) 22.9%,
148 - rgba(var(--bg-sidebar-color-rgb) / 0.769) 28.9%,
149 - rgba(var(--bg-sidebar-color-rgb) / 0.707) 34.4%,
150 - rgba(var(--bg-sidebar-color-rgb) / 0.644) 39.5%,
151 - rgba(var(--bg-sidebar-color-rgb) / 0.578) 44.5%,
152 - rgba(var(--bg-sidebar-color-rgb) / 0.511) 49.5%,
153 - rgba(var(--bg-sidebar-color-rgb) / 0.443) 54.7%,
154 - rgba(var(--bg-sidebar-color-rgb) / 0.373) 60.3%,
155 - rgba(var(--bg-sidebar-color-rgb) / 0.301) 66.4%,
156 - rgba(var(--bg-sidebar-color-rgb) / 0.228) 73.3%,
157 - rgba(var(--bg-sidebar-color-rgb) / 0.153) 81%,
158 - rgba(var(--bg-sidebar-color-rgb) / 0.077) 89.9%,
159 - rgba(var(--bg-sidebar-color-rgb) / 0) 100%
160 - );
161 - }
95 + .gradient-sidebar {
96 + position: absolute;
97 + inset: 0;
98 + background-color: var(--bg-sidebar-color);
99 + background: linear-gradient(
100 + to bottom,
101 + rgba(var(--bg-sidebar-color-rgb) / 1) 0%,
102 + rgba(var(--bg-sidebar-color-rgb) / 0.945) 8.6%,
103 + rgba(var(--bg-sidebar-color-rgb) / 0.888) 16.2%,
104 + rgba(var(--bg-sidebar-color-rgb) / 0.83) 22.9%,
105 + rgba(var(--bg-sidebar-color-rgb) / 0.769) 28.9%,
106 + rgba(var(--bg-sidebar-color-rgb) / 0.707) 34.4%,
107 + rgba(var(--bg-sidebar-color-rgb) / 0.644) 39.5%,
108 + rgba(var(--bg-sidebar-color-rgb) / 0.578) 44.5%,
109 + rgba(var(--bg-sidebar-color-rgb) / 0.511) 49.5%,
110 + rgba(var(--bg-sidebar-color-rgb) / 0.443) 54.7%,
111 + rgba(var(--bg-sidebar-color-rgb) / 0.373) 60.3%,
112 + rgba(var(--bg-sidebar-color-rgb) / 0.301) 66.4%,
113 + rgba(var(--bg-sidebar-color-rgb) / 0.228) 73.3%,
114 + rgba(var(--bg-sidebar-color-rgb) / 0.153) 81%,
115 + rgba(var(--bg-sidebar-color-rgb) / 0.077) 89.9%,
116 + rgba(var(--bg-sidebar-color-rgb) / 0) 100%
117 + );
118 }
163 - &.gradient-bg-body {
164 - &::before {
165 - content: "";
166 - width: 100%;
167 - height: 100%;
168 - position: absolute;
169 - display: block;
170 - top: 0;
171 - left: 0;
172 - z-index: -1;
173 - background-color: var(--bg-body-color);
174 - background: linear-gradient(
175 - to bottom,
176 - rgba(var(--bg-body-color-rgb) / 1) 0%,
177 - rgba(var(--bg-body-color-rgb) / 0.738) 19%,
178 - rgba(var(--bg-body-color-rgb) / 0.541) 34%,
179 - rgba(var(--bg-body-color-rgb) / 0.382) 47%,
180 - rgba(var(--bg-body-color-rgb) / 0.278) 56.5%,
181 - rgba(var(--bg-body-color-rgb) / 0.194) 65%,
182 - rgba(var(--bg-body-color-rgb) / 0.126) 73%,
183 - rgba(var(--bg-body-color-rgb) / 0.075) 80.2%,
184 - rgba(var(--bg-body-color-rgb) / 0.042) 86.1%,
185 - rgba(var(--bg-body-color-rgb) / 0.021) 91%,
186 - rgba(var(--bg-body-color-rgb) / 0.008) 95.2%,
187 - rgba(var(--bg-body-color-rgb) / 0.002) 98.2%,
188 - rgba(var(--bg-body-color-rgb) / 0) 100%
189 - );
190 - }
119 + .gradient-body {
120 + position: absolute;
121 + inset: 0;
122 + background-color: var(--bg-body-color);
123 + background: linear-gradient(
124 + to bottom,
125 + rgba(var(--bg-body-color-rgb) / 1) 0%,
126 + rgba(var(--bg-body-color-rgb) / 0.738) 19%,
127 + rgba(var(--bg-body-color-rgb) / 0.541) 34%,
128 + rgba(var(--bg-body-color-rgb) / 0.382) 47%,
129 + rgba(var(--bg-body-color-rgb) / 0.278) 56.5%,
130 + rgba(var(--bg-body-color-rgb) / 0.194) 65%,
131 + rgba(var(--bg-body-color-rgb) / 0.126) 73%,
132 + rgba(var(--bg-body-color-rgb) / 0.075) 80.2%,
133 + rgba(var(--bg-body-color-rgb) / 0.042) 86.1%,
134 + rgba(var(--bg-body-color-rgb) / 0.021) 91%,
135 + rgba(var(--bg-body-color-rgb) / 0.008) 95.2%,
136 + rgba(var(--bg-body-color-rgb) / 0.002) 98.2%,
137 + rgba(var(--bg-body-color-rgb) / 0) 100%
138 + );
139 }
140 }
141
frontend/src/assets/scss/index.scss
-215
@@ -1,221 +1,6 @@
1 @use "sass:meta";
2 -@tailwind base;
3 -@tailwind components;
4 -@tailwind utilities;
5 -
2 @include meta.load-css("fonts");
3 @include meta.load-css("common");
4 @include meta.load-css("common-animations");
5 @include meta.load-css("router-animations");
6 @include meta.load-css("overrides/naive-override");
11 -
12 -html,
13 -body {
14 - text-size-adjust: 100%;
15 - -webkit-tap-highlight-color: transparent;
16 - -webkit-touch-callout: none;
17 - -webkit-font-smoothing: antialiased;
18 - -moz-osx-font-smoothing: grayscale;
19 - text-rendering: optimizeLegibility;
20 - line-height: 1.35;
21 - font-size: var(--font-size);
22 - text-wrap: pretty;
23 -
24 - margin: 0;
25 - padding: 0;
26 - box-sizing: border-box;
27 -
28 - width: 100vw;
29 - width: 100dvw;
30 - height: 100vh;
31 - height: 100dvh;
32 - overflow: hidden;
33 -
34 - &:focus {
35 - outline: none;
36 - }
37 -}
38 -
39 -[v-cloak] {
40 - display: none !important;
41 -}
42 -
43 -::view-transition-old(root),
44 -::view-transition-new(root) {
45 - animation: none;
46 - mix-blend-mode: normal;
47 -}
48 -::view-transition-old(root) {
49 - z-index: 1;
50 -}
51 -::view-transition-new(root) {
52 - z-index: 99999;
53 -}
54 -
55 -::selection {
56 - background-color: rgba(var(--primary-color-rgb) / 0.2);
57 -}
58 -
59 -#app {
60 - width: 100vw;
61 - height: 100vh;
62 - overflow: auto;
63 -}
64 -
65 -svg {
66 - touch-action: initial !important;
67 -}
68 -
69 -input {
70 - accent-color: var(--primary-color);
71 -}
72 -
73 -p {
74 - color: var(--fg-secondary-color);
75 -}
76 -
77 -code,
78 -kbd,
79 -samp,
80 -pre {
81 - font-family: var(--font-family-mono);
82 -}
83 -
84 -code {
85 - padding: 1px 6px;
86 - border-radius: var(--border-radius-small);
87 - background-color: rgba(var(--hover-color-rgb) / 0.4);
88 - font-size: 13px;
89 -}
90 -pre {
91 - border-radius: var(--border-radius-small);
92 -
93 - code {
94 - padding: 12px;
95 - display: block;
96 - overflow-x: auto;
97 - }
98 -}
99 -
100 -a {
101 - text-decoration: underline;
102 - text-decoration-color: var(--primary-color);
103 -}
104 -
105 -blockquote {
106 - display: block;
107 - padding-left: 1em;
108 - border-left: 4px solid var(--border-color);
109 -}
110 -
111 -dl {
112 - dt {
113 - font-weight: bold;
114 - margin-bottom: 2px;
115 - }
116 -
117 - & > dd:not(:last-child) {
118 - margin-bottom: 10px;
119 - }
120 -}
121 -
122 -ul {
123 - display: block;
124 - list-style-type: disc;
125 - padding-left: 20px;
126 - line-height: 1.6;
127 -
128 - ul {
129 - list-style-type: circle;
130 - margin-top: 3px;
131 - margin-bottom: 6px;
132 - }
133 -}
134 -
135 -ol {
136 - display: block;
137 - list-style-type: decimal;
138 - padding-left: 20px;
139 - line-height: 1.6;
140 -
141 - ol {
142 - list-style-type: decimal;
143 - margin-top: 3px;
144 - margin-bottom: 6px;
145 - }
146 -}
147 -
148 -mark {
149 - padding: 2px 0px;
150 - border-radius: var(--border-radius-small);
151 - background-color: rgba(var(--primary-color-rgb) / 0.3);
152 - color: var(--fg-default-color);
153 -}
154 -
155 -@media print {
156 - html,
157 - body {
158 - overflow: initial;
159 - }
160 - body {
161 - #app {
162 - height: initial;
163 - background-color: white;
164 -
165 - & > .n-config-provider {
166 - & > .layout {
167 - display: block;
168 - height: initial;
169 - background-color: white;
170 -
171 - & > .header-bar {
172 - display: none;
173 - }
174 - & > .main {
175 - background-color: white;
176 - overflow: initial;
177 - height: initial;
178 -
179 - header.toolbar {
180 - display: none;
181 - }
182 - footer.footer {
183 - display: none;
184 - }
185 -
186 - & > .n-scrollbar {
187 - overflow: initial;
188 - height: initial;
189 -
190 - & > .n-scrollbar-container {
191 - overflow: initial;
192 - height: initial;
193 - }
194 - }
195 - }
196 - }
197 - }
198 - }
199 - }
200 -}
201 -
202 -html.theme-dark .shiki,
203 -html.theme-dark .shiki span {
204 - color: var(--shiki-dark) !important;
205 - //background-color: var(--shiki-dark-bg) !important;
206 - /* Optional, if you also want font styles */
207 - font-style: var(--shiki-dark-font-style) !important;
208 - font-weight: var(--shiki-dark-font-weight) !important;
209 - text-decoration: var(--shiki-dark-text-decoration) !important;
210 -}
211 -html.theme-dark,
212 -html.theme-light {
213 - .shiki {
214 - overflow: hidden;
215 - background-color: transparent !important;
216 -
217 - span {
218 - background-color: transparent !important;
219 - }
220 - }
221 -}
frontend/src/assets/scss/overrides/naive-override.scss
+77 -22
@@ -46,9 +46,7 @@
46 }
47
48 .n-badge {
49 - .n-badge-sup {
50 - top: inherit;
51 - }
49 + direction: ltr;
50 }
51
52 .n-dropdown-menu {
@@ -109,6 +107,82 @@
107 }
108 }
109
110 +.n-form-item {
111 + .n-form-item-feedback-wrapper:not(:empty) {
112 + transform: translateY(-7px);
113 + padding-left: 0px !important;
114 + padding-right: 0px !important;
115 + padding-top: 0 !important;
116 + z-index: 1;
117 +
118 + .n-form-item-feedback {
119 + font-size: 13px;
120 + line-height: 1.2;
121 + padding: 3px 12px;
122 + border-bottom-left-radius: var(--border-radius);
123 + border-bottom-right-radius: var(--border-radius);
124 + background: color-mix(in srgb, currentColor 5%, var(--bg-default-color) 95%);
125 + border: 1px solid currentColor;
126 + border-top: 0;
127 + }
128 + }
129 +
130 + &.n-form-item--small-size {
131 + .n-form-item-feedback-wrapper:not(:empty) {
132 + transform: translateY(-6px);
133 +
134 + .n-form-item-feedback {
135 + font-size: 11px;
136 + padding: 3px 10px;
137 + }
138 + }
139 + }
140 +
141 + &.n-form-item--small-large {
142 + .n-form-item-feedback-wrapper:not(:empty) {
143 + .n-form-item-feedback {
144 + padding: 3px 14px;
145 + }
146 + }
147 + }
148 +
149 + .n-form-item-blank--error {
150 + .n-upload-dragger {
151 + border-color: var(--n-feedback-text-color-error);
152 + }
153 + .n-upload-file-list:not(:empty) {
154 + margin-bottom: 24px;
155 + }
156 + }
157 +}
158 +
159 +.n-menu {
160 + .n-menu-item {
161 + .n-menu-item-content {
162 + gap: 16px;
163 +
164 + .n-menu-item-content__icon {
165 + margin-right: 0 !important;
166 + margin-left: 0 !important;
167 + }
168 + }
169 + }
170 + .n-menu-item-group {
171 + .n-menu-item-group-title {
172 + padding-left: 22px !important;
173 + padding-right: 22px !important;
174 + }
175 + }
176 +
177 + &.n-menu--horizontal {
178 + .n-menu-item {
179 + .n-menu-item-content {
180 + gap: 8px;
181 + }
182 + }
183 + }
184 +}
185 +
186 .n-space.n-space--rtl {
187 .n-layout {
188 aside.n-layout-sider.n-layout-sider--left-placement.n-layout-sider--bordered {
@@ -139,25 +213,6 @@
213 .n-menu {
214 direction: rtl;
215
142 - .n-menu-item {
143 - .n-menu-item-content {
144 - padding-left: unset;
145 - padding-right: 32px;
146 - gap: 8px;
147 -
148 - .n-menu-item-content__icon {
149 - margin-right: unset !important;
150 - }
151 - }
152 - }
153 -
154 - .n-menu-item-group {
155 - .n-menu-item-group-title {
156 - padding-right: 32px;
157 - padding-left: 0 !important;
158 - }
159 - }
160 -
216 &.n-menu--collapsed {
217 .n-menu-item {
218 .n-menu-item-content {
frontend/src/components/agents/AgentCard.vue
+6 -6
@@ -149,9 +149,9 @@ function toggleCritical(agentId: string, criticalStatus: boolean) {
149
150 .wrapper {
151 display: flex;
152 - @apply gap-6;
152 flex-direction: row;
153 align-items: center;
154 + gap: calc(var(--spacing) * 6);
155 overflow: hidden;
156
157 .agent-header {
@@ -162,7 +162,7 @@ function toggleCritical(agentId: string, criticalStatus: boolean) {
162 .title {
163 display: flex;
164 align-items: center;
165 - @apply gap-2;
165 + gap: calc(var(--spacing) * 2);
166 margin-bottom: 4px;
167
168 .hostname {
@@ -192,7 +192,7 @@ function toggleCritical(agentId: string, criticalStatus: boolean) {
192 }
193 .info {
194 font-family: var(--font-family-mono);
195 - @apply text-xs;
195 + font-size: var(--text-xs);
196 opacity: 0.7;
197 white-space: nowrap;
198 overflow: hidden;
@@ -217,7 +217,7 @@ function toggleCritical(agentId: string, criticalStatus: boolean) {
217 }
218 .ip-address {
219 white-space: nowrap;
220 - @apply text-xs;
220 + font-size: var(--text-xs);
221 font-family: var(--font-family-mono);
222 opacity: 0.7;
223 overflow: hidden;
@@ -236,7 +236,7 @@ function toggleCritical(agentId: string, criticalStatus: boolean) {
236
237 @container (max-width: 550px) {
238 .wrapper {
239 - @apply gap-5;
239 + gap: calc(var(--spacing) * 5);
240
241 .agent-header {
242 min-width: initial;
@@ -245,7 +245,7 @@ function toggleCritical(agentId: string, criticalStatus: boolean) {
245 }
246 @container (max-width: 400px) {
247 .wrapper {
248 - @apply gap-4;
248 + gap: calc(var(--spacing) * 4);
249
250 .agent-header {
251 flex-grow: 1;
frontend/src/components/agents/AgentToolbar.vue
+5 -4
@@ -201,20 +201,21 @@ function load() {
201 }
202 .agents-list {
203 .title {
204 - @apply mb-2;
204 + margin-bottom: calc(var(--spacing) * 2);
205 }
206
207 .list {
208 .item {
209 border: 2px solid transparent;
210 - @apply px-3 py-2;
210 + padding-inline: calc(var(--spacing) * 3);
211 + padding-block: calc(var(--spacing) * 2);
212 font-size: 14px;
213 font-weight: bold;
214 cursor: pointer;
215 border-radius: var(--border-radius);
216
217 &:not(:last-child) {
217 - @apply mb-2;
218 + margin-bottom: calc(var(--spacing) * 2);
219 }
220
221 &:hover {
@@ -224,7 +225,7 @@ function load() {
225 }
226
227 .agents-critical-list {
227 - @apply mb-5;
228 + margin-bottom: calc(var(--spacing) * 5);
229
230 .list {
231 .item {
frontend/src/components/agents/vulnerabilities/VulnerabilityCard.vue
+9 -4
@@ -179,7 +179,7 @@ const showDialog = ref(false)
179 cursor: pointer;
180 position: relative;
181 border-radius: var(--border-radius);
182 - @apply py-2;
182 + padding-block: calc(var(--spacing) * 2);
183
184 .severity {
185 position: absolute;
@@ -190,7 +190,9 @@ const showDialog = ref(false)
190 line-height: 1;
191 text-transform: uppercase;
192 font-family: var(--font-family-mono);
193 - @apply px-2 py-0.5 text-xs;
193 + padding-inline: calc(var(--spacing) * 2);
194 + padding-block: calc(var(--spacing) * 0.5);
195 + font-size: var(--text-xs);
196 white-space: nowrap;
197 text-overflow: ellipsis;
198 background-color: var(--bg-default-color);
@@ -213,7 +215,9 @@ const showDialog = ref(false)
215 top: 0;
216 right: 0px;
217 text-align: center;
216 - @apply px-2 py-0.5 text-xs;
218 + padding-inline: calc(var(--spacing) * 2);
219 + padding-block: calc(var(--spacing) * 0.5);
220 + font-size: var(--text-xs);
221 z-index: 2;
222 width: 100%;
223 height: 100%;
@@ -221,7 +225,8 @@ const showDialog = ref(false)
225 }
226
227 .wrapper {
224 - @apply px-4 py-3;
228 + padding-inline: calc(var(--spacing) * 4);
229 + padding-block: calc(var(--spacing) * 3);
230
231 .title {
232 font-weight: bold;
frontend/src/components/auth/ForgotPassword.vue
+18 -16
@@ -1,21 +1,23 @@
1 <template>
2 - <n-form ref="formRef" :model="model" :rules="rules">
3 - <n-form-item path="email" label="Email" first>
4 - <n-input
5 - v-model:value="model.email"
6 - placeholder="Input your email"
7 - size="large"
8 - @keydown.enter="forgotPassword"
9 - />
10 - </n-form-item>
11 - <div class="flex flex-col items-end gap-6">
12 - <div class="w-full">
13 - <n-button type="primary" class="!w-full" size="large" :disabled="!isValid" @click="forgotPassword">
14 - Send Reset Link
15 - </n-button>
2 + <div>
3 + <n-form ref="formRef" :model :rules>
4 + <n-form-item path="email" label="Email" first>
5 + <n-input
6 + v-model:value="model.email"
7 + placeholder="Input your email"
8 + size="large"
9 + @keydown.enter="forgotPassword"
10 + />
11 + </n-form-item>
12 + <div class="flex flex-col items-end gap-6">
13 + <div class="w-full">
14 + <n-button type="primary" class="w-full!" size="large" :disabled="!isValid" @click="forgotPassword">
15 + Send Reset Link
16 + </n-button>
17 + </div>
18 </div>
17 - </div>
18 - </n-form>
19 + </n-form>
20 + </div>
21 </template>
22
23 <script lang="ts" setup>
frontend/src/components/auth/SignIn.vue
+30 -28
@@ -1,33 +1,35 @@
1 <template>
2 - <n-form ref="formRef" :model="model" :rules="rules">
3 - <n-form-item path="username" label="Username">
4 - <n-input
5 - v-model:value="model.username"
6 - placeholder="Insert your Username"
7 - :input-props="{ autocomplete: 'username' }"
8 - size="large"
9 - @keydown.enter="signIn"
10 - />
11 - </n-form-item>
12 - <n-form-item path="password" label="Password">
13 - <n-input
14 - v-model:value="model.password"
15 - type="password"
16 - show-password-on="click"
17 - placeholder="Insert your password"
18 - :input-props="{ autocomplete: 'password' }"
19 - size="large"
20 - @keydown.enter="signIn"
21 - />
22 - </n-form-item>
23 - <div class="flex flex-col items-end gap-6">
24 - <div class="w-full">
25 - <n-button type="primary" class="!w-full" size="large" :loading :disabled="!isValid" @click="signIn">
26 - Sign in
27 - </n-button>
2 + <div>
3 + <n-form ref="formRef" :model :rules>
4 + <n-form-item path="username" label="Username">
5 + <n-input
6 + v-model:value="model.username"
7 + placeholder="Insert your Username"
8 + :input-props="{ autocomplete: 'username' }"
9 + size="large"
10 + @keydown.enter="signIn"
11 + />
12 + </n-form-item>
13 + <n-form-item path="password" label="Password">
14 + <n-input
15 + v-model:value="model.password"
16 + type="password"
17 + show-password-on="click"
18 + placeholder="Insert your password"
19 + :input-props="{ autocomplete: 'password' }"
20 + size="large"
21 + @keydown.enter="signIn"
22 + />
23 + </n-form-item>
24 + <div class="flex flex-col items-end gap-6">
25 + <div class="w-full">
26 + <n-button type="primary" class="w-full!" size="large" :loading :disabled="!isValid" @click="signIn">
27 + Sign in
28 + </n-button>
29 + </div>
30 </div>
29 - </div>
30 - </n-form>
31 + </n-form>
32 + </div>
33 </template>
34
35 <script lang="ts" setup>
frontend/src/components/auth/SignUp.vue
+86 -84
@@ -1,68 +1,69 @@
1 <template>
2 - <n-spin :show="loading">
3 - <n-form ref="formRef" :model="model" :rules="rules">
4 - <n-steps :current="wizardCurrent" vertical>
5 - <n-step title="Account">
6 - <div v-show="wizardCurrent === 1" class="pt-3">
7 - <n-form-item path="email" label="Email" first>
8 - <n-input
9 - v-model:value="model.email"
10 - size="large"
11 - placeholder="Email..."
12 - @keydown.enter="signUp"
13 - />
14 - </n-form-item>
15 - <n-form-item path="password" label="Password" first>
16 - <n-input
17 - v-model:value="model.password"
18 - type="password"
19 - size="large"
20 - show-password-on="click"
21 - placeholder="At least 8 characters"
22 - @keydown.enter="signUp"
23 - />
24 - </n-form-item>
25 - <n-form-item path="confirmPassword" label="Confirm Password" first>
26 - <n-input
27 - v-model:value="model.confirmPassword"
28 - type="password"
29 - :disabled="!model.password"
30 - size="large"
31 - show-password-on="click"
32 - placeholder="At least 8 characters"
33 - @keydown.enter="signUp"
34 - />
35 - </n-form-item>
36 - <div class="mt-3 flex items-center justify-between gap-3">
37 - <n-button secondary size="large" @click="reset(1)">Reset</n-button>
2 + <div>
3 + <n-spin :show="loading">
4 + <n-form ref="formRef" :model :rules>
5 + <n-steps :current="wizardCurrent" vertical>
6 + <n-step title="Account">
7 + <div v-show="wizardCurrent === 1" class="pt-3">
8 + <n-form-item path="email" label="Email" first>
9 + <n-input
10 + v-model:value="model.email"
11 + size="large"
12 + placeholder="Email..."
13 + @keydown.enter="signUp"
14 + />
15 + </n-form-item>
16 + <n-form-item path="password" label="Password" first>
17 + <n-input
18 + v-model:value="model.password"
19 + type="password"
20 + size="large"
21 + show-password-on="click"
22 + placeholder="At least 8 characters"
23 + @keydown.enter="signUp"
24 + />
25 + </n-form-item>
26 + <n-form-item path="confirmPassword" label="Confirm Password" first>
27 + <n-input
28 + v-model:value="model.confirmPassword"
29 + type="password"
30 + :disabled="!model.password"
31 + size="large"
32 + show-password-on="click"
33 + placeholder="At least 8 characters"
34 + @keydown.enter="signUp"
35 + />
36 + </n-form-item>
37 + <div class="mt-3 flex items-center justify-between gap-3">
38 + <n-button secondary size="large" @click="reset(1)">Reset</n-button>
39
39 - <n-button
40 - type="primary"
41 - size="large"
42 - icon-placement="right"
43 - :disabled="!accountStepValid"
44 - @click="wizardCurrent = 2"
45 - >
46 - <template #icon>
47 - <Icon :name="ArrowRightIcon"></Icon>
48 - </template>
49 - Next
50 - </n-button>
40 + <n-button
41 + type="primary"
42 + size="large"
43 + icon-placement="right"
44 + :disabled="!accountStepValid"
45 + @click="wizardCurrent = 2"
46 + >
47 + <template #icon>
48 + <Icon :name="ArrowRightIcon"></Icon>
49 + </template>
50 + Next
51 + </n-button>
52 + </div>
53 </div>
52 - </div>
53 - </n-step>
54 - <n-step title="Details">
55 - <div v-show="wizardCurrent === 2" class="pt-3">
56 - <n-form-item path="username" label="Username" first>
57 - <n-input
58 - v-model:value="model.username"
59 - size="large"
60 - placeholder="Username..."
61 - @keydown.enter="signUp"
62 - />
63 - </n-form-item>
54 + </n-step>
55 + <n-step title="Details">
56 + <div v-show="wizardCurrent === 2" class="pt-3">
57 + <n-form-item path="username" label="Username" first>
58 + <n-input
59 + v-model:value="model.username"
60 + size="large"
61 + placeholder="Username..."
62 + @keydown.enter="signUp"
63 + />
64 + </n-form-item>
65
65 - <!--
66 + <!--
67 <div class="propic flex gap-5 mb-5">
68 <div class="avatar">
69 <n-avatar :size="80" :src="model.propic" round />
@@ -115,34 +116,35 @@
116 </n-form-item>
117 -->
118
118 - <div class="mt-3 flex items-center justify-between gap-3">
119 - <div class="flex items-center justify-between gap-3">
120 - <n-button size="large" @click="wizardCurrent = 1">
119 + <div class="mt-3 flex items-center justify-between gap-3">
120 + <div class="flex items-center justify-between gap-3">
121 + <n-button size="large" @click="wizardCurrent = 1">
122 + <template #icon>
123 + <Icon :name="ArrowLeftIcon"></Icon>
124 + </template>
125 + Back
126 + </n-button>
127 + <n-button secondary size="large" @click="reset(2)">Reset</n-button>
128 + </div>
129 + <n-button
130 + type="success"
131 + size="large"
132 + :loading="loading"
133 + :disabled="!accountStepValid || !detailsStepValid"
134 + @click="signUp"
135 + >
136 <template #icon>
122 - <Icon :name="ArrowLeftIcon"></Icon>
137 + <Icon :name="UserAddIcon"></Icon>
138 </template>
124 - Back
139 + Create account
140 </n-button>
126 - <n-button secondary size="large" @click="reset(2)">Reset</n-button>
141 </div>
128 - <n-button
129 - type="success"
130 - size="large"
131 - :loading="loading"
132 - :disabled="!accountStepValid || !detailsStepValid"
133 - @click="signUp"
134 - >
135 - <template #icon>
136 - <Icon :name="UserAddIcon"></Icon>
137 - </template>
138 - Create account
139 - </n-button>
142 </div>
141 - </div>
142 - </n-step>
143 - </n-steps>
144 - </n-form>
145 - </n-spin>
143 + </n-step>
144 + </n-steps>
145 + </n-form>
146 + </n-spin>
147 + </div>
148 </template>
149
150 <script lang="ts" setup>
frontend/src/components/common/CollapseKeepAlive.vue
+1 -1
@@ -86,7 +86,7 @@ const { show, embedded, arrow, arrowOffset } = defineProps<{
86 opacity: 1;
87
88 &.arrow {
89 - @apply pt-3;
89 + padding-top: calc(var(--spacing) * 3);
90
91 &::after {
92 transform: rotateX(0deg);
frontend/src/components/common/ExpandableText.vue
+1 -1
@@ -42,7 +42,7 @@ function truncate(val: string): string {
42
43 <style lang="scss">
44 .expandable-text-popover {
45 - @apply max-w-96;
45 + max-width: 380px;
46
47 .expandable-text-popover-container {
48 overflow-x: hidden;
frontend/src/components/common/ImageCropper.vue
+1 -1
@@ -3,7 +3,7 @@
3 <slot :open-cropper="openCropper" />
4
5 <n-modal v-model:show="showCropper">
6 - <n-card class="image-cropper-modal flex flex-col" content-class="!p-5">
6 + <n-card class="image-cropper-modal flex flex-col" content-class="p-5!">
7 <div class="aspect-square">
8 <div v-if="!img" class="upload-box">
9 <n-upload v-show="!img" accept="image/*" :show-file-list="false" @change="setImage">
frontend/src/components/common/ListPercentage.vue
+1 -1
@@ -54,7 +54,7 @@ const style = computed(() => themeStore.style)
54 .list-header {
55 & > * {
56 border-bottom: 1px solid var(--border-color);
57 - @apply pb-1;
57 + padding-bottom: calc(var(--spacing) * 1);
58 }
59 }
60 </style>
frontend/src/components/common/LocaleSelect.vue
+4 -19
@@ -11,10 +11,12 @@ import Icon from "@/components/common/Icon.vue"
11 import { useLocalesStore } from "@/stores/i18n"
12 import { NSelect } from "naive-ui"
13 import { computed, h } from "vue"
14 +import { useI18n } from "vue-i18n"
15
16 const localesStore = useLocalesStore()
17
17 -const { setLocale, t } = localesStore
18 +const { setLocale } = localesStore
19 +const { t } = useI18n()
20
21 const list = computed(() =>
22 localesStore.availableLocales.map(i => ({
@@ -42,24 +44,7 @@ function renderLabel(option: SelectOption): VNodeChild {
44 "span",
45 {},
46 {
45 - default: () => {
46 - switch (option.label) {
47 - case "it":
48 - return t("italian")
49 - case "en":
50 - return t("english")
51 - case "es":
52 - return t("spanish")
53 - case "fr":
54 - return t("french")
55 - case "de":
56 - return t("german")
57 - case "jp":
58 - return t("japanese")
59 - default:
60 - return option.label
61 - }
62 - }
47 + default: () => t(`locales.${option.label}`, `${option.label}`)
48 }
49 )
50 ]
frontend/src/components/common/Notifications/List.vue
+18 -13
@@ -5,24 +5,20 @@
5 :key="item.id"
6 class="item flex"
7 :class="[{ pointer: !!item.action }, item.type]"
8 - @click="item.action ? preformAction(item.id, item.action) : () => {}"
8 + @click.stop="item.action ? preformAction(item.id, item.action) : () => {}"
9 >
10 <div class="icon-box">
11 <Icon v-if="item.category === 'alert'" :name="AlertIcon" :size="21" />
12 - <n-tooltip v-if="!item.read" trigger="hover" class="!p-0" content-class="!p-0" placement="right">
12 + <n-tooltip v-if="!item.read" trigger="hover" class="p-0!" content-class="p-0!" placement="right">
13 <template #trigger>
14 <div class="read-badge" @click.stop="setRead(item.id)" />
15 </template>
16 - <div class="px-3 py-2">Set as read</div>
16 + <div class="px-2 py-1 text-sm">Set as read</div>
17 </n-tooltip>
18 </div>
19 <div class="content grow">
20 - <div class="title">
21 - {{ item.title }}
22 - </div>
23 - <div class="description">
24 - {{ item.description }}
25 - </div>
20 + <div class="title">{{ item.title }}</div>
21 + <div class="description">{{ item.description }}</div>
22 <div class="footer flex items-center justify-between">
23 <div class="date">
24 {{ formatDatetime(item.date) }}
@@ -32,9 +28,14 @@
28 </div>
29 </div>
30 </div>
35 - <div class="delete-btn" @click.stop="deleteOne(item.id)">
36 - <Icon :name="DeleteIcon" :size="18" />
37 - </div>
31 + <n-tooltip trigger="hover" class="p-0!" content-class="p-0!" placement="left">
32 + <template #trigger>
33 + <div class="delete-btn" @click.stop="deleteOne(item.id)">
34 + <Icon :name="DeleteIcon" :size="14" />
35 + </div>
36 + </template>
37 + <div class="px-2 py-1 text-sm">Delete</div>
38 + </n-tooltip>
39 </div>
40 <slot name="last" />
41 <n-empty v-if="!list.length" description="There is no notification" class="h-48 justify-center" />
@@ -51,7 +52,7 @@ import { computed } from "vue"
52 const props = defineProps<{
53 maxItems?: number
54 }>()
54 -const DeleteIcon = "carbon:close"
55 +const DeleteIcon = "carbon:trash-can"
56 const AlertIcon = "mdi:alert-outline"
57
58 const list = useNotifications().list
@@ -145,6 +146,10 @@ function formatDatetime(date: Date | string) {
146 right: 8px;
147 cursor: pointer;
148 opacity: 0;
149 +
150 + &:hover {
151 + color: var(--error-color);
152 + }
153 }
154
155 &.success {
frontend/src/components/common/Percentage.vue
+1 -1
@@ -35,7 +35,7 @@
35 :percentage="value"
36 :show-indicator="false"
37 :stroke-width="18"
38 - class="!w-5"
38 + class="w-5!"
39 />
40 </span>
41 </div>
frontend/src/components/common/SearchDialog.vue
+2 -2
@@ -1,6 +1,6 @@
1 <template>
2 <n-modal v-model:show="showSearchBox" class="search-box-modal">
3 - <n-card content-class="!p-0" class="!w-150" :bordered="false" size="huge" role="dialog" aria-modal="true">
3 + <n-card content-class="p-0!" class="w-150!" :bordered="false" size="huge" role="dialog" aria-modal="true">
4 <div class="search-box" @keydown.up="prevItem()" @keydown.down="nextItem()">
5 <div class="search-input flex items-center">
6 <Icon :name="SearchIcon" :size="16" />
@@ -9,7 +9,7 @@
9 <Icon :name="CloseIcon" :size="20" class="cursor-pointer" @click="closeBox()" />
10 </div>
11 <n-divider />
12 - <n-scrollbar ref="scrollContent" class="!h-96">
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">{{ group.name }}</div>
frontend/src/components/common/cards/CardEntity.vue
+12 -9
@@ -107,12 +107,13 @@ const { size, status, embedded, highlighted, clickable, hoverable, disabled, loa
107 .main-box,
108 .extra-box,
109 .footer-box {
110 - @apply gap-3 p-4;
110 + gap: calc(var(--spacing) * 3);
111 + padding: calc(var(--spacing) * 4);
112 }
113
114 .main-box {
115 .header-box {
115 - @apply gap-3;
116 + gap: calc(var(--spacing) * 3);
117 }
118 }
119 }
@@ -122,12 +123,13 @@ const { size, status, embedded, highlighted, clickable, hoverable, disabled, loa
123 .main-box,
124 .extra-box,
125 .footer-box {
125 - @apply gap-2 p-3;
126 + gap: calc(var(--spacing) * 2);
127 + padding: calc(var(--spacing) * 3);
128 }
129
130 .main-box {
131 .header-box {
130 - @apply gap-2;
132 + gap: calc(var(--spacing) * 2);
133 }
134 }
135 }
@@ -138,19 +140,20 @@ const { size, status, embedded, highlighted, clickable, hoverable, disabled, loa
140 .main-box,
141 .extra-box,
142 .footer-box {
141 - @apply gap-6 p-6;
143 + gap: calc(var(--spacing) * 6);
144 + padding: calc(var(--spacing) * 6);
145 }
146
147 .main-box {
148 .header-box {
146 - @apply gap-6;
149 + gap: calc(var(--spacing) * 6);
150 }
151 }
152 }
153 }
154
155 &.clickable {
153 - @apply cursor-pointer;
156 + cursor: pointer;
157 }
158
159 &.embedded {
@@ -197,10 +200,10 @@ const { size, status, embedded, highlighted, clickable, hoverable, disabled, loa
200 }
201
202 &.disabled {
200 - @apply cursor-not-allowed;
203 + cursor: not-allowed;
204
205 .card-entity-wrapper {
203 - @apply opacity-70;
206 + opacity: 70%;
207 }
208 }
209 }
frontend/src/components/connectors/ConfigForm/ConfigForm.vue
+2 -1
@@ -295,7 +295,8 @@ onMounted(() => {
295 .connector-header {
296 display: flex;
297 align-items: center;
298 - @apply mb-7 gap-5;
298 + margin-bottom: calc(var(--spacing) * 7);
299 + gap: calc(var(--spacing) * 5);
300
301 .connector-image {
302 border: 2px solid var(--bg-body-color);
frontend/src/components/customers/integrations/CustomerIntegrationDetails.vue
+1 -1
@@ -31,7 +31,7 @@
31 </div>
32 </n-collapse-transition>
33 <n-collapse-transition :show="mode === 'edit'">
34 - <n-spin v-model:show="updating" class="flex min-h-80" content-class="flex flex-col grow">
34 + <n-spin v-model:show="updating" class="flex min-h-80" content-class="flex grow flex-col">
35 <div class="flex grow flex-col justify-between gap-5">
36 <n-form ref="form" :rules :label-width="80" :model>
37 <div class="flex flex-wrap gap-2">
frontend/src/components/graylog/Metrics/List.vue
+3 -2
@@ -86,13 +86,14 @@ function sanitizeMetrics(metrics: ThroughputMetric[]): Metrics[] {
86 <style lang="scss" scoped>
87 .metrics-list {
88 .metrics-group {
89 - @apply mb-6;
89 + margin-bottom: calc(var(--spacing) * 6);
90 overflow: hidden;
91
92 .list {
93 background-color: var(--bg-secondary-color);
94 .metric-wrap {
95 - @apply px-4 py-3;
95 + padding-inline: calc(var(--spacing) * 4);
96 + padding-block: calc(var(--spacing) * 3);
97
98 .metric {
99 line-height: 1.1;
frontend/src/components/incidentManagement/alerts/AlertDetails.vue
+2 -2
@@ -1,12 +1,12 @@
1 <template>
2 - <n-spin :show="loading" class="flex grow flex-col" content-class="flex flex-col grow">
2 + <n-spin :show="loading" class="flex grow flex-col" content-class="flex grow flex-col">
3 <n-tabs
4 v-if="alert"
5 type="line"
6 animated
7 :tabs-padding="24"
8 class="grow"
9 - pane-wrapper-class="flex flex-col grow"
9 + pane-wrapper-class="flex grow flex-col"
10 >
11 <n-tab-pane name="Overview" tab="Overview" display-directive="show:lazy" class="flex grow flex-col">
12 <div class="pt-1">
frontend/src/components/incidentManagement/alerts/AlertIoCsForm.vue
+1 -1
@@ -1,5 +1,5 @@
1 <template>
2 - <n-spin :show="submitting" class="flex min-h-48 grow flex-col" content-class="flex flex-col grow gap-4">
2 + <n-spin :show="submitting" class="flex min-h-48 grow flex-col" content-class="flex grow flex-col gap-4">
3 <n-form ref="formRef" :label-width="80" :model="form" :rules="rules">
4 <div class="flex flex-col gap-3">
5 <div>
frontend/src/components/incidentManagement/alerts/AlertMergeCaseButton.vue
+2 -2
@@ -12,13 +12,13 @@
12 preset="card"
13 :title="`Select the case you want to merge ${alerts.length > 1 ? 'them' : 'it'} with :`"
14 :style="{ maxWidth: 'min(850px, 90vw)', minHeight: 'min(540px, 90vh)', maxHeight: '80vh' }"
15 - content-class="overflow-hidden flex flex-col !px-2 !py-0"
15 + content-class="flex flex-col overflow-hidden !px-2 !py-0"
16 segmented
17 >
18 <n-spin
19 :show="loadingCases"
20 class="flex grow flex-col overflow-hidden"
21 - content-class="grow overflow-hidden flex flex-col"
21 + content-class="flex grow flex-col overflow-hidden"
22 >
23 <n-scrollbar class="flex grow flex-col" content-class="grow" trigger="none">
24 <div class="flex flex-col gap-2 px-5 py-5">
frontend/src/components/incidentManagement/alerts/AlertOverview.vue
+1 -1
@@ -1,5 +1,5 @@
1 <template>
2 - <n-spin :show="loading" class="flex grow flex-col" content-class="flex flex-col grow">
2 + <n-spin :show="loading" class="flex grow flex-col" content-class="flex grow flex-col">
3 <div class="flex grow flex-col justify-between gap-4">
4 <div class="content-box flex flex-col gap-4 py-3">
5 <div class="flex flex-col gap-4 px-7 sm:!flex-row">
frontend/src/components/incidentManagement/cases/CaseDataStore.vue
+1 -1
@@ -1,5 +1,5 @@
1 <template>
2 - <n-spin :show="loading" class="flex min-h-48 grow flex-col" content-class="flex flex-col grow gap-4">
2 + <n-spin :show="loading" class="flex min-h-48 grow flex-col" content-class="flex grow flex-col gap-4">
3 <div>
4 <n-collapse-transition :show="!showUploadForm">
5 <n-button v-if="dataStore.length" :loading="uploading" type="primary" @click="openUploadForm()">
frontend/src/components/incidentManagement/cases/CaseDetails.vue
+2 -2
@@ -1,12 +1,12 @@
1 <template>
2 - <n-spin :show="loading" class="flex grow flex-col" content-class="flex flex-col grow">
2 + <n-spin :show="loading" class="flex grow flex-col" content-class="flex grow flex-col">
3 <n-tabs
4 v-if="caseEntity"
5 type="line"
6 animated
7 :tabs-padding="24"
8 class="grow"
9 - pane-wrapper-class="flex flex-col grow"
9 + pane-wrapper-class="flex grow flex-col"
10 >
11 <n-tab-pane name="Overview" tab="Overview" display-directive="show:lazy" class="flex grow flex-col">
12 <div class="pt-1">
frontend/src/components/incidentManagement/cases/CaseOverview.vue
+1 -1
@@ -1,5 +1,5 @@
1 <template>
2 - <n-spin :show="loading" class="flex grow flex-col" content-class="flex flex-col grow">
2 + <n-spin :show="loading" class="flex grow flex-col" content-class="flex grow flex-col">
3 <div class="flex grow flex-col justify-between gap-4">
4 <div class="content-box flex flex-col gap-4 py-3">
5 <div class="flex flex-col gap-4 px-7 sm:!flex-row">
frontend/src/components/incidentManagement/cases/CaseReportTemplateManager.vue
+2 -2
@@ -1,5 +1,5 @@
1 <template>
2 - <n-spin :show="loading" class="flex min-h-48 grow flex-col" content-class="flex flex-col grow gap-4">
2 + <n-spin :show="loading" class="flex min-h-48 grow flex-col" content-class="flex grow flex-col gap-4">
3 <div>
4 <n-collapse-transition :show="!showUploadForm">
5 <div class="flex flex-wrap items-center gap-3">
@@ -74,7 +74,7 @@
74 size="small"
75 class="overflow-hidden"
76 embedded
77 - content-class="flex justify-between items-center flex-wrap gap-4"
77 + content-class="flex flex-wrap items-center justify-between gap-4"
78 >
79 <div class="flex gap-3">
80 <n-tooltip to="body">
frontend/src/components/indices/ClusterHealth.vue
+6 -3
@@ -107,20 +107,23 @@ onBeforeMount(() => {
107 <style lang="scss" scoped>
108 .cluster-health {
109 .card-wrap {
110 - @apply gap-6 gap-x-6 px-4 py-3;
110 + gap: calc(var(--spacing) * 6);
111 + column-gap: calc(var(--spacing) * 6);
112 + padding-inline: calc(var(--spacing) * 4);
113 + padding-block: calc(var(--spacing) * 3);
114 column-width: 12rem;
115 column-count: auto;
116
117 .box {
118 overflow: hidden;
116 - @apply mb-6;
119 + margin-bottom: calc(var(--spacing) * 6);
120 .value {
121 font-weight: bold;
122 margin-bottom: 2px;
123 white-space: nowrap;
124 }
125 .label {
123 - @apply text-xs;
126 + font-size: var(--text-xs);
127 font-family: var(--font-family-mono);
128 opacity: 0.8;
129 }
frontend/src/components/indices/Details.vue
+3 -3
@@ -155,12 +155,12 @@ onBeforeMount(() => {
155 display: flex;
156 align-items: center;
157 justify-content: space-between;
158 - @apply gap-4;
158 + gap: calc(var(--spacing) * 4);
159 }
160
161 .details-box {
162 .shards {
163 - @apply mt-4;
163 + margin-top: calc(var(--spacing) * 4);
164
165 .shard-state {
166 font-weight: bold;
@@ -178,7 +178,7 @@ onBeforeMount(() => {
178 .box-header {
179 flex-direction: column;
180 align-items: flex-start;
181 - @apply gap-2;
181 + gap: calc(var(--spacing) * 2);
182
183 .select-box {
184 width: 100%;
frontend/src/components/indices/IndexCard.vue
+3 -3
@@ -141,12 +141,12 @@ function deleteIndex() {
141 display: flex;
142 justify-content: space-between;
143 flex-wrap: wrap;
144 - @apply gap-6;
144 + gap: calc(var(--spacing) * 6);
145
146 .group {
147 display: flex;
148 justify-content: space-between;
149 - @apply gap-6;
149 + gap: calc(var(--spacing) * 6);
150 flex-grow: 1;
151 flex-wrap: wrap;
152
@@ -159,7 +159,7 @@ function deleteIndex() {
159 }
160 .label {
161 white-space: nowrap;
162 - @apply text-xs;
162 + font-size: var(--text-xs);
163 font-family: var(--font-family-mono);
164 opacity: 0.8;
165 }
frontend/src/components/indices/Marquee.vue
+1 -1
@@ -109,7 +109,7 @@ onBeforeMount(() => {
109 .indices-marquee {
110 .info {
111 opacity: 0.5;
112 - @apply text-xs;
112 + font-size: var(--text-xs);
113 margin-top: 5px;
114 }
115 .marquee-wrap {
frontend/src/components/indices/NodeAllocation.vue
+5 -4
@@ -137,8 +137,9 @@ onBeforeMount(() => {
137 overflow: hidden;
138
139 .group {
140 - @apply px-4 py-3;
141 - @apply gap-6;
140 + padding-inline: calc(var(--spacing) * 4);
141 + padding-block: calc(var(--spacing) * 3);
142 + gap: calc(var(--spacing) * 6);
143 display: flex;
144 justify-content: space-between;
145 flex-grow: 1;
@@ -153,7 +154,7 @@ onBeforeMount(() => {
154 margin-bottom: 2px;
155 }
156 .label {
156 - @apply text-xs;
157 + font-size: var(--text-xs);
158 font-family: var(--font-family-mono);
159 opacity: 0.8;
160 }
@@ -181,7 +182,7 @@ onBeforeMount(() => {
182 }
183
184 &:not(:last-child) {
184 - @apply mb-4;
185 + margin-bottom: calc(var(--spacing) * 4);
186 }
187 }
188 }
frontend/src/components/indices/UnhealthyIndices.vue
+1 -1
@@ -68,7 +68,7 @@ const unhealthyIndices = computed(() =>
68 cursor: pointer;
69
70 &:not(:last-child) {
71 - @apply mb-3;
71 + margin-bottom: calc(var(--spacing) * 3);
72 }
73 }
74 }
frontend/src/components/license/LicenseDetails.vue
+1 -1
@@ -1,5 +1,5 @@
1 <template>
2 - <n-spin :show="loading" content-class=" grow flex flex-col" class="flex flex-col overflow-hidden">
2 + <n-spin :show="loading" content-class="flex grow flex-col" class="flex flex-col overflow-hidden">
3 <div v-if="license" class="flex flex-col gap-4">
4 <CardKV v-if="!hideKey">
5 <template #key>
frontend/src/components/license/LicenseFeatureCheck.vue
+3 -3
@@ -8,7 +8,7 @@
8 <span v-else></span>
9 </template>
10 </template>
11 - <div class="w-90vw flex !max-w-lg flex-col gap-3">
11 + <div class="flex w-[90vw] !max-w-lg flex-col gap-3">
12 <div>
13 It seems that the feature you are looking for is currently unavailable. To unlock and use it, you
14 need to enable this feature. You can manage your features from the License page.
@@ -25,7 +25,7 @@
25 </n-tooltip>
26
27 <div v-if="showFeedback && feedback === 'overlay'" class="over-layer animate-fade">
28 - <n-card class="w-90vw !max-w-lg">
28 + <n-card class="w-[90vw] !max-w-lg">
29 <template #header>
30 <div class="flex items-center gap-3">
31 <Icon :name="AlertIcon" :size="18" />
@@ -49,7 +49,7 @@
49 </n-card>
50 </div>
51
52 - <n-modal v-model:show="showModal" class="w-90vw !max-w-lg" preset="card">
52 + <n-modal v-model:show="showModal" class="w-[90vw] !max-w-lg" preset="card">
53 <template #header>
54 <div class="flex items-center gap-3">
55 <Icon :name="AlertIcon" :size="18" />
frontend/src/components/license/SubscriptionCard.vue
+1 -1
@@ -54,7 +54,7 @@
54 content-class="flex flex-col"
55 segmented
56 >
57 - <n-spin :show="canceling" content-class="flex flex-col gap-4 grow" class="flex grow flex-col">
57 + <n-spin :show="canceling" content-class="flex grow flex-col gap-4" class="flex grow flex-col">
58 <div class="flex justify-between gap-4">
59 <div>{{ subscription.info }}</div>
60 <div class="text-primary whitespace-nowrap font-mono">
frontend/src/components/reportCreation/Panels.vue
+3 -3
@@ -1,5 +1,5 @@
1 <template>
2 - <n-spin v-model:show="loading" class="h-full w-full overflow-hidden" content-class="overflow-hidden h-full w-full">
2 + <n-spin v-model:show="loading" class="h-full w-full overflow-hidden" content-class="h-full w-full overflow-hidden">
3 <div v-if="org" class="report-panels flex h-full w-full gap-2">
4 <div class="panels-container flex h-full grow flex-col gap-4">
5 <div class="rows-container">
@@ -504,14 +504,14 @@ onMounted(() => {
504 z-index: 0;
505 width: unset;
506 height: unset;
507 - @apply bottom-3 left-3 right-3 top-3;
507 + inset: calc(var(--spacing) * 3);
508 }
509
510 .drop-panels-area {
511 position: absolute;
512 width: unset;
513 height: unset;
514 - @apply bottom-3 left-3 right-3 top-3;
514 + inset: calc(var(--spacing) * 3);
515 }
516
517 .left-box {
frontend/src/components/sigma/QueryDetails.vue
+1 -1
@@ -1,5 +1,5 @@
1 <template>
2 - <n-tabs type="line" animated :tabs-padding="24" class="grow" pane-wrapper-class="flex flex-col grow">
2 + <n-tabs type="line" animated :tabs-padding="24" class="grow" pane-wrapper-class="flex grow flex-col">
3 <n-tab-pane name="Overview" tab="Overview" display-directive="show:lazy" class="flex grow flex-col">
4 <div class="pt-1">
5 <QueryOverview :query @updated="updateQuery($event)" @deleted="emit('deleted', query)" />
frontend/src/components/sigma/QueryOverview.vue
+1 -1
@@ -1,5 +1,5 @@
1 <template>
2 - <n-spin :show="loading" class="flex grow flex-col" content-class="flex flex-col grow">
2 + <n-spin :show="loading" class="flex grow flex-col" content-class="flex grow flex-col">
3 <div class="flex grow flex-col justify-between gap-4">
4 <div class="content-box flex flex-col gap-4 py-3">
5 <div class="flex flex-col gap-4 px-7 sm:!flex-row">
frontend/src/components/soc/SocAlerts/SocAlertItem/SocAlertItemTime.vue
+1 -1
@@ -44,7 +44,7 @@ function formatDate(timestamp: string | number, utc: boolean = true): string {
44 font-family: var(--font-family-mono);
45
46 &.hover {
47 - @apply cursor-help;
47 + cursor: help;
48
49 &:hover {
50 color: var(--primary-color);
frontend/src/composables/useLoadingBarSetup.ts new
+16
@@ -0,0 +1,16 @@
1 +import { useMainStore } from "@/stores/main"
2 +import { useLoadingBar } from "naive-ui"
3 +import { onMounted } from "vue"
4 +import { useRouter } from "vue-router"
5 +
6 +export function useLoadingBarSetup() {
7 + const router = useRouter()
8 + const mainStore = useMainStore()
9 +
10 + onMounted(() => {
11 + const loadingBar = useLoadingBar()
12 + router.beforeEach(() => loadingBar?.start())
13 + router.afterEach(() => loadingBar?.finish())
14 + mainStore.setLoadingBar(loadingBar)
15 + })
16 +}
frontend/src/design-tokens.json
+4 -4
@@ -67,11 +67,11 @@
67 "light": {
68 "sidebarBackground": "rgb(255, 255, 255)",
69 "bodyBackground": "rgb(245, 247, 249)",
70 + "background": "rgb(255, 255, 255)",
71 + "backgroundSecondary": "rgb(250, 251, 252)",
72 "text": "rgb(0, 0, 0)",
73 "textSecondary": "rgb(73, 84, 101)",
74 "textTertiary": "rgb(114, 115, 115)",
73 - "background": "rgb(255, 255, 255)",
74 - "backgroundSecondary": "rgb(250, 251, 252)",
75 "border": "rgb(226, 230, 233)",
76 "hover": "rgba(221, 224, 225, 0.5)",
77 "primary": "rgb(219, 157, 0)",
@@ -87,11 +87,11 @@
87 "dark": {
88 "sidebarBackground": "rgb(29, 31, 37)",
89 "bodyBackground": "rgb(20, 22, 26)",
90 + "background": "rgb(38, 40, 45)",
91 + "backgroundSecondary": "rgb(29, 31, 37)",
92 "text": "rgb(255, 255, 255)",
93 "textSecondary": "rgb(172, 181, 190)",
94 "textTertiary": "rgb(172, 181, 190)",
93 - "background": "rgb(38, 40, 45)",
94 - "backgroundSecondary": "rgb(29, 31, 37)",
95 "border": "rgb(67, 68, 76)",
96 "hover": "rgba(59, 61, 68, 0.5)",
97 "primary": "rgb(255, 182, 0)",
frontend/src/emitter/index.ts renamed
frontend/src/i18n.d.ts new
+54
@@ -0,0 +1,54 @@
1 +import type { MessageSchema } from "@/lang/config"
2 +import type { RecursiveKeyOf } from "@/types/common"
3 +
4 +// To ensure it is treated as a module, add at least one `export` statement
5 +export {}
6 +
7 +declare module "@vue/runtime-core" {
8 + interface ComponentCustomProperties {
9 + $t: {
10 + // Firma 1: Traduzione semplice
11 + (key: RecursiveKeyOf<MessageSchema>): string
12 +
13 + // Firma 2: Traduzione con numero plurale
14 + (key: RecursiveKeyOf<MessageSchema>, plural: number): string
15 +
16 + // Firma 3: Traduzione con numero plurale e opzioni aggiuntive
17 + (key: RecursiveKeyOf<MessageSchema>, plural: number, options: TranslateOptions<Locales>): string
18 +
19 + // Firma 4: Traduzione con messaggio predefinito
20 + (key: RecursiveKeyOf<MessageSchema>, defaultMsg: string): string
21 +
22 + // Firma 5: Traduzione con messaggio predefinito e opzioni aggiuntive
23 + (key: RecursiveKeyOf<MessageSchema>, defaultMsg: string, options: TranslateOptions<Locales>): string
24 +
25 + // Firma 6: Traduzione con interpolazione di lista
26 + (key: RecursiveKeyOf<MessageSchema>, list: unknown[]): string
27 +
28 + // Firma 7: Traduzione con interpolazione di lista e numero plurale
29 + (key: RecursiveKeyOf<MessageSchema>, list: unknown[], plural: number): string
30 +
31 + // Firma 8: Traduzione con interpolazione di lista e messaggio predefinito
32 + (key: RecursiveKeyOf<MessageSchema>, list: unknown[], defaultMsg: string): string
33 +
34 + // Firma 9: Traduzione con interpolazione di lista e opzioni aggiuntive
35 + (key: RecursiveKeyOf<MessageSchema>, list: unknown[], options: TranslateOptions<Locales>): string
36 +
37 + // Firma 10: Traduzione con interpolazione nominale
38 + (key: RecursiveKeyOf<MessageSchema>, named: NamedValue): string
39 +
40 + // Firma 11: Traduzione con interpolazione nominale e numero plurale
41 + (key: RecursiveKeyOf<MessageSchema>, named: NamedValue, plural: number): string
42 +
43 + // Firma 12: Traduzione con interpolazione nominale e messaggio predefinito
44 + (key: RecursiveKeyOf<MessageSchema>, named: NamedValue, defaultMsg: string): string
45 +
46 + // Firma 13: Traduzione con interpolazione nominale e opzioni aggiuntive
47 + (key: RecursiveKeyOf<MessageSchema>, named: NamedValue, options: TranslateOptions<Locales>): string
48 + }
49 + }
50 +}
51 +
52 +declare module "vue-i18n" {
53 + export interface DefineLocaleMessage extends MessageSchema {}
54 +}
frontend/src/lang/config.ts
+12 -13
@@ -1,23 +1,22 @@
1 -import * as locales from "."
1 +import type { RecursiveKeyOf } from "@/types/common"
2 +import type { I18nOptions } from "vue-i18n"
3 +import * as locales from "./locales"
4
3 -export type Locale = keyof typeof locales
4 -export type MessageSchema = (typeof locales)[Locale]
5 +export type LocaleCodes = keyof typeof locales
6 +export type MessageSchema = (typeof locales)[LocaleCodes]
7 +export type I18nString = RecursiveKeyOf<MessageSchema>
8
9 export function getI18NConf() {
7 - // @ts-expect-error "locales" don't match with [key: string]: { default: MessageSchema } }
8 - const localesEntries = Object.entries<{ default: MessageSchema }>(locales)
10 + const localesEntries = Object.entries<MessageSchema>(locales)
11
10 - const messages = localesEntries.reduce(
11 - (acc: { [key: string]: MessageSchema }, cur: [string, { default: MessageSchema }]) => {
12 - acc[cur[0]] = cur[1].default
13 - return acc
14 - },
15 - {}
16 - ) as { [key in Locale]: MessageSchema }
12 + const messages = localesEntries.reduce((acc: { [key: string]: MessageSchema }, cur: [string, MessageSchema]) => {
13 + acc[cur[0]] = cur[1]
14 + return acc
15 + }, {}) as { [key in LocaleCodes]: MessageSchema }
16
17 return {
18 legacy: false,
19 locale: "en",
20 messages
22 - }
21 + } satisfies I18nOptions
22 }
frontend/src/lang/de.ts deleted
-10
@@ -1,10 +0,0 @@
1 -export default {
2 - italian: "Italienisch",
3 - english: "Englisch",
4 - japanese: "Japanisch",
5 - french: "Französisch",
6 - german: "Deutsch",
7 - spanish: "Spanisch",
8 - sun_description:
9 - "Die Sonne ist ein mittelgroßer Stern, der sich im Zentrum unseres Sonnensystems befindet. Sie ist eine Quelle von Licht und Wärme, die das Leben auf der Erde ermöglicht. Hauptsächlich aus Wasserstoff und Helium bestehend, erzeugt sie Energie durch Kernfusion. Ihre Masse und Gravitation halten die Planeten und andere Himmelskörper in einer Umlaufbahn um sie."
10 -}
frontend/src/lang/en.ts deleted
-10
@@ -1,10 +0,0 @@
1 -export default {
2 - italian: "Italian",
3 - english: "English",
4 - japanese: "Japanese",
5 - french: "French",
6 - german: "German",
7 - spanish: "Spanish",
8 - sun_description:
9 - "The sun is a medium-sized star located at the center of our solar system. It is a source of light and heat that sustains life on Earth. Composed mainly of hydrogen and helium, it generates energy through nuclear fusion. Its mass and gravity keep the planets and other celestial bodies in orbit around it."
10 -}
frontend/src/lang/es.ts deleted
-10
@@ -1,10 +0,0 @@
1 -export default {
2 - italian: "Italiano",
3 - english: "Inglés",
4 - japanese: "Japonés",
5 - french: "Francés",
6 - german: "Alemán",
7 - spanish: "Español",
8 - sun_description:
9 - "El sol es una estrella de tamaño medio ubicada en el centro de nuestro sistema solar. Es una fuente de luz y calor que sustenta la vida en la Tierra. Compuesto principalmente por hidrógeno y helio, genera energía a través de la fusión nuclear. Su masa y gravedad mantienen en órbita a los planetas y otros cuerpos celestes en el sistema solar."
10 -}
frontend/src/lang/fr.ts deleted
-10
@@ -1,10 +0,0 @@
1 -export default {
2 - italian: "Italien",
3 - english: "Anglais",
4 - japanese: "Japonais",
5 - french: "Français",
6 - german: "Allemand",
7 - spanish: "Espagnol",
8 - sun_description:
9 - "Le soleil est une étoile de taille moyenne située au centre de notre système solaire. Il est une source de lumière et de chaleur qui permet la vie sur Terre. Principalement composé d'hydrogène et d'hélium, il génère de l'énergie par fusion nucléaire. Sa masse et sa gravité maintiennent en orbite les planètes et autres corps célestes du système solaire."
10 -}
frontend/src/lang/index.ts
+9 -6
@@ -1,6 +1,9 @@
1 -export * as de from "./de"
2 -export * as en from "./en"
3 -export * as es from "./es"
4 -export * as fr from "./fr"
5 -export * as it from "./it"
6 -export * as jp from "./jp"
1 +import type { LocaleCodes, MessageSchema } from "./config"
2 +import { createI18n } from "vue-i18n"
3 +import { getI18NConf } from "./config"
4 +
5 +const instance = createI18n<[MessageSchema], LocaleCodes>(getI18NConf())
6 +
7 +export default instance
8 +
9 +export const i18nGlobal = instance.global
frontend/src/lang/it.ts deleted
-10
@@ -1,10 +0,0 @@
1 -export default {
2 - italian: "Italiano",
3 - english: "Inglese",
4 - japanese: "Giapponese",
5 - french: "Francese",
6 - german: "Tedesco",
7 - spanish: "Spagnolo",
8 - sun_description:
9 - "Il sole è una stella di dimensioni medie che si trova al centro del nostro sistema solare. È una sorgente di luce e calore che permette la vita sulla Terra. Composto principalmente da idrogeno e elio, genera energia attraverso la fusione nucleare. La sua massa e la sua gravità mantengono in orbita i pianeti e gli altri corpi celesti nel sistema solare."
10 -}
frontend/src/lang/jp.ts deleted
-10
@@ -1,10 +0,0 @@
1 -export default {
2 - italian: "イタリア語 (Italiago)",
3 - english: "英語 (Eigo)",
4 - japanese: "日本語 (Nihongo)",
5 - french: "フランス語 (Furansugo)",
6 - german: "ドイツ語 (Doitsugo)",
7 - spanish: "スペイン語 (Supeingo)",
8 - sun_description:
9 - "太陽は、太陽系の中心に位置する中程度の大きさの星です。地球上の生命を維持する光と熱の源です。主に水素とヘリウムで構成され、核融合によってエネルギーを生成します。その質量と重力によって、惑星や他の天体は太陽の周りを軌道上に保ちます。"
10 -}
frontend/src/lang/locales/de.json new
+11
@@ -0,0 +1,11 @@
1 +{
2 + "locales": {
3 + "it": "Italienisch",
4 + "en": "Englisch",
5 + "jp": "Japanisch",
6 + "fr": "Französisch",
7 + "de": "Deutsch",
8 + "es": "Spanisch"
9 + },
10 + "sun_description": "Die Sonne ist ein mittelgroßer Stern, der sich im Zentrum unseres Sonnensystems befindet. Sie ist eine Quelle von Licht und Wärme, die das Leben auf der Erde ermöglicht. Hauptsächlich aus Wasserstoff und Helium bestehend, erzeugt sie Energie durch Kernfusion. Ihre Masse und Gravitation halten die Planeten und andere Himmelskörper in einer Umlaufbahn um sie."
11 +}
frontend/src/lang/locales/en.json new
+11
@@ -0,0 +1,11 @@
1 +{
2 + "locales": {
3 + "it": "Italian",
4 + "en": "English",
5 + "jp": "Japanese",
6 + "fr": "French",
7 + "de": "German",
8 + "es": "Spanish"
9 + },
10 + "sun_description": "The sun is a medium-sized star located at the center of our solar system. It is a source of light and heat that sustains life on Earth. Composed mainly of hydrogen and helium, it generates energy through nuclear fusion. Its mass and gravity keep the planets and other celestial bodies in orbit around it."
11 +}
frontend/src/lang/locales/es.json new
+11
@@ -0,0 +1,11 @@
1 +{
2 + "locales": {
3 + "it": "Italiano",
4 + "en": "Inglés",
5 + "jp": "Japonés",
6 + "fr": "Francés",
7 + "de": "Alemán",
8 + "es": "Español"
9 + },
10 + "sun_description": "El sol es una estrella de tamaño medio ubicada en el centro de nuestro sistema solar. Es una fuente de luz y calor que sustenta la vida en la Tierra. Compuesto principalmente por hidrógeno y helio, genera energía a través de la fusión nuclear. Su masa y gravedad mantienen en órbita a los planetas y otros cuerpos celestes en el sistema solar."
11 +}
frontend/src/lang/locales/fr.json new
+11
@@ -0,0 +1,11 @@
1 +{
2 + "locales": {
3 + "it": "Italien",
4 + "en": "Anglais",
5 + "jp": "Japonais",
6 + "fr": "Français",
7 + "de": "Allemand",
8 + "es": "Espagnol"
9 + },
10 + "sun_description": "Le soleil est une étoile de taille moyenne située au centre de notre système solaire. Il est une source de lumière et de chaleur qui permet la vie sur Terre. Principalement composé d'hydrogène et d'hélium, il génère de l'énergie par fusion nucléaire. Sa masse et sa gravité maintiennent en orbite les planètes et autres corps célestes du système solaire."
11 +}
frontend/src/lang/locales/index.ts new
+6
@@ -0,0 +1,6 @@
1 +export { default as de } from "./de.json"
2 +export { default as en } from "./en.json"
3 +export { default as es } from "./es.json"
4 +export { default as fr } from "./fr.json"
5 +export { default as it } from "./it.json"
6 +export { default as jp } from "./jp.json"
frontend/src/lang/locales/it.json new
+11
@@ -0,0 +1,11 @@
1 +{
2 + "locales": {
3 + "it": "Italiano",
4 + "en": "Inglese",
5 + "jp": "Giapponese",
6 + "fr": "Francese",
7 + "de": "Tedesco",
8 + "es": "Spagnolo"
9 + },
10 + "sun_description": "Il sole è una stella di dimensioni medie che si trova al centro del nostro sistema solare. È una sorgente di luce e calore che permette la vita sulla Terra. Composto principalmente da idrogeno e elio, genera energia attraverso la fusione nucleare. La sua massa e la sua gravità mantengono in orbita i pianeti e gli altri corpi celesti nel sistema solare."
11 +}
frontend/src/lang/locales/jp.json new
+11
@@ -0,0 +1,11 @@
1 +{
2 + "locales": {
3 + "it": "イタリア語 (Italiago)",
4 + "en": "英語 (Eigo)",
5 + "jp": "日本語 (Nihongo)",
6 + "fr": "フランス語 (Furansugo)",
7 + "de": "ドイツ語 (Doitsugo)",
8 + "es": "スペイン語 (Supeingo)"
9 + },
10 + "sun_description": "太陽は、太陽系の中心に位置する中程度の大きさの星です。地球上の生命を維持する光と熱の源です。主に水素とヘリウムで構成され、核融合によってエネルギーを生成します。その質量と重力によって、惑星や他の天体は太陽の周りを軌道上に保ちます。"
11 +}
frontend/src/main.ts
+3 -5
@@ -1,11 +1,11 @@
1 -import type { Locale, MessageSchema } from "@/lang/config"
1 import App from "@/App.vue"
3 -import { getI18NConf } from "@/lang/config"
2 +import i18n from "@/lang"
3 import router from "@/router"
4 import { createPinia } from "pinia"
5 import { createPersistedState } from "pinia-plugin-persistedstate"
6 import { createApp } from "vue"
8 -import { createI18n } from "vue-i18n"
7 +import "@/assets/scss/index.scss"
8 +import "./tailwind.css"
9
10 const meta = document.createElement("meta")
11 meta.name = "naive-ui-style"
@@ -18,8 +18,6 @@ pinia.use(
18 })
19 )
20
21 -const i18n = createI18n<MessageSchema, Locale>(getI18NConf())
22 -
21 const app = createApp(App)
22 app.use(pinia)
23 app.use(i18n)
frontend/src/stores/i18n.ts
+18 -13
@@ -1,7 +1,7 @@
1 -import type { Locale } from "@/lang/config"
1 +import type { LocaleCodes } from "@/lang/config"
2 import type { NDateLocale, NLocale } from "naive-ui"
3 import type { WritableComputedRef } from "vue"
4 -import type { ComposerTranslation } from "vue-i18n"
4 +import dayjs from "@/utils/dayjs"
5 import {
6 dateDeDE,
7 dateEnUS,
@@ -17,26 +17,31 @@ import {
17 jaJP
18 } from "naive-ui"
19 import { acceptHMRUpdate, defineStore } from "pinia"
20 +import { nextTick } from "vue"
21 import { useI18n } from "vue-i18n"
22
22 -export type I18nLangCode = Locale
23 -
23 export const useLocalesStore = defineStore("i18n", {
25 - state: () => ({
26 - locale: useI18n().locale as WritableComputedRef<I18nLangCode, string>,
27 - availableLocales: useI18n().availableLocales as I18nLangCode[]
28 - }),
24 + state: () => {
25 + nextTick(() => {
26 + const dayjsLocale = useLocalesStore().locale === "jp" ? "ja" : useLocalesStore().locale
27 + dayjs.locale(dayjsLocale)
28 + })
29 +
30 + return {
31 + locale: useI18n().locale as WritableComputedRef<LocaleCodes, string>,
32 + availableLocales: useI18n().availableLocales as LocaleCodes[]
33 + }
34 + },
35 actions: {
30 - setLocale(locale: I18nLangCode): I18nLangCode {
36 + setLocale(locale: LocaleCodes): LocaleCodes {
37 + const dayjsLocale = locale === "jp" ? "ja" : locale
38 + dayjs.locale(dayjsLocale)
39 this.locale = locale
40 return locale
41 }
42 },
43 getters: {
36 - t(): ComposerTranslation {
37 - return useI18n().t
38 - },
39 - naiveuiLocales(): { code: I18nLangCode; ui: NLocale; date: NDateLocale }[] {
44 + naiveuiLocales(): { code: LocaleCodes; ui: NLocale; date: NDateLocale }[] {
45 return [
46 { code: "de", ui: deDE, date: dateDeDE },
47 { code: "en", ui: enUS, date: dateEnUS },
frontend/src/tailwind.css new
+279
@@ -0,0 +1,279 @@
1 +@import "tailwindcss";
2 +@config '../tailwind.config.js';
3 +
4 +@custom-variant dark (&:where(.theme-dark, .theme-dark *));
5 +
6 +@theme inline {
7 + --font-*: initial;
8 + --font-sans: var(--font-family), sans-serif;
9 + --font-serif: var(--font-family-display), serif;
10 + --font-display: var(--font-family-display), serif;
11 + --font-mono: var(--font-family-mono), monospace;
12 +
13 + --color-primary: var(--primary-color);
14 + --color-success: var(--success-color);
15 + --color-error: var(--error-color);
16 + --color-warning: var(--warning-color);
17 + --color-info: var(--info-color);
18 + --color-border: var(--border-color);
19 + --color-hover: var(--hover-color);
20 +
21 + --color-extra-1: var(--extra1-color);
22 + --color-extra-2: var(--extra2-color);
23 + --color-extra-3: var(--extra3-color);
24 + --color-extra-4: var(--extra4-color);
25 +
26 + --border-color-default: var(--border-color);
27 +
28 + --background-color-default: var(--bg-default-color);
29 + --background-color-secondary: var(--bg-secondary-color);
30 + --background-color-body: var(--bg-body-color);
31 + --background-color-sidebar: var(--bg-sidebar-color);
32 +
33 + --text-color-default: var(--fg-default-color);
34 + --text-color-secondary: var(--fg-secondary-color);
35 + --text-color-tertiary: var(--fg-tertiary-color);
36 +
37 + --breakpoint-xs: 460px;
38 +
39 + --animate-fade: fade 0.3s forwards;
40 +
41 + @keyframes fade {
42 + from {
43 + opacity: 0;
44 + }
45 + to {
46 + opacity: 1;
47 + }
48 + }
49 +}
50 +
51 +@layer base {
52 + /*
53 + The default border color has changed to `currentColor` in Tailwind CSS v4,
54 + so we've added these compatibility styles to make sure everything still
55 + looks the same as it did with Tailwind CSS v3.
56 +
57 + If we ever want to remove these styles, we need to add an explicit border
58 + color utility to any element that depends on these defaults.
59 + */
60 + *,
61 + ::after,
62 + ::before,
63 + ::backdrop,
64 + ::file-selector-button {
65 + border-color: var(--color-gray-200, currentColor);
66 + }
67 +
68 + html,
69 + body {
70 + text-size-adjust: 100%;
71 + -webkit-tap-highlight-color: transparent;
72 + -webkit-touch-callout: none;
73 + -webkit-font-smoothing: antialiased;
74 + -moz-osx-font-smoothing: grayscale;
75 + text-rendering: optimizeLegibility;
76 + line-height: var(--line-height);
77 + font-size: var(--font-size);
78 + text-wrap: pretty;
79 +
80 + margin: 0;
81 + padding: 0;
82 + box-sizing: border-box;
83 +
84 + width: 100vw;
85 + height: 100vh;
86 + height: 100svh;
87 + overflow: hidden;
88 +
89 + &:focus {
90 + outline: none;
91 + }
92 + }
93 +
94 + [v-cloak] {
95 + display: none !important;
96 + }
97 +
98 + ::view-transition-old(root),
99 + ::view-transition-new(root) {
100 + animation: none;
101 + mix-blend-mode: normal;
102 + }
103 + ::view-transition-old(root) {
104 + z-index: 1;
105 + }
106 + ::view-transition-new(root) {
107 + z-index: 99999;
108 + }
109 +
110 + ::selection {
111 + background-color: rgba(var(--primary-color-rgb) / 0.2);
112 + }
113 +
114 + #app {
115 + width: 100vw;
116 + height: 100vh;
117 + height: 100svh;
118 + overflow: auto;
119 + }
120 +
121 + svg {
122 + touch-action: initial !important;
123 + }
124 +
125 + input {
126 + accent-color: var(--primary-color);
127 + }
128 +
129 + p {
130 + color: var(--fg-secondary-color);
131 + }
132 +
133 + code,
134 + kbd,
135 + samp,
136 + pre {
137 + font-family: var(--font-family-mono);
138 + }
139 +
140 + code {
141 + padding: 1px 6px;
142 + border-radius: var(--border-radius-small);
143 + background-color: rgba(var(--hover-color-rgb) / 0.4);
144 + font-size: 13px;
145 + }
146 + pre {
147 + border-radius: var(--border-radius-small);
148 +
149 + code {
150 + padding: 12px;
151 + display: block;
152 + overflow-x: auto;
153 + }
154 + }
155 +
156 + a {
157 + text-decoration: underline;
158 + text-decoration-color: var(--primary-color);
159 + color: var(--primary-color);
160 + }
161 +
162 + blockquote {
163 + display: block;
164 + padding-left: 1em;
165 + border-left: 4px solid var(--border-color);
166 + }
167 +
168 + dl {
169 + dt {
170 + font-weight: bold;
171 + margin-bottom: 2px;
172 + }
173 +
174 + & > dd:not(:last-child) {
175 + margin-bottom: 10px;
176 + }
177 + }
178 +
179 + ul {
180 + display: block;
181 + list-style-type: disc;
182 + padding-left: 20px;
183 + line-height: 1.6;
184 +
185 + ul {
186 + list-style-type: circle;
187 + margin-top: 3px;
188 + margin-bottom: 6px;
189 + }
190 + }
191 +
192 + ol {
193 + display: block;
194 + list-style-type: decimal;
195 + padding-left: 20px;
196 + line-height: 1.6;
197 +
198 + ol {
199 + list-style-type: decimal;
200 + margin-top: 3px;
201 + margin-bottom: 6px;
202 + }
203 + }
204 +
205 + mark {
206 + padding: 2px 0px;
207 + border-radius: var(--border-radius-small);
208 + background-color: rgba(var(--primary-color-rgb) / 0.3);
209 + color: var(--fg-default-color);
210 + }
211 +
212 + @media print {
213 + html,
214 + body {
215 + overflow: initial;
216 + }
217 + body {
218 + #app {
219 + height: initial;
220 + background-color: white;
221 +
222 + & > .n-config-provider {
223 + & > .layout {
224 + display: block;
225 + height: initial;
226 + background-color: white;
227 +
228 + & > .header-bar {
229 + display: none;
230 + }
231 + & > .main {
232 + background-color: white;
233 + overflow: initial;
234 + height: initial;
235 +
236 + header.toolbar {
237 + display: none;
238 + }
239 + footer.footer {
240 + display: none;
241 + }
242 +
243 + & > .n-scrollbar {
244 + overflow: initial;
245 + height: initial;
246 +
247 + & > .n-scrollbar-container {
248 + overflow: initial;
249 + height: initial;
250 + }
251 + }
252 + }
253 + }
254 + }
255 + }
256 + }
257 + }
258 +
259 + html.theme-dark .shiki,
260 + html.theme-dark .shiki span {
261 + color: var(--shiki-dark) !important;
262 + /*background-color: var(--shiki-dark-bg) !important;*/
263 + /* Optional, if you also want font styles */
264 + font-style: var(--shiki-dark-font-style) !important;
265 + font-weight: var(--shiki-dark-font-weight) !important;
266 + text-decoration: var(--shiki-dark-text-decoration) !important;
267 + }
268 + html.theme-dark,
269 + html.theme-light {
270 + .shiki {
271 + overflow: hidden;
272 + background-color: transparent !important;
273 +
274 + span {
275 + background-color: transparent !important;
276 + }
277 + }
278 + }
279 +}
frontend/src/theme/index.ts
+3 -1
@@ -162,6 +162,7 @@ export function getCssVars(state: ThemeState, getters: ThemeGetters): { [key: st
162 const fontFamilyDisplay = state.fontFamily.display
163 const fontFamilyMono = state.fontFamily.mono
164 const fontSize = state.fontSize.default
165 + const lineHeight = state.lineHeight.default
166
167 const borderRadius = state.borderRadius.default
168 const borderRadiusSmall = state.borderRadius.small
@@ -195,7 +196,8 @@ export function getCssVars(state: ThemeState, getters: ThemeGetters): { [key: st
196 "font-family": `${fontFamily}`,
197 "font-family-display": `${fontFamilyDisplay}`,
198 "font-family-mono": `${fontFamilyMono}`,
198 - "font-size": `${fontSize}`
199 + "font-size": `${fontSize}`,
200 + "line-height": `${lineHeight}`
201 }
202
203 // import colors by patterns
frontend/src/types/common.d.ts
+10
@@ -9,3 +9,13 @@ export type ApiCommonResponse<T = unknown> = AxiosResponse<FlaskBaseResponse & T
9 export type DeepNullable<T> = {
10 [K in keyof T]: DeepNullable<T[K]> | null
11 }
12 +
13 +export type Nullable<T> = {
14 + [K in keyof T]: T[K] | null
15 +}
16 +
17 +export type RecursiveKeyOf<TObj extends object> = {
18 + [TKey in keyof TObj & (string | number)]: TObj[TKey] extends object
19 + ? `${TKey}` | `${TKey}.${RecursiveKeyOf<TObj[TKey]>}`
20 + : `${TKey}`
21 +}[keyof TObj & (string | number)]
frontend/src/utils/dayjs.ts
+6 -2
@@ -1,10 +1,15 @@
1 import dayjs from "dayjs"
2 -import locale_en from "dayjs/locale/en.js"
2 import customParseFormat from "dayjs/plugin/customParseFormat"
3 import duration from "dayjs/plugin/duration"
4 import relativeTime from "dayjs/plugin/relativeTime"
5 import timezone from "dayjs/plugin/timezone"
6 import utc from "dayjs/plugin/utc"
7 +import "dayjs/locale/it"
8 +import "dayjs/locale/en"
9 +import "dayjs/locale/de"
10 +import "dayjs/locale/es"
11 +import "dayjs/locale/fr"
12 +import "dayjs/locale/ja"
13 /*
14 import isSameOrAfter from "dayjs/plugin/isSameOrAfter"
15 dayjs.extend(isSameOrAfter)
@@ -14,7 +19,6 @@ dayjs.extend(relativeTime)
19 dayjs.extend(duration)
20 dayjs.extend(customParseFormat)
21 dayjs.extend(timezone)
17 -dayjs.locale(locale_en)
22 dayjs.tz.setDefault(dayjs.tz.guess())
23
24 export default dayjs
frontend/src/views/Auth.vue
+1 -3
@@ -88,13 +88,11 @@ onBeforeMount(() => {
88
89 &.centered {
90 flex-basis: 100%;
91 +
92 .form-wrap {
93 padding: 60px;
94 width: 100%;
95 max-width: 500px;
95 - background-color: var(--bg-default-color);
96 - border-radius: 20px;
97 - @apply shadow-xl;
96 }
97
98 @media (max-width: 600px) {
frontend/src/views/Indices.vue
+2 -2
@@ -107,11 +107,11 @@ onBeforeMount(() => {
107 <style lang="scss" scoped>
108 .page {
109 .section {
110 - @apply mb-6;
110 + margin-bottom: calc(var(--spacing) * 6);
111
112 .columns {
113 display: flex;
114 - @apply gap-6;
114 + gap: calc(var(--spacing) * 6);
115
116 .stretchy {
117 height: 100%;
frontend/src/views/Overview.vue
+2 -2
@@ -114,11 +114,11 @@ useResizeObserver(page, entries => {
114 <style lang="scss" scoped>
115 .page {
116 .section {
117 - @apply mb-6;
117 + margin-bottom: calc(var(--spacing) * 6);
118
119 .columns {
120 display: flex;
121 - @apply gap-6;
121 + gap: calc(var(--spacing) * 6);
122
123 .stretchy {
124 height: 100%;
frontend/src/views/Profile.vue
+2 -2
@@ -1,6 +1,6 @@
1 <template>
2 <div class="page">
3 - <n-card class="header flex flex-col" content-class="!p-0">
3 + <n-card class="header flex flex-col" content-class="p-0!">
4 <div class="user-info flex flex-wrap">
5 <div class="propic">
6 <n-avatar :size="100" :src="userPic" round :img-props="{ alt: 'avatar' }" />
@@ -39,7 +39,7 @@
39 </div>
40 </div>
41 <div class="actions">
42 - <ChangePassword :username="userName" size="small" />
42 + <ChangePassword :user="{ username: userName, id: 0, email: '' }" size="small" />
43
44 <ImageCropper
45 v-if="propicEnabled"
frontend/src/views/agents/Overview.vue
+4 -3
@@ -324,11 +324,11 @@ onBeforeMount(() => {
324 display: flex;
325 align-items: center;
326 line-height: 1;
327 - @apply gap-4;
327 + gap: calc(var(--spacing) * 4);
328
329 h1 {
330 margin: 0;
331 - @apply text-2xl;
331 + font-size: var(--text-2xl);
332 word-break: break-all;
333 }
334
@@ -344,7 +344,8 @@ onBeforeMount(() => {
344 }
345
346 .section {
347 - @apply mt-2 min-h-52;
347 + margin-top: calc(var(--spacing) * 2);
348 + min-height: 200px;
349 }
350 }
351 </style>
frontend/src/views/agents/SysmonConfig.vue
+1 -1
@@ -108,7 +108,7 @@
108 <n-spin
109 :show="loadingConfig || uploadingConfig || deployingConfig"
110 class="flex h-full w-full overflow-hidden"
111 - content-class="overflow-hidden grow h-full flex flex-col justify-center"
111 + content-class="flex h-full grow flex-col justify-center overflow-hidden"
112 >
113 <template v-if="currentConfig">
114 <XMLEditor
frontend/tailwind.config.js
-107
@@ -14,115 +14,8 @@ function getValue(origin, val) {
14 return val
15 }
16
17 -function remFromPX(px) {
18 - return {
19 - key: Number.parseFloat(_.toNumber(px / 4).toFixed(4)),
20 - rem: `${Number.parseFloat(_.toNumber(px / 16).toFixed(4))}rem`
21 - }
22 -}
23 -
17 export default {
25 - content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
26 - darkMode: ["selector", `.theme-dark`],
27 - theme: {
28 - fontFamily: {
29 - sans: ["var(--font-family)", "sans-serif"],
30 - serif: ["var(--font-family-display)", "serif"],
31 - display: ["var(--font-family-display)", "serif"],
32 - mono: ["var(--font-family-mono)", "monospace"]
33 - },
34 - extend: {
35 - colors: {
36 - primary: "rgb(var(--primary-color-rgb))",
37 - success: "rgb(var(--success-color-rgb))",
38 - error: "rgb(var(--error-color-rgb))",
39 - warning: "rgb(var(--warning-color-rgb))",
40 - info: "rgb(var(--info-color-rgb))",
41 - border: "rgb(var(--border-color-rgb))",
42 - hover: "rgb(var(--hover-color-rgb))",
43 - extra: {
44 - 1: "rgb(var(--extra1-color-rgb))",
45 - 2: "rgb(var(--extra2-color-rgb))",
46 - 3: "rgb(var(--extra3-color-rgb))",
47 - 4: "rgb(var(--extra4-color-rgb))"
48 - }
49 - },
50 - backgroundColor: {
51 - default: "rgb(var(--bg-default-color-rgb))",
52 - secondary: "rgb(var(--bg-secondary-color-rgb))",
53 - body: "rgb(var(--bg-body-color-rgb))",
54 - sidebar: "rgb(var(--bg-sidebar-color-rgb))"
55 - },
56 - textColor: {
57 - default: "rgb(var(--fg-default-color-rgb))",
58 - secondary: "rgb(var(--fg-secondary-color-rgb))",
59 - tertiary: "rgb(var(--fg-tertiary-color-rgb))"
60 - },
61 - animation: {
62 - fade: "fade 0.3s forwards"
63 - },
64 - keyframes: {
65 - fade: {
66 - from: { opacity: 0 },
67 - to: { opacity: 1 }
68 - }
69 - },
70 - screens: {
71 - xs: "460px"
72 - },
73 - height: {
74 - [remFromPX(3).key]: remFromPX(3).rem, // 0.75
75 - [remFromPX(600).key]: remFromPX(600).rem, // 150
76 - "60vh": "60vh"
77 - },
78 - minHeight: {
79 - 114: "28.5rem",
80 - 120: "30rem",
81 - [remFromPX(548).key]: remFromPX(548).rem // 137
82 - },
83 - maxHeight: {
84 - "50vh": "50vh",
85 - 106: "26.5rem",
86 - 125: "31.25rem",
87 - [remFromPX(600).key]: remFromPX(600).rem // 150
88 - },
89 - width: {
90 - [remFromPX(22).key]: remFromPX(22).rem, // 5.5
91 - [remFromPX(600).key]: remFromPX(600).rem, // 150
92 - "90vw": "90vw"
93 - },
94 - maxWidth: {
95 - "90vw": "90vw"
96 - },
97 - spacing: {
98 - "20vh": "20vh",
99 - "50vw": "50vw"
100 - }
101 - }
102 - },
103 - safelist: [
104 - "p-4",
105 - "py-4",
106 - "!p-1",
107 - "flex",
108 - "flex-col",
109 - "!justify-start",
110 - "opacity-50",
111 - "hover:text-red-500",
112 - "hover:opacity-100",
113 - "items-center",
114 - "gap-5",
115 - "w-72",
116 - "max-h-50vh",
117 - "max-w-90vw",
118 - "!h-0.75",
119 - "text-primary",
120 - "mx-1",
121 - "basis-1/4",
122 - "basis-1/5"
123 - ],
18 plugins: [
125 - require("@tailwindcss/container-queries"),
19 plugin(({ addBase, theme }) => {
20 addBase({
21 h1: {
frontend/vite.config.ts
+4 -1
@@ -1,6 +1,7 @@
1 import fs from "node:fs"
2 import process from "node:process"
3 import { fileURLToPath, URL } from "node:url"
4 +import tailwindcss from "@tailwindcss/vite"
5 import vue from "@vitejs/plugin-vue"
6 import vueJsx from "@vitejs/plugin-vue-jsx"
7 import { defineConfig, loadEnv } from "vite"
@@ -16,6 +17,7 @@ export default defineConfig(({ mode }) => {
17
18 return {
19 plugins: [
20 + tailwindcss(),
21 vue({
22 script: {
23 defineModel: true
@@ -29,7 +31,8 @@ export default defineConfig(({ mode }) => {
31 ],
32 resolve: {
33 alias: {
32 - "@": fileURLToPath(new URL("./src", import.meta.url))
34 + "@": fileURLToPath(new URL("./src", import.meta.url)),
35 + "node:process": "process/browser"
36 }
37 },
38 optimizeDeps: {