fix(nodes,edges): try to resolve component before falling back to default
This commit is contained in:
@@ -1,47 +1,46 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useHandle, useVueFlow } from '../../composables'
|
import { useHandle, useVueFlow } from '../../composables'
|
||||||
import { ConnectionMode, Position, GraphEdge, EdgeComponent } from '../../types'
|
import { ConnectionMode, Position, EdgeComponent } from '../../types'
|
||||||
import { getEdgePositions, getHandle, getMarkerId } from '../../utils'
|
import { getEdgePositions, getHandle, getMarkerId } from '../../utils'
|
||||||
import EdgeAnchor from './EdgeAnchor.vue'
|
import EdgeAnchor from './EdgeAnchor.vue'
|
||||||
|
|
||||||
interface EdgeWrapper {
|
interface EdgeWrapper {
|
||||||
edge: GraphEdge
|
id: string
|
||||||
component?: EdgeComponent
|
|
||||||
selectable?: boolean
|
selectable?: boolean
|
||||||
updatable?: boolean
|
updatable?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<EdgeWrapper>()
|
const props = defineProps<EdgeWrapper>()
|
||||||
const emit = defineEmits(['update:edge'])
|
|
||||||
const edge = useVModel(props, 'edge', emit)
|
|
||||||
const { store } = useVueFlow()
|
const { store } = useVueFlow()
|
||||||
|
const edge = store.getEdge(props.id)
|
||||||
|
if (!edge) throw new Error(`Edge with ${props.id} not found!`)
|
||||||
|
|
||||||
const updating = ref(false)
|
const updating = ref(false)
|
||||||
const { onMouseDown } = useHandle()
|
const { onMouseDown } = useHandle()
|
||||||
|
|
||||||
const onEdgeClick = (event: MouseEvent) => {
|
const onEdgeClick = (event: MouseEvent) => {
|
||||||
const data = { event, edge: edge.value }
|
const data = { event, edge }
|
||||||
if (props.selectable) {
|
if (props.selectable) {
|
||||||
store.nodesSelectionActive = false
|
store.nodesSelectionActive = false
|
||||||
store.addSelectedEdges([edge.value])
|
store.addSelectedEdges([edge])
|
||||||
}
|
}
|
||||||
store.hooks.edgeClick.trigger(data)
|
store.hooks.edgeClick.trigger(data)
|
||||||
}
|
}
|
||||||
const onEdgeContextMenu = (event: MouseEvent) => store.hooks.edgeContextMenu.trigger({ event, edge: edge.value })
|
const onEdgeContextMenu = (event: MouseEvent) => store.hooks.edgeContextMenu.trigger({ event, edge })
|
||||||
const onDoubleClick = (event: MouseEvent) => store.hooks.edgeDoubleClick.trigger({ event, edge: edge.value })
|
const onDoubleClick = (event: MouseEvent) => store.hooks.edgeDoubleClick.trigger({ event, edge })
|
||||||
const onEdgeMouseEnter = (event: MouseEvent) => store.hooks.edgeMouseEnter.trigger({ event, edge: edge.value })
|
const onEdgeMouseEnter = (event: MouseEvent) => store.hooks.edgeMouseEnter.trigger({ event, edge })
|
||||||
const onEdgeMouseMove = (event: MouseEvent) => store.hooks.edgeMouseMove.trigger({ event, edge: edge.value })
|
const onEdgeMouseMove = (event: MouseEvent) => store.hooks.edgeMouseMove.trigger({ event, edge })
|
||||||
const onEdgeMouseLeave = (event: MouseEvent) => store.hooks.edgeMouseLeave.trigger({ event, edge: edge.value })
|
const onEdgeMouseLeave = (event: MouseEvent) => store.hooks.edgeMouseLeave.trigger({ event, edge })
|
||||||
const onEdgeUpdaterMouseEnter = () => (updating.value = true)
|
const onEdgeUpdaterMouseEnter = () => (updating.value = true)
|
||||||
const onEdgeUpdaterMouseOut = () => (updating.value = false)
|
const onEdgeUpdaterMouseOut = () => (updating.value = false)
|
||||||
const onEdgeUpdaterSourceMouseDown = (event: MouseEvent) => handleEdgeUpdater(event, true)
|
const onEdgeUpdaterSourceMouseDown = (event: MouseEvent) => handleEdgeUpdater(event, true)
|
||||||
const onEdgeUpdaterTargetMouseDown = (event: MouseEvent) => handleEdgeUpdater(event, false)
|
const onEdgeUpdaterTargetMouseDown = (event: MouseEvent) => handleEdgeUpdater(event, false)
|
||||||
|
|
||||||
const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => {
|
const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => {
|
||||||
const nodeId = isSourceHandle ? edge.value.target : edge.value.source
|
const nodeId = isSourceHandle ? edge.target : edge.source
|
||||||
const handleId = (isSourceHandle ? edge.value.targetHandle : edge.value.sourceHandle) ?? ''
|
const handleId = (isSourceHandle ? edge.targetHandle : edge.sourceHandle) ?? ''
|
||||||
|
|
||||||
store.hooks.edgeUpdateStart.trigger({ event, edge: edge.value })
|
store.hooks.edgeUpdateStart.trigger({ event, edge })
|
||||||
onMouseDown(
|
onMouseDown(
|
||||||
event,
|
event,
|
||||||
handleId,
|
handleId,
|
||||||
@@ -49,22 +48,22 @@ const handleEdgeUpdater = (event: MouseEvent, isSourceHandle: boolean) => {
|
|||||||
isSourceHandle,
|
isSourceHandle,
|
||||||
undefined,
|
undefined,
|
||||||
isSourceHandle ? 'target' : 'source',
|
isSourceHandle ? 'target' : 'source',
|
||||||
(connection) => store.hooks.edgeUpdate.trigger({ edge: edge.value, connection }),
|
(connection) => store.hooks.edgeUpdate.trigger({ edge, connection }),
|
||||||
() => store.hooks.edgeUpdateEnd.trigger({ event, edge: edge.value }),
|
() => store.hooks.edgeUpdateEnd.trigger({ event, edge }),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// when connection type is loose we can define all handles as sources
|
// when connection type is loose we can define all handles as sources
|
||||||
const targetNodeHandles = computed(() =>
|
const targetNodeHandles = computed(() =>
|
||||||
store.connectionMode === ConnectionMode.Strict
|
store.connectionMode === ConnectionMode.Strict
|
||||||
? edge.value.targetNode.handleBounds.target
|
? edge.targetNode.handleBounds.target
|
||||||
: edge.value.targetNode.handleBounds.target ?? edge.value.targetNode.handleBounds.source,
|
: edge.targetNode.handleBounds.target ?? edge.targetNode.handleBounds.source,
|
||||||
)
|
)
|
||||||
const sourceHandle = controlledComputed(
|
const sourceHandle = controlledComputed(
|
||||||
() => edge.value.sourceNode.handleBounds,
|
() => edge.sourceNode.handleBounds,
|
||||||
() => getHandle(edge.value.sourceNode.handleBounds.source, edge.value.sourceHandle),
|
() => getHandle(edge.sourceNode.handleBounds.source, edge.sourceHandle),
|
||||||
)
|
)
|
||||||
const targetHandle = computed(() => getHandle(targetNodeHandles.value, edge.value.targetHandle))
|
const targetHandle = computed(() => getHandle(targetNodeHandles.value, edge.targetHandle))
|
||||||
const sourcePosition = computed(() => (sourceHandle.value ? sourceHandle.value.position : Position.Bottom))
|
const sourcePosition = computed(() => (sourceHandle.value ? sourceHandle.value.position : Position.Bottom))
|
||||||
const targetPosition = computed(() => (targetHandle.value ? targetHandle.value.position : Position.Top))
|
const targetPosition = computed(() => (targetHandle.value ? targetHandle.value.position : Position.Top))
|
||||||
const edgeUpdaterRadius = computed(() => store.edgeUpdaterRadius)
|
const edgeUpdaterRadius = computed(() => store.edgeUpdaterRadius)
|
||||||
@@ -74,30 +73,44 @@ onMounted(() => {
|
|||||||
[
|
[
|
||||||
sourcePosition,
|
sourcePosition,
|
||||||
targetPosition,
|
targetPosition,
|
||||||
() => edge.value.sourceNode.position,
|
() => edge.sourceNode.position,
|
||||||
() => edge.value.targetNode.position,
|
() => edge.targetNode.position,
|
||||||
() => edge.value.sourceNode.computedPosition,
|
() => edge.sourceNode.computedPosition,
|
||||||
() => edge.value.targetNode.computedPosition,
|
() => edge.targetNode.computedPosition,
|
||||||
() => edge.value.sourceNode.dimensions,
|
() => edge.sourceNode.dimensions,
|
||||||
() => edge.value.targetNode.dimensions,
|
() => edge.targetNode.dimensions,
|
||||||
],
|
],
|
||||||
() => {
|
() => {
|
||||||
const { sourceX, sourceY, targetY, targetX } = getEdgePositions(
|
const { sourceX, sourceY, targetY, targetX } = getEdgePositions(
|
||||||
edge.value.sourceNode,
|
edge.sourceNode,
|
||||||
sourceHandle.value,
|
sourceHandle.value,
|
||||||
sourcePosition.value,
|
sourcePosition.value,
|
||||||
edge.value.targetNode,
|
edge.targetNode,
|
||||||
targetHandle.value,
|
targetHandle.value,
|
||||||
targetPosition.value,
|
targetPosition.value,
|
||||||
)
|
)
|
||||||
if (edge.value.sourceX !== sourceX) edge.value.sourceX = sourceX
|
if (edge.sourceX !== sourceX) edge.sourceX = sourceX
|
||||||
if (edge.value.sourceY !== sourceY) edge.value.sourceY = sourceY
|
if (edge.sourceY !== sourceY) edge.sourceY = sourceY
|
||||||
if (edge.value.targetX !== targetX) edge.value.targetX = targetX
|
if (edge.targetX !== targetX) edge.targetX = targetX
|
||||||
if (edge.value.targetY !== targetY) edge.value.targetY = targetY
|
if (edge.targetY !== targetY) edge.targetY = targetY
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true },
|
{ immediate: true, deep: true },
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const name = ref(edge.type ?? 'default')
|
||||||
|
const type = computed(() => {
|
||||||
|
let edgeType = store.getEdgeTypes[name.value]
|
||||||
|
if (typeof edgeType === 'string') edgeType = resolveComponent(name.value, false) as EdgeComponent
|
||||||
|
if (typeof edgeType !== 'string') return edgeType
|
||||||
|
|
||||||
|
const slot = useSlots()?.[name.value]?.({})
|
||||||
|
if (!slot || !slot[0].key?.toString().includes(name.value)) {
|
||||||
|
console.warn(`Node type "${edge.type}" not found and no slot detected. Using fallback type "default".`)
|
||||||
|
name.value = 'default'
|
||||||
|
return store.getEdgeTypes.default
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export default {
|
export default {
|
||||||
@@ -109,7 +122,7 @@ export default {
|
|||||||
:key="`edge-${edge.id}`"
|
:key="`edge-${edge.id}`"
|
||||||
:class="[
|
:class="[
|
||||||
'vue-flow__edge',
|
'vue-flow__edge',
|
||||||
`vue-flow__edge-${edge.type || 'default'}`,
|
`vue-flow__edge-${name}`,
|
||||||
store.noPanClassName,
|
store.noPanClassName,
|
||||||
{
|
{
|
||||||
selected: edge.selected,
|
selected: edge.selected,
|
||||||
@@ -157,7 +170,8 @@ export default {
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<component
|
<component
|
||||||
:is="props.component ?? edge.type"
|
:is="type"
|
||||||
|
v-if="type"
|
||||||
v-bind="{
|
v-bind="{
|
||||||
id: edge.id,
|
id: edge.id,
|
||||||
sourceNode: edge.sourceNode,
|
sourceNode: edge.sourceNode,
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DraggableEventListener, DraggableCore } from '@braks/revue-draggable'
|
import { DraggableEventListener, DraggableCore } from '@braks/revue-draggable'
|
||||||
import { useVueFlow } from '../../composables'
|
import { useVueFlow } from '../../composables'
|
||||||
import { GraphNode, NodeComponent, SnapGrid } from '../../types'
|
import { NodeComponent, SnapGrid } from '../../types'
|
||||||
import { NodeId } from '../../context'
|
import { NodeId } from '../../context'
|
||||||
import { getXYZPos } from '../../utils'
|
import { getXYZPos } from '../../utils'
|
||||||
|
|
||||||
interface NodeWrapperProps {
|
interface NodeWrapperProps {
|
||||||
node: GraphNode
|
id: string
|
||||||
type: NodeComponent
|
|
||||||
draggable: boolean
|
draggable: boolean
|
||||||
selectable: boolean
|
selectable: boolean
|
||||||
connectable: boolean
|
connectable: boolean
|
||||||
@@ -15,74 +14,72 @@ interface NodeWrapperProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<NodeWrapperProps>()
|
const props = defineProps<NodeWrapperProps>()
|
||||||
const node = useVModel(props, 'node')
|
|
||||||
const { store } = useVueFlow()
|
const { store } = useVueFlow()
|
||||||
provide(NodeId, props.node.id)
|
const node = store.getNode(props.id)
|
||||||
|
if (!node) throw new Error(`Node with ${props.id} not found!`)
|
||||||
|
provide(NodeId, props.id)
|
||||||
|
|
||||||
const nodeElement = templateRef<HTMLDivElement>('node-element', null)
|
const nodeElement = templateRef<HTMLDivElement>('node-element', null)
|
||||||
|
|
||||||
const onMouseEnterHandler = () =>
|
const onMouseEnterHandler = () => node.dragging && ((event: MouseEvent) => store.hooks.nodeMouseEnter.trigger({ event, node }))
|
||||||
node.value.dragging && ((event: MouseEvent) => store.hooks.nodeMouseEnter.trigger({ event, node: node.value }))
|
const onMouseMoveHandler = () => node.dragging && ((event: MouseEvent) => store.hooks.nodeMouseMove.trigger({ event, node }))
|
||||||
const onMouseMoveHandler = () =>
|
const onMouseLeaveHandler = () => node.dragging && ((event: MouseEvent) => store.hooks.nodeMouseLeave.trigger({ event, node }))
|
||||||
node.value.dragging && ((event: MouseEvent) => store.hooks.nodeMouseMove.trigger({ event, node: node.value }))
|
|
||||||
const onMouseLeaveHandler = () =>
|
|
||||||
node.value.dragging && ((event: MouseEvent) => store.hooks.nodeMouseLeave.trigger({ event, node: node.value }))
|
|
||||||
const onContextMenuHandler = () => (event: MouseEvent) =>
|
const onContextMenuHandler = () => (event: MouseEvent) =>
|
||||||
store.hooks.nodeContextMenu.trigger({
|
store.hooks.nodeContextMenu.trigger({
|
||||||
event,
|
event,
|
||||||
node: node.value,
|
node,
|
||||||
})
|
})
|
||||||
const onDoubleClick = () => (event: MouseEvent) => store.hooks.nodeDoubleClick.trigger({ event, node: node.value })
|
const onDoubleClick = () => (event: MouseEvent) => store.hooks.nodeDoubleClick.trigger({ event, node })
|
||||||
const onSelectNodeHandler = (event: MouseEvent) => {
|
const onSelectNodeHandler = (event: MouseEvent) => {
|
||||||
if (!props.draggable) {
|
if (!props.draggable) {
|
||||||
if (props.selectable) {
|
if (props.selectable) {
|
||||||
store.nodesSelectionActive = false
|
store.nodesSelectionActive = false
|
||||||
if (!node.value.selected) store.addSelectedNodes([node.value])
|
if (!node.selected) store.addSelectedNodes([node])
|
||||||
}
|
}
|
||||||
store.hooks.nodeClick.trigger({ event, node: node.value })
|
store.hooks.nodeClick.trigger({ event, node })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const onDragStart: DraggableEventListener = ({ event }) => {
|
const onDragStart: DraggableEventListener = ({ event }) => {
|
||||||
store.addSelectedNodes([])
|
store.addSelectedNodes([])
|
||||||
store.hooks.nodeDragStart.trigger({ event, node: node.value })
|
store.hooks.nodeDragStart.trigger({ event, node })
|
||||||
|
|
||||||
if (store.selectNodesOnDrag && props.selectable) {
|
if (store.selectNodesOnDrag && props.selectable) {
|
||||||
store.nodesSelectionActive = false
|
store.nodesSelectionActive = false
|
||||||
|
|
||||||
if (!node.value.selected) store.addSelectedNodes([node.value])
|
if (!node.selected) store.addSelectedNodes([node])
|
||||||
} else if (!store.selectNodesOnDrag && !node.value.selected && props.selectable) {
|
} else if (!store.selectNodesOnDrag && !node.selected && props.selectable) {
|
||||||
store.nodesSelectionActive = false
|
store.nodesSelectionActive = false
|
||||||
store.addSelectedNodes([])
|
store.addSelectedNodes([])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const onDrag: DraggableEventListener = ({ event, data: { deltaX, deltaY } }) => {
|
const onDrag: DraggableEventListener = ({ event, data: { deltaX, deltaY } }) => {
|
||||||
nextTick(() => store.updateNodePosition({ id: node.value.id, diff: { x: deltaX, y: deltaY }, dragging: true }))
|
nextTick(() => store.updateNodePosition({ id: node.id, diff: { x: deltaX, y: deltaY }, dragging: true }))
|
||||||
store.hooks.nodeDrag.trigger({ event, node: node.value })
|
store.hooks.nodeDrag.trigger({ event, node })
|
||||||
}
|
}
|
||||||
const onDragStop: DraggableEventListener = ({ event, data: { deltaX, deltaY } }) => {
|
const onDragStop: DraggableEventListener = ({ event, data: { deltaX, deltaY } }) => {
|
||||||
// onDragStop also gets called when user just clicks on a node.
|
// onDragStop also gets called when user just clicks on a node.
|
||||||
// Because of that we set dragging to true inside the onDrag handler and handle the click here
|
// Because of that we set dragging to true inside the onDrag handler and handle the click here
|
||||||
if (!node.value.dragging) {
|
if (!node.dragging) {
|
||||||
if (props.selectable && !store.selectNodesOnDrag && !node.value.selected) {
|
if (props.selectable && !store.selectNodesOnDrag && !node.selected) {
|
||||||
store.addSelectedNodes([node.value])
|
store.addSelectedNodes([node])
|
||||||
}
|
}
|
||||||
store.hooks.nodeClick.trigger({ event, node: node.value })
|
store.hooks.nodeClick.trigger({ event, node })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
store.updateNodePosition({ id: node.value.id, diff: { x: deltaX, y: deltaY }, dragging: false })
|
store.updateNodePosition({ id: node.id, diff: { x: deltaX, y: deltaY }, dragging: false })
|
||||||
store.hooks.nodeDragStop.trigger({ event, node: node.value })
|
store.hooks.nodeDragStop.trigger({ event, node })
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
useResizeObserver(nodeElement, () =>
|
useResizeObserver(nodeElement, () =>
|
||||||
store.updateNodeDimensions([{ id: node.value.id, nodeElement: nodeElement.value, forceUpdate: true }]),
|
store.updateNodeDimensions([{ id: node.id, nodeElement: nodeElement.value, forceUpdate: true }]),
|
||||||
)
|
)
|
||||||
|
|
||||||
watch([() => node.value.type, () => node.value.sourcePosition, () => node.value.targetPosition], () =>
|
watch([() => node.type, () => node.sourcePosition, () => node.targetPosition], () =>
|
||||||
nextTick(() => store.updateNodeDimensions([{ id: node.value.id, nodeElement: nodeElement.value }])),
|
nextTick(() => store.updateNodeDimensions([{ id: node.id, nodeElement: nodeElement.value }])),
|
||||||
)
|
)
|
||||||
|
|
||||||
store.updateNodeDimensions([{ id: node.value.id, nodeElement: nodeElement.value }])
|
store.updateNodeDimensions([{ id: node.id, nodeElement: nodeElement.value }])
|
||||||
})
|
})
|
||||||
|
|
||||||
const scale = controlledComputed(
|
const scale = controlledComputed(
|
||||||
@@ -91,22 +88,36 @@ const scale = controlledComputed(
|
|||||||
)
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
[() => node.value.position, () => store.getNode(node.value.parentNode!)],
|
[() => node.position, () => store.getNode(node.parentNode!)],
|
||||||
([pos, parent]) => {
|
([pos, parent]) => {
|
||||||
const xyzPos = {
|
const xyzPos = {
|
||||||
...pos,
|
...pos,
|
||||||
z: node.value.dragging || node.value.selected ? 1000 : node.value.computedPosition.z,
|
z: node.dragging || node.selected ? 1000 : node.computedPosition.z,
|
||||||
}
|
}
|
||||||
if (parent) {
|
if (parent) {
|
||||||
node.value.computedPosition = getXYZPos(parent, xyzPos)
|
node.computedPosition = getXYZPos(parent, xyzPos)
|
||||||
} else {
|
} else {
|
||||||
node.value.computedPosition = xyzPos
|
node.computedPosition = xyzPos
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true },
|
{ deep: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
store.updateNodePosition({ id: node.value.id, diff: { x: 0, y: 0 } })
|
store.updateNodePosition({ id: node.id, diff: { x: 0, y: 0 } })
|
||||||
|
|
||||||
|
const name = ref(node.type ?? 'default')
|
||||||
|
const type = computed(() => {
|
||||||
|
let nodeType = store.getNodeTypes[name.value]
|
||||||
|
if (typeof nodeType === 'string') nodeType = resolveComponent(name.value, false) as NodeComponent
|
||||||
|
if (typeof nodeType !== 'string') return nodeType
|
||||||
|
|
||||||
|
const slot = useSlots()?.[name.value]?.({})
|
||||||
|
if (!slot || !slot[0].key?.toString().includes(name.value)) {
|
||||||
|
console.warn(`Node type "${node.type}" not found and no slot detected. Using fallback type "default".`)
|
||||||
|
name.value = 'default'
|
||||||
|
return store.getNodeTypes.default
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export default {
|
export default {
|
||||||
@@ -130,7 +141,7 @@ export default {
|
|||||||
:key="`node-${node.id}`"
|
:key="`node-${node.id}`"
|
||||||
:class="[
|
:class="[
|
||||||
'vue-flow__node',
|
'vue-flow__node',
|
||||||
`vue-flow__node-${node.type}`,
|
`vue-flow__node-${name}`,
|
||||||
store.noPanClassName,
|
store.noPanClassName,
|
||||||
{
|
{
|
||||||
dragging: node.dragging,
|
dragging: node.dragging,
|
||||||
@@ -176,7 +187,8 @@ export default {
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<component
|
<component
|
||||||
:is="props.type ?? node.type"
|
:is="type"
|
||||||
|
v-if="type"
|
||||||
v-bind="{
|
v-bind="{
|
||||||
nodeElement,
|
nodeElement,
|
||||||
id: node.id,
|
id: node.id,
|
||||||
|
|||||||
@@ -6,15 +6,6 @@ import { groupEdgesByZLevel } from '../../utils'
|
|||||||
import MarkerDefinitions from './MarkerDefinitions.vue'
|
import MarkerDefinitions from './MarkerDefinitions.vue'
|
||||||
|
|
||||||
const { store } = useVueFlow()
|
const { store } = useVueFlow()
|
||||||
const getType = (type?: string) => {
|
|
||||||
const t = type ?? 'default'
|
|
||||||
let edgeType = store.getEdgeTypes[t]
|
|
||||||
if (!edgeType) {
|
|
||||||
edgeType = store.getEdgeTypes.default
|
|
||||||
console.warn(`Edge type "${type}" not found. Using fallback type "default".`)
|
|
||||||
}
|
|
||||||
return edgeType
|
|
||||||
}
|
|
||||||
|
|
||||||
const sourceNode = controlledComputed(
|
const sourceNode = controlledComputed(
|
||||||
() => store.connectionNodeId,
|
() => store.connectionNodeId,
|
||||||
@@ -52,14 +43,13 @@ export default {
|
|||||||
<g>
|
<g>
|
||||||
<EdgeWrapper
|
<EdgeWrapper
|
||||||
v-for="edge of group.edges"
|
v-for="edge of group.edges"
|
||||||
|
:id="edge.id"
|
||||||
:key="edge.id"
|
:key="edge.id"
|
||||||
:edge="edge"
|
|
||||||
:component="getType(edge.type)"
|
|
||||||
:selectable="typeof edge.selectable === 'undefined' ? store.elementsSelectable : edge.selectable"
|
:selectable="typeof edge.selectable === 'undefined' ? store.elementsSelectable : edge.selectable"
|
||||||
:updatable="typeof edge.updatable === 'undefined' ? store.edgesUpdatable : edge.updatable"
|
:updatable="typeof edge.updatable === 'undefined' ? store.edgesUpdatable : edge.updatable"
|
||||||
>
|
>
|
||||||
<template #default="edgeProps">
|
<template #default="edgeProps">
|
||||||
<slot :name="`edge-${edge.type}`" v-bind="edgeProps"></slot>
|
<slot v-if="edge.type" :name="`edge-${edge.type}`" v-bind="edgeProps"></slot>
|
||||||
</template>
|
</template>
|
||||||
</EdgeWrapper>
|
</EdgeWrapper>
|
||||||
<ConnectionLine v-if="connectionLineVisible && sourceNode" :source-node="sourceNode">
|
<ConnectionLine v-if="connectionLineVisible && sourceNode" :source-node="sourceNode">
|
||||||
|
|||||||
@@ -1,20 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { GraphNode } from '../../types'
|
|
||||||
import NodeWrapper from '../../components/Nodes/NodeWrapper.vue'
|
import NodeWrapper from '../../components/Nodes/NodeWrapper.vue'
|
||||||
import { useVueFlow } from '../../composables'
|
import { useVueFlow } from '../../composables'
|
||||||
|
|
||||||
const { store } = useVueFlow()
|
const { store } = useVueFlow()
|
||||||
const getType = (type?: string) => {
|
|
||||||
const t = type ?? 'default'
|
|
||||||
let nodeType = store.getNodeTypes[t]
|
|
||||||
if (!nodeType) {
|
|
||||||
nodeType = store.getNodeTypes.default
|
|
||||||
console.warn(`Node type "${type}" not found. Using fallback type "default".`)
|
|
||||||
}
|
|
||||||
return nodeType
|
|
||||||
}
|
|
||||||
|
|
||||||
const snapGrid = (node: GraphNode) => node.snapGrid ?? (store.snapToGrid ? store.snapGrid : undefined)
|
|
||||||
</script>
|
</script>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export default {
|
export default {
|
||||||
@@ -25,16 +13,15 @@ export default {
|
|||||||
<div class="vue-flow__nodes vue-flow__container">
|
<div class="vue-flow__nodes vue-flow__container">
|
||||||
<NodeWrapper
|
<NodeWrapper
|
||||||
v-for="node of store.getNodes"
|
v-for="node of store.getNodes"
|
||||||
|
:id="node.id"
|
||||||
:key="node.id"
|
:key="node.id"
|
||||||
:node="node"
|
|
||||||
:type="getType(node.type)"
|
|
||||||
:draggable="typeof node.draggable === 'undefined' ? store.nodesDraggable : !!node.draggable"
|
:draggable="typeof node.draggable === 'undefined' ? store.nodesDraggable : !!node.draggable"
|
||||||
:selectable="typeof node.selectable === 'undefined' ? store.elementsSelectable : !!node.selectable"
|
:selectable="typeof node.selectable === 'undefined' ? store.elementsSelectable : !!node.selectable"
|
||||||
:connectable="typeof node.connectable === 'undefined' ? store.nodesConnectable : !!node.connectable"
|
:connectable="typeof node.connectable === 'undefined' ? store.nodesConnectable : !!node.connectable"
|
||||||
:snap-grid="snapGrid(node)"
|
:snap-grid="node.snapGrid ?? (store.snapToGrid ? store.snapGrid : undefined)"
|
||||||
>
|
>
|
||||||
<template #default="nodeProps">
|
<template #default="nodeProps">
|
||||||
<slot :name="`node-${node.type}`" v-bind="nodeProps"></slot>
|
<slot v-if="node.type" :name="`node-${node.type}`" v-bind="nodeProps"></slot>
|
||||||
</template>
|
</template>
|
||||||
</NodeWrapper>
|
</NodeWrapper>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user