import { defineComponent, onMounted, ref, watch, computed, onBeforeUnmount } from 'vue' import { tools } from '@store/Modules/tools' import { useUserStore } from '@store/UserStore' import { useRouter } from 'vue-router' import { useGlobalStore } from '@store/globalStore' import { useProducts } from '@store/Products' import { useI18n } from '@/boot/i18n' import { toolsext } from '@store/Modules/toolsext' import { useQuasar } from 'quasar' import { costanti } from '@costanti' import { shared_consts } from '@/common/shared_vuejs' import { CProductCard } from '@src/components/CProductCard' import { CMySelect } from '@src/components/CMySelect' import { CCatalogoCard } from '@src/components/CCatalogoCard' import { CSelectUserActive } from '@src/components/CSelectUserActive' import { IProduct, ISearchList } from 'model' import { fieldsTable } from '@store/Modules/fieldsTable' export default defineComponent({ name: 'Catalogo', components: { CCatalogoCard, CProductCard, CSelectUserActive, CMySelect }, props: {}, setup() { const userStore = useUserStore() const globalStore = useGlobalStore() const productStore = useProducts() const router = useRouter() const $q = useQuasar() const { t } = useI18n() const search = ref('') const optauthors = ref([]) const filter = ref({ author: '', publisher: '', type: '', ageGroup: '' }) const cosa = ref(0) const cat = ref('') const idGasSel = ref('') const loadpage = ref(false) const refreshpage = ref(false) const show_hide = ref(false) const mycolumns = ref([]) const searchList = ref([] as ISearchList[]) const arrProducts = ref([]) const numRecLoaded = ref(0) // Create a ref for the component to fix const componentToFixRef = ref(null); const isFixed = ref(false); const labelcombo = computed(() => (item: any) => { let lab = item.label if (item.showcount) lab += ' (' + valoriopt.value(item, false, false).length + ')' return lab }) const arrLoaded = computed(() => { if (arrProducts.value && numRecLoaded.value) return arrProducts.value.slice(0, numRecLoaded.value) else { return [] } }) // Register the scroll event on component mount const handleScroll = () => { const scrollTop = window.scrollY || document.documentElement.scrollTop; // Set a threshold value based on how much scroll is needed to fix the components const threshold = 300; // Update the isFixed ref based on the scroll position isFixed.value = scrollTop > threshold; }; watch(() => cat.value, (newval, oldval) => { calcArrProducts() }) watch(() => idGasSel.value, (newval, oldval) => { calcArrProducts() }) watch(() => search.value, (newval, oldval) => { calcArrProducts() if (tools.scrollTop() > 300) { tools.scrollToTopValue(300) } }) watch(() => filter.value.author, (newval, oldval) => { calcArrProducts() if (tools.scrollTop() > 300) { tools.scrollToTopValue(300) } }) watch(() => cosa.value, (newval, oldval) => { tools.setCookie(tools.COOK_COSA_PRODOTTI, cosa.value.toString()) if (cosa.value !== shared_consts.PROD.TUTTI) cat.value = '' calcArrProducts() }) function calcArrProducts() { // console.log('calcArrProducts') refreshpage.value = true let arrprod = productStore.getProducts(cosa.value) || []; let catstr = cat.value || ''; let filtroAuthor = filter.value.author || ''; let gasselstr = '' if (cosa.value === shared_consts.PROD.GAS) { gasselstr = idGasSel.value || ''; } let lowerSearchText = (search.value || '').toLowerCase().trim(); lowerSearchText = lowerSearchText.replace(/[-@:=]/g, ''); if ((!lowerSearchText || (lowerSearchText && lowerSearchText.length < 2)) && !catstr && !filtroAuthor && (!gasselstr && (cosa.value !== shared_consts.PROD.GAS))) { } else { arrprod = arrprod.filter((product: IProduct) => { if (product && product.productInfo) { let lowerName = (product.productInfo.name || '').toLowerCase(); let hasCategoria = !catstr || (catstr && (product.productInfo.idCatProds || []).includes(catstr)); let hasAuthor = !filtroAuthor || (filtroAuthor && (product.productInfo.idAuthors || []).includes(filtroAuthor)); let productgassel = true if (gasselstr || (cosa.value === shared_consts.PROD.GAS)) { productgassel = (product.idGasordine === gasselstr) } // Use a regular expression to match whole words let codeMatch = new RegExp(`\\b${lowerSearchText}\\b`, 'i'); // let nameMatch = new RegExp(`\\b(?=.*\\b${lowerSearchText.split(/\s+/).map(word => `(${word})\\b`).join('.*\\b')}\\b)`, 'i'); // Check if all words in lowerSearchText are present in lowerName let allWordsPresent = lowerSearchText.split(/\s+/).every(word => new RegExp(`\\b${word}\\b`, 'i').test(lowerName)); return (codeMatch.test(product.productInfo.code || '') || allWordsPresent) && hasCategoria && hasAuthor && productgassel; } else { console.error('product or product.productInfo is null'); return false; } }); } arrProducts.value = arrprod loaddata() refreshpage.value = false } /*function getProducts() { let arrprod = productStore.getProducts(cosa.value) if (!search.value) { return arrprod } let lowerSearchText = search.value.toLowerCase(); let catstr = cat.value; return arrprod.filter((product: IProduct) => { let lowerName = product.productInfo.name!.toLowerCase(); const hasCategoria = !catstr || (catstr && product.productInfo.idCatProds?.includes(catstr)); return (product.productInfo.code!.includes(search.value) || lowerName.includes(lowerSearchText)) && hasCategoria }); }*/ async function mounted() { loadpage.value = false await productStore.loadProducts() mycolumns.value = fieldsTable.getArrColsByTable('products') searchList.value = [ { label: 'Ricerca', table: 'products', key: 'titolo', type: costanti.FieldType.select_by_server, value: '', addall: true, arrvalue: [], useinput: true, filter: null, tablesel: 'products', }, ] optauthors.value = productStore.getAuthors() cosa.value = tools.getCookie(tools.COOK_COSA_PRODOTTI, shared_consts.PROD.GAS, true) if (cosa.value === shared_consts.PROD.TUTTI) cosa.value = shared_consts.PROD.GAS // Inizializza loadpage.value = true window.addEventListener('scroll', handleScroll); calcArrProducts() loaddata() } function loaddata() { numRecLoaded.value = 20 } // Remove the event listener on component destroy onBeforeUnmount(() => { window.removeEventListener('scroll', handleScroll); }); function getCatProds() { let arrcat = productStore.getCatProds(cosa.value) let riscat: any = [{ label: 'Tutti', value: '', icon: undefined, color: undefined }] for (const rec of arrcat) { riscat.push({ label: rec.name, value: rec._id, icon: rec.icon, color: rec.color }) } return riscat } function onLoadScroll(index: number, done: any) { if (index >= 1) { if (numRecLoaded.value < arrProducts.value.length) { const step = 10 let mynrec = numRecLoaded.value + step if (mynrec > arrProducts.value.length) mynrec = arrProducts.value.length numRecLoaded.value = mynrec } done() } else { done(true) } } function filterFn(val: any, update: any, abort: any) { update(() => { const needle = val.toLowerCase(); optauthors.value = productStore.getAuthors().filter(v => { const authorName = v.label.toLowerCase(); const wordsToSearch = needle.split(' '); return wordsToSearch.every((word: any) => { if (word.length > 1) { return authorName.includes(word); } else { return authorName.split(' ').some((namePart: any) => namePart.startsWith(word)); } }); }); }); } function selauthor(id: string, value: string) { filter.value.author = id } function searchval(newval: any, table: any, tablesel: any) { console.log('REFRR searchval', newval, table, 'tablesel', tablesel) if (newval === '') { search.value = '' } else { search.value = newval.name } } const valoriopt = computed(() => (item: any, addall: boolean, addnone: boolean) => { // console.log('valoriopt', item.table) return globalStore.getTableJoinByName(item.table, addall, addnone, item.filter) }) onMounted(mounted) return { userStore, costanti, tools, toolsext, search, cosa, shared_consts, getCatProds, cat, idGasSel, productStore, t, loadpage, refreshpage, componentToFixRef, isFixed, arrProducts, show_hide, onLoadScroll, numRecLoaded, arrLoaded, filter, optauthors, filterFn, selauthor, searchList, fieldsTable, searchval, valoriopt, labelcombo, mycolumns, } } })