galleria prodotto

This commit is contained in:
Surya Paolo
2025-08-12 19:43:36 +02:00
parent f1f3f5ad07
commit 5d8e38fea6
25 changed files with 848 additions and 524 deletions

View File

@@ -1,15 +1,18 @@
import type { PropType } from 'vue'; import type { PropType } from 'vue';
import { defineComponent, ref, watch, onMounted, computed } from 'vue' import { defineComponent, ref, watch, onMounted, computed } from 'vue';
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n';
import { useUserStore } from '@store/UserStore' import { useUserStore } from '@store/UserStore';
import { useQuasar } from 'quasar' import { useQuasar } from 'quasar';
import type { IImgGallery } from 'model'; import type { IImgGallery } from 'model';
import { IGallery } from 'model' import { IGallery } from 'model';
import { CMyPage } from '@src/components/CMyPage' import { CMyPage } from '@src/components/CMyPage';
import { tools } from '@tools' import { tools } from '@tools';
import { useGlobalStore } from '@store/globalStore' import { useGlobalStore } from '@store/globalStore';
import { costanti } from '@costanti' import { costanti } from '@costanti';
import { shared_consts } from 'app/src/common/shared_vuejs'; import { shared_consts } from 'app/src/common/shared_vuejs';
import { Api } from 'app/src/store/Api';
import axios from 'app/src/boot/axios';
import { toolsext } from 'app/src/store/Modules/toolsext';
export default defineComponent({ export default defineComponent({
name: 'CGallery', name: 'CGallery',
@@ -57,6 +60,11 @@ export default defineComponent({
required: false, required: false,
default: false, default: false,
}, },
fieldtype: {
type: Number,
required: false,
default: 0,
},
imgGall: { imgGall: {
type: Object as PropType<IImgGallery[] | string | undefined | null>, type: Object as PropType<IImgGallery[] | string | undefined | null>,
required: true, required: true,
@@ -65,174 +73,182 @@ export default defineComponent({
emits: ['showandsave'], emits: ['showandsave'],
components: { CMyPage }, components: { CMyPage },
setup(props, { emit }) { setup(props, { emit }) {
const $q = useQuasar() const $q = useQuasar();
const { t } = useI18n() const { t } = useI18n();
const userStore = useUserStore() const userStore = useUserStore();
const globalStore = useGlobalStore() const globalStore = useGlobalStore();
const displayGall = ref(false) const displayGall = ref(false);
const gallerylist = ref(<IImgGallery[]>[]) const gallerylist = ref(<IImgGallery[]>[]);
const maximizedToggle = ref(true) const maximizedToggle = ref(true);
const fullscreen = ref(false) const fullscreen = ref(false);
const fullscreensrc = ref('') const fullscreensrc = ref('');
const uploadOptions = ref({ // qui definisci le opzioni da passare const upl = ref();
const uploadOptions = ref({
// qui definisci le opzioni da passare
quality: 'original', // esempio di opzione di qualità quality: 'original', // esempio di opzione di qualità
resize: true // opzione per abilitare il ridimensionamento resize: true, // opzione per abilitare il ridimensionamento
}) });
function isValid(myobj: any): boolean { function isValid(myobj: any): boolean {
return (myobj && typeof myobj !== 'string' && typeof myobj !== 'undefined') return myobj && typeof myobj !== 'string' && typeof myobj !== 'undefined';
} }
const isListImgValid = computed(() => { const isListImgValid = computed(() => {
const arr = getlistimages() const arr = getlistimages();
if (arr && tools.isArray(arr)) { if (arr && tools.isArray(arr)) {
return arr.length > 0 return arr.length > 0;
} else { } else {
return !!arr return !!arr;
} }
}) });
watch(() => props.imgGall, (newval, oldval) => { watch(
if (isValid(props.imgGall)) { () => props.imgGall,
// @ts-ignore (newval, oldval) => {
gallerylist.value = props.imgGall if (isValid(props.imgGall)) {
// @ts-ignore
gallerylist.value = props.imgGall;
}
} }
}) );
function created() { function created() {
// console.log('created cgallery') // console.log('created cgallery')
if (isValid(props.imgGall)) { if (isValid(props.imgGall)) {
// @ts-ignore // @ts-ignore
let myarr: any = props.imgGall let myarr: any = props.imgGall;
gallerylist.value = [] gallerylist.value = [];
if (Array.isArray(myarr)) { if (Array.isArray(myarr)) {
myarr.forEach((pic: any) => { myarr.forEach((pic: any) => {
if (pic.imagefile) { if (pic?.imagefile) {
gallerylist.value.push(pic) gallerylist.value.push(pic);
} else {
gallerylist.value.push(pic);
} }
}) });
} }
} else { } else {
gallerylist.value = [ gallerylist.value = [];
]
} }
uploadOptions.value = { uploadOptions.value = {
quality: props.quality, quality: props.quality,
resize: props.resize, resize: props.resize,
} };
} }
function getnumimages() { function getnumimages() {
if (gallerylist.value) if (gallerylist.value) return gallerylist.value.length;
return gallerylist.value.length else return 0;
else
return 0
} }
function getlistimages() { function getlistimages() {
if (gallerylist.value) if (gallerylist.value)
// return gallerylist.value.slice().sort((a: any, b: any) => a.order! - b.order!) // return gallerylist.value.slice().sort((a: any, b: any) => a.order! - b.order!)
//return gallerylist.value.filter(filename => !filename) //return gallerylist.value.filter(filename => !filename)
return gallerylist.value return gallerylist.value;
else else return null;
return null
} }
function onDragStart(e: any) { function onDragStart(e: any) {
console.log('onDragStart') console.log('onDragStart');
e.dataTransfer.setData('text', e.target.id) e.dataTransfer.setData('text', e.target.id);
e.dataTransfer.dropEffect = 'move' e.dataTransfer.dropEffect = 'move';
} }
function onDragEnter(e: any) { function onDragEnter(e: any) {
if (props.canModify) { if (props.canModify) {
// don't drop on other draggables // don't drop on other draggables
if (e.target.draggable !== true) { if (e.target.draggable !== true) {
e.target.classList.add('drag-enter') e.target.classList.add('drag-enter');
} }
} }
} }
function onDragLeave(e: any) { function onDragLeave(e: any) {
if (props.canModify) { if (props.canModify) {
e.target.classList.remove('drag-enter') e.target.classList.remove('drag-enter');
} }
} }
function onDragOver(e: any) { function onDragOver(e: any) {
if (props.canModify) { if (props.canModify) {
e.preventDefault() e.preventDefault();
} }
} }
function onDrop(e: any) { function onDrop(e: any) {
if (props.canModify) { if (props.canModify) {
console.log('onDrop', e) console.log('onDrop', e);
e.preventDefault() e.preventDefault();
// don't drop on other draggables // don't drop on other draggables
if (e.target.draggable === true) { if (e.target.draggable === true) {
return return;
} }
if (gallerylist.value) { if (gallerylist.value) {
const draggedId = e.dataTransfer.getData('text');
const draggedId = e.dataTransfer.getData('text') let dragout = '';
let dragout = ''
try { try {
dragout = e.target.parentNode.parentNode.parentNode.id dragout = e.target.parentNode.parentNode.parentNode.id;
} catch (err) { } catch (err) {
dragout = '' dragout = '';
} }
const draggedEl = document.getElementById(draggedId) const draggedEl = document.getElementById(draggedId);
console.log('draggedId', draggedId, 'draggedEl', draggedEl) console.log('draggedId', draggedId, 'draggedEl', draggedEl);
console.log('dragout', dragout) console.log('dragout', dragout);
// check if original parent node // check if original parent node
if (draggedEl) { if (draggedEl) {
if (draggedEl.parentNode === e.target) { if (draggedEl.parentNode === e.target) {
e.target.classList.remove('drag-enter') e.target.classList.remove('drag-enter');
return return;
} }
} }
const myindexIn = gallerylist.value.findIndex((rec: any) => rec._id === draggedId) const myindexIn = gallerylist.value.findIndex(
const myrecIn: IImgGallery = gallerylist.value[myindexIn] (rec: any) => rec._id === draggedId
);
const myrecIn: IImgGallery = gallerylist.value[myindexIn];
let myrecOut: IImgGallery let myrecOut: IImgGallery;
const myindexout = gallerylist.value.findIndex((rec: any) => rec._id === dragout) const myindexout = gallerylist.value.findIndex(
myrecOut = gallerylist.value[myindexout] (rec: any) => rec._id === dragout
);
myrecOut = gallerylist.value[myindexout];
if (myindexIn === myindexout) if (myindexIn === myindexout) return;
return
tools.array_move(gallerylist.value, myindexIn, myindexout);
tools.array_move(gallerylist.value, myindexIn, myindexout)
// make the exchange // make the exchange
// draggedEl.parentNode.removeChild(draggedEl) // draggedEl.parentNode.removeChild(draggedEl)
// e.target.appendChild(draggedEl) // e.target.appendChild(draggedEl)
e.target.classList.remove('drag-enter') e.target.classList.remove('drag-enter');
save() save();
} }
} }
} }
function getclass() { function getclass() {
return (props.edit || displayGall.value) ? (props.isInModif ? 'my-card-gallery' : 'my-card-gallery-noModif') : 'my-card-gallery-view' + ' text-center' return props.edit || displayGall.value
? props.isInModif
? 'my-card-gallery'
: 'my-card-gallery-noModif'
: 'my-card-gallery-view' + ' text-center';
} }
function getclimg() { function getclimg() {
let mycl = (props.edit || displayGall.value) ? 'myimg' : 'myimg-view' let mycl = props.edit || displayGall.value ? 'myimg' : 'myimg-view';
if (props.canModify && props.edit) if (props.canModify && props.edit) mycl = mycl + ' myimg-modify';
mycl = mycl + ' myimg-modify' return mycl;
return mycl
} }
/*function getlastord() { /*function getlastord() {
@@ -248,79 +264,81 @@ export default defineComponent({
}*/ }*/
function uploaded(info: any) { function uploaded(info: any) {
console.log('uploaded', info) console.log('uploaded', info);
let vers_img = tools.getGenerateVersionImage() let vers_img = tools.getGenerateVersionImage();
if (gallerylist.value) { if (gallerylist.value) {
console.log('vers_img', vers_img) console.log('vers_img', vers_img);
if (props.single && info.files) { if (props.single && info.files) {
console.log('gallerylist.value[0]', info.files[0].name) console.log('gallerylist.value[0]', info.files[0].name);
if (info.files[0].name.imagefile) { if (info.files[0].name.imagefile) {
gallerylist.value[0] = info.files[0].name gallerylist.value[0] = info.files[0].name;
} else { } else {
gallerylist.value[0] = { imagefile: info.files[0].name, vers_img } gallerylist.value[0] = { imagefile: info.files[0].name, vers_img, fieldtype: props.fieldtype };
} }
} else { } else {
for (const file of info.files) { for (const file of info.files) {
if (file.name.imagefile) { if (file.name.imagefile) {
gallerylist.value.push(file.name) gallerylist.value.push(file.name);
} else { } else {
gallerylist.value.push({ imagefile: file.name, vers_img }) gallerylist.value.push({ imagefile: file.name, vers_img, fieldtype: props.fieldtype });
} }
} }
} }
save() save();
console.log('CGALLERY gallerylist', gallerylist.value) console.log('CGALLERY gallerylist', gallerylist.value);
} }
} }
function apri() { function apri() {
displayGall.value = true displayGall.value = true;
} }
function deleted(rec: any) { function deleted(rec: any) {
console.log('deleted', rec.imagefile) console.log('deleted', rec.imagefile);
// console.table(mylistimages) // console.table(mylistimages)
if (gallerylist.value) { if (gallerylist.value) {
const index = gallerylist.value.findIndex((elem: any) => elem.imagefile === rec.imagefile) const index = gallerylist.value.findIndex(
(elem: any) => elem.imagefile === rec.imagefile
);
if (index > -1) { if (index > -1) {
gallerylist.value.splice(index, 1) gallerylist.value.splice(index, 1);
} }
gallerylist.value = gallerylist.value.filter((elem: any) => typeof elem.imagefile === 'string' && elem.imagefile) gallerylist.value = gallerylist.value.filter(
(elem: any) => typeof elem.imagefile === 'string' && elem.imagefile
);
// mylistimages = mylistimages.pop((elem) => elem.imagefile !== rec.imagefile) // mylistimages = mylistimages.pop((elem) => elem.imagefile !== rec.imagefile)
// console.table(mylistimages) // console.table(mylistimages)
console.log('single', props.single) console.log('single', props.single);
save() save();
} }
} }
function getfullname(rec: any) { function getfullname(rec: any) {
if (rec) { if (rec) {
return tools.getDirUpload() + props.directory + '/' + rec.imagefile return tools.getDirUpload() + props.directory + '/' + rec.imagefile;
} else { } else {
return props.imagebak return props.imagebak;
} }
} }
function copytoclipboard(rec: any) { function copytoclipboard(rec: any) {
const filename = getfullname(rec) const filename = getfullname(rec);
tools.copyStringToClipboard($q, filename, true) tools.copyStringToClipboard($q, filename, true);
} }
function deleteFile(rec: any) { function deleteFile(rec: any) {
console.log('deleteFile....') console.log('deleteFile....');
const filename = getfullname(rec) const filename = getfullname(rec);
const filenamerel = filename.replace(/^.*[\\\/]/, '') const filenamerel = filename.replace(/^.*[\\\/]/, '');
$q.dialog({ $q.dialog({
message: 'Eliminare il file ' + filenamerel + '?', message: 'Eliminare il file ' + filenamerel + '?',
@@ -333,91 +351,134 @@ export default defineComponent({
cancel: true, cancel: true,
persistent: false, persistent: false,
}).onOk(async () => { }).onOk(async () => {
// Delete File on server: // Delete File on server:
const ris = await globalStore.DeleteFile({ filename }) const ris = await globalStore.DeleteFile({ filename });
// console.log('ris', ris) // console.log('ris', ris)
//if (ris) //if (ris)
deleted(rec) deleted(rec);
}) });
} }
function save() { function save() {
console.log('CGallery save', gallerylist.value) console.log('CGallery save', gallerylist.value);
if (gallerylist.value.length > 0) { if (gallerylist.value.length > 0) {
if (!props.single) { if (!props.single) {
emit('showandsave', gallerylist.value) emit('showandsave', gallerylist.value);
} else { } else {
emit('showandsave', gallerylist.value[0]) emit('showandsave', gallerylist.value[0]);
} }
} else { } else {
emit('showandsave', !props.single ? [] : '') emit('showandsave', !props.single ? [] : '');
} }
} }
function close() { function close() {
return '' return '';
} }
function getrealdirectory() { function getrealdirectory() {
if (props.directory == 'productinfos') if (props.directory == 'productinfos') return 'products';
return 'products' else return props.directory;
else
return props.directory
} }
function getParamDir() { function getParamDir() {
return tools.escapeslash(getrealdirectory()) return tools.escapeslash(getrealdirectory());
} }
function getUrl() { function getUrl() {
const myurl = tools.geturlupload() + getParamDir() const myurl = tools.geturlupload() + getParamDir();
console.log('myurl', myurl) console.log('myurl', myurl);
return myurl return myurl;
} }
function ImgFullScreen(mygallery: IImgGallery) { function ImgFullScreen(mygallery: IImgGallery) {
fullscreen.value = true fullscreen.value = true;
fullscreensrc.value = getfullname(mygallery) fullscreensrc.value = getfullname(mygallery);
} }
function onRejected(rejectedEntries: any) { function onRejected(rejectedEntries: any) {
// Notify plugin needs to be installed // Notify plugin needs to be installed
// https://quasar.dev/quasar-plugins/notify#Installation // https://quasar.dev/quasar-plugins/notify#Installation
console.log('rejectedEntries', rejectedEntries) console.log('rejectedEntries', rejectedEntries);
$q.notify({ $q.notify({
type: 'negative', type: 'negative',
message: 'La Dimensione massima dell\'immagine è di 2 MB' message: "La Dimensione massima dell'immagine è di 2 MB",
}) });
} }
function getFileTypeStr() { function getFileTypeStr() {
let tipo = '' let tipo = '';
if (props.filetype === shared_consts.FILETYPE.IMG) if (props.filetype === shared_consts.FILETYPE.IMG) tipo = 'Immagine';
tipo = 'Immagine' else if (props.filetype === shared_consts.FILETYPE.PDF) tipo = 'PDF';
else if (props.filetype === shared_consts.FILETYPE.PDF)
tipo = 'PDF'
return tipo return tipo;
} }
function getAccept() { function getAccept() {
let tipo = '' let tipo = '';
if (props.filetype === shared_consts.FILETYPE.IMG) if (props.filetype === shared_consts.FILETYPE.IMG) tipo = 'image/*';
tipo = 'image/*' else if (props.filetype === shared_consts.FILETYPE.PDF) tipo = 'application/pdf';
else if (props.filetype === shared_consts.FILETYPE.PDF)
tipo = 'application/pdf'
return tipo return tipo;
} }
function isPDF() { function isPDF() {
return props.filetype === shared_consts.FILETYPE.PDF return props.filetype === shared_consts.FILETYPE.PDF;
} }
function isIMG() { function isIMG() {
return props.filetype === shared_consts.FILETYPE.IMG return props.filetype === shared_consts.FILETYPE.IMG;
} }
const uploadFactory = async (files: readonly File[]) => {
const userStore = useUserStore();
const url = getUrl();
onMounted(created) const buildFormData = () => {
const fd = new FormData();
// "file" è il fieldName atteso dal backend (adegua se diverso)
files.forEach((f) => fd.append('file', f, f.name));
// opzionale: passaggio di options come nel tuo backend
fd.append('options', JSON.stringify({ quality: 'original' }));
return fd;
};
const sendOnce = async () => {
return Api.SendReq(url, 'POST', buildFormData());
};
try {
await sendOnce();
} catch (err: any) {
const status = err?.response?.status;
try {
// usa la tua logica centralizzata
Api.checkTokenScaduto(
status,
/*evitaloop*/ false,
url,
'POST',
null,
/*setAuthToken*/ true
);
if (ret !== null) {
// token aggiornato -> ritenta UNA volta
await sendOnce();
} else {
throw err;
}
} catch (err2: any) {
// se lhandler segnala re-login, mostra messaggio e rilancia
const mystatus = err2?.status || err2?.code;
if (mystatus === toolsext.ERR_RETRY_LOGIN) {
$q.notify({
type: 'warning',
message: 'Sessione scaduta. Effettua nuovamente il login.',
});
}
throw err2;
}
}
};
onMounted(created);
return { return {
getlistimages, getlistimages,
@@ -453,6 +514,8 @@ export default defineComponent({
shared_consts, shared_consts,
isIMG, isIMG,
isPDF, isPDF,
} upl,
} uploadFactory,
}) };
},
});

View File

@@ -322,7 +322,7 @@
:src="tools.getsrcimg(mygallery, getrealdirectory())" :src="tools.getsrcimg(mygallery, getrealdirectory())"
:class="getclimg()" :class="getclimg()"
@click="ImgFullScreen(mygallery)" @click="ImgFullScreen(mygallery)"
:alt="mygallery.alt" :alt="mygallery?.alt"
> >
<div <div
v-if="mygallery.description" v-if="mygallery.description"

View File

@@ -80,7 +80,7 @@ export default defineComponent({
function saveFielDim(rec: any, newval: any, col: IColGridTable) { function saveFielDim(rec: any, newval: any, col: IColGridTable) {
// console.log('saveFielDim', rec, 'newval', newval, 'col', col) // console.log('saveFielDim', rec, 'newval', newval, 'col', col)
if (col.fieldtype === costanti.FieldType.image) { if (col.fieldtype === costanti.FieldType.imagerec) {
if (!rec[col.name]) { if (!rec[col.name]) {
rec[col.name] = {} rec[col.name] = {}

View File

@@ -54,7 +54,7 @@
@update:model-value="modifElem" @update:model-value="modifElem"
:canEdit="true" :canEdit="true"
:canModify="true" :canModify="true"
:fieldtype="costanti.FieldType.image" :fieldtype="costanti.FieldType.imagerec"
@save="saveFielDim" @save="saveFielDim"
> >
</CMyFieldRec> </CMyFieldRec>

View File

@@ -553,9 +553,9 @@ export default defineComponent({
const iscatalogo = costanti.CATALOGO_FIELDS.includes(col.name); const iscatalogo = costanti.CATALOGO_FIELDS.includes(col.name);
const isscheda = costanti.SCHEDA_FIELDS.includes(col.name); const isscheda = costanti.SCHEDA_FIELDS.includes(col.name);
const isIImg = costanti.IMG_FIELDS.includes(col.name) && col.fieldtype === costanti.FieldType.image; const isIImg = costanti.IMG_FIELDS.includes(col.name) && col.fieldtype === costanti.FieldType.imagerec;
if (col.fieldtype === costanti.FieldType.image) { if (col.fieldtype === costanti.FieldType.imagerec) {
if (iscatalogo) { if (iscatalogo) {
myel.value.catalogo[col.name] = newval.imagefile; myel.value.catalogo[col.name] = newval.imagefile;
//console.log('SALVATO IN', col.name, newval.imagefile, 'RIS', myel.value.catalogo[col.name]) //console.log('SALVATO IN', col.name, newval.imagefile, 'RIS', myel.value.catalogo[col.name])

View File

@@ -711,7 +711,7 @@
@update:model-value="modifElem" @update:model-value="modifElem"
:canEdit="true" :canEdit="true"
:canModify="true" :canModify="true"
:fieldtype="costanti.FieldType.image" :fieldtype="costanti.FieldType.imagerec"
> >
</CMyFieldRec> </CMyFieldRec>
@@ -760,7 +760,7 @@
@update:model-value="modifElem" @update:model-value="modifElem"
:canEdit="true" :canEdit="true"
:canModify="true" :canModify="true"
:fieldtype="costanti.FieldType.image" :fieldtype="costanti.FieldType.imagerec"
> >
</CMyFieldRec> </CMyFieldRec>
<CMyFieldRec <CMyFieldRec
@@ -772,7 +772,7 @@
@update:model-value="modifElem" @update:model-value="modifElem"
:canEdit="true" :canEdit="true"
:canModify="true" :canModify="true"
:fieldtype="costanti.FieldType.image" :fieldtype="costanti.FieldType.imagerec"
> >
</CMyFieldRec> </CMyFieldRec>
<div class="row"> <div class="row">
@@ -947,7 +947,7 @@
@update:model-value="modifElem" @update:model-value="modifElem"
:canEdit="true" :canEdit="true"
:canModify="true" :canModify="true"
:fieldtype="costanti.FieldType.image" :fieldtype="costanti.FieldType.imagerec"
> >
</CMyFieldRec> </CMyFieldRec>
<CMyFieldRec <CMyFieldRec
@@ -1009,7 +1009,7 @@
:canEdit="true" :canEdit="true"
:canModify="true" :canModify="true"
:path="path" :path="path"
:fieldtype="costanti.FieldType.image" :fieldtype="costanti.FieldType.imagerec"
> >
</CMyFieldRec> </CMyFieldRec>
</div> </div>
@@ -1036,7 +1036,7 @@
@update:model-value="modifElem" @update:model-value="modifElem"
:canEdit="true" :canEdit="true"
:canModify="true" :canModify="true"
:fieldtype="costanti.FieldType.image" :fieldtype="costanti.FieldType.imagerec"
> >
</CMyFieldRec> </CMyFieldRec>
<div class=""> <div class="">

File diff suppressed because it is too large Load Diff

View File

@@ -564,7 +564,7 @@
</CAccomodation> </CAccomodation>
</div> </div>
<div <div
v-else-if="col.fieldtype === costanti.FieldType.image" v-else-if="col.fieldtype === costanti.FieldType.imagerec"
style="text-align: center" style="text-align: center"
> >
<div v-if="canEdit"> <div v-if="canEdit">
@@ -727,6 +727,77 @@
? [myvalue] ? [myvalue]
: [{ imagefile: myvalue, vers_img: 1 }] : [{ imagefile: myvalue, vers_img: 1 }]
" "
:fieldtype="col.fieldtype"
:edit="isviewfield()"
:canModify="canModify"
:isInModif="isInModif"
:single="true"
@update:imgGall="changevalRec"
@showandsave="Savedb"
>
</CGallery>
</div>
<div v-else>
<div
v-if="myvalue"
class="text-center"
>
<q-img
:src="myvalue"
class="text-center"
style="height: 100px; width: 100px"
alt="foto"
>
</q-img>
</div>
<div
v-else
class="text-center"
>
<q-img
:src="
col.showpicprofile_ifnotset
? userStore.getImgByProfile(row['profile'], true)
: '/images/noimg-user.svg'
"
class="text-center"
style="height: 100px; width: 100px"
alt="nessuna immagine"
>
</q-img>
</div>
<q-btn
v-if="myvalue"
label="Rimuovi Foto"
color="blue"
icon="fas fa-trash-alt"
size="sm"
@click="removephoto"
></q-btn>
</div>
</div>
<div v-else-if="col.fieldtype === costanti.FieldType.imgfile_sfuso">
<div v-if="canEdit">
{{ t('reg.photo') }}
<CGallery
:imagebak="
col.showpicprofile_ifnotset
? userStore.getImgByProfile(row['profile'], true)
: ''
"
:title="tools.getTitleGall(table)"
:directory="tools.getDirectoryGall(myrow, table, mypath)"
:imgGall="
myvalue && myvalue.imagefile
? [myvalue]
: [
{
imagefile: myvalue,
vers_img: 1,
fieldtype: col.fieldtype,
},
]
"
:edit="isviewfield()" :edit="isviewfield()"
:canModify="canModify" :canModify="canModify"
:isInModif="isInModif" :isInModif="isInModif"
@@ -1978,6 +2049,40 @@
? [myvalue] ? [myvalue]
: [{ imagefile: myvalue, vers_img: 1 }] : [{ imagefile: myvalue, vers_img: 1 }]
" "
:fieldtype="col.fieldtype"
:edit="isviewfield()"
:canModify="canModify"
:isInModif="isInModif"
:single="true"
@update:imgGall="changevalRec"
@showandsave="Savedb"
>
</CGallery>
</div>
</div>
<div v-else-if="col.fieldtype === costanti.FieldType.imgfile_sfuso">
<div v-if="canEdit">
{{ t('reg.photo') }}
<CGallery
:imagebak="
col.showpicprofile_ifnotset
? userStore.getImgByProfile(row['profile'], true)
: ''
"
:title="tools.getTitleGall(table)"
:directory="tools.getDirectoryGall(myrow, table, mypath)"
:imgGall="
myvalue && myvalue.imagefile
? [myvalue]
: [
{
imagefile: myvalue,
vers_img: 1,
fieldtype: col.fieldtype,
},
]
"
:fieldtype="col.fieldtype"
:edit="isviewfield()" :edit="isviewfield()"
:canModify="canModify" :canModify="canModify"
:isInModif="isInModif" :isInModif="isInModif"

View File

@@ -203,7 +203,7 @@
table="users" table="users"
mykey="profile" mykey="profile"
mysubkey="img" mysubkey="img"
:type="costanti.FieldType.image" :type="costanti.FieldType.imagerec"
> >
</CMyFieldDb>--> </CMyFieldDb>-->
</div> </div>

View File

@@ -456,7 +456,7 @@
mykey="imagefile" mykey="imagefile"
debounce="1000" debounce="1000"
@save="updateproductmodif" @save="updateproductmodif"
:type="costanti.FieldType.image" :type="costanti.FieldType.imagerec"
> >
</CMyValueDb> </CMyValueDb>
</div> </div>
@@ -472,7 +472,7 @@
@update:model-value="modifElem" @update:model-value="modifElem"
:canEdit="true" :canEdit="true"
:canModify="true" :canModify="true"
:fieldtype="costanti.FieldType.image" :fieldtype="costanti.FieldType.imagerec"
> >
</CMyFieldRec>--> </CMyFieldRec>-->
</q-card-section> </q-card-section>

View File

@@ -6,7 +6,7 @@ import { CMyPage } from '@src/components/CMyPage'
import { CTitleBanner } from '@src/components/CTitleBanner' import { CTitleBanner } from '@src/components/CTitleBanner'
import { CGridTableRec } from '@src/components/CGridTableRec' import { CGridTableRec } from '@src/components/CGridTableRec'
import { colTableProductInfos } from '@src/store/Modules/fieldsTable' import { colTableProductInfosShort } from '@src/store/Modules/fieldsTable'
import MixinMetaTags from '@src/mixins/mixin-metatags' import MixinMetaTags from '@src/mixins/mixin-metatags'
export default defineComponent({ export default defineComponent({
@@ -17,7 +17,7 @@ export default defineComponent({
const { setmeta } = MixinMetaTags() const { setmeta } = MixinMetaTags()
return { return {
colTableProductInfos, colTableProductInfosShort,
setmeta, setmeta,
} }
} }

View File

@@ -13,7 +13,7 @@
<div class="q-ma-sm q-gutter-sm q-pa-xs"> <div class="q-ma-sm q-gutter-sm q-pa-xs">
<CTitleBanner title="Info Prodotti"></CTitleBanner> <CTitleBanner title="Info Prodotti"></CTitleBanner>
<CGridTableRec prop_mytable="productinfos" prop_mytitle="Lista Info Prodotti" <CGridTableRec prop_mytable="productinfos" prop_mytitle="Lista Info Prodotti"
:prop_mycolumns="colTableProductInfos" prop_colkey="name" nodataLabel="Nessun Info Prodotto" :prop_mycolumns="colTableProductInfosShort" prop_colkey="name" nodataLabel="Nessun Info Prodotto"
noresultLabel="Il filtro selezionato non ha trovato nessun risultato"> noresultLabel="Il filtro selezionato non ha trovato nessun risultato">
</CGridTableRec> </CGridTableRec>

View File

@@ -0,0 +1,24 @@
import { defineComponent } from 'vue'
import { CImgText } from '../../../components/CImgText/index'
import { CCard } from '@src/components/CCard'
import { CMyPage } from '@src/components/CMyPage'
import { CTitleBanner } from '@src/components/CTitleBanner'
import { CGridTableRec } from '@src/components/CGridTableRec'
import { colTableProductInfos } from '@src/store/Modules/fieldsTable'
import MixinMetaTags from '@src/mixins/mixin-metatags'
export default defineComponent({
name: 'productInfosComplete',
components: { CImgText, CCard, CMyPage, CTitleBanner, CGridTableRec },
setup() {
const { setmeta } = MixinMetaTags()
return {
colTableProductInfos,
setmeta,
}
}
})

View File

@@ -0,0 +1,28 @@
<template>
<CMyPage title="Info Prodotti" imgbackground="/images/prodotti.jpg" sizes="max-height: 120px">
<span>{{
setmeta({
title: 'Info Prodotti',
description: '',
keywords: '',
})
}}
</span>
<div class="q-ma-sm q-gutter-sm q-pa-xs">
<CTitleBanner title="Info Prodotti"></CTitleBanner>
<CGridTableRec prop_mytable="productinfos" prop_mytitle="Lista Info Prodotti"
:prop_mycolumns="colTableProductInfos" prop_colkey="name" nodataLabel="Nessun Info Prodotto"
noresultLabel="Il filtro selezionato non ha trovato nessun risultato">
</CGridTableRec>
</div>
</CMyPage>
</template>
<script lang="ts" src="./productInfosComplete.ts">
</script>
<style lang="scss" scoped>
@import 'productInfosComplete.scss';
</style>

View File

@@ -7,6 +7,7 @@ import { CTitleBanner } from '@src/components/CTitleBanner'
import { CGridTableRec } from '@src/components/CGridTableRec' import { CGridTableRec } from '@src/components/CGridTableRec'
import { colTableProducts } from '@src/store/Modules/fieldsTable' import { colTableProducts } from '@src/store/Modules/fieldsTable'
import { colTableProdShort } from '@src/store/Modules/fieldsTable'
import MixinMetaTags from '@src/mixins/mixin-metatags' import MixinMetaTags from '@src/mixins/mixin-metatags'
export default defineComponent({ export default defineComponent({
@@ -17,7 +18,7 @@ export default defineComponent({
const { setmeta } = MixinMetaTags() const { setmeta } = MixinMetaTags()
return { return {
colTableProducts, colTableProdShort,
setmeta, setmeta,
} }
} }

View File

@@ -7,7 +7,7 @@
<CGridTableRec <CGridTableRec
prop_mytable="products" prop_mytable="products"
prop_mytitle="Lista Prodotti" prop_mytitle="Lista Prodotti"
:prop_mycolumns="colTableProducts" :prop_mycolumns="colTableProdShort"
prop_colkey="name" prop_colkey="name"
nodataLabel="Nessun Prodotto" nodataLabel="Nessun Prodotto"
noresultLabel="Il filtro selezionato non ha trovato nessun risultato"> noresultLabel="Il filtro selezionato non ha trovato nessun risultato">

View File

@@ -101,10 +101,10 @@ function getRoutesEcomm(site: ISites) {
{ {
active: true, active: true,
order: 30, order: 30,
path: '/admin/ecommerce/gestoreordini', path: '/admin/ecommerce/products',
materialIcon: 'fas fa-lemon', materialIcon: 'fas fa-lemon',
name: 'mypages.gestoreordini', name: 'mypages.listinoprodotti',
component: () => import('@src/views/admin/gestoreordini/gestoreordini.vue'), component: () => import('@src/rootgen/admin/products/products.vue'),
inmenu: true, inmenu: true,
submenu: true, submenu: true,
level_parent: 0, level_parent: 0,
@@ -115,10 +115,10 @@ function getRoutesEcomm(site: ISites) {
{ {
active: true, active: true,
order: 30, order: 30,
path: '/admin/ecommerce/products', path: '/admin/ecommerce/gestoreordini',
materialIcon: 'fas fa-lemon', materialIcon: 'fas fa-lemon',
name: 'mypages.listinoprodotti', name: 'mypages.gestoreordini',
component: () => import('@src/rootgen/admin/products/products.vue'), component: () => import('@src/views/admin/gestoreordini/gestoreordini.vue'),
inmenu: true, inmenu: true,
submenu: true, submenu: true,
level_parent: 0, level_parent: 0,

View File

@@ -112,7 +112,7 @@ function getIterableStream(stream: NodeJS.ReadableStream): AsyncIterable<any> {
} }
// Funzione helper per inviare la richiesta HTTP // Funzione helper per inviare la richiesta HTTP
async function Request(type, path, payload, responsedata = {}, options = {}) { async function Request(type: string, path: string, payload: any, responsedata = {}, options: any = {}) {
const userStore = useUserStore(); const userStore = useUserStore();
const globalStore = useGlobalStore(); const globalStore = useGlobalStore();
const baseURL = globalStore.getServerHost(); const baseURL = globalStore.getServerHost();

View File

@@ -122,7 +122,7 @@ export const Api = {
} }
}, },
async checkTokenScaduto(status, evitaloop, url, method, mydata, setAuthToken = false) { async checkTokenScaduto(status: number, evitaloop: boolean, url: string, method: string, mydata: any, setAuthToken: boolean = false) {
const userStore = useUserStore(); const userStore = useUserStore();
if (status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_TOKEN_EXPIRED) { if (status === serv_constants.RIS_CODE__HTTP_FORBIDDEN_TOKEN_EXPIRED) {
@@ -167,7 +167,7 @@ export const Api = {
}, },
// Base per la chiamata con gestione degli errori e retry // Base per la chiamata con gestione degli errori e retry
async SendReqBase(url, method, mydata, setAuthToken = false, evitaloop = false, myformdata, responsedata, options) { async SendReqBase(url: string, method: string, mydata: any, setAuthToken = false, evitaloop = false, myformdata: any, responsedata: any, options: any) {
const mydataout = { const mydataout = {
...mydata, ...mydata,
keyappid: import.meta.env.VITE_PAO_APP_ID, keyappid: import.meta.env.VITE_PAO_APP_ID,
@@ -199,7 +199,7 @@ export const Api = {
} }
// Verifica sul token (funzione custom) // Verifica sul token (funzione custom)
const ret = await this.checkTokenScaduto(res.status, evitaloop, url, method, mydata, setAuthToken); const ret: any = await this.checkTokenScaduto(res.status, evitaloop, url, method, mydata, setAuthToken);
if (ret) return ret; if (ret) return ret;
if (tools.isDebug()) console.log(' ----> ', res); if (tools.isDebug()) console.log(' ----> ', res);
@@ -214,7 +214,7 @@ export const Api = {
} }
}, 1000); }, 1000);
const ret = await this.checkTokenScaduto(error.status, evitaloop, url, method, mydataout, setAuthToken); const ret: any = await this.checkTokenScaduto(error.status, evitaloop, url, method, mydataout, setAuthToken);
if (ret) return ret; if (ret) return ret;
console.error('Errore nella richiesta:', error); console.error('Errore nella richiesta:', error);
@@ -255,7 +255,7 @@ export const Api = {
}, },
// Funzione che gestisce la chiamata con retry // Funzione che gestisce la chiamata con retry
async SendReq(url, method, mydata, setAuthToken = false, evitaloop = false, retryCount = 1, retryDelay = 5000, myformdata = null, responsedata = null, options = null) { async SendReq(url: string, method: string, mydata: any, setAuthToken = false, evitaloop = false, retryCount = 1, retryDelay = 5000, myformdata = null, responsedata = null, options = null) {
try { try {
return await this.SendReqBase(url, method, mydata, setAuthToken, evitaloop, myformdata, responsedata, options); return await this.SendReqBase(url, method, mydata, setAuthToken, evitaloop, myformdata, responsedata, options);
} catch (error) { } catch (error) {

View File

@@ -463,9 +463,10 @@ export const costanti = {
password: 512, password: 512,
listimages: 1024, listimages: 1024,
exact: 2048, exact: 2048,
image: 3000, imagerec: 3000,
pdf: 3050, pdf: 3050,
image_and_filename: 3100, image_and_filename: 3100,
imgfile_sfuso: 3150,
imgcard: 3500, imgcard: 3500,
coordinates: 3800, coordinates: 3800,
select_by_server: 4000, select_by_server: 4000,

View File

@@ -130,7 +130,7 @@ export const colTableRaccoltaCataloghi = [
AddCol({ AddCol({
name: 'foto_raccolta', name: 'foto_raccolta',
label_trans: 'racccat.foto_raccolta', label_trans: 'racccat.foto_raccolta',
fieldtype: costanti.FieldType.image, fieldtype: costanti.FieldType.imagerec,
jointable: '', jointable: '',
showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit, showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit,
isadvanced_field: false, isadvanced_field: false,
@@ -186,7 +186,7 @@ export const colTableCatalogList = [
AddCol({ AddCol({
name: 'foto_collana', name: 'foto_collana',
label_trans: 'cataloglist.foto_collana', label_trans: 'cataloglist.foto_collana',
fieldtype: costanti.FieldType.image, fieldtype: costanti.FieldType.imagerec,
jointable: '', jointable: '',
showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit, showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit,
isadvanced_field: false, isadvanced_field: false,
@@ -254,7 +254,7 @@ export const colTableCatalogList = [
AddCol({ AddCol({
name: 'img_bordata', name: 'img_bordata',
label_trans: 'cataloglist.img_bordata', label_trans: 'cataloglist.img_bordata',
fieldtype: costanti.FieldType.image, fieldtype: costanti.FieldType.imagerec,
jointable: '', jointable: '',
showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit, showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit,
isadvanced_field: false, isadvanced_field: false,
@@ -262,7 +262,7 @@ export const colTableCatalogList = [
AddCol({ AddCol({
name: 'img_intro', name: 'img_intro',
label_trans: 'cataloglist.img_intro', label_trans: 'cataloglist.img_intro',
fieldtype: costanti.FieldType.image, fieldtype: costanti.FieldType.imagerec,
jointable: '', jointable: '',
showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit, showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit,
isadvanced_field: false, isadvanced_field: false,
@@ -282,7 +282,7 @@ export const colTableCatalogList = [
AddCol({ AddCol({
name: 'img_bordata_stampa', name: 'img_bordata_stampa',
label_trans: 'cataloglist.img_bordata_stampa', label_trans: 'cataloglist.img_bordata_stampa',
fieldtype: costanti.FieldType.image, fieldtype: costanti.FieldType.imagerec,
jointable: '', jointable: '',
showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit, showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit,
isadvanced_field: false, isadvanced_field: false,
@@ -290,7 +290,7 @@ export const colTableCatalogList = [
AddCol({ AddCol({
name: 'img_intro_stampa', name: 'img_intro_stampa',
label_trans: 'cataloglist.img_intro_stampa', label_trans: 'cataloglist.img_intro_stampa',
fieldtype: costanti.FieldType.image, fieldtype: costanti.FieldType.imagerec,
jointable: '', jointable: '',
showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit, showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit,
isadvanced_field: false, isadvanced_field: false,
@@ -371,7 +371,7 @@ export const colIText = [
AddCol({ name: 'line_height', label_trans: 'catalogo.line_height', fieldtype: costanti.FieldType.number }), AddCol({ name: 'line_height', label_trans: 'catalogo.line_height', fieldtype: costanti.FieldType.number }),
] ]
export const colmyIImg = [ export const colmyIImg = [
AddCol({ name: 'imagefile', label_trans: 'iimg.imagefile', fieldtype: costanti.FieldType.image }), AddCol({ name: 'imagefile', label_trans: 'iimg.imagefile', fieldtype: costanti.FieldType.imagerec }),
AddCol({ name: 'fit', label_trans: 'iimg.fit', fieldtype: costanti.FieldType.string }), AddCol({ name: 'fit', label_trans: 'iimg.fit', fieldtype: costanti.FieldType.string }),
] ]
@@ -504,7 +504,7 @@ export const colmyelems = [
AddCol({ AddCol({
name: 'image', name: 'image',
label_trans: 'myelems.image', label_trans: 'myelems.image',
fieldtype: costanti.FieldType.image, fieldtype: costanti.FieldType.imagerec,
}), }),
AddCol(DeleteRec), AddCol(DeleteRec),
AddCol(DuplicateRec), AddCol(DuplicateRec),
@@ -1737,7 +1737,7 @@ export const colAttivita = [
AddCol({ AddCol({
name: 'logo', name: 'logo',
label_trans: 'attivita.logo', label_trans: 'attivita.logo',
fieldtype: costanti.FieldType.image, fieldtype: costanti.FieldType.imagerec,
jointable: '', jointable: '',
showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit, showWhen: costanti.showWhen.NewRec + costanti.showWhen.InPage + costanti.showWhen.InEdit,
isadvanced_field: false, isadvanced_field: false,
@@ -2699,6 +2699,21 @@ export const colTableVariazioni = [
AddCol({ name: 'eta', label_trans: 'catalogo.eta', fieldtype: costanti.FieldType.string }), AddCol({ name: 'eta', label_trans: 'catalogo.eta', fieldtype: costanti.FieldType.string }),
] ]
export const colTableProductInfosShort = [
AddCol({ name: 'code', label_trans: 'products.code', required: true }),
AddCol({ name: 'name', label_trans: 'products.name' }),
AddCol({ name: 'description', label_trans: 'products.description', fieldtype: costanti.FieldType.html }),
AddCol({ name: 'imagefile', label_trans: 'products.img', fieldtype: costanti.FieldType.imgfile_sfuso, path: 'products/' }),
AddCol({
name: 'idCatProds',
label_trans: 'products.category',
fieldtype: costanti.FieldType.multiselect,
jointable: 'catprods',
}),
AddCol(DeleteRec),
AddCol(DuplicateRec),
]
export const colTableProductInfos = [ export const colTableProductInfos = [
AddCol({ name: 'code', label_trans: 'products.code', required: true }), AddCol({ name: 'code', label_trans: 'products.code', required: true }),
AddCol({ name: 'codice_EAN', label_trans: 'products.codice_EAN' }), AddCol({ name: 'codice_EAN', label_trans: 'products.codice_EAN' }),
@@ -2768,6 +2783,20 @@ export const colTableOrdersCart = [
AddCol({ name: 'status', label_trans: 'orderscart.status', fieldtype: costanti.FieldType.number }), AddCol({ name: 'status', label_trans: 'orderscart.status', fieldtype: costanti.FieldType.number }),
] ]
export const colTableProdShort = [
AddCol({ name: 'active', label_trans: 'products.active', fieldtype: costanti.FieldType.boolean }),
AddCol({ name: 'name', label_trans: 'products.name' }),
AddCol({ name: 'price', label_trans: 'products.price', fieldtype: costanti.FieldType.number, required: true }),
AddCol({ name: 'price_acquistato', label_trans: 'products.price_acquistato', fieldtype: costanti.FieldType.number, required: true }),
AddCol({
name: 'idProductInfo',
label_trans: 'products.productInfo',
fieldtype: costanti.FieldType.select,
jointable: 'productinfos',
}),
]
export const colTableProducts = [ export const colTableProducts = [
AddCol({ name: 'active', label_trans: 'products.active', fieldtype: costanti.FieldType.boolean }), AddCol({ name: 'active', label_trans: 'products.active', fieldtype: costanti.FieldType.boolean }),
AddCol({ name: 'isbn', label_trans: 'products.isbn' }), AddCol({ name: 'isbn', label_trans: 'products.isbn' }),

View File

@@ -8937,7 +8937,7 @@ export const tools = {
} }
}, },
getDirectoryGall(myrow: any, table: string, path: string) { getDirectoryGall(myrow: any, table: string, path: string, fieldtype: number = 0) {
const userStore = useUserStore(); const userStore = useUserStore();
// console.log('getDirectoryGall', myrow) // console.log('getDirectoryGall', myrow)
@@ -10178,7 +10178,7 @@ export const tools = {
let eseguito = false; let eseguito = false;
// if (table === 'myelems') { // if (table === 'myelems') {
if (type === costanti.FieldType.image && newval.imagefile) { if (type === costanti.FieldType.imagerec && newval.imagefile) {
let myval = newval.imagefile; let myval = newval.imagefile;
await setValDb( await setValDb(
$q, $q,

View File

@@ -99,7 +99,7 @@
table="users" table="users"
mykey="profile" mykey="profile"
mysubkey="img" mysubkey="img"
:type="costanti.FieldType.image" :type="costanti.FieldType.imagerec"
> >
</CMyFieldDb> </CMyFieldDb>
</div> </div>

View File

@@ -26,7 +26,7 @@
table="users" table="users"
mykey="profile" mykey="profile"
mysubkey="img" mysubkey="img"
:type="costanti.FieldType.image"> :type="costanti.FieldType.imagerec">
</CMyFieldDb> </CMyFieldDb>
</div> </div>
<div class="myrow"> <div class="myrow">