diff --git a/cypress.config.js b/cypress.config.js
index 1100b59b1e7..c21fd581911 100644
--- a/cypress.config.js
+++ b/cypress.config.js
@@ -34,5 +34,7 @@ module.exports = defineConfig({
             require('cypress-mochawesome-reporter/plugin')(on);
             // implement node event listeners here
         },
+        viewportWidth: 1280,
+        viewportHeight: 720,
     },
 });
diff --git a/package.json b/package.json
index 9d14e8727b6..8071d262f1e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
     "name": "salix-front",
-    "version": "25.04.0",
+    "version": "25.06.0",
     "description": "Salix frontend",
     "productName": "Salix",
     "author": "Verdnatura",
@@ -21,24 +21,24 @@
     },
     "dependencies": {
         "@quasar/cli": "^2.3.0",
-        "@quasar/extras": "^1.16.9",
+        "@quasar/extras": "^1.16.14",
         "axios": "^1.4.0",
         "chromium": "^3.0.3",
         "croppie": "^2.6.5",
         "moment": "^2.30.1",
         "pinia": "^2.1.3",
-        "quasar": "^2.14.5",
+        "quasar": "^2.17.4",
         "validator": "^13.9.0",
-        "vue": "^3.3.4",
-        "vue-i18n": "^9.2.2",
-        "vue-router": "^4.2.1"
+        "vue": "^3.5.13",
+        "vue-i18n": "^9.3.0",
+        "vue-router": "^4.2.5"
     },
     "devDependencies": {
         "@commitlint/cli": "^19.2.1",
         "@commitlint/config-conventional": "^19.1.0",
         "@intlify/unplugin-vue-i18n": "^0.8.1",
         "@pinia/testing": "^0.1.2",
-        "@quasar/app-vite": "^1.7.3",
+        "@quasar/app-vite": "^1.11.0",
         "@quasar/quasar-app-extension-qcalendar": "4.0.0-beta.15",
         "@quasar/quasar-app-extension-testing-unit-vitest": "^0.4.0",
         "@vue/test-utils": "^2.4.4",
@@ -52,7 +52,7 @@
         "husky": "^8.0.0",
         "postcss": "^8.4.23",
         "prettier": "^2.8.8",
-        "vitest": "^0.31.1"
+        "vitest": "^0.34.0"
     },
     "engines": {
         "node": "^20 || ^18 || ^16",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7bf640347e4..fe53485a278 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -9,8 +9,8 @@ dependencies:
     specifier: ^2.3.0
     version: 2.3.0
   '@quasar/extras':
-    specifier: ^1.16.9
-    version: 1.16.9
+    specifier: ^1.16.14
+    version: 1.16.15
   axios:
     specifier: ^1.4.0
     version: 1.6.7
@@ -25,27 +25,27 @@ dependencies:
     version: 2.30.1
   pinia:
     specifier: ^2.1.3
-    version: 2.1.7(typescript@5.5.4)(vue@3.4.19)
+    version: 2.1.7(typescript@5.5.4)(vue@3.5.13)
   quasar:
-    specifier: ^2.14.5
-    version: 2.14.5
+    specifier: ^2.17.4
+    version: 2.17.7
   validator:
     specifier: ^13.9.0
     version: 13.11.0
   vue:
-    specifier: ^3.3.4
-    version: 3.4.19(typescript@5.5.4)
+    specifier: ^3.5.13
+    version: 3.5.13(typescript@5.5.4)
   vue-i18n:
-    specifier: ^9.2.2
-    version: 9.9.1(vue@3.4.19)
+    specifier: ^9.3.0
+    version: 9.9.1(vue@3.5.13)
   vue-router:
-    specifier: ^4.2.1
-    version: 4.2.5(vue@3.4.19)
+    specifier: ^4.2.5
+    version: 4.2.5(vue@3.5.13)
 
 devDependencies:
   '@commitlint/cli':
     specifier: ^19.2.1
-    version: 19.4.0(@types/node@20.11.19)(typescript@5.5.4)
+    version: 19.4.0(@types/node@22.10.7)(typescript@5.5.4)
   '@commitlint/config-conventional':
     specifier: ^19.1.0
     version: 19.2.2
@@ -54,19 +54,19 @@ devDependencies:
     version: 0.8.2(vue-i18n@9.9.1)
   '@pinia/testing':
     specifier: ^0.1.2
-    version: 0.1.3(pinia@2.1.7)(vue@3.4.19)
+    version: 0.1.3(pinia@2.1.7)(vue@3.5.13)
   '@quasar/app-vite':
-    specifier: ^1.7.3
-    version: 1.7.3(eslint@8.56.0)(pinia@2.1.7)(quasar@2.14.5)(vue-router@4.2.5)(vue@3.4.19)
+    specifier: ^1.11.0
+    version: 1.11.0(eslint@8.56.0)(pinia@2.1.7)(quasar@2.17.7)(vue-router@4.2.5)(vue@3.5.13)
   '@quasar/quasar-app-extension-qcalendar':
     specifier: 4.0.0-beta.15
     version: 4.0.0-beta.15
   '@quasar/quasar-app-extension-testing-unit-vitest':
     specifier: ^0.4.0
-    version: 0.4.0(@vue/test-utils@2.4.4)(quasar@2.14.5)(typescript@5.5.4)(vite@5.1.4)(vitest@0.31.4)(vue@3.4.19)
+    version: 0.4.0(@vue/test-utils@2.4.4)(quasar@2.17.7)(typescript@5.5.4)(vite@5.1.4)(vitest@0.34.6)(vue@3.5.13)
   '@vue/test-utils':
     specifier: ^2.4.4
-    version: 2.4.4(vue@3.4.19)
+    version: 2.4.4(vue@3.5.13)
   autoprefixer:
     specifier: ^10.4.14
     version: 10.4.17(postcss@8.4.35)
@@ -98,8 +98,8 @@ devDependencies:
     specifier: ^2.8.8
     version: 2.8.8
   vitest:
-    specifier: ^0.31.1
-    version: 0.31.4
+    specifier: ^0.34.0
+    version: 0.34.6
 
 packages:
 
@@ -119,16 +119,26 @@ packages:
   /@babel/helper-string-parser@7.23.4:
     resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==}
     engines: {node: '>=6.9.0'}
+    dev: true
+
+  /@babel/helper-string-parser@7.25.9:
+    resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
+    engines: {node: '>=6.9.0'}
 
   /@babel/helper-validator-identifier@7.22.20:
     resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
     engines: {node: '>=6.9.0'}
+    dev: true
 
   /@babel/helper-validator-identifier@7.24.7:
     resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==}
     engines: {node: '>=6.9.0'}
     dev: true
 
+  /@babel/helper-validator-identifier@7.25.9:
+    resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
+    engines: {node: '>=6.9.0'}
+
   /@babel/highlight@7.24.7:
     resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==}
     engines: {node: '>=6.9.0'}
@@ -145,6 +155,14 @@ packages:
     hasBin: true
     dependencies:
       '@babel/types': 7.23.9
+    dev: true
+
+  /@babel/parser@7.26.5:
+    resolution: {integrity: sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==}
+    engines: {node: '>=6.0.0'}
+    hasBin: true
+    dependencies:
+      '@babel/types': 7.26.5
 
   /@babel/types@7.23.9:
     resolution: {integrity: sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==}
@@ -153,6 +171,14 @@ packages:
       '@babel/helper-string-parser': 7.23.4
       '@babel/helper-validator-identifier': 7.22.20
       to-fast-properties: 2.0.0
+    dev: true
+
+  /@babel/types@7.26.5:
+    resolution: {integrity: sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/helper-string-parser': 7.25.9
+      '@babel/helper-validator-identifier': 7.25.9
 
   /@colors/colors@1.5.0:
     resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
@@ -161,14 +187,14 @@ packages:
     dev: true
     optional: true
 
-  /@commitlint/cli@19.4.0(@types/node@20.11.19)(typescript@5.5.4):
+  /@commitlint/cli@19.4.0(@types/node@22.10.7)(typescript@5.5.4):
     resolution: {integrity: sha512-sJX4J9UioVwZHq7JWM9tjT5bgWYaIN3rC4FP7YwfEwBYiIO+wMyRttRvQLNkow0vCdM0D67r9NEWU0Ui03I4Eg==}
     engines: {node: '>=v18'}
     hasBin: true
     dependencies:
       '@commitlint/format': 19.3.0
       '@commitlint/lint': 19.2.2
-      '@commitlint/load': 19.4.0(@types/node@20.11.19)(typescript@5.5.4)
+      '@commitlint/load': 19.4.0(@types/node@22.10.7)(typescript@5.5.4)
       '@commitlint/read': 19.4.0
       '@commitlint/types': 19.0.3
       execa: 8.0.1
@@ -237,7 +263,7 @@ packages:
       '@commitlint/types': 19.0.3
     dev: true
 
-  /@commitlint/load@19.4.0(@types/node@20.11.19)(typescript@5.5.4):
+  /@commitlint/load@19.4.0(@types/node@22.10.7)(typescript@5.5.4):
     resolution: {integrity: sha512-I4lCWaEZYQJ1y+Y+gdvbGAx9pYPavqZAZ3/7/8BpWh+QjscAn8AjsUpLV2PycBsEx7gupq5gM4BViV9xwTIJuw==}
     engines: {node: '>=v18'}
     dependencies:
@@ -247,7 +273,7 @@ packages:
       '@commitlint/types': 19.0.3
       chalk: 5.3.0
       cosmiconfig: 9.0.0(typescript@5.5.4)
-      cosmiconfig-typescript-loader: 5.0.0(@types/node@20.11.19)(cosmiconfig@9.0.0)(typescript@5.5.4)
+      cosmiconfig-typescript-loader: 5.0.0(@types/node@22.10.7)(cosmiconfig@9.0.0)(typescript@5.5.4)
       lodash.isplainobject: 4.0.6
       lodash.merge: 4.6.2
       lodash.uniq: 4.5.0
@@ -370,15 +396,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/android-arm64@0.18.20:
-    resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [android]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/android-arm64@0.19.12:
     resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==}
     engines: {node: '>=12'}
@@ -388,15 +405,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/android-arm@0.18.20:
-    resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==}
-    engines: {node: '>=12'}
-    cpu: [arm]
-    os: [android]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/android-arm@0.19.12:
     resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==}
     engines: {node: '>=12'}
@@ -406,15 +414,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/android-x64@0.18.20:
-    resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [android]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/android-x64@0.19.12:
     resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==}
     engines: {node: '>=12'}
@@ -424,15 +423,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/darwin-arm64@0.18.20:
-    resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [darwin]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/darwin-arm64@0.19.12:
     resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==}
     engines: {node: '>=12'}
@@ -442,15 +432,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/darwin-x64@0.18.20:
-    resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [darwin]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/darwin-x64@0.19.12:
     resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==}
     engines: {node: '>=12'}
@@ -460,15 +441,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/freebsd-arm64@0.18.20:
-    resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [freebsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/freebsd-arm64@0.19.12:
     resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==}
     engines: {node: '>=12'}
@@ -478,15 +450,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/freebsd-x64@0.18.20:
-    resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [freebsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/freebsd-x64@0.19.12:
     resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==}
     engines: {node: '>=12'}
@@ -496,15 +459,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-arm64@0.18.20:
-    resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/linux-arm64@0.19.12:
     resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==}
     engines: {node: '>=12'}
@@ -514,15 +468,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-arm@0.18.20:
-    resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==}
-    engines: {node: '>=12'}
-    cpu: [arm]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/linux-arm@0.19.12:
     resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==}
     engines: {node: '>=12'}
@@ -532,15 +477,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-ia32@0.18.20:
-    resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==}
-    engines: {node: '>=12'}
-    cpu: [ia32]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/linux-ia32@0.19.12:
     resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==}
     engines: {node: '>=12'}
@@ -550,15 +486,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-loong64@0.18.20:
-    resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==}
-    engines: {node: '>=12'}
-    cpu: [loong64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/linux-loong64@0.19.12:
     resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==}
     engines: {node: '>=12'}
@@ -568,15 +495,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-mips64el@0.18.20:
-    resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==}
-    engines: {node: '>=12'}
-    cpu: [mips64el]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/linux-mips64el@0.19.12:
     resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==}
     engines: {node: '>=12'}
@@ -586,15 +504,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-ppc64@0.18.20:
-    resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==}
-    engines: {node: '>=12'}
-    cpu: [ppc64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/linux-ppc64@0.19.12:
     resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==}
     engines: {node: '>=12'}
@@ -604,15 +513,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-riscv64@0.18.20:
-    resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==}
-    engines: {node: '>=12'}
-    cpu: [riscv64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/linux-riscv64@0.19.12:
     resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==}
     engines: {node: '>=12'}
@@ -622,15 +522,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-s390x@0.18.20:
-    resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==}
-    engines: {node: '>=12'}
-    cpu: [s390x]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/linux-s390x@0.19.12:
     resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==}
     engines: {node: '>=12'}
@@ -640,15 +531,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-x64@0.18.20:
-    resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/linux-x64@0.19.12:
     resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==}
     engines: {node: '>=12'}
@@ -658,15 +540,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/netbsd-x64@0.18.20:
-    resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [netbsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/netbsd-x64@0.19.12:
     resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==}
     engines: {node: '>=12'}
@@ -676,15 +549,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/openbsd-x64@0.18.20:
-    resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [openbsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/openbsd-x64@0.19.12:
     resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==}
     engines: {node: '>=12'}
@@ -694,15 +558,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/sunos-x64@0.18.20:
-    resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [sunos]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/sunos-x64@0.19.12:
     resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==}
     engines: {node: '>=12'}
@@ -712,15 +567,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/win32-arm64@0.18.20:
-    resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [win32]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/win32-arm64@0.19.12:
     resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==}
     engines: {node: '>=12'}
@@ -730,15 +576,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/win32-ia32@0.18.20:
-    resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==}
-    engines: {node: '>=12'}
-    cpu: [ia32]
-    os: [win32]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/win32-ia32@0.19.12:
     resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==}
     engines: {node: '>=12'}
@@ -748,15 +585,6 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/win32-x64@0.18.20:
-    resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [win32]
-    requiresBuild: true
-    dev: true
-    optional: true
-
   /@esbuild/win32-x64@0.19.12:
     resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==}
     engines: {node: '>=12'}
@@ -839,7 +667,7 @@ packages:
       '@intlify/shared': 11.0.0-rc.1
       jsonc-eslint-parser: 1.4.1
       source-map: 0.6.1
-      vue-i18n: 9.9.1(vue@3.4.19)
+      vue-i18n: 9.9.1(vue@3.5.13)
       yaml-eslint-parser: 0.3.2
     dev: true
 
@@ -901,7 +729,7 @@ packages:
       picocolors: 1.0.0
       source-map: 0.6.1
       unplugin: 1.7.1
-      vue-i18n: 9.9.1(vue@3.4.19)
+      vue-i18n: 9.9.1(vue@3.5.13)
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -918,6 +746,13 @@ packages:
       wrap-ansi-cjs: /wrap-ansi@7.0.0
     dev: true
 
+  /@jest/schemas@29.6.3:
+    resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
+    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+    dependencies:
+      '@sinclair/typebox': 0.27.8
+    dev: true
+
   /@jridgewell/gen-mapping@0.3.3:
     resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
     engines: {node: '>=6.0.0'}
@@ -927,6 +762,15 @@ packages:
       '@jridgewell/trace-mapping': 0.3.22
     dev: true
 
+  /@jridgewell/gen-mapping@0.3.8:
+    resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
+    engines: {node: '>=6.0.0'}
+    dependencies:
+      '@jridgewell/set-array': 1.2.1
+      '@jridgewell/sourcemap-codec': 1.4.15
+      '@jridgewell/trace-mapping': 0.3.25
+    dev: true
+
   /@jridgewell/resolve-uri@3.1.2:
     resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
     engines: {node: '>=6.0.0'}
@@ -937,8 +781,24 @@ packages:
     engines: {node: '>=6.0.0'}
     dev: true
 
+  /@jridgewell/set-array@1.2.1:
+    resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
+    engines: {node: '>=6.0.0'}
+    dev: true
+
+  /@jridgewell/source-map@0.3.6:
+    resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==}
+    dependencies:
+      '@jridgewell/gen-mapping': 0.3.8
+      '@jridgewell/trace-mapping': 0.3.25
+    dev: true
+
   /@jridgewell/sourcemap-codec@1.4.15:
     resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+    dev: true
+
+  /@jridgewell/sourcemap-codec@1.5.0:
+    resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
 
   /@jridgewell/trace-mapping@0.3.22:
     resolution: {integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==}
@@ -947,6 +807,13 @@ packages:
       '@jridgewell/sourcemap-codec': 1.4.15
     dev: true
 
+  /@jridgewell/trace-mapping@0.3.25:
+    resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+    dependencies:
+      '@jridgewell/resolve-uri': 3.1.2
+      '@jridgewell/sourcemap-codec': 1.4.15
+    dev: true
+
   /@nodelib/fs.scandir@2.1.5:
     resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
     engines: {node: '>= 8'}
@@ -972,13 +839,156 @@ packages:
     resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
     dev: true
 
-  /@pinia/testing@0.1.3(pinia@2.1.7)(vue@3.4.19):
+  /@parcel/watcher-android-arm64@2.5.0:
+    resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [arm64]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher-darwin-arm64@2.5.0:
+    resolution: {integrity: sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [arm64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher-darwin-x64@2.5.0:
+    resolution: {integrity: sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [x64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher-freebsd-x64@2.5.0:
+    resolution: {integrity: sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [x64]
+    os: [freebsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher-linux-arm-glibc@2.5.0:
+    resolution: {integrity: sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [arm]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher-linux-arm-musl@2.5.0:
+    resolution: {integrity: sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [arm]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher-linux-arm64-glibc@2.5.0:
+    resolution: {integrity: sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [arm64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher-linux-arm64-musl@2.5.0:
+    resolution: {integrity: sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [arm64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher-linux-x64-glibc@2.5.0:
+    resolution: {integrity: sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [x64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher-linux-x64-musl@2.5.0:
+    resolution: {integrity: sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [x64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher-win32-arm64@2.5.0:
+    resolution: {integrity: sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [arm64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher-win32-ia32@2.5.0:
+    resolution: {integrity: sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [ia32]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher-win32-x64@2.5.0:
+    resolution: {integrity: sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==}
+    engines: {node: '>= 10.0.0'}
+    cpu: [x64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@parcel/watcher@2.5.0:
+    resolution: {integrity: sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==}
+    engines: {node: '>= 10.0.0'}
+    requiresBuild: true
+    dependencies:
+      detect-libc: 1.0.3
+      is-glob: 4.0.3
+      micromatch: 4.0.5
+      node-addon-api: 7.1.1
+    optionalDependencies:
+      '@parcel/watcher-android-arm64': 2.5.0
+      '@parcel/watcher-darwin-arm64': 2.5.0
+      '@parcel/watcher-darwin-x64': 2.5.0
+      '@parcel/watcher-freebsd-x64': 2.5.0
+      '@parcel/watcher-linux-arm-glibc': 2.5.0
+      '@parcel/watcher-linux-arm-musl': 2.5.0
+      '@parcel/watcher-linux-arm64-glibc': 2.5.0
+      '@parcel/watcher-linux-arm64-musl': 2.5.0
+      '@parcel/watcher-linux-x64-glibc': 2.5.0
+      '@parcel/watcher-linux-x64-musl': 2.5.0
+      '@parcel/watcher-win32-arm64': 2.5.0
+      '@parcel/watcher-win32-ia32': 2.5.0
+      '@parcel/watcher-win32-x64': 2.5.0
+    dev: true
+    optional: true
+
+  /@pinia/testing@0.1.3(pinia@2.1.7)(vue@3.5.13):
     resolution: {integrity: sha512-D2Ds2s69kKFaRf2KCcP1NhNZEg5+we59aRyQalwRm7ygWfLM25nDH66267U3hNvRUOTx8ofL24GzodZkOmB5xw==}
     peerDependencies:
       pinia: '>=2.1.5'
     dependencies:
-      pinia: 2.1.7(typescript@5.5.4)(vue@3.4.19)
-      vue-demi: 0.14.7(vue@3.4.19)
+      pinia: 2.1.7(typescript@5.5.4)(vue@3.5.13)
+      vue-demi: 0.14.7(vue@3.5.13)
     transitivePeerDependencies:
       - '@vue/composition-api'
       - vue
@@ -1012,21 +1022,24 @@ packages:
       config-chain: 1.1.13
     dev: false
 
-  /@quasar/app-vite@1.7.3(eslint@8.56.0)(pinia@2.1.7)(quasar@2.14.5)(vue-router@4.2.5)(vue@3.4.19):
-    resolution: {integrity: sha512-pnDInCFP9M1d7lJzS8UkiFq8bGWdekLz8Gu+NLI9UAxruIM9QVlSD4hUmWptTQXaVEvYlDnqfW3LOr57B8eVtw==}
+  /@quasar/app-vite@1.11.0(eslint@8.56.0)(pinia@2.1.7)(quasar@2.17.7)(vue-router@4.2.5)(vue@3.5.13):
+    resolution: {integrity: sha512-PUeqtYs2liA/O17LJ25jzKckB0MG1ZW/iuDC7NvCMZpYT6Ab66AypiYfPf4WGWeAqricorHVNRyMfMpTscR/hA==}
     engines: {node: ^24 || ^22 || ^20 || ^18 || ^16 || ^14.19, npm: '>= 6.14.12', yarn: '>= 1.17.3'}
     hasBin: true
     peerDependencies:
+      '@electron/packager': '>= 18'
       electron-builder: '>= 22'
       electron-packager: '>= 15'
       eslint: ^8.11.0
       pinia: ^2.0.0
-      quasar: ^2.14.0
+      quasar: ^2.16.0
       vue: ^3.2.29
       vue-router: ^4.0.12
       vuex: ^4.0.0
-      workbox-build: '>= 6'
+      workbox-build: ^6 || 7.0.x
     peerDependenciesMeta:
+      '@electron/packager':
+        optional: true
       electron-builder:
         optional: true
       electron-packager:
@@ -1041,13 +1054,13 @@ packages:
         optional: true
     dependencies:
       '@quasar/render-ssr-error': 1.0.3
-      '@quasar/vite-plugin': 1.6.0(@vitejs/plugin-vue@2.3.4)(quasar@2.14.5)(vite@2.9.17)(vue@3.4.19)
+      '@quasar/vite-plugin': 1.9.0(@vitejs/plugin-vue@2.3.4)(quasar@2.17.7)(vite@2.9.17)(vue@3.5.13)
       '@rollup/pluginutils': 4.2.1
       '@types/chrome': 0.0.208
       '@types/compression': 1.7.5
       '@types/cordova': 0.0.34
       '@types/express': 4.17.21
-      '@vitejs/plugin-vue': 2.3.4(vite@5.1.4)(vue@3.4.19)
+      '@vitejs/plugin-vue': 2.3.4(vite@5.1.4)(vue@3.5.13)
       archiver: 5.3.2
       chokidar: 3.6.0
       ci-info: 3.9.0
@@ -1060,24 +1073,24 @@ packages:
       express: 4.18.2
       fast-glob: 3.2.12
       fs-extra: 11.2.0
-      html-minifier: 4.0.0
+      html-minifier-terser: 7.2.0
       inquirer: 8.2.6
       isbinaryfile: 5.0.2
       kolorist: 1.8.0
       lodash: 4.17.21
       minimist: 1.2.8
       open: 8.4.2
-      pinia: 2.1.7(typescript@5.5.4)(vue@3.4.19)
-      quasar: 2.14.5
+      pinia: 2.1.7(typescript@5.5.4)(vue@3.5.13)
+      quasar: 2.17.7
       register-service-worker: 1.7.2
       rollup-plugin-visualizer: 5.12.0
-      sass: 1.71.1
+      sass: 1.83.4
       semver: 7.6.0
       serialize-javascript: 6.0.2
       table: 6.8.1
-      vite: 2.9.17(sass@1.71.1)
-      vue: 3.4.19(typescript@5.5.4)
-      vue-router: 4.2.5(vue@3.4.19)
+      vite: 2.9.17(sass@1.83.4)
+      vue: 3.5.13(typescript@5.5.4)
+      vue-router: 4.2.5(vue@3.5.13)
       webpack-merge: 5.10.0
     transitivePeerDependencies:
       - less
@@ -1112,8 +1125,8 @@ packages:
       - supports-color
     dev: false
 
-  /@quasar/extras@1.16.9:
-    resolution: {integrity: sha512-SlOhwzXyPQHWgQIS2ncyDdYdksCJvUYNtgsDQqzAKEG3r3d/ejOxvThle79HTK3Q6HB+gQWFG21Ux00Osr5XSw==}
+  /@quasar/extras@1.16.15:
+    resolution: {integrity: sha512-ZM8rUAagZ3Gm7Thu6DjKdGfkyFBv61RaCeVSIWdve6+q300yN+6aouxttf2RmxCk12RsSqEyzBnIg7BlF1s7MA==}
     dev: false
 
   /@quasar/quasar-app-extension-qcalendar@4.0.0-beta.15:
@@ -1123,7 +1136,7 @@ packages:
       '@quasar/quasar-ui-qcalendar': 4.0.0-beta.19
     dev: true
 
-  /@quasar/quasar-app-extension-testing-unit-vitest@0.4.0(@vue/test-utils@2.4.4)(quasar@2.14.5)(typescript@5.5.4)(vite@5.1.4)(vitest@0.31.4)(vue@3.4.19):
+  /@quasar/quasar-app-extension-testing-unit-vitest@0.4.0(@vue/test-utils@2.4.4)(quasar@2.17.7)(typescript@5.5.4)(vite@5.1.4)(vitest@0.34.6)(vue@3.5.13):
     resolution: {integrity: sha512-eyzdUdmZiCueNS+5nedjMmzdbpCetSrtdGIwW6KplW1dTzRbLiNvYUjpBOxQGmJCgEhWy9zuswJ7MZ/bTql24Q==}
     engines: {node: '>= 12.22.1', npm: '>= 6.14.12', yarn: '>= 1.17.3'}
     peerDependencies:
@@ -1136,14 +1149,14 @@ packages:
       '@vitest/ui':
         optional: true
     dependencies:
-      '@vue/test-utils': 2.4.4(vue@3.4.19)
+      '@vue/test-utils': 2.4.4(vue@3.5.13)
       happy-dom: 11.2.0
       lodash-es: 4.17.21
-      quasar: 2.14.5
+      quasar: 2.17.7
       vite-jsconfig-paths: 2.0.1(vite@5.1.4)
       vite-tsconfig-paths: 4.3.1(typescript@5.5.4)(vite@5.1.4)
-      vitest: 0.31.4
-      vue: 3.4.19(typescript@5.5.4)
+      vitest: 0.34.6
+      vue: 3.5.13(typescript@5.5.4)
     transitivePeerDependencies:
       - supports-color
       - typescript
@@ -1169,19 +1182,19 @@ packages:
       selfsigned: 2.4.1
     dev: false
 
-  /@quasar/vite-plugin@1.6.0(@vitejs/plugin-vue@2.3.4)(quasar@2.14.5)(vite@2.9.17)(vue@3.4.19):
-    resolution: {integrity: sha512-LmbV76G1CwWZbrEQhqyZpkRQTJyO3xpW55aXY1zWN+JhyUeG77CcMCEWteBVnJ6I6ehUPFDC9ONd2+WlwH6rNQ==}
-    engines: {node: '>=12'}
+  /@quasar/vite-plugin@1.9.0(@vitejs/plugin-vue@2.3.4)(quasar@2.17.7)(vite@2.9.17)(vue@3.5.13):
+    resolution: {integrity: sha512-r1MFtI2QZJ2g20pe75Zuv4aoi0uoK8oP0yEdzLWRoOLCbhtf2+StJpUza9TydYi3KcvCl9+4HUf3OAWVKoxDmQ==}
+    engines: {node: '>=18'}
     peerDependencies:
-      '@vitejs/plugin-vue': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-beta.0
-      quasar: ^2.8.0
-      vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-beta.0
+      '@vitejs/plugin-vue': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0
+      quasar: ^2.16.0
+      vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0
       vue: ^3.0.0
     dependencies:
-      '@vitejs/plugin-vue': 2.3.4(vite@5.1.4)(vue@3.4.19)
-      quasar: 2.14.5
-      vite: 2.9.17(sass@1.71.1)
-      vue: 3.4.19(typescript@5.5.4)
+      '@vitejs/plugin-vue': 2.3.4(vite@5.1.4)(vue@3.5.13)
+      quasar: 2.17.7
+      vite: 2.9.17(sass@1.83.4)
+      vue: 3.5.13(typescript@5.5.4)
     dev: true
 
   /@rollup/pluginutils@4.2.1:
@@ -1296,6 +1309,10 @@ packages:
     dev: true
     optional: true
 
+  /@sinclair/typebox@0.27.8:
+    resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
+    dev: true
+
   /@sindresorhus/is@4.6.0:
     resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
     engines: {node: '>=10'}
@@ -1324,7 +1341,7 @@ packages:
     resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
     dependencies:
       '@types/connect': 3.4.38
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
     dev: true
 
   /@types/cacheable-request@6.0.3:
@@ -1332,7 +1349,7 @@ packages:
     dependencies:
       '@types/http-cache-semantics': 4.0.4
       '@types/keyv': 3.1.4
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
       '@types/responselike': 1.0.3
     dev: false
 
@@ -1362,13 +1379,13 @@ packages:
   /@types/connect@3.4.38:
     resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
     dependencies:
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
     dev: true
 
   /@types/conventional-commits-parser@5.0.0:
     resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==}
     dependencies:
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
     dev: true
 
   /@types/cordova@0.0.34:
@@ -1382,7 +1399,7 @@ packages:
   /@types/express-serve-static-core@4.17.43:
     resolution: {integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==}
     dependencies:
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
       '@types/qs': 6.9.11
       '@types/range-parser': 1.2.7
       '@types/send': 0.17.4
@@ -1422,7 +1439,7 @@ packages:
   /@types/http-proxy@1.17.14:
     resolution: {integrity: sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==}
     dependencies:
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
     dev: false
 
   /@types/json5@0.0.29:
@@ -1432,7 +1449,7 @@ packages:
   /@types/keyv@3.1.4:
     resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
     dependencies:
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
     dev: false
 
   /@types/mime@1.3.5:
@@ -1446,13 +1463,13 @@ packages:
   /@types/node-forge@1.3.11:
     resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
     dependencies:
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
     dev: false
 
-  /@types/node@20.11.19:
-    resolution: {integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==}
+  /@types/node@22.10.7:
+    resolution: {integrity: sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==}
     dependencies:
-      undici-types: 5.26.5
+      undici-types: 6.20.0
 
   /@types/qs@6.9.11:
     resolution: {integrity: sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==}
@@ -1465,14 +1482,14 @@ packages:
   /@types/responselike@1.0.3:
     resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==}
     dependencies:
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
     dev: false
 
   /@types/send@0.17.4:
     resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==}
     dependencies:
       '@types/mime': 1.3.5
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
     dev: true
 
   /@types/serve-static@1.15.5:
@@ -1480,7 +1497,7 @@ packages:
     dependencies:
       '@types/http-errors': 2.0.4
       '@types/mime': 3.0.4
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
     dev: true
 
   /@types/sinonjs__fake-timers@8.1.1:
@@ -1495,7 +1512,7 @@ packages:
     resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
     requiresBuild: true
     dependencies:
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
     dev: true
     optional: true
 
@@ -1503,54 +1520,53 @@ packages:
     resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
     dev: true
 
-  /@vitejs/plugin-vue@2.3.4(vite@5.1.4)(vue@3.4.19):
+  /@vitejs/plugin-vue@2.3.4(vite@5.1.4)(vue@3.5.13):
     resolution: {integrity: sha512-IfFNbtkbIm36O9KB8QodlwwYvTEsJb4Lll4c2IwB3VHc2gie2mSPtSzL0eYay7X2jd/2WX02FjSGTWR6OPr/zg==}
     engines: {node: '>=12.0.0'}
     peerDependencies:
       vite: ^2.5.10
       vue: ^3.2.25
     dependencies:
-      vite: 5.1.4(@types/node@20.11.19)
-      vue: 3.4.19(typescript@5.5.4)
+      vite: 5.1.4(@types/node@22.10.7)
+      vue: 3.5.13(typescript@5.5.4)
     dev: true
 
-  /@vitest/expect@0.31.4:
-    resolution: {integrity: sha512-tibyx8o7GUyGHZGyPgzwiaPaLDQ9MMuCOrc03BYT0nryUuhLbL7NV2r/q98iv5STlwMgaKuFJkgBW/8iPKwlSg==}
+  /@vitest/expect@0.34.6:
+    resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==}
     dependencies:
-      '@vitest/spy': 0.31.4
-      '@vitest/utils': 0.31.4
+      '@vitest/spy': 0.34.6
+      '@vitest/utils': 0.34.6
       chai: 4.4.1
     dev: true
 
-  /@vitest/runner@0.31.4:
-    resolution: {integrity: sha512-Wgm6UER+gwq6zkyrm5/wbpXGF+g+UBB78asJlFkIOwyse0pz8lZoiC6SW5i4gPnls/zUcPLWS7Zog0LVepXnpg==}
+  /@vitest/runner@0.34.6:
+    resolution: {integrity: sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==}
     dependencies:
-      '@vitest/utils': 0.31.4
-      concordance: 5.0.4
+      '@vitest/utils': 0.34.6
       p-limit: 4.0.0
       pathe: 1.1.2
     dev: true
 
-  /@vitest/snapshot@0.31.4:
-    resolution: {integrity: sha512-LemvNumL3NdWSmfVAMpXILGyaXPkZbG5tyl6+RQSdcHnTj6hvA49UAI8jzez9oQyE/FWLKRSNqTGzsHuk89LRA==}
+  /@vitest/snapshot@0.34.6:
+    resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==}
     dependencies:
       magic-string: 0.30.7
       pathe: 1.1.2
-      pretty-format: 27.5.1
+      pretty-format: 29.7.0
     dev: true
 
-  /@vitest/spy@0.31.4:
-    resolution: {integrity: sha512-3ei5ZH1s3aqbEyftPAzSuunGICRuhE+IXOmpURFdkm5ybUADk+viyQfejNk6q8M5QGX8/EVKw+QWMEP3DTJDag==}
+  /@vitest/spy@0.34.6:
+    resolution: {integrity: sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==}
     dependencies:
       tinyspy: 2.2.1
     dev: true
 
-  /@vitest/utils@0.31.4:
-    resolution: {integrity: sha512-DobZbHacWznoGUfYU8XDPY78UubJxXfMNY1+SUdOp1NsI34eopSA6aZMeaGu10waSOeYwE8lxrd/pLfT0RMxjQ==}
+  /@vitest/utils@0.34.6:
+    resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==}
     dependencies:
-      concordance: 5.0.4
+      diff-sequences: 29.6.3
       loupe: 2.3.7
-      pretty-format: 27.5.1
+      pretty-format: 29.7.0
     dev: true
 
   /@vue/compiler-core@3.4.19:
@@ -1561,12 +1577,29 @@ packages:
       entities: 4.5.0
       estree-walker: 2.0.2
       source-map-js: 1.0.2
+    dev: true
+
+  /@vue/compiler-core@3.5.13:
+    resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==}
+    dependencies:
+      '@babel/parser': 7.26.5
+      '@vue/shared': 3.5.13
+      entities: 4.5.0
+      estree-walker: 2.0.2
+      source-map-js: 1.2.1
 
   /@vue/compiler-dom@3.4.19:
     resolution: {integrity: sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==}
     dependencies:
       '@vue/compiler-core': 3.4.19
       '@vue/shared': 3.4.19
+    dev: true
+
+  /@vue/compiler-dom@3.5.13:
+    resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==}
+    dependencies:
+      '@vue/compiler-core': 3.5.13
+      '@vue/shared': 3.5.13
 
   /@vue/compiler-sfc@3.4.19:
     resolution: {integrity: sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==}
@@ -1580,47 +1613,73 @@ packages:
       magic-string: 0.30.7
       postcss: 8.4.35
       source-map-js: 1.0.2
+    dev: true
+
+  /@vue/compiler-sfc@3.5.13:
+    resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==}
+    dependencies:
+      '@babel/parser': 7.26.5
+      '@vue/compiler-core': 3.5.13
+      '@vue/compiler-dom': 3.5.13
+      '@vue/compiler-ssr': 3.5.13
+      '@vue/shared': 3.5.13
+      estree-walker: 2.0.2
+      magic-string: 0.30.17
+      postcss: 8.5.1
+      source-map-js: 1.2.1
 
   /@vue/compiler-ssr@3.4.19:
     resolution: {integrity: sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==}
     dependencies:
       '@vue/compiler-dom': 3.4.19
       '@vue/shared': 3.4.19
+    dev: true
+
+  /@vue/compiler-ssr@3.5.13:
+    resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==}
+    dependencies:
+      '@vue/compiler-dom': 3.5.13
+      '@vue/shared': 3.5.13
 
   /@vue/devtools-api@6.6.1:
     resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==}
 
-  /@vue/reactivity@3.4.19:
-    resolution: {integrity: sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==}
+  /@vue/reactivity@3.5.13:
+    resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==}
     dependencies:
-      '@vue/shared': 3.4.19
+      '@vue/shared': 3.5.13
 
-  /@vue/runtime-core@3.4.19:
-    resolution: {integrity: sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==}
+  /@vue/runtime-core@3.5.13:
+    resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==}
     dependencies:
-      '@vue/reactivity': 3.4.19
-      '@vue/shared': 3.4.19
+      '@vue/reactivity': 3.5.13
+      '@vue/shared': 3.5.13
 
-  /@vue/runtime-dom@3.4.19:
-    resolution: {integrity: sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==}
+  /@vue/runtime-dom@3.5.13:
+    resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==}
     dependencies:
-      '@vue/runtime-core': 3.4.19
-      '@vue/shared': 3.4.19
+      '@vue/reactivity': 3.5.13
+      '@vue/runtime-core': 3.5.13
+      '@vue/shared': 3.5.13
       csstype: 3.1.3
 
-  /@vue/server-renderer@3.4.19(vue@3.4.19):
-    resolution: {integrity: sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==}
+  /@vue/server-renderer@3.5.13(vue@3.5.13):
+    resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==}
     peerDependencies:
-      vue: 3.4.19
+      vue: 3.5.13
     dependencies:
-      '@vue/compiler-ssr': 3.4.19
-      '@vue/shared': 3.4.19
-      vue: 3.4.19(typescript@5.5.4)
+      '@vue/compiler-ssr': 3.5.13
+      '@vue/shared': 3.5.13
+      vue: 3.5.13(typescript@5.5.4)
 
   /@vue/shared@3.4.19:
     resolution: {integrity: sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==}
+    dev: true
 
-  /@vue/test-utils@2.4.4(vue@3.4.19):
+  /@vue/shared@3.5.13:
+    resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
+
+  /@vue/test-utils@2.4.4(vue@3.5.13):
     resolution: {integrity: sha512-8jkRxz8pNhClAf4Co4ZrpAoFISdvT3nuSkUlY6Ys6rmTpw3DMWG/X3mw3gQ7QJzgCZO9f+zuE2kW57fi09MW7Q==}
     peerDependencies:
       '@vue/server-renderer': ^3.0.1
@@ -1630,7 +1689,7 @@ packages:
         optional: true
     dependencies:
       js-beautify: 1.15.1
-      vue: 3.4.19(typescript@5.5.4)
+      vue: 3.5.13(typescript@5.5.4)
       vue-component-type-helpers: 1.8.27
     dev: true
 
@@ -1939,10 +1998,6 @@ packages:
     resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
     dev: true
 
-  /blueimp-md5@2.19.0:
-    resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==}
-    dev: true
-
   /body-parser@1.20.1:
     resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==}
     engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
@@ -2025,7 +2080,6 @@ packages:
 
   /buffer-from@1.1.2:
     resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
-    dev: false
 
   /buffer@5.7.1:
     resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
@@ -2109,11 +2163,11 @@ packages:
     engines: {node: '>=6'}
     dev: true
 
-  /camel-case@3.0.0:
-    resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==}
+  /camel-case@4.1.2:
+    resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
     dependencies:
-      no-case: 2.3.2
-      upper-case: 1.1.3
+      pascal-case: 3.1.2
+      tslib: 2.6.2
     dev: true
 
   /camelcase@5.3.1:
@@ -2203,6 +2257,13 @@ packages:
       fsevents: 2.3.3
     dev: true
 
+  /chokidar@4.0.3:
+    resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+    engines: {node: '>= 14.16.0'}
+    dependencies:
+      readdirp: 4.1.1
+    dev: true
+
   /chromium@3.0.3:
     resolution: {integrity: sha512-TfbzP/3t38Us5xrbb9x87M/y5I/j3jx0zeJhhQ72gjp6dwJuhVP6hBZnBH4wEg7512VVXk9zCfTuPFOdw7bQqg==}
     os: [darwin, linux, win32]
@@ -2224,9 +2285,9 @@ packages:
     resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
     engines: {node: '>=8'}
 
-  /clean-css@4.2.4:
-    resolution: {integrity: sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==}
-    engines: {node: '>= 4.0'}
+  /clean-css@5.3.3:
+    resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==}
+    engines: {node: '>= 10.0'}
     dependencies:
       source-map: 0.6.1
     dev: true
@@ -2425,20 +2486,6 @@ packages:
       typedarray: 0.0.6
     dev: false
 
-  /concordance@5.0.4:
-    resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==}
-    engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'}
-    dependencies:
-      date-time: 3.1.0
-      esutils: 2.0.3
-      fast-diff: 1.3.0
-      js-string-escape: 1.0.1
-      lodash: 4.17.21
-      md5-hex: 3.0.1
-      semver: 7.6.0
-      well-known-symbols: 2.0.0
-    dev: true
-
   /config-chain@1.1.13:
     resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
     dependencies:
