import { PropType, computed, defineComponent, onMounted, ref, watch, reactive, } from 'vue'; import draggable from 'vuedraggable'; import { tools } from '@tools'; import { useQuasar } from 'quasar'; import { useRouter } from 'vue-router'; import { useGlobalStore } from '@src/store/globalStore'; import { useProducts } from '@src/store/Products'; import { useUserStore } from '@src/store/UserStore'; import { CMyValueDb } from '@src/components/CMyValueDb'; 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'; import type { IMyScheda, IOptCatalogo, IOrderCart, IProduct } from '@src/model'; import { shared_consts } from 'app/src/common/shared_vuejs'; import { CViewTable } from '../CViewTable'; import { CLabel } from '../CLabel'; import { useI18n } from 'vue-i18n'; import * as XLSX from 'xlsx'; export default defineComponent({ name: 'CProductTable', emits: ['update:lista_prodotti', 'update:optcatalogo', 'rigenera', 'addtolist'], components: { draggable, CSearchProduct, CMyDialog, CMyValueDb, CViewTable, 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, default: [], }, table: { type: String, required: true, }, idcatalog: { type: String, required: false, default: '', }, optcatalogo: { type: Object as PropType, required: false, default: null, }, scheda: { type: Object as PropType, required: false, default: () => ({}), }, options: { type: Object, required: false, default: () => ({}), }, title: { type: String, required: false, default: 'Lista', }, }, setup(props, { emit }) { // Copia locale della lista_prodotti per manipolazione interna const internalProducts = ref([...(props.lista_prodotti || [])]); const $router = useRouter(); const { t } = useI18n(); const $q = useQuasar(); const searchText = ref(''); const fabexp = ref(''); const arrordersCart = ref([]); const globalStore = useGlobalStore(); const ProductStore = useProducts(); const userStore = useUserStore(); const showProd = ref(false); const selProd = ref(null); const cmd = ref(shared_consts.SCHEDA_PRODOTTO.CMD_NONE); const showQtaDisponibile = ref(false); const loading = ref(true); const visufromgm = ref(false); const updatefromgm = ref(false); const field_updated_fromGM = ref(''); const modifOn = ref(false); const modifTrafiletto = ref(false); const sortAttribute = ref(''); const sortDirection = ref(1); const addstr = ref(''); const showDialogExport = ref(false); const showDialogImport = ref(false); const selectedExportColumns = ref([]); const optionscatalogo = ref({ maxlength: 0 }); function handleUpdate(newList) { internalProducts.value = newList; riaggiornaListaProdAlGenitore(); } function riaggiornaListaProdAlGenitore() { aggiornaLista(false); } const editOn = computed({ get(): boolean { return globalStore.editOn ? globalStore.editOn : false; }, set(value: boolean) { return tools.updateEditOn(value); }, }); // Aggiorna la copia locale quando il prop cambia watch( () => props.lista_prodotti, (newVal) => { internalProducts.value = [...newVal]; internalProducts.value.forEach((p: IProduct) => { p.myorder = ProductStore.createMyOrder(); }); } ), { deep: true }; watch( () => searchText.value, () => { searchProducts(); } ); const allColumns = ref([]); const isVisibleEditBtn = ref(false); // Colonne della tabella const allColumns_Raccolta = ref([ { name: 'pos', label: 'Ind', field: 'pos', align: 'left', style: 'width: 50px', notsortable: true, }, { name: 'edit', label: 'Mod', field: '', align: 'left', style: 'width: 50px', edit: true, noexp: true, notsortable: true, visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'drag', label: 'Ord', field: '', align: 'left', style: 'width: 50px', edit: true, noexp: true, notsortable: true, visu: costanti.VISUCAMPI.PER_LOGGATI, }, { name: 'image', label: 'Foto', field: 'image', align: 'center', noexp: true, notsortable: true, }, { name: 'title', label: 'Titolo', field: 'title', align: 'left' }, { name: 'pdf_generato', label: 'Generato', field: 'pdf_generato', align: 'center', }, { name: 'data_generato', label: 'Data Generato', field: 'data_generato', align: 'center', }, { name: 'pdf_generato_stampa', label: 'Generato Stampa', field: 'pdf_generato_stampa', align: 'center', }, { name: 'data_generato_stampa', label: 'Data Generato Stampa', field: 'data_generato_stampa', align: 'center', }, { name: 'pdf_online', label: 'PDF OnLine', field: 'pdf_online', align: 'center', }, { name: 'pdf_online_size', label: 'Size', field: 'pdf_online_size', align: 'center', }, { name: 'data_online', label: 'Data Online', field: 'data_online', align: 'center', }, { name: 'pdf_online_stampa', label: 'PDF OnLine Stampa', field: 'pdf_online_stampa', align: 'center', }, { name: 'pdf_online_stampa_size', label: 'Size', field: 'pdf_online_stampa_size', align: 'center', }, { name: 'data_online_stampa', label: 'Data Online Stampa', field: 'data_online_stampa', align: 'center', }, { name: 'actions', label: 'Azioni', field: '', align: 'center', visu: costanti.VISUCAMPI.PER_EDITORE, noexp: true, notsortable: true, }, ]); const allColumns_Catalog = ref([ { name: 'pos', label: 'Ind', field: 'pos', align: 'left', style: 'width: 50px', notsortable: true, }, { name: 'addtolist', label: 'Add', field: 'addtolist', align: 'center', noexp: true, notsortable: true, visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'edit', label: 'Mod', field: '', align: 'left', style: 'width: 50px', edit: true, noexp: true, notsortable: true, visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'drag', label: 'Ord', field: '', align: 'left', style: 'width: 50px', edit: true, noexp: true, notsortable: true, visu: costanti.VISUCAMPI.PER_LOGGATI, }, { name: 'validato', label: 'Val', field: 'validato', align: 'left', style: '', noexp: true, visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'scraped', label: 'Estratto', field: 'scraped', align: 'left', style: '', noexp: true, visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'scraped_error', label: 'Err estrazione', field: 'scraped_error', align: 'left', style: '', noexp: true, visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'image', label: 'Foto', field: 'image', align: 'center', noexp: true, notsortable: true, }, { name: 'addtocart', label: 'Carrello', field: 'addtocart', align: 'center', noexp: true, notsortable: true, visu: costanti.VISUCAMPI.PER_LOGGATI, }, { name: 'name', label: 'Titolo', field: 'name', align: 'left' }, { name: 'sottotitolo', label: 'Sottotitolo', field: 'sottotitolo', align: 'left', }, { name: 'authors', label: 'Autore', field: 'authors', align: 'left' }, { name: 'isbn', label: 'ISBN', field: 'isbn', align: 'left' }, { name: 'trafiletto', label: 'Sinossi', field: 'trafiletto', align: 'left', visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'catprods', label: 'Argomento', field: 'catprods', align: 'left', }, { name: 'edizione', label: 'Edizione', field: 'edizione', align: 'left' }, { name: 'casaeditrice', label: 'Casa Editrice', field: 'casaeditrice', align: 'left', }, { name: 'idCollana', label: 'Collana', field: 'idCollana', align: 'left', }, { name: 'stato', label: 'Stato', field: 'stato', align: 'left' }, { name: 'tipologia', label: 'Tipologia', field: 'tipologia', align: 'left', }, { name: 'tipoformato', label: 'Formato', field: 'tipoformato', align: 'left', }, { name: 'pagine', label: 'Pag.', field: 'pagine', align: 'right' }, { name: 'prezzo', label: 'Prezzo Intero', field: 'prezzo', align: 'right' }, /*{ name: 'prezzo_sconto', label: '€ (sconto)', field: 'prezzo_sconto', align: 'right', },*/ { name: 'date_pub', label: 'Pubblicato', field: 'date_pub', align: 'left', }, //{ name: "ranking", label: "Class.", field: "ranking", align: "right" }, //{ name: "rank3M", label: "Class. 3M", field: "rank3M", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE }, //{ name: "rank6M", label: "Class. 6M", field: "rank6M", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE }, //{ name: "rank1Y", label: "Class. 1Y", field: "rank1Y", align: "right", visu: costanti.VISUCAMPI.PER_EDITORE }, { name: 'totVen', label: 'Vend', field: 'totVen', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'vLast6M', label: 'Ven 6M', field: 'vLast6M', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'fatLast6M', label: 'Fat 6M', field: 'fatLast6M', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'fatLast1Y', label: 'Fat 1A', field: 'fatLast1Y', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'fatLast2Y', label: 'Fat 2A', field: 'fatLast2Y', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'totFat', label: 'Fat 5A', field: 'totFat', align: 'right', visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'ult_ord', label: 'Ult. Ordine', field: 'ult_ord', align: 'left', visu: costanti.VISUCAMPI.PER_EDITORE, }, { name: 'quantity', label: 'Disponib.', field: 'quantity', align: 'right', }, { name: 'actions', label: 'Azioni', field: '', align: 'center', visu: costanti.VISUCAMPI.PER_EDITORE, noexp: true, notsortable: true, }, ]); const allColumnsComputed = computed(() => { return allColumns.value.filter( (col) => !col.visu || col.visu === costanti.VISUCAMPI.PER_TUTTI || (col.visu === costanti.VISUCAMPI.PER_EDITORE && tools.isCollaboratore()) || (col.visu === costanti.VISUCAMPI.PER_LOGGATI && tools.isLogged()) ); }); const allColumnsToExported = computed(() => { return allColumnsComputed.value.filter((col) => !col.noexp); }); async function mounted() { //myorder = ProductStore.createMyOrder() // ProductStore.initproduct(myorder); internalProducts.value.forEach((p: IProduct) => { p.myorder = ProductStore.createMyOrder(); }); // console.log('mounted CProductTable'); loading.value = true; if (props.table === shared_consts.TABLES_CATALOG) { selectedColumns.value = selectedColumns_Catalogs.value; } else { // "ProductStore" selectedColumns.value = tools.isUtente() ? selectedColumns_Utenti.value : selectedColumns_Editori.value; } addstr.value = tools.addstrCookie(props.table); if (props.table === shared_consts.TABLES_PRODUCTS) { allColumns.value = allColumns_Catalog.value; isVisibleEditBtn.value = true; } else if (props.table === shared_consts.TABLES_CATALOG) { allColumns.value = allColumns_Raccolta.value; isVisibleEditBtn.value = false; } optionscatalogo.value = { maxlength: props.scheda?.testo_bottom?.maxlength, }; const savedColumns = tools.getCookie(addstr.value + 'selColCat_2'); const col = tools.getCookie(addstr.value + 'Exp_Columns', null); selectedExportColumns.value = col ? col : []; if (savedColumns) { selectedColumns.value = savedColumns; } const savedSortAttribute = tools.getCookie(addstr.value + 'sortAttr'); if (savedSortAttribute && props.optcatalogo.showListaArgomenti) { if (isColumnVisible(savedSortAttribute)) { sortAttribute.value = savedSortAttribute; const savedSortDir = tools.getCookie(addstr.value + 'sortDir'); if (savedSortDir) { sortDirection.value = savedSortDir; } } } loading.value = false; } function getFieldValue(element: any, field: any, colexport: boolean = false): any { if (!element) return ''; try { if (props.table === shared_consts.TABLES_CATALOG) { const catalog = element; switch (field.field) { case 'active': return catalog.active; case 'title': return catalog.title; case 'pdf_generato': return catalog.pdf_generato ? `PDF` : ''; case 'pdf_generato_stampa': return catalog.pdf_generato_stampa ? `PDF` : ''; case 'data_generato': return tools.getstrDate(catalog.data_generato); case 'data_generato_stampa': return tools.getstrDate(catalog.data_generato_stampa); case 'pdf_online': return catalog.pdf_online ? `PDF` : ''; case 'pdf_online_stampa': return catalog.pdf_online_stampa ? `PDF` : ''; case 'data_online': return tools.getstrDate(catalog.data_online); case 'data_online_stampa': return tools.getstrDate(catalog.data_online_stampa); case 'addtocart': case 'addtolist': return true; case 'image': return catalog.foto_collana?.imagefile ? tools.getFullFileNameByImageFile( shared_consts.TABLES_CATALOG, catalog.foto_collana?.imagefile, catalog._id ) : ''; } } else { switch (field.field) { case 'image': return element.productInfo?.imagefile ? tools.getFullFileNameByImageFile( 'products', element.productInfo?.imagefile ) : element.productInfo?.image_link; case 'name': return element.productInfo?.name; case 'sottotitolo': return element.productInfo?.sottotitolo; case 'authors': return formatAuthors(element.productInfo?.authors); case 'validato': return element.validaprod?.esito === costanti.VALIDATO.SI ? 'SI' : element.validaprod?.esito === costanti.VALIDATO.TO_RESOLV ? 'ERR' : 'NO'; case 'scraped': return element.scraped === true ? 'SI' : ''; case 'scraped_error': return element.scraped_error === true ? 'ERR' : ''; case 'isbn': return element.isbn; case 'trafiletto': return element.productInfo?.descr_trafiletto_catalogo?.length > 100 ? 'SI ✏️' : 'NO ✏️'; case 'catprods': return tools.formatCatProds(element.productInfo?.catprods); case 'edizione': return element.arrvariazioni?.[0]?.edizione; case 'casaeditrice': return ProductStore.getCasaEditriceByIdPublisher( element.productInfo?.idPublisher ); case 'idCollana': return tools.formatCollane(element.productInfo?.idCollana); case 'stato': return ProductStore.getDescrStatiProdottoByIdStatoProdotto( element.productInfo?.idStatoProdotto || '' ); case 'tipologia': return ProductStore.getDescrByIdTipologia( element.arrvariazioni?.[0]?.idTipologia || '' ); case 'tipoformato': return ProductStore.getDescrByIdTipoFormato( element.arrvariazioni?.[0]?.idTipoFormato || '' ); case 'date_pub': return tools.getstrDate(element.productInfo?.date_pub); case 'prezzo': // return element.price ? '€ ' + element.price.toFixed(2) : ''; const add = colexport ? '' : ' '; return '€' + add + element.arrvariazioni?.[0]?.price?.toFixed(2); case 'prezzo_sconto': const add2 = colexport ? '' : ' '; // return element.sale_price ? '€ ' + element.sale_price.toFixed(2) : ''; return '€' + add2 + element.arrvariazioni?.[0]?.sale_price?.toFixed(2); case 'rank3M': return element.productInfo?.rank3M; case 'rank6M': return element.productInfo?.rank6M; case 'rank1Y': return element.productInfo?.rank1Y; case 'pagine': return element.arrvariazioni?.[0]?.pagine; case 'totVen': return element.productInfo?.totVen; case 'totFat': return element.productInfo?.totFat; case 'fatLast6M': return element.productInfo?.fatLast6M; case 'fatLast1Y': return element.productInfo?.fatLast1Y; case 'fatLast2Y': return element.productInfo?.fatLast2Y; case 'ult_ord': return tools.getstrDate(element.productInfo?.dataUltimoOrdine); case 'quantity': if (tools.isUtente()) return tools.getDescrQuantitàByQuantity( element.arrvariazioni?.[0]?.quantita ); else return element.arrvariazioni?.[0]?.quantita; default: return null; } } } catch (e) { console.error('Errore getFieldValue:', e, element, field); return null; } } function getFieldClass(element: any, field: any): string { if (!element) return ''; switch (field.field) { case 'trafiletto': return element.productInfo?.descr_trafiletto_catalogo?.length > 100 ? 'text-green' : 'text-red'; case 'stato': if (ProductStore.isProssimaUscita(element.productInfo)) { return 'bg-purple-3'; } if (ProductStore.isPrevendita(element.productInfo)) { return 'bg-blue-3'; } if (ProductStore.isNonVendibile(element.productInfo)) { return 'bg-grey'; } return ''; case 'validato': if (element.validaprod?.esito === costanti.VALIDATO.SI) { return 'bg-green'; } else if (element.validaprod?.esito === costanti.VALIDATO.TO_RESOLV) { return 'bg-red'; } else { return 'bg-grey'; } case 'quantity': if (ProductStore.isPubblicato(element.productInfo)) { if (ProductStore.isQtaLimitata(element)) { return 'bg-yellow'; } if (ProductStore.isInEsaurendo(element)) { return 'bg-orange'; } if (ProductStore.isEsaurito(element)) { return 'text-white bg-red-10'; } } return ''; case 'rank3M': case 'rank6M': case 'rank1Y': case 'pagine': case 'totVen': case 'totFat': case 'fatLast6M': case 'fatLast1Y': case 'fatLast2Y': default: return ''; } } function getFieldStyle(element: any, field: any): Record { if (!element) return {}; switch (field.field) { case 'trafiletto': return { cursor: 'pointer', textAlign: 'center', }; case 'prezzo': case 'prezzo_sconto': return { width: '55px', textAlign: 'right' }; case 'validato': return { cursor: 'pointer', textAlign: 'center', color: 'white', }; case 'image': return { width: '50px', height: '50px', }; case 'pagine': case 'totVen': case 'totFat': case 'fatLast6M': case 'fatLast1Y': case 'fatLast2Y': case 'quantity': return { textAlign: 'right', }; default: return {}; } } let cookieValue: [] | null = null; let keyvalue = addstr.value + 'selColCat_2'; if (tools.isUtente()) keyvalue += '_utente'; try { cookieValue = tools.getCookie(keyvalue); // Se il cookie esiste e contiene una stringa JSON valida cookieValue = cookieValue ? cookieValue : []; } catch (error) { console.error("Errore durante la lettura del cookie 'selColCat'", error); cookieValue = []; // In caso di errore, inizializza come array vuoto } const selectedColumns_Editori = ref( cookieValue.length > 0 ? cookieValue : [ 'pos', 'addtolist', 'drag', 'edit', 'validato', 'image', 'name', 'authors', 'isbn', 'catprods', 'stato', 'date_pub', 'pagine', 'trafiletto', 'fatLast1Y', 'quantity', 'actions', ] ); const selectedColumns_Utenti = ref( cookieValue.length > 0 ? cookieValue : [ 'pos', 'image', 'addtocart', 'name', 'authors', 'isbn', 'catprods', 'stato', 'date_pub', 'pagine', 'quantity', 'prezzo', ] ); const selectedColumns_Catalogs = ref( cookieValue.length > 0 ? cookieValue : ['pos', 'drag', 'image', 'title', 'pdf_generato', 'actions'] ); const selectedColumns = ref([]); function isEditColumn(name: string): boolean { const column = allColumns.value.find((col) => col.name === name); return column ? column.edit : false; } const faiConfronto = () => { return ( Array.isArray(props.lista_prod_confronto) && props.lista_prod_confronto.length > 0 ); }; // 3. Funzione per verificare se una colonna è visibile (isColumnVisible) const isColumnVisible = (column: string, real?: boolean, element?: any) => { if (column === 'actions' && !real) { return false; } if (internalProducts.value?.length > 1000) { if (column === 'image') { return false; } } let ok = allColumns.value.some((col) => col.name === column) && (!props.optcatalogo.showListaArgomenti || (props.optcatalogo.showListaArgomenti && !isEditColumn(column))); if ( props.options?.showbuttAdd && column === 'addtolist' && (!element || !props.lista_prod_confronto.some((prod: any) => prod._id === element?._id)) ) { if (tools.isCollaboratore()) ok = true; } if (column === 'addtolist') { if (!faiConfronto()) { ok = false; } } return selectedColumns.value.includes(column) && ok; }; function isElementVisible(col: string, element: any) { let ok = true; if (col === 'addtolist') { if ( props.options?.showbuttAdd && element && props.lista_prod_confronto.some((prod: any) => prod._id === element?._id) ) { ok = false; } } return ok; } const getColumnLabelByName = (name: string): string => { const column = allColumns.value.find((col) => col.name === name); return column ? column.label : ''; }; // Funzione per eliminare un prodotto const removeProduct = (product: IProduct) => { return $q .dialog({ message: t('scheda.removeProduct'), html: true, ok: { label: t('dialog.yes'), push: false, }, title: '', cancel: true, persistent: false, }) .onOk(() => { aggiornaLista(false, product); }); }; function aggiornaLista(frominput: boolean, deleteelem: any = null) { const precsearch = searchText.value; searchText.value = ''; if (frominput) 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( addstr.value + 'selColCat_2', JSON.stringify(selectedColumns.value) ); }; const saveSelectedColumnsExport = (column: string[]) => { tools.setCookie(addstr.value + 'Exp_Columns', JSON.stringify(column)); }; // 9. Watcher per salvare automaticamente le preferenze quando cambiano watch( () => selectedColumns.value, () => { saveSelectedColumns(); } ); watch( () => sortAttribute.value, (newVal) => { tools.setCookie(addstr.value + 'sortAttr', newVal); } ); watch( () => sortDirection.value, (newVal) => { tools.setCookie(addstr.value + 'sortDir', newVal); } ); // Funzione chiamata alla fine del drag-and-drop const onDragEnd = () => { // console.log("Nuovo ordine:", internalProducts.value); aggiornaLista(false); }; function formatAuthors(authors: IAuthor[] | undefined | null): string { if (!authors || !Array.isArray(authors)) { return ''; // Restituisci una stringa vuota se authors non è un array valido } // Estrai il nome e il cognome di ogni autore e uniscili con ', ' return authors .map((author) => `${author.name ?? ''} ${author.surname ?? ''}`.trim()) .filter((name) => name.length > 0) // Filtra eventuali nomi vuoti .join(', '); } function showProduct(element: any) { if (isProduct()) { let link_macro = element.productInfo?.link_macro; if (tools.isUtente() && link_macro) { tools.openUrl(link_macro + '?utm_source=catalog&id=' + props.idcatalog); } else { selProd.value = element; showProd.value = true; } } else if (isCatalog()) { // Apri la pagina del catalogo if (element.idPageAssigned) { const mypagepath = ProductStore.getPathByPage(element.idPageAssigned); // fai il route sulla pagina myfilename $router.push(`/${mypagepath}`); } } } function modifyProduct(element: any) { if (element) { selProd.value = element; cmd.value = shared_consts.SCHEDA_PRODOTTO.CMD_MODIFICA; modifOn.value = true; } } function modifyTrafiletto(element: any) { if (element) { selProd.value = element; cmd.value = shared_consts.SCHEDA_PRODOTTO.CMD_MODIFICA; modifTrafiletto.value = true; } } function updateProduct(element: any) { selProd.value = element; // Aggiorna l'elemento nella lista interna internalProducts.value = internalProducts.value.map((prod: any) => { if (prod._id === selProd.value._id) { return selProd.value; } return prod; }); aggiornaLista(false); } async function updateproductmodif(element: any) { console.log('PRODUCT TABLE: updateproductmodif'); try { if (element?._id) { selProd.value = await ProductStore.getProductById(element?._id); } else { selProd.value = await ProductStore.getProductById(selProd.value?._id); } // update record inside internalProducts internalProducts.value = internalProducts.value.map((prod: any) => { if (prod._id === selProd.value._id) { return selProd.value; } return prod; }); riaggiornaListaProdAlGenitore(); } catch (e) { console.error('err', e); } } async function refreshFieldFromGM(field: string) { if (selProd.value) { loading.value = true; updatefromgm.value = true; field_updated_fromGM.value = ''; field_updated_fromGM.value = await globalStore.getGM_FieldOf_T_Web_Articoli( selProd.value.productInfo.sku!, field, shared_consts.CmdQueryMs.GET ); loading.value = false; } } const sortTable = (sortAttributeToSort: string) => { if (!props.optcatalogo.showListaArgomenti) return false; if (sortAttributeToSort) { if (sortAttribute.value === sortAttributeToSort) { sortDirection.value = -sortDirection.value; } else { sortAttribute.value = sortAttributeToSort; sortDirection.value = 1; } internalProducts.value = internalProducts.value.sort((a: any, b: any) => { const aVal = getFieldValue(a, { field: sortAttributeToSort }); const bVal = getFieldValue(b, { field: sortAttributeToSort }); if (aVal instanceof Date && bVal instanceof Date) { return sortDirection.value === 1 ? aVal.getTime() - bVal.getTime() : bVal.getTime() - aVal.getTime(); } if ( typeof aVal === 'string' && typeof bVal === 'string' && aVal.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/) && bVal.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/) ) { const aDate = new Date(aVal.split('/').reverse().join('-')); const bDate = new Date(bVal.split('/').reverse().join('-')); return sortDirection.value === 1 ? aDate.getTime() - bDate.getTime() : bDate.getTime() - aDate.getTime(); } if (typeof aVal === 'number' && typeof bVal === 'number') { return sortDirection.value === 1 ? aVal - bVal : bVal - aVal; } if (typeof aVal === 'string' && typeof bVal === 'string') { return sortDirection.value === 1 ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal); } return sortDirection.value === 1 ? String(aVal).localeCompare(String(bVal)) : String(bVal).localeCompare(String(aVal)); }); } }; function rigenera() { emit('rigenera'); } function addtolist(element: any) { emit('addtolist', element); } function getFieldClick(element: any, field: any): (() => void) | null { switch (field.field) { case 'trafiletto': return () => modifyTrafiletto(element); case 'validato': return () => modifyProduct(element); case 'image': return () => showProduct(element); case 'stato': return () => { // esempio: mostra dettagli dello stato // console.log('Stato prodotto:', element.productInfo?.idStatoProdotto); }; case 'quantity': return () => { // esempio: mostra log disponibilità // console.log('Quantità disponibile:', element.arrvariazioni?.[0]?.quantita); }; default: return null; } } function exportToCSV( title: string = 'lista_', columns: any[], separatore: string = '\t' ) { saveSelectedColumnsExport(columns); const csvContent = [ columns.map((col) => getColumnLabelByName(col)).join(separatore), ...internalProducts.value.map((product: any) => { return columns .map((col: string) => { const field = { field: col }; return field.field === 'pos' ? internalProducts.value.indexOf(product) + 1 : getFieldValue(product, field, true); }) .join(separatore); }), ].join('\r\n'); const filename = title + new Date().toISOString().slice(0, 10) + '.csv'; const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement('a'); const url = URL.createObjectURL(blob); link.setAttribute('href', url); link.setAttribute('download', filename); link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } function exportToXLSAfterCSV( title: string = 'lista', columns: any[], separatore: string = '\t' ) { if (!Array.isArray(columns)) { console.error('Errore: columns non è un array:', columns); return; } saveSelectedColumnsExport(columns); const csvContent = [ columns.map((col) => getColumnLabelByName(col)).join(separatore), ...internalProducts.value.map((product: any) => { return columns .map((col: string) => { const field = { field: col }; return field.field === 'pos' ? internalProducts.value.indexOf(product) + 1 : getFieldValue(product, field, true); }) .join(separatore); }), ].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); } function exportToXLS(csvContent: string, title: string) { // Usa SheetJS per creare il file XLS a partire dal CSV const worksheet = XLSX.utils.aoa_to_sheet( csvContent.split('\r\n').map((line) => line.split('\t')) ); const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); // Genera il file XLS const xlsData = XLSX.write(workbook, { bookType: 'xls', type: 'array' }); // Crea il Blob correttamente con il tipo MIME const xlsBlob = new Blob([xlsData], { type: 'application/vnd.ms-excel' }); // Crea un URL per il file XLS const xlsFilename = `${title}${new Date().toISOString().slice(0, 10)}.xls`; const xlsUrl = URL.createObjectURL(xlsBlob); // Crea un link per scaricare il file const link = document.createElement('a'); link.href = xlsUrl; link.download = xlsFilename; link.click(); } function isSortable(field: string): boolean { return ( allColumns && !allColumns.value.find((col) => col.name === field)?.notsortable ); } function getImageByElement(element: any) { let image = ''; if (props.table === shared_consts.TABLES_CATALOG) { image = element.foto_collana?.imagefile; } else { image = element.productInfo?.imagefile; } return image; } function isProduct() { return props.table === shared_consts.TABLES_PRODUCTS; } function isCatalog() { return props.table === shared_consts.TABLES_CATALOG; } /* async function addToCart(element: any) { if (props.table === shared_consts.TABLES_PRODUCTS) { await updateProduct(element); if (!!element) { arrordersCart.value = ProductStore.getOrdersCartInAttesaByIdProduct( element._id ); ProductStore.setMyOrder(myorder, element, null, { setstore: false, }); } } }*/ async function addtoCart(element: any, add: boolean) { if (!userStore.isLogged) { tools.showNeutralNotif($q, t('ecomm.area_personale')); globalStore.rightDrawerOpen = true; return false; } ProductStore.setMyOrder(element.myorder, element, null, { setstore: false, }); const ris = await ProductStore.addtoCartBase({ $q, t, id: element._id, order: element.myorder, addqty: add, }); updateProduct(element); } function searchProducts() { console.log('searchProducts'); if (!searchText.value) { internalProducts.value = [...props.lista_prodotti]; return; } // Funzione per "escapare" i caratteri speciali nelle regex const escapeRegex = (w: any) => { return w.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/#/g, '\\#'); }; // Escape del testo di ricerca per evitare conflitti con caratteri speciali const searchTextEscaped = escapeRegex(searchText.value.toLowerCase()); const searchRegex = new RegExp(searchTextEscaped, 'i'); internalProducts.value = props.lista_prodotti.filter((prod: any) => { // Controllo se il titolo corrisponde alla regex const titleMatch = searchRegex.test(`${prod.productInfo?.name}`); // Controllo se uno degli autori corrisponde alla regex const authorMatch = prod.productInfo?.authors && prod.productInfo.authors.some((author: IAuthor) => searchRegex.test(`${author.name} ${author.surname}`) ); // Controllo se il codice corrisponde alla regex const codeMatch = searchRegex.test(`${prod.productInfo?.code}`); return titleMatch || authorMatch || codeMatch; }); } function addArrayTitlesToList(myarr: IProduct[]) { console.log('addArrayTitlesToList'); for (const elem of myarr) { addtolist(elem); } showDialogImport.value = false; // chiudi dialog } onMounted(mounted); return { allColumns, selectedColumns, isColumnVisible, internalProducts, formatAuthors, removeProduct, modifyProduct, tools, globalStore, costanti, onDragEnd, showProduct, showProd, selProd, cmd, shared_consts, updateProduct, field_updated_fromGM, refreshFieldFromGM, updatefromgm, visufromgm, loading, showQtaDisponibile, modifOn, modifTrafiletto, updateproductmodif, optionscatalogo, t, ProductStore, sortTable, sortAttribute, sortDirection, getFieldValue, getFieldClass, getFieldStyle, getFieldClick, handleUpdate, exportToCSV, exportToXLSAfterCSV, isSortable, getImageByElement, isVisibleEditBtn, isProduct, isCatalog, allColumnsComputed, addtoCart, arrordersCart, addtolist, searchProducts, searchText, isElementVisible, fabexp, showDialogExport, showDialogImport, selectedExportColumns, allColumnsToExported, addArrayTitlesToList, }; }, });