- Finalmente risolto il calcolo e l'impaginazione del PDF, per WEb e per Stampa (300 dpi) !

- corretto altre cose sulla lista cataloghi.
This commit is contained in:
Surya Paolo
2025-05-23 16:31:04 +02:00
parent e0583044d7
commit 3d2d1cbdd7
22 changed files with 2189 additions and 2848 deletions

View File

@@ -41,6 +41,16 @@ export default defineComponent({
required: false,
default: '',
},
quality: {
type: String,
required: false,
default: 'original',
},
resize: {
type: Boolean,
required: false,
default: false,
},
imgGall: {
type: Object as PropType<IImgGallery[] | string | undefined | null>,
required: true,
@@ -62,6 +72,10 @@ export default defineComponent({
const fullscreen = ref(false)
const fullscreensrc = ref('')
const uploadOptions = ref({ // qui definisci le opzioni da passare
quality: 'original', // esempio di opzione di qualità
resize: true // opzione per abilitare il ridimensionamento
})
function isValid(myobj: any): boolean {
return (myobj && typeof myobj !== 'string' && typeof myobj !== 'undefined')
@@ -101,6 +115,10 @@ export default defineComponent({
]
}
uploadOptions.value = {
quality: props.quality,
resize: props.resize,
}
}
function getnumimages() {
@@ -396,6 +414,7 @@ export default defineComponent({
isListImgValid,
costanti,
getrealdirectory,
uploadOptions,
}
}
})

View File

@@ -81,7 +81,8 @@
: 'Aggiungi Immagine'
" accept="image/*" :url="getUrl()" :headers="tools.getheaders()" :max-file-size="3000000"
:multiple="!single" auto-upload hide-upload-btn no-thumbnails @uploaded="uploaded" @rejected="onRejected"
style="width: 208px"></q-uploader>
style="width: 208px"
:options="uploadOptions"></q-uploader>
</div>
</div>
</div>

View File

@@ -347,6 +347,7 @@ export default defineComponent({
myel.value.catalogo.areadistampa.margini = { left: '0.59', top: '0.59', right: '0.59', bottom: '0.28' };
myel.value.catalogo.print_isTemplate = false;
myel.value.catalogo.print_linkIdTemplate = '';
myel.value.catalogo.print_linkIdTemplatePerStampa = '';
}
myel.value.catalogo.areadistampa = tools.resetRecIAreaDiStampa(myel.value.catalogo.areadistampa);
@@ -356,6 +357,7 @@ export default defineComponent({
myel.value.catalogo.dimensioni_def = {
isTemplate: false,
linkIdTemplate: '',
linkIdTemplatePerStampa: '',
name: '',
pagina: {},
};

View File

@@ -1489,7 +1489,9 @@
:key="recscheda._id"
:name="ind"
dense
:label="`${ind}. ` + recscheda.scheda.name ? recscheda.scheda.name : `Scheda ` + (ind + 1)"
:label="
`${ind}. ` + recscheda.scheda.name ? recscheda.scheda.name : `Scheda ` + (ind + 1)
"
>
<div class="row">
<q-select
@@ -1501,7 +1503,7 @@
:options="globalStore.getSchedeOpt('SEARCH_')"
@update:model-value="modifElem"
label="Scheda collegata:"
style="width: 250px"
style="width: 350px"
emit-value
map-options
>
@@ -1780,6 +1782,20 @@
label="Pagina di Default"
icon="fas fa-play-circle"
>
<q-select
v-model="myel.catalogo.selectedVersionStampabile"
:options="[
{ label: 'Versione Web', value: shared_consts.PREPARA_PDF.WEB },
{ label: 'Versione Stampabile', value: shared_consts.PREPARA_PDF.STAMPA },
]"
label="Seleziona Versione"
emit-value
map-options
style="width: 300px"
@update:model-value="modifElem"
>
</q-select>
<q-toggle
v-model="myel.catalogo.dimensioni_def.isTemplate"
color="positive"
@@ -1802,6 +1818,20 @@
map-options
>
</q-select>
<q-select
:behavior="$q.platform.is.ios === true ? 'dialog' : 'menu'"
v-if="enableEdit"
rounded
outlined
v-model="myel.catalogo.dimensioni_def.linkIdTemplatePerStampa"
:options="Products.getOptCatalogoTemplate()"
@update:model-value="modifElem"
label="Catalogo collegato per STAMPA:"
style="width: 250px"
emit-value
map-options
>
</q-select>
<div
v-if="myel.catalogo.dimensioni_def.pagina"
@@ -1944,7 +1974,21 @@
:options="globalStore.getSchedeOpt()"
@update:model-value="modifElem"
label="Scheda collegata:"
style="width: 250px"
style="width: 350px"
emit-value
map-options
>
</q-select>
<q-select
:behavior="$q.platform.is.ios === true ? 'dialog' : 'menu'"
v-if="enableEdit"
rounded
outlined
v-model="recscheda.scheda.linkIdTemplatePerStampa"
:options="globalStore.getSchedeOpt()"
@update:model-value="modifElem"
label="Scheda collegata STAMPA:"
style="width: 350px"
emit-value
map-options
>
@@ -2428,13 +2472,32 @@
:options="Products.getOptCatalogoPrintTemplate()"
@update:model-value="modifElem"
label="Catalogo Stampa collegato:"
style="width: 250px"
style="width: 350px"
emit-value
map-options
>
</q-select>
<q-select
:behavior="$q.platform.is.ios === true ? 'dialog' : 'menu'"
v-if="enableEdit"
rounded
outlined
v-model="myel.catalogo.print_linkIdTemplatePerStampa"
:options="Products.getOptCatalogoPrintTemplate()"
@update:model-value="modifElem"
label="Catalogo Stampa collegato per STAMPA:"
style="width: 350px"
emit-value
map-options
>
</q-select>
<div :class="{ 'sfondo_print': !myel.catalogo.print_linkIdTemplate, 'bg-grey': myel.catalogo.print_linkIdTemplate }">
<div
:class="{
sfondo_print: !myel.catalogo.print_linkIdTemplate,
'bg-grey': myel.catalogo.print_linkIdTemplate,
}"
>
Per Stampa:
<q-toggle
v-model="myel.catalogo.printable"
@@ -2456,7 +2519,7 @@
<q-select
rounded
style="width: 200px"
style="width: 350px"
outlined
v-model="myel.catalogo.areadistampa.format"
:options="tools.SelectListFormatPDF"

View File

@@ -1,11 +1,4 @@
import {
PropType,
computed,
defineComponent,
onMounted,
ref,
watch,
} from 'vue';
import { PropType, computed, defineComponent, onMounted, ref, watch } from 'vue';
import draggable from 'vuedraggable';
import { tools } from '@tools';
@@ -54,6 +47,11 @@ export default defineComponent({
type: String,
required: true,
},
idcatalog: {
type: String,
required: false,
default: '',
},
optcatalogo: {
type: Object as PropType<IOptCatalogo>,
required: false,
@@ -103,7 +101,7 @@ export default defineComponent({
function handleUpdate(newList) {
internalProducts.value = newList;
riaggiornaListaProdAlGenitore()
riaggiornaListaProdAlGenitore();
}
function riaggiornaListaProdAlGenitore() {
@@ -266,6 +264,7 @@ export default defineComponent({
field: 'validato',
align: 'left',
style: '',
visu: costanti.VISUCAMPI.PER_EDITORE,
},
{
name: 'scraped',
@@ -273,6 +272,7 @@ export default defineComponent({
field: 'scraped',
align: 'left',
style: '',
visu: costanti.VISUCAMPI.PER_EDITORE,
},
{
name: 'scraped_error',
@@ -280,6 +280,7 @@ export default defineComponent({
field: 'scraped_error',
align: 'left',
style: '',
visu: costanti.VISUCAMPI.PER_EDITORE,
},
{
name: 'image',
@@ -303,6 +304,7 @@ export default defineComponent({
label: 'Sinossi',
field: 'trafiletto',
align: 'left',
visu: costanti.VISUCAMPI.PER_EDITORE,
},
{
name: 'catprods',
@@ -421,6 +423,12 @@ export default defineComponent({
},
]);
const allColumnsComputed = computed(() => {
return allColumns.value.filter(
(col) => !col.visu || col.visu === costanti.VISUCAMPI.PER_TUTTI
);
});
async function mounted() {
console.log('mounted CProductTable');
loading.value = true;
@@ -515,10 +523,7 @@ export default defineComponent({
switch (field.field) {
case 'image':
return element.productInfo?.imagefile
? tools.getFullFileNameByImageFile(
'productInfos',
element.productInfo?.imagefile
)
? tools.getFullFileNameByImageFile('productInfos', element.productInfo?.imagefile)
: element.productInfo?.image_link;
case 'name':
@@ -538,9 +543,7 @@ export default defineComponent({
: 'NO';
case 'scraped':
return element.scraped === true
? '<span class="text-bold">SI</span>'
: '';
return element.scraped === true ? '<span class="text-bold">SI</span>' : '';
case 'scraped_error':
return element.scraped_error === true
? '<span class="text-bold text-red">ERR</span>'
@@ -550,8 +553,7 @@ export default defineComponent({
return element.isbn;
case 'trafiletto':
return element.productInfo?.descr_trafiletto_catalogo?.length >
100
return element.productInfo?.descr_trafiletto_catalogo?.length > 100
? 'SI ✏️'
: 'NO ✏️';
@@ -562,9 +564,7 @@ export default defineComponent({
return element.arrvariazioni?.[0]?.edizione;
case 'casaeditrice':
return products.getCasaEditriceByIdPublisher(
element.productInfo?.idPublisher
);
return products.getCasaEditriceByIdPublisher(element.productInfo?.idPublisher);
case 'idCollana':
return tools.formatCollane(element.productInfo?.idCollana);
@@ -575,9 +575,7 @@ export default defineComponent({
);
case 'tipologia':
return products.getDescrByIdTipologia(
element.arrvariazioni?.[0]?.idTipologia || ''
);
return products.getDescrByIdTipologia(element.arrvariazioni?.[0]?.idTipologia || '');
case 'tipoformato':
return products.getDescrByIdTipoFormato(
@@ -591,9 +589,7 @@ export default defineComponent({
return element.price ? '€ ' + element.price.toFixed(2) : '';
case 'prezzo_sconto':
return element.sale_price
? '€ ' + element.sale_price.toFixed(2)
: '';
return element.sale_price ? '€ ' + element.sale_price.toFixed(2) : '';
case 'rank3M':
return element.productInfo?.rank3M;
@@ -627,9 +623,7 @@ export default defineComponent({
case 'quantity':
if (tools.isUtente())
return tools.getDescrQuantitàByQuantity(
element.arrvariazioni?.[0]?.quantita
);
return tools.getDescrQuantitàByQuantity(element.arrvariazioni?.[0]?.quantita);
else return element.arrvariazioni?.[0]?.quantita;
default:
@@ -665,9 +659,7 @@ export default defineComponent({
case 'validato':
if (element.validaprod?.esito === costanti.VALIDATO.SI) {
return 'bg-green';
} else if (
element.validaprod?.esito === costanti.VALIDATO.TO_RESOLV
) {
} else if (element.validaprod?.esito === costanti.VALIDATO.TO_RESOLV) {
return 'bg-red';
} else {
return 'bg-grey';
@@ -839,19 +831,14 @@ export default defineComponent({
persistent: false,
})
.onOk(() => {
internalProducts.value = internalProducts.value.filter(
(p: any) => p._id !== product._id
);
internalProducts.value = internalProducts.value.filter((p: any) => p._id !== product._id);
emit('update:lista_prodotti', internalProducts.value); // Notifica il parent del cambiamento
});
};
// 8. Salvataggio delle colonne selezionate in un cookie
const saveSelectedColumns = () => {
tools.setCookie(
addstr.value + 'selColCat_2',
JSON.stringify(selectedColumns.value)
);
tools.setCookie(addstr.value + 'selColCat_2', JSON.stringify(selectedColumns.value));
};
// 9. Watcher per salvare automaticamente le preferenze quando cambiano
@@ -896,13 +883,20 @@ export default defineComponent({
function showProduct(element: any) {
if (isProduct()) {
selProd.value = element;
let link_macro = element.productInfo?.link_macro;
showProd.value = true;
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}`);
}
@@ -956,7 +950,7 @@ export default defineComponent({
}
return prod;
});
riaggiornaListaProdAlGenitore()
riaggiornaListaProdAlGenitore();
} catch (e) {
console.error('err', e);
}
@@ -967,12 +961,11 @@ export default defineComponent({
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
);
field_updated_fromGM.value = await globalStore.getGM_FieldOf_T_Web_Articoli(
selProd.value.productInfo.sku!,
field,
shared_consts.CmdQueryMs.GET
);
loading.value = false;
}
}
@@ -987,40 +980,36 @@ export default defineComponent({
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);
}
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
? String(aVal).localeCompare(String(bVal))
: String(bVal).localeCompare(String(aVal));
? 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));
});
}
};
@@ -1062,9 +1051,7 @@ export default defineComponent({
.join('|'),
...internalProducts.value.map((product: any) => {
return selectedColumns.value
.filter(
(col) => !allColumns.value.find((c) => c.name === col)?.noexp
)
.filter((col) => !allColumns.value.find((c) => c.name === col)?.noexp)
.map((col: string) => {
const field = { field: col };
return field.field === 'pos'
@@ -1075,8 +1062,7 @@ export default defineComponent({
}),
].join('\r\n');
const filename =
'prodotti_' + new Date().toISOString().slice(0, 10) + '.csv';
const filename = 'prodotti_' + 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);
@@ -1091,10 +1077,7 @@ export default defineComponent({
}
function isSortable(field: string): boolean {
return (
allColumns &&
!allColumns.value.find((col) => col.name === field)?.notsortable
);
return allColumns && !allColumns.value.find((col) => col.name === field)?.notsortable;
}
function getImageByElement(element) {
@@ -1161,6 +1144,7 @@ export default defineComponent({
isVisibleEditBtn,
isProduct,
isCatalog,
allColumnsComputed,
};
},
});

View File

@@ -8,7 +8,7 @@
<div class="q-mb-md text-right">
<q-select
v-model="selectedColumns"
:options="allColumns"
:options="allColumnsComputed"
label="Colonne da visualizzare"
multiple
filled
@@ -42,7 +42,7 @@
<!-- Intestazioni (Thead) -->
<thead>
<tr>
<template v-for="col in allColumns">
<template v-for="col in allColumnsComputed">
<th
v-if="isColumnVisible(col.name)"
:key="col.name"
@@ -90,7 +90,7 @@
}"
>
<template
v-for="field in allColumns"
v-for="field in allColumnsComputed"
:key="field.name"
>
<!-- Icona Drag Handle -->

View File

@@ -199,40 +199,6 @@ export default defineComponent({
return lista && lista.value && lista.value._id ? lista.value._id : '';
}
function populateDataWithlinkIdTemplate() {
// console.log('populateDataWithlinkIdTemplate')
if (optcatalogo.value) {
// LINK PAGINA
if (optcatalogo.value.dimensioni_def.linkIdTemplate) {
const reccatalog = globalStore.sovrascriviPaginaDefaultFromTemplate(optcatalogo.value.dimensioni_def.linkIdTemplate, optcatalogo.value.dimensioni_def);
if (reccatalog) {
optcatalogo.value.dimensioni_def.pagina = { ...reccatalog.dimensioni_def.pagina};
}
}
if (optcatalogo.value.print_linkIdTemplate) {
const reccatalog = globalStore.sovrascriviAreadistampaFromTemplate(optcatalogo.value.print_linkIdTemplate, optcatalogo.value);
if (reccatalog) {
optcatalogo.value.areadistampa = { ...reccatalog.areadistampa};
}
}
// LINK SCHEDA
for (const recscheda of optcatalogo.value.arrSchede!) {
if (recscheda.scheda?.linkIdTemplate) {
// ricopia da Template:
const myscheda = globalStore.sovrascriviSchedaFromTemplate(recscheda.scheda?.linkIdTemplate, recscheda);
if (myscheda) {
recscheda.scheda = { ...myscheda };
}
}
}
}
// console.log(' FINE - populateDataWithlinkIdTemplate')
}
function isProductLibro() {
return props.table === 'products';
}
@@ -264,7 +230,7 @@ export default defineComponent({
}
if (props.nameLinkTemplate) {
populateDataWithlinkIdTemplate();
optcatalogo.value = productStore.populateDataWithlinkIdTemplate(optcatalogo.value);
}
if (props.visu === shared_consts.VISU_SEARCHPROD_MODE.INSERT) {