From 3999b17e88724887fffe309a0b32fbcefc994dbd Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Fri, 30 Jan 2026 10:30:07 +0100 Subject: [PATCH] Enhance drag-and-drop functionality in Dashboard: Update styles for dragging state in DashboardWidget, including opacity and box-shadow adjustments. Improve LoggedInView by adding drop indicators for better user experience during widget rearrangement. Refactor drag-and-drop logic to maintain visual cues and ensure smoother interactions. --- frontend/src/components/DashboardWidget.vue | 7 +- frontend/src/views/home/LoggedInView.vue | 71 +++++++++++++++++++-- 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/DashboardWidget.vue b/frontend/src/components/DashboardWidget.vue index 990b0bf..0be3956 100644 --- a/frontend/src/components/DashboardWidget.vue +++ b/frontend/src/components/DashboardWidget.vue @@ -264,10 +264,13 @@ export default { border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.06); overflow: hidden; + transition: opacity 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease; } .dashboard-widget.is-dragging { - opacity: 0.7; - box-shadow: 0 4px 12px rgba(0,0,0,0.15); + opacity: 0.5; + box-shadow: 0 8px 24px rgba(0,0,0,0.25); + transform: rotate(2deg); + cursor: grabbing; } .dashboard-widget__titlebar { diff --git a/frontend/src/views/home/LoggedInView.vue b/frontend/src/views/home/LoggedInView.vue index 9004008..d71930e 100644 --- a/frontend/src/views/home/LoggedInView.vue +++ b/frontend/src/views/home/LoggedInView.vue @@ -63,9 +63,19 @@ @drop="onGridDrop" > @@ -240,13 +257,18 @@ export default { await this.saveConfig(); }, setDropTarget(index) { - this.dragOverIndex = index; + if (this.draggedIndex !== null && this.draggedIndex !== index) { + this.dragOverIndex = index; + } }, clearDropTarget() { - this.dragOverIndex = null; + // Nicht sofort löschen, damit der Indikator sichtbar bleibt + // Wird beim Drop oder Drag-End gelöscht }, onGridDragover() { - this.dragOverIndex = this.widgets.length; + if (this.draggedIndex !== null) { + this.dragOverIndex = this.widgets.length; + } }, async onGridDrop() { if (this.draggedIndex == null) return; @@ -277,6 +299,10 @@ export default { this.draggedIndex = null; this.dragOverIndex = null; await this.saveConfig(); + }, + onDragEnd() { + this.draggedIndex = null; + this.dragOverIndex = null; } } }; @@ -374,7 +400,7 @@ export default { .dashboard-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); - grid-auto-rows: 200px; + grid-auto-rows: 420px; gap: 20px; } @@ -382,6 +408,7 @@ export default { min-height: 0; display: flex; flex-direction: column; + transition: all 0.2s ease; } .dashboard-grid-cell > * { @@ -395,6 +422,38 @@ export default { outline: 2px dashed #0d6efd; outline-offset: 4px; border-radius: 8px; + background-color: rgba(13, 110, 253, 0.05); +} + +.dashboard-grid-cell.drag-source { + opacity: 0.4; +} + +.dashboard-drop-indicator { + display: flex; + align-items: center; + justify-content: center; + min-height: 0; + padding: 0; +} + +.drop-indicator-line { + width: 100%; + height: 3px; + background: linear-gradient(90deg, transparent, #0d6efd, transparent); + border-radius: 2px; + animation: pulse-drop-indicator 1.5s ease-in-out infinite; +} + +@keyframes pulse-drop-indicator { + 0%, 100% { + opacity: 0.5; + transform: scaleX(0.8); + } + 50% { + opacity: 1; + transform: scaleX(1); + } } .dashboard-widget-edit {