@@ -2518,7 +2565,7 @@ packages:
       vary: 1.1.2
     dev: false
 
-  /cosmiconfig-typescript-loader@5.0.0(@types/node@20.11.19)(cosmiconfig@9.0.0)(typescript@5.5.4):
+  /cosmiconfig-typescript-loader@5.0.0(@types/node@22.10.7)(cosmiconfig@9.0.0)(typescript@5.5.4):
     resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==}
     engines: {node: '>=v16'}
     peerDependencies:
@@ -2526,7 +2573,7 @@ packages:
       cosmiconfig: '>=8.2'
       typescript: '>=4'
     dependencies:
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
       cosmiconfig: 9.0.0(typescript@5.5.4)
       jiti: 1.21.6
       typescript: 5.5.4
@@ -2673,13 +2720,6 @@ packages:
       assert-plus: 1.0.0
     dev: true
 
-  /date-time@3.1.0:
-    resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==}
-    engines: {node: '>=6'}
-    dependencies:
-      time-zone: 1.0.0
-    dev: true
-
   /dateformat@4.6.3:
     resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==}
     dev: true
@@ -2838,6 +2878,19 @@ packages:
     resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
     engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
 
+  /detect-libc@1.0.3:
+    resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==}
+    engines: {node: '>=0.10'}
+    hasBin: true
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /diff-sequences@29.6.3:
+    resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
+    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+    dev: true
+
   /diff@5.2.0:
     resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
     engines: {node: '>=0.3.1'}
@@ -2850,6 +2903,13 @@ packages:
       esutils: 2.0.3
     dev: true
 
+  /dot-case@3.0.4:
+    resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
+    dependencies:
+      no-case: 3.0.4
+      tslib: 2.6.2
+    dev: true
+
   /dot-prop@5.3.0:
     resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
     engines: {node: '>=8'}
@@ -3154,36 +3214,6 @@ packages:
       esbuild-windows-arm64: 0.14.51
     dev: true
 
-  /esbuild@0.18.20:
-    resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
-    engines: {node: '>=12'}
-    hasBin: true
-    requiresBuild: true
-    optionalDependencies:
-      '@esbuild/android-arm': 0.18.20
-      '@esbuild/android-arm64': 0.18.20
-      '@esbuild/android-x64': 0.18.20
-      '@esbuild/darwin-arm64': 0.18.20
-      '@esbuild/darwin-x64': 0.18.20
-      '@esbuild/freebsd-arm64': 0.18.20
-      '@esbuild/freebsd-x64': 0.18.20
-      '@esbuild/linux-arm': 0.18.20
-      '@esbuild/linux-arm64': 0.18.20
-      '@esbuild/linux-ia32': 0.18.20
-      '@esbuild/linux-loong64': 0.18.20
-      '@esbuild/linux-mips64el': 0.18.20
-      '@esbuild/linux-ppc64': 0.18.20
-      '@esbuild/linux-riscv64': 0.18.20
-      '@esbuild/linux-s390x': 0.18.20
-      '@esbuild/linux-x64': 0.18.20
-      '@esbuild/netbsd-x64': 0.18.20
-      '@esbuild/openbsd-x64': 0.18.20
-      '@esbuild/sunos-x64': 0.18.20
-      '@esbuild/win32-arm64': 0.18.20
-      '@esbuild/win32-ia32': 0.18.20
-      '@esbuild/win32-x64': 0.18.20
-    dev: true
-
   /esbuild@0.19.12:
     resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==}
     engines: {node: '>=12'}
@@ -3556,10 +3586,6 @@ packages:
     resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
     dev: true
 
-  /fast-diff@1.3.0:
-    resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
-    dev: true
-
   /fast-glob@3.2.12:
     resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
     engines: {node: '>=8.6.0'}
@@ -4025,18 +4051,18 @@ packages:
     hasBin: true
     dev: true
 
-  /html-minifier@4.0.0:
-    resolution: {integrity: sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==}
-    engines: {node: '>=6'}
+  /html-minifier-terser@7.2.0:
+    resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==}
+    engines: {node: ^14.13.1 || >=16.0.0}
     hasBin: true
     dependencies:
-      camel-case: 3.0.0
-      clean-css: 4.2.4
-      commander: 2.20.3
-      he: 1.2.0
-      param-case: 2.1.1
+      camel-case: 4.1.2
+      clean-css: 5.3.3
+      commander: 10.0.1
+      entities: 4.5.0
+      param-case: 3.0.4
       relateurl: 0.2.7
-      uglify-js: 3.17.4
+      terser: 5.37.0
     dev: true
 
   /http-cache-semantics@4.1.1:
@@ -4155,8 +4181,8 @@ packages:
     engines: {node: '>= 4'}
     dev: true
 
-  /immutable@4.3.5:
-    resolution: {integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==}
+  /immutable@5.0.3:
+    resolution: {integrity: sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==}
     dev: true
 
   /import-fresh@3.3.0:
@@ -4418,11 +4444,6 @@ packages:
     engines: {node: '>=14'}
     dev: true
 
-  /js-string-escape@1.0.1:
-    resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==}
-    engines: {node: '>= 0.8'}
-    dev: true
-
   /js-tokens@4.0.0:
     resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
     dev: true
@@ -4726,8 +4747,10 @@ packages:
       get-func-name: 2.0.2
     dev: true
 
-  /lower-case@1.1.4:
-    resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==}
+  /lower-case@2.0.2:
+    resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
+    dependencies:
+      tslib: 2.6.2
     dev: true
 
   /lowercase-keys@2.0.0:
@@ -4758,17 +4781,16 @@ packages:
     dependencies:
       yallist: 4.0.0
 
+  /magic-string@0.30.17:
+    resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
+    dependencies:
+      '@jridgewell/sourcemap-codec': 1.5.0
+
   /magic-string@0.30.7:
     resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==}
     engines: {node: '>=12'}
     dependencies:
       '@jridgewell/sourcemap-codec': 1.4.15
-
-  /md5-hex@3.0.1:
-    resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==}
-    engines: {node: '>=8'}
-    dependencies:
-      blueimp-md5: 2.19.0
     dev: true
 
   /media-typer@0.3.0:
@@ -4992,6 +5014,12 @@ packages:
     resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
     engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
     hasBin: true
+    dev: true
+
+  /nanoid@3.3.8:
+    resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
+    engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+    hasBin: true
 
   /natural-compare@1.4.0:
     resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
@@ -5001,12 +5029,19 @@ packages:
     resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
     engines: {node: '>= 0.6'}
 
-  /no-case@2.3.2:
-    resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==}
+  /no-case@3.0.4:
+    resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
     dependencies:
-      lower-case: 1.1.4
+      lower-case: 2.0.2
+      tslib: 2.6.2
     dev: true
 
+  /node-addon-api@7.1.1:
+    resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
+    requiresBuild: true
+    dev: true
+    optional: true
+
   /node-forge@1.3.1:
     resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
     engines: {node: '>= 6.13.0'}
@@ -5229,10 +5264,11 @@ packages:
       semver: 7.6.0
     dev: false
 
-  /param-case@2.1.1:
-    resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==}
+  /param-case@3.0.4:
+    resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
     dependencies:
-      no-case: 2.3.2
+      dot-case: 3.0.4
+      tslib: 2.6.2
     dev: true
 
   /parent-module@1.0.1:
@@ -5256,6 +5292,13 @@ packages:
     resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
     engines: {node: '>= 0.8'}
 
+  /pascal-case@3.1.2:
+    resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
+    dependencies:
+      no-case: 3.0.4
+      tslib: 2.6.2
+    dev: true
+
   /path-exists@4.0.0:
     resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
     engines: {node: '>=8'}
@@ -5310,6 +5353,10 @@ packages:
 
   /picocolors@1.0.0:
     resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+    dev: true
+
+  /picocolors@1.1.1:
+    resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
 
   /picomatch@2.3.1:
     resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
@@ -5320,7 +5367,7 @@ packages:
     engines: {node: '>=0.10.0'}
     dev: true
 
-  /pinia@2.1.7(typescript@5.5.4)(vue@3.4.19):
+  /pinia@2.1.7(typescript@5.5.4)(vue@3.5.13):
     resolution: {integrity: sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==}
     peerDependencies:
       '@vue/composition-api': ^1.4.0
@@ -5334,8 +5381,8 @@ packages:
     dependencies:
       '@vue/devtools-api': 6.6.1
       typescript: 5.5.4
-      vue: 3.4.19(typescript@5.5.4)
-      vue-demi: 0.14.7(vue@3.4.19)
+      vue: 3.5.13(typescript@5.5.4)
+      vue-demi: 0.14.7(vue@3.5.13)
 
   /pirates@4.0.6:
     resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
@@ -5369,6 +5416,15 @@ packages:
       nanoid: 3.3.7
       picocolors: 1.0.0
       source-map-js: 1.0.2
+    dev: true
+
+  /postcss@8.5.1:
+    resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==}
+    engines: {node: ^10 || ^12 || >=14}
+    dependencies:
+      nanoid: 3.3.8
+      picocolors: 1.1.1
+      source-map-js: 1.2.1
 
   /prelude-ls@1.2.1:
     resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
@@ -5386,13 +5442,13 @@ packages:
     engines: {node: '>=6'}
     dev: true
 
-  /pretty-format@27.5.1:
-    resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
-    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+  /pretty-format@29.7.0:
+    resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
+    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
     dependencies:
-      ansi-regex: 5.0.1
+      '@jest/schemas': 29.6.3
       ansi-styles: 5.2.0
-      react-is: 17.0.2
+      react-is: 18.3.1
     dev: true
 
   /process-nextick-args@2.0.1:
@@ -5473,8 +5529,8 @@ packages:
     dependencies:
       side-channel: 1.0.5
 
-  /quasar@2.14.5:
-    resolution: {integrity: sha512-N+iRYoby09P9l+R5nKfA0tCPXdXJJHCPifjP8CkL/JASX5yHEjuwh7KoNiWzYLZPbsYXVuQKqwtDy0qXuXTv2g==}
+  /quasar@2.17.7:
+    resolution: {integrity: sha512-nPJdHoONlcW7WEU2Ody907Wx945Zfyuea/KP4LBaEn5AcL95PUWp8Gz/0zDYNnFw0aCWRtye3SUAdQl5tmrn5w==}
     engines: {node: '>= 10.18.1', npm: '>= 6.13.4', yarn: '>= 1.21.1'}
 
   /querystringify@2.2.0:
@@ -5523,8 +5579,8 @@ packages:
     resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
     dev: true
 
-  /react-is@17.0.2:
-    resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
+  /react-is@18.3.1:
+    resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
     dev: true
 
   /readable-stream@2.3.8:
@@ -5560,6 +5616,11 @@ packages:
       picomatch: 2.3.1
     dev: true
 
+  /readdirp@4.1.1:
+    resolution: {integrity: sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==}
+    engines: {node: '>= 14.18.0'}
+    dev: true
+
   /recrawl-sync@2.2.3:
     resolution: {integrity: sha512-vSaTR9t+cpxlskkdUFrsEpnf67kSmPk66yAGT1fZPrDudxQjoMzPgQhSMImQ0pAw5k0NPirefQfhopSjhdUtpQ==}
     dependencies:
@@ -5707,14 +5768,6 @@ packages:
       fsevents: 2.3.3
     dev: true
 
-  /rollup@3.29.4:
-    resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==}
-    engines: {node: '>=14.18.0', npm: '>=8.0.0'}
-    hasBin: true
-    optionalDependencies:
-      fsevents: 2.3.3
-    dev: true
-
   /rollup@4.12.0:
     resolution: {integrity: sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==}
     engines: {node: '>=18.0.0', npm: '>=8.0.0'}
@@ -5780,14 +5833,16 @@ packages:
   /safer-buffer@2.1.2:
     resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
 
-  /sass@1.71.1:
-    resolution: {integrity: sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==}
+  /sass@1.83.4:
+    resolution: {integrity: sha512-B1bozCeNQiOgDcLd33e2Cs2U60wZwjUUXzh900ZyQF5qUasvMdDZYbQ566LJu7cqR+sAHlAfO6RMkaID5s6qpA==}
     engines: {node: '>=14.0.0'}
     hasBin: true
     dependencies:
-      chokidar: 3.6.0
-      immutable: 4.3.5
+      chokidar: 4.0.3
+      immutable: 5.0.3
       source-map-js: 1.0.2
+    optionalDependencies:
+      '@parcel/watcher': 2.5.0
     dev: true
 
   /sax@1.1.4:
@@ -5941,6 +5996,17 @@ packages:
     resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
     engines: {node: '>=0.10.0'}
 
+  /source-map-js@1.2.1:
+    resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+    engines: {node: '>=0.10.0'}
+
+  /source-map-support@0.5.21:
+    resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
+    dependencies:
+      buffer-from: 1.1.2
+      source-map: 0.6.1
+    dev: true
+
   /source-map@0.6.1:
     resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
     engines: {node: '>=0.10.0'}
@@ -6128,6 +6194,17 @@ packages:
     resolution: {integrity: sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==}
     dev: true
 
+  /terser@5.37.0:
+    resolution: {integrity: sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==}
+    engines: {node: '>=10'}
+    hasBin: true
+    dependencies:
+      '@jridgewell/source-map': 0.3.6
+      acorn: 8.11.3
+      commander: 2.20.3
+      source-map-support: 0.5.21
+    dev: true
+
   /text-extensions@2.4.0:
     resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==}
     engines: {node: '>=8'}
@@ -6158,17 +6235,12 @@ packages:
     resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
     dev: true
 
-  /time-zone@1.0.0:
-    resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==}
-    engines: {node: '>=4'}
-    dev: true
-
   /tinybench@2.6.0:
     resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==}
     dev: true
 
-  /tinypool@0.5.0:
-    resolution: {integrity: sha512-paHQtnrlS1QZYKF/GnLoOM/DN9fqaGOFbCbxzAhwniySnzl9Ebk8w73/dd34DAhe/obUbPAOldTyYXQZxnPBPQ==}
+  /tinypool@0.7.0:
+    resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==}
     engines: {node: '>=14.0.0'}
     dev: true
 
@@ -6198,6 +6270,7 @@ packages:
   /to-fast-properties@2.0.0:
     resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
     engines: {node: '>=4'}
+    dev: true
 
   /to-regex-range@5.0.1:
     resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
@@ -6326,14 +6399,8 @@ packages:
     resolution: {integrity: sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==}
     dev: true
 
-  /uglify-js@3.17.4:
-    resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
-    engines: {node: '>=0.8.0'}
-    hasBin: true
-    dev: true
-
-  /undici-types@5.26.5:
-    resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+  /undici-types@6.20.0:
+    resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
 
   /unicorn-magic@0.1.0:
     resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
@@ -6409,10 +6476,6 @@ packages:
       xdg-basedir: 5.1.0
     dev: false
 
-  /upper-case@1.1.3:
-    resolution: {integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==}
-    dev: true
-
   /uri-js@4.4.1:
     resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
     dependencies:
@@ -6464,22 +6527,22 @@ packages:
       globrex: 0.1.2
       recrawl-sync: 2.2.3
       tsconfig-paths: 3.15.0
-      vite: 5.1.4(@types/node@20.11.19)
+      vite: 5.1.4(@types/node@22.10.7)
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /vite-node@0.31.4(@types/node@20.11.19):
-    resolution: {integrity: sha512-uzL377GjJtTbuc5KQxVbDu2xfU/x0wVjUtXQR2ihS21q/NK6ROr4oG0rsSkBBddZUVCwzfx22in76/0ZZHXgkQ==}
+  /vite-node@0.34.6(@types/node@22.10.7):
+    resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==}
     engines: {node: '>=v14.18.0'}
     hasBin: true
     dependencies:
       cac: 6.7.14
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.7(supports-color@8.1.1)
       mlly: 1.5.0
       pathe: 1.1.2
       picocolors: 1.0.0
-      vite: 4.5.2(@types/node@20.11.19)
+      vite: 5.1.4(@types/node@22.10.7)
     transitivePeerDependencies:
       - '@types/node'
       - less
@@ -6502,13 +6565,13 @@ packages:
       debug: 4.3.4(supports-color@8.1.1)
       globrex: 0.1.2
       tsconfck: 3.0.2(typescript@5.5.4)
-      vite: 5.1.4(@types/node@20.11.19)
+      vite: 5.1.4(@types/node@22.10.7)
     transitivePeerDependencies:
       - supports-color
       - typescript
     dev: true
 
-  /vite@2.9.17(sass@1.71.1):
+  /vite@2.9.17(sass@1.83.4):
     resolution: {integrity: sha512-XxcRzra6d7xrKXH66jZUgb+srThoPu+TLJc06GifUyKq9JmjHkc1Numc8ra0h56rju2jfVWw3B3fs5l3OFMvUw==}
     engines: {node: '>=12.2.0'}
     hasBin: true
@@ -6528,48 +6591,12 @@ packages:
       postcss: 8.4.35
       resolve: 1.22.8
       rollup: 2.77.3
-      sass: 1.71.1
+      sass: 1.83.4
     optionalDependencies:
       fsevents: 2.3.3
     dev: true
 
-  /vite@4.5.2(@types/node@20.11.19):
-    resolution: {integrity: sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==}
-    engines: {node: ^14.18.0 || >=16.0.0}
-    hasBin: true
-    peerDependencies:
-      '@types/node': '>= 14'
-      less: '*'
-      lightningcss: ^1.21.0
-      sass: '*'
-      stylus: '*'
-      sugarss: '*'
-      terser: ^5.4.0
-    peerDependenciesMeta:
-      '@types/node':
-        optional: true
-      less:
-        optional: true
-      lightningcss:
-        optional: true
-      sass:
-        optional: true
-      stylus:
-        optional: true
-      sugarss:
-        optional: true
-      terser:
-        optional: true
-    dependencies:
-      '@types/node': 20.11.19
-      esbuild: 0.18.20
-      postcss: 8.4.35
-      rollup: 3.29.4
-    optionalDependencies:
-      fsevents: 2.3.3
-    dev: true
-
-  /vite@5.1.4(@types/node@20.11.19):
+  /vite@5.1.4(@types/node@22.10.7):
     resolution: {integrity: sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==}
     engines: {node: ^18.0.0 || >=20.0.0}
     hasBin: true
@@ -6597,7 +6624,7 @@ packages:
       terser:
         optional: true
     dependencies:
-      '@types/node': 20.11.19
+      '@types/node': 22.10.7
       esbuild: 0.19.12
       postcss: 8.4.35
       rollup: 4.12.0
@@ -6605,8 +6632,8 @@ packages:
       fsevents: 2.3.3
     dev: true
 
-  /vitest@0.31.4:
-    resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==}
+  /vitest@0.34.6:
+    resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==}
     engines: {node: '>=v14.18.0'}
     hasBin: true
     peerDependencies:
@@ -6638,18 +6665,17 @@ packages:
     dependencies:
       '@types/chai': 4.3.12
       '@types/chai-subset': 1.3.5
-      '@types/node': 20.11.19
-      '@vitest/expect': 0.31.4
-      '@vitest/runner': 0.31.4
-      '@vitest/snapshot': 0.31.4
-      '@vitest/spy': 0.31.4
-      '@vitest/utils': 0.31.4
+      '@types/node': 22.10.7
+      '@vitest/expect': 0.34.6
+      '@vitest/runner': 0.34.6
+      '@vitest/snapshot': 0.34.6
+      '@vitest/spy': 0.34.6
+      '@vitest/utils': 0.34.6
       acorn: 8.11.3
       acorn-walk: 8.3.2
       cac: 6.7.14
       chai: 4.4.1
-      concordance: 5.0.4
-      debug: 4.3.4(supports-color@8.1.1)
+      debug: 4.3.7(supports-color@8.1.1)
       local-pkg: 0.4.3
       magic-string: 0.30.7
       pathe: 1.1.2
@@ -6657,9 +6683,9 @@ packages:
       std-env: 3.7.0
       strip-literal: 1.3.0
       tinybench: 2.6.0
-      tinypool: 0.5.0
-      vite: 4.5.2(@types/node@20.11.19)
-      vite-node: 0.31.4(@types/node@20.11.19)
+      tinypool: 0.7.0
+      vite: 5.1.4(@types/node@22.10.7)
+      vite-node: 0.34.6(@types/node@22.10.7)
       why-is-node-running: 2.2.2
     transitivePeerDependencies:
       - less
@@ -6675,7 +6701,7 @@ packages:
     resolution: {integrity: sha512-0vOfAtI67UjeO1G6UiX5Kd76CqaQ67wrRZiOe7UAb9Jm6GzlUr/fC7CV90XfwapJRjpCMaZFhv1V0ajWRmE9Dg==}
     dev: true
 
-  /vue-demi@0.14.7(vue@3.4.19):
+  /vue-demi@0.14.7(vue@3.5.13):
     resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
     engines: {node: '>=12'}
     hasBin: true
@@ -6687,7 +6713,7 @@ packages:
       '@vue/composition-api':
         optional: true
     dependencies:
-      vue: 3.4.19(typescript@5.5.4)
+      vue: 3.5.13(typescript@5.5.4)
 
   /vue-eslint-parser@9.4.2(eslint@8.56.0):
     resolution: {integrity: sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==}
@@ -6707,7 +6733,7 @@ packages:
       - supports-color
     dev: true
 
-  /vue-i18n@9.9.1(vue@3.4.19):
+  /vue-i18n@9.9.1(vue@3.5.13):
     resolution: {integrity: sha512-xyQ4VspLdNSPTKBFBPWa1tvtj+9HuockZwgFeD2OhxxXuC2CWeNvV4seu2o9+vbQOyQbhAM5Ez56oxUrrnTWdw==}
     engines: {node: '>= 16'}
     peerDependencies:
@@ -6716,29 +6742,29 @@ packages:
       '@intlify/core-base': 9.9.1
       '@intlify/shared': 9.9.1
       '@vue/devtools-api': 6.6.1
-      vue: 3.4.19(typescript@5.5.4)
+      vue: 3.5.13(typescript@5.5.4)
 
-  /vue-router@4.2.5(vue@3.4.19):
+  /vue-router@4.2.5(vue@3.5.13):
     resolution: {integrity: sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==}
     peerDependencies:
       vue: ^3.2.0
     dependencies:
       '@vue/devtools-api': 6.6.1
-      vue: 3.4.19(typescript@5.5.4)
+      vue: 3.5.13(typescript@5.5.4)
 
-  /vue@3.4.19(typescript@5.5.4):
-    resolution: {integrity: sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==}
+  /vue@3.5.13(typescript@5.5.4):
+    resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==}
     peerDependencies:
       typescript: '*'
     peerDependenciesMeta:
       typescript:
         optional: true
     dependencies:
-      '@vue/compiler-dom': 3.4.19
-      '@vue/compiler-sfc': 3.4.19
-      '@vue/runtime-dom': 3.4.19
-      '@vue/server-renderer': 3.4.19(vue@3.4.19)
-      '@vue/shared': 3.4.19
+      '@vue/compiler-dom': 3.5.13
+      '@vue/compiler-sfc': 3.5.13
+      '@vue/runtime-dom': 3.5.13
+      '@vue/server-renderer': 3.5.13(vue@3.5.13)
+      '@vue/shared': 3.5.13
       typescript: 5.5.4
 
   /wcwidth@1.0.1:
@@ -6770,11 +6796,6 @@ packages:
     resolution: {integrity: sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==}
     dev: true
 
-  /well-known-symbols@2.0.0:
-    resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==}
-    engines: {node: '>=6'}
-    dev: true
-
   /whatwg-encoding@2.0.0:
     resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==}
     engines: {node: '>=12'}
diff --git a/src/components/UserPanel.vue b/src/components/UserPanel.vue
index a0ef73a1fe1..5f3266eb2d4 100644
--- a/src/components/UserPanel.vue
+++ b/src/components/UserPanel.vue
@@ -1,6 +1,9 @@
 <script setup>
+import quasarLang from 'src/utils/quasarLang';
+
 import { onMounted, computed, ref } from 'vue';
-import { Dark, Quasar } from 'quasar';
+
+import { Dark } from 'quasar';
 import { useI18n } from 'vue-i18n';
 import { useRouter } from 'vue-router';
 import axios from 'axios';
@@ -31,14 +34,7 @@ const userLocale = computed({
 
         value = localeEquivalence[value] ?? value;
 
-        try {
-            /* @vite-ignore */
-            import(`../../node_modules/quasar/lang/${value}.mjs`).then((lang) => {
-                Quasar.lang.set(lang.default);
-            });
-        } catch (error) {
-            //
-        }
+        quasarLang(value);
     },
 });
 
diff --git a/src/components/VnTable/__tests__/VnVisibleColumns.spec.js b/src/components/VnTable/__tests__/VnVisibleColumns.spec.js
new file mode 100644
index 00000000000..bf767688bb3
--- /dev/null
+++ b/src/components/VnTable/__tests__/VnVisibleColumns.spec.js
@@ -0,0 +1,121 @@
+import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest';
+import { createWrapper } from 'app/test/vitest/helper';
+import VnVisibleColumn from '../VnVisibleColumn.vue';
+import { axios } from 'app/test/vitest/helper';
+
+describe('VnVisibleColumns', () => {
+    let wrapper;
+    let vm;
+
+    beforeEach(() => {
+        wrapper = createWrapper(VnVisibleColumn, {
+            propsData: {
+                tableCode: 'testTable',
+                skip: ['skippedColumn'],
+            },
+        });
+        vm = wrapper.vm;
+    });
+
+    afterEach(() => {
+        vi.clearAllMocks();
+    });
+
+    describe('setUserConfigViewData()', () => {
+        it('should initialize localColumns with visible configuration', () => {
+            vm.columns = [
+                { name: 'columnMockName', label: undefined },
+                { name: 'columnMockAddress', label: undefined },
+                { name: 'columnMockId', label: undefined },
+            ];
+            const configuration = {
+                columnMockName: true,
+                columnMockAddress: false,
+                columnMockId: true,
+            };
+            const expectedColumns = [
+                { name: 'columnMockName', label: undefined, visible: true },
+                { name: 'columnMockAddress', label: undefined, visible: false },
+                { name: 'columnMockId', label: undefined, visible: true },
+            ];
+
+            vm.setUserConfigViewData(configuration, false);
+
+            expect(vm.localColumns).toEqual(expectedColumns);
+        });
+
+        it('should skip columns based on props', () => {
+            vm.columns = [
+                { name: 'columnMockName', label: undefined },
+                { name: 'columnMockId', label: undefined },
+                { name: 'skippedColumn', label: 'Skipped Column' },
+            ];
+            const configuration = {
+                columnMockName: true,
+                skippedColumn: false,
+                columnMockId: true,
+            };
+            const expectedColumns = [
+                { name: 'columnMockName', label: undefined, visible: true },
+                { name: 'columnMockId', label: undefined, visible: true },
+            ];
+
+            vm.setUserConfigViewData(configuration, false);
+
+            expect(vm.localColumns).toEqual(expectedColumns);
+        });
+    });
+
+    describe('toggleMarkAll()', () => {
+        it('should set all localColumns to visible=true', () => {
+            vm.localColumns = [
+                { name: 'columnMockName', visible: false },
+                { name: 'columnMockId', visible: false },
+            ];
+
+            vm.toggleMarkAll(true);
+
+            expect(vm.localColumns.every((col) => col.visible)).toBe(true);
+        });
+
+        it('should set all localColumns to visible=false', () => {
+            vm.localColumns = [
+                { name: 'columnMockName', visible: true },
+                { name: 'columnMockId', visible: true },
+            ];
+
+            vm.toggleMarkAll(false);
+
+            expect(vm.localColumns.every((col) => col.visible)).toBe(false);
+        });
+    });
+
+    describe('saveConfig()', () => {
+        it('should call setUserConfigViewData and axios.post with correct params', async () => {
+            const mockAxiosPost = vi.spyOn(axios, 'post').mockResolvedValue({
+                data: [{ id: 1 }],
+            });
+
+            vm.localColumns = [
+                { name: 'columnMockName', visible: true },
+                { name: 'columnMockId', visible: false },
+            ];
+
+            await vm.saveConfig();
+
+            expect(mockAxiosPost).toHaveBeenCalledWith('UserConfigViews/crud', {
+                creates: [
+                    {
+                        userFk: vm.user.id,
+                        tableCode: vm.tableCode,
+                        tableConfig: vm.tableCode,
+                        configuration: {
+                            columnMockName: true,
+                            columnMockId: false,
+                        },
+                    },
+                ],
+            });
+        });
+    });
+});
diff --git a/src/components/common/RightMenu.vue b/src/components/common/RightMenu.vue
index 32dc2874dce..9512d32d419 100644
--- a/src/components/common/RightMenu.vue
+++ b/src/components/common/RightMenu.vue
@@ -1,29 +1,17 @@
 <script setup>
-import { ref, onMounted, useSlots } from 'vue';
+import { onMounted, useSlots } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useStateStore } from 'stores/useStateStore';
 import { useQuasar } from 'quasar';
+import { useHasContent } from 'src/composables/useHasContent';
 
 const { t } = useI18n();
 const quasar = useQuasar();
 const stateStore = useStateStore();
 const slots = useSlots();
-const hasContent = ref(false);
-const rightPanel = ref(null);
+const hasContent = useHasContent('#right-panel');
 
 onMounted(() => {
-    rightPanel.value = document.querySelector('#right-panel');
-    if (!rightPanel.value) return;
-
-    const observer = new MutationObserver(() => {
-        hasContent.value = rightPanel.value.childNodes.length;
-    });
-
-    observer.observe(rightPanel.value, {
-        subtree: true,
-        childList: true,
-        attributes: true,
-    });
     if ((!slots['right-panel'] && !hasContent.value) || quasar.platform.is.mobile)
         stateStore.rightDrawer = false;
 });
diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue
index ed3cadc6bd7..a4eb269585f 100644
--- a/src/components/common/VnDmsList.vue
+++ b/src/components/common/VnDmsList.vue
@@ -299,11 +299,12 @@ defineExpose({
         :url="$props.model"
         :user-filter="dmsFilter"
         :order="['dmsFk DESC']"
-        :auto-load="true"
+        auto-load
         @on-fetch="setData"
     >
         <template #body>
             <QTable
+                v-if="rows"
                 :columns="columns"
                 :rows="rows"
                 class="full-width q-mt-md"
diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue
index 4c7445aabf0..e921d8e1f3e 100644
--- a/src/components/common/VnInput.vue
+++ b/src/components/common/VnInput.vue
@@ -42,10 +42,13 @@ const $props = defineProps({
         type: Number,
         default: null,
     },
+    uppercase: {
+        type: Boolean,
+        default: false,
+    },
 });
 
 const vnInputRef = ref(null);
-const showPassword = ref(false);
 const value = computed({
     get() {
         return $props.modelValue;
@@ -117,6 +120,10 @@ const handleInsertMode = (e) => {
         input.setSelectionRange(cursorPos + 1, cursorPos + 1);
     });
 };
+
+const handleUppercase = () => {
+    value.value = value.value?.toUpperCase() || '';
+};
 </script>
 
 <template>
@@ -159,7 +166,16 @@ const handleInsertMode = (e) => {
                             emit('remove');
                         }
                     "
+                ></QIcon>
+                
+                <QIcon
+                    name="match_case"
+                    size="xs"
+                    v-if="!$attrs.disabled && !($attrs.readonly) && $props.uppercase"
+                    @click="handleUppercase"
+                    class="uppercase-icon"
                 />
+                
                 <slot name="append" v-if="$slots.append && !$attrs.disabled" />
                 <QIcon v-if="info" name="info">
                     <QTooltip max-width="350px">
@@ -170,3 +186,14 @@ const handleInsertMode = (e) => {
         </QInput>
     </div>
 </template>
+
+<i18n>
+    en:
+        inputMin: Must be more than {value}
+        maxLength: The value exceeds {value} characters
+        inputMax: Must be less than {value}
+    es:
+        inputMin: Debe ser mayor a {value}
+        maxLength: El valor excede los {value} carácteres
+        inputMax: Debe ser menor a {value}
+</i18n>
\ No newline at end of file
diff --git a/src/components/common/VnInputDate.vue b/src/components/common/VnInputDate.vue
index 952a843e390..a8888aad84b 100644
--- a/src/components/common/VnInputDate.vue
+++ b/src/components/common/VnInputDate.vue
@@ -105,6 +105,7 @@ const manageDate = (date) => {
             :rules="mixinRules"
             :clearable="false"
             @click="isPopupOpen = !isPopupOpen"
+            @keydown="isPopupOpen = false"
             hide-bottom-space
         >
             <template #append>
diff --git a/src/components/common/VnInputTime.vue b/src/components/common/VnInputTime.vue
index 4147f89765d..323427f5b4e 100644
--- a/src/components/common/VnInputTime.vue
+++ b/src/components/common/VnInputTime.vue
@@ -79,6 +79,7 @@ function dateToTime(newDate) {
             style="min-width: 100px"
             :rules="mixinRules"
             @click="isPopupOpen = !isPopupOpen"
+            @keydown="isPopupOpen = false"
             type="time"
             hide-bottom-space
         >
diff --git a/src/components/common/VnLocation.vue b/src/components/common/VnLocation.vue
index f5822218727..014b84b316e 100644
--- a/src/components/common/VnLocation.vue
+++ b/src/components/common/VnLocation.vue
@@ -2,7 +2,7 @@
 import CreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue';
 import VnSelectDialog from 'components/common/VnSelectDialog.vue';
 import { useI18n } from 'vue-i18n';
-import { computed } from 'vue';
+import { ref, watch } from 'vue';
 import { useAttrs } from 'vue';
 import { useRequired } from 'src/composables/useRequired';
 const { t } = useI18n();
@@ -16,6 +16,14 @@ const props = defineProps({
     },
 });
 
+watch(
+    () => props.location,
+    (newValue) => {
+        if (!modelValue.value) return;
+        modelValue.value = formatLocation(newValue) ?? null;
+    }
+);
+
 const mixinRules = [requiredFieldRule];
 const locationProperties = [
     'postcode',
@@ -43,9 +51,7 @@ const formatLocation = (obj, properties = locationProperties) => {
     return filteredParts.join(', ');
 };
 
-const modelValue = computed(() =>
-    props.location ? formatLocation(props.location, locationProperties) : null
-);
+const modelValue = ref(props.location ? formatLocation(props.location) : null);
 
 function showLabel(data) {
     const dataProperties = [
@@ -64,9 +70,6 @@ const handleModelValue = (data) => {
     <VnSelectDialog
         v-model="modelValue"
         option-filter-value="search"
-        :option-label="
-            (opt) => (typeof modelValue === 'string' ? modelValue : showLabel(opt))
-        "
         url="Postcodes/filter"
         @update:model-value="handleModelValue"
         :use-like="false"
diff --git a/src/components/common/VnSection.vue b/src/components/common/VnSection.vue
index edd8d3dfa98..16ea7904743 100644
--- a/src/components/common/VnSection.vue
+++ b/src/components/common/VnSection.vue
@@ -2,9 +2,10 @@
 import RightMenu from './RightMenu.vue';
 import VnSearchbar from 'components/ui/VnSearchbar.vue';
 import VnTableFilter from '../VnTable/VnTableFilter.vue';
-import { onBeforeMount, computed } from 'vue';
+import { onBeforeMount, computed, ref } from 'vue';
 import { useArrayData } from 'src/composables/useArrayData';
 import { useRoute } from 'vue-router';
+import { useHasContent } from 'src/composables/useHasContent';
 
 const $props = defineProps({
     section: {
@@ -51,10 +52,13 @@ const sectionValue = computed(() => $props.section ?? $props.dataKey);
 const isMainSection = computed(() => {
     const isSame = sectionValue.value == route.name;
     if (!isSame && arrayData) {
-        arrayData.reset(['userParams', 'userFilter']);
+        arrayData.reset(['userParams', 'filter']);
+        arrayData.setCurrentFilter();
     }
     return isSame;
 });
+const searchbarId = 'section-searchbar';
+const hasContent = useHasContent(`#${searchbarId}`);
 
 onBeforeMount(() => {
     if ($props.dataKey)
@@ -69,14 +73,14 @@ onBeforeMount(() => {
 <template>
     <slot name="searchbar">
         <VnSearchbar
-            v-if="searchBar"
+            v-if="searchBar && !hasContent"
             v-bind="arrayDataProps"
             :data-key="dataKey"
             :label="$t(`${prefix}.search`)"
             :info="$t(`${prefix}.searchInfo`)"
         />
+        <div :id="searchbarId"></div>
     </slot>
-
     <RightMenu>
         <template #right-panel v-if="$slots['rightMenu'] || rightFilter">
             <slot name="rightMenu">
diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue
index ee94a1d81bf..43134dbff60 100644
--- a/src/components/common/VnSelect.vue
+++ b/src/components/common/VnSelect.vue
@@ -232,12 +232,15 @@ async function fetchFilter(val) {
     } else defaultWhere = { [key]: getVal(val) };
     const where = { ...(val ? defaultWhere : {}), ...$props.where };
     $props.exprBuilder && Object.assign(where, $props.exprBuilder(key, val));
-    const fetchOptions = { where, include, limit };
-    if (fields) fetchOptions.fields = fields;
-    if (sortBy) fetchOptions.order = sortBy;
+    const filterOptions = { where, include, limit };
+    if (fields) filterOptions.fields = fields;
+    if (sortBy) filterOptions.order = sortBy;
     arrayData.resetPagination();
 
-    const { data } = await arrayData.applyFilter({ filter: fetchOptions });
+    const { data } = await arrayData.applyFilter(
+        { filter: filterOptions },
+        { updateRouter: false }
+    );
     setOptions(data);
     return data;
 }
@@ -294,7 +297,7 @@ async function onScroll({ to, direction, from, index }) {
     }
 }
 
-defineExpose({ opts: myOptions });
+defineExpose({ opts: myOptions, vnSelectRef });
 
 function handleKeyDown(event) {
     if (event.key === 'Tab' && !event.shiftKey) {
diff --git a/src/components/common/VnSelectDialog.vue b/src/components/common/VnSelectDialog.vue
index 12322c3fa4f..a4cd0011d29 100644
--- a/src/components/common/VnSelectDialog.vue
+++ b/src/components/common/VnSelectDialog.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { computed } from 'vue';
+import { ref, computed } from 'vue';
 import { useRole } from 'src/composables/useRole';
 import { useAcl } from 'src/composables/useAcl';
 
@@ -7,6 +7,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 const emit = defineEmits(['update:modelValue']);
 
 const value = defineModel({ type: [String, Number, Object] });
+const select = ref(null);
 const $props = defineProps({
     rolesAllowedToCreate: {
         type: Array,
@@ -33,10 +34,13 @@ const isAllowedToCreate = computed(() => {
     if ($props.acls.length) return acl.hasAny($props.acls);
     return role.hasAny($props.rolesAllowedToCreate);
 });
+
+defineExpose({ vnSelectDialogRef: select });
 </script>
 
 <template>
     <VnSelect
+        ref="select"
         v-model="value"
         v-bind="$attrs"
         @update:model-value="(...args) => emit('update:modelValue', ...args)"
diff --git a/src/components/common/VnSelectWorker.vue b/src/components/common/VnSelectWorker.vue
index 9a8151a3d47..2762d6c024a 100644
--- a/src/components/common/VnSelectWorker.vue
+++ b/src/components/common/VnSelectWorker.vue
@@ -55,7 +55,7 @@ const url = computed(() => {
         sort-by="nickname ASC"
     >
         <template #prepend v-if="$props.hasAvatar">
-            <VnAvatar :worker-id="value" color="primary" :title="title" />
+            <VnAvatar :worker-id="value" color="primary" v-bind="$attrs" />
         </template>
         <template #append v-if="$props.hasInfo">
             <QIcon name="info" class="cursor-pointer">
@@ -72,7 +72,8 @@ const url = computed(() => {
                         {{ scope.opt.nickname }}
                     </QItemLabel>
                     <QItemLabel caption v-else>
-                        #{{ scope.opt.id }}, {{ scope.opt.nickname }}, {{ scope.opt.code }}
+                        #{{ scope.opt.id }}, {{ scope.opt.nickname }},
+                        {{ scope.opt.code }}
                     </QItemLabel>
                 </QItemSection>
             </QItem>
diff --git a/src/components/common/__tests__/VnInputDate.spec.js b/src/components/common/__tests__/VnInputDate.spec.js
new file mode 100644
index 00000000000..21ca91e96e7
--- /dev/null
+++ b/src/components/common/__tests__/VnInputDate.spec.js
@@ -0,0 +1,72 @@
+import { createWrapper } from 'app/test/vitest/helper.js';
+import { describe, it, expect } from 'vitest';
+import VnInputDate from 'components/common/VnInputDate.vue';
+
+let vm;
+let wrapper;
+
+function generateWrapper(date, outlined, required) {
+    wrapper = createWrapper(VnInputDate, {
+        props: {
+            modelValue: date,
+        },
+        attrs: {
+            isOutlined: outlined,
+            required: required
+        },
+    });
+    wrapper = wrapper.wrapper;
+    vm = wrapper.vm;
+};
+
+describe('VnInputDate', () => {
+
+    describe('formattedDate', () => {     
+        it('formats a valid date correctly', async () => {
+            generateWrapper('2023-12-25', false, false);
+            await vm.$nextTick();
+            expect(vm.formattedDate).toBe('25/12/2023');
+        });
+
+        it('updates the model value when a new date is set', async () => {
+            const input = wrapper.find('input');
+            await input.setValue('31/12/2023');
+            expect(wrapper.emitted()['update:modelValue']).toBeTruthy();
+            expect(wrapper.emitted()['update:modelValue'][0][0]).toBe('2023-12-31T00:00:00.000Z');
+        });
+
+        it('should not update the model value when an invalid date is set', async () => {
+            const input = wrapper.find('input');
+            await input.setValue('invalid-date');
+            expect(wrapper.emitted()['update:modelValue'][0][0]).toBe('2023-12-31T00:00:00.000Z');
+        }); 
+    });
+
+    describe('styleAttrs', () => {
+        it('should return empty styleAttrs when isOutlined is false', async () => {
+            generateWrapper('2023-12-25', false, false);
+            await vm.$nextTick();
+            expect(vm.styleAttrs).toEqual({}); 
+        });
+
+        it('should set styleAttrs when isOutlined is true', async () => {        
+            generateWrapper('2023-12-25', true, false);
+            await vm.$nextTick();
+            expect(vm.styleAttrs.outlined).toBe(true);
+        });
+    });
+
+    describe('required', () => {
+        it('should not applies required class when isRequired is false', async () => {
+            generateWrapper('2023-12-25', false, false);
+            await vm.$nextTick();
+            expect(wrapper.find('.vn-input-date').classes()).not.toContain('required');
+        });
+        
+        it('should applies required class when isRequired is true', async () => {
+            generateWrapper('2023-12-25', false, true);
+            await vm.$nextTick();
+            expect(wrapper.find('.vn-input-date').classes()).toContain('required');
+        });
+    });
+});
\ No newline at end of file
diff --git a/src/components/common/__tests__/VnInputTime.spec.js b/src/components/common/__tests__/VnInputTime.spec.js
new file mode 100644
index 00000000000..2692ac71bf2
--- /dev/null
+++ b/src/components/common/__tests__/VnInputTime.spec.js
@@ -0,0 +1,63 @@
+import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
+import { createWrapper } from 'app/test/vitest/helper';
+import VnInputTime from 'components/common/VnInputTime.vue';
+
+describe('VnInputTime', () => {
+    let wrapper;
+    let vm;
+
+    beforeAll(() => {
+        wrapper = createWrapper(VnInputTime, {
+            props: {
+                isOutlined: true,
+                timeOnly: false,
+            },
+        });
+        vm = wrapper.vm;
+        wrapper = wrapper.wrapper;
+    });
+
+    afterEach(() => {
+        vi.clearAllMocks();
+    });
+
+    it('should return the correct data if isOutlined is true', () => {
+        expect(vm.isOutlined).toBe(true);
+        expect(vm.styleAttrs).toEqual({ dense: true, outlined: true, rounded: true });
+    });
+
+    it('should return the formatted data', () => {
+        expect(vm.dateToTime('2022-01-01T03:23:43')).toBe('03:23');
+    });
+
+    describe('formattedTime', () => {
+        it('should return the formatted time for a valid ISO date', () => {
+            vm.model = '2025-01-02T15:45:00';
+            expect(vm.formattedTime).toBe('15:45');
+        });
+
+        it('should handle null model value gracefully', () => {
+            vm.model = null;
+            expect(vm.formattedTime).toBe(null);
+        });
+
+        it('should handle time-only input correctly', async () => {
+            await wrapper.setProps({ timeOnly: true });
+            vm.formattedTime = '14:30';
+            expect(vm.model).toBe('14:30');
+        });
+
+        it('should pad short time values correctly', async () => {
+            await wrapper.setProps({ timeOnly: true });
+            vm.formattedTime = '9';
+            expect(vm.model).toBe('09:00');
+        });
+
+        it('should not update the model if the value is unchanged', () => {
+            vm.model = '14:30';
+            const previousModel = vm.model;
+            vm.formattedTime = '14:30';
+            expect(vm.model).toBe(previousModel);
+        });
+    });
+});
\ No newline at end of file
diff --git a/src/components/ui/CardSummary.vue b/src/components/ui/CardSummary.vue
index a1de3eee392..f9de8e0c192 100644
--- a/src/components/ui/CardSummary.vue
+++ b/src/components/ui/CardSummary.vue
@@ -2,7 +2,6 @@
 import { ref, computed, watch, onBeforeMount } from 'vue';
 import { useRoute } from 'vue-router';
 import SkeletonSummary from 'components/ui/SkeletonSummary.vue';
-import VnLv from 'src/components/ui/VnLv.vue';
 import { useArrayData } from 'src/composables/useArrayData';
 import { isDialogOpened } from 'src/filters';
 import VnMoreOptions from './VnMoreOptions.vue';
@@ -176,7 +175,7 @@ async function fetch() {
                 display: inline-block;
             }
             .header.link:hover {
-                color: lighten($primary, 20%);
+                color: rgba(var(--q-primary), 0.8);
             }
             .q-checkbox {
                 & .q-checkbox__label {
diff --git a/src/components/ui/FetchedTags.vue b/src/components/ui/FetchedTags.vue
index 6e159087c27..b3912f77944 100644
--- a/src/components/ui/FetchedTags.vue
+++ b/src/components/ui/FetchedTags.vue
@@ -18,8 +18,7 @@ const $props = defineProps({
     },
     columns: {
         type: Number,
-        required: false,
-        default: null,
+        default: 3,
     },
 });
 
diff --git a/src/components/ui/SkeletonSummary.vue b/src/components/ui/SkeletonSummary.vue
index e8407ee7b36..659d4c53d7b 100644
--- a/src/components/ui/SkeletonSummary.vue
+++ b/src/components/ui/SkeletonSummary.vue
@@ -1,38 +1,49 @@
 <template>
     <div class="header bg-primary q-pa-sm q-mb-md">
         <QSkeleton type="rect" square />
+        <QSkeleton type="rect" square />
     </div>
     <div class="row q-pa-md q-col-gutter-md q-mb-md">
-        <QSkeleton type="rect" class="q-mb-md" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="rect" class="q-mb-md" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="rect" class="q-mb-md" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="rect" class="q-mb-md" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="rect" class="q-mb-md" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
-        <QSkeleton type="text" square />
+        <div class="col">
+            <QSkeleton type="rect" class="q-mb-md" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+        </div>
+        <div class="col">
+            <QSkeleton type="rect" class="q-mb-md" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+        </div>
+        <div class="col">
+            <QSkeleton type="rect" class="q-mb-md" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+        </div>
+        <div class="col">
+            <QSkeleton type="rect" class="q-mb-md" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+        </div>
+        <div class="col">
+            <QSkeleton type="rect" class="q-mb-md" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+            <QSkeleton type="text" square />
+        </div>
     </div>
 </template>
 
diff --git a/src/components/ui/VnSearchbar.vue b/src/components/ui/VnSearchbar.vue
index bfaa76588a3..a5ca97b709c 100644
--- a/src/components/ui/VnSearchbar.vue
+++ b/src/components/ui/VnSearchbar.vue
@@ -113,23 +113,20 @@ onMounted(() => {
 });
 
 async function search() {
-    const staticParams = Object.keys(store.userParams ?? {}).length
-        ? store.userParams
-        : store.defaultParams;
     arrayData.resetPagination();
 
-    const filter = {
-        params: {
-            search: searchText.value,
-        },
-        filter: props.filter,
-    };
+    let filter = { params: { search: searchText.value } };
 
     if (!props.searchRemoveParams || !searchText.value) {
-        filter.params = {
-            ...staticParams,
-            search: searchText.value,
+        filter = {
+            params: {
+                ...store.userParams,
+                search: searchText.value,
+            },
+            filter: store.filter,
         };
+    } else {
+        arrayData.reset(['currentFilter', 'userParams']);
     }
 
     if (props.whereFilter) {
diff --git a/src/components/ui/__tests__/CardSummary.spec.js b/src/components/ui/__tests__/CardSummary.spec.js
new file mode 100644
index 00000000000..411ebf9bb60
--- /dev/null
+++ b/src/components/ui/__tests__/CardSummary.spec.js
@@ -0,0 +1,78 @@
+import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest';
+import { createWrapper, axios } from 'app/test/vitest/helper';
+import CardSummary from 'src/components/ui/CardSummary.vue';
+import * as vueRouter from 'vue-router';
+
+describe('CardSummary', () => {
+    let vm;
+    let wrapper;
+
+    beforeAll(() => {
+        vi.spyOn(axios, 'get').mockResolvedValue({ data: [] });
+    });
+
+    vi.spyOn(vueRouter, 'useRoute').mockReturnValue({
+        query: {},
+        params: {},
+        meta: { moduleName: 'mockName' },
+        path: 'mockName/1/summary',
+        name: 'CardSummary',
+    });
+
+    beforeEach(() => {
+        wrapper = createWrapper(CardSummary, {
+            propsData: {
+                dataKey: 'cardSummaryKey',
+                url: 'cardSummaryUrl',
+                filter: 'cardFilter',
+            },
+        });
+        vm = wrapper.vm;
+        wrapper = wrapper.wrapper;
+    });
+
+    afterEach(() => {
+        vi.clearAllMocks();
+    });
+
+    it('should fetch data correctly', async () => {
+        const fetchSpy = vi
+            .spyOn(vm.arrayData, 'fetch')
+            .mockResolvedValue({ data: [{ id: 1, name: 'Test Entity' }] });
+        await vm.fetch();
+
+        expect(fetchSpy).toHaveBeenCalledWith({ append: false, updateRouter: false });
+        expect(wrapper.emitted('onFetch')).toBeTruthy();
+        expect(vm.isLoading).toBe(false);
+    });
+
+    it('should set correct props to the store', () => {
+        expect(vm.store.url).toEqual('cardSummaryUrl');
+        expect(vm.store.filter).toEqual('cardFilter');
+    });
+
+    it('should compute entity correctly from store data', () => {
+        vm.store.data = [{ id: 1, name: 'Entity 1' }];
+        expect(vm.entity).toEqual({ id: 1, name: 'Entity 1' });
+    });
+
+    it('should handle empty data gracefully', () => {
+        vm.store.data = [];
+        expect(vm.entity).toBeUndefined();
+    });
+
+    it('should respond to prop changes and refetch data', async () => {
+        const newUrl = 'CardSummary/35';
+        const newKey = 'cardSummaryKey/35';
+        const fetchSpy = vi.spyOn(vm.arrayData, 'fetch');
+        await wrapper.setProps({ url: newUrl, filter: { key: newKey } });
+
+        expect(fetchSpy).toHaveBeenCalled();
+        expect(vm.store.url).toBe(newUrl);
+        expect(vm.store.filter).toEqual({ key: newKey });
+    });
+
+    it('should return true if route path ends with /summary' , () => {
+        expect(vm.isSummary).toBe(true);
+    });
+});
\ No newline at end of file
diff --git a/src/components/ui/__tests__/VnImg.spec.js b/src/components/ui/__tests__/VnImg.spec.js
new file mode 100644
index 00000000000..39dd1077540
--- /dev/null
+++ b/src/components/ui/__tests__/VnImg.spec.js
@@ -0,0 +1,89 @@
+import { vi, describe, expect, it, beforeEach, afterEach } from 'vitest';
+import { createWrapper } from 'app/test/vitest/helper';
+import VnImg from 'src/components/ui/VnImg.vue';
+
+let wrapper;
+let vm;
+const isEmployeeMock = vi.fn();
+
+function generateWrapper(storage = 'images') {
+    wrapper = createWrapper(VnImg, {
+        props: {
+            id: 123, 
+            zoomResolution: '400x400',
+            storage, 
+        }
+    });
+    wrapper = wrapper.wrapper;
+    vm = wrapper.vm; 
+    vm.timeStamp = 'timestamp';   
+};
+
+vi.mock('src/composables/useSession', () => ({
+    useSession: () => ({
+      getTokenMultimedia: () => 'token',
+    }),
+}));
+  
+vi.mock('src/composables/useRole', () => ({
+    useRole: () => ({
+        isEmployee: isEmployeeMock,
+    }),
+}));
+
+
+describe('VnImg', () => {    
+    beforeEach(() => {
+        isEmployeeMock.mockReset();
+    });
+
+    afterEach(() => {
+        vi.clearAllMocks();
+    });
+
+    describe('getUrl', () => {
+        it('should return /api/{storage}/{id}/downloadFile?access_token={token} when storage is dms', async () => {
+            isEmployeeMock.mockReturnValue(false);
+            generateWrapper('dms');
+            await vm.$nextTick();
+            const url = vm.getUrl();
+            expect(url).toBe('/api/dms/123/downloadFile?access_token=token');    
+        });
+
+        it('should return /no-user.png when role is not employee and storage is not dms', async () => {
+            isEmployeeMock.mockReturnValue(false);
+            generateWrapper();
+            await vm.$nextTick();   
+            const url = vm.getUrl();
+            expect(url).toBe('/no-user.png');
+        });
+
+        it('should return /api/{storage}/{collection}/{curResolution}/{id}/download?access_token={token}&{timeStamp} when zoom is false and role is employee and storage is not dms', async () => {
+            isEmployeeMock.mockReturnValue(true);
+            generateWrapper();
+            await vm.$nextTick();
+            const url = vm.getUrl();
+            expect(url).toBe('/api/images/catalog/200x200/123/download?access_token=token&timestamp');
+        });
+
+        it('should return /api/{storage}/{collection}/{curResolution}/{id}/download?access_token={token}&{timeStamp} when zoom is true and role is employee and storage is not dms', async () => {
+            isEmployeeMock.mockReturnValue(true);
+            generateWrapper();
+            await vm.$nextTick();
+            const url = vm.getUrl(true);
+            expect(url).toBe('/api/images/catalog/400x400/123/download?access_token=token&timestamp');
+        });
+    });
+
+    describe('reload', () => {
+        it('should update the timestamp', async () => {
+            generateWrapper();
+            const initialTimestamp = wrapper.vm.timeStamp;
+
+            wrapper.vm.reload();
+            const newTimestamp = wrapper.vm.timeStamp;
+       
+            expect(initialTimestamp).not.toEqual(newTimestamp);
+        });
+    });
+});
\ No newline at end of file
diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js
index c13c4f9a609..d76053ce938 100644
--- a/src/composables/useArrayData.js
+++ b/src/composables/useArrayData.js
@@ -7,7 +7,9 @@ import { isDialogOpened } from 'src/filters';
 
 const arrayDataStore = useArrayDataStore();
 
-export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
+export function useArrayData(key, userOptions) {
+    key ??= useRoute().meta.moduleName;
+    
     if (!key) throw new Error('ArrayData: A key is required to use this composable');
 
     if (!arrayDataStore.get(key)) arrayDataStore.set(key);
@@ -31,10 +33,11 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
                     : JSON.parse(params?.filter ?? '{}');
             delete params.filter;
 
-            store.userParams = { ...store.userParams, ...params };
+            store.userParams = params;
             store.filter = { ...filter, ...store.userFilter };
             if (filter?.order) store.order = filter.order;
         }
+        setCurrentFilter();
     });
 
     if (key && userOptions) setOptions();
@@ -76,11 +79,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
 
         cancelRequest();
         canceller = new AbortController();
-        const { params, limit } = getCurrentFilter();
-
-        store.currentFilter = JSON.parse(JSON.stringify(params));
-        delete store.currentFilter.filter.include;
-        store.currentFilter.filter = JSON.stringify(store.currentFilter.filter);
+        const { params, limit } = setCurrentFilter();
 
         let exprFilter;
         if (store?.exprBuilder) {
@@ -105,7 +104,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
         store.hasMoreData = limit && response.data.length >= limit;
 
         if (!append && !isDialogOpened() && updateRouter) {
-            if (updateStateParams(response.data)?.redirect) return;
+            if (updateStateParams(response.data)?.redirect && !store.keepData) return;
         }
         store.isLoading = false;
         canceller = null;
@@ -140,12 +139,12 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
         }
     }
 
-    async function applyFilter({ filter, params }) {
+    async function applyFilter({ filter, params }, fetchOptions = {}) {
         if (filter) store.userFilter = filter;
         store.filter = {};
         if (params) store.userParams = { ...params };
 
-        const response = await fetch({});
+        const response = await fetch(fetchOptions);
         return response;
     }
 
@@ -274,14 +273,14 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
     }
 
     function getCurrentFilter() {
+        if (!Object.keys(store.userParams).length)
+            store.userParams = store.defaultParams ?? {};
+
         const filter = {
             limit: store.limit,
+            ...store.userFilter,
         };
 
-        let userParams = { ...store.userParams };
-
-        Object.assign(filter, store.userFilter);
-
         let where;
         if (filter?.where || store.filter?.where)
             where = Object.assign(filter?.where ?? {}, store.filter?.where ?? {});
@@ -289,7 +288,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
         filter.where = where;
         const params = { filter };
 
-        Object.assign(params, userParams);
+        Object.assign(params, store.userParams);
         if (params.filter) params.filter.skip = store.skip;
         if (store?.order && typeof store?.order == 'string') store.order = [store.order];
         if (store.order?.length) params.filter.order = [...store.order];
@@ -298,6 +297,14 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
         return { filter, params, limit: filter.limit };
     }
 
+    function setCurrentFilter() {
+        const { params, limit } = getCurrentFilter();
+        store.currentFilter = JSON.parse(JSON.stringify(params));
+        delete store.currentFilter.filter.include;
+        store.currentFilter.filter = JSON.stringify(store.currentFilter.filter);
+        return { params, limit };
+    }
+
     function processData(data, { map = true, append = true }) {
         if (!append) {
             store.data = [];
@@ -331,6 +338,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
         applyFilter,
         addFilter,
         getCurrentFilter,
+        setCurrentFilter,
         addFilterWhere,
         addOrder,
         deleteOrder,
diff --git a/src/composables/useFilterParams.js b/src/composables/useFilterParams.js
index 2878e4b76ab..07dcdf99b36 100644
--- a/src/composables/useFilterParams.js
+++ b/src/composables/useFilterParams.js
@@ -29,8 +29,12 @@ export function useFilterParams(key) {
         orders.value = orderObject;
     }
 
-    function setUserParams(watchedParams) {
-        if (!watchedParams || Object.keys(watchedParams).length == 0) return;
+    function setUserParams(watchedParams = {}) {
+        if (Object.keys(watchedParams).length == 0) {
+            params.value = {};
+            orders.value = {};
+            return;
+        }
 
         if (typeof watchedParams == 'string') watchedParams = JSON.parse(watchedParams);
         if (typeof watchedParams?.filter == 'string')
diff --git a/src/composables/useHasContent.js b/src/composables/useHasContent.js
new file mode 100644
index 00000000000..8ab01837605
--- /dev/null
+++ b/src/composables/useHasContent.js
@@ -0,0 +1,24 @@
+import { onMounted, ref } from 'vue';
+
+export function useHasContent(selector) {
+    const container = ref({});
+    const hasContent = ref();
+
+    onMounted(() => {
+        container.value = document.querySelector(selector);
+        if (!container.value) return;
+
+        const observer = new MutationObserver(() => {
+            if (document.querySelector(selector))
+                hasContent.value = !!container.value.childNodes.length;
+        });
+
+        observer.observe(container.value, {
+            subtree: true,
+            childList: true,
+            attributes: true,
+        });
+    });
+
+    return hasContent;
+}
diff --git a/src/css/app.scss b/src/css/app.scss
index d4790a6b8a2..a28a04a16ed 100644
--- a/src/css/app.scss
+++ b/src/css/app.scss
@@ -310,6 +310,14 @@ input::-webkit-inner-spin-button {
 .no-visible {
     visibility: hidden;
 }
+
+.q-item > .q-item__section:has(.q-checkbox) {
+    max-width: min-content;
+}
+
+.row > .column:has(.q-checkbox) {
+    max-width: min-content;
+}
 .q-field__inner {
     .q-field__control {
         min-height: auto !important;
diff --git a/src/filters/index.js b/src/filters/index.js
index a92d2eb07ee..bf1429aee8e 100644
--- a/src/filters/index.js
+++ b/src/filters/index.js
@@ -16,6 +16,7 @@ import getUpdatedValues from './getUpdatedValues';
 import getParamWhere from './getParamWhere';
 import parsePhone from './parsePhone';
 import isDialogOpened from './isDialogOpened';
+import toCelsius from './toCelsius';
 
 export {
     getUpdatedValues,
@@ -36,4 +37,5 @@ export {
     dashIfEmpty,
     dateRange,
     getParamWhere,
+    toCelsius,
 };
diff --git a/src/filters/toCelsius.js b/src/filters/toCelsius.js
new file mode 100644
index 00000000000..83cab32ca85
--- /dev/null
+++ b/src/filters/toCelsius.js
@@ -0,0 +1,3 @@
+export default function toCelsius(value) {
+    return value ? `${value}°C` : '';
+}
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index bf001c9ba4d..4734469702d 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -346,6 +346,7 @@ globals:
         countryFk: Country
         companyFk: Company
     changePass: Change password
+    setPass: Set password
     deleteConfirmTitle: Delete selected elements
     changeState: Change state
     raid: 'Raid {daysInForward} days'
@@ -388,80 +389,6 @@ cau:
     subtitle: By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.
     inputLabel: Explain why this error should not appear
     askPrivileges: Ask for privileges
-entry:
-    list:
-        newEntry: New entry
-        tableVisibleColumns:
-            created: Creation
-            supplierFk: Supplier
-            isBooked: Booked
-            isConfirmed: Confirmed
-            isOrdered: Ordered
-            companyFk: Company
-            travelFk: Travel
-            isExcludedFromAvailable: Inventory
-            invoiceAmount: Import
-    summary:
-        commission: Commission
-        currency: Currency
-        invoiceNumber: Invoice number
-        ordered: Ordered
-        booked: Booked
-        excludedFromAvailable: Inventory
-        travelReference: Reference
-        travelAgency: Agency
-        travelShipped: Shipped
-        travelDelivered: Delivered
-        travelLanded: Landed
-        travelReceived: Received
-        buys: Buys
-        stickers: Stickers
-        package: Package
-        packing: Pack.
-        grouping: Group.
-        buyingValue: Buying value
-        import: Import
-        pvp: PVP
-    basicData:
-        travel: Travel
-        currency: Currency
-        commission: Commission
-        observation: Observation
-        booked: Booked
-        excludedFromAvailable: Inventory
-    buys:
-        observations: Observations
-        packagingFk: Box
-        color: Color
-        printedStickers: Printed stickers
-    notes:
-        observationType: Observation type
-    latestBuys:
-        tableVisibleColumns:
-            image: Picture
-            itemFk: Item ID
-            weightByPiece: Weight/Piece
-            isActive: Active
-            family: Family
-            entryFk: Entry
-            freightValue: Freight value
-            comissionValue: Commission value
-            packageValue: Package value
-            isIgnored: Is ignored
-            price2: Grouping
-            price3: Packing
-            minPrice: Min
-            ektFk: Ekt
-            packingOut: Package out
-            landing: Landing
-            isExcludedFromAvailable: Es inventory
-    params:
-        toShipped: To
-        fromShipped: From
-        warehouseiNFk: Warehouse
-        daysOnward: Days onward
-        daysAgo: Days ago
-        warehouseInFk: Warehouse in
 ticket:
     params:
         ticketFk: Ticket ID
@@ -578,27 +505,6 @@ parking:
     searchBar:
         info: You can search by parking code
         label: Search parking...
-order:
-    field:
-        salesPersonFk: Sales Person
-    form:
-        clientFk: Client
-        addressFk: Address
-        agencyModeFk: Agency
-    list:
-        newOrder: New Order
-    summary:
-        basket: Basket
-        notConfirmed: Not confirmed
-        created: Created
-        createdFrom: Created From
-        address: Address
-        total: Total
-        items: Items
-        orderTicketList: Order Ticket List
-        amount: Amount
-        confirm: Confirm
-        confirmLines: Confirm lines
 department:
     chat: Chat
     bossDepartment: Boss Department
@@ -798,6 +704,7 @@ travel:
             totalEntries: Total entries
             totalEntriesTooltip: Total entries
             daysOnward: Landed days onwards
+            awb: AWB
     summary:
         entryId: Entry Id
         freight: Freight
@@ -889,7 +796,10 @@ components:
         hasMinPrice: Minimum price
         # LatestBuysFilter
         salesPersonFk: Buyer
+        supplierFk: Supplier
         from: From
+        to: To
+        visible: Is visible
         active: Is active
         floramondo: Is floramondo
         showBadDates: Show future items
diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml
index 2c95f936c5f..b764b1e4350 100644
--- a/src/i18n/locale/es.yml
+++ b/src/i18n/locale/es.yml
@@ -348,6 +348,7 @@ globals:
         countryFk: País
         companyFk: Empresa
     changePass: Cambiar contraseña
+    setPass: Establecer contraseña
     deleteConfirmTitle: Eliminar los elementos seleccionados
     changeState: Cambiar estado
     raid: 'Redada {daysInForward} días'
@@ -388,80 +389,6 @@ cau:
     subtitle: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc
     inputLabel: Explique el motivo por el que no deberia aparecer este fallo
     askPrivileges: Solicitar permisos
-entry:
-    list:
-        newEntry: Nueva entrada
-        tableVisibleColumns:
-            created: Creación
-            supplierFk: Proveedor
-            isBooked: Asentado
-            isConfirmed: Confirmado
-            isOrdered: Pedida
-            companyFk: Empresa
-            travelFk: Envio
-            isExcludedFromAvailable: Inventario
-            invoiceAmount: Importe
-    summary:
-        commission: Comisión
-        currency: Moneda
-        invoiceNumber: Núm. factura
-        ordered: Pedida
-        booked: Contabilizada
-        excludedFromAvailable: Inventario
-        travelReference: Referencia
-        travelAgency: Agencia
-        travelShipped: F. envio
-        travelWarehouseOut: Alm. salida
-        travelDelivered: Enviada
-        travelLanded: F. entrega
-        travelReceived: Recibida
-        buys: Compras
-        stickers: Etiquetas
-        package: Embalaje
-        packing: Pack.
-        grouping: Group.
-        buyingValue: Coste
-        import: Importe
-        pvp: PVP
-    basicData:
-        travel: Envío
-        currency: Moneda
-        observation: Observación
-        commission: Comisión
-        booked: Asentado
-        excludedFromAvailable: Inventario
-    buys:
-        observations: Observaciónes
-        packagingFk: Embalaje
-        color: Color
-        printedStickers: Etiquetas impresas
-    notes:
-        observationType: Tipo de observación
-    latestBuys:
-        tableVisibleColumns:
-            image: Foto
-            itemFk: Id Artículo
-            weightByPiece: Peso (gramos)/tallo
-            isActive: Activo
-            family: Familia
-            entryFk: Entrada
-            freightValue: Porte
-            comissionValue: Comisión
-            packageValue: Embalaje
-            isIgnored: Ignorado
-            price2: Grouping
-            price3: Packing
-            minPrice: Min
-            ektFk: Ekt
-            packingOut: Embalaje envíos
-            landing: Llegada
-            isExcludedFromAvailable: Es inventario
-    params:
-        toShipped: Hasta
-        fromShipped: Desde
-        warehouseInFk: Alm. entrada
-        daysOnward: Días adelante
-        daysAgo: Días atras
 ticket:
     params:
         ticketFk: ID de ticket
@@ -562,30 +489,6 @@ invoiceOut:
         comercial: Comercial
         errors:
             downloadCsvFailed: Error al descargar CSV
-order:
-    field:
-        salesPersonFk: Comercial
-    form:
-        clientFk: Cliente
-        addressFk: Dirección
-        agencyModeFk: Agencia
-    list:
-        newOrder: Nuevo Pedido
-    summary:
-        basket: Cesta
-        notConfirmed: No confirmada
-        created: Creado
-        createdFrom: Creado desde
-        address: Dirección
-        total: Total
-        vat: IVA
-        state: Estado
-        alias: Alias
-        items: Artículos
-        orderTicketList: Tickets del pedido
-        amount: Monto
-        confirm: Confirmar
-        confirmLines: Confirmar lineas
 shelving:
     list:
         parking: Parking
@@ -797,6 +700,7 @@ travel:
             totalEntries: ∑
             totalEntriesTooltip: Entradas totales
             daysOnward: Días de llegada en adelante
+            awb: AWB
     summary:
         entryId: Id entrada
         freight: Porte
@@ -889,7 +793,11 @@ components:
         wareHouseFk: Almacén
         # LatestBuysFilter
         salesPersonFk: Comprador
+        supplierFk: Proveedor
+        visible: Visible
         active: Activo
+        from: Desde
+        to: Hasta
         floramondo: Floramondo
         showBadDates: Ver items a futuro
     userPanel:
diff --git a/src/layouts/OutLayout.vue b/src/layouts/OutLayout.vue
index 0eb1329a405..4ccc6bf9ee9 100644
--- a/src/layouts/OutLayout.vue
+++ b/src/layouts/OutLayout.vue
@@ -2,6 +2,8 @@
 import { Dark, Quasar } from 'quasar';
 import { computed } from 'vue';
 import { useI18n } from 'vue-i18n';
+import { localeEquivalence } from 'src/i18n/index';
+import quasarLang from 'src/utils/quasarLang';
 
 const { t, locale } = useI18n();
 
@@ -12,18 +14,9 @@ const userLocale = computed({
     set(value) {
         locale.value = value;
 
-        if (value === 'en') value = 'en-GB';
+        value = localeEquivalence[value] ?? value;
 
-        // FIXME: Dynamic imports from absolute paths are not compatible with vite:
-        // https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations
-        try {
-            const langList = import.meta.glob('../../node_modules/quasar/lang/*.mjs');
-            langList[`../../node_modules/quasar/lang/${value}.mjs`]().then((lang) => {
-                Quasar.lang.set(lang.default);
-            });
-        } catch (error) {
-            //
-        }
+        quasarLang(value);
     },
 });
 
diff --git a/src/pages/Account/Card/AccountDescriptorMenu.vue b/src/pages/Account/Card/AccountDescriptorMenu.vue
index aa49dabe887..ccf029e4493 100644
--- a/src/pages/Account/Card/AccountDescriptorMenu.vue
+++ b/src/pages/Account/Card/AccountDescriptorMenu.vue
@@ -1,48 +1,56 @@
 <script setup>
 import axios from 'axios';
-import { computed, onMounted, ref } from 'vue';
+import { computed, onMounted, ref, toRefs } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useVnConfirm } from 'composables/useVnConfirm';
+import { useRoute } from 'vue-router';
 import { useAcl } from 'src/composables/useAcl';
 import { useArrayData } from 'src/composables/useArrayData';
+import { useState } from 'src/composables/useState';
 import VnConfirm from 'src/components/ui/VnConfirm.vue';
-import VnChangePassword from 'src/components/common/VnChangePassword.vue';
-import useNotify from 'src/composables/useNotify.js';
-import useHasAccount from 'src/composables/useHasAccount.js';
 import VnInputPassword from 'src/components/common/VnInputPassword.vue';
+import VnChangePassword from 'src/components/common/VnChangePassword.vue';
+import { useQuasar } from 'quasar';
+import { useRouter } from 'vue-router';
 
 const $props = defineProps({
-    entityId: {
-        type: Number,
+    hasAccount: {
+        type: Boolean,
+        default: false,
         required: true,
     },
 });
 
 const { t } = useI18n();
+const { hasAccount } = toRefs($props);
 const { openConfirmationModal } = useVnConfirm();
-const { notify } = useNotify();
+const route = useRoute();
+const router = useRouter();
+const state = useState();
+const user = state.getUser();
+const { notify } = useQuasar();
 const account = computed(() => useArrayData('AccountId').store.data[0]);
-
-onMounted(async () => {
-    account.value.hasAccount = await useHasAccount($props.entityId);
-});
+account.value.hasAccount = hasAccount.value;
+const entityId = computed(() => +route.params.id);
+const hasitManagementAccess = ref();
+const hasSysadminAccess = ref();
 
 async function updateStatusAccount(active) {
     if (active) {
-        await axios.post(`Accounts`, { id: $props.entityId });
+        await axios.post(`Accounts`, { id: entityId.value });
     } else {
-        await axios.delete(`Accounts/${$props.entityId}`);
+        await axios.delete(`Accounts/${entityId.value}`);
     }
 
     account.value.hasAccount = active;
     const status = active ? 'enable' : 'disable';
     notify({
-        message: t(`account.card.${status}Account.success`),
+        message: t(`account.card.actions.${status}Account.success`),
         type: 'positive',
     });
 }
 async function updateStatusUser(active) {
-    await axios.patch(`VnUsers/${$props.entityId}`, { active });
+    await axios.patch(`VnUsers/${entityId.value}`, { active });
     account.value.active = active;
     const status = active ? 'activate' : 'deactivate';
     notify({
@@ -50,6 +58,17 @@ async function updateStatusUser(active) {
         type: 'positive',
     });
 }
+
+async function deleteAccount() {
+    const { data } = await axios.delete(`VnUsers/${entityId.value}`);
+    if (data) {
+        notify({
+            message: t('account.card.actions.delete.success'),
+            type: 'positive',
+        });
+        router.push({ name: 'AccountList' });
+    }
+}
 const showSyncDialog = ref(false);
 const syncPassword = ref(null);
 const shouldSyncPassword = ref(false);
@@ -64,11 +83,27 @@ async function sync() {
         type: 'positive',
     });
 }
+const askOldPass = ref(false);
+const changePassRef = ref();
+
+const onChangePass = (oldPass) => {
+    askOldPass.value = oldPass;
+    changePassRef.value.show();
+};
+
+onMounted(() => {
+    hasitManagementAccess.value = useAcl().hasAny([
+        { model: 'VnUser', props: 'higherPrivileges', accessType: 'WRITE' },
+    ]);
+    hasSysadminAccess.value = useAcl().hasAny([
+        { model: 'VnUser', props: 'adminUser', accessType: 'WRITE' },
+    ]);
+});
 </script>
 <template>
     <VnChangePassword
         ref="changePassRef"
-        :ask-old-pass="true"
+        :ask-old-pass="askOldPass"
         :submit-fn="
             async (newPassword, oldPassword) => {
                 await axios.patch(`Accounts/change-password`, {
@@ -110,18 +145,46 @@ async function sync() {
         </template>
     </VnConfirm>
     <QItem
-        v-if="
-            entityId == account.id &&
-            useAcl().hasAny([{ model: 'Account', props: '*', accessType: 'WRITE' }])
-        "
+        v-if="hasitManagementAccess"
         v-ripple
         clickable
-        @click="$refs.changePassRef.show()"
+        @click="
+            openConfirmationModal(
+                t('account.card.actions.disableAccount.title'),
+                t('account.card.actions.disableAccount.subtitle'),
+                () => deleteAccount()
+            )
+        "
     >
-        <QItemSection>{{ t('globals.changePass') }}</QItemSection>
+        <QItemSection>{{ t('globals.delete') }}</QItemSection>
     </QItem>
     <QItem
-        v-if="account.hasAccount"
+        v-if="hasSysadminAccess"
+        v-ripple
+        clickable
+        @click="user.id === account.id ? onChangePass(true) : onChangePass(false)"
+    >
+        <QItemSection v-if="user.id === account.id">
+            {{ t('globals.changePass') }}
+        </QItemSection>
+        <QItemSection v-else>{{ t('globals.setPass') }}</QItemSection>
+    </QItem>
+    <QItem
+        v-if="!account.hasAccount && hasSysadminAccess"
+        v-ripple
+        clickable
+        @click="
+            openConfirmationModal(
+                t('account.card.actions.enableAccount.title'),
+                t('account.card.actions.enableAccount.subtitle'),
+                () => updateStatusAccount(true)
+            )
+        "
+    >
+        <QItemSection>{{ t('account.card.actions.enableAccount.name') }}</QItemSection>
+    </QItem>
+    <QItem
+        v-if="account.hasAccount && hasSysadminAccess"
         v-ripple
         clickable
         @click="
@@ -136,7 +199,7 @@ async function sync() {
     </QItem>
 
     <QItem
-        v-if="!account.active"
+        v-if="!account.active && hasitManagementAccess"
         v-ripple
         clickable
         @click="
@@ -150,7 +213,7 @@ async function sync() {
         <QItemSection>{{ t('account.card.actions.activateUser.name') }}</QItemSection>
     </QItem>
     <QItem
-        v-if="account.active"
+        v-if="account.active && hasitManagementAccess"
         v-ripple
         clickable
         @click="
@@ -163,7 +226,12 @@ async function sync() {
     >
         <QItemSection>{{ t('account.card.actions.deactivateUser.name') }}</QItemSection>
     </QItem>
-    <QItem v-ripple clickable @click="showSyncDialog = true">
+    <QItem
+        v-if="useAcl().hasAny([{ model: 'VnRole', props: '*', accessType: 'WRITE' }])"
+        v-ripple
+        clickable
+        @click="showSyncDialog = true"
+    >
         <QItemSection>{{ t('account.card.actions.sync.name') }}</QItemSection>
     </QItem>
     <QSeparator />
diff --git a/src/pages/Customer/Card/CustomerBillingData.vue b/src/pages/Customer/Card/CustomerBillingData.vue
index 48f729e29d7..29394ceece4 100644
--- a/src/pages/Customer/Card/CustomerBillingData.vue
+++ b/src/pages/Customer/Card/CustomerBillingData.vue
@@ -38,7 +38,7 @@ const getBankEntities = (data, formData) => {
                     hide-selected
                     option-label="name"
                     option-value="id"
-                    v-model="data.payMethod"
+                    v-model="data.payMethodFk"
                 />
                 <VnInput :label="t('Due day')" clearable v-model="data.dueDay" />
             </VnRow>
diff --git a/src/pages/Customer/Card/CustomerCredits.vue b/src/pages/Customer/Card/CustomerCredits.vue
index 1fa7047e5c6..d6e4be89e3e 100644
--- a/src/pages/Customer/Card/CustomerCredits.vue
+++ b/src/pages/Customer/Card/CustomerCredits.vue
@@ -59,6 +59,7 @@ const columns = computed(() => [
 </script>
 <template>
     <VnTable
+        :user-filter="{ include: filter.include }"
         ref="tableRef"
         data-key="ClientCredit"
         url="ClientCredits"
diff --git a/src/pages/Customer/Card/CustomerDescriptor.vue b/src/pages/Customer/Card/CustomerDescriptor.vue
index dc5f08d3757..cb49109d01b 100644
--- a/src/pages/Customer/Card/CustomerDescriptor.vue
+++ b/src/pages/Customer/Card/CustomerDescriptor.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, computed, onMounted } from 'vue';
+import { ref, computed } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 
@@ -11,16 +11,9 @@ import CardDescriptor from 'components/ui/CardDescriptor.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import VnUserLink from 'src/components/ui/VnUserLink.vue';
 import CustomerDescriptorMenu from './CustomerDescriptorMenu.vue';
-import { useState } from 'src/composables/useState';
-const state = useState();
-
-const customer = ref();
-
-onMounted(async () => {
-    customer.value = state.get('customer');
-    if (customer.value) customer.value.webAccess = data.value?.account?.isActive;
-});
 
+const customerDebt = ref();
+const customerCredit = ref();
 const $props = defineProps({
     id: {
         type: Number,
@@ -42,10 +35,12 @@ const entityId = computed(() => {
 
 const data = ref(useCardDescription());
 const setData = (entity) => {
+    customerDebt.value = entity?.debt;
+    customerCredit.value = entity?.credit;
     data.value = useCardDescription(entity?.name, entity?.id);
 };
 const debtWarning = computed(() => {
-    return customer.value?.debt > customer.value?.credit ? 'negative' : 'primary';
+    return customerDebt.value > customerCredit.value ? 'negative' : 'primary';
 });
 </script>
 
@@ -97,26 +92,21 @@ const debtWarning = computed(() => {
                 :value="entity.businessType.description"
             />
         </template>
-        <template #icons>
-            <QCardActions v-if="customer" class="q-gutter-x-md">
+        <template #icons="{ entity }">
+            <QCardActions class="q-gutter-x-md">
                 <QIcon
-                    v-if="!customer.isActive"
+                    v-if="!entity.isActive"
                     name="vn:disabled"
                     size="xs"
                     color="primary"
                 >
                     <QTooltip>{{ t('customer.card.isDisabled') }}</QTooltip>
                 </QIcon>
-                <QIcon
-                    v-if="customer.isFreezed"
-                    name="vn:frozen"
-                    size="xs"
-                    color="primary"
-                >
+                <QIcon v-if="entity.isFreezed" name="vn:frozen" size="xs" color="primary">
                     <QTooltip>{{ t('customer.card.isFrozen') }}</QTooltip>
                 </QIcon>
                 <QIcon
-                    v-if="!customer.account?.active"
+                    v-if="!entity.account?.active"
                     color="primary"
                     name="vn:noweb"
                     size="xs"
@@ -124,7 +114,7 @@ const debtWarning = computed(() => {
                     <QTooltip>{{ t('customer.card.webAccountInactive') }}</QTooltip>
                 </QIcon>
                 <QIcon
-                    v-if="customer.debt > customer.credit"
+                    v-if="entity.debt > entity.credit"
                     name="vn:risk"
                     size="xs"
                     :color="debtWarning"
@@ -132,7 +122,7 @@ const debtWarning = computed(() => {
                     <QTooltip>{{ t('customer.card.hasDebt') }}</QTooltip>
                 </QIcon>
                 <QIcon
-                    v-if="!customer.isTaxDataChecked"
+                    v-if="!entity.isTaxDataChecked"
                     name="vn:no036"
                     size="xs"
                     color="primary"
@@ -140,7 +130,7 @@ const debtWarning = computed(() => {
                     <QTooltip>{{ t('customer.card.notChecked') }}</QTooltip>
                 </QIcon>
                 <QBtn
-                    v-if="customer.unpaid"
+                    v-if="entity.unpaid"
                     flat
                     size="sm"
                     icon="vn:Client_unpaid"
diff --git a/src/pages/Customer/Card/CustomerFiscalData.vue b/src/pages/Customer/Card/CustomerFiscalData.vue
index aff7deda41a..8f2c4efb00c 100644
--- a/src/pages/Customer/Card/CustomerFiscalData.vue
+++ b/src/pages/Customer/Card/CustomerFiscalData.vue
@@ -44,6 +44,7 @@ function handleLocation(data, location) {
                     :required="true"
                     :rules="validate('client.socialName')"
                     clearable
+                    uppercase="true"
                     v-model="data.socialName"
                 >
                     <template #append>
diff --git a/src/pages/Customer/Card/CustomerGreuges.vue b/src/pages/Customer/Card/CustomerGreuges.vue
index dcf297d12ed..47a589aaafd 100644
--- a/src/pages/Customer/Card/CustomerGreuges.vue
+++ b/src/pages/Customer/Card/CustomerGreuges.vue
@@ -84,6 +84,7 @@ const columns = computed(() => [
             component: 'number',
             autofocus: true,
             required: true,
+            positive: false,
         },
         format: ({ amount }) => toCurrency(amount),
         create: true,
diff --git a/src/pages/Customer/CustomerList.vue b/src/pages/Customer/CustomerList.vue
index fdfd7ff9c86..bd2947cfcdb 100644
--- a/src/pages/Customer/CustomerList.vue
+++ b/src/pages/Customer/CustomerList.vue
@@ -50,6 +50,14 @@ const columns = computed(() => [
         isTitle: true,
         create: true,
         columnClass: 'expand',
+        attrs: {
+            uppercase: true,
+        },
+        columnFilter: {
+            attrs: {
+                uppercase: false,
+            },
+        },
     },
     {
         align: 'left',
@@ -423,7 +431,7 @@ function handleLocation(data, location) {
                 :label="t('customer.summary.salesPerson')"
                 v-model="data.salesPersonFk"
                 :params="{
-                    departmentCodes: ['VT', 'shopping'],
+                    departmentCodes: ['VT'],
                 }"
                 :has-avatar="true"
                 :id-value="data.salesPersonFk"
diff --git a/src/pages/Customer/components/CustomerAddressCreate.vue b/src/pages/Customer/components/CustomerAddressCreate.vue
index bc4d6a1285a..32b4078db88 100644
--- a/src/pages/Customer/components/CustomerAddressCreate.vue
+++ b/src/pages/Customer/components/CustomerAddressCreate.vue
@@ -11,6 +11,7 @@ import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
 import CustomerNewCustomsAgent from 'src/pages/Customer/components/CustomerNewCustomsAgent.vue';
+import VnInputNumber from 'src/components/common/VnInputNumber.vue';
 
 const { t } = useI18n();
 const route = useRoute();
@@ -150,6 +151,22 @@ function onAgentCreated({ id, fiscalName }, data) {
                     </template>
                 </VnSelectDialog>
             </VnRow>
+            <VnRow>
+                <VnInputNumber
+                    :label="t('Longitude')"
+                    clearable
+                    v-model="data.longitude"
+                    :decimal-places="7"
+                    :positive="false"
+                />
+                <VnInputNumber
+                    :label="t('Latitude')"
+                    clearable
+                    v-model="data.latitude"
+                    :decimal-places="7"
+                    :positive="false"
+                />
+            </VnRow>
         </template>
     </FormModel>
 </template>
@@ -175,4 +192,6 @@ es:
     Mobile: Movíl
     Incoterms: Incoterms
     Customs agent: Agente de aduanas
+    Longitude: Longitud
+    Latitude: Latitud
 </i18n>
diff --git a/src/pages/Department/Card/DepartmentDescriptor.vue b/src/pages/Department/Card/DepartmentDescriptor.vue
index e08495faf96..b219ccfe12c 100644
--- a/src/pages/Department/Card/DepartmentDescriptor.vue
+++ b/src/pages/Department/Card/DepartmentDescriptor.vue
@@ -106,7 +106,7 @@ const { openConfirmationModal } = useVnConfirm();
                     :to="{
                         name: 'WorkerList',
                         query: {
-                            params: JSON.stringify({ departmentFk: entityId }),
+                            table: JSON.stringify({ departmentFk: entityId }),
                         },
                     }"
                 >
diff --git a/src/pages/Entry/Card/EntryBasicData.vue b/src/pages/Entry/Card/EntryBasicData.vue
index 14728783747..68d666fc0cd 100644
--- a/src/pages/Entry/Card/EntryBasicData.vue
+++ b/src/pages/Entry/Card/EntryBasicData.vue
@@ -3,7 +3,6 @@ import { ref } from 'vue';
 import { useRoute } from 'vue-router';
 import { useI18n } from 'vue-i18n';
 import { useRole } from 'src/composables/useRole';
-
 import FetchData from 'components/FetchData.vue';
 import FormModel from 'components/FormModel.vue';
 import VnRow from 'components/ui/VnRow.vue';
@@ -11,7 +10,7 @@ import VnInput from 'src/components/common/VnInput.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
 import FilterTravelForm from 'src/components/FilterTravelForm.vue';
-
+import VnInputNumber from 'src/components/common/VnInputNumber.vue';
 import { toDate } from 'src/filters';
 
 const route = useRoute();
@@ -26,6 +25,7 @@ const onFilterTravelSelected = (formData, id) => {
     formData.travelFk = id;
 };
 </script>
+
 <template>
     <FetchData
         ref="companiesRef"
@@ -93,14 +93,13 @@ const onFilterTravelSelected = (formData, id) => {
                     <template #option="scope">
                         <QItem v-bind="scope.itemProps">
                             <QItemSection>
-                                <QItemLabel
-                                    >{{ scope.opt?.agencyModeName }} -
-                                    {{ scope.opt?.warehouseInName }} ({{
-                                        toDate(scope.opt?.shipped)
-                                    }}) &#x2192; {{ scope.opt?.warehouseOutName }} ({{
-                                        toDate(scope.opt?.landed)
-                                    }})</QItemLabel
-                                >
+                                <QItemLabel>
+                                    {{ scope.opt?.agencyModeName }} -
+                                    {{ scope.opt?.warehouseInName }}
+                                    ({{ toDate(scope.opt?.shipped) }}) →
+                                    {{ scope.opt?.warehouseOutName }}
+                                    ({{ toDate(scope.opt?.landed) }})
+                                </QItemLabel>
                             </QItemSection>
                         </QItem>
                     </template>
@@ -126,6 +125,13 @@ const onFilterTravelSelected = (formData, id) => {
                 />
             </VnRow>
             <VnRow>
+                <VnInputNumber
+                    :label="t('entry.summary.commission')"
+                    v-model="data.commission"
+                    step="1"
+                    autofocus
+                    :positive="false"
+                />
                 <VnSelect
                     :label="t('entry.summary.currency')"
                     v-model="data.currencyFk"
@@ -133,12 +139,23 @@ const onFilterTravelSelected = (formData, id) => {
                     option-value="id"
                     option-label="code"
                 />
-                <QInput
-                    :label="t('entry.summary.commission')"
-                    v-model="data.commission"
-                    type="number"
-                    autofocus
-                    min="0"
+            </VnRow>
+            <VnRow>
+                <VnInputNumber
+                    v-model="data.initialTemperature"
+                    name="initialTemperature"
+                    :label="t('entry.basicData.initialTemperature')"
+                    :step="0.5"
+                    :decimal-places="2"
+                    :positive="false"
+                />
+                <VnInputNumber
+                    v-model="data.finalTemperature"
+                    name="finalTemperature"
+                    :label="t('entry.basicData.finalTemperature')"
+                    :step="0.5"
+                    :decimal-places="2"
+                    :positive="false"
                 />
             </VnRow>
             <VnRow>
diff --git a/src/pages/Entry/Card/EntryCard.vue b/src/pages/Entry/Card/EntryCard.vue
index 3f259633806..e00623a21d0 100644
--- a/src/pages/Entry/Card/EntryCard.vue
+++ b/src/pages/Entry/Card/EntryCard.vue
@@ -1,21 +1,13 @@
 <script setup>
-import VnCard from 'components/common/VnCard.vue';
+import VnCardBeta from 'components/common/VnCardBeta.vue';
 import EntryDescriptor from './EntryDescriptor.vue';
-import EntryFilter from '../EntryFilter.vue';
-import filter from './EntryFilter.js';
+import filter from './EntryFilter.js'
 </script>
 <template>
-    <VnCard
+    <VnCardBeta
         data-key="Entry"
         base-url="Entries"
-        :filter="filter"
         :descriptor="EntryDescriptor"
-        :filter-panel="EntryFilter"
-        search-data-key="EntryList"
-        :searchbar-props="{
-            url: 'Entries/filter',
-            label: 'Search entries',
-            info: 'You can search by entry reference',
-        }"
+        :user-filter="filter"
     />
 </template>
diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue
index 755e39454b0..8c46fb6e67e 100644
--- a/src/pages/Entry/Card/EntrySummary.vue
+++ b/src/pages/Entry/Card/EntrySummary.vue
@@ -7,7 +7,7 @@ import CardSummary from 'components/ui/CardSummary.vue';
 import VnLv from 'src/components/ui/VnLv.vue';
 import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
 
-import { toDate, toCurrency } from 'src/filters';
+import { toDate, toCurrency, toCelsius } from 'src/filters';
 import { getUrl } from 'src/composables/getUrl';
 import axios from 'axios';
 import FetchedTags from 'src/components/ui/FetchedTags.vue';
@@ -193,6 +193,14 @@ const fetchEntryBuys = async () => {
                     :label="t('entry.summary.invoiceNumber')"
                     :value="entry.invoiceNumber"
                 />
+                <VnLv
+                    :label="t('entry.basicData.initialTemperature')"
+                    :value="toCelsius(entry.initialTemperature)"
+                />
+                <VnLv
+                    :label="t('entry.basicData.finalTemperature')"
+                    :value="toCelsius(entry.finalTemperature)"
+                />
             </QCard>
             <QCard class="vn-one">
                 <VnTitle
diff --git a/src/pages/Entry/EntryFilter.vue b/src/pages/Entry/EntryFilter.vue
index f91f7f1284e..bc8b40aaaa1 100644
--- a/src/pages/Entry/EntryFilter.vue
+++ b/src/pages/Entry/EntryFilter.vue
@@ -40,7 +40,7 @@ const companiesOptions = ref([]);
     <VnFilterPanel :data-key="props.dataKey" :search-button="true">
         <template #tags="{ tag, formatFn }">
             <div class="q-gutter-x-xs">
-                <strong>{{ t(`params.${tag.label}`) }}: </strong>
+                <strong>{{ t(`entryFilter.params.${tag.label}`) }}: </strong>
                 <span>{{ formatFn(tag.value) }}</span>
             </div>
         </template>
@@ -49,7 +49,7 @@ const companiesOptions = ref([]);
                 <QItemSection>
                     <VnInput
                         v-model="params.search"
-                        :label="t('entryFilter.filter.search')"
+                        :label="t('entryFilter.params.search')"
                         is-outlined
                     />
                 </QItemSection>
@@ -58,7 +58,7 @@ const companiesOptions = ref([]);
                 <QItemSection>
                     <VnInput
                         v-model="params.reference"
-                        :label="t('entryFilter.filter.reference')"
+                        :label="t('entryFilter.params.reference')"
                         is-outlined
                     />
                 </QItemSection>
@@ -67,7 +67,7 @@ const companiesOptions = ref([]);
                 <QItemSection>
                     <VnInput
                         v-model="params.invoiceNumber"
-                        :label="t('params.invoiceNumber')"
+                        :label="t('entryFilter.params.invoiceNumber')"
                         is-outlined
                     />
                 </QItemSection>
@@ -76,7 +76,7 @@ const companiesOptions = ref([]);
                 <QItemSection>
                     <VnInput
                         v-model="params.travelFk"
-                        :label="t('params.travelFk')"
+                        :label="t('entryFilter.params.travelFk')"
                         is-outlined
                     />
                 </QItemSection>
@@ -84,7 +84,7 @@ const companiesOptions = ref([]);
             <QItem>
                 <QItemSection>
                     <VnSelect
-                        :label="t('params.companyFk')"
+                        :label="t('entryFilter.params.companyFk')"
                         v-model="params.companyFk"
                         @update:model-value="searchFn()"
                         :options="companiesOptions"
@@ -100,7 +100,7 @@ const companiesOptions = ref([]);
             <QItem>
                 <QItemSection>
                     <VnSelect
-                        :label="t('params.currencyFk')"
+                        :label="t('entryFilter.params.currencyFk')"
                         v-model="params.currencyFk"
                         @update:model-value="searchFn()"
                         :options="currenciesOptions"
@@ -116,7 +116,7 @@ const companiesOptions = ref([]);
             <QItem>
                 <QItemSection>
                     <VnSelect
-                        :label="t('params.supplierFk')"
+                        :label="t('entryFilter.params.supplierFk')"
                         v-model="params.supplierFk"
                         @update:model-value="searchFn()"
                         url="Suppliers"
@@ -148,7 +148,7 @@ const companiesOptions = ref([]);
             <QItem>
                 <QItemSection>
                     <VnInputDate
-                        :label="t('params.created')"
+                        :label="t('entryFilter.params.created')"
                         v-model="params.created"
                         @update:model-value="searchFn()"
                         is-outlined
@@ -158,7 +158,7 @@ const companiesOptions = ref([]);
             <QItem>
                 <QItemSection>
                     <VnInputDate
-                        :label="t('params.from')"
+                        :label="t('entryFilter.params.from')"
                         v-model="params.from"
                         @update:model-value="searchFn()"
                         is-outlined
@@ -168,7 +168,7 @@ const companiesOptions = ref([]);
             <QItem>
                 <QItemSection>
                     <VnInputDate
-                        :label="t('params.to')"
+                        :label="t('entryFilter.params.to')"
                         v-model="params.to"
                         @update:model-value="searchFn()"
                         is-outlined
@@ -178,14 +178,14 @@ const companiesOptions = ref([]);
             <QItem>
                 <QItemSection>
                     <QCheckbox
-                        :label="t('params.isBooked')"
+                        :label="t('entryFilter.params.isBooked')"
                         v-model="params.isBooked"
                         toggle-indeterminate
                     />
                 </QItemSection>
                 <QItemSection>
                     <QCheckbox
-                        :label="t('params.isConfirmed')"
+                        :label="t('entryFilter.params.isConfirmed')"
                         v-model="params.isConfirmed"
                         toggle-indeterminate
                     />
@@ -194,7 +194,7 @@ const companiesOptions = ref([]);
             <QItem>
                 <QItemSection>
                     <QCheckbox
-                        :label="t('params.isOrdered')"
+                        :label="t('entryFilter.params.isOrdered')"
                         v-model="params.isOrdered"
                         toggle-indeterminate
                     />
@@ -202,35 +202,4 @@ const companiesOptions = ref([]);
             </QItem>
         </template>
     </VnFilterPanel>
-</template>
-
-<i18n>
-en:
-    params:
-        
-        invoiceNumber: Invoice number
-        travelFk: Travel
-        companyFk: Company
-        currencyFk: Currency
-        supplierFk: Supplier
-        from: From
-        to: To
-        created: Created
-        isBooked: Booked
-        isConfirmed: Confirmed
-        isOrdered: Ordered
-es:
-    params:
-       
-        invoiceNumber: Núm. factura
-        travelFk: Envío
-        companyFk: Empresa
-        currencyFk: Moneda
-        supplierFk: Proveedor
-        from: Desde
-        to: Hasta
-        created: Fecha creación
-        isBooked: Asentado
-        isConfirmed: Confirmado
-        isOrdered: Pedida
-</i18n>
+</template>
\ No newline at end of file
diff --git a/src/pages/Entry/EntryLatestBuys.vue b/src/pages/Entry/EntryLatestBuys.vue
index 450efe62414..73fdcbbbf16 100644
--- a/src/pages/Entry/EntryLatestBuys.vue
+++ b/src/pages/Entry/EntryLatestBuys.vue
@@ -102,7 +102,7 @@ const columns = [
     },
     {
         align: 'left',
-        label: t('globals.weightByPiece'),
+        label: t('entry.latestBuys.tableVisibleColumns.weightByPiece'),
         name: 'weightByPiece',
         columnFilter: {
             component: 'number',
@@ -157,7 +157,7 @@ const columns = [
     },
     {
         align: 'left',
-        label: t('entry.buys.packageValue'),
+        label: t('entry.latestBuys.tableVisibleColumns.packageValue'),
         name: 'packageValue',
         columnFilter: {
             component: 'number',
@@ -262,8 +262,3 @@ onUnmounted(() => (stateStore.rightDrawer = false));
         :right-search="false"
     />
 </template>
-
-<i18n>
-es:
-    Edit buy(s): Editar compra(s)
-</i18n>
diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue
index 879a5091434..64104215669 100644
--- a/src/pages/Entry/EntryList.vue
+++ b/src/pages/Entry/EntryList.vue
@@ -2,17 +2,17 @@
 import { ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import EntryFilter from './EntryFilter.vue';
-import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
 import VnTable from 'components/VnTable/VnTable.vue';
-import RightMenu from 'src/components/common/RightMenu.vue';
-import { toDate } from 'src/filters';
+import { toCelsius, toDate } from 'src/filters';
 import { useSummaryDialog } from 'src/composables/useSummaryDialog';
 import EntrySummary from './Card/EntrySummary.vue';
 import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
 import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
+import VnSection from 'src/components/common/VnSection.vue';
 
 const { t } = useI18n();
 const tableRef = ref();
+const dataKey = 'EntryList';
 
 const { viewSummary } = useSummaryDialog();
 const entryFilter = {
@@ -157,6 +157,20 @@ const columns = computed(() => [
         name: 'invoiceAmount',
         cardVisible: true,
     },
+    {
+        align: 'left',
+        name: 'initialTemperature',
+        label: t('entry.basicData.initialTemperature'),
+        field: 'initialTemperature',
+        format: (row) => toCelsius(row.initialTemperature),
+    },
+    {
+        align: 'left',
+        name: 'finalTemperature',
+        label: t('entry.basicData.finalTemperature'),
+        field: 'finalTemperature',
+        format: (row) => toCelsius(row.finalTemperature),
+    },
     {
         label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
         name: 'isExcludedFromAvailable',
@@ -178,73 +192,73 @@ const columns = computed(() => [
     },
 ]);
 </script>
+
 <template>
-    <VnSearchbar
-        data-key="EntryList"
+    <VnSection
+        :data-key="dataKey"
+        :columns="columns"
+        prefix="entry"
         url="Entries/filter"
-        :label="t('Search entries')"
-        :info="t('You can search by entry reference')"
-    />
-    <RightMenu>
-        <template #right-panel>
+        :array-data-props="{
+            url: 'Entries/filter',
+            order: 'id DESC',
+            userFilter: entryFilter,
+        }"
+    >
+        <template #rightMenu>
             <EntryFilter data-key="EntryList" />
         </template>
-    </RightMenu>
-    <VnTable
-        ref="tableRef"
-        data-key="EntryList"
-        url="Entries/filter"
-        :filter="entryFilter"
-        :create="{
-            urlCreate: 'Entries',
-            title: t('Create entry'),
-            onDataSaved: ({ id }) => tableRef.redirect(id),
-            formInitialData: {},
-        }"
-        order="id DESC"
-        :columns="columns"
-        redirect="entry"
-        :right-search="false"
-    >
-        <template #column-status="{ row }">
-            <div class="row q-gutter-xs">
-                <QIcon
-                    v-if="!!row.isExcludedFromAvailable"
-                    name="vn:inventory"
-                    color="primary"
-                >
-                    <QTooltip>{{
-                        t('entry.list.tableVisibleColumns.isExcludedFromAvailable')
-                    }}</QTooltip>
-                </QIcon>
-                <QIcon v-if="!!row.isRaid" name="vn:net" color="primary">
-                    <QTooltip>
-                        {{
-                            t('globals.raid', { daysInForward: row.daysInForward })
-                        }}</QTooltip
-                    >
-                </QIcon>
-            </div>
+        <template #body>
+            <VnTable
+                ref="tableRef"
+                :data-key="dataKey"
+                :create="{
+                    urlCreate: 'Entries',
+                    title: t('entry.list.newEntry'),
+                    onDataSaved: ({ id }) => tableRef.redirect(id),
+                    formInitialData: {},
+                }"
+                :columns="columns"
+                redirect="entry"
+                :right-search="false"
+            >
+                <template #column-status="{ row }">
+                    <div class="row q-gutter-xs">
+                        <QIcon
+                            v-if="!!row.isExcludedFromAvailable"
+                            name="vn:inventory"
+                            color="primary"
+                        >
+                            <QTooltip>{{
+                                t(
+                                    'entry.list.tableVisibleColumns.isExcludedFromAvailable'
+                                )
+                            }}</QTooltip>
+                        </QIcon>
+                        <QIcon v-if="!!row.isRaid" name="vn:net" color="primary">
+                            <QTooltip>
+                                {{
+                                    t('globals.raid', {
+                                        daysInForward: row.daysInForward,
+                                    })
+                                }}</QTooltip
+                            >
+                        </QIcon>
+                    </div>
+                </template>
+                <template #column-supplierFk="{ row }">
+                    <span class="link" @click.stop>
+                        {{ row.supplierName }}
+                        <SupplierDescriptorProxy :id="row.supplierFk" />
+                    </span>
+                </template>
+                <template #column-travelFk="{ row }">
+                    <span class="link" @click.stop>
+                        {{ row.travelRef }}
+                        <TravelDescriptorProxy :id="row.travelFk" />
+                    </span>
+                </template>
+            </VnTable>
         </template>
-        <template #column-supplierFk="{ row }">
-            <span class="link" @click.stop>
-                {{ row.supplierName }}
-                <SupplierDescriptorProxy :id="row.supplierFk" />
-            </span>
-        </template>
-        <template #column-travelFk="{ row }">
-            <span class="link" @click.stop>
-                {{ row.travelRef }}
-                <TravelDescriptorProxy :id="row.travelFk" />
-            </span>
-        </template>
-    </VnTable>
+    </VnSection>
 </template>
-
-<i18n>
-es:
-    Virtual entry: Es una redada
-    Search entries: Buscar entradas
-    You can search by entry reference: Puedes buscar por referencia de la entrada
-    Create entry: Crear entrada
-</i18n>
diff --git a/src/pages/Entry/EntryStockBought.vue b/src/pages/Entry/EntryStockBought.vue
index 3f0cd2d99c1..fa0bdc12e2f 100644
--- a/src/pages/Entry/EntryStockBought.vue
+++ b/src/pages/Entry/EntryStockBought.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref } from 'vue';
+import { ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useState } from 'src/composables/useState';
 import { useQuasar } from 'quasar';
@@ -19,7 +19,7 @@ const { t } = useI18n();
 const quasar = useQuasar();
 const state = useState();
 const user = state.getUser();
-const columns = [
+const columns = computed(() => [
     {
         align: 'left',
         label: 'Id',
@@ -31,7 +31,7 @@ const columns = [
     {
         align: 'left',
         name: 'workerFk',
-        label: t('Buyer'),
+        label: t('entryStockBought.buyer'),
         isTitle: true,
         component: 'select',
         cardVisible: true,
@@ -49,7 +49,7 @@ const columns = [
     },
     {
         align: 'center',
-        label: t('Reserve'),
+        label: t('entryStockBought.reserve'),
         name: 'reserve',
         columnFilter: false,
         create: true,
@@ -58,7 +58,7 @@ const columns = [
     },
     {
         align: 'center',
-        label: t('Bought'),
+        label: t('entryStockBought.bought'),
         name: 'bought',
         summation: true,
         cardVisible: true,
@@ -66,7 +66,7 @@ const columns = [
     },
     {
         align: 'left',
-        label: t('Date'),
+        label: t('entryStockBought.date'),
         name: 'dated',
         component: 'date',
         visible: false,
@@ -77,7 +77,7 @@ const columns = [
         name: 'tableActions',
         actions: [
             {
-                title: t('View more details'),
+                title: t('entryStockBought.viewMoreDetails'),
                 icon: 'search',
                 isPrimary: true,
                 action: (row) => {
@@ -92,7 +92,7 @@ const columns = [
             },
         ],
     },
-];
+]);
 
 const fetchDataRef = ref();
 const travelDialogRef = ref(false);
@@ -166,7 +166,7 @@ function round(value) {
             <VnRow class="travel">
                 <div v-if="travel">
                     <span style="color: var(--vn-label-color)">
-                        {{ t('Purchase Spaces') }}:
+                        {{ t('entryStockBought.purchaseSpaces') }}:
                     </span>
                     <span>
                         {{ travel?.m3 }}
@@ -177,7 +177,7 @@ function round(value) {
                         flat
                         icon="edit"
                         @click="openDialog()"
-                        :title="t('Edit travel')"
+                        :title="t('entryStockBought.editTravel')"
                         color="primary"
                     />
                 </div>
@@ -226,7 +226,7 @@ function round(value) {
                 @on-fetch="(data) => setFooter(data)"
                 :create="{
                     urlCreate: 'StockBoughts',
-                    title: t('Reserve some space'),
+                    title: t('entryStockBought.reserveSomeSpace'),
                     onDataSaved: () => tableRef.reload(),
                     formInitialData: {
                         workerFk: user.id,
@@ -288,16 +288,3 @@ function round(value) {
     color: $negative !important;
 }
 </style>
-<i18n>
-    es:
-        Edit travel: Editar envío
-        Travel: Envíos
-        Purchase Spaces: Espacios de compra
-        Buyer: Comprador
-        Reserve: Reservado
-        Bought: Comprado
-        Date: Fecha
-        View more details: Ver más detalles
-        Reserve some space: Reservar espacio
-        This buyer has already made a reservation for this date: Este comprador ya ha hecho una reserva para esta fecha
-</i18n>
diff --git a/src/pages/Entry/MyEntries.vue b/src/pages/Entry/MyEntries.vue
index dbe05eb8803..3f7566ae0da 100644
--- a/src/pages/Entry/MyEntries.vue
+++ b/src/pages/Entry/MyEntries.vue
@@ -123,8 +123,8 @@ const printBuys = (rowId) => {
     <VnSearchbar
         data-key="myEntriesList"
         url="Entries/filter"
-        :label="t('Search entries')"
-        :info="t('You can search by entry reference')"
+        :label="t('myEntries.search')"
+        :info="t('myEntries.searchInfo')"
     />
     <VnTable
         data-key="myEntriesList"
@@ -137,7 +137,3 @@ const printBuys = (rowId) => {
         chip-locale="myEntries"
     />
 </template>
-
-<i18n>
-    You can search by entry reference: Puedes buscar por referencia de la entrada
-</i18n>
diff --git a/src/pages/Entry/locale/en.yml b/src/pages/Entry/locale/en.yml
index 59c2666a7a9..97a3be32b2a 100644
--- a/src/pages/Entry/locale/en.yml
+++ b/src/pages/Entry/locale/en.yml
@@ -1,9 +1,94 @@
-entryList:
+entry:
     list:
+        newEntry: New entry
+        tableVisibleColumns:
+            created: Creation
+            supplierFk: Supplier
+            isBooked: Booked
+            isConfirmed: Confirmed
+            isOrdered: Ordered
+            companyFk: Company
+            travelFk: Travel
+            isExcludedFromAvailable: Inventory
+            invoiceAmount: Import
         inventoryEntry: Inventory entry
-        showEntryReport: Show entry report
+    summary:
+        commission: Commission
+        currency: Currency
+        invoiceNumber: Invoice number
+        ordered: Ordered
+        booked: Booked
+        excludedFromAvailable: Inventory
+        travelReference: Reference
+        travelAgency: Agency
+        travelShipped: Shipped
+        travelDelivered: Delivered
+        travelLanded: Landed
+        travelReceived: Received
+        buys: Buys
+        stickers: Stickers
+        package: Package
+        packing: Pack.
+        grouping: Group.
+        buyingValue: Buying value
+        import: Import
+        pvp: PVP
+    basicData:
+        travel: Travel
+        currency: Currency
+        commission: Commission
+        observation: Observation
+        booked: Booked
+        excludedFromAvailable: Inventory
+        initialTemperature: Ini °C
+        finalTemperature: Fin °C
+    buys:
+        observations: Observations
+        packagingFk: Box
+        color: Color
+        printedStickers: Printed stickers
+    notes:
+        observationType: Observation type
+    latestBuys:
+        tableVisibleColumns:
+            image: Picture
+            itemFk: Item ID
+            weightByPiece: Weight/Piece
+            isActive: Active
+            family: Family
+            entryFk: Entry
+            freightValue: Freight value
+            comissionValue: Commission value
+            packageValue: Package value
+            isIgnored: Is ignored
+            price2: Grouping
+            price3: Packing
+            minPrice: Min
+            ektFk: Ekt
+            packingOut: Package out
+            landing: Landing
+            isExcludedFromAvailable: Es inventory
+    params:
+        toShipped: To
+        fromShipped: From
+        daysOnward: Days onward
+        daysAgo: Days ago
+        warehouseInFk: Warehouse in
+    search: Search entries
+    searchInfo: You can search by entry reference
 entryFilter:
-    filter:
+    params:
+        invoiceNumber: Invoice number
+        travelFk: Travel
+        companyFk: Company
+        currencyFk: Currency
+        supplierFk: Supplier
+        from: From
+        to: To
+        created: Created
+        isBooked: Booked
+        isConfirmed: Confirmed
+        isOrdered: Ordered
         search: General search
         reference: Reference
 myEntries:
@@ -19,5 +104,18 @@ myEntries:
     daysOnward: Days onward
     daysAgo: Days ago
     downloadCsv: Download CSV
+    search: Search entries
+    searchInfo: You can search by entry reference
+entryStockBought:
+    travel: Travel
+    editTravel: Edit travel
+    purchaseSpaces: Purchase spaces
+    buyer: Buyer
+    reserve: Reserve
+    bought: Bought
+    date: Date
+    viewMoreDetails: View more details
+    reserveSomeSpace: Reserve some space
+    thisBuyerHasReservationThisDate: This buyer has already made a reservation for this date
 wasteRecalc:
     recalcOk: The wastes were successfully recalculated
diff --git a/src/pages/Entry/locale/es.yml b/src/pages/Entry/locale/es.yml
index 4fb7bbf08b4..99391341733 100644
--- a/src/pages/Entry/locale/es.yml
+++ b/src/pages/Entry/locale/es.yml
@@ -1,12 +1,95 @@
-Search entries: Buscar entradas
-You can search by entry reference: Puedes buscar por referencia de la entrada
-
-entryList:
+entry:
     list:
+        newEntry: Nueva entrada
+        tableVisibleColumns:
+            created: Creación
+            supplierFk: Proveedor
+            isBooked: Asentado
+            isConfirmed: Confirmado
+            isOrdered: Pedida
+            companyFk: Empresa
+            travelFk: Envio
+            isExcludedFromAvailable: Inventario
+            invoiceAmount: Importe
         inventoryEntry: Es inventario
-        showEntryReport: Ver informe del pedido
+    summary:
+        commission: Comisión
+        currency: Moneda
+        invoiceNumber: Núm. factura
+        ordered: Pedida
+        booked: Contabilizada
+        excludedFromAvailable: Inventario
+        travelReference: Referencia
+        travelAgency: Agencia
+        travelShipped: F. envio
+        travelWarehouseOut: Alm. salida
+        travelDelivered: Enviada
+        travelLanded: F. entrega
+        travelReceived: Recibida
+        buys: Compras
+        stickers: Etiquetas
+        package: Embalaje
+        packing: Pack.
+        grouping: Group.
+        buyingValue: Coste
+        import: Importe
+        pvp: PVP
+    basicData:
+        travel: Envío
+        currency: Moneda
+        observation: Observación
+        commission: Comisión
+        booked: Asentado
+        excludedFromAvailable: Inventario
+        initialTemperature: Ini °C
+        finalTemperature: Fin °C
+    buys:
+        observations: Observaciónes
+        packagingFk: Embalaje
+        color: Color
+        printedStickers: Etiquetas impresas
+    notes:
+        observationType: Tipo de observación
+    latestBuys:
+        tableVisibleColumns:
+            image: Foto
+            itemFk: Id Artículo
+            weightByPiece: Peso (gramos)/tallo
+            isActive: Activo
+            family: Familia
+            entryFk: Entrada
+            freightValue: Porte
+            comissionValue: Comisión
+            packageValue: Embalaje
+            isIgnored: Ignorado
+            price2: Grouping
+            price3: Packing
+            minPrice: Min
+            ektFk: Ekt
+            packingOut: Embalaje envíos
+            landing: Llegada
+            isExcludedFromAvailable: Es inventario
+    params:
+        toShipped: Hasta
+        fromShipped: Desde
+        warehouseInFk: Alm. entrada
+        daysOnward: Días adelante
+        daysAgo: Días atras
+    search: Buscar entradas
+    searchInfo: Puedes buscar por referencia de entrada
 entryFilter:
-    filter:
+    params:
+        invoiceNumber: Núm. factura
+        travelFk: Envío
+        companyFk: Empresa
+        currencyFk: Moneda
+        supplierFk: Proveedor
+        from: Desde
+        to: Hasta
+        created: Fecha creación
+        isBooked: Asentado
+        isConfirmed: Confirmado
+        isOrdered: Pedida
         search: Búsqueda general
         reference: Referencia
 myEntries:
@@ -22,5 +105,18 @@ myEntries:
     daysOnward: Días adelante
     daysAgo: Días atras
     downloadCsv: Descargar CSV
+    search: Buscar entradas
+    searchInfo: Puedes buscar por referencia de la entrada
+entryStockBought:
+    travel: Envío
+    editTravel: Editar envío
+    purchaseSpaces: Espacios de compra
+    buyer: Comprador
+    reserve: Reservado
+    bought: Comprado
+    date: Fecha
+    viewMoreDetails: Ver más detalles
+    reserveSomeSpace: Reservar espacio
+    thisBuyerHasReservationThisDate: Este comprador ya ha hecho una reserva para esta fecha
 wasteRecalc:
     recalcOk: Se han recalculado las mermas correctamente
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
index 4d9e180eb4a..9fa3bcbcb24 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
@@ -6,24 +6,16 @@ import axios from 'axios';
 import { toCurrency, toDate } from 'src/filters';
 import VnLv from 'src/components/ui/VnLv.vue';
 import CardDescriptor from 'components/ui/CardDescriptor.vue';
-import FetchData from 'src/components/FetchData.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import { useCapitalize } from 'src/composables/useCapitalize';
 import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
 import InvoiceInDescriptorMenu from './InvoiceInDescriptorMenu.vue';
 
 const $props = defineProps({ id: { type: Number, default: null } });
-const { push, currentRoute } = useRouter();
+const { currentRoute } = useRouter();
 const { t } = useI18n();
 
 const cardDescriptorRef = ref();
-const correctionDialogRef = ref();
 const entityId = computed(() => $props.id || +currentRoute.value.params.id);
 const totalAmount = ref();
-const config = ref();
-const cplusRectificationTypes = ref([]);
-const siiTypeInvoiceIns = ref([]);
-const invoiceCorrectionTypes = ref([]);
 
 const filter = {
     include: [
@@ -85,12 +77,6 @@ const routes = reactive({
         return { name: 'EntryCard', params: { id } };
     },
 });
-const correctionFormData = reactive({
-    invoiceReason: 2,
-    invoiceType: 2,
-    invoiceClass: 6,
-});
-const isNotFilled = computed(() => Object.values(correctionFormData).includes(null));
 
 onBeforeMount(async () => {
     await setInvoiceCorrection(entityId.value);
@@ -122,38 +108,8 @@ async function setInvoiceCorrection(id) {
         (corrected) => corrected.correctingFk
     );
 }
-
-const createInvoiceInCorrection = async () => {
-    const { data: correctingId } = await axios.post(
-        'InvoiceIns/corrective',
-        Object.assign(correctionFormData, { id: entityId.value })
-    );
-    push({ path: `/invoice-in/${correctingId}/summary` });
-};
 </script>
 <template>
-    <FetchData
-        url="InvoiceInConfigs"
-        :where="{ fields: ['sageWithholdingFk'] }"
-        auto-load
-        @on-fetch="(data) => (config = data)"
-    />
-    <FetchData
-        url="CplusRectificationTypes"
-        @on-fetch="(data) => (cplusRectificationTypes = data)"
-        auto-load
-    />
-    <FetchData
-        url="SiiTypeInvoiceIns"
-        :where="{ code: { like: 'R%' } }"
-        @on-fetch="(data) => (siiTypeInvoiceIns = data)"
-        auto-load
-    />
-    <FetchData
-        url="InvoiceCorrectionTypes"
-        @on-fetch="(data) => (invoiceCorrectionTypes = data)"
-        auto-load
-    />
     <CardDescriptor
         ref="cardDescriptorRef"
         module="InvoiceIn"
@@ -167,7 +123,10 @@ const createInvoiceInCorrection = async () => {
         </template>
         <template #body="{ entity }">
             <VnLv :label="t('invoicein.list.issued')" :value="toDate(entity.issued)" />
-            <VnLv :label="t('invoicein.summary.bookedDate')" :value="toDate(entity.booked)" />
+            <VnLv
+                :label="t('invoicein.summary.bookedDate')"
+                :value="toDate(entity.booked)"
+            />
             <VnLv :label="t('invoicein.list.amount')" :value="toCurrency(totalAmount)" />
             <VnLv :label="t('invoicein.list.supplier')">
                 <template #value>
@@ -227,65 +186,6 @@ const createInvoiceInCorrection = async () => {
             </QCardActions>
         </template>
     </CardDescriptor>
-    <QDialog ref="correctionDialogRef">
-        <QCard>
-            <QCardSection>
-                <QItem class="q-px-none">
-                    <span class="text-primary text-h6 full-width">
-                        {{ t('Create rectificative invoice') }}
-                    </span>
-                    <QBtn icon="close" flat round dense v-close-popup />
-                </QItem>
-            </QCardSection>
-            <QCardSection>
-                <QItem>
-                    <QItemSection>
-                        <QInput
-                            :label="t('Original invoice')"
-                            v-model="entityId"
-                            readonly
-                        />
-                        <VnSelect
-                            :label="`${useCapitalize(t('globals.class'))}`"
-                            v-model="correctionFormData.invoiceClass"
-                            :options="siiTypeInvoiceIns"
-                            option-value="id"
-                            option-label="code"
-                            :required="true"
-                        />
-                    </QItemSection>
-                    <QItemSection>
-                        <VnSelect
-                            :label="`${useCapitalize(t('globals.type'))}`"
-                            v-model="correctionFormData.invoiceType"
-                            :options="cplusRectificationTypes"
-                            option-value="id"
-                            option-label="description"
-                            :required="true"
-                        />
-                        <VnSelect
-                            :label="`${useCapitalize(t('globals.reason'))}`"
-                            v-model="correctionFormData.invoiceReason"
-                            :options="invoiceCorrectionTypes"
-                            option-value="id"
-                            option-label="description"
-                            :required="true"
-                        />
-                    </QItemSection>
-                </QItem>
-            </QCardSection>
-            <QCardActions class="justify-end q-mr-sm">
-                <QBtn flat :label="t('globals.close')" color="primary" v-close-popup />
-                <QBtn
-                    :label="t('globals.save')"
-                    color="primary"
-                    v-close-popup
-                    @click="createInvoiceInCorrection"
-                    :disable="isNotFilled"
-                />
-            </QCardActions>
-        </QCard>
-    </QDialog>
 </template>
 <style lang="scss" scoped>
 .q-dialog {
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue
index 647b68f88ed..24bf427e931 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptorMenu.vue
@@ -8,9 +8,12 @@ import { useAcl } from 'src/composables/useAcl';
 import { downloadFile } from 'src/composables/downloadFile';
 import { useArrayData } from 'src/composables/useArrayData';
 import { usePrintService } from 'composables/usePrintService';
+import { useCapitalize } from 'src/composables/useCapitalize';
 import VnConfirm from 'src/components/ui/VnConfirm.vue';
 import SendEmailDialog from 'components/common/SendEmailDialog.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
 import InvoiceInToBook from '../InvoiceInToBook.vue';
+import FetchData from 'src/components/FetchData.vue';
 
 const { hasAny } = useAcl();
 const { t } = useI18n();
@@ -31,6 +34,10 @@ const correctionDialogRef = ref();
 const invoiceInCorrection = reactive({ correcting: [], corrected: null });
 const entityId = computed(() => $props.invoice.id || +currentRoute.value.params.id);
 const invoiceIn = computed(() => arrayData.store.data);
+const isNotFilled = computed(() => Object.values(correctionFormData).includes(null));
+const invoiceCorrectionTypes = ref([]);
+const cplusRectificationTypes = ref([]);
+const siiTypeInvoiceIns = ref([]);
 const actions = {
     unbook: {
         title: t('assertAction', { action: t('invoicein.descriptorMenu.unbook') }),
@@ -48,6 +55,11 @@ const actions = {
     sendPdf: { cb: sendPdfInvoiceConfirmation },
     correct: { cb: () => correctionDialogRef.value.show() },
 };
+const correctionFormData = reactive({
+    invoiceReason: 2,
+    invoiceType: 2,
+    invoiceClass: 8,
+});
 const canEditProp = (props) =>
     hasAny([{ model: 'InvoiceIn', props, accessType: 'WRITE' }]);
 
@@ -133,9 +145,39 @@ function sendPdfInvoice({ address }) {
             recipient: address,
         });
 }
+
+const createInvoiceInCorrection = async () => {
+    const { data: correctingId } = await axios.post(
+        'InvoiceIns/corrective',
+        Object.assign(correctionFormData, { id: entityId.value })
+    );
+    push({ path: `/invoice-in/${correctingId}/summary` });
+};
 </script>
 
 <template>
+    <FetchData
+        url="InvoiceCorrectionTypes"
+        @on-fetch="(data) => (invoiceCorrectionTypes = data)"
+        auto-load
+    />
+    <FetchData
+        url="CplusRectificationTypes"
+        @on-fetch="(data) => (cplusRectificationTypes = data)"
+        auto-load
+    />
+    <FetchData
+        url="SiiTypeInvoiceIns"
+        :where="{ code: { like: 'R%' } }"
+        @on-fetch="(data) => (siiTypeInvoiceIns = data)"
+        auto-load
+    />
+    <FetchData
+        url="InvoiceInConfigs"
+        :where="{ fields: ['sageWithholdingFk'] }"
+        auto-load
+        @on-fetch="(data) => (config = data)"
+    />
     <InvoiceInToBook>
         <template #content="{ book }">
             <QItem
@@ -162,7 +204,7 @@ function sendPdfInvoice({ address }) {
         v-if="canEditProp('deleteById')"
         v-ripple
         clickable
-        @click="triggerMenu('invoicein.descriptorMenu.delete')"
+        @click="triggerMenu('delete')"
     >
         <QItemSection>{{ t('invoicein.descriptorMenu.deleteInvoice') }}</QItemSection>
     </QItem>
@@ -192,6 +234,79 @@ function sendPdfInvoice({ address }) {
     <QItem v-if="invoice.dmsFk" v-ripple clickable @click="downloadFile(invoice.dmsFk)">
         <QItemSection>{{ t('components.smartCard.downloadFile') }}</QItemSection>
     </QItem>
+    <QDialog ref="correctionDialogRef">
+        <QCard>
+            <QCardSection>
+                <QItem class="q-px-none">
+                    <span class="text-primary text-h6 full-width">
+                        {{ t('Create rectificative invoice') }}
+                    </span>
+                    <QBtn icon="close" flat round dense v-close-popup />
+                </QItem>
+            </QCardSection>
+            <QCardSection>
+                <QItem>
+                    <QItemSection>
+                        <QInput
+                            :label="t('Original invoice')"
+                            v-model="entityId"
+                            readonly
+                        />
+                        <VnSelect
+                            :label="`${useCapitalize(t('globals.class'))}`"
+                            v-model="correctionFormData.invoiceClass"
+                            :options="siiTypeInvoiceIns"
+                            option-value="id"
+                            option-label="code"
+                            :required="true"
+                        />
+                    </QItemSection>
+                    <QItemSection>
+                        <VnSelect
+                            :label="`${useCapitalize(t('globals.type'))}`"
+                            v-model="correctionFormData.invoiceType"
+                            :options="cplusRectificationTypes"
+                            option-value="id"
+                            option-label="description"
+                            :required="true"
+                        >
+                            <template #option="{ itemProps, opt }">
+                                <QItem v-bind="itemProps">
+                                    {{ console.log('opt: ', opt) }}
+                                    <QItemSection>
+                                        <QItemLabel
+                                            >{{ opt.id }} -
+                                            {{ opt.description }}</QItemLabel
+                                        >
+                                    </QItemSection>
+                                </QItem>
+                                <div></div>
+                            </template>
+                        </VnSelect>
+
+                        <VnSelect
+                            :label="`${useCapitalize(t('globals.reason'))}`"
+                            v-model="correctionFormData.invoiceReason"
+                            :options="invoiceCorrectionTypes"
+                            option-value="id"
+                            option-label="description"
+                            :required="true"
+                        />
+                    </QItemSection>
+                </QItem>
+            </QCardSection>
+            <QCardActions class="justify-end q-mr-sm">
+                <QBtn flat :label="t('globals.close')" color="primary" v-close-popup />
+                <QBtn
+                    :label="t('globals.save')"
+                    color="primary"
+                    v-close-popup
+                    @click="createInvoiceInCorrection"
+                    :disable="isNotFilled"
+                />
+            </QCardActions>
+        </QCard>
+    </QDialog>
 </template>
 
 <i18n>
diff --git a/src/pages/InvoiceIn/Card/InvoiceInVat.vue b/src/pages/InvoiceIn/Card/InvoiceInVat.vue
index f7ef7d525be..f99e060b8f1 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInVat.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInVat.vue
@@ -25,6 +25,7 @@ const sageTaxTypes = ref([]);
 const sageTransactionTypes = ref([]);
 const rowsSelected = ref([]);
 const invoiceInFormRef = ref();
+const expenseRef = ref();
 
 defineProps({
     actionIcon: {
@@ -89,6 +90,11 @@ const columns = computed(() => [
         field: (row) => row.foreignValue,
         align: 'left',
     },
+    {
+        name: 'total',
+        label: 'Total',
+        align: 'left',
+    },
 ]);
 
 const filter = {
@@ -128,8 +134,26 @@ function autocompleteExpense(evt, row, col) {
         ({ id }) => id == useAccountShortToStandard(param)
     );
 
-    if (lookup) row[col.model] = lookup;
+    expenseRef.value.vnSelectDialogRef.vnSelectRef.toggleOption(lookup);
 }
+
+const taxableBaseTotal = computed(() => {   
+    return getTotal(invoiceInFormRef.value.formData, 'taxableBase', );
+});
+
+const taxRateTotal = computed(() => {
+    return getTotal(invoiceInFormRef.value.formData, null, {
+        cb: taxRate,
+    });
+});
+
+
+const combinedTotal = computed(() => {
+    return +taxableBaseTotal.value + +taxRateTotal.value;
+});
+
+
+
 </script>
 <template>
     <FetchData
@@ -167,6 +191,7 @@ function autocompleteExpense(evt, row, col) {
                 <template #body-cell-expense="{ row, col }">
                     <QTd>
                         <VnSelectDialog
+                            ref="expenseRef"
                             v-model="row[col.model]"
                             :options="col.options"
                             :option-value="col.optionValue"
@@ -270,26 +295,20 @@ function autocompleteExpense(evt, row, col) {
                         <QTd />
                         <QTd />
                         <QTd>
-                            {{ getTotal(rows, 'taxableBase', { currency: 'default' }) }}
+                            {{ toCurrency(taxableBaseTotal) }}
                         </QTd>
                         <QTd />
                         <QTd />
                         <QTd>
-                            {{
-                                getTotal(rows, null, { cb: taxRate, currency: 'default' })
-                            }}</QTd
-                        >
+                            {{ toCurrency(taxRateTotal) }}
+                        </QTd>
+                        <QTd />
                         <QTd>
-                            <template v-if="isNotEuro(invoiceIn.currency.code)">
-                                {{
-                                    getTotal(rows, 'foreignValue', {
-                                        currency: invoiceIn.currency.code,
-                                    })
-                                }}
-                            </template>
+                            {{ toCurrency(combinedTotal) }}
                         </QTd>
                     </QTr>
                 </template>
+
                 <template #item="props">
                     <div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
                         <QCard bordered flat class="q-my-xs">
diff --git a/src/pages/Item/Card/ItemDiary.vue b/src/pages/Item/Card/ItemDiary.vue
index 96a003a095b..c2f2c19a020 100644
--- a/src/pages/Item/Card/ItemDiary.vue
+++ b/src/pages/Item/Card/ItemDiary.vue
@@ -1,7 +1,7 @@
 <script setup>
-import { onMounted, computed, reactive, ref, nextTick, watch } from 'vue';
+import { onMounted, computed, ref, nextTick } from 'vue';
 import { useI18n } from 'vue-i18n';
-import { useRoute, useRouter } from 'vue-router';
+import { useRoute } from 'vue-router';
 
 import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
 import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue';
@@ -22,19 +22,16 @@ import VnSubToolbar from 'components/ui/VnSubToolbar.vue';
 
 const { t } = useI18n();
 const route = useRoute();
-const router = useRouter();
 const state = useState();
 const user = state.getUser();
-const today = ref(Date.vnNew());
+const today = Date.vnNew();
+today.setHours(0, 0, 0, 0);
 const warehousesOptions = ref([]);
-const itemBalancesRef = ref(null);
-const itemsBalanceFilter = reactive({
-    where: { itemFk: route.params.id, warehouseFk: null, date: null },
-});
-const itemBalances = ref([]);
-const warehouseFk = ref(null);
-const _showWhatsBeforeInventory = ref(false);
+const itemBalances = computed(() => arrayDataItemBalances.store.data);
+const where = computed(() => arrayDataItemBalances.store.filter.where || {});
+const showWhatsBeforeInventory = ref(false);
 const inventoriedDate = ref(null);
+let arrayDataItemBalances = useArrayData('ItemBalances');
 
 const originTypeMap = {
     entry: {
@@ -122,36 +119,28 @@ const columns = computed(() => [
     },
 ]);
 
-const showWhatsBeforeInventory = computed({
-    get: () => _showWhatsBeforeInventory.value,
-    set: (val) => {
-        _showWhatsBeforeInventory.value = val;
-        if (!val) itemsBalanceFilter.where.date = null;
-        else itemsBalanceFilter.where.date = inventoriedDate.value ?? new Date();
-    },
-});
-
 onMounted(async () => {
-    today.value.setHours(0, 0, 0, 0);
-    if (route.query.warehouseFk) warehouseFk.value = route.query.warehouseFk;
-    else if (user.value) warehouseFk.value = user.value.warehouseFk;
-    itemsBalanceFilter.where.warehouseFk = warehouseFk.value;
-    const { data } = await axios.get('Configs/findOne');
-    inventoriedDate.value = data.inventoried;
+    const ref = where.value;
+    const query = route.query;
+    inventoriedDate.value =
+        (await axios.get('Configs/findOne')).data?.inventoried || today;
+
+    if (query.warehouseFk) ref.warehouseFk = query.warehouseFk;
+    else if (!ref.warehouseFk && user.value) ref.warehouseFk = user.value.warehouseFk;
+    if (ref.date) showWhatsBeforeInventory.value = true;
+    ref.itemFk = route.params.id;
+
+    arrayDataItemBalances = useArrayData('ItemBalances', {
+        url: 'Items/getBalance',
+        filter: { where: ref },
+    });
+
     await fetchItemBalances();
     await scrollToToday();
-    await updateWarehouse(warehouseFk.value);
+    await updateWarehouse(ref.warehouseFk);
 });
 
-watch(
-    () => router.currentRoute.value.params.id,
-    (newId) => {
-        itemsBalanceFilter.where.itemFk = newId;
-        itemBalancesRef.value.fetch();
-    }
-);
-
-const fetchItemBalances = async () => await itemBalancesRef.value.fetch();
+const fetchItemBalances = async () => await arrayDataItemBalances.fetch({});
 
 const getBadgeAttrs = (_date) => {
     const isSameDate = date.isSameDate(today.value, _date);
@@ -178,23 +167,13 @@ const formatDateForAttribute = (dateValue) => {
 };
 
 async function updateWarehouse(warehouseFk) {
-    const stock = useArrayData('descriptorStock', {
-        userParams: {
-            warehouseFk,
-        },
-    });
+    const stock = useArrayData('descriptorStock', { userParams: { warehouseFk } });
     await stock.fetch({});
     stock.store.data.itemFk = route.params.id;
 }
 </script>
 
 <template>
-    <FetchData
-        ref="itemBalancesRef"
-        url="Items/getBalance"
-        :filter="itemsBalanceFilter"
-        @on-fetch="(data) => (itemBalances = data)"
-    />
     <FetchData
         url="Warehouses"
         :filter="{ fields: ['id', 'name'], order: 'name ASC' }"
@@ -207,27 +186,30 @@ async function updateWarehouse(warehouseFk) {
                 <VnSelect
                     :label="t('itemDiary.warehouse')"
                     :options="warehousesOptions"
-                    hide-selected
-                    option-label="name"
-                    option-value="id"
-                    dense
-                    v-model="itemsBalanceFilter.where.warehouseFk"
+                    v-model="where.warehouseFk"
                     @update:model-value="
-                        (value) => fetchItemBalances() && updateWarehouse(value)
+                        (val) => fetchItemBalances() && updateWarehouse(val)
                     "
                     class="q-mr-lg"
+                    :is-clearable="false"
                 />
                 <QCheckbox
                     :label="t('itemDiary.showBefore')"
                     v-model="showWhatsBeforeInventory"
-                    @update:model-value="fetchItemBalances"
+                    @update:model-value="
+                        async (val) => {
+                            if (!val) where.date = null;
+                            else where.date = inventoriedDate;
+                            await fetchItemBalances();
+                        }
+                    "
                     class="q-mr-lg"
                 />
                 <VnInputDate
                     v-if="showWhatsBeforeInventory"
                     :label="t('itemDiary.since')"
                     dense
-                    v-model="itemsBalanceFilter.where.date"
+                    v-model="where.date"
                     @update:model-value="fetchItemBalances"
                 />
             </div>
diff --git a/src/pages/Item/Card/ItemLastEntries.vue b/src/pages/Item/Card/ItemLastEntries.vue
index c2df553c3ec..7d8890c2bfb 100644
--- a/src/pages/Item/Card/ItemLastEntries.vue
+++ b/src/pages/Item/Card/ItemLastEntries.vue
@@ -36,18 +36,7 @@ const exprBuilder = (param, value) => {
     }
 };
 
-const where = {
-    itemFk: route.params.id,
-};
-
-const arrayData = useArrayData('ItemLastEntries', {
-    url: 'Items/lastEntriesFilter',
-    order: ['landed DESC', 'buyFk DESC'],
-    exprBuilder: exprBuilder,
-    userFilter: {
-        where: where,
-    },
-});
+let arrayData = useArrayData('ItemLastEntries');
 const itemLastEntries = ref([]);
 
 const columns = computed(() => [
@@ -161,25 +150,51 @@ const getDate = (date, type) => {
 };
 
 const updateFilter = async () => {
-    let filter;
-    if (!from.value && to.value) filter = { lte: to.value };
-    else if (from.value && !to.value) filter = { gte: from.value };
-    else if (from.value && to.value) filter = { between: [from.value, to.value] };
-
-    const userFilter = arrayData.store.userFilter.where;
-
-    userFilter.landed = filter;
+    let landed;
+    if (!from.value && to.value) landed = { lte: to.value };
+    else if (from.value && !to.value) landed = { gte: from.value };
+    else if (from.value && to.value) landed = { between: [from.value, to.value] };
 
+    arrayData.store.filter.where.landed = landed;
     await fetchItemLastEntries();
 };
 
 onMounted(async () => {
-    const _from = Date.vnNew();
-    _from.setDate(_from.getDate() - 75);
-    from.value = getDate(_from, 'from');
-    const _to = Date.vnNew();
-    _to.setDate(_to.getDate() + 10);
-    to.value = getDate(_to, 'to');
+    const landed = arrayData.store.filter.where?.landed;
+    arrayData = useArrayData('ItemLastEntries', {
+        url: 'Items/lastEntriesFilter',
+        order: ['landed DESC', 'buyFk DESC'],
+        exprBuilder: exprBuilder,
+        filter: {
+            where: {
+                itemFk: route.params.id,
+                landed,
+            },
+        },
+    });
+
+    if (landed) {
+        const key = Object.keys(landed)[0];
+        switch (key) {
+            case 'gte':
+                from.value = landed.gte;
+                break;
+            case 'lte':
+                to.value = landed.lte;
+                break;
+            case 'between':
+                from.value = landed.between[0];
+                to.value = landed.between[1];
+                break;
+        }
+    } else {
+        const _from = Date.vnNew();
+        _from.setDate(_from.getDate() - 75);
+        from.value = getDate(_from, 'from');
+        const _to = Date.vnNew();
+        _to.setDate(_to.getDate() + 10);
+        to.value = getDate(_to, 'to');
+    }
 
     updateFilter();
 
diff --git a/src/pages/Item/ItemList.vue b/src/pages/Item/ItemList.vue
index f04563791d5..00d0f5c4e2e 100644
--- a/src/pages/Item/ItemList.vue
+++ b/src/pages/Item/ItemList.vue
@@ -391,7 +391,7 @@ onBeforeMount(async () => {
                     {{ row?.subName.toUpperCase() }}
                 </div>
             </div>
-            <FetchedTags :item="row" :columns="3" />
+            <FetchedTags :item="row" />
         </template>
         <template #more-create-dialog="{ data }">
             <VnInput
diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml
index 907c72acd89..52722198b10 100644
--- a/src/pages/Item/locale/en.yml
+++ b/src/pages/Item/locale/en.yml
@@ -58,6 +58,7 @@ lastEntries:
     pvp: PVP
     label: Label
     grouping: Grouping
+    packing: Packing
     quantity: Quantity
     cost: Cost
     kg: Kg.
diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml
index 015dea4dd63..29af8dc5c30 100644
--- a/src/pages/Item/locale/es.yml
+++ b/src/pages/Item/locale/es.yml
@@ -58,6 +58,7 @@ lastEntries:
     pvp: PVP
     label: Eti.
     grouping: Grouping
+    packing: Packing
     quantity: Cantidad
     cost: Coste
     kg: Kg.
diff --git a/src/pages/Order/Card/OrderCard.vue b/src/pages/Order/Card/OrderCard.vue
index 67c0f1de510..823815f59b9 100644
--- a/src/pages/Order/Card/OrderCard.vue
+++ b/src/pages/Order/Card/OrderCard.vue
@@ -1,38 +1,12 @@
 <script setup>
-import { computed } from 'vue';
-import { useRoute } from 'vue-router';
-import VnCard from 'components/common/VnCard.vue';
+import VnCardBeta from 'components/common/VnCardBeta.vue';
 import OrderDescriptor from 'pages/Order/Card/OrderDescriptor.vue';
-import OrderFilter from './OrderFilter.vue';
-import OrderSearchbar from './OrderSearchbar.vue';
-import OrderCatalogFilter from './OrderCatalogFilter.vue';
-const config = {
-    OrderCatalog: OrderCatalogFilter,
-};
-const route = useRoute();
-
-const routeName = computed(() => route.name);
-const customRouteRedirectName = computed(() => {
-    const route = config[routeName.value];
-    if (route) return null;
-    return 'OrderList';
-});
-const customFilterPanel = computed(() => {
-    const filterPanel = config[routeName.value] ?? OrderFilter;
-    return filterPanel;
-});
 </script>
 
 <template>
-    <VnCard
+    <VnCardBeta
         data-key="Order"
         base-url="Orders"
         :descriptor="OrderDescriptor"
-        :filter-panel="customFilterPanel"
-        :search-data-key="customRouteRedirectName"
-    >
-        <template #searchbar>
-            <OrderSearchbar />
-        </template>
-    </VnCard>
+    />
 </template>
diff --git a/src/pages/Order/Card/OrderCatalog.vue b/src/pages/Order/Card/OrderCatalog.vue
index da2e88aa990..186f216fb1b 100644
--- a/src/pages/Order/Card/OrderCatalog.vue
+++ b/src/pages/Order/Card/OrderCatalog.vue
@@ -15,15 +15,18 @@ const router = useRouter();
 const stateStore = useStateStore();
 const { t } = useI18n();
 const dataKey = 'OrderCatalogList';
-const arrayData = useArrayData(dataKey);
-const store = arrayData.store;
-const tags = ref([]);
-const itemRefs = ref({});
-
-let catalogParams = {
+const catalogParams = {
     orderFk: route.params.id,
     orderBy: JSON.stringify({ field: 'relevancy DESC, name', way: 'ASC', isTag: false }),
 };
+const arrayData = useArrayData(dataKey, {
+    url: 'Orders/CatalogFilter',
+    limit: 50,
+    userParams: catalogParams,
+});
+const store = arrayData.store;
+const tags = ref([]);
+const itemRefs = ref({});
 
 onMounted(() => {
     stateStore.rightDrawer = true;
@@ -66,7 +69,6 @@ function extractValueTags(items) {
     );
     tagValue.value = resultValueTags;
 }
-const autoLoad = computed(() => !!JSON.parse(route?.query.table ?? '{}')?.categoryFk);
 
 watch(
     () => store.data,
@@ -78,16 +80,15 @@ watch(
 </script>
 
 <template>
-    <VnSearchbar
-        :data-key="dataKey"
-        :user-params="catalogParams"
-        :static-params="['orderFk', 'orderBy']"
-        :redirect="false"
-        url="Orders/CatalogFilter"
-        :label="t('Search items')"
-        :info="t('You can search items by name or id')"
-        :search-remove-params="false"
-    />
+    <Teleport to="#section-searchbar" v-if="stateStore.isHeaderMounted()">
+        <VnSearchbar
+            :data-key="dataKey"
+            :redirect="false"
+            :label="t('Search items')"
+            :info="t('You can search items by name or id')"
+            :search-remove-params="false"
+        />
+    </Teleport>
     <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()">
         <OrderCatalogFilter
             :data-key="dataKey"
@@ -98,13 +99,7 @@ watch(
     </Teleport>
     <QPage class="column items-center q-pa-md" data-cy="orderCatalogPage">
         <div class="full-width">
-            <VnPaginate
-                :data-key="dataKey"
-                url="Orders/CatalogFilter"
-                :limit="50"
-                :user-params="catalogParams"
-                :auto-load="autoLoad"
-            >
+            <VnPaginate :data-key="dataKey">
                 <template #body="{ rows }">
                     <div class="catalog-list">
                         <div v-if="rows && !rows?.length" class="no-result">
diff --git a/src/pages/Order/Card/OrderLines.vue b/src/pages/Order/Card/OrderLines.vue
index 6093addb5eb..36dc3883e77 100644
--- a/src/pages/Order/Card/OrderLines.vue
+++ b/src/pages/Order/Card/OrderLines.vue
@@ -208,15 +208,28 @@ async function remove(item) {
 async function handleConfirm() {
     const result = await confirm(route.params.id);
     if (result) {
+        const sale = await axios.get(`OrderRows`, {
+            params: {
+                filter: JSON.stringify({
+                    where: { orderFk: route.params.id },
+                }),
+            },
+        });
+        const ticket = await axios.get(`Sales`, {
+            params: {
+                filter: JSON.stringify({
+                    where: { id: sale.data[0].saleFk },
+                }),
+            },
+        });
         quasar.notify({
             message: t('globals.dataSaved'),
             type: 'positive',
         });
         router.push({
             name: 'TicketSale',
-            query: {
-                table: JSON.stringify({ id: route.params.id }),
-            },
+            params: { id: ticket.data[0].ticketFk },
+            query: { table: JSON.stringify({ filter: { limit: 20, skip: 0 } }) },
         });
     }
 }
diff --git a/src/pages/Order/Card/OrderSearchbar.vue b/src/pages/Order/Card/OrderSearchbar.vue
deleted file mode 100644
index fa30a097fd2..00000000000
--- a/src/pages/Order/Card/OrderSearchbar.vue
+++ /dev/null
@@ -1,22 +0,0 @@
-<script setup>
-import { useI18n } from 'vue-i18n';
-import VnSearchbar from 'components/ui/VnSearchbar.vue';
-
-const { t } = useI18n();
-</script>
-
-<template>
-    <VnSearchbar
-        data-key="OrderList"
-        url="Orders/filter"
-        :label="t('Search order')"
-        :info="t('Search orders by ticket id')"
-    />
-</template>
-
-<style scoped lang="scss"></style>
-<i18n>
-es:
-    Search order: Buscar orden
-    Search orders by ticket id: Buscar pedido por id ticket
-</i18n>
diff --git a/src/pages/Order/OrderList.vue b/src/pages/Order/OrderList.vue
index baa20354152..ae1fe68bd47 100644
--- a/src/pages/Order/OrderList.vue
+++ b/src/pages/Order/OrderList.vue
@@ -8,15 +8,14 @@ import { useRoute } from 'vue-router';
 
 import axios from 'axios';
 import OrderSummary from 'pages/Order/Card/OrderSummary.vue';
-import OrderSearchbar from './Card/OrderSearchbar.vue';
 import OrderFilter from './Card/OrderFilter.vue';
-import RightMenu from 'src/components/common/RightMenu.vue';
 import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
 import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
 
 import VnTable from 'src/components/VnTable/VnTable.vue';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
+import VnSection from 'src/components/common/VnSection.vue';
 
 const { t } = useI18n();
 const { viewSummary } = useSummaryDialog();
@@ -24,6 +23,8 @@ const tableRef = ref();
 const agencyList = ref([]);
 const route = useRoute();
 const addressOptions = ref([]);
+const dataKey = 'OrderList';
+
 const columns = computed(() => [
     {
         align: 'left',
@@ -178,117 +179,126 @@ const getDateColor = (date) => {
     if (difference < 0) return 'bg-success';
 };
 </script>
+
 <template>
-    <OrderSearchbar />
-    <RightMenu>
-        <template #right-panel>
+    <VnSection
+        :data-key="dataKey"
+        :columns="columns"
+        prefix="order"
+        :array-data-props="{
+            url: 'Orders/filter',
+            order: ['landed DESC', 'clientFk ASC', 'id DESC'],
+        }"
+    >
+        <template #rightMenu>
             <OrderFilter data-key="OrderList" />
         </template>
-    </RightMenu>
-    <VnTable
-        ref="tableRef"
-        data-key="OrderList"
-        url="Orders/filter"
-        :order="['landed DESC', 'clientFk ASC', 'id DESC']"
-        :create="{
-            urlCreate: 'Orders/new',
-            title: t('module.cerateOrder'),
-            onDataSaved: (url) => {
-                tableRef.redirect(`${url}/catalog`);
-            },
-            formInitialData: {
-                active: true,
-                addressId: null,
-                clientFk: null,
-            },
-        }"
-        :user-params="{ showEmpty: false }"
-        :columns="columns"
-        :right-search="false"
-        redirect="order"
-    >
-        <template #column-clientFk="{ row }">
-            <span class="link" @click.stop>
-                {{ row?.clientName }}
-                <CustomerDescriptorProxy :id="row?.clientFk" />
-            </span>
-        </template>
-        <template #column-salesPersonFk="{ row }">
-            <span class="link" @click.stop>
-                {{ row?.name }}
-                <WorkerDescriptorProxy :id="row?.salesPersonFk" />
-            </span>
-        </template>
-        <template #column-landed="{ row }">
-            <span v-if="getDateColor(row.landed)">
-                <QChip :class="getDateColor(row.landed)" dense square>
-                    {{ toDate(row?.landed) }}
-                </QChip>
-            </span>
-        </template>
-        <template #more-create-dialog="{ data }">
-            <VnSelect
-                url="Clients"
-                :include="{ relation: 'addresses' }"
-                v-model="data.clientFk"
-                :label="t('module.customer')"
-                @update:model-value="(id) => fetchClientAddress(id, data)"
+        <template #body>
+            <VnTable
+                ref="tableRef"
+                :data-key="dataKey"
+                :create="{
+                    urlCreate: 'Orders/new',
+                    title: t('module.cerateOrder'),
+                    onDataSaved: (url) => {
+                        tableRef.redirect(`${url}/catalog`);
+                    },
+                    formInitialData: {
+                        active: true,
+                        addressId: null,
+                        clientFk: null,
+                    },
+                }"
+                :user-params="{ showEmpty: false }"
+                :columns="columns"
+                :right-search="false"
+                redirect="order"
             >
-                <template #option="scope">
-                    <QItem v-bind="scope.itemProps">
-                        <QItemSection>
-                            <QItemLabel>
-                                {{ scope.opt.name }}
-                            </QItemLabel>
-                            <QItemLabel caption>
-                                {{ `#${scope.opt.id}` }}
-                            </QItemLabel>
-                        </QItemSection>
-                    </QItem>
+                <template #column-clientFk="{ row }">
+                    <span class="link" @click.stop>
+                        {{ row?.clientName }}
+                        <CustomerDescriptorProxy :id="row?.clientFk" />
+                    </span>
                 </template>
-            </VnSelect>
-            <VnSelect
-                v-model="data.addressId"
-                :options="addressOptions"
-                :label="t('module.address')"
-                option-value="id"
-                option-label="nickname"
-                @update:model-value="() => fetchAgencies(data)"
-            >
-                <template #option="scope">
-                    <QItem v-bind="scope.itemProps">
-                        <QItemSection>
-                            <QItemLabel
-                                :class="{
-                                    'color-vn-label': !scope.opt?.isActive,
-                                }"
-                            >
-                                {{
-                                    `${
-                                        !scope.opt?.isActive
-                                            ? t('basicData.inactive')
-                                            : ''
-                                    } `
-                                }}
-                                {{ scope.opt?.nickname }}: {{ scope.opt?.street }},
-                                {{ scope.opt?.city }}
-                            </QItemLabel>
-                        </QItemSection>
-                    </QItem>
+                <template #column-salesPersonFk="{ row }">
+                    <span class="link" @click.stop>
+                        {{ row?.name }}
+                        <WorkerDescriptorProxy :id="row?.salesPersonFk" />
+                    </span>
                 </template>
-            </VnSelect>
-            <VnInputDate
-                v-model="data.landed"
-                :label="t('module.landed')"
-                @update:model-value="() => fetchAgencies(data)"
-            />
-            <VnSelect
-                v-model="data.agencyModeId"
-                :label="t('module.agency')"
-                :options="agencyList"
-                option-value="agencyModeFk"
-                option-label="agencyMode"
-            />
+                <template #column-landed="{ row }">
+                    <span v-if="getDateColor(row.landed)">
+                        <QChip :class="getDateColor(row.landed)" dense square>
+                            {{ toDate(row?.landed) }}
+                        </QChip>
+                    </span>
+                </template>
+                <template #more-create-dialog="{ data }">
+                    <VnSelect
+                        url="Clients"
+                        :include="{ relation: 'addresses' }"
+                        v-model="data.clientFk"
+                        :label="t('module.customer')"
+                        @update:model-value="(id) => fetchClientAddress(id, data)"
+                    >
+                        <template #option="scope">
+                            <QItem v-bind="scope.itemProps">
+                                <QItemSection>
+                                    <QItemLabel>
+                                        {{ scope.opt.name }}
+                                    </QItemLabel>
+                                    <QItemLabel caption>
+                                        {{ `#${scope.opt.id}` }}
+                                    </QItemLabel>
+                                </QItemSection>
+                            </QItem>
+                        </template>
+                    </VnSelect>
+                    <VnSelect
+                        v-model="data.addressId"
+                        :options="addressOptions"
+                        :label="t('module.address')"
+                        option-value="id"
+                        option-label="nickname"
+                        @update:model-value="() => fetchAgencies(data)"
+                    >
+                        <template #option="scope">
+                            <QItem v-bind="scope.itemProps">
+                                <QItemSection>
+                                    <QItemLabel
+                                        :class="{
+                                            'color-vn-label': !scope.opt?.isActive,
+                                        }"
+                                    >
+                                        {{
+                                            `${
+                                                !scope.opt?.isActive
+                                                    ? t('basicData.inactive')
+                                                    : ''
+                                            } `
+                                        }}
+                                        {{ scope.opt?.nickname }}:
+                                        {{ scope.opt?.street }},
+                                        {{ scope.opt?.city }}
+                                    </QItemLabel>
+                                </QItemSection>
+                            </QItem>
+                        </template>
+                    </VnSelect>
+                    <VnInputDate
+                        v-model="data.landed"
+                        :label="t('module.landed')"
+                        @update:model-value="() => fetchAgencies(data)"
+                    />
+                    <VnSelect
+                        v-model="data.agencyModeId"
+                        :label="t('module.agency')"
+                        :options="agencyList"
+                        option-value="agencyModeFk"
+                        option-label="agencyMode"
+                    />
+                </template>
+            </VnTable>
         </template>
-    </VnTable>
+    </VnSection>
 </template>
diff --git a/src/pages/Order/locale/en.yml b/src/pages/Order/locale/en.yml
index 4349bc76f58..14e41c55983 100644
--- a/src/pages/Order/locale/en.yml
+++ b/src/pages/Order/locale/en.yml
@@ -21,3 +21,26 @@ lines:
     image: Image
 params:
     tagGroups: Tags
+order:
+    field:
+        salesPersonFk: Sales Person
+    form:
+        clientFk: Client
+        addressFk: Address
+        agencyModeFk: Agency
+    list:
+        newOrder: New Order
+    summary:
+        basket: Basket
+        notConfirmed: Not confirmed
+        created: Created
+        createdFrom: Created From
+        address: Address
+        total: Total
+        items: Items
+        orderTicketList: Order Ticket List
+        amount: Amount
+        confirm: Confirm
+        confirmLines: Confirm lines
+    search: Search orders
+    searchInfo: You can search orders by ticket id
diff --git a/src/pages/Order/locale/es.yml b/src/pages/Order/locale/es.yml
index cef06cb6d97..44e243ad117 100644
--- a/src/pages/Order/locale/es.yml
+++ b/src/pages/Order/locale/es.yml
@@ -21,3 +21,29 @@ lines:
     image: Imagen
 params:
     tagGroups: Tags
+order:
+    field:
+        salesPersonFk: Comercial
+    form:
+        clientFk: Cliente
+        addressFk: Dirección
+        agencyModeFk: Agencia
+    list:
+        newOrder: Nuevo Pedido
+    summary:
+        basket: Cesta
+        notConfirmed: No confirmada
+        created: Creado
+        createdFrom: Creado desde
+        address: Dirección
+        total: Total
+        vat: IVA
+        state: Estado
+        alias: Alias
+        items: Artículos
+        orderTicketList: Tickets del pedido
+        amount: Monto
+        confirm: Confirmar
+        confirmLines: Confirmar lineas
+    search: Buscar pedido
+    searchInfo: Buscar pedidos por el número de ticket
diff --git a/src/pages/Supplier/Card/SupplierFiscalData.vue b/src/pages/Supplier/Card/SupplierFiscalData.vue
index 44235717f86..1d9f3ab94d1 100644
--- a/src/pages/Supplier/Card/SupplierFiscalData.vue
+++ b/src/pages/Supplier/Card/SupplierFiscalData.vue
@@ -68,6 +68,8 @@ function handleLocation(data, location) {
                 'supplierActivityFk',
                 'healthRegister',
                 'street',
+                'isVies',
+                'isTrucker',
             ],
             include: [
                 {
@@ -92,6 +94,7 @@ function handleLocation(data, location) {
                 <VnInput
                     v-model="data.name"
                     :label="t('supplier.fiscalData.name')"
+                    uppercase="true"
                     clearable
                 />
                 <VnInput
diff --git a/src/pages/Supplier/SupplierList.vue b/src/pages/Supplier/SupplierList.vue
index c0748af871e..85cc11857c4 100644
--- a/src/pages/Supplier/SupplierList.vue
+++ b/src/pages/Supplier/SupplierList.vue
@@ -5,6 +5,7 @@ import VnTable from 'components/VnTable/VnTable.vue';
 import VnSearchbar from 'components/ui/VnSearchbar.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
 import SupplierListFilter from './SupplierListFilter.vue';
+import VnInput from 'src/components/common/VnInput.vue';
 
 const { t } = useI18n();
 const tableRef = ref();
@@ -23,9 +24,14 @@ const columns = computed(() => [
         align: 'left',
         label: t('globals.name'),
         name: 'socialName',
-        create: true,
+        attrs: {
+            uppercase: true,
+        },
         columnFilter: {
             name: 'search',
+            attrs: {
+                uppercase: false,
+            },
         },
         isTitle: true,
     },
@@ -118,14 +124,18 @@ const columns = computed(() => [
             formInitialData: {},
             mapper: (data) => {
                 data.name = data.socialName;
-                delete data.socialName;
+
                 return data;
             },
         }"
         :right-search="false"
         order="id ASC"
         :columns="columns"
-    />
+    >
+        <template #more-create-dialog="{ data }">
+            <VnInput :label="t('globals.name')" v-model="data.socialName" :uppercase="true" />
+            </template>
+    </VnTable>
 </template>
 
 <i18n>
diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index 8aa785c74bf..b849b3b35d6 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -54,7 +54,6 @@ const transfer = ref({
 });
 const tableRef = ref([]);
 const canProceed = ref();
-const isLoading = ref(false);
 
 watch(
     () => route.params.id,
@@ -197,6 +196,7 @@ const changeQuantity = async (sale) => {
     try {
         if (!rowToUpdate.value) return;
         rowToUpdate.value = null;
+        sale.isNew = false;
         await updateQuantity(sale);
     } catch (e) {
         const { quantity } = tableRef.value.CrudModelRef.originalData.find(
@@ -214,9 +214,6 @@ const updateQuantity = async ({ quantity, id }) => {
 };
 
 const addSale = async (sale) => {
-    if (isLoading.value) return;
-
-    isLoading.value = true;
     const params = {
         barcode: sale.itemFk,
         quantity: sale.quantity,
@@ -237,6 +234,7 @@ const addSale = async (sale) => {
     sale.item = newSale.item;
 
     notify('globals.dataSaved', 'positive');
+    sale.isNew = false;
     arrayData.fetch({});
 };
 
@@ -754,6 +752,7 @@ watch(
                 option-label="name"
                 option-value="id"
                 v-model="row.itemFk"
+                :use-like="false"
                 @update:model-value="updateItem(row)"
             >
                 <template #option="scope">
diff --git a/src/pages/Ticket/Card/TicketService.vue b/src/pages/Ticket/Card/TicketService.vue
index 950e6e8bec4..d045eadee87 100644
--- a/src/pages/Ticket/Card/TicketService.vue
+++ b/src/pages/Ticket/Card/TicketService.vue
@@ -166,8 +166,10 @@ async function handleSave() {
                             v-model="row.ticketServiceTypeFk"
                             :options="ticketServiceOptions"
                             option-label="name"
+                            :roles-allowed-to-create="['administrative']"
                             option-value="id"
                             hide-selected
+                            sort-by="name ASC"
                         >
                             <template #form>
                                 <TicketCreateServiceType
diff --git a/src/pages/Ticket/TicketFilter.vue b/src/pages/Ticket/TicketFilter.vue
index 7dcb834d27c..4b50892b097 100644
--- a/src/pages/Ticket/TicketFilter.vue
+++ b/src/pages/Ticket/TicketFilter.vue
@@ -7,6 +7,7 @@ import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
 import VnInput from 'src/components/common/VnInput.vue';
 import VnInputDate from 'components/common/VnInputDate.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
 
 const { t } = useI18n();
 const props = defineProps({
@@ -81,15 +82,12 @@ const getGroupedStates = (data) => {
             </QItem>
             <QItem>
                 <QItemSection>
-                    <VnSelect
-                        :label="t('Salesperson')"
+                    <VnSelectWorker
+                        :label="t('globals.salesPerson')"
                         v-model="params.salesPersonFk"
-                        url="Workers/activeWithInheritedRole"
-                        :where="{ role: 'salesPerson' }"
-                        option-value="id"
-                        option-label="firstName"
-                        :use-like="false"
-                        sort-by="firstName ASC"
+                        :params="{
+                            departmentCodes: ['VT'],
+                        }"
                         dense
                         outlined
                         rounded
diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue
index 9deb2280858..689711a74cd 100644
--- a/src/pages/Travel/Card/TravelSummary.vue
+++ b/src/pages/Travel/Card/TravelSummary.vue
@@ -9,7 +9,7 @@ import VnTitle from 'src/components/common/VnTitle.vue';
 import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue';
 import FetchData from 'src/components/FetchData.vue';
 import VnRow from 'components/ui/VnRow.vue';
-import { toDate, toCurrency } from 'src/filters';
+import { toDate, toCurrency, toCelsius } from 'src/filters';
 import axios from 'axios';
 import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
 
@@ -97,6 +97,20 @@ const entriesTableColumns = computed(() => {
             showValue: true,
         },
         { label: 'm³', field: 'm3', name: 'm3', align: 'left', showValue: true },
+        {
+            label: t('entry.basicData.initialTemperature'),
+            field: 'initialTemperature',
+            name: 'initialTemperature',
+            align: 'left',
+            format: (val) => toCelsius(val),
+        },
+        {
+            label: t('entry.basicData.finalTemperature'),
+            field: 'finalTemperature',
+            name: 'finalTemperature',
+            align: 'left',
+            format: (val) => toCelsius(val),
+        },
         {
             label: '',
             field: 'observation',
@@ -127,14 +141,14 @@ const thermographsTableColumns = computed(() => {
             field: 'maxTemperature',
             name: 'maxTemperature',
             align: 'left',
-            format: (val) => (val ? `${val}°` : ''),
+            format: (val) => toCelsius(val),
         },
         {
             label: t('globals.minTemperature'),
             field: 'minTemperature',
             name: 'minTemperature',
             align: 'left',
-            format: (val) => (val ? `${val}°` : ''),
+            format: (val) => toCelsius(val),
         },
         {
             label: t('globals.state'),
diff --git a/src/pages/Travel/Card/TravelThermographs.vue b/src/pages/Travel/Card/TravelThermographs.vue
index 2bf3293a638..85781a6a4af 100644
--- a/src/pages/Travel/Card/TravelThermographs.vue
+++ b/src/pages/Travel/Card/TravelThermographs.vue
@@ -10,7 +10,7 @@ import FetchData from 'src/components/FetchData.vue';
 
 import axios from 'axios';
 import useNotify from 'src/composables/useNotify.js';
-import { toDate } from 'src/filters';
+import { toDate, toCelsius } from 'src/filters';
 import { downloadFile } from 'src/composables/downloadFile';
 
 const route = useRoute();
@@ -52,14 +52,14 @@ const TableColumns = computed(() => {
             field: 'maxTemperature',
             name: 'maxTemperature',
             align: 'left',
-            format: (val) => (val ? `${val}°` : ''),
+            format: (val) => toCelsius(val),
         },
         {
             label: t('globals.minTemperature'),
             field: 'minTemperature',
             name: 'minTemperature',
             align: 'left',
-            format: (val) => (val ? `${val}°` : ''),
+            format: (val) => toCelsius(val),
         },
         {
             label: t('globals.state'),
diff --git a/src/pages/Travel/TravelList.vue b/src/pages/Travel/TravelList.vue
index 67fdb32547c..c976678e0eb 100644
--- a/src/pages/Travel/TravelList.vue
+++ b/src/pages/Travel/TravelList.vue
@@ -79,6 +79,13 @@ const columns = computed(() => [
         cardVisible: true,
         create: true,
     },
+    {
+        align: 'left',
+        name: 'awb',
+        label: t('travel.travelList.tableVisibleColumns.awb'),
+        columnFilter: false,
+        format: (row) => row.awbCode,
+    },
     {
         align: 'left',
         name: 'warehouseInFk',
diff --git a/src/pages/Worker/Card/WorkerPda.vue b/src/pages/Worker/Card/WorkerPda.vue
index 3ceee2493e3..c1beef40dc9 100644
--- a/src/pages/Worker/Card/WorkerPda.vue
+++ b/src/pages/Worker/Card/WorkerPda.vue
@@ -27,7 +27,7 @@ const initialData = computed(() => {
     return {
         userFk: routeId.value,
         deviceProductionFk: null,
-        simSerialNumber: null,
+        simFk: null,
     };
 });
 
@@ -42,7 +42,7 @@ const deallocatePDA = async (deviceProductionFk) => {
 
 function reloadData() {
     initialData.value.deviceProductionFk = null;
-    initialData.value.simSerialNumber = null;
+    initialData.value.simFk = null;
     paginate.value.fetch();
 }
 </script>
@@ -89,7 +89,7 @@ function reloadData() {
                         />
                         <VnInput
                             :label="t('Current SIM')"
-                            :model-value="row?.simSerialNumber"
+                            :model-value="row?.simFk"
                             disable
                         />
                         <QBtn
@@ -150,7 +150,7 @@ function reloadData() {
                                     </template>
                                 </VnSelect>
                                 <VnInput
-                                    v-model="data.simSerialNumber"
+                                    v-model="data.simFk"
                                     :label="t('SIM serial number')"
                                     id="simSerialNumber"
                                     use-input
diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue
index 65fbf4b4370..919331e2dcc 100644
--- a/src/pages/Worker/Card/WorkerTimeControl.vue
+++ b/src/pages/Worker/Card/WorkerTimeControl.vue
@@ -283,21 +283,22 @@ const fetchWeekData = async () => {
         year: selectedDateYear.value,
         week: selectedWeekNumber.value,
     };
-    const mail = (
-        await axiosNoError.get(`Workers/${route.params.id}/mail`, {
-            params: { filter: { where } },
-        })
-    ).data[0];
+    try {
+        const [{ data: mailData }, { data: countData }] = await Promise.all([
+            axiosNoError.get(`Workers/${route.params.id}/mail`, {
+                params: { filter: { where } },
+            }),
+            axiosNoError.get('WorkerTimeControlMails/count', { params: { where } }),
+        ]);
 
-    if (!mail) state.value = null;
-    else {
-        state.value = mail.state;
-        reason.value = mail.reason;
+        const mail = mailData[0];
+
+        state.value = mail?.state;
+        reason.value = mail?.reason;
+        canResend.value = !!countData.count;
+    } catch {
+        state.value = null;
     }
-
-    canResend.value = !!(
-        await axiosNoError.get('WorkerTimeControlMails/count', { params: { where } })
-    ).data.count;
 };
 
 const setHours = (data) => {
diff --git a/src/pages/Worker/WorkerList.vue b/src/pages/Worker/WorkerList.vue
index 48393a8c797..0b784b993f5 100644
--- a/src/pages/Worker/WorkerList.vue
+++ b/src/pages/Worker/WorkerList.vue
@@ -138,7 +138,11 @@ function uppercaseStreetModel(data) {
     return {
         get: () => (data.street ? data.street.toUpperCase() : ''),
         set: (value) => {
-            data.street = value.toUpperCase();
+            if (value) {
+                data.street = value.toUpperCase();
+            } else {
+                data.street = null;
+            }
         },
     };
 }
diff --git a/src/router/modules/entry.js b/src/router/modules/entry.js
index 26ce773c5d1..f362c76533c 100644
--- a/src/router/modules/entry.js
+++ b/src/router/modules/entry.js
@@ -1,50 +1,123 @@
 import { RouterView } from 'vue-router';
 
+const entryCard = {
+    name: 'EntryCard',
+    path: ':id',
+    component: () => import('src/pages/Entry/Card/EntryCard.vue'),
+    redirect: { name: 'EntrySummary' },
+    meta: {
+        menu: [
+            'EntryBasicData',
+            'EntryBuys',
+            'EntryNotes',
+            'EntryDms',
+            'EntryLog',
+        ],
+    },
+    children: [
+        {
+            path: 'summary',
+            name: 'EntrySummary',
+            meta: {
+                title: 'summary',
+                icon: 'launch',
+            },
+            component: () => import('src/pages/Entry/Card/EntrySummary.vue'),
+        },
+        {
+            path: 'basic-data',
+            name: 'EntryBasicData',
+            meta: {
+                title: 'basicData',
+                icon: 'vn:settings',
+            },
+            component: () => import('src/pages/Entry/Card/EntryBasicData.vue'),
+        },
+        {
+            path: 'buys',
+            name: 'EntryBuys',
+            meta: {
+                title: 'buys',
+                icon: 'vn:lines',
+            },
+            component: () => import('src/pages/Entry/Card/EntryBuys.vue'),
+        },
+        {
+            path: 'buys/import',
+            name: 'EntryBuysImport',
+            component: () => import('src/pages/Entry/Card/EntryBuysImport.vue'),
+        },
+        {
+            path: 'notes',
+            name: 'EntryNotes',
+            meta: {
+                title: 'notes',
+                icon: 'vn:notes',
+            },
+            component: () => import('src/pages/Entry/Card/EntryNotes.vue'),
+        },
+        {
+            path: 'dms',
+            name: 'EntryDms',
+            meta: {
+                title: 'dms',
+                icon: 'smb_share',
+            },
+            component: () => import('src/pages/Entry/Card/EntryDms.vue'),
+        },
+        {
+            path: 'log',
+            name: 'EntryLog',
+            meta: {
+                title: 'log',
+                icon: 'vn:History',
+            },
+            component: () => import('src/pages/Entry/Card/EntryLog.vue'),
+        },
+    ],
+};
+
 export default {
-    path: '/entry',
     name: 'Entry',
+    path: '/entry',
     meta: {
         title: 'entries',
         icon: 'vn:entry',
         moduleName: 'Entry',
         keyBinding: 'e',
-    },
-    component: RouterView,
-    redirect: { name: 'EntryMain' },
-    menus: {
-        main: [
+        menu: [
             'EntryList',
             'MyEntries',
             'EntryLatestBuys',
             'EntryStockBought',
             'EntryWasteRecalc',
-        ],
-        card: ['EntryBasicData', 'EntryBuys', 'EntryNotes', 'EntryDms', 'EntryLog'],
+        ]
     },
+    component: RouterView,
+    redirect: { name: 'EntryMain' },
     children: [
         {
-            path: '',
             name: 'EntryMain',
+            path: '',
             component: () => import('src/components/common/VnModule.vue'),
-            redirect: { name: 'EntryList' },
+            redirect: { name: 'EntryIndexMain' },
             children: [
                 {
-                    path: 'list',
-                    name: 'EntryList',
-                    meta: {
-                        title: 'list',
-                        icon: 'view_list',
-                    },
+                    path:'',
+                    name: 'EntryIndexMain',
+                    redirect: { name: 'EntryList' },
                     component: () => import('src/pages/Entry/EntryList.vue'),
-                },
-                {
-                    path: 'my',
-                    name: 'MyEntries',
-                    meta: {
-                        title: 'labeler',
-                        icon: 'sell',
-                    },
-                    component: () => import('src/pages/Entry/MyEntries.vue'),
+                    children: [
+                        {
+                            name: 'EntryList',
+                            path: 'list',
+                            meta: {
+                                title: 'list',
+                                icon: 'view_list',
+                            },
+                        },
+                        entryCard,
+                    ],
                 },
                 {
                     path: 'create',
@@ -54,6 +127,15 @@ export default {
                         icon: 'add',
                     },
                     component: () => import('src/pages/Entry/EntryCreate.vue'),
+                },                
+                {
+                    path: 'my',
+                    name: 'MyEntries',
+                    meta: {
+                        title: 'labeler',
+                        icon: 'sell',
+                    },
+                    component: () => import('src/pages/Entry/MyEntries.vue'),
                 },
                 {
                     path: 'latest-buys',
@@ -84,72 +166,5 @@ export default {
                 },
             ],
         },
-        {
-            name: 'EntryCard',
-            path: ':id',
-            component: () => import('src/pages/Entry/Card/EntryCard.vue'),
-            redirect: { name: 'EntrySummary' },
-            children: [
-                {
-                    name: 'EntrySummary',
-                    path: 'summary',
-                    meta: {
-                        title: 'summary',
-                        icon: 'launch',
-                    },
-                    component: () => import('src/pages/Entry/Card/EntrySummary.vue'),
-                },
-                {
-                    path: 'basic-data',
-                    name: 'EntryBasicData',
-                    meta: {
-                        title: 'basicData',
-                        icon: 'vn:settings',
-                    },
-                    component: () => import('src/pages/Entry/Card/EntryBasicData.vue'),
-                },
-                {
-                    path: 'buys',
-                    name: 'EntryBuys',
-                    meta: {
-                        title: 'buys',
-                        icon: 'vn:lines',
-                    },
-                    component: () => import('src/pages/Entry/Card/EntryBuys.vue'),
-                },
-                {
-                    path: 'buys/import',
-                    name: 'EntryBuysImport',
-                    component: () => import('src/pages/Entry/Card/EntryBuysImport.vue'),
-                },
-                {
-                    path: 'notes',
-                    name: 'EntryNotes',
-                    meta: {
-                        title: 'notes',
-                        icon: 'vn:notes',
-                    },
-                    component: () => import('src/pages/Entry/Card/EntryNotes.vue'),
-                },
-                {
-                    path: 'dms',
-                    name: 'EntryDms',
-                    meta: {
-                        title: 'dms',
-                        icon: 'smb_share',
-                    },
-                    component: () => import('src/pages/Entry/Card/EntryDms.vue'),
-                },
-                {
-                    path: 'log',
-                    name: 'EntryLog',
-                    meta: {
-                        title: 'log',
-                        icon: 'vn:History',
-                    },
-                    component: () => import('src/pages/Entry/Card/EntryLog.vue'),
-                },
-            ],
-        },
     ],
-};
+};
\ No newline at end of file
diff --git a/src/router/modules/order.js b/src/router/modules/order.js
index 77af812cf79..bdd080e7fee 100644
--- a/src/router/modules/order.js
+++ b/src/router/modules/order.js
@@ -1,35 +1,102 @@
 import { RouterView } from 'vue-router';
 
+const orderCard = {
+    name: 'OrderCard',
+    path: ':id',
+    component: () => import('src/pages/Order/Card/OrderCard.vue'),
+    redirect: { name: 'OrderSummary' },
+    meta: {
+        menu: [
+            'OrderBasicData',
+            'OrderCatalog',
+            'OrderVolume',
+            'OrderLines',
+        ],
+    },
+    children: [
+        {
+            path: 'summary',
+            name: 'OrderSummary',
+            meta: {
+                title: 'summary',
+                icon: 'launch',
+            },
+            component: () => import('src/pages/Order/Card/OrderSummary.vue'),
+        },
+        {
+            path: 'basic-data',
+            name: 'OrderBasicData',
+            meta: {
+                title: 'basicData',
+                icon: 'vn:settings',
+            },
+            component: () => import('src/pages/Order/Card/OrderBasicData.vue'),
+        },
+        {
+            path: 'catalog',
+            name: 'OrderCatalog',
+            meta: {
+                title: 'catalog',
+                icon: 'vn:basket',
+            },
+            component: () => import('src/pages/Order/Card/OrderCatalog.vue'),
+        },
+        {
+            path: 'volume',
+            name: 'OrderVolume',
+            meta: {
+                title: 'volume',
+                icon: 'vn:volume',
+            },
+            component: () => import('src/pages/Order/Card/OrderVolume.vue'),
+        },
+        {
+            path: 'line',
+            name: 'OrderLines',
+            meta: {
+                title: 'lines',
+                icon: 'vn:lines',
+            },
+            component: () => import('src/pages/Order/Card/OrderLines.vue'),
+        },
+    ],
+};
+
 export default {
-    path: '/order',
     name: 'Order',
+    path: '/order',
     meta: {
         title: 'order',
         icon: 'vn:basket',
         moduleName: 'Order',
         keyBinding: 'o',
+        menu: ['OrderList'],
     },
     component: RouterView,
     redirect: { name: 'OrderMain' },
-    menus: {
-        main: ['OrderList'],
-        card: ['OrderBasicData', 'OrderCatalog', 'OrderVolume', 'OrderLines'],
-    },
     children: [
         {
-            path: '',
             name: 'OrderMain',
+            path: '',
             component: () => import('src/components/common/VnModule.vue'),
-            redirect: { name: 'OrderList' },
+            redirect: { name: 'OrderIndexMain' },
             children: [
                 {
-                    path: 'list',
-                    name: 'OrderList',
-                    meta: {
-                        title: 'orderList',
-                        icon: 'view_list',
-                    },
+                    path: '',
+                    name: 'OrderIndexMain',            
+                    redirect: { name: 'OrderList' },
                     component: () => import('src/pages/Order/OrderList.vue'),
+                    children: [
+                        {
+                            name: 'OrderList',
+                            path: 'list',
+                            meta: {
+                                title: 'orderList',
+                                icon: 'view_list',
+                            },
+                        },
+                        orderCard,
+                    ],
                 },
                 {
                     path: 'create',
@@ -42,58 +109,5 @@ export default {
                 },
             ],
         },
-        {
-            name: 'OrderCard',
-            path: ':id',
-            component: () => import('src/pages/Order/Card/OrderCard.vue'),
-            redirect: { name: 'OrderSummary' },
-            children: [
-                {
-                    name: 'OrderSummary',
-                    path: 'summary',
-                    meta: {
-                        title: 'summary',
-                        icon: 'launch',
-                    },
-                    component: () => import('src/pages/Order/Card/OrderSummary.vue'),
-                },
-                {
-                    name: 'OrderBasicData',
-                    path: 'basic-data',
-                    meta: {
-                        title: 'basicData',
-                        icon: 'vn:settings',
-                    },
-                    component: () => import('src/pages/Order/Card/OrderBasicData.vue'),
-                },
-                {
-                    name: 'OrderCatalog',
-                    path: 'catalog',
-                    meta: {
-                        title: 'catalog',
-                        icon: 'vn:basket',
-                    },
-                    component: () => import('src/pages/Order/Card/OrderCatalog.vue'),
-                },
-                {
-                    name: 'OrderVolume',
-                    path: 'volume',
-                    meta: {
-                        title: 'volume',
-                        icon: 'vn:volume',
-                    },
-                    component: () => import('src/pages/Order/Card/OrderVolume.vue'),
-                },
-                {
-                    name: 'OrderLines',
-                    path: 'line',
-                    meta: {
-                        title: 'lines',
-                        icon: 'vn:lines',
-                    },
-                    component: () => import('src/pages/Order/Card/OrderLines.vue'),
-                },
-            ],
-        },
     ],
-};
+};
\ No newline at end of file
diff --git a/src/stores/invoiceOutGlobal.js b/src/stores/invoiceOutGlobal.js
index d8649753f3a..d8e061f845f 100644
--- a/src/stores/invoiceOutGlobal.js
+++ b/src/stores/invoiceOutGlobal.js
@@ -7,7 +7,14 @@ import useNotify from 'src/composables/useNotify.js';
 import axios from 'axios';
 
 const { notify } = useNotify();
-
+const initInvoicing = {
+    invoicing: false,
+    nRequests: 0,
+    nPdfs: 0,
+    totalPdfs: 0,
+    addressIndex: 0,
+    errors: [],
+};
 export const useInvoiceOutGlobalStore = defineStore({
     id: 'invoiceOutGlobal',
     state: () => ({
@@ -23,16 +30,11 @@ export const useInvoiceOutGlobalStore = defineStore({
         addresses: [],
         minInvoicingDate: null,
         parallelism: null,
-        invoicing: false,
-        isInvoicing: false,
         status: null,
-        addressIndex: 0,
-        errors: [],
+
         printer: null,
-        nRequests: 0,
-        nPdfs: 0,
-        totalPdfs: 0,
         formData: null,
+        ...initInvoicing,
     }),
     actions: {
         async init() {
@@ -117,12 +119,13 @@ export const useInvoiceOutGlobalStore = defineStore({
                     );
                     throw new Error("There aren't addresses to invoice");
                 }
-                this.invoicing = false;
-                this.status = 'invoicing';
                 this.formData = formData;
-                this.addressIndex = 0;
-                this.errors = [];
-                await this.invoiceClient();
+                this.status = 'invoicing';
+                //reset data
+                for (const key in initInvoicing) {
+                    this[key] = initInvoicing[key];
+                }
+                this.invoiceClient();
             } catch (err) {
                 this.handleError(err);
             }
@@ -184,7 +187,6 @@ export const useInvoiceOutGlobalStore = defineStore({
         async invoiceClient() {
             if (this.invoicing || this.nRequests >= this.parallelism) return;
             const address = this.addresses[this.addressIndex];
-
             if (!address || !this.status || this.status == 'stopping') {
                 this.status = 'stopping';
                 this.invoicing = false;
@@ -192,6 +194,7 @@ export const useInvoiceOutGlobalStore = defineStore({
             }
             try {
                 this.invoicing = true;
+                this.nRequests++;
                 const params = {
                     clientId: address.clientId,
                     addressId: address.id,
@@ -215,6 +218,7 @@ export const useInvoiceOutGlobalStore = defineStore({
                 }
             } finally {
                 this.invoicing = false;
+                this.nRequests--;
                 this.addressIndex++;
                 this.invoiceClient();
             }
diff --git a/src/utils/quasarLang.js b/src/utils/quasarLang.js
new file mode 100644
index 00000000000..ebd590c0501
--- /dev/null
+++ b/src/utils/quasarLang.js
@@ -0,0 +1,12 @@
+const langList = import.meta.glob('../../node_modules/quasar/lang/*.js');
+import { Quasar } from 'quasar';
+
+export default function (value) {
+    try {
+        langList[`../../node_modules/quasar/lang/${value}.js`]().then((lang) => {
+            Quasar.lang.set(lang.default);
+        });
+    } catch (error) {
+        //
+    }
+}
diff --git a/test/cypress/integration/claim/claimPhoto.spec.js b/test/cypress/integration/claim/claimPhoto.spec.js
index 9b2978b190f..0a732006063 100755
--- a/test/cypress/integration/claim/claimPhoto.spec.js
+++ b/test/cypress/integration/claim/claimPhoto.spec.js
@@ -1,5 +1,6 @@
 /// <reference types="cypress" />
-describe('ClaimPhoto', () => {
+// redmine.verdnatura.es/issues/8417
+describe.skip('ClaimPhoto', () => {
     beforeEach(() => {
         const claimId = 1;
         cy.login('developer');
diff --git a/test/cypress/integration/entry/myEntry.spec.js b/test/cypress/integration/entry/myEntry.spec.js
index 4addec1c455..c254764192d 100644
--- a/test/cypress/integration/entry/myEntry.spec.js
+++ b/test/cypress/integration/entry/myEntry.spec.js
@@ -8,8 +8,8 @@ describe('EntryMy when is supplier', () => {
             },
         });
     });
-
-    it('should open buyLabel when is supplier', () => {
+    // https://redmine.verdnatura.es/issues/8418
+    it.skip('should open buyLabel when is supplier', () => {
         cy.get(
             '[to="/null/3"] > .q-card > .column > .q-btn > .q-btn__content > .q-icon'
         ).click();
diff --git a/test/cypress/integration/invoiceIn/invoiceInCorrective.spec.js b/test/cypress/integration/invoiceIn/invoiceInCorrective.spec.js
index 0eb8733551e..c2f11189207 100644
--- a/test/cypress/integration/invoiceIn/invoiceInCorrective.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInCorrective.spec.js
@@ -1,6 +1,6 @@
 /// <reference types="cypress" />
-
-describe('InvoiceInCorrective', () => {
+// https://redmine.verdnatura.es/issues/8419
+describe.skip('InvoiceInCorrective', () => {
     const createCorrective = '.q-menu > .q-list > :nth-child(6) > .q-item__section';
     const rectificativeSection = '.q-drawer-container .q-list > a:nth-child(6)';
     const saveDialog = '.q-card > .q-card__actions > .q-btn--standard ';
diff --git a/test/cypress/integration/invoiceIn/invoiceInList.spec.js b/test/cypress/integration/invoiceIn/invoiceInList.spec.js
index d9ab3f7e790..0eb495419e4 100644
--- a/test/cypress/integration/invoiceIn/invoiceInList.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInList.spec.js
@@ -21,8 +21,8 @@ describe('InvoiceInList', () => {
                 cy.url().should('include', `/invoice-in/${id}/summary`);
             });
     });
-
-    it('should open the details', () => {
+    // https://redmine.verdnatura.es/issues/8420
+    it.skip('should open the details', () => {
         cy.get(firstDetailBtn).click();
         cy.get(summaryHeaders).eq(1).contains('Basic data');
         cy.get(summaryHeaders).eq(4).contains('Vat');
diff --git a/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js b/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js
index b7fd113074d..44b0a996180 100644
--- a/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js
+++ b/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js
@@ -9,7 +9,6 @@ describe('InvoiceOut summary', () => {
         cy.viewport(1920, 1080);
         cy.login('developer');
         cy.visit(`/#/invoice-out/list`);
-        cy.typeSearchbar('{enter}');
     });
 
     it('should generate the invoice PDF', () => {
@@ -19,13 +18,12 @@ describe('InvoiceOut summary', () => {
         cy.dataCy('VnConfirm_confirm').click();
         cy.checkNotification('The invoice PDF document has been regenerated');
     });
-
     it('should refund the invoice ', () => {
         cy.typeSearchbar('T1111111{enter}');
         cy.dataCy('descriptor-more-opts').click();
         cy.get('.q-menu > .q-list > :nth-child(7)').click();
         cy.get('#q-portal--menu--3 > .q-menu > .q-list > :nth-child(2)').click();
-        cy.checkNotification('The following refund ticket have been created 1000000');
+        cy.checkNotification('The following refund ticket have been created');
     });
 
     it('should delete an invoice ', () => {
@@ -35,7 +33,6 @@ describe('InvoiceOut summary', () => {
         cy.dataCy('VnConfirm_confirm').click();
         cy.checkNotification('InvoiceOut deleted');
     });
-
     it('should transfer the invoice ', () => {
         cy.typeSearchbar('T1111111{enter}');
         cy.dataCy('descriptor-more-opts').click();
diff --git a/test/cypress/integration/item/itemList.spec.js b/test/cypress/integration/item/itemList.spec.js
index 49e3934513b..97e85a2120c 100644
--- a/test/cypress/integration/item/itemList.spec.js
+++ b/test/cypress/integration/item/itemList.spec.js
@@ -15,8 +15,8 @@ describe('Item list', () => {
         cy.get('.q-menu .q-item').contains('Anthurium').click();
         cy.get('.q-virtual-scroll__content > :nth-child(4) > :nth-child(4)').click();
     });
-
-    it('should create an item', () => {
+    // https://redmine.verdnatura.es/issues/8421
+    it.skip('should create an item', () => {
         const data = {
             Description: { val: `Test item` },
             Type: { val: `Crisantemo`, type: 'select' },
diff --git a/test/cypress/integration/item/itemTag.spec.js b/test/cypress/integration/item/itemTag.spec.js
index c2de93068cf..28e0a747fcc 100644
--- a/test/cypress/integration/item/itemTag.spec.js
+++ b/test/cypress/integration/item/itemTag.spec.js
@@ -18,8 +18,8 @@ describe('Item tag', () => {
         +cy.dataCy('crudModelDefaultSaveBtn').click();
         cy.checkNotification("The tag or priority can't be repeated for an item");
     });
-
-    it('should add a new tag', () => {
+    // https://redmine.verdnatura.es/issues/8422
+    it.skip('should add a new tag', () => {
         cy.get('.q-page').should('be.visible');
         cy.get('.q-page-sticky > div').click();
         cy.get('.q-page-sticky > div').click();
diff --git a/test/cypress/integration/ticket/ticketExpedition.spec.js b/test/cypress/integration/ticket/ticketExpedition.spec.js
index d74a122a1dc..d957f2136ec 100644
--- a/test/cypress/integration/ticket/ticketExpedition.spec.js
+++ b/test/cypress/integration/ticket/ticketExpedition.spec.js
@@ -1,6 +1,6 @@
 /// <reference types="cypress" />
-
-describe('Ticket expedtion', () => {
+// https://redmine.verdnatura.es/issues/8423
+describe.skip('Ticket expedtion', () => {
     const tableContent = '.q-table .q-virtual-scroll__content';
     const stateTd = 'td:nth-child(9)';
 
diff --git a/test/cypress/integration/ticket/ticketList.spec.js b/test/cypress/integration/ticket/ticketList.spec.js
index e273825c0c4..3337287c4b3 100644
--- a/test/cypress/integration/ticket/ticketList.spec.js
+++ b/test/cypress/integration/ticket/ticketList.spec.js
@@ -30,8 +30,8 @@ describe('TicketList', () => {
         cy.get(firstRow).find('.q-btn:first').click();
         cy.get('@windowOpen').should('be.calledWithMatch', /\/ticket\/\d+\/sale/);
     });
-
-    it('should open ticket summary', () => {
+    // https://redmine.verdnatura.es/issues/8424
+    it.skip('should open ticket summary', () => {
         searchResults();
         cy.get(firstRow).find('.q-btn:last').click();
         cy.dataCy('ticketSummary').should('exist');
diff --git a/test/cypress/integration/ticket/ticketSale.spec.js b/test/cypress/integration/ticket/ticketSale.spec.js
index 7bc53f01085..aed8dc85ac2 100644
--- a/test/cypress/integration/ticket/ticketSale.spec.js
+++ b/test/cypress/integration/ticket/ticketSale.spec.js
@@ -1,7 +1,5 @@
 /// <reference types="cypress" />
 
-const c = require('croppie');
-
 describe('TicketSale', () => {
     beforeEach(() => {
         cy.login('developer');
diff --git a/test/cypress/integration/vnComponent/VnLocation.spec.js b/test/cypress/integration/vnComponent/VnLocation.spec.js
index 14eb0f978a7..751b3a06590 100644
--- a/test/cypress/integration/vnComponent/VnLocation.spec.js
+++ b/test/cypress/integration/vnComponent/VnLocation.spec.js
@@ -49,7 +49,8 @@ describe('VnLocation', () => {
         beforeEach(() => {
             cy.viewport(1280, 720);
             cy.login('developer');
-            cy.visit('/#/worker/create', { timeout: 5000 });
+            cy.visit('/#/worker/list', { timeout: 5000 });
+            cy.dataCy('vnTableCreateBtn').click();
             cy.waitForElement('.q-card');
             cy.get(inputLocation).click();
         });
diff --git a/test/cypress/integration/worker/workerList.spec.js b/test/cypress/integration/worker/workerList.spec.js
index c1c37fd320a..0a45441c141 100644
--- a/test/cypress/integration/worker/workerList.spec.js
+++ b/test/cypress/integration/worker/workerList.spec.js
@@ -10,8 +10,8 @@ describe('WorkerList', () => {
 
     it('should open the worker summary', () => {
         cy.get(inputName).type('jessica{enter}');
-        cy.get(searchBtn).click();
         cy.intercept('GET', /\/api\/Workers\/summary+/).as('worker');
+        cy.get(searchBtn).click();
         cy.wait('@worker').then(() =>
             cy.get(descriptorTitle).should('include.text', 'Jessica')
         );
diff --git a/test/cypress/integration/zone/zoneWarehouse.spec.js b/test/cypress/integration/zone/zoneWarehouse.spec.js
index 817e26312d5..a55a5619e6a 100644
--- a/test/cypress/integration/zone/zoneWarehouse.spec.js
+++ b/test/cypress/integration/zone/zoneWarehouse.spec.js
@@ -18,8 +18,8 @@ describe('ZoneWarehouse', () => {
         cy.get(saveBtn).click();
         cy.checkNotification(dataError);
     });
-
-    it('should create & remove a warehouse', () => {
+    // https://redmine.verdnatura.es/issues/8425
+    it.skip('should create & remove a warehouse', () => {
         cy.addBtnClick();
         cy.fillInForm(data);
         cy.get(saveBtn).click();