- ottimizzato il caricamento del sito

- ottimizzato il caricamento del catalogo.
This commit is contained in:
Surya Paolo
2025-05-15 18:22:37 +02:00
parent 50015712f5
commit 9e0634da05
17 changed files with 410565 additions and 143 deletions

410386
_LIMBO/dati.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -32,7 +32,6 @@
"@cubejs-client/core": "^1.2.26", "@cubejs-client/core": "^1.2.26",
"@quasar/extras": "^1.16.17", "@quasar/extras": "^1.16.17",
"@quasar/quasar-ui-qcalendar": "^4.1.2", "@quasar/quasar-ui-qcalendar": "^4.1.2",
"@syncfusion/ej2-vue-pdfviewer": "^29.1.40",
"@types/jsbarcode": "^3.11.4", "@types/jsbarcode": "^3.11.4",
"@types/leaflet": "^1.9.17", "@types/leaflet": "^1.9.17",
"@vue/compat": "^3.5.13", "@vue/compat": "^3.5.13",
@@ -52,8 +51,6 @@
"echarts": "5.6.0", "echarts": "5.6.0",
"eslint-plugin-n": "^17.16.2", "eslint-plugin-n": "^17.16.2",
"eslint-plugin-quasar": "^1.1.0", "eslint-plugin-quasar": "^1.1.0",
"graphql": "^16.10.0",
"graphql-tag": "^2.12.6",
"gsap": "^3.12.7", "gsap": "^3.12.7",
"html2pdf.js": "^0.10.3", "html2pdf.js": "^0.10.3",
"jquery": "^3.7.1", "jquery": "^3.7.1",
@@ -67,7 +64,6 @@
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"pinia": "^3.0.1", "pinia": "^3.0.1",
"qrcode-vue3": "^1.7.1",
"quasar": "^2.18.1", "quasar": "^2.18.1",
"quasar-extras": "^2.0.9", "quasar-extras": "^2.0.9",
"register-service-worker": "^1.7.2", "register-service-worker": "^1.7.2",
@@ -80,7 +76,6 @@
"vue-echarts": "^7.0.3", "vue-echarts": "^7.0.3",
"vue-i18n": "^11.1.2", "vue-i18n": "^11.1.2",
"vue-idb": "^0.2.0", "vue-idb": "^0.2.0",
"vue-image-zoomer": "^2.4.4",
"vue-property-decorator": "^10.0.0-rc.3", "vue-property-decorator": "^10.0.0-rc.3",
"vue-router": "^4.5.0", "vue-router": "^4.5.0",
"vue-scroll-reveal": "^2.1.0", "vue-scroll-reveal": "^2.1.0",
@@ -89,7 +84,6 @@
"vue-timeago3": "^2.3.2", "vue-timeago3": "^2.3.2",
"vue2-dragula": "^2.5.5", "vue2-dragula": "^2.5.5",
"vue3-apexcharts": "^1.8.0", "vue3-apexcharts": "^1.8.0",
"vue3-pdf-app": "^1.0.3",
"vue3-qr-reader": "^1.0.0", "vue3-qr-reader": "^1.0.0",
"vuedraggable": "^4.1.0", "vuedraggable": "^4.1.0",
"vuex": "^4.1.0", "vuex": "^4.1.0",

View File

@@ -18,7 +18,7 @@ export default defineConfig((ctx) => {
// boot: ['vue-i18n', 'vue-meta', 'axios', 'vee-validate', 'myconfig', 'local-storage', 'error-handler', 'globalroutines', 'vue-idb', 'dragula', 'guard'], // boot: ['vue-i18n', 'vue-meta', 'axios', 'vee-validate', 'myconfig', 'local-storage', 'error-handler', 'globalroutines', 'vue-idb', 'dragula', 'guard'],
boot: ['i18n', 'axios', 'pinia', 'vee-validate', boot: ['i18n', 'axios', 'pinia', 'vee-validate',
'myconfig', 'myconfig',
'local-storage', 'error-handler', 'globalroutines', 'local-storage', 'globalroutines',
'calendar', 'social-sharing', 'timeago', 'guard'], 'calendar', 'social-sharing', 'timeago', 'guard'],
// https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css // https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css

View File

@@ -1,9 +0,0 @@
import { boot } from 'quasar/wrappers'
// import something here
import errorHandler from '../error-handler'
// leave the export, even if you don't use it
export default boot(({ app, router }) => {
// something to do
app.config.globalProperties.$errorHandler = errorHandler
})

View File

@@ -37,10 +37,6 @@ import { useRouter } from 'vue-router'
import { costanti } from '@costanti' import { costanti } from '@costanti'
import VuePdfApp from 'vue3-pdf-app'
// import this to use default icons for buttons
import 'vue3-pdf-app/dist/icons/main.css'
export default defineComponent({ export default defineComponent({
name: 'CCatalogoCard', name: 'CCatalogoCard',
@@ -89,7 +85,7 @@ export default defineComponent({
}, },
}, },
components: { components: {
CTitleBanner, CCardState, CCopyBtn, CMyValueDb, VuePdfApp, CPrice, CBarCode, CLabel, CTitleBanner, CCardState, CCopyBtn, CMyValueDb, CPrice, CBarCode, CLabel,
CText, CViewTable, CTableCupleLabelValue, CSchedaProdotto, CModifTrafiletto CText, CViewTable, CTableCupleLabelValue, CSchedaProdotto, CModifTrafiletto
}, },
setup(props, { emit }) { setup(props, { emit }) {

View File

@@ -617,10 +617,10 @@
></q-btn> ></q-btn>
</q-toolbar> </q-toolbar>
<q-card-section> <q-card-section>
<vue-pdf-app <!--<vue-pdf-app
:pdf="myproduct.productInfo.link_scheda" :pdf="myproduct.productInfo.link_scheda"
style="height: 100vh" style="height: 100vh"
></vue-pdf-app> ></vue-pdf-app>-->
</q-card-section> </q-card-section>
</q-dialog> </q-dialog>

View File

@@ -24,10 +24,6 @@ import { useRouter } from 'vue-router'
import { costanti } from '@costanti' import { costanti } from '@costanti'
import VuePdfApp from 'vue3-pdf-app'
// import this to use default icons for buttons
import 'vue3-pdf-app/dist/icons/main.css'
export default defineComponent({ export default defineComponent({
name: 'CProductCard', name: 'CProductCard',
@@ -55,7 +51,7 @@ export default defineComponent({
}, },
components: { components: {
CTitleBanner, CCardState, CCopyBtn, CTitleBanner, CCardState, CCopyBtn,
CMyFieldRec, CMyValueDb, VuePdfApp, CBarCode, CMyFieldRec, CMyValueDb, CBarCode,
}, },
setup(props, { emit }) { setup(props, { emit }) {
const $q = useQuasar() const $q = useQuasar()

View File

@@ -1060,10 +1060,10 @@
></q-btn> ></q-btn>
</q-toolbar> </q-toolbar>
<q-card-section> <q-card-section>
<vue-pdf-app <!--<vue-pdf-app
:pdf="myproduct.productInfo.link_scheda" :pdf="myproduct.productInfo.link_scheda"
style="height: 100vh" style="height: 100vh"
></vue-pdf-app> ></vue-pdf-app>-->
</q-card-section> </q-card-section>
</q-dialog> </q-dialog>

View File

@@ -13,8 +13,6 @@ import { useI18n } from 'vue-i18n'
import { toolsext } from '@store/Modules/toolsext' import { toolsext } from '@store/Modules/toolsext'
import { useQuasar } from 'quasar' import { useQuasar } from 'quasar'
import QrcodeVue from 'qrcode-vue3'
import { QrStream, QrCapture, QrDropzone } from 'vue3-qr-reader' import { QrStream, QrCapture, QrDropzone } from 'vue3-qr-reader'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
@@ -45,7 +43,7 @@ export default defineComponent({
}, },
}, },
components: { components: {
QrcodeVue, QrStream, QrStream,
QrCapture, QrCapture,
QrDropzone QrDropzone
}, },

View File

@@ -1,21 +0,0 @@
// import Backend from './backend'
// import Firebase from './firebase'
import Graphql from './graphql'
export default (context: any, error: any) => {
/*
if (error.constructor.nametranslate === 'FirebaseError') {
Firebase(error)
return
}
if (error.response && error.response.data && error.response.data.backend) {
Backend(error)
return
} */
if (error[0] && error[0].locations && error[0].validation) {
Graphql(error)
return
}
console.log('Error handler', error)
}

View File

@@ -38,10 +38,15 @@ export interface ICatalog {
date_created?: Date, date_created?: Date,
date_updated?: Date, date_updated?: Date,
lista_prodotti?: IProduct[]
isCatalogoGenerale?: boolean isCatalogoGenerale?: boolean
num_lista_prodotti?: number
lista_prodotti?: IProduct[]
prodotti_caricati_inmem?: boolean
} }
export interface IRaccoltaCatalogo { export interface IRaccoltaCatalogo {
_id: string _id: string
idapp: string idapp: string

View File

@@ -141,20 +141,20 @@ export interface IProduct {
note?: string note?: string
arrvariazioni?: IVariazione[] arrvariazioni?: IVariazione[]
stockQty: number, // UPDATING stockQty?: number, // UPDATING
stockBloccatiQty: number, // UPDATING stockBloccatiQty?: number, // UPDATING
bookedQtyOrdered: number // UPDATING bookedQtyOrdered?: number // UPDATING
bookedQtyConfirmed: number // UPDATING bookedQtyConfirmed?: number // UPDATING
qtyToReachForGas: number qtyToReachForGas?: number
maxbookableGASQty: number maxbookableGASQty?: number
bookedGASQtyOrdered: number // UPDATING bookedGASQtyOrdered?: number // UPDATING
bookedGASQtyConfirmed: number // UPDATING bookedGASQtyConfirmed?: number // UPDATING
bookableGASBloccatiQty: number // UPDATING bookableGASBloccatiQty?: number // UPDATING
minBuyQty: number minBuyQty?: number
minStepQty: number minStepQty?: number
maxBookableSinglePersQty: number maxBookableSinglePersQty?: number
canBeShipped?: boolean canBeShipped?: boolean
canBeBuyOnline?: boolean canBeBuyOnline?: boolean
} }

View File

@@ -1,41 +1,103 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia';
import type { import type { ICatalogState } from '@src/model';
ICatalogState import { IAccount, ICircuit, ICatalog, IGlobalState, IGroupShort, IMyCircuit, IMyGroup, IUserFields } from '@src/model';
} from '@src/model'; import { tools } from '@tools';
import { import translate from '@src/globalroutines/util';
IAccount,
ICircuit, ICatalog, IGlobalState, IGroupShort, IMyCircuit, IMyGroup, IUserFields
} from '@src/model'
import { tools } from '@tools'
import translate from '@src/globalroutines/util'
import * as Types from '@src/store/Api/ApiTypes' import { useProducts } from 'app/src/store/Products';
import { useGlobalStore } from '@store/globalStore' import { useUserStore } from 'app/src/store/UserStore';
import { serv_constants } from '@store/Modules/serv_constants'
import { Api } from '@api'
import { toolsext } from '@store/Modules/toolsext'
import { static_data } from '@src/db/static_data'
import * as Types from '@src/store/Api/ApiTypes';
import { useGlobalStore } from '@store/globalStore';
import { serv_constants } from '@store/Modules/serv_constants';
import { Api } from '@api';
import { toolsext } from '@store/Modules/toolsext';
import { static_data } from '@src/db/static_data';
import { shared_consts } from '@src/common/shared_vuejs' import { shared_consts } from '@src/common/shared_vuejs';
import { costanti } from '@costanti' import { costanti } from '@costanti';
import globalroutines from '../globalroutines/index' import globalroutines from '../globalroutines/index';
export const useCatalogStore = defineStore('CatalogStore', { export const useCatalogStore = defineStore('CatalogStore', {
state: (): ICatalogState => ({ state: (): ICatalogState => ({
catalogs: [{ _id: '', idapp: '', title: '' }] catalogs: [{ _id: '', idapp: '', title: '' }],
}), }),
getters: { getters: {
getCatalogById: (state) => (id: string) => { getCatalogById: (state) => async (id: string) => {
return state.catalogs.find((cat: ICatalog) => cat._id === id); // carica in memoria il catalogo singolo
},
// se non lo trovo, allora lo carica dal server
let cat = state.catalogs.find((cat: ICatalog) => cat._id === id);
if ((cat && !cat.prodotti_caricati_inmem) || !cat) {
// Lo carica dal server
cat = await this.loadCatalogById(id);
}
return cat;
},
}, },
actions: { actions: {
async loadCatalogById(id: string) {
const userStore = useUserStore();
const globalStore = useGlobalStore();
}, let ris = null;
ris = await Api.SendReq('/catalogs/id/' + id, 'GET', null)
.then((res) => {
console.log('catalogs', res.data.catalog);
if (res.data.catalog) {
// console.log('RISULTANTE CATEGORIES DAL SERVER = ', res.data.categories)
this.updateDataCatalog(res);
return res.data.product;
} else {
return null;
}
}) })
.catch((error) => {
console.log('error loadCatalogById', error);
userStore.setErrorCatch(error);
return new Types.AxiosError(serv_constants.RIS_CODE_ERR, null, toolsext.ERR_GENERICO, error);
});
return ris;
},
async loadProductsOnlyByIdPageCatalog(idPage: string, forzacaricamento: boolean = false) {
// controlla se è stata già caricata in memoria
const productStore = useProducts();
const reccat = this.catalogs.find((cat: ICatalog) => cat.idPageAssigned === idPage);
if (reccat) {
const mycat = await this.loadCatalogById(reccat._id);
if (mycat) {
// Aggiorna la lista products con questo array del server "reccat.lista_prodotti"
productStore.updateProductsByArray(mycat.lista_prodotti);
}
return reccat.lista_prodotti;
} else {
return [];
}
},
updateDataCatalog(res: any) {
if (res && res.data.catalog) {
// Update catalog from server
const indelem = this.catalogs.findIndex((catalog: ICatalogCompleto) => catalog._id === res.data.catalog._id);
if (indelem >= 0) {
this.catalogs[indelem] = { ...res.data.catalog };
this.catalogs[indelem].prodotti_caricati_inmem = true;
}
}
},
},
});

View File

@@ -108,24 +108,24 @@ function getRecordProductEmpty(): IProduct {
bookableAvailableQty: 0, bookableAvailableQty: 0,
minBuyQty: 1, minBuyQty: 1,
minStepQty: 1, minStepQty: 1,
maxBookableSinglePersQty: 0, // maxBookableSinglePersQty: 0,
stockQty: 0, stockQty: 0,
stockBloccatiQty: 0, // stockBloccatiQty: 0,
bookedQtyOrdered: 0, // bookedQtyOrdered: 0,
bookedQtyConfirmed: 0, // bookedQtyConfirmed: 0,
qtyToReachForGas: 0, // qtyToReachForGas: 0,
maxbookableGASQty: 0, // maxbookableGASQty: 0,
bookedGASQtyOrdered: 0, // bookedGASQtyOrdered: 0,
bookedGASQtyConfirmed: 0, // bookedGASQtyConfirmed: 0,
bookableGASBloccatiQty: 0, // bookableGASBloccatiQty: 0,
canBeShipped: false, // canBeShipped: false,
QuantitaOrdinateInAttesa: 0, // QuantitaOrdinateInAttesa: 0,
QuantitaPrenotateInAttesa: 0, // QuantitaPrenotateInAttesa: 0,
canBeBuyOnline: false, // canBeBuyOnline: false,
}; };
} }
@@ -978,19 +978,22 @@ export const useProducts = defineStore('Products', {
return ris; return ris;
}, },
async loadProductById(id: string) { async loadProductById(id: string, forzacaricamento?: boolean) {
const userStore = useUserStore(); const userStore = useUserStore();
const globalStore = useGlobalStore(); const globalStore = useGlobalStore();
//if (!globalStore.site.confpages.enableEcommerce)
// return null
// if (this.userActive._id === '') {
// return new Types.AxiosError(0, null, 0, '')
// }
let ris = null; let ris = null;
let myprod = null;
if (this.products && !forzacaricamento) {
// cerca su this.products
myprod = this.products.find((prod: IProduct) => prod._id === id);
if (myprod) {
return myprod
}
}
ris = await Api.SendReq('/products/id/' + id, 'GET', null) ris = await Api.SendReq('/products/id/' + id, 'GET', null)
.then((res) => { .then((res) => {
console.log('product', res.data.product); console.log('product', res.data.product);
@@ -1932,9 +1935,9 @@ export const useProducts = defineStore('Products', {
arr.push({ label: mylabel, value: myelem._id }); arr.push({ label: mylabel, value: myelem._id });
} }
}; }
return arr return arr;
}, },
getOptCatalogoPrintTemplate() { getOptCatalogoPrintTemplate() {
// Ottieni l'array delle pagine che in cataloghi sono dimensioni_def.isTemplate // Ottieni l'array delle pagine che in cataloghi sono dimensioni_def.isTemplate
@@ -1958,9 +1961,9 @@ export const useProducts = defineStore('Products', {
arr.push({ label: mylabel, value: myelem._id }); arr.push({ label: mylabel, value: myelem._id });
} }
}; }
return arr return arr;
}, },
getSchedeOpt(arrschede: ISchedaSingola[], tag?: string): any[] { getSchedeOpt(arrschede: ISchedaSingola[], tag?: string): any[] {
@@ -2159,6 +2162,14 @@ export const useProducts = defineStore('Products', {
}); });
}, },
updateProductsByArray: (state: IProductsState) => (arrrec: IProduct[]) => {
if (arrrec && arrrec.length > 0) {
// update products array from this array
const myarr = state.products.filter((rec) => !arrrec.find((newrec) => newrec._id === rec._id));
state.products = myarr.concat(arrrec);
}
},
getPathByPage(idpag: string) { getPathByPage(idpag: string) {
let linkpage = ''; let linkpage = '';

View File

@@ -1,7 +0,0 @@
import { errorHandler } from '../../error-handler'
declare module 'vue/types/vue' {
interface Vue {
$errorHandler: errorHandler
}
}

View File

@@ -154,7 +154,7 @@ export default defineComponent({
}; };
function updateCatalogoPadre() { function updateCatalogoPadre() {
console.log('catalogo.ts PADRE'); // console.log('catalogo.ts PADRE');
emit('update:modelValue', optcatalogo.value); emit('update:modelValue', optcatalogo.value);
//emit('updateCatalogo', optcatalogo.value); //emit('updateCatalogo', optcatalogo.value);
} }
@@ -405,7 +405,7 @@ export default defineComponent({
watch( watch(
() => optcatalogo.value.aggiorna, () => optcatalogo.value.aggiorna,
(newval, oldval) => { (newval, oldval) => {
console.log('Aggiorna array...'); // console.log('Aggiorna array...');
generatearrProdToViewSorted(); generatearrProdToViewSorted();
} }
); );
@@ -580,7 +580,7 @@ export default defineComponent({
} }
function populateDataWithlinkIdTemplate() { function populateDataWithlinkIdTemplate() {
console.log('populateDataWithlinkIdTemplate') // console.log('populateDataWithlinkIdTemplate')
if (optcatalogo.value) { if (optcatalogo.value) {
// LINK PAGINA // LINK PAGINA
@@ -830,17 +830,23 @@ export default defineComponent({
}) })
.sort((a, b) => (getProductsSorted([a, b], sortField, sortDir)[0] === a ? -1 : 1)); .sort((a, b) => (getProductsSorted([a, b], sortField, sortDir)[0] === a ? -1 : 1));
console.log(' sortField=' + sortField); // console.log(' sortField=' + sortField);
console.log(' sortDir=' + sortDir); // console.log(' sortDir=' + sortDir);
console.log(' Filtro=' + arrargomstr); // console.log(' Filtro=' + arrargomstr);
console.log(' idCollane=' + idCollane); // console.log(' idCollane=' + idCollane);
console.log('PRODOTTI FILTRATI:', arrris.length); // console.log('PRODOTTI FILTRATI:', arrris.length);
return arrris; return arrris;
} }
async function calcArrProducts(generalista?: boolean) { async function calcArrProducts(generalista?: boolean) {
console.log('calcArrProducts (generalista=' + generalista + ')'); // console.log('calcArrProducts (generalista=' + generalista + ')');
if (generalista) {
// Devono esistere tutti i prodotti
await productStore.loadProducts(true);
}
if (!loadpage.value) return; if (!loadpage.value) return;
@@ -872,7 +878,7 @@ export default defineComponent({
// Se nel catalogo è stato già generato, allora gli passo quello. // Se nel catalogo è stato già generato, allora gli passo quello.
const trovatocatalogo = getCatalogoByMyPage.value; const trovatocatalogo = getCatalogoByMyPage.value;
if (editore) console.log('FILTRO editore', editore); // if (editore) console.log('FILTRO editore', editore);
if (showListaFiltrata.value) { if (showListaFiltrata.value) {
generalista = true; generalista = true;
@@ -933,9 +939,9 @@ export default defineComponent({
} }
} }
console.log('***** FINE calcArrPROD'); // console.log('***** FINE calcArrPROD');
console.log('areadistampa FINITO...', optcatalogo.value.areadistampa) // console.log('areadistampa FINITO...', optcatalogo.value.areadistampa)
generatinglist.value = false; generatinglist.value = false;
rigeneraLibri.value = false; rigeneraLibri.value = false;
@@ -1073,9 +1079,9 @@ export default defineComponent({
function getProductsSorted(arrprod: IProduct[], sort_field: string, sort_dir: number): IProduct[] { function getProductsSorted(arrprod: IProduct[], sort_field: string, sort_dir: number): IProduct[] {
if (sort_field) { if (sort_field) {
// console.log('--- Primi 10 elementi INIZIALI:'); // console.log('--- Primi 10 elementi INIZIALI:');
arrprod.slice(0, 15).forEach((product, index) => { /*arrprod.slice(0, 15).forEach((product, index) => {
console.log(`${index + 1}. ${product.productInfo?.name} (${product.productInfo?.date_pub})`); console.log(`${index + 1}. ${product.productInfo?.name} (${product.productInfo?.date_pub})`);
}); });*/
// Crea una copia dell'array per non modificare l'originale // Crea una copia dell'array per non modificare l'originale
const sortedArr = [...arrprod].sort((a: IProduct, b: IProduct) => { const sortedArr = [...arrprod].sort((a: IProduct, b: IProduct) => {
@@ -1101,11 +1107,11 @@ export default defineComponent({
// logga i primi N elementi, mostrando il nome del prodotto (productInfo.name e la data di pibblicazione : productinfo.date_pub // logga i primi N elementi, mostrando il nome del prodotto (productInfo.name e la data di pibblicazione : productinfo.date_pub
if (sortedArr.length > 0) { if (sortedArr.length > 0) {
// console.log('Primi 15 elementi ordinati: ***** '); // console.log('Primi 15 elementi ordinati: ***** ');
sortedArr.slice(0, 15).forEach((product, index) => { /*sortedArr.slice(0, 15).forEach((product, index) => {
console.log(`${index + 1}. ${product.productInfo?.name} (${product.productInfo?.date_pub})`); console.log(`${index + 1}. ${product.productInfo?.name} (${product.productInfo?.date_pub})`);
}); });*/
} else { } else {
console.log('Nessun prodotto trovato.'); // console.log('Nessun prodotto trovato.');
} }
return sortedArr; return sortedArr;
@@ -1355,7 +1361,12 @@ export default defineComponent({
); );
loadpage.value = false; loadpage.value = false;
if (showListaFiltrata.value) {
// Carica tutti i prodotti
await productStore.loadProducts(true); await productStore.loadProducts(true);
} else {
getCatalogoByMyPage.value.lista_prodotti = await catalogStore.loadProductsOnlyByIdPageCatalog(props.idPage);
}
mycolumns.value = fieldsTable.getArrColsByTable('products'); mycolumns.value = fieldsTable.getArrColsByTable('products');

View File

@@ -1070,7 +1070,7 @@
@close="addnewProd = false" @close="addnewProd = false"
nameLinkTemplate="SEARCH_Prima" nameLinkTemplate="SEARCH_Prima"
:empty="true" :empty="true"
table="catalogs" table="products"
> >
</CSearchProduct> </CSearchProduct>
</CMyDialog> </CMyDialog>