2026-04-07 11:58:07 +02:00
|
|
|
export function normalizeLayoutForEditor(layout) {
|
|
|
|
|
if (!layout?.widgets) return layout
|
|
|
|
|
return {
|
|
|
|
|
...layout,
|
|
|
|
|
widgets: layout.widgets.map((w) => ({
|
|
|
|
|
...w,
|
|
|
|
|
config: w.config && typeof w.config === 'object' ? { ...w.config } : {},
|
|
|
|
|
})),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 11:47:16 +02:00
|
|
|
export function moveWidget(layout, index, delta) {
|
|
|
|
|
const next = [...layout.widgets]
|
|
|
|
|
const j = index + delta
|
|
|
|
|
if (j < 0 || j >= next.length) return layout
|
|
|
|
|
const t = next[index]
|
|
|
|
|
next[index] = next[j]
|
|
|
|
|
next[j] = t
|
|
|
|
|
return { ...layout, widgets: next }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function toggleWidget(layout, index) {
|
|
|
|
|
const next = layout.widgets.map((w, i) => (i === index ? { ...w, enabled: !w.enabled } : w))
|
|
|
|
|
const anyOn = next.some((w) => w.enabled)
|
|
|
|
|
if (!anyOn) return layout
|
|
|
|
|
return { ...layout, widgets: next }
|
|
|
|
|
}
|
2026-04-08 07:58:52 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Verschiebt eine Zeile von fromIndex nach dropIndex (Indizes im vollen layout.widgets).
|
|
|
|
|
* Semantik wie üblich: Element landet an Position dropIndex (nach Entfernen an der alten Stelle).
|
|
|
|
|
*/
|
|
|
|
|
export function moveWidgetToIndex(layout, fromIndex, dropIndex) {
|
|
|
|
|
if (!layout?.widgets?.length) return layout
|
|
|
|
|
if (fromIndex < 0 || fromIndex >= layout.widgets.length) return layout
|
|
|
|
|
if (dropIndex < 0 || dropIndex > layout.widgets.length) return layout
|
|
|
|
|
if (fromIndex === dropIndex) return layout
|
|
|
|
|
const next = [...layout.widgets]
|
|
|
|
|
next.splice(dropIndex, 0, next.splice(fromIndex, 1)[0])
|
|
|
|
|
return { ...layout, widgets: next }
|
|
|
|
|
}
|