an updated and hopefully faster version of the ST Toolbox
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

// 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);
}