From 4af1e60f765ceb0e212069720ded727d15bcbacc Mon Sep 17 00:00:00 2001 From: Timo Reichl Date: Tue, 29 Apr 2025 19:23:31 +0200 Subject: [PATCH] Geisterstunde --- .../formDesigner/ComponentRenderer.vue | 85 ++++++++++++++----- .../FormDesignerToolsComponent.vue | 13 ++- .../renderer/FlexLayoutRenderer.vue | 4 + .../process/layouts/FormDesignerLayout.vue | 12 ++- .../process/models/formDesigner/FormBlock.js | 3 +- .../process/store/formBlockDragStatus.js | 15 ++++ 6 files changed, 107 insertions(+), 25 deletions(-) create mode 100644 src/modules/process/store/formBlockDragStatus.js diff --git a/src/modules/process/components/formDesigner/ComponentRenderer.vue b/src/modules/process/components/formDesigner/ComponentRenderer.vue index 99e063f..0c3d656 100644 --- a/src/modules/process/components/formDesigner/ComponentRenderer.vue +++ b/src/modules/process/components/formDesigner/ComponentRenderer.vue @@ -4,10 +4,10 @@ :is="resolvedComponent" v-bind="element.props" @update-items="updateSchema" - @dragover.prevent="onDragOver($event)" + @dragover.prevent="onDragOver($event, index)" @drop="onDrop($event, index)" @dragleave="onDragLeave()" - :class="getDropClass" + :class="(getDropClass, isGhost)" /> @@ -43,6 +43,7 @@ const FlexLayoutRenderer = defineAsyncComponent(() => "@/modules/process/components/formDesigner/renderer/FlexLayoutRenderer.vue" ) ); +import { useDragStore } from "@/modules/process/store/formBlockDragStatus"; import { InputTextBlock } from "@/modules/process/models/formDesigner/blocks/InputTextBlock"; import { ButtonBlock } from "@/modules/process/models/formDesigner/blocks/ButtonBlock"; @@ -64,6 +65,7 @@ export default defineComponent({ data() { return { dropIndicator: null, + dragOver: false, }; }, props: { @@ -108,11 +110,28 @@ export default defineComponent({ return ""; } }, + isGhost() { + return this.element.ghost ? "ghost" : ""; + }, }, methods: { updateSchema(newItems) { this.$emit("update-schema", newItems); }, + addGhost(type, index) { + if ( + this.dropIndicator?.position === "right" || + this.dropIndicator?.position === "below" + ) { + index = index + 1; + } + let newElement = this.createElementByType(type); + newElement.ghost = true; + this.dropIndicator = null; + if (newElement) { + this.$emit("insert-item", { index, newElement }); + } + }, onDrop(event, index) { event.stopPropagation(); event.preventDefault(); @@ -129,27 +148,47 @@ export default defineComponent({ this.$emit("insert-item", { index, newElement }); } }, - onDragOver(event) { - event.stopPropagation(); - const bounds = event.currentTarget.getBoundingClientRect(); - const offsetX = event.clientX - bounds.left; - const offsetY = event.clientY - bounds.top; + async onDragOver(event, index) { + if (this.element.ghost) { + // do nothing + } else { + event.stopPropagation(); + const bounds = event.currentTarget.getBoundingClientRect(); + const offsetX = event.clientX - bounds.left; + const offsetY = event.clientY - bounds.top; - const isHorizontal = this.direction === "horizontal"; + const isHorizontal = this.direction === "horizontal"; - const position = isHorizontal - ? offsetX < bounds.width / 2 - ? "left" - : "right" - : offsetY < bounds.height / 2 - ? "above" - : "below"; + const position = isHorizontal + ? offsetX < bounds.width / 2 + ? "left" + : "right" + : offsetY < bounds.height / 2 + ? "above" + : "below"; - const curElement = this.element; - this.dropIndicator = { - type: curElement.type, - position, - }; + const curElement = this.element; + + if ( + position !== this.dropIndicator?.position && + this.dropIndicator?.position + ) { + this.dragOver = false; + await this.$emit("remove-ghosts"); + console.log("neue Position"); + } + + this.dropIndicator = { + type: curElement.type, + position, + }; + if (this.dragOver === false) { + const dragStore = useDragStore(); + this.addGhost(dragStore.currentDraggedType, index); + } + + this.dragOver = true; + } }, onDragLeave() { if ( @@ -158,6 +197,8 @@ export default defineComponent({ ) { this.dropIndicator = null; } + this.dragOver = false; + this.$emit("remove-ghosts"); }, createElementByType(type) { switch (type) { @@ -235,4 +276,8 @@ export default defineComponent({ bottom: 0; width: 2px; } + +.component-container .ghost { + opacity: 0.3; +} diff --git a/src/modules/process/components/formDesigner/FormDesignerToolsComponent.vue b/src/modules/process/components/formDesigner/FormDesignerToolsComponent.vue index 3c23ebe..171f39c 100644 --- a/src/modules/process/components/formDesigner/FormDesignerToolsComponent.vue +++ b/src/modules/process/components/formDesigner/FormDesignerToolsComponent.vue @@ -31,6 +31,7 @@ class="row ms-0 me-0 d-flex formItem align-items-center justify-content-center" draggable="true" @dragstart="startDrag($event, 'InputText')" + @dragend="endDrag" >