Files
myprojplanet_vite/src/components/CGallery/CGallery.ts
2025-08-12 19:43:36 +02:00

522 lines
13 KiB
TypeScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { PropType } from 'vue';
import { defineComponent, ref, watch, onMounted, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useUserStore } from '@store/UserStore';
import { useQuasar } from 'quasar';
import type { IImgGallery } from 'model';
import { IGallery } from 'model';
import { CMyPage } from '@src/components/CMyPage';
import { tools } from '@tools';
import { useGlobalStore } from '@store/globalStore';
import { costanti } from '@costanti';
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({
name: 'CGallery',
props: {
edit: {
type: Boolean,
required: true,
},
canModify: {
type: Boolean,
required: true,
},
isInModif: {
type: Boolean,
required: false,
default: false,
},
single: {
type: Boolean,
required: false,
default: false,
},
title: String,
directory: {
type: String,
required: true,
},
imagebak: {
type: String,
required: false,
default: '',
},
filetype: {
type: Number,
required: false,
default: shared_consts.FILETYPE.IMG,
},
quality: {
type: String,
required: false,
default: 'original',
},
resize: {
type: Boolean,
required: false,
default: false,
},
fieldtype: {
type: Number,
required: false,
default: 0,
},
imgGall: {
type: Object as PropType<IImgGallery[] | string | undefined | null>,
required: true,
},
},
emits: ['showandsave'],
components: { CMyPage },
setup(props, { emit }) {
const $q = useQuasar();
const { t } = useI18n();
const userStore = useUserStore();
const globalStore = useGlobalStore();
const displayGall = ref(false);
const gallerylist = ref(<IImgGallery[]>[]);
const maximizedToggle = ref(true);
const fullscreen = ref(false);
const fullscreensrc = ref('');
const upl = 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';
}
const isListImgValid = computed(() => {
const arr = getlistimages();
if (arr && tools.isArray(arr)) {
return arr.length > 0;
} else {
return !!arr;
}
});
watch(
() => props.imgGall,
(newval, oldval) => {
if (isValid(props.imgGall)) {
// @ts-ignore
gallerylist.value = props.imgGall;
}
}
);
function created() {
// console.log('created cgallery')
if (isValid(props.imgGall)) {
// @ts-ignore
let myarr: any = props.imgGall;
gallerylist.value = [];
if (Array.isArray(myarr)) {
myarr.forEach((pic: any) => {
if (pic?.imagefile) {
gallerylist.value.push(pic);
} else {
gallerylist.value.push(pic);
}
});
}
} else {
gallerylist.value = [];
}
uploadOptions.value = {
quality: props.quality,
resize: props.resize,
};
}
function getnumimages() {
if (gallerylist.value) return gallerylist.value.length;
else return 0;
}
function getlistimages() {
if (gallerylist.value)
// return gallerylist.value.slice().sort((a: any, b: any) => a.order! - b.order!)
//return gallerylist.value.filter(filename => !filename)
return gallerylist.value;
else return null;
}
function onDragStart(e: any) {
console.log('onDragStart');
e.dataTransfer.setData('text', e.target.id);
e.dataTransfer.dropEffect = 'move';
}
function onDragEnter(e: any) {
if (props.canModify) {
// don't drop on other draggables
if (e.target.draggable !== true) {
e.target.classList.add('drag-enter');
}
}
}
function onDragLeave(e: any) {
if (props.canModify) {
e.target.classList.remove('drag-enter');
}
}
function onDragOver(e: any) {
if (props.canModify) {
e.preventDefault();
}
}
function onDrop(e: any) {
if (props.canModify) {
console.log('onDrop', e);
e.preventDefault();
// don't drop on other draggables
if (e.target.draggable === true) {
return;
}
if (gallerylist.value) {
const draggedId = e.dataTransfer.getData('text');
let dragout = '';
try {
dragout = e.target.parentNode.parentNode.parentNode.id;
} catch (err) {
dragout = '';
}
const draggedEl = document.getElementById(draggedId);
console.log('draggedId', draggedId, 'draggedEl', draggedEl);
console.log('dragout', dragout);
// check if original parent node
if (draggedEl) {
if (draggedEl.parentNode === e.target) {
e.target.classList.remove('drag-enter');
return;
}
}
const myindexIn = gallerylist.value.findIndex(
(rec: any) => rec._id === draggedId
);
const myrecIn: IImgGallery = gallerylist.value[myindexIn];
let myrecOut: IImgGallery;
const myindexout = gallerylist.value.findIndex(
(rec: any) => rec._id === dragout
);
myrecOut = gallerylist.value[myindexout];
if (myindexIn === myindexout) return;
tools.array_move(gallerylist.value, myindexIn, myindexout);
// make the exchange
// draggedEl.parentNode.removeChild(draggedEl)
// e.target.appendChild(draggedEl)
e.target.classList.remove('drag-enter');
save();
}
}
}
function getclass() {
return props.edit || displayGall.value
? props.isInModif
? 'my-card-gallery'
: 'my-card-gallery-noModif'
: 'my-card-gallery-view' + ' text-center';
}
function getclimg() {
let mycl = props.edit || displayGall.value ? 'myimg' : 'myimg-view';
if (props.canModify && props.edit) mycl = mycl + ' myimg-modify';
return mycl;
}
/*function getlastord() {
if (gallerylist.value) {
let myord = 0
for (const file of gallerylist.value) {
if (file.order! > myord)
myord = file.order!
}
return myord + 10
}
}*/
function uploaded(info: any) {
console.log('uploaded', info);
let vers_img = tools.getGenerateVersionImage();
if (gallerylist.value) {
console.log('vers_img', vers_img);
if (props.single && info.files) {
console.log('gallerylist.value[0]', info.files[0].name);
if (info.files[0].name.imagefile) {
gallerylist.value[0] = info.files[0].name;
} else {
gallerylist.value[0] = { imagefile: info.files[0].name, vers_img, fieldtype: props.fieldtype };
}
} else {
for (const file of info.files) {
if (file.name.imagefile) {
gallerylist.value.push(file.name);
} else {
gallerylist.value.push({ imagefile: file.name, vers_img, fieldtype: props.fieldtype });
}
}
}
save();
console.log('CGALLERY gallerylist', gallerylist.value);
}
}
function apri() {
displayGall.value = true;
}
function deleted(rec: any) {
console.log('deleted', rec.imagefile);
// console.table(mylistimages)
if (gallerylist.value) {
const index = gallerylist.value.findIndex(
(elem: any) => elem.imagefile === rec.imagefile
);
if (index > -1) {
gallerylist.value.splice(index, 1);
}
gallerylist.value = gallerylist.value.filter(
(elem: any) => typeof elem.imagefile === 'string' && elem.imagefile
);
// mylistimages = mylistimages.pop((elem) => elem.imagefile !== rec.imagefile)
// console.table(mylistimages)
console.log('single', props.single);
save();
}
}
function getfullname(rec: any) {
if (rec) {
return tools.getDirUpload() + props.directory + '/' + rec.imagefile;
} else {
return props.imagebak;
}
}
function copytoclipboard(rec: any) {
const filename = getfullname(rec);
tools.copyStringToClipboard($q, filename, true);
}
function deleteFile(rec: any) {
console.log('deleteFile....');
const filename = getfullname(rec);
const filenamerel = filename.replace(/^.*[\\\/]/, '');
$q.dialog({
message: 'Eliminare il file ' + filenamerel + '?',
html: true,
ok: {
label: 'Elimina',
push: true,
},
title: filenamerel,
cancel: true,
persistent: false,
}).onOk(async () => {
// Delete File on server:
const ris = await globalStore.DeleteFile({ filename });
// console.log('ris', ris)
//if (ris)
deleted(rec);
});
}
function save() {
console.log('CGallery save', gallerylist.value);
if (gallerylist.value.length > 0) {
if (!props.single) {
emit('showandsave', gallerylist.value);
} else {
emit('showandsave', gallerylist.value[0]);
}
} else {
emit('showandsave', !props.single ? [] : '');
}
}
function close() {
return '';
}
function getrealdirectory() {
if (props.directory == 'productinfos') return 'products';
else return props.directory;
}
function getParamDir() {
return tools.escapeslash(getrealdirectory());
}
function getUrl() {
const myurl = tools.geturlupload() + getParamDir();
console.log('myurl', myurl);
return myurl;
}
function ImgFullScreen(mygallery: IImgGallery) {
fullscreen.value = true;
fullscreensrc.value = getfullname(mygallery);
}
function onRejected(rejectedEntries: any) {
// Notify plugin needs to be installed
// https://quasar.dev/quasar-plugins/notify#Installation
console.log('rejectedEntries', rejectedEntries);
$q.notify({
type: 'negative',
message: "La Dimensione massima dell'immagine è di 2 MB",
});
}
function getFileTypeStr() {
let tipo = '';
if (props.filetype === shared_consts.FILETYPE.IMG) tipo = 'Immagine';
else if (props.filetype === shared_consts.FILETYPE.PDF) tipo = 'PDF';
return tipo;
}
function getAccept() {
let tipo = '';
if (props.filetype === shared_consts.FILETYPE.IMG) tipo = 'image/*';
else if (props.filetype === shared_consts.FILETYPE.PDF) tipo = 'application/pdf';
return tipo;
}
function isPDF() {
return props.filetype === shared_consts.FILETYPE.PDF;
}
function isIMG() {
return props.filetype === shared_consts.FILETYPE.IMG;
}
const uploadFactory = async (files: readonly File[]) => {
const userStore = useUserStore();
const url = getUrl();
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 {
getlistimages,
onDragStart,
onDragEnter,
onDragLeave,
onDragOver,
onDrop,
getclass,
getclimg,
copytoclipboard,
deleteFile,
tools,
uploaded,
gallerylist,
getnumimages,
apri,
displayGall,
save,
maximizedToggle,
getUrl,
close,
ImgFullScreen,
fullscreen,
fullscreensrc,
onRejected,
isListImgValid,
costanti,
getrealdirectory,
uploadOptions,
getFileTypeStr,
getAccept,
shared_consts,
isIMG,
isPDF,
upl,
uploadFactory,
};
},
});