Skip to content

Commit 5539701

Browse files
Merge branch 'master' into dev/fix-group-retry-counts
2 parents 46b4d6c + 36ac5dd commit 5539701

File tree

1 file changed

+127
-1
lines changed

1 file changed

+127
-1
lines changed

src/components/MonitorListItem.vue

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
<template>
22
<div>
3-
<div :style="depthMargin">
3+
<div
4+
class="draggable-item"
5+
:style="depthMargin"
6+
:class="{ 'drag-over': dragOverCount > 0 }"
7+
@dragstart="onDragStart"
8+
@dragenter.prevent="onDragEnter"
9+
@dragleave.prevent="onDragLeave"
10+
@dragover.prevent
11+
@drop.prevent="onDrop"
12+
>
413
<!-- Checkbox -->
514
<div v-if="isSelectMode" class="select-input-wrapper">
615
<input
@@ -116,6 +125,7 @@ export default {
116125
data() {
117126
return {
118127
isCollapsed: true,
128+
dragOverCount: 0,
119129
};
120130
},
121131
computed: {
@@ -187,6 +197,91 @@ export default {
187197
188198
window.localStorage.setItem("monitorCollapsed", JSON.stringify(storageObject));
189199
},
200+
/**
201+
* Initializes the drag operation if the monitor is draggable.
202+
* @param {DragEvent} event - The dragstart event triggered by the browser.
203+
* @returns {void} This method does not return anything.
204+
*/
205+
onDragStart(event) {
206+
try {
207+
event.dataTransfer.setData("text/monitor-id", String(this.monitor.id));
208+
event.dataTransfer.effectAllowed = "move";
209+
} catch (e) {
210+
// ignore
211+
}
212+
},
213+
214+
onDragEnter(event) {
215+
if (this.monitor.type !== "group") {
216+
return;
217+
}
218+
219+
this.dragOverCount++;
220+
},
221+
222+
onDragLeave(event) {
223+
if (this.monitor.type !== "group") {
224+
return;
225+
}
226+
227+
this.dragOverCount = Math.max(0, this.dragOverCount - 1);
228+
},
229+
230+
async onDrop(event) {
231+
this.dragOverCount = 0;
232+
233+
// Only groups accept drops
234+
if (this.monitor.type !== "group") {
235+
return;
236+
}
237+
238+
const draggedId = event.dataTransfer.getData("text/monitor-id");
239+
if (!draggedId) {
240+
return;
241+
}
242+
243+
const draggedMonitorId = parseInt(draggedId);
244+
if (isNaN(draggedMonitorId) || draggedMonitorId === this.monitor.id) {
245+
return;
246+
}
247+
248+
const draggedMonitor = this.$root.monitorList[draggedMonitorId];
249+
if (!draggedMonitor) {
250+
return;
251+
}
252+
253+
// Save original parent so we can revert locally if server returns error
254+
const originalParent = draggedMonitor.parent;
255+
256+
// Prepare a full monitor object (clone) and set new parent
257+
const monitorToSave = JSON.parse(JSON.stringify(draggedMonitor));
258+
monitorToSave.parent = this.monitor.id;
259+
260+
// Optimistically update local state so UI updates immediately
261+
this.$root.monitorList[draggedMonitorId].parent = this.monitor.id;
262+
263+
// Send updated monitor state via socket
264+
try {
265+
this.$root.getSocket().emit("editMonitor", monitorToSave, (res) => {
266+
if (!res || !res.ok) {
267+
// Revert local change on error
268+
if (this.$root.monitorList[draggedMonitorId]) {
269+
this.$root.monitorList[draggedMonitorId].parent = originalParent;
270+
}
271+
if (res && res.msg) {
272+
this.$root.toastError(res.msg);
273+
}
274+
} else {
275+
this.$root.toastRes(res);
276+
}
277+
});
278+
} catch (e) {
279+
// revert on exception
280+
if (this.$root.monitorList[draggedMonitorId]) {
281+
this.$root.monitorList[draggedMonitorId].parent = originalParent;
282+
}
283+
}
284+
},
190285
/**
191286
* Get URL of monitor
192287
* @param {number} id ID of monitor
@@ -253,4 +348,35 @@ export default {
253348
z-index: 15;
254349
}
255350
351+
.drag-over {
352+
border: 4px dashed $primary;
353+
border-radius: 0.5rem;
354+
background-color: $highlight-white;
355+
}
356+
357+
.dark {
358+
.drag-over {
359+
background-color: $dark-bg2;
360+
}
361+
}
362+
363+
/* -4px on all due to border-width */
364+
.monitor-list .drag-over .item {
365+
padding: 9px 11px 6px 11px;
366+
}
367+
368+
.draggable-item {
369+
cursor: grab;
370+
position: relative;
371+
372+
/* We don't want the padding change due to the border animated */
373+
.item {
374+
transition: none !important;
375+
}
376+
377+
&.dragging {
378+
cursor: grabbing;
379+
}
380+
}
381+
256382
</style>

0 commit comments

Comments
 (0)