diff --git a/app/components/editor/DecisionNodeCanvas.vue b/app/components/editor/DecisionNodeCanvas.vue index 9183a4b..6f7586f 100644 --- a/app/components/editor/DecisionNodeCanvas.vue +++ b/app/components/editor/DecisionNodeCanvas.vue @@ -41,40 +41,46 @@ @pointerdown.stop="(event) => onNodePointerDown(event, node)" @dblclick.prevent="() => emit('select', node.id)" > -
-
- - {{ node.role }} - - {{ node.phase }} + + +
+
+
+ + {{ node.role }} + + {{ node.phase }} +
+
+ Start + End +
-
- Start - End -
-
-
-

{{ node.id }}

-

{{ node.title || 'Untitled node' }}

-

{{ node.summary }}

-
- - → {{ transition.target }} - {{ transition.type }} - -
-
- - {{ node.autopCount }} auto trigger{{ node.autopCount > 1 ? 's' : '' }} +
+
+

{{ node.id }}

+

{{ node.title || 'Untitled node' }}

+

{{ node.summary }}

+
+
+ + → {{ transition.target }} + {{ transition.type }} + +
+
+ + {{ node.autopCount }} auto trigger{{ node.autopCount > 1 ? 's' : '' }} +
@@ -325,14 +331,14 @@ function transitionColor(transition: DecisionNodeTransition) { } function computeEdgePath(source: { x: number; y: number; width: number; height: number }, target: { x: number; y: number; width: number; height: number }) { - const startX = source.x + source.width - const startY = source.y + source.height / 2 - const endX = target.x - const endY = target.y + target.height / 2 - const deltaX = Math.max(80, Math.abs(endX - startX) / 1.5) - const control1X = startX + deltaX - const control2X = endX - deltaX - return `M ${startX} ${startY} C ${control1X} ${startY}, ${control2X} ${endY}, ${endX} ${endY}` + const startX = source.x + source.width / 2 + const startY = source.y + source.height + const endX = target.x + target.width / 2 + const endY = target.y + const deltaY = Math.max(80, Math.abs(endY - startY) / 1.5) + const control1Y = startY + deltaY + const control2Y = endY - deltaY + return `M ${startX} ${startY} C ${startX} ${control1Y}, ${endX} ${control2Y}, ${endX} ${endY}` } let panPointerId: number | null = null @@ -492,4 +498,20 @@ onBeforeUnmount(() => { .control-btn { @apply pointer-events-auto flex h-9 w-9 items-center justify-center rounded-lg border border-white/10 bg-black/40 text-white/80 transition hover:border-cyan-400 hover:text-cyan-200; } + +.node-connector { + @apply pointer-events-none absolute h-3 w-3 rounded-full border-2 border-white/60 bg-[#070d1a]; +} + +.node-connector--input { + top: 0; + left: 50%; + transform: translate(-50%, -50%); +} + +.node-connector--output { + bottom: 0; + left: 50%; + transform: translate(-50%, 50%); +} diff --git a/app/pages/editor/index.vue b/app/pages/editor/index.vue index 6ed110c..e298255 100644 --- a/app/pages/editor/index.vue +++ b/app/pages/editor/index.vue @@ -7,12 +7,10 @@ flat density="comfortable" color="rgba(11, 18, 36, 0.92)" - class="border-b border-white/10 backdrop-blur-md shrink-0" - :extended="true" - height="72" - extension-height="92" + class="shrink-0 border-b border-white/10 backdrop-blur-md" + height="76" > -
+
@@ -20,105 +18,195 @@

Decision Flow Studio

- -