- corretto gruppomacro catalogo, info prodotti, estrazione dati da amazon corretto.

This commit is contained in:
Surya Paolo
2025-09-27 17:24:40 +02:00
parent c8589e794f
commit d6c0bcf879
13 changed files with 330 additions and 252 deletions

View File

@@ -1,13 +1,11 @@
VITE_APP_ID="18"
VITE_APP_URL="https://gruppomacro.app"
VITE_MONGODB_HOST="https://api.gruppomacro.app"
VITE_LOGO_REG='gruppomacro-logo-full.png'
VITE_APP_URL="https://test.gruppomacro.app"
VITE_MONGODB_HOST="https://testapi.gruppomacro.app"
VITE_LOGO_REG="gruppomacro-logo-full.png"
VITE_PUBLICKEY_PUSH="BJgo8XR_upbnbMLWgCAUELo6DK7dRXffYAnFOxbaMMz5favBgcQBKT-eISqouO-jRad4Sw8l5nd2wCF6KorGiTc"
VITE_DEBUG="0"
VITE_VUE_APP_ISTEST="0"
VITE_DEBUG="1"
VITE_VUE_APP_ISTEST="1"
DIRECTORY_LOCAL="myprojplanet_vite"
DIRECTORY_SERVER="/var/www/nodejs_piuchebuono_server"
SERVERDIR_WEBSITE="/var/www/gruppomacro.app"
DIRECTORY_SERVER="/var/www/nodejs_test.piuchebuono_server"
SERVERDIR_WEBSITE="/var/www/test.gruppomacro.app"
SERVERPW_WEBSITE="pwdadmin@1AOK"
PORT_SPA="8089"
PORT_PWA="8099"

View File

