- Editor Pagine Elementi: Sezione, Righe, Colonne, Elementi. (rows, columns, elems)

This commit is contained in:
Surya Paolo
2025-09-08 01:02:32 +02:00
parent 63d0f865fd
commit cb0c26a43c
19 changed files with 1915 additions and 412 deletions

View File

@@ -1392,7 +1392,7 @@ export const useGlobalStore = defineStore('GlobalStore', {
// console.table(res)
return res.data;
})
.catch((error) => {
.catch((error: Types.AxiosError) => {
console.log('error loadPickup', error);
userStore.setErrorCatch(error);
return null;
@@ -2747,52 +2747,240 @@ export const useGlobalStore = defineStore('GlobalStore', {
);
},
async saveMyElem($q: any, t: any, myelem: IMyElem) {
const mydata = {
table: 'myelems',
data: {},
};
console.log(' DA SALVARE', myelem);
// Tipi base (adatta se già definiti altrove)
// type ElemType = typeof shared_consts.ELEMTYPE[keyof typeof shared_consts.ELEMTYPE];
mydata.data = myelem;
/* ===========================
* UTILITY / FINDERS
* =========================== */
return await this.saveTable(mydata)
.then(async (newelem) => {
if (newelem) {
console.log('*** newelem', newelem);
// Save in Memory
for (let i = 0; i < this.myelems.length; i++) {
if (this.myelems[i]._id === newelem._id) {
this.myelems[i] = newelem;
console.log('SALVATO', this.myelems[i]);
break;
}
}
// Aggiorna anche tutto il sito...
// await this.loadSite()
tools.showPositiveNotif($q, t('db.recupdated'));
} else {
tools.showNegativeNotif($q, t('db.recfailed'));
}
return newelem;
})
.catch((e) => {
tools.showNegativeNotif($q, t('db.recfailed'));
return false;
});
// Trova una section top-level per _id
findSectionById(this: any, sectionId: string) {
return this.myelems.find((e: IMyElem) => e._id === sectionId);
},
async addNewElem($q: any, t: any, myelem: IMyElem) {
const newelem = await this.saveMyElem($q, t, myelem);
if (newelem) {
this.myelems.push(newelem);
// Trova { row, section } a partire dall'id della row
findRowWithSection(this: any, rowId: string): { row?: IMyElem; section?: IMyElem } {
for (const section of this.myelems as IMyElem[]) {
const row = (section.rows || []).find((r) => r._id === rowId);
if (row) return { row, section };
}
return {};
},
// Trova { column, row, section } a partire dall'id della column
findColumnWithParents(
this: any,
columnId: string
): { column?: IMyElem; row?: IMyElem; section?: IMyElem } {
for (const section of this.myelems as IMyElem[]) {
for (const row of section.rows || []) {
const column = (row.columns || []).find((c) => c._id === columnId);
if (column) return { column, row, section };
}
}
return {};
},
// Piccolo helper per assicurare che la proprietà sia un array
ensureArray<T extends object, K extends keyof T>(obj: T, key: K) {
if (!Array.isArray(obj[key])) {
// @ts-ignore
obj[key] = [];
}
},
// Restituisce SEMPRE il contenitore top-level (section) da salvare.
// Se gli passi già una section, ritorna quella.
// Se gli passi row/column/elem, risale a partire dagli id.
resolveTopContainer(this: any, elem: IMyElem): IMyElem | null {
// 1) Se è già una section presente a top-level
if (
elem &&
(elem.rows || []).length >= 0 &&
this.myelems.some((s: IMyElem) => s._id === elem._id)
) {
return elem;
}
return newelem;
// 2) Prova con gli id noti
// - se elem è una row
if (elem?._id) {
const { row, section } = this.findRowWithSection.call(this, elem._id);
if (row && section) return section;
}
// - se elem è una column
if (elem?._id) {
const { column, section } = this.findColumnWithParents.call(this, elem._id);
if (column && section) return section;
}
// 3) Se ha idElemParent, risali finché non trovi la section top-level
let cursor: IMyElem | undefined = elem;
const byId = (id: string | undefined) => {
if (!id) return undefined;
// cerca a TUTTI i livelli
return (
(this.myelems as IMyElem[]).find((e) => e._id === id) ||
(this.myelems as IMyElem[])
.flatMap((s) => s.rows || [])
.find((r) => r._id === id) ||
(this.myelems as IMyElem[])
.flatMap((s) => s.rows || [])
.flatMap((r) => r.columns || [])
.find((c) => c._id === id) ||
(this.myelems as IMyElem[])
.flatMap((s) => s.rows || [])
.flatMap((r) => r.columns || [])
.flatMap((c) => c.elems || [])
.find((el) => el._id === id)
);
};
// risali la catena
while (cursor?.idElemParent) {
const parent = byId(cursor.idElemParent);
if (!parent) break;
// se il parent è una section top-level, fermati
if (this.myelems.some((s: IMyElem) => s._id === parent._id)) {
return parent;
}
cursor = parent;
}
return null;
},
/* ===========================
* SALVATAGGIO
* =========================== */
async saveContainer(this: any, $q: any, t: any, container: IMyElem) {
const payload = { table: 'myelems', data: container };
try {
const saved = await this.saveTable(payload);
if (saved) {
// aggiorna memoria: replace o push
const idx = (this.myelems as IMyElem[]).findIndex((e) => e._id === saved._id);
if (idx >= 0) this.myelems[idx] = saved;
else this.myelems.push(saved);
tools.showPositiveNotif($q, t('db.recupdated'));
return saved as IMyElem;
} else {
tools.showNegativeNotif($q, t('db.recfailed'));
return false;
}
} catch (e) {
tools.showNegativeNotif($q, t('db.recfailed'));
return false;
}
},
/* ===========================
* API PUBBLICHE
* =========================== */
async saveMyElem(this: any, $q: any, t: any, myelem: IMyElem) {
// Decide cosa salvare:
// - se è un semplice nuovo top-level, salva lui
// - altrimenti risali al contenitore top-level (section)
const container = this.resolveTopContainer.call(this, myelem) ?? myelem;
return await this.saveContainer.call(this, $q, t, container);
},
// Dispatcher snello (compatibile con la tua firma esistente)
async addNewElem(
this: any,
$q: any,
t: any,
myelemOrig: IMyElem, // "dove" sto aggiungendo
myelemDest: IMyElem // "cosa" sto aggiungendo
) {
switch (true) {
case myelemOrig.type === shared_consts.ELEMTYPE.SECTION &&
myelemDest && myelemDest.type === shared_consts.ELEMTYPE.ROW:
return await this.addRowToSection.call(
this,
$q,
t,
myelemOrig._id!,
myelemDest
);
case myelemOrig.type === shared_consts.ELEMTYPE.ROW &&
myelemDest && myelemDest.type === shared_consts.ELEMTYPE.COLUMN:
return await this.addColumnToRow.call(this, $q, t, myelemOrig._id!, myelemDest);
case myelemOrig.type === shared_consts.ELEMTYPE.COLUMN:
return await this.addElemToColumn.call(
this,
$q,
t,
myelemOrig._id!,
myelemDest
);
default:
// fallback: crea/salva un record "piatto" top-level
const saved = await this.saveMyElem.call(this, $q, t, myelemDest);
if (saved && !(this.myelems as IMyElem[]).some((e) => e._id === saved._id)) {
this.myelems.push(saved);
}
return saved;
}
},
/* ===========================
* HELPERS DI AGGIUNTA
* =========================== */
async addRowToSection(
this: any,
$q: any,
t: any,
sectionId: string,
newRow: IMyElem
) {
const section = this.findSectionById.call(this, sectionId);
if (!section) return false;
this.ensureArray(section, 'rows');
newRow.idElemParent = section._id!;
(section.rows as IMyElem[]).push(newRow);
return await this.saveMyElem.call(this, $q, t, section);
},
async addColumnToRow(this: any, $q: any, t: any, rowId: string, newCol: IMyElem) {
const { row, section } = this.findRowWithSection.call(this, rowId);
if (!row || !section) return false;
this.ensureArray(row, 'columns');
newCol.idElemParent = row._id!;
(row.columns as IMyElem[]).push(newCol);
// Salva la SECTION (contenitore)
return await this.saveMyElem.call(this, $q, t, section);
},
async addElemToColumn(
this: any,
$q: any,
t: any,
columnId: string,
newElem: IMyElem
) {
const { column, row, section } = this.findColumnWithParents.call(this, columnId);
if (!column || !row || !section) return false;
this.ensureArray(column, 'elems');
newElem.idElemParent = column._id!;
(column.elems as IMyElem[]).push(newElem);
// Salva la SECTION (contenitore)
return await this.saveMyElem.call(this, $q, t, section);
},
changeVisuDrawer(path: string, edit: boolean) {
@@ -2854,17 +3042,25 @@ export const useGlobalStore = defineStore('GlobalStore', {
};
},
async prepareAddNewElem(order: any, $q: any, t: any, myelem: any, newtype: any) {
async prepareAddNewElem(
order: any,
$q: any,
t: any,
myelemOrig: any,
myelemDest: any,
newtype: any
) {
const newrec: IMyElem = {
_id: undefined,
type: newtype,
path: myelem.path,
idPage: myelem.idPage,
path: myelemDest.path,
idPage: myelemDest.idPage,
order: order ? order : 1000,
active: true,
container: '',
};
// Gestisci altri tipi di elementi con configurazioni specifiche
if (newrec.type === shared_consts.ELEMTYPE.CAROUSEL_IMGS) {
newrec.container2 = '8';
newrec.height = 600;
@@ -2876,9 +3072,16 @@ export const useGlobalStore = defineStore('GlobalStore', {
newrec.catalogo = this.createCatalogoVuoto();
} else if (newrec.type === shared_consts.ELEMTYPE.RACCOLTA) {
newrec.catalogo = this.createRaccoltaCataloghiVuoto();
} else if (newrec.type === shared_consts.ELEMTYPE.TEXT) {
newrec.container = "Inserisci qui il testo"
} else if (newrec.type === shared_consts.ELEMTYPE.HTML) {
newrec.containerHtml = "Inserisci qui il testo"
} else if (newrec.type === shared_consts.ELEMTYPE.IMAGEUPLOAD) {
newrec.containerHtml
}
const mynewrec = await this.addNewElem($q, t, newrec);
// Aggiungi il nuovo elemento alla struttura
const mynewrec = await this.addNewElem($q, t, myelemOrig, newrec);
return mynewrec;
},