diff --git a/cypress.config.js b/cypress.config.js index e2046d6c4..f8e771093 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -11,12 +11,22 @@ module.exports = defineConfig({ video: false, specPattern: 'test/cypress/integration/**/*.spec.js', experimentalRunAllSpecs: true, + watchForFileChanges: true, + reporter: 'cypress-mochawesome-reporter', + reporterOptions: { + charts: true, + reportPageTitle: 'Cypress Inline Reporter', + embeddedScreenshots: true, + reportDir: 'test/cypress/reports', + inlineAssets: true, + }, component: { componentFolder: 'src', testFiles: '**/*.spec.js', supportFile: 'test/cypress/support/unit.js', }, setupNodeEvents(on, config) { + require('cypress-mochawesome-reporter/plugin')(on); // implement node event listeners here }, }, diff --git a/package.json b/package.json index eaaa0b812..e2e75f253 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,17 @@ { "name": "salix-front", - "version": "24.42.0", + "version": "24.44.0", "description": "Salix frontend", "productName": "Salix", "author": "Verdnatura", "private": true, "packageManager": "pnpm@8.15.1", "scripts": { + "resetDatabase": "cd ../salix && gulp docker", "lint": "eslint --ext .js,.vue ./", "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore", "test:e2e": "cypress open", - "test:e2e:ci": "cd ../salix && gulp docker && cd ../salix-front && cypress run", + "test:e2e:ci": "npm run resetDatabase && cd ../salix-front && cypress run", "test": "echo \"See package.json => scripts for available tests.\" && exit 0", "test:unit": "vitest", "test:unit:ci": "vitest run", @@ -42,6 +43,7 @@ "@vue/test-utils": "^2.4.4", "autoprefixer": "^10.4.14", "cypress": "^13.6.6", + "cypress-mochawesome-reporter": "^3.8.2", "eslint": "^8.41.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-cypress": "^2.13.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e336c39bb..83dfa0469 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -70,6 +70,9 @@ devDependencies: cypress: specifier: ^13.6.6 version: 13.6.6 + cypress-mochawesome-reporter: + specifier: ^3.8.2 + version: 3.8.2(cypress@13.6.6)(mocha@10.7.3) eslint: specifier: ^8.41.0 version: 8.56.0 @@ -829,8 +832,8 @@ packages: vue-i18n: optional: true dependencies: - '@intlify/message-compiler': 10.0.0-beta.5 - '@intlify/shared': 10.0.0-beta.5 + '@intlify/message-compiler': 10.0.0 + '@intlify/shared': 10.0.0 jsonc-eslint-parser: 1.4.1 source-map: 0.6.1 vue-i18n: 9.9.1(vue@3.4.19) @@ -844,11 +847,11 @@ packages: '@intlify/message-compiler': 9.9.1 '@intlify/shared': 9.9.1 - /@intlify/message-compiler@10.0.0-beta.5: - resolution: {integrity: sha512-hLLchnM1dmtSEruerkzvU9vePsLqBXz3RU85SCx/Vd12fFQiymP+/5Rn9MJ8MyfLmIOLDEx4PRh+/GkIQP6oog==} + /@intlify/message-compiler@10.0.0: + resolution: {integrity: sha512-OcaWc63NC/9p1cMdgoNKBj4d61BH8sUW1Hfs6YijTd9656ZR4rNqXAlRnBrfS5ABq0vjQjpa8VnyvH9hK49yBw==} engines: {node: '>= 16'} dependencies: - '@intlify/shared': 10.0.0-beta.5 + '@intlify/shared': 10.0.0 source-map-js: 1.0.2 dev: true @@ -859,8 +862,8 @@ packages: '@intlify/shared': 9.9.1 source-map-js: 1.0.2 - /@intlify/shared@10.0.0-beta.5: - resolution: {integrity: sha512-g9bq5Y1bOcC9qxtNk4UWtF3sXm6Wh0fGISb7vD5aLyF7yQv7ZFjxQjJzBP2GqG/9+PAGYutqjP1GGadNqFtyAQ==} + /@intlify/shared@10.0.0: + resolution: {integrity: sha512-6ngLfI7DOTew2dcF9WMJx+NnMWghMBhIiHbGg+wRvngpzD5KZJZiJVuzMsUQE1a5YebEmtpTEfUrDp/NqVGdiw==} engines: {node: '>= 16'} dev: true @@ -884,7 +887,7 @@ packages: optional: true dependencies: '@intlify/bundle-utils': 4.0.0(vue-i18n@9.9.1) - '@intlify/shared': 10.0.0-beta.5 + '@intlify/shared': 10.0.0 '@rollup/pluginutils': 4.2.1 '@vue/compiler-sfc': 3.4.19 debug: 4.3.4(supports-color@8.1.1) @@ -1999,6 +2002,10 @@ packages: dependencies: fill-range: 7.0.1 + /browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + dev: true + /browserslist@4.23.0: resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -2106,6 +2113,16 @@ packages: upper-case: 1.1.3 dev: true + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + /camelcase@7.0.1: resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} engines: {node: '>=14.16'} @@ -2255,6 +2272,22 @@ packages: engines: {node: '>= 10'} dev: true + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + + /cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -2558,6 +2591,23 @@ packages: /csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + /cypress-mochawesome-reporter@3.8.2(cypress@13.6.6)(mocha@10.7.3): + resolution: {integrity: sha512-oJZkNzhNmN9ZD+LmZyFuPb8aWaIijyHyqYh52YOBvR6B6ckfJNCHP3A98a+/nG0H4t46CKTNwo+wNpMa4d2kjA==} + engines: {node: '>=14'} + hasBin: true + peerDependencies: + cypress: '>=6.2.0' + dependencies: + commander: 10.0.1 + cypress: 13.6.6 + fs-extra: 10.1.0 + mochawesome: 7.1.3(mocha@10.7.3) + mochawesome-merge: 4.3.0 + mochawesome-report-generator: 6.2.0 + transitivePeerDependencies: + - mocha + dev: true + /cypress@13.6.6: resolution: {integrity: sha512-S+2S9S94611hXimH9a3EAYt81QM913ZVA03pUmGDfLTFa5gyp85NJ8dJGSlEAEmyRsYkioS1TtnWtbv/Fzt11A==} engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} @@ -2627,6 +2677,10 @@ packages: time-zone: 1.0.0 dev: true + /dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + dev: true + /dayjs@1.11.10: resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} dev: true @@ -2676,6 +2730,29 @@ packages: ms: 2.1.2 supports-color: 8.1.1 + /debug@4.3.7(supports-color@8.1.1): + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + supports-color: 8.1.1 + dev: true + + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + dev: true + /decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} @@ -2758,6 +2835,11 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + /diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} + engines: {node: '>=0.3.1'} + dev: true + /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -3550,6 +3632,14 @@ packages: transitivePeerDependencies: - supports-color + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -3646,6 +3736,15 @@ packages: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} dev: true + /fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: true + /fs-extra@11.2.0: resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} @@ -3654,6 +3753,15 @@ packages: jsonfile: 6.1.0 universalify: 2.0.1 + /fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + /fs-extra@9.1.0: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} @@ -3675,6 +3783,10 @@ packages: dev: true optional: true + /fsu@1.1.1: + resolution: {integrity: sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A==} + dev: true + /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -3775,6 +3887,18 @@ packages: once: 1.4.0 path-is-absolute: 1.0.1 + /glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + dev: true + /global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} engines: {node: '>=18'} @@ -4189,6 +4313,11 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + /is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + dev: true + /is-plain-obj@3.0.0: resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} engines: {node: '>=10'} @@ -4361,6 +4490,12 @@ packages: resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} dev: true + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + /jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} dependencies: @@ -4452,6 +4587,13 @@ packages: engines: {node: '>=14'} dev: true + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -4486,10 +4628,26 @@ packages: resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} dev: true + /lodash.isempty@4.4.0: + resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==} + dev: true + + /lodash.isfunction@3.0.9: + resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} + dev: true + + /lodash.isobject@3.0.2: + resolution: {integrity: sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA==} + dev: true + /lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} dev: true + /lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + dev: true + /lodash.kebabcase@4.1.1: resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} dev: true @@ -4552,6 +4710,13 @@ packages: wrap-ansi: 6.2.0 dev: true + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + /loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} dependencies: @@ -4722,6 +4887,79 @@ packages: ufo: 1.4.0 dev: true + /mocha@10.7.3: + resolution: {integrity: sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==} + engines: {node: '>= 14.0.0'} + hasBin: true + dependencies: + ansi-colors: 4.1.3 + browser-stdout: 1.3.1 + chokidar: 3.6.0 + debug: 4.3.7(supports-color@8.1.1) + diff: 5.2.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 8.1.0 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 5.1.6 + ms: 2.1.3 + serialize-javascript: 6.0.2 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.5.1 + yargs: 16.2.0 + yargs-parser: 20.2.9 + yargs-unparser: 2.0.0 + dev: true + + /mochawesome-merge@4.3.0: + resolution: {integrity: sha512-1roR6g+VUlfdaRmL8dCiVpKiaUhbPVm1ZQYUM6zHX46mWk+tpsKVZR6ba98k2zc8nlPvYd71yn5gyH970pKBSw==} + engines: {node: '>=10.0.0'} + hasBin: true + dependencies: + fs-extra: 7.0.1 + glob: 7.2.3 + yargs: 15.4.1 + dev: true + + /mochawesome-report-generator@6.2.0: + resolution: {integrity: sha512-Ghw8JhQFizF0Vjbtp9B0i//+BOkV5OWcQCPpbO0NGOoxV33o+gKDYU0Pr2pGxkIHnqZ+g5mYiXF7GMNgAcDpSg==} + hasBin: true + dependencies: + chalk: 4.1.2 + dateformat: 4.6.3 + escape-html: 1.0.3 + fs-extra: 10.1.0 + fsu: 1.1.1 + lodash.isfunction: 3.0.9 + opener: 1.5.2 + prop-types: 15.8.1 + tcomb: 3.2.29 + tcomb-validation: 3.4.1 + validator: 13.11.0 + yargs: 17.7.2 + dev: true + + /mochawesome@7.1.3(mocha@10.7.3): + resolution: {integrity: sha512-Vkb3jR5GZ1cXohMQQ73H3cZz7RoxGjjUo0G5hu0jLaW+0FdUxUwg3Cj29bqQdh0rFcnyV06pWmqmi5eBPnEuNQ==} + peerDependencies: + mocha: '>=7' + dependencies: + chalk: 4.1.2 + diff: 5.2.0 + json-stringify-safe: 5.0.1 + lodash.isempty: 4.4.0 + lodash.isfunction: 3.0.9 + lodash.isobject: 3.0.2 + lodash.isstring: 4.0.1 + mocha: 10.7.3 + mochawesome-report-generator: 6.2.0 + strip-ansi: 6.0.1 + uuid: 8.3.2 + dev: true + /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -4870,6 +5108,11 @@ packages: is-wsl: 2.2.0 dev: false + /opener@1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + dev: true + /optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -4915,6 +5158,13 @@ packages: engines: {node: '>=12.20'} dev: false + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -4929,6 +5179,13 @@ packages: yocto-queue: 1.0.0 dev: true + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + /p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -4950,6 +5207,11 @@ packages: aggregate-error: 3.1.0 dev: true + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + /package-json@8.1.1: resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} engines: {node: '>=14.16'} @@ -5139,6 +5401,14 @@ packages: engines: {node: '>=0.4.0'} dev: false + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + /proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} @@ -5242,6 +5512,10 @@ packages: strip-json-comments: 2.0.1 dev: false + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + /react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} dev: true @@ -5328,6 +5602,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: true + /requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -5573,6 +5851,10 @@ packages: transitivePeerDependencies: - supports-color + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + /set-function-length@1.2.1: resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} engines: {node: '>= 0.4'} @@ -5829,6 +6111,16 @@ packages: readable-stream: 3.6.2 dev: true + /tcomb-validation@3.4.1: + resolution: {integrity: sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA==} + dependencies: + tcomb: 3.2.29 + dev: true + + /tcomb@3.2.29: + resolution: {integrity: sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==} + dev: true + /text-extensions@2.4.0: resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} engines: {node: '>=8'} @@ -6048,6 +6340,11 @@ packages: crypto-random-string: 4.0.0 dev: false + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: true + /universalify@0.2.0: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} @@ -6137,7 +6434,6 @@ packages: /validator@13.11.0: resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} engines: {node: '>= 0.10'} - dev: false /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} @@ -6484,6 +6780,10 @@ packages: engines: {node: '>=12'} dev: true + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: true + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -6511,6 +6811,10 @@ packages: resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} dev: true + /workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} + dev: true + /wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -6559,6 +6863,10 @@ packages: engines: {node: '>=12'} dev: true + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: true + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -6584,11 +6892,64 @@ packages: engines: {node: '>= 6'} dev: true + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: true + + /yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + dev: true + /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} dev: true + /yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + dev: true + + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: true + + /yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + dependencies: + cliui: 7.0.4 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + dev: true + /yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} diff --git a/src/boot/axios.js b/src/boot/axios.js index 99a163cca..aee38e887 100644 --- a/src/boot/axios.js +++ b/src/boot/axios.js @@ -2,9 +2,11 @@ import axios from 'axios'; import { useSession } from 'src/composables/useSession'; import { Router } from 'src/router'; import useNotify from 'src/composables/useNotify.js'; +import { useStateQueryStore } from 'src/stores/useStateQueryStore'; const session = useSession(); const { notify } = useNotify(); +const stateQuery = useStateQueryStore(); const baseUrl = '/api/'; axios.defaults.baseURL = baseUrl; @@ -15,7 +17,7 @@ const onRequest = (config) => { if (token.length && !config.headers.Authorization) { config.headers.Authorization = token; } - + stateQuery.add(config); return config; }; @@ -24,10 +26,10 @@ const onRequestError = (error) => { }; const onResponse = (response) => { - const { method } = response.config; + const config = response.config; + stateQuery.remove(config); - const isSaveRequest = method === 'patch'; - if (isSaveRequest) { + if (config.method === 'patch') { notify('globals.dataSaved', 'positive'); } @@ -35,37 +37,9 @@ const onResponse = (response) => { }; const onResponseError = (error) => { - let message = ''; + stateQuery.remove(error.config); - const response = error.response; - const responseData = response && response.data; - const responseError = responseData && response.data.error; - if (responseError) { - message = responseError.message; - } - - switch (response?.status) { - case 422: - if (error.name == 'ValidationError') - message += - ' "' + - responseError.details.context + - '.' + - Object.keys(responseError.details.codes).join(',') + - '"'; - break; - case 500: - message = 'errors.statusInternalServerError'; - break; - case 502: - message = 'errors.statusBadGateway'; - break; - case 504: - message = 'errors.statusGatewayTimeout'; - break; - } - - if (session.isLoggedIn() && response?.status === 401) { + if (session.isLoggedIn() && error.response?.status === 401) { session.destroy(false); const hash = window.location.hash; const url = hash.slice(1); @@ -74,8 +48,6 @@ const onResponseError = (error) => { return Promise.reject(error); } - notify(message, 'negative'); - return Promise.reject(error); }; diff --git a/src/boot/defaults/qInput.js b/src/boot/defaults/qInput.js new file mode 100644 index 000000000..299b98718 --- /dev/null +++ b/src/boot/defaults/qInput.js @@ -0,0 +1,4 @@ +import { QInput } from 'quasar'; +import setDefault from './setDefault'; + +setDefault(QInput, 'dense', true); diff --git a/src/boot/defaults/qSelect.js b/src/boot/defaults/qSelect.js new file mode 100644 index 000000000..be0ba048a --- /dev/null +++ b/src/boot/defaults/qSelect.js @@ -0,0 +1,4 @@ +import { QSelect } from 'quasar'; +import setDefault from './setDefault'; + +setDefault(QSelect, 'dense', true); diff --git a/src/boot/mainShortcutMixin.js b/src/boot/mainShortcutMixin.js deleted file mode 100644 index 8e5f147db..000000000 --- a/src/boot/mainShortcutMixin.js +++ /dev/null @@ -1,38 +0,0 @@ -import routes from 'src/router/modules'; -import { useRouter } from 'vue-router'; - -let isNotified = false; - -export default { - created: function () { - const router = useRouter(); - const keyBindingMap = routes - .filter((route) => route.meta.keyBinding) - .reduce((map, route) => { - map['Key' + route.meta.keyBinding.toUpperCase()] = route.path; - return map; - }, {}); - - const handleKeyDown = (event) => { - const { ctrlKey, altKey, code } = event; - - if (ctrlKey && altKey && keyBindingMap[code] && !isNotified) { - event.preventDefault(); - router.push(keyBindingMap[code]); - isNotified = true; - } - }; - - const handleKeyUp = (event) => { - const { ctrlKey, altKey } = event; - - // Resetea la bandera cuando se sueltan las teclas ctrl o alt - if (!ctrlKey || !altKey) { - isNotified = false; - } - }; - - window.addEventListener('keydown', handleKeyDown); - window.addEventListener('keyup', handleKeyUp); - }, -}; diff --git a/src/boot/quasar.defaults.js b/src/boot/quasar.defaults.js index c792100d7..9638e2057 100644 --- a/src/boot/quasar.defaults.js +++ b/src/boot/quasar.defaults.js @@ -1 +1,3 @@ export * from './defaults/qTable'; +export * from './defaults/qInput'; +export * from './defaults/qSelect'; diff --git a/src/boot/quasar.js b/src/boot/quasar.js index 5db6edd24..01fe68d8b 100644 --- a/src/boot/quasar.js +++ b/src/boot/quasar.js @@ -1,16 +1,51 @@ import { boot } from 'quasar/wrappers'; import qFormMixin from './qformMixin'; -import mainShortcutMixin from './mainShortcutMixin'; import keyShortcut from './keyShortcut'; import useNotify from 'src/composables/useNotify.js'; +import { CanceledError } from 'axios'; + const { notify } = useNotify(); export default boot(({ app }) => { app.mixin(qFormMixin); - app.mixin(mainShortcutMixin); app.directive('shortcut', keyShortcut); - app.config.errorHandler = function (err) { - console.error(err); - notify('globals.error', 'negative', 'error'); + app.config.errorHandler = (error) => { + let message; + const response = error.response; + const responseData = response?.data; + const responseError = responseData && response.data.error; + if (responseError) { + message = responseError.message; + } + + switch (response?.status) { + case 422: + if (error.name == 'ValidationError') + message += + ' "' + + responseError.details.context + + '.' + + Object.keys(responseError.details.codes).join(',') + + '"'; + break; + case 500: + message = 'errors.statusInternalServerError'; + break; + case 502: + message = 'errors.statusBadGateway'; + break; + case 504: + message = 'errors.statusGatewayTimeout'; + break; + } + + console.error(error); + if (error instanceof CanceledError) { + const env = process.env.NODE_ENV; + if (env && env !== 'development') return; + message = 'Duplicate request'; + } + + notify(message ?? 'globals.error', 'negative', 'error'); }; }); diff --git a/src/components/CreateBankEntityForm.vue b/src/components/CreateBankEntityForm.vue index 0a3c10f57..a42be6ef8 100644 --- a/src/components/CreateBankEntityForm.vue +++ b/src/components/CreateBankEntityForm.vue @@ -31,8 +31,8 @@ const countriesFilter = { const countriesOptions = ref([]); -const onDataSaved = (formData, requestResponse) => { - emit('onDataSaved', formData, requestResponse); +const onDataSaved = (...args) => { + emit('onDataSaved', ...args); }; onMounted(async () => { diff --git a/src/components/CreateNewPostcodeForm.vue b/src/components/CreateNewPostcodeForm.vue index 99cba5360..03cba8ac7 100644 --- a/src/components/CreateNewPostcodeForm.vue +++ b/src/components/CreateNewPostcodeForm.vue @@ -79,14 +79,20 @@ async function onProvinceCreated(data) { watch( () => [postcodeFormData.countryFk], async (newCountryFk, oldValueFk) => { - if (!!oldValueFk[0] && newCountryFk[0] !== oldValueFk[0]) { + if (Array.isArray(newCountryFk)) { + newCountryFk = newCountryFk[0]; + } + if (Array.isArray(oldValueFk)) { + oldValueFk = oldValueFk[0]; + } + if (!!oldValueFk && newCountryFk !== oldValueFk) { postcodeFormData.provinceFk = null; postcodeFormData.townFk = null; } - if ((newCountryFk, newCountryFk !== postcodeFormData.countryFk)) { + if (oldValueFk !== newCountryFk) { await provincesFetchDataRef.value.fetch({ where: { - countryFk: newCountryFk[0], + countryFk: newCountryFk, }, }); await townsFetchDataRef.value.fetch({ @@ -102,10 +108,13 @@ watch( watch( () => postcodeFormData.provinceFk, - async (newProvinceFk) => { - if (newProvinceFk[0] && newProvinceFk[0] !== postcodeFormData.provinceFk) { + async (newProvinceFk, oldValueFk) => { + if (Array.isArray(newProvinceFk)) { + newProvinceFk = newProvinceFk[0]; + } + if (newProvinceFk !== oldValueFk) { await townsFetchDataRef.value.fetch({ - where: { provinceFk: newProvinceFk[0] }, + where: { provinceFk: newProvinceFk }, }); } } @@ -125,16 +134,20 @@ async function handleCountries(data) { - + { }, }" url="Autonomies/location" + :sort-by="['name ASC']" + :limit="30" /> { @on-fetch="(data) => (warehousesOptions = data)" auto-load url="Warehouses" - :filter="{ fields: ['id', 'name'], order: 'name ASC', limit: 30 }" + :filter="{ fields: ['id', 'name'], order: 'name ASC' }" /> [ { - label: t('entry.buys.id'), + label: t('globals.id'), name: 'id', field: 'id', align: 'left', }, { - label: t('entry.buys.name'), + label: t('globals.name'), name: 'name', field: 'name', align: 'left', }, { - label: t('entry.buys.size'), + label: t('globals.size'), name: 'size', field: 'size', align: 'left', }, { - label: t('entry.buys.producer'), + label: t('globals.producer'), name: 'producerName', field: 'producer', align: 'left', @@ -152,10 +152,10 @@ const selectItem = ({ id }) => {

{{ t('Filter item') }}

- + { v-model="itemFilterParams.producerFk" /> [ { - label: t('entry.basicData.id'), + label: t('globals.id'), name: 'id', field: 'id', align: 'left', }, { - label: t('entry.basicData.warehouseOut'), + label: t('globals.warehouseOut'), name: 'warehouseOutFk', field: 'warehouseOutFk', align: 'left', @@ -62,7 +62,7 @@ const tableColumns = computed(() => [ warehousesOptions.value.find((warehouse) => warehouse.id === val).name, }, { - label: t('entry.basicData.warehouseIn'), + label: t('globals.warehouseIn'), name: 'warehouseInFk', field: 'warehouseInFk', align: 'left', @@ -70,14 +70,14 @@ const tableColumns = computed(() => [ warehousesOptions.value.find((warehouse) => warehouse.id === val).name, }, { - label: t('entry.basicData.shipped'), + label: t('globals.shipped'), name: 'shipped', field: 'shipped', align: 'left', format: (val) => toDate(val), }, { - label: t('entry.basicData.landed'), + label: t('globals.landed'), name: 'landed', field: 'landed', align: 'left', @@ -146,7 +146,7 @@ const selectTravel = ({ id }) => {

{{ t('Filter travels') }}

{ v-model="travelFilterParams.agencyModeFk" /> { v-model="travelFilterParams.warehouseOutFk" /> { v-model="travelFilterParams.warehouseInFk" /> diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue index 05f947cf3..c668769e5 100644 --- a/src/components/FormModel.vue +++ b/src/components/FormModel.vue @@ -217,9 +217,6 @@ async function save() { updateAndEmit('onDataSaved', formData.value, response?.data); if ($props.reload) await arrayData.fetch({}); hasChanges.value = false; - } catch (err) { - console.error(err); - notify('errors.writeRequest', 'negative'); } finally { isLoading.value = false; } @@ -275,6 +272,7 @@ defineExpose({ hasChanges, reset, fetch, + formData, }); diff --git a/src/components/ItemsFilterPanel.vue b/src/components/ItemsFilterPanel.vue index e89d32da4..938dceb4d 100644 --- a/src/components/ItemsFilterPanel.vue +++ b/src/components/ItemsFilterPanel.vue @@ -248,7 +248,7 @@ const removeTag = (index, params, search) => { > import axios from 'axios'; -import { onMounted, watch, ref, reactive } from 'vue'; +import { onMounted, watch, ref, reactive, computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { QSeparator, useQuasar } from 'quasar'; import { useRoute } from 'vue-router'; @@ -9,6 +9,7 @@ import { toLowerCamel } from 'src/filters'; import routes from 'src/router/modules'; import LeftMenuItem from './LeftMenuItem.vue'; import LeftMenuItemGroup from './LeftMenuItemGroup.vue'; +import VnInput from './common/VnInput.vue'; const { t } = useI18n(); const route = useRoute(); @@ -22,7 +23,40 @@ const props = defineProps({ }, }); +const items = ref([]); const expansionItemElements = reactive({}); +const pinnedModules = computed(() => { + const map = new Map(); + items.value.forEach((item) => item.isPinned && map.set(item.name, item)); + return map; +}); +const search = ref(null); + +const filteredItems = computed(() => { + if (!search.value) return items.value; + const normalizedSearch = normalize(search.value); + return items.value.filter((item) => { + const locale = normalize(t(item.title)); + return locale.includes(normalizedSearch); + }); +}); + +const filteredPinnedModules = computed(() => { + if (!search.value) return pinnedModules.value; + const normalizedSearch = search.value + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') + .toLowerCase(); + const map = new Map(); + for (const [key, pinnedModule] of pinnedModules.value) { + const locale = t(pinnedModule.title) + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') + .toLowerCase(); + if (locale.includes(normalizedSearch)) map.set(key, pinnedModule); + } + return map; +}); onMounted(async () => { await navigation.fetchPinned(); @@ -66,8 +100,6 @@ function addChildren(module, route, parent) { } } -const items = ref([]); - function getRoutes() { if (props.source === 'main') { const modules = Object.assign([], navigation.getModules().value); @@ -123,21 +155,57 @@ async function togglePinned(item, event) { const handleItemExpansion = (itemName) => { expansionItemElements[itemName].scrollToLastElement(); }; + +function normalize(text) { + return text + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') + .toLowerCase(); +}