@@ -208,7 +208,7 @@ export default defineComponent({
function completeOrder() {
$q.dialog({
message: t('ecomm.conferma_acq', { qty: myTotalQty }),
message: t('ecomm.conferma_acq', { qty: myTotalQty.value }),
ok: {
label: t('dialog.yes'),
push: true,

View File

@@ -789,7 +789,7 @@ export default defineComponent({
dataextractedWeb.value = '... caricamento in corso...';
try {
const data = await scrapingBook(false);
const data = await scrapingBook(false, false);
const html = tools.generateHtmlTableFromObject(data);
dataextractedWeb.value = html;
} catch (error) {
@@ -885,6 +885,7 @@ export default defineComponent({
heightoggetto,
mywidthogg,
myheightogg,
scrapingBook,
};
},
});

View File

@@ -76,7 +76,7 @@
scheda,
true
) ?? '100%',
'height': tools.adjustSize(
height: tools.adjustSize(
optcatalogo,
scheda.dimensioni?.scheda_prodotto?.size?.height,
scheda,
@@ -84,13 +84,17 @@
),
}"
>
<div
:style="`position: relative; align-content: center;`"
>
<div :style="`position: relative; align-content: center;`">
<a
target="_blank"
:href="myCatalog?.disattiva_link_immagini ? null : myproduct.productInfo.link_macro"
:style="myCatalog?.disattiva_link_immagini ? 'cursor: normal !important;' : ''"
:href="
myCatalog?.disattiva_link_immagini
? null
: myproduct.productInfo.link_macro
"
:style="
myCatalog?.disattiva_link_immagini ? 'cursor: normal !important;' : ''
"
>
<q-img
v-if="myproduct.productInfo"
@@ -143,7 +147,11 @@
: undefined,
display: 'block',
}"
@click.stop.prevent="myCatalog?.disattiva_link_immagini ? null : tools.openUrl(myproduct.productInfo.link_macro)"
@click.stop.prevent="
myCatalog?.disattiva_link_immagini
? null
: tools.openUrl(myproduct.productInfo.link_macro)
"
>
</q-img>
</a>
@@ -158,18 +166,35 @@
z-index: 10;
"
>
<div v-if="!optcatalogo.generazionePDFInCorso && !myCatalog?.disattiva_link_immagini">
<div
v-if="
!optcatalogo.generazionePDFInCorso &&
!myCatalog?.disattiva_link_immagini
"
>
<q-btn
icon="fas fa-external-link-alt"
color="primary"
class="no-print"
rounded
size="sm"
@click.stop.prevent="tools.openUrl(myCatalog?.disattiva_link_immagini ? null : myproduct.productInfo.link_macro)"
@click.stop.prevent="
tools.openUrl(
myCatalog?.disattiva_link_immagini
? null
: myproduct.productInfo.link_macro
)
"
>
</q-btn>
</div>
<div v-if="!optcatalogo.generazionePDFInCorso && tools.isLogged() && !myCatalog?.disattiva_link_immagini">
<div
v-if="
!optcatalogo.generazionePDFInCorso &&
tools.isLogged() &&
!myCatalog?.disattiva_link_immagini
"
>
<q-btn
icon-right="fas fa-cart-plus"
color="positive"
@@ -902,7 +927,8 @@
v-model="myproduct"
titolo="Sinossi"
table="products"
mykey="productInfo.descr_trafiletto_catalogo"
mykey="productInfo"
mysubkey="descr_trafiletto_catalogo"
:canModify="true"
:type="costanti.FieldType.editor_nohtml"
@updateproductmodif="updateproductmodif"

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';
@@ -87,10 +80,14 @@ export default defineComponent({
const myproduct = ref<IProduct>({ ...props.modelValue });
const id = computed(() => myproduct.value.productInfo._id);
const id = computed(() => myproduct.value._id);
const myvalue = computed<string>(() => {
return myproduct.value.productInfo[props.mykey];
if (props.mysubkey) {
return myproduct.value[props.mykey][props.mysubkey];
} else {
return myproduct.value[props.mykey];
}
});
watch(
@@ -105,7 +102,8 @@ export default defineComponent({
loading.value = true;
try {
const myscrapingbookrec = await products.loadMyScrapingBook(
myproduct.value.isbn, false
myproduct.value.isbn,
false
);
myscrapingbook.value = myscrapingbookrec;
} catch (error) {
@@ -152,10 +150,7 @@ export default defineComponent({
}
async function updateproduct(load?: boolean) {
myproduct.value = await products.getProductById(
myproduct.value._id,
load
);
myproduct.value = await products.getProductById(myproduct.value._id, load);
}
const copyToClipboard = (text) => {
@@ -187,8 +182,9 @@ export default defineComponent({
function getPrompt() {
// Prompt:
let mydescr = 'Scrivimi la sinossi del libro che ti indicherò, che andrà in un catalogo libri, la lunghezza del testo finale dev\'essere compresa tra 760 e 780 caratteri, senza spiegazione, senza titolo iniziale, solo la sinossi. Togli eventuali riferimenti a chi ha fatto la prefazione. Rendilo un po\' accattivante, ma non troppo. Senza immagine. Non inserire nessun link o riferimenti esterni o citazioni esterne. L\'output è solo la sinossi, senza altre spiegazioni. \n\n';
return mydescr
let mydescr =
"Scrivimi la sinossi del libro che ti indicherò, che andrà in un catalogo libri, la lunghezza del testo finale dev'essere compresa tra 760 e 780 caratteri, senza spiegazione, senza titolo iniziale, solo la sinossi. Togli eventuali riferimenti a chi ha fatto la prefazione. Rendilo un po' accattivante, ma non troppo. Senza immagine. Non inserire nessun link o riferimenti esterni o citazioni esterne. L'output è solo la sinossi, senza altre spiegazioni. \n\n";
return mydescr;
}
function copyDescrizioneFromScrapingData() {
@@ -197,9 +193,14 @@ export default defineComponent({
const data = myscrapingbook.value;
if (!data) return false;
mydescr = getPrompt()
mydescr = getPrompt();
mydescr += 'Titolo Libro: ' + data.titolo + '\n';
mydescr += 'Autore Libro: ' + (data?.autore.trim() ? data?.autore.trim() : products.getAutoriByArrayAuthors(myproduct?.value.productInfo?.authors)) + '\n';
mydescr +=
'Autore Libro: ' +
(data?.autore.trim()
? data?.autore.trim()
: products.getAutoriByArrayAuthors(myproduct?.value.productInfo?.authors)) +
'\n';
mydescr += 'DESCRIZIONE LIBRO: \n';
mydescr += data.descrizione_lunga;
@@ -210,9 +211,12 @@ export default defineComponent({
function copyDescrizioneFromGruppoMacro() {
let mydescr = '';
mydescr = getPrompt()
mydescr = getPrompt();
mydescr += 'Titolo Libro: ' + myproduct?.value.productInfo?.name + '\n';
mydescr += 'Autore Libro: ' + products.getAutoriByArrayAuthors(myproduct?.value.productInfo?.authors) + '\n';
mydescr +=
'Autore Libro: ' +
products.getAutoriByArrayAuthors(myproduct?.value.productInfo?.authors) +
'\n';
mydescr += 'DESCRIZIONE LIBRO: \n';
mydescr += myproduct?.value.productInfo?.descrizione_completa_macro;

View File

@@ -1,8 +1,8 @@
import { defineComponent, ref, watch, toRef, onMounted } from 'vue'
import { useI18n } from 'vue-i18n'
import { useQuasar } from 'quasar'
import { tools } from '@tools'
import { costanti } from '@costanti'
import { defineComponent, ref, watch, toRef, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import { tools } from '@tools';
import { costanti } from '@costanti';
export default defineComponent({
name: 'CMyChipList',
@@ -36,22 +36,22 @@ export default defineComponent({
myclass: {
type: String,
required: false,
default: ''
default: '',
},
opticon: {
type: String,
required: false,
default: ''
default: '',
},
optcolor: {
type: String,
required: false,
default: ''
default: '',
},
labelifblank: {
type: String,
required: false,
default: ''
default: '',
},
rec: {
type: Object,
@@ -62,173 +62,185 @@ export default defineComponent({
type: String,
required: false,
default: '',
}
},
},
components: {},
setup(props, { emit }) {
const { t } = useI18n()
const { t } = useI18n();
const myval = toRef(props, 'value')
const myarrvalues = ref(<any>[])
const myval = toRef(props, 'value');
const myarrvalues = ref(<any>[]);
watch(() => myval.value, (newval, oldval) => {
refreshval()
})
watch(
() => myval.value,
(newval, oldval) => {
refreshval();
}
);
function refreshval() {
// console.log('refreshval')
myarrvalues.value = []
// azzero l'array di uscita
myarrvalues.value = [];
// console.log('options', props.options)
if (props.options.length > 0) {
props.options.forEach((rec: any, index) => {
// console.log('rec', rec)
// --- MULTISELECT: itera sulle selezioni, non sulle options ---
if (props.type === costanti.FieldType.multiselect) {
if (!!myval.value) {
if (Array.isArray(myval.value) && myval.value.length) {
myval.value.forEach((recout, idx) => {
// valore "chiave" della selezione
const value =
props.type_out === costanti.FieldType.object
? recout?.[props.optval]
: recout && typeof recout === 'object'
? recout._id
: recout;
/*
console.log('rec', rec)
console.log('optval', props.optval)
console.log('optlab', props.optlab)
console.log('myval.value', myval.value)
console.log('rec[props.optval]', rec[props.optval])
*/
if (value == null) return; // skip selezioni non valide
let trovato = false
// provo a trovare il record corrispondente tra le options (se presenti)
const recFromOptions = Array.isArray(props.options)
? props.options.find((o) => o && o[props.optval] === value)
: null;
if (props.type_out === costanti.FieldType.object) {
// @ts-ignore
trovato = myval.value.find((recout) => recout[props.optval] === rec[props.optval])
} else {
// @ts-ignore
trovato = myval.value.includes(rec[props.optval])
}
const baseRec =
recFromOptions || (typeof recout === 'object' ? recout : null);
if (trovato) {
const mydata: any = {
const mydata = {
label: null,
value: rec[props.optval],
// myris = mylist.filter((myrec) => arrval.includes(myrec[key]))
value,
valbool: true,
icon: '',
color: tools.getColorByIndexBest(index)
// priorità: optcolor -> color su record -> fallback colore
color:
(props.optcolor && baseRec?.[props.optcolor]) ||
baseRec?.color ||
tools.getColorByIndexBest(idx),
};
// icon (se disponibile)
if (props.opticon && baseRec?.[props.opticon]) {
mydata.icon = baseRec[props.opticon];
}
if (rec['color']) {
mydata.color = rec['color']
}
/*
if (rec['theme']) {
mydata.class = rec['theme']
}
*/
// console.log('mydata', mydata)
// label
if (tools.isObject(props.optlab)) {
// @ts-ignore
mydata.label = props.options.filter((myrec: any) => myrec[props.optval] === mydata.value).map(props.optlab)
if (mydata.label)
mydata.label = mydata.label[0]
// se optlab è funzione/mapper, applico al record trovato in options
if (recFromOptions) {
mydata.label =
typeof props.optlab === 'function'
? props.optlab(recFromOptions)
: tools.getValueByFunzOrVal(recFromOptions, props.optlab);
} else {
mydata.label = tools.getValueByFunzOrVal(rec, props.optlab)
// fallback: provo su recout se è un oggetto
mydata.label = tools.getValueByFunzOrVal(baseRec || {}, props.optlab);
}
} else {
// optlab è chiave o funzione gestita dalla utility
mydata.label = tools.getValueByFunzOrVal(baseRec || {}, props.optlab);
}
// console.log('mydata.label', mydata.label)
if (props.opticon)
mydata.icon = rec[props.opticon]
if (props.optcolor)
mydata.color = rec[props.optcolor]
myarrvalues.value.push(mydata)
}
myarrvalues.value.push(mydata);
});
}
// se multiselect non ha prodotto nulla, gestisco eventuale fallback sotto
} else if (props.type === costanti.FieldType.select) {
if (myval.value === rec[props.optval]) {
const mydata: any = {
// --- SELECT: itera sulle options e trova la corrispondenza ---
if (Array.isArray(props.options) && props.options.length) {
props.options.forEach((rec, index) => {
if (myval.value === rec?.[props.optval]) {
const mydata = {
value: myval.value,
valbool: true,
icon: '',
color: tools.getColorByIndexBest(index)
}
color:
(props.optcolor && rec?.[props.optcolor]) ||
rec?.color ||
tools.getColorByIndexBest(index),
label: null,
};
// console.log('mydata', mydata, 'optlab', optlab, 'myval.value', myval.value)
if (props.opticon && rec?.[props.opticon]) mydata.icon = rec[props.opticon];
if (tools.isObject(props.optlab)) {
// @ts-ignore
mydata.label = props.options.filter((myrec: any) => myrec[props.optval] === mydata.value).map(props.optlab)
if (mydata.label)
mydata.label = mydata.label[0]
// cerco l'option corrispondente e la mappo
const opt = props.options.find(
(o) => o && o[props.optval] === mydata.value
);
mydata.label = opt
? typeof props.optlab === 'function'
? props.optlab(opt)
: tools.getValueByFunzOrVal(opt, props.optlab)
: null;
} else {
mydata.label = tools.getValueByFunzOrVal(rec, props.optlab)
mydata.label = tools.getValueByFunzOrVal(rec, props.optlab);
}
if (props.opticon)
mydata.icon = rec[props.opticon]
if (props.optcolor)
mydata.color = rec[props.optcolor]
myarrvalues.value.push(mydata)
myarrvalues.value.push(mydata);
}
});
}
} else {
if (tools.isBitActive(myval.value, rec[props.optval])) {
// console.log('rec', rec, 'props.optlab', props.optlab)
// --- BITMASK (o altro tipo legacy): itera sulle options e verifica i bit attivi ---
if (Array.isArray(props.options) && props.options.length) {
props.options.forEach((rec, index) => {
const optVal = rec?.[props.optval];
if (optVal == null) return;
if (tools.isBitActive(myval.value, optVal)) {
const mydata = {
label: t(tools.getValueByFunzOrVal(rec, props.optlab)),
value: rec[props.optval],
valbool: tools.isBitActive(myval.value, rec[props.optval]),
value: optVal,
valbool: true,
icon: '',
color: tools.getColorByIndexBest(index)
color:
(props.optcolor && rec?.[props.optcolor]) ||
rec?.color ||
tools.getColorByIndexBest(index),
};
if (props.opticon && rec?.[props.opticon]) mydata.icon = rec[props.opticon];
myarrvalues.value.push(mydata);
}
if (props.opticon)
mydata.icon = rec[props.opticon]
if (props.optcolor)
mydata.color = rec[props.optcolor]
myarrvalues.value.push(mydata)
});
}
}
})
} else {
if (props.type === costanti.FieldType.select_by_server) {
const mydata: any = {
// @ts-ignore
label: props.rec[props.optlab],
// --- FALLBACK quando non ci sono options ma select_by_server ---
if (
(!Array.isArray(props.options) || props.options.length === 0) &&
props.type === costanti.FieldType.select_by_server
) {
const mydata = {
label: props.rec?.[props.optlab],
value: 0,
valbool: true,
icon: '',
color: tools.getColorByIndexBest(0)
}
color: tools.getColorByIndexBest(0),
};
if (!mydata.label && props.labelifblank) {
mydata.label = props.labelifblank
mydata.color = 'grey'
mydata.label = props.labelifblank;
mydata.color = 'grey';
}
myarrvalues.value.push(mydata)
}
myarrvalues.value.push(mydata);
}
if (myarrvalues.value.length === 0)
myarrvalues.value.push({ label: t('otherpages.manage.nessuno'), color: 'gray' })
// console.log('arrvalues=', myarrvalues)
// --- Nessuna selezione: placeholder "nessuno" ---
if (!Array.isArray(myarrvalues.value) || myarrvalues.value.length === 0) {
myarrvalues.value = [{ label: t('otherpages.manage.nessuno'), color: 'gray' }];
}
}
function mounted() {
refreshval()
refreshval();
}
onMounted(mounted)
onMounted(mounted);
return {
myarrvalues,
}
}
})
};
},
});

View File

@@ -1068,6 +1068,7 @@
</div>
<!-- Show Value -->
<div v-else-if="col.fieldtype === costanti.FieldType.multiselect">
<div v-if="isInModif">
<CMySelect
:type_out="col.field_outtype"

View File

@@ -462,19 +462,6 @@
</div>
{{ myproduct.productInfo.imagefile }}
</div>
<!--<CMyFieldRec
title="Immagine:"
table="myelems"
:id="myproduct.productInfo._id"
:rec="myproduct.productInfo"
field="imagefile"
@update:model-value="modifElem"
:canEdit="true"
:canModify="true"
:fieldtype="costanti.FieldType.imagerec"
>
</CMyFieldRec>-->
</q-card-section>
<q-card-section v-if="isOrdGas()">
<q-item

View File

@@ -389,7 +389,8 @@
v-model="selProd"
titolo="Sinossi"
table="products"
mykey="productInfo.descr_trafiletto_catalogo"
mykey="productInfo"
mysubkey="descr_trafiletto_catalogo"
:canModify="true"
:type="costanti.FieldType.editor_nohtml"
@updateproductmodif="updateproductmodif"

View File

@@ -83,8 +83,9 @@ export default defineComponent({
label: 'Fatturati',
table: 'products',
id: myproduct.value._id, // ID dinamico, da sostituire con il valore reale
rec: myproduct.value.productInfo, // Oggetto dinamico, da sostituire con il valore reale
mykey: 'totFat',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'totFat',
debounce: '1000',
type: costanti.FieldType.number,
},
@@ -93,8 +94,9 @@ export default defineComponent({
label: 'Fatturati ultimi 3 Mesi',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo,
mykey: 'fatLast3M',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'fatLast3M',
debounce: '1000',
type: costanti.FieldType.number,
},
@@ -103,8 +105,9 @@ export default defineComponent({
label: 'Fatturati ultimi 6 Mesi',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo,
mykey: 'fatLast6M',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'fatLast6M',
debounce: '1000',
type: costanti.FieldType.number,
},
@@ -113,8 +116,9 @@ export default defineComponent({
label: 'Fatturati ultimo Anno',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo,
mykey: 'fatLast1Y',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'fatLast1Y',
debounce: '1000',
type: costanti.FieldType.number,
},
@@ -123,8 +127,9 @@ export default defineComponent({
label: 'Fatturati ultimi 2 Anni',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo,
mykey: 'fatLast2Y',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'fatLast2Y',
debounce: '1000',
type: costanti.FieldType.number,
},
@@ -133,8 +138,9 @@ export default defineComponent({
label: 'Venduti',
table: 'products',
id: myproduct.value._id, // ID dinamico, da sostituire con il valore reale
rec: myproduct.value.productInfo, // Oggetto dinamico, da sostituire con il valore reale
mykey: 'totVen',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'totVen',
debounce: '1000',
type: costanti.FieldType.number,
},
@@ -143,8 +149,9 @@ export default defineComponent({
label: 'Venduti Ultimi 3 Mesi',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo,
mykey: 'vLast3M',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'vLast3M',
debounce: '1000',
type: costanti.FieldType.number,
},
@@ -153,8 +160,9 @@ export default defineComponent({
label: 'Venduti Ultimi 6 Mesi',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo,
mykey: 'vLast6M',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'vLast6M',
debounce: '1000',
type: costanti.FieldType.number,
},
@@ -163,8 +171,9 @@ export default defineComponent({
label: 'Venduti Ultimo Anno',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo,
mykey: 'vLast1Y',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'vLast1Y',
debounce: '1000',
type: costanti.FieldType.number,
},
@@ -173,8 +182,9 @@ export default defineComponent({
label: 'Venduti Ultimi 2 Anni',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo,
mykey: 'vLast2Y',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'vLast2Y',
debounce: '1000',
type: costanti.FieldType.number,
},
@@ -216,8 +226,9 @@ export default defineComponent({
title: myproduct.value?.productInfo?.name,
table: 'products',
id: myproduct.value._id, // ID dinamico, da sostituire con il valore reale
rec: myproduct.value.productInfo, // Oggetto dinamico, da sostituire con il valore reale
mykey: 'descrizione_breve_macro',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'descrizione_breve_macro',
maxlength: 650,
debounce: '1000',
type: costanti.FieldType.editor_nohtml,
@@ -229,8 +240,9 @@ export default defineComponent({
label: 'Descrizione Estesa',
table: 'products',
id: myproduct.value._id, // ID dinamico, da sostituire con il valore reale
rec: myproduct.value.productInfo, // Oggetto dinamico, da sostituire con il valore reale
mykey: 'descrizione_completa_macro',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'descrizione_completa_macro',
maxlength: props.scheda?.testo_bottom?.maxlength
? props.scheda?.testo_bottom?.maxlength
: 10000,
@@ -244,8 +256,9 @@ export default defineComponent({
label: 'Link a gruppomacro.com',
table: 'products',
id: myproduct.value._id, // ID dinamico, da sostituire con il valore reale
rec: myproduct.value.productInfo, // Oggetto dinamico, da sostituire con il valore reale
mykey: 'link_macro',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'link_macro',
debounce: '1000',
type: costanti.FieldType.string,
dense: true,
@@ -256,8 +269,9 @@ export default defineComponent({
label: 'Imagefile',
table: 'products',
id: myproduct.value._id, // ID dinamico, da sostituire con il valore reale
rec: myproduct.value.productInfo, // Oggetto dinamico, da sostituire con il valore reale
mykey: 'imagefile',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'imagefile',
debounce: '1000',
type: costanti.FieldType.string,
dense: true,
@@ -275,8 +289,9 @@ export default defineComponent({
label: 'Titolo',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo, // Oggetto dinamico, da sostituire con il valore reale
mykey: 'name',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'name',
debounce: '1000',
type: costanti.FieldType.string,
dense: true,
@@ -297,8 +312,9 @@ export default defineComponent({
label: 'SottoTitolo',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo,
mykey: 'sottotitolo',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'sottotitolo',
debounce: '1000',
type: costanti.FieldType.string,
dense: true,
@@ -308,8 +324,9 @@ export default defineComponent({
label: 'Pubblicazione',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo,
mykey: 'date_pub',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'date_pub',
debounce: '1000',
type: costanti.FieldType.onlydate,
dense: true,
@@ -330,8 +347,9 @@ export default defineComponent({
label: 'Stato',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo,
mykey: 'idStatoProdotto',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'idStatoProdotto',
debounce: '1000',
type: costanti.FieldType.select,
jointable: 't_web_statiprodottos',
@@ -341,9 +359,10 @@ export default defineComponent({
editOn: true,
label: 'Argomento',
table: 'products',
id: myproduct.value.productInfo?._id,
rec: myproduct.value.productInfo,
mykey: 'idCatProds',
id: myproduct.value._id,
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'idCatProds',
debounce: '1000',
type: costanti.FieldType.multiselect,
jointable: 'catprods',
@@ -448,8 +467,9 @@ export default defineComponent({
label: 'Aggiornato (da GM) il',
table: 'products',
id: myproduct.value._id,
rec: myproduct.value.productInfo,
mykey: 'date_updated_fromGM',
rec: myproduct.value,
mykey: 'productInfo',
mysubkey: 'date_updated_fromGM',
debounce: '1000',
type: costanti.FieldType.onlydate,
dense: true,

View File

@@ -19,8 +19,11 @@ import MixinBase from '../../mixins/mixin-base'
export default defineComponent({
name: 'LandingFooter',
components: { Logo, FormNewsletter, CFacebookFrame },
setup() {
props: {
mykey: { type: String, required: false },
mysubkey: { type: String, required: false }
},
setup(props: { mykey?: string; mysubkey?: string }) {
const $q = useQuasar()
const { t } = useI18n()
const globalStore = useGlobalStore()
@@ -39,7 +42,37 @@ export default defineComponent({
return 'linear-gradient(180deg, ' + mycol + ' 95%, #FFF)'
})
// console.log('LandingFooter - INIT')
// New: Access nested product data via optional props
const productSource = computed(() => {
// Try to read a globally exposed product store value if present
try {
const gp: any = (globalStore as any).myproduct
if (gp && gp.value !== undefined) return gp.value
} catch {
// ignore
}
// Fallback: try to read from site.productInfo if available
try {
const s: any = site.value
if (s && s.productInfo) return s.productInfo
} catch {
// ignore
}
// Final fallback
return {}
})
const nestedProductValue = computed(() => {
const key = props.mykey
if (!key) return undefined
const base = (productSource.value as any)?.[key]
if (props.mysubkey && base && typeof base === 'object') {
return base[props.mysubkey]
}
return base
})
function TelegramSupport() {
return globalStore.getValueSettingsByKey('TELEGRAM_SUPPORT', false)
@@ -90,6 +123,7 @@ export default defineComponent({
site,
getBackColorText,
t,
nestedProductValue,
}
},
})

View File

@@ -256,13 +256,6 @@ export default function () {
if (idprod >= 0 && key) {
productStore.products[idprod][key as keyof IProduct] = value;
}
/*} else if (table === 'productinfos') {
const productStore = useProducts()
const idprod = productStore.products.findIndex((rec: IProduct) => rec.productInfo._id === id)
if (idprod >= 0 && key) {
const myfield = key as keyof IProductInfo
productStore.products[idprod].productInfo[myfield] = value
}*/
} else if (table === 'arrvariazioni') {
const productStore = useProducts();
const idprod = productStore.products.findIndex((rec: IProduct) => rec._id === id);

View File

@@ -14,12 +14,13 @@
v-model="checkAggiornaQta"
label="Aggiorna Quantità in Magazzino"
></q-toggle>
<label class="text-reader">
<br>&nbsp;</br>
<div class="text-reader q-ma-md q-pa-md text-center">
<input
type="file"
@change="loadTextFromFile"
/>
</label>
</div>
<br />
<br />