fix(planner): fix widget layout drag-and-drop order persistence across page navigation

This commit is contained in:
2026-09-11 15:25:19 +02:00
parent 0436c076e3
commit 88ec1418cf
2 changed files with 74 additions and 28 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../includes/integrations/microsoft.php';
$user = require_auth();
$user = require_auth(true);
$db = get_db_connection();
header('Content-Type: application/json');
+73 -27
View File
@@ -2247,17 +2247,25 @@ async function saveWidgetLayoutConfig() {
btn.disabled = true;
try {
const payload = focizWidgets.map((w, idx) => ({
focizWidgets.forEach((item, idx) => {
item.order = idx + 1;
});
const payload = focizWidgets.map((w) => ({
id: w.id,
enabled: !!w.enabled,
col_span: parseInt(w.col_span, 10) || 6,
order: idx + 1
order: w.order
}));
try {
localStorage.setItem('fociz_widget_layout_cache', JSON.stringify(payload));
} catch(e) {}
const res = await fetch('/api/planner.php?action=save_widget_layout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ layout: payload })
body: JSON.stringify({ layout: payload }),
keepalive: true
});
const data = await res.json();
if (data.success) {
@@ -2322,20 +2330,71 @@ function showWidgetToast(htmlMessage, type = 'success', duration = 3500) {
}, duration);
}
// --- Achtergrond Auto-Save voor Widget Layout ---
async function persistWidgetLayoutAuto() {
// --- Bepaal de actuele widget layout en exacte volgorde uit het scherm (DOM) ---
function getActiveWidgetLayoutPayload() {
const grid = document.getElementById('focizWidgetGrid');
const seenIds = new Set();
const payload = [];
let currentOrder = 1;
// 1. Zichtbare widgets in het raster in hun exacte visuele volgorde op het scherm
if (grid) {
const wrappers = Array.from(grid.querySelectorAll('.fociz-widget-wrapper'));
wrappers.forEach(wrap => {
const wId = wrap.getAttribute('data-widget-id');
if (wId && !seenIds.has(wId)) {
seenIds.add(wId);
const item = focizWidgets.find(x => x.id === wId);
const colSpan = parseInt(wrap.getAttribute('data-col-span'), 10) || (item ? parseInt(item.col_span, 10) : 6);
const widgetObj = {
id: wId,
enabled: true,
col_span: colSpan,
order: currentOrder++
};
payload.push(widgetObj);
if (item) {
item.order = widgetObj.order;
item.col_span = colSpan;
item.enabled = true;
}
}
});
}
// 2. Uitgeschakelde of verborgen widgets achteraan toevoegen
focizWidgets.forEach(w => {
if (!seenIds.has(w.id)) {
seenIds.add(w.id);
payload.push({
id: w.id,
enabled: !!w.enabled,
col_span: parseInt(w.col_span, 10) || 6,
order: currentOrder++
});
}
});
// 3. Sorteer focizWidgets array in het geheugen synchroon met de nieuwe volgorde
focizWidgets.sort((a, b) => (a.order || 0) - (b.order || 0));
return payload;
}
// --- Achtergrond Auto-Save voor Widget Layout met keepalive ---
async function persistWidgetLayoutAuto(customPayload = null) {
try {
const payload = focizWidgets.map((w, idx) => ({
id: w.id,
enabled: !!w.enabled,
col_span: parseInt(w.col_span, 10) || 6,
order: idx + 1
}));
const payload = customPayload || getActiveWidgetLayoutPayload();
try {
localStorage.setItem('fociz_widget_layout_cache', JSON.stringify(payload));
} catch(e) {}
const res = await fetch('/api/planner.php?action=save_widget_layout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ layout: payload })
body: JSON.stringify({ layout: payload }),
keepalive: true
});
const data = await res.json();
return data.success;
@@ -2775,21 +2834,8 @@ function cancelWidgetDragging() {
// Controleer gewijzigde volgorde en sla asynchroon op via AJAX
function saveCurrentGridOrderIfChanged() {
const grid = document.getElementById('focizWidgetGrid');
if (!grid) return;
const currentWrappers = Array.from(grid.querySelectorAll('.fociz-widget-wrapper'));
// Synchroniseer de order in focizWidgets met de actuele DOM-volgorde
currentWrappers.forEach((el, index) => {
const wId = el.getAttribute('data-widget-id');
const item = focizWidgets.find(x => x.id === wId);
if (item) {
item.order = index + 1;
}
});
// Altijd opslaan na een drag (zet ook de volgorde opnieuw neer)
persistWidgetLayoutAuto();
const payload = getActiveWidgetLayoutPayload();
persistWidgetLayoutAuto(payload);
showWidgetToast('Widget indeling opgeslagen', 'success');
}