From d37797fdad61467264e3a9b4acadc2b2d1e8f4bf Mon Sep 17 00:00:00 2001 From: Surya Paolo Date: Fri, 11 Jul 2025 12:55:24 +0200 Subject: [PATCH] - Import di un file XLS contenente una lista di libri, all'interno di un catalogo. --- .env | 4 +- index.html | 2 +- package.json | 14 +- .../comunitanuovomondo.app/package.json | 8 +- .../_ALL_SITES/freeplanet.app/package.json | 12 +- .../_ALL_SITES/gruppomacro.app/package.json | 14 +- scripts/_ALL_SITES/kolibrilab.it/package.json | 12 +- .../nutriben-naturopatia.it/package.json | 14 +- .../_ALL_SITES/piuchebuono.app/package.json | 12 +- scripts/_ALL_SITES/riso.app/package.json | 12 +- src-pwa/custom-service-worker.js | 2 +- .../CCatalogoCard/CCatalogoCard.vue | 2 +- .../CImportListaTitoli.scss | 23 ++ .../CImportListaTitoli/CImportListaTitoli.ts | 313 ++++++++++++++++++ .../CImportListaTitoli/CImportListaTitoli.vue | 87 +++++ src/components/CImportListaTitoli/index.ts | 1 + src/components/CProductTable/CProductTable.ts | 75 +++-- .../CProductTable/CProductTable.vue | 32 +- src/views/ecommerce/catalogo/catalogo.ts | 2 +- src/views/ecommerce/catalogo/catalogo.vue | 7 +- 20 files changed, 568 insertions(+), 80 deletions(-) create mode 100755 src/components/CImportListaTitoli/CImportListaTitoli.scss create mode 100755 src/components/CImportListaTitoli/CImportListaTitoli.ts create mode 100755 src/components/CImportListaTitoli/CImportListaTitoli.vue create mode 100755 src/components/CImportListaTitoli/index.ts diff --git a/.env b/.env index 9d54436a..e34de06f 100755 --- a/.env +++ b/.env @@ -1,6 +1,6 @@ -VITE_APP_VERSION="1.2.63" +VITE_APP_VERSION="1.2.65" VITE_LANG_DEFAULT="it" VITE_PAO_APP_ID="KKPPAA5KJK435J3KSS9F9D8S9F8SD98F9SDF" -VITE_SERVICE_WORKER_FILE="sw-1.2.63.js" +VITE_SERVICE_WORKER_FILE="sw-1.2.65.js" VITE_PROJECT_ID_MAIN="5cc0a13fe5c9d156728f400a" VITE_VUE_ROUTER_MODE="history" \ No newline at end of file diff --git a/index.html b/index.html index 190cfea9..b62c85b7 100755 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@ - + diff --git a/package.json b/package.json index fe74e247..aa0bc479 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gruppomacro", - "version": "1.2.63", + "version": "1.2.65", "description": "Gruppo Macro", "productName": "Gruppo Macro", "author": "Surya", @@ -9,20 +9,20 @@ "license": "MIT", "type": "module", "scripts": { - "dev": "PORT=8089 APP_VERSION='1.2.63' quasar dev", + "dev": "PORT=8089 APP_VERSION='1.2.65' quasar dev", "dev_noCheck": "SKIP_TSC=true quasar dev", "build": "quasar build", - "buildpwa": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", - "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", + "buildpwa": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", + "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", "type-check": "vue-tsc --noEmit", "type-check:watch": "vue-tsc --noEmit --watch", - "buildspa": "APP_VERSION='1.2.63' quasar build -m spa", + "buildspa": "APP_VERSION='1.2.65' quasar build -m spa", "lint": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\"", "lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt", "lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt", "fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt", - "pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.63' quasar dev -m pwa", - "spa": "NODE_ENV=development PORT=8089 APP_VERSION='1.2.63' quasar dev", + "pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.65' quasar dev -m pwa", + "spa": "NODE_ENV=development PORT=8089 APP_VERSION='1.2.65' quasar dev", "debug": "quasar dev --mode debug", "test": "echo \"No test specified\" && exit 0", "generate-sw": "workbox generateSW workbox-config.js", diff --git a/scripts/_ALL_SITES/comunitanuovomondo.app/package.json b/scripts/_ALL_SITES/comunitanuovomondo.app/package.json index 61e64452..a4070eb7 100755 --- a/scripts/_ALL_SITES/comunitanuovomondo.app/package.json +++ b/scripts/_ALL_SITES/comunitanuovomondo.app/package.json @@ -1,6 +1,6 @@ { "name": "cnm", - "version": "1.2.63", + "version": "1.2.65", "description": "Comunita Nuovo Mondo", "productName": "ComunitaNuovoMondo", "author": "Surya", @@ -9,7 +9,7 @@ "license": "MIT", "type": "module", "scripts": { - "dev": "PORT=8083 APP_VERSION='1.2.63' quasar dev", + "dev": "PORT=8083 APP_VERSION='1.2.65' quasar dev", "dev_noCheck": "SKIP_TSC=true quasar dev", "build": "quasar build", "buildpwa": "NODE_ENV=production quasar build -m pwa", @@ -21,8 +21,8 @@ "lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt", "lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt", "fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt", - "pwa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.63' quasar dev -m pwa", - "spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.63' quasar dev", + "pwa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.65' quasar dev -m pwa", + "spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.65' quasar dev", "debug": "quasar dev --mode debug", "test": "echo \"No test specified\" && exit 0", "generate-sw": "workbox generateSW workbox-config.js", diff --git a/scripts/_ALL_SITES/freeplanet.app/package.json b/scripts/_ALL_SITES/freeplanet.app/package.json index bacede26..3209f6fd 100755 --- a/scripts/_ALL_SITES/freeplanet.app/package.json +++ b/scripts/_ALL_SITES/freeplanet.app/package.json @@ -1,6 +1,6 @@ { "name": "freeplanet", - "version": "1.2.63", + "version": "1.2.65", "description": "freeplanet", "productName": "freeplanet", "author": "Surya", @@ -9,11 +9,11 @@ "license": "MIT", "type": "module", "scripts": { - "dev": "PORT=8087 APP_VERSION='1.2.63' quasar dev", + "dev": "PORT=8087 APP_VERSION='1.2.65' quasar dev", "dev_noCheck": "SKIP_TSC=true quasar dev", "build": "quasar build", - "buildpwa": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", - "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", + "buildpwa": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", + "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", "type-check": "vue-tsc --noEmit", "type-check:watch": "vue-tsc --noEmit --watch", "buildspa": "quasar build -m spa", @@ -21,8 +21,8 @@ "lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt", "lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt", "fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt", - "pwa": "NODE_ENV=development PORT=8097 APP_VERSION='1.2.63' quasar dev -m pwa", - "spa": "NODE_ENV=development PORT=8087 APP_VERSION='1.2.63' quasar dev", + "pwa": "NODE_ENV=development PORT=8097 APP_VERSION='1.2.65' quasar dev -m pwa", + "spa": "NODE_ENV=development PORT=8087 APP_VERSION='1.2.65' quasar dev", "debug": "quasar dev --mode debug", "test": "echo \"No test specified\" && exit 0", "generate-sw": "workbox generateSW workbox-config.js", diff --git a/scripts/_ALL_SITES/gruppomacro.app/package.json b/scripts/_ALL_SITES/gruppomacro.app/package.json index ab8a0223..61aa3177 100755 --- a/scripts/_ALL_SITES/gruppomacro.app/package.json +++ b/scripts/_ALL_SITES/gruppomacro.app/package.json @@ -1,6 +1,6 @@ { "name": "gruppomacro", - "version": "1.2.63", + "version": "1.2.65", "description": "Gruppo Macro", "productName": "Gruppo Macro", "author": "Surya", @@ -9,20 +9,20 @@ "license": "MIT", "type": "module", "scripts": { - "dev": "PORT=8089 APP_VERSION='1.2.63' quasar dev", + "dev": "PORT=8089 APP_VERSION='1.2.65' quasar dev", "dev_noCheck": "SKIP_TSC=true quasar dev", "build": "quasar build", - "buildpwa": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", - "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", + "buildpwa": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", + "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", "type-check": "vue-tsc --noEmit", "type-check:watch": "vue-tsc --noEmit --watch", - "buildspa": "APP_VERSION='1.2.63' quasar build -m spa", + "buildspa": "APP_VERSION='1.2.65' quasar build -m spa", "lint": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\"", "lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt", "lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt", "fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt", - "pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.63' quasar dev -m pwa", - "spa": "NODE_ENV=development PORT=8089 APP_VERSION='1.2.63' quasar dev", + "pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.65' quasar dev -m pwa", + "spa": "NODE_ENV=development PORT=8089 APP_VERSION='1.2.65' quasar dev", "debug": "quasar dev --mode debug", "test": "echo \"No test specified\" && exit 0", "generate-sw": "workbox generateSW workbox-config.js", diff --git a/scripts/_ALL_SITES/kolibrilab.it/package.json b/scripts/_ALL_SITES/kolibrilab.it/package.json index 57d94f0b..f3cbf885 100755 --- a/scripts/_ALL_SITES/kolibrilab.it/package.json +++ b/scripts/_ALL_SITES/kolibrilab.it/package.json @@ -1,6 +1,6 @@ { "name": "kolibrilab", - "version": "1.2.63", + "version": "1.2.65", "description": "kolibrilab", "productName": "kolibrilab", "author": "Surya Paolo", @@ -8,11 +8,11 @@ "keywords": [], "license": "MIT", "scripts": { - "dev": "PORT=8083 APP_VERSION='1.2.63' quasar dev", + "dev": "PORT=8083 APP_VERSION='1.2.65' quasar dev", "dev_noCheck": "SKIP_TSC=true quasar dev", "build": "quasar build", - "buildpwa": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", - "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", + "buildpwa": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", + "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", "type-check": "vue-tsc --noEmit", "type-check:watch": "vue-tsc --noEmit --watch", "buildspa": "quasar build -m spa", @@ -20,8 +20,8 @@ "lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt", "lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt", "fix": "eslint --ext .ts,.vue --ignore-path .gitignore ./ --fix > file.out.txt", - "pwa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.63' quasar dev -m pwa", - "spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.63' quasar dev", + "pwa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.65' quasar dev -m pwa", + "spa": "NODE_ENV=development PORT=8083 APP_VERSION='1.2.65' quasar dev", "spanorefresh": "NODE_ENV=development NODE_OPTIONS=--max_old_space_size=4096 DEBUG=v8:* quasar dev -m spa", "test": "echo \"No test specified\" && exit 0", "generate-sw": "workbox generateSW workbox-config.js" diff --git a/scripts/_ALL_SITES/nutriben-naturopatia.it/package.json b/scripts/_ALL_SITES/nutriben-naturopatia.it/package.json index 6c1ea933..74e5044c 100755 --- a/scripts/_ALL_SITES/nutriben-naturopatia.it/package.json +++ b/scripts/_ALL_SITES/nutriben-naturopatia.it/package.json @@ -1,6 +1,6 @@ { "name": "nutriben", - "version": "1.2.63", + "version": "1.2.65", "description": "Nutriben", "productName": "Nutriben", "author": "Surya", @@ -9,20 +9,20 @@ "license": "MIT", "type": "module", "scripts": { - "dev": "PORT=8093 APP_VERSION='1.2.63' quasar dev", + "dev": "PORT=8093 APP_VERSION='1.2.65' quasar dev", "dev_noCheck": "SKIP_TSC=true quasar dev", "build": "quasar build", - "buildpwa": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", - "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", + "buildpwa": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", + "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", "type-check": "vue-tsc --noEmit", "type-check:watch": "vue-tsc --noEmit --watch", - "buildspa": "APP_VERSION='1.2.63' quasar build -m spa", + "buildspa": "APP_VERSION='1.2.65' quasar build -m spa", "lint": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\"", "lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt", "lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt", "fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt", - "pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.63' quasar dev -m pwa", - "spa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.63' quasar dev", + "pwa": "NODE_ENV=development PORT=8099 APP_VERSION='1.2.65' quasar dev -m pwa", + "spa": "NODE_ENV=development PORT=8093 APP_VERSION='1.2.65' quasar dev", "debug": "quasar dev --mode debug", "test": "echo \"No test specified\" && exit 0", "generate-sw": "workbox generateSW workbox-config.js", diff --git a/scripts/_ALL_SITES/piuchebuono.app/package.json b/scripts/_ALL_SITES/piuchebuono.app/package.json index 06690b59..daeb7e3b 100755 --- a/scripts/_ALL_SITES/piuchebuono.app/package.json +++ b/scripts/_ALL_SITES/piuchebuono.app/package.json @@ -1,6 +1,6 @@ { "name": "piuchebuono", - "version": "1.2.63", + "version": "1.2.65", "description": "PiuCheBuono", "productName": "PiuCheBuono", "author": "Surya", @@ -9,11 +9,11 @@ "license": "MIT", "type": "module", "scripts": { - "dev": "PORT=8085 APP_VERSION='1.2.63' quasar dev", + "dev": "PORT=8085 APP_VERSION='1.2.65' quasar dev", "dev_noCheck": "SKIP_TSC=true quasar dev", "build": "quasar build", - "buildpwa": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", - "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", + "buildpwa": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", + "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", "type-check": "vue-tsc --noEmit", "type-check:watch": "vue-tsc --noEmit --watch", "buildspa": "quasar build -m spa", @@ -21,8 +21,8 @@ "lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt", "lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt", "fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt", - "pwa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.63' quasar dev -m pwa", - "spa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.63' quasar dev", + "pwa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.65' quasar dev -m pwa", + "spa": "NODE_ENV=development PORT=8085 APP_VERSION='1.2.65' quasar dev", "debug": "quasar dev --mode debug", "test": "echo \"No test specified\" && exit 0", "generate-sw": "workbox generateSW workbox-config.js", diff --git a/scripts/_ALL_SITES/riso.app/package.json b/scripts/_ALL_SITES/riso.app/package.json index 8130c6f1..f0bea8c0 100755 --- a/scripts/_ALL_SITES/riso.app/package.json +++ b/scripts/_ALL_SITES/riso.app/package.json @@ -1,6 +1,6 @@ { "name": "riso", - "version": "1.2.63", + "version": "1.2.65", "description": "Siamo la Rete Italiana di Scambio Orizzontale, abbiamo creato questa piattaforma per metterla al servizio di chi vuole riscoprire il valore della condivisione e della cooperazione. Valori semplici e profondi che ci aiutano a ritrovare il Senso della Vita, perduto in questa società consumista, e riporti quei Sani Pricìpi Naturali ed Umani di Fratellanza che intere popolazioni antiche conoscevano bene.", "productName": "Riso", "author": "Surya", @@ -9,11 +9,11 @@ "license": "MIT", "type": "module", "scripts": { - "dev": "APP_VERSION='1.2.63' PORT=8084 quasar dev", + "dev": "APP_VERSION='1.2.65' PORT=8084 quasar dev", "dev_noCheck": "SKIP_TSC=true quasar dev", "build": "quasar build", - "buildpwa": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", - "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.63' quasar build -m pwa", + "buildpwa": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", + "buildpwatest": "NODE_ENV=production APP_VERSION='1.2.65' quasar build -m pwa", "type-check": "vue-tsc --noEmit", "type-check:watch": "vue-tsc --noEmit --watch", "buildspa": "quasar build -m spa", @@ -21,8 +21,8 @@ "lintfile": "eslint --ext .js,.ts,.vue --ignore-path .gitignore ./ > file.out.txt", "lintfileNoJS": "eslint --ext .ts,.vue --ignore-path .gitignore ./ > file.out.txt", "fix": "eslint -c ./eslint.config.js \"./src*/**/*.{ts,js,cjs,mjs,vue}\" --ignore-pattern .gitignore ./ --fix > file.out.txt", - "pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.63' quasar dev -m pwa", - "spa": "NODE_ENV=development PORT=8084 APP_VERSION='1.2.63' quasar dev", + "pwa": "NODE_ENV=development PORT=8094 APP_VERSION='1.2.65' quasar dev -m pwa", + "spa": "NODE_ENV=development PORT=8084 APP_VERSION='1.2.65' quasar dev", "debug": "quasar dev --mode debug", "test": "echo \"No test specified\" && exit 0", "generate-sw": "workbox generateSW workbox-config.js", diff --git a/src-pwa/custom-service-worker.js b/src-pwa/custom-service-worker.js index 71d99e14..377295c4 100755 --- a/src-pwa/custom-service-worker.js +++ b/src-pwa/custom-service-worker.js @@ -3,7 +3,7 @@ /* global workbox */ /* global cfgenv */ -const VITE_APP_VERSION = '1.2.63'; +const VITE_APP_VERSION = '1.2.65'; // Costanti di configurazione const DYNAMIC_CACHE = 'dynamic-cache-v2'; diff --git a/src/components/CCatalogoCard/CCatalogoCard.vue b/src/components/CCatalogoCard/CCatalogoCard.vue index 95670e61..ab9ba985 100755 --- a/src/components/CCatalogoCard/CCatalogoCard.vue +++ b/src/components/CCatalogoCard/CCatalogoCard.vue @@ -163,7 +163,7 @@ > -
+
([]); + const searchResults = ref([]); + const loading = ref(false); + const error = ref(null); + + const columns = ref([ + { + name: 'title', + label: 'Titolo', + field: 'title', + align: 'left', + sortable: true, + }, + { + name: 'isbn', + label: 'ISBN', + field: 'isbn', + align: 'left', + sortable: true, + }, + { + name: 'select', + label: 'Seleziona', + field: 'select', + align: 'left', + }, + ]); + + const onRequest = (props: any) => { + const { page, rowsPerPage, sortBy, descending } = props.pagination; + const filterValue = filter.value; + const filteredRows = searchResults.value + .filter((row) => { + const title = row.title?.toLowerCase() || ''; + const author = row.author?.toLowerCase() || ''; + const isbn = row.isbn?.toLowerCase() || ''; + return ( + title.includes(filterValue.toLowerCase()) || + author.includes(filterValue.toLowerCase()) || + isbn.includes(filterValue.toLowerCase()) + ); + }) + .sort((a, b) => { + const sortA = a[sortBy]; + const sortB = b[sortBy]; + if (descending) { + return sortA < sortB ? 1 : -1; + } else { + return sortA > sortB ? 1 : -1; + } + }); + + pagination.rowsNumber = filteredRows.length; + pagination.page = page; + pagination.rowsPerPage = rowsPerPage; + pagination.sortBy = sortBy; + pagination.descending = descending; + + return { + pagination, + rows: filteredRows.slice((page - 1) * rowsPerPage, page * rowsPerPage), + }; + }; + + const filter = ref(''); + + + const importSelectedBooks = () => { + if (searchResults.value.length === 0) { + $q.notify({ + message: t('Nessun libro selezionato'), + color: 'warning', + }); + return; + } + + // Aggiungi i libri selezionati alla lista dell'utente + emit( + 'addArrayTitlesToList', + searchResults.value.filter((row) => row.select), + ); + + }; + + const pagination = reactive({ + sortBy: 'title', + descending: false, + page: 1, + rowsPerPage: 50, + rowsNumber: searchResults.value.length, + }); + + const filteredResults = computed(() => { + const { sortBy, descending, page, rowsPerPage, rowsNumber } = pagination; + const firstIndex = (page - 1) * rowsPerPage; + const lastIndex = firstIndex + rowsPerPage; + + return searchResults.value.slice(firstIndex, lastIndex).sort((a, b) => { + const aValue = a[sortBy]; + const bValue = b[sortBy]; + return descending ? bValue.localeCompare(aValue) : aValue.localeCompare(bValue); + }); + }); + + // Gestore del caricamento del file + const handleFileUpload = (event: Event) => { + const file = (event.target as HTMLInputElement).files?.[0]; + if (file) { + loading.value = true; + error.value = null; + const reader = new FileReader(); + + reader.onload = async () => { + try { + // Verifica il tipo di file (CSV o Excel) e parse + if (file.name.endsWith('.csv')) { + fileData.value = await parseCSV(reader.result as string); + } else if (file.name.endsWith('.xls') || file.name.endsWith('.xlsx')) { + fileData.value = await parseExcel(reader.result as ArrayBuffer); + } + } catch (err) { + error.value = 'Errore nel parsing del file: ' + err; + } finally { + loading.value = false; + } + }; + + // Leggi il file con il metodo appropriato basato sul tipo + if (file.name.endsWith('.csv')) { + reader.readAsText(file); + } else if (file.name.endsWith('.xls') || file.name.endsWith('.xlsx')) { + reader.readAsArrayBuffer(file); // ← Questa è la correzione principale + } + } + }; + // Funzione di ricerca dei libri + const searchBooksHandler = async () => { + if (!fileData.value || fileData.value.length === 0) { + return; + } + + loading.value = true; + error.value = null; + + try { + // Esegui la ricerca con la funzione di backend + searchResults.value = await searchBooks(fileData.value); + + if (searchResults.value && searchResults.value.length > 0) { + $q.notify({ + message: `Trovati ${searchResults.value.length} libri`, + color: 'positive', + }); + } + if (searchResults.value && searchResults.value.length === 0) { + $q.notify({ + message: 'Nessun libro importabile', + color: 'negative', + }); + } + + } catch (err) { + error.value = 'Errore nella ricerca dei libri'; + } finally { + loading.value = false; + } + }; + + async function parseCSV(csvText: string): Promise { + // Funzione per analizzare un file CSV + const lines = csvText.split('\n'); + const headers = lines[0].split(','); + const data = lines.slice(1).map((line) => { + const values = line.split(','); + return headers.reduce((acc, header, index) => { + acc[header.trim()] = values[index].trim(); + return acc; + }, {} as any); + }); + + return data; + } + + async function parseExcel(excelData: ArrayBuffer): Promise { + try { + // Debug: verifica il tipo e la dimensione di excelData + console.log('Tipo di excelData:', typeof excelData); + console.log('È ArrayBuffer?', excelData instanceof ArrayBuffer); + console.log('Dimensione excelData:', excelData.byteLength); + + // Usa direttamente l'ArrayBuffer con type: 'buffer' + const workbook = XLSX.read(excelData, { type: 'buffer' }); + + // Controllo se ci sono fogli + if (!workbook.SheetNames || workbook.SheetNames.length === 0) { + throw new Error('Nessun foglio trovato nel file Excel'); + } + + console.log('Fogli disponibili:', workbook.SheetNames); + + // Prendi il nome del primo foglio + const sheetName = workbook.SheetNames[0]; + const sheet = workbook.Sheets[sheetName]; + + // Controllo se il foglio esiste + if (!sheet) { + throw new Error(`Il foglio "${sheetName}" non è stato trovato`); + } + + // Debug: mostra la struttura del foglio + console.log('Foglio:', sheetName); + console.log('Range del foglio:', sheet['!ref']); + console.log( + 'Tutte le celle:', + Object.keys(sheet).filter((key) => !key.startsWith('!')) + ); + + // Usa sheet_to_json per convertire il foglio in array di righe + const rows = XLSX.utils.sheet_to_json(sheet, { + header: 1, + defval: '', + raw: false, + }); + + console.log('Righe estratte:', rows.length); + console.log('Prime 3 righe:', rows.slice(0, 3)); + + // Filtra le righe completamente vuote + const filteredRows = rows.filter( + (row: any[]) => + Array.isArray(row) && + row.some((cell) => cell !== null && cell !== undefined && cell !== '') + ); + + return filteredRows; + } catch (error) { + console.error("Errore durante l'analisi del file Excel:", error); + throw new Error(`Errore durante l'analisi del file Excel: ${error.message}`); + } + } + + async function searchBooks(books: any[]): Promise { + const response = await Api.SendReq('/api/search-books', 'POST', { books }); + + if (response.status !== 200) { + throw new Error('Errore nella risposta del server'); + } + + return response.data; // Supponiamo che il backend ritorni un array di oggetti con id e title + } + + function deselectAll() { + + searchResults.value.forEach((row) => (row.select = false)); + + } + + return { + handleFileUpload, + searchBooks: searchBooksHandler, + searchResults, + loading, + error, + fileData, + pagination, + filteredResults, + importSelectedBooks, + filter, + onRequest, + columns, + deselectAll, + }; + }, +}); diff --git a/src/components/CImportListaTitoli/CImportListaTitoli.vue b/src/components/CImportListaTitoli/CImportListaTitoli.vue new file mode 100755 index 00000000..9f046f4c --- /dev/null +++ b/src/components/CImportListaTitoli/CImportListaTitoli.vue @@ -0,0 +1,87 @@ + + + + diff --git a/src/components/CImportListaTitoli/index.ts b/src/components/CImportListaTitoli/index.ts new file mode 100755 index 00000000..504d6e11 --- /dev/null +++ b/src/components/CImportListaTitoli/index.ts @@ -0,0 +1 @@ +export {default as CImportListaTitoli} from './CImportListaTitoli.vue' diff --git a/src/components/CProductTable/CProductTable.ts b/src/components/CProductTable/CProductTable.ts index 97b8db56..5bfc3bcb 100755 --- a/src/components/CProductTable/CProductTable.ts +++ b/src/components/CProductTable/CProductTable.ts @@ -23,6 +23,7 @@ import { CSchedaProdotto } from '@src/components/CSchedaProdotto'; import { CSearchProduct } from '@src/components/CSearchProduct'; import { CMyDialog } from '@src/components/CMyDialog'; import { CModifTrafiletto } from '@src/components/CModifTrafiletto'; +import { CImportListaTitoli } from '@src/components/CImportListaTitoli'; import { costanti } from '@costanti'; import { IAuthor, ICatProd } from 'app/src/model'; @@ -47,12 +48,18 @@ export default defineComponent({ CLabel, CSchedaProdotto, CModifTrafiletto, + CImportListaTitoli, }, props: { lista_prodotti: { type: Array, required: true, }, + canadd: { + trype: Boolean, + required: false, + default: false, + }, lista_prod_confronto: { type: Array, required: false, @@ -128,6 +135,7 @@ export default defineComponent({ const addstr = ref(''); const showDialogExport = ref(false); + const showDialogImport = ref(false); const selectedExportColumns = ref([]); const optionscatalogo = ref({ maxlength: 0 }); @@ -138,7 +146,7 @@ export default defineComponent({ } function riaggiornaListaProdAlGenitore() { - emit('update:lista_prodotti', internalProducts.value); + aggiornaLista(); } const editOn = computed({ @@ -551,7 +559,8 @@ export default defineComponent({ }; const savedColumns = tools.getCookie(addstr.value + 'selColCat_2'); - selectedExportColumns.value = tools.getCookie(addstr.value + 'Exp_Columns'); + const col = tools.getCookie(addstr.value + 'Exp_Columns', null); + selectedExportColumns.value = col ? col : []; if (savedColumns) { selectedColumns.value = savedColumns; } @@ -987,13 +996,27 @@ export default defineComponent({ persistent: false, }) .onOk(() => { - internalProducts.value = internalProducts.value.filter( - (p: any) => p._id !== product._id - ); - emit('update:lista_prodotti', internalProducts.value); // Notifica il parent del cambiamento + aggiornaLista(product); }); }; + function aggiornaLista(deleteelem: any = null) { + const precsearch = searchText.value; + + searchText.value = ''; + internalProducts.value = [...props.lista_prodotti]; + + if (deleteelem) { + internalProducts.value = internalProducts.value.filter( + (p: any) => p._id !== deleteelem._id + ); + } + + emit('update:lista_prodotti', internalProducts.value); // Notifica il parent del cambiamento + + searchText.value = precsearch; + } + // 8. Salvataggio delle colonne selezionate in un cookie const saveSelectedColumns = () => { tools.setCookie( @@ -1031,7 +1054,7 @@ export default defineComponent({ // Funzione chiamata alla fine del drag-and-drop const onDragEnd = () => { // console.log("Nuovo ordine:", internalProducts.value); - emit('update:lista_prodotti', internalProducts.value); // Notifica il parent del cambiamento + aggiornaLista(); }; function formatAuthors(authors: IAuthor[] | undefined | null): string { @@ -1096,7 +1119,7 @@ export default defineComponent({ return prod; }); - emit('update:lista_prodotti', internalProducts.value); // Notifica il parent del cambiamento + aggiornaLista(); } async function updateproductmodif(element: any) { @@ -1184,7 +1207,7 @@ export default defineComponent({ emit('rigenera'); } - function addtolist(element) { + function addtolist(element: any) { emit('addtolist', element); } @@ -1221,13 +1244,9 @@ export default defineComponent({ ) { saveSelectedColumnsExport(columns); const csvContent = [ - columns - .filter((col) => !columns.find((c) => c.name === col)?.noexp) - .map((col) => getColumnLabelByName(col)) - .join(separatore), + columns.map((col) => getColumnLabelByName(col)).join(separatore), ...internalProducts.value.map((product: any) => { return columns - .filter((col) => !columns.find((c) => c.name === col)?.noexp) .map((col: string) => { const field = { field: col }; return field.field === 'pos' @@ -1257,15 +1276,15 @@ export default defineComponent({ columns: any[], separatore: string = '\t' ) { + if (!Array.isArray(columns)) { + console.error('Errore: columns non è un array:', columns); + return; + } saveSelectedColumnsExport(columns); const csvContent = [ - columns - .filter((col) => !columns.find((c) => c.name === col)?.noexp) - .map((col) => getColumnLabelByName(col)) - .join(separatore), + columns.map((col) => getColumnLabelByName(col)).join(separatore), ...internalProducts.value.map((product: any) => { return columns - .filter((col) => !columns.find((c) => c.name === col)?.noexp) .map((col: string) => { const field = { field: col }; return field.field === 'pos' @@ -1276,6 +1295,12 @@ export default defineComponent({ }), ].join('\r\n'); + // Verifica che csvContent non sia vuoto e che abbia un formato valido + if (!csvContent || csvContent.trim() === '') { + console.error('Errore: csvContent è vuoto o malformato'); + return; + } + // Creazione del file XLS dopo il CSV exportToXLS(csvContent, title); } @@ -1403,6 +1428,16 @@ export default defineComponent({ }); } + function addArrayTitlesToList(myarr: IProduct[]) { + console.log('addArrayTitlesToList'); + + for (const elem of myarr) { + addtolist(elem); + } + + showDialogImport.value = false; // chiudi dialog + } + onMounted(mounted); return { @@ -1459,8 +1494,10 @@ export default defineComponent({ isElementVisible, fabexp, showDialogExport, + showDialogImport, selectedExportColumns, allColumnsToExported, + addArrayTitlesToList, }; }, }); diff --git a/src/components/CProductTable/CProductTable.vue b/src/components/CProductTable/CProductTable.vue index 65ad2e00..f24ab67c 100755 --- a/src/components/CProductTable/CProductTable.vue +++ b/src/components/CProductTable/CProductTable.vue @@ -44,9 +44,7 @@ - +
Esporta {{ title }}
@@ -112,14 +110,40 @@
+ + + + +
Importa su {{ title }}
+
+ + + + + +
+
+
diff --git a/src/views/ecommerce/catalogo/catalogo.ts b/src/views/ecommerce/catalogo/catalogo.ts index 072988d0..f4fa21d7 100755 --- a/src/views/ecommerce/catalogo/catalogo.ts +++ b/src/views/ecommerce/catalogo/catalogo.ts @@ -2394,7 +2394,7 @@ export default defineComponent({ } function addProductToList(element: IProduct, where: string) { - // console.log('addProductToList', element) + console.log('addProductToList', element) if (element) { // add this record to lista_prodotti diff --git a/src/views/ecommerce/catalogo/catalogo.vue b/src/views/ecommerce/catalogo/catalogo.vue index f64643e7..5697671e 100755 --- a/src/views/ecommerce/catalogo/catalogo.vue +++ b/src/views/ecommerce/catalogo/catalogo.vue @@ -203,7 +203,7 @@ >-->