diff --git a/frontend/src/components/DashboardWidget.vue b/frontend/src/components/DashboardWidget.vue index 9a502e7..66e2129 100644 --- a/frontend/src/components/DashboardWidget.vue +++ b/frontend/src/components/DashboardWidget.vue @@ -226,6 +226,30 @@ export default { e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', this.widgetId); e.dataTransfer.setData('application/x-widget-id', this.widgetId); + + // Erstelle ein visuelles Drag-Ghost-Bild + const dragGhost = this.$el.cloneNode(true); + dragGhost.style.position = 'absolute'; + dragGhost.style.top = '-9999px'; + dragGhost.style.width = `${this.$el.offsetWidth}px`; + dragGhost.style.opacity = '0.8'; + dragGhost.style.transform = 'rotate(-2deg)'; + dragGhost.style.pointerEvents = 'none'; + document.body.appendChild(dragGhost); + + // Setze das Drag-Image mit Offset, damit es unter dem Cursor erscheint + const rect = this.$el.getBoundingClientRect(); + const offsetX = e.clientX - rect.left; + const offsetY = e.clientY - rect.top; + e.dataTransfer.setDragImage(dragGhost, offsetX, offsetY); + + // Entferne das Ghost-Element nach kurzer Verzögerung + setTimeout(() => { + if (dragGhost.parentNode) { + dragGhost.parentNode.removeChild(dragGhost); + } + }, 0); + this.$emit('drag-start', { widgetId: this.widgetId, event: e }); }, onDragEnd() { @@ -267,9 +291,10 @@ export default { transition: opacity 0.2s ease, box-shadow 0.2s ease; } .dashboard-widget.is-dragging { - opacity: 0.6; + opacity: 0.4; box-shadow: 0 4px 12px rgba(0,0,0,0.2); cursor: grabbing; + border: 2px dashed #0d6efd; } .dashboard-widget__titlebar {