- 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",
"@quasar/extras": "^1.16.17",
"@quasar/quasar-ui-qcalendar": "^4.1.2",
"@syncfusion/ej2-vue-pdfviewer": "^29.1.40",
"@types/jsbarcode": "^3.11.4",
"@types/leaflet": "^1.9.17",
"@vue/compat": "^3.5.13",
@@ -52,8 +51,6 @@
"echarts": "5.6.0",
"eslint-plugin-n": "^17.16.2",
"eslint-plugin-quasar": "^1.1.0",
"graphql": "^16.10.0",
"graphql-tag": "^2.12.6",
"gsap": "^3.12.7",
"html2pdf.js": "^0.10.3",
"jquery": "^3.7.1",
@@ -67,7 +64,6 @@
"normalize.css": "^8.0.1",
"nprogress": "^0.2.0",
"pinia": "^3.0.1",
"qrcode-vue3": "^1.7.1",
"quasar": "^2.18.1",
"quasar-extras": "^2.0.9",
"register-service-worker": "^1.7.2",
@@ -80,7 +76,6 @@
"vue-echarts": "^7.0.3",
"vue-i18n": "^11.1.2",
"vue-idb": "^0.2.0",
"vue-image-zoomer": "^2.4.4",
"vue-property-decorator": "^10.0.0-rc.3",
"vue-router": "^4.5.0",
"vue-scroll-reveal": "^2.1.0",
@@ -89,7 +84,6 @@
"vue-timeago3": "^2.3.2",
"vue2-dragula": "^2.5.5",
"vue3-apexcharts": "^1.8.0",
"vue3-pdf-app": "^1.0.3",
"vue3-qr-reader": "^1.0.0",
"vuedraggable": "^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: ['i18n', 'axios', 'pinia', 'vee-validate',
'myconfig',
'local-storage', 'error-handler', 'globalroutines',
'local-storage', 'globalroutines',
'calendar', 'social-sharing', 'timeago', 'guard'],
// 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 VuePdfApp from 'vue3-pdf-app'
// import this to use default icons for buttons
import 'vue3-pdf-app/dist/icons/main.css'
export default defineComponent({
name: 'CCatalogoCard',
@@ -89,7 +85,7 @@ export default defineComponent({
},
},
components: {
CTitleBanner, CCardState, CCopyBtn, CMyValueDb, VuePdfApp, CPrice, CBarCode, CLabel,
CTitleBanner, CCardState, CCopyBtn, CMyValueDb, CPrice, CBarCode, CLabel,
CText, CViewTable, CTableCupleLabelValue, CSchedaProdotto, CModifTrafiletto
},
setup(props, { emit }) {

View File

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

View File

@@ -24,10 +24,6 @@ import { useRouter } from 'vue-router'
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({
name: 'CProductCard',
@@ -55,7 +51,7 @@ export default defineComponent({
},
components: {
CTitleBanner, CCardState, CCopyBtn,
CMyFieldRec, CMyValueDb, VuePdfApp, CBarCode,
CMyFieldRec, CMyValueDb, CBarCode,
},
setup(props, { emit }) {
const $q = useQuasar()

View File

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

View File

@@ -13,8 +13,6 @@ import { useI18n } from 'vue-i18n'
import { toolsext } from '@store/Modules/toolsext'
import { useQuasar } from 'quasar'
import QrcodeVue from 'qrcode-vue3'
import { QrStream, QrCapture, QrDropzone } from 'vue3-qr-reader'
import { useRouter } from 'vue-router'
@@ -45,7 +43,7 @@ export default defineComponent({
},
},
components: {
QrcodeVue, QrStream,
QrStream,
QrCapture,
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_updated?: Date,
lista_prodotti?: IProduct[]
isCatalogoGenerale?: boolean
num_lista_prodotti?: number
lista_prodotti?: IProduct[]
prodotti_caricati_inmem?: boolean
}
export interface IRaccoltaCatalogo {
_id: string
idapp: string

View File

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

View File

@@ -1,41 +1,103 @@
import { defineStore } from 'pinia'
import { defineStore } from 'pinia';
import type {
ICatalogState
} from '@src/model';
import {
IAccount,
ICircuit, ICatalog, IGlobalState, IGroupShort, IMyCircuit, IMyGroup, IUserFields
} from '@src/model'
import { tools } from '@tools'
import translate from '@src/globalroutines/util'
import type { ICatalogState } from '@src/model';
import { 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 { 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 { useProducts } from 'app/src/store/Products';
import { useUserStore } from 'app/src/store/UserStore';
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 { costanti } from '@costanti'
import { shared_consts } from '@src/common/shared_vuejs';
import { costanti } from '@costanti';
import globalroutines from '../globalroutines/index'
import globalroutines from '../globalroutines/index';
export const useCatalogStore = defineStore('CatalogStore', {
state: (): ICatalogState => ({
catalogs: [{ _id: '', idapp: '', title: '' }]
catalogs: [{ _id: '', idapp: '', title: '' }],
}),
getters: {
getCatalogById: (state) => (id: string) => {
return state.catalogs.find((cat: ICatalog) => cat._id === id);
},
getCatalogById: (state) => async (id: string) => {
// 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: {
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,
minBuyQty: 1,
minStepQty: 1,
maxBookableSinglePersQty: 0,
// maxBookableSinglePersQty: 0,
stockQty: 0,
stockBloccatiQty: 0,
bookedQtyOrdered: 0,
bookedQtyConfirmed: 0,
// stockBloccatiQty: 0,
// bookedQtyOrdered: 0,
// bookedQtyConfirmed: 0,
qtyToReachForGas: 0,
// qtyToReachForGas: 0,
maxbookableGASQty: 0,
bookedGASQtyOrdered: 0,
bookedGASQtyConfirmed: 0,
bookableGASBloccatiQty: 0,
// maxbookableGASQty: 0,
// bookedGASQtyOrdered: 0,
// bookedGASQtyConfirmed: 0,
// bookableGASBloccatiQty: 0,
canBeShipped: false,
QuantitaOrdinateInAttesa: 0,
QuantitaPrenotateInAttesa: 0,
canBeBuyOnline: false,
// canBeShipped: false,
// QuantitaOrdinateInAttesa: 0,
// QuantitaPrenotateInAttesa: 0,
// canBeBuyOnline: false,
};
}
@@ -978,19 +978,22 @@ export const useProducts = defineStore('Products', {
return ris;
},
async loadProductById(id: string) {
async loadProductById(id: string, forzacaricamento?: boolean) {
const userStore = useUserStore();
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 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)
.then((res) => {
console.log('product', res.data.product);
@@ -1932,9 +1935,9 @@ export const useProducts = defineStore('Products', {
arr.push({ label: mylabel, value: myelem._id });
}
};
}
return arr
return arr;
},
getOptCatalogoPrintTemplate() {
// 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 });
}
};
}
return arr
return arr;
},
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) {
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() {
console.log('catalogo.ts PADRE');
// console.log('catalogo.ts PADRE');
emit('update:modelValue', optcatalogo.value);
//emit('updateCatalogo', optcatalogo.value);
}
@@ -405,7 +405,7 @@ export default defineComponent({
watch(
() => optcatalogo.value.aggiorna,
(newval, oldval) => {
console.log('Aggiorna array...');
// console.log('Aggiorna array...');
generatearrProdToViewSorted();
}
);
@@ -580,7 +580,7 @@ export default defineComponent({
}
function populateDataWithlinkIdTemplate() {
console.log('populateDataWithlinkIdTemplate')
// console.log('populateDataWithlinkIdTemplate')
if (optcatalogo.value) {
// LINK PAGINA
@@ -830,17 +830,23 @@ export default defineComponent({
})
.sort((a, b) => (getProductsSorted([a, b], sortField, sortDir)[0] === a ? -1 : 1));
console.log(' sortField=' + sortField);
console.log(' sortDir=' + sortDir);
console.log(' Filtro=' + arrargomstr);
console.log(' idCollane=' + idCollane);
console.log('PRODOTTI FILTRATI:', arrris.length);
// console.log(' sortField=' + sortField);
// console.log(' sortDir=' + sortDir);
// console.log(' Filtro=' + arrargomstr);
// console.log(' idCollane=' + idCollane);
// console.log('PRODOTTI FILTRATI:', arrris.length);
return arrris;
}
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;
@@ -872,7 +878,7 @@ export default defineComponent({
// Se nel catalogo è stato già generato, allora gli passo quello.
const trovatocatalogo = getCatalogoByMyPage.value;
if (editore) console.log('FILTRO editore', editore);
// if (editore) console.log('FILTRO editore', editore);
if (showListaFiltrata.value) {
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;
rigeneraLibri.value = false;
@@ -1073,9 +1079,9 @@ export default defineComponent({
function getProductsSorted(arrprod: IProduct[], sort_field: string, sort_dir: number): IProduct[] {
if (sort_field) {
// 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})`);
});
});*/
// Crea una copia dell'array per non modificare l'originale
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
if (sortedArr.length > 0) {
// 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})`);
});
});*/
} else {
console.log('Nessun prodotto trovato.');
// console.log('Nessun prodotto trovato.');
}
return sortedArr;
@@ -1355,7 +1361,12 @@ export default defineComponent({
);
loadpage.value = false;
await productStore.loadProducts(true);
if (showListaFiltrata.value) {
// Carica tutti i prodotti
await productStore.loadProducts(true);
} else {
getCatalogoByMyPage.value.lista_prodotti = await catalogStore.loadProductsOnlyByIdPageCatalog(props.idPage);
}
mycolumns.value = fieldsTable.getArrColsByTable('products');

View File

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