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 } : {}, })), } } 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 } } /** * 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 } }