You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
4.5 KiB
154 lines
4.5 KiB
// Simple Dashboard Drag and Drop
|
|
let isCustomizing = false;
|
|
let draggedCard = null;
|
|
|
|
// Initialize on page load
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
loadLayout();
|
|
});
|
|
|
|
function toggleCustomize() {
|
|
const btn = document.getElementById('customize-btn');
|
|
const help = document.getElementById('customization-help');
|
|
const cards = document.querySelectorAll('.draggable-card');
|
|
const handles = document.querySelectorAll('.drag-handle');
|
|
|
|
isCustomizing = !isCustomizing;
|
|
|
|
if (isCustomizing) {
|
|
btn.textContent = '💾 Save Layout';
|
|
btn.classList.add('saving');
|
|
help.style.display = 'block';
|
|
|
|
// Enable dragging
|
|
cards.forEach(card => {
|
|
card.draggable = true;
|
|
card.classList.add('customizable');
|
|
card.addEventListener('dragstart', handleDragStart);
|
|
card.addEventListener('dragover', handleDragOver);
|
|
card.addEventListener('drop', handleDrop);
|
|
card.addEventListener('dragend', handleDragEnd);
|
|
});
|
|
|
|
// Show handles
|
|
handles.forEach(handle => handle.style.display = 'block');
|
|
|
|
} else {
|
|
btn.textContent = '📝 Customize Layout';
|
|
btn.classList.remove('saving');
|
|
help.style.display = 'none';
|
|
|
|
// Disable dragging
|
|
cards.forEach(card => {
|
|
card.draggable = false;
|
|
card.classList.remove('customizable');
|
|
card.removeEventListener('dragstart', handleDragStart);
|
|
card.removeEventListener('dragover', handleDragOver);
|
|
card.removeEventListener('drop', handleDrop);
|
|
card.removeEventListener('dragend', handleDragEnd);
|
|
});
|
|
|
|
// Hide handles
|
|
handles.forEach(handle => handle.style.display = 'none');
|
|
|
|
// Save the current layout
|
|
saveLayout();
|
|
showMessage('Layout saved!', 'success');
|
|
}
|
|
}
|
|
|
|
function handleDragStart(e) {
|
|
draggedCard = e.target.closest('.draggable-card');
|
|
draggedCard.classList.add('dragging');
|
|
e.dataTransfer.effectAllowed = 'move';
|
|
}
|
|
|
|
function handleDragOver(e) {
|
|
e.preventDefault();
|
|
e.dataTransfer.dropEffect = 'move';
|
|
|
|
const card = e.target.closest('.draggable-card');
|
|
if (card && card !== draggedCard) {
|
|
const grid = document.getElementById('dashboard-grid');
|
|
const cards = Array.from(grid.children);
|
|
const draggedIndex = cards.indexOf(draggedCard);
|
|
const targetIndex = cards.indexOf(card);
|
|
|
|
if (draggedIndex < targetIndex) {
|
|
grid.insertBefore(draggedCard, card.nextSibling);
|
|
} else {
|
|
grid.insertBefore(draggedCard, card);
|
|
}
|
|
}
|
|
}
|
|
|
|
function handleDrop(e) {
|
|
e.preventDefault();
|
|
}
|
|
|
|
function handleDragEnd(e) {
|
|
if (draggedCard) {
|
|
draggedCard.classList.remove('dragging');
|
|
draggedCard = null;
|
|
}
|
|
}
|
|
|
|
function saveLayout() {
|
|
const cards = document.querySelectorAll('.draggable-card');
|
|
const layout = Array.from(cards).map((card, index) => ({
|
|
id: card.dataset.widgetId,
|
|
position: index
|
|
}));
|
|
localStorage.setItem('dashboard-layout', JSON.stringify(layout));
|
|
}
|
|
|
|
function loadLayout() {
|
|
const saved = localStorage.getItem('dashboard-layout');
|
|
if (!saved) return;
|
|
|
|
try {
|
|
const layout = JSON.parse(saved);
|
|
const grid = document.getElementById('dashboard-grid');
|
|
|
|
// Sort layout by position
|
|
layout.sort((a, b) => a.position - b.position);
|
|
|
|
// Reorder cards
|
|
layout.forEach(item => {
|
|
const card = document.querySelector(`[data-widget-id="${item.id}"]`);
|
|
if (card) grid.appendChild(card);
|
|
});
|
|
} catch (e) {
|
|
console.warn('Failed to load layout:', e);
|
|
}
|
|
}
|
|
|
|
function showMessage(text, type) {
|
|
// Create message element
|
|
const msg = document.createElement('div');
|
|
msg.textContent = text;
|
|
msg.style.cssText = `
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
padding: 12px 20px;
|
|
border-radius: 4px;
|
|
color: white;
|
|
font-weight: bold;
|
|
z-index: 10000;
|
|
background: ${type === 'success' ? '#10b981' : '#ef4444'};
|
|
transform: translateX(300px);
|
|
transition: transform 0.3s ease;
|
|
`;
|
|
|
|
document.body.appendChild(msg);
|
|
|
|
// Show message
|
|
setTimeout(() => msg.style.transform = 'translateX(0)', 100);
|
|
|
|
// Hide message
|
|
setTimeout(() => {
|
|
msg.style.transform = 'translateX(300px)';
|
|
setTimeout(() => document.body.removeChild(msg), 300);
|
|
}, 2000);
|
|
}
|