chore(vue-flow,store): move store utils to separate file
This commit is contained in:
@@ -2,122 +2,36 @@ import useState from './state'
|
|||||||
import type {
|
import type {
|
||||||
Actions,
|
Actions,
|
||||||
ComputedGetters,
|
ComputedGetters,
|
||||||
Connection,
|
|
||||||
CoordinateExtent,
|
CoordinateExtent,
|
||||||
Edge,
|
|
||||||
EdgeChange,
|
EdgeChange,
|
||||||
Getters,
|
|
||||||
GraphEdge,
|
GraphEdge,
|
||||||
GraphNode,
|
GraphNode,
|
||||||
Node,
|
|
||||||
NodeChange,
|
NodeChange,
|
||||||
NodeDimensionChange,
|
NodeDimensionChange,
|
||||||
NodePositionChange,
|
NodePositionChange,
|
||||||
State,
|
State,
|
||||||
} from '~/types'
|
} from '~/types'
|
||||||
import {
|
import {
|
||||||
|
addEdgeToStore,
|
||||||
applyChanges,
|
applyChanges,
|
||||||
|
createGraphNodes,
|
||||||
connectionExists,
|
connectionExists,
|
||||||
createAdditionChange,
|
createAdditionChange,
|
||||||
createPositionChange,
|
createPositionChange,
|
||||||
createSelectionChange,
|
createSelectionChange,
|
||||||
getDimensions,
|
getDimensions,
|
||||||
getEdgeId,
|
|
||||||
getHandleBounds,
|
getHandleBounds,
|
||||||
getSelectionChanges,
|
getSelectionChanges,
|
||||||
|
isDef,
|
||||||
isEdge,
|
isEdge,
|
||||||
isGraphEdge,
|
isGraphEdge,
|
||||||
isGraphNode,
|
isGraphNode,
|
||||||
isNode,
|
isNode,
|
||||||
isParentSelected,
|
isParentSelected,
|
||||||
parseEdge,
|
parseEdge,
|
||||||
parseNode,
|
updateEdgeAction,
|
||||||
} from '~/utils'
|
} from '~/utils'
|
||||||
|
|
||||||
const isDef = <T>(val: T): val is NonNullable<T> => typeof val !== 'undefined'
|
|
||||||
|
|
||||||
const addEdge = (edgeParams: Edge | Connection, edges: Edge[]) => {
|
|
||||||
if (!edgeParams.source || !edgeParams.target) {
|
|
||||||
console.warn("[vueflow]: Can't create edge. An edge needs a source and a target.")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
let edge
|
|
||||||
if (isEdge(edgeParams)) {
|
|
||||||
edge = { ...edgeParams }
|
|
||||||
} else {
|
|
||||||
edge = {
|
|
||||||
...edgeParams,
|
|
||||||
id: getEdgeId(edgeParams),
|
|
||||||
} as Edge
|
|
||||||
}
|
|
||||||
edge = parseEdge(edge)
|
|
||||||
if (connectionExists(edge, edges)) return false
|
|
||||||
return edge
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateEdgeAction = (edge: GraphEdge, newConnection: Connection, edges: GraphEdge[], add: Actions['addEdges']) => {
|
|
||||||
if (!newConnection.source || !newConnection.target) {
|
|
||||||
console.warn("[vueflow]: Can't create new edge. An edge needs a source and a target.")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const foundEdge = edges.find((e) => isGraphEdge(e) && e.id === edge.id)
|
|
||||||
|
|
||||||
if (!foundEdge) {
|
|
||||||
console.warn(`[vueflow]: The old edge with id=${edge.id} does not exist.`)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
edges.splice(edges.indexOf(edge), 1)
|
|
||||||
const newEdge = {
|
|
||||||
...edge,
|
|
||||||
id: getEdgeId(newConnection),
|
|
||||||
source: newConnection.source,
|
|
||||||
target: newConnection.target,
|
|
||||||
sourceHandle: newConnection.sourceHandle,
|
|
||||||
targetHandle: newConnection.targetHandle,
|
|
||||||
}
|
|
||||||
add([newEdge])
|
|
||||||
|
|
||||||
return newEdge
|
|
||||||
}
|
|
||||||
|
|
||||||
const createGraphNodes = (nodes: Node[], getNode: Getters['getNode'], currGraphNodes: GraphNode[], extent: CoordinateExtent) => {
|
|
||||||
const parentNodes: Record<string, true> = {}
|
|
||||||
|
|
||||||
const graphNodes = nodes.map((node) => {
|
|
||||||
const parsed = shallowReactive(
|
|
||||||
parseNode(node, extent, {
|
|
||||||
...getNode(node.id),
|
|
||||||
parentNode: node.parentNode,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
if (node.parentNode) {
|
|
||||||
parentNodes[node.parentNode] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return parsed
|
|
||||||
})
|
|
||||||
|
|
||||||
graphNodes.forEach((node) => {
|
|
||||||
const nextNodes = [...graphNodes, ...currGraphNodes]
|
|
||||||
if (node.parentNode && !nextNodes.find((n) => n.id === node.parentNode)) {
|
|
||||||
console.warn(`[vueflow]: Parent node ${node.parentNode} not found`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.parentNode || parentNodes[node.id]) {
|
|
||||||
if (parentNodes[node.id]) {
|
|
||||||
node.isParent = true
|
|
||||||
}
|
|
||||||
const parent = node.parentNode ? getNode(node.parentNode) : undefined
|
|
||||||
if (parent) parent.isParent = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return graphNodes
|
|
||||||
}
|
|
||||||
|
|
||||||
export default (state: State, getters: ComputedGetters): Actions => {
|
export default (state: State, getters: ComputedGetters): Actions => {
|
||||||
const updateNodePosition: Actions['updateNodePosition'] = ({ id, diff = { x: 0, y: 0 } }) => {
|
const updateNodePosition: Actions['updateNodePosition'] = ({ id, diff = { x: 0, y: 0 } }) => {
|
||||||
const nodePosPromise = new Promise<NodePositionChange[]>((resolve) => {
|
const nodePosPromise = new Promise<NodePositionChange[]>((resolve) => {
|
||||||
@@ -173,49 +87,45 @@ export default (state: State, getters: ComputedGetters): Actions => {
|
|||||||
if (changes.length) state.hooks.nodesChange.trigger(changes)
|
if (changes.length) state.hooks.nodesChange.trigger(changes)
|
||||||
}
|
}
|
||||||
|
|
||||||
const addSelectedNodes: Actions['addSelectedNodes'] = (nodes) => {
|
const nodeSelectionHandler = (nodes: GraphNode[], selected: boolean) => {
|
||||||
const selectedNodesIds = nodes.map((n) => n.id)
|
const nodeIds = nodes.map((n) => n.id)
|
||||||
|
|
||||||
let changedNodes: NodeChange[]
|
let changedNodes: NodeChange[]
|
||||||
if (state.multiSelectionActive) changedNodes = selectedNodesIds.map((nodeId) => createSelectionChange(nodeId, true))
|
if (state.multiSelectionActive) changedNodes = nodeIds.map((nodeId) => createSelectionChange(nodeId, selected))
|
||||||
else changedNodes = getSelectionChanges(state.nodes, selectedNodesIds, getters.getNode.value)
|
else changedNodes = getSelectionChanges(state.nodes, nodeIds, getters.getNode.value)
|
||||||
|
|
||||||
if (changedNodes.length) state.hooks.nodesChange.trigger(changedNodes)
|
if (changedNodes.length) state.hooks.nodesChange.trigger(changedNodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
const addSelectedEdges: Actions['addSelectedEdges'] = (edges) => {
|
const edgeSelectionHandler = (edges: GraphEdge[], selected: boolean) => {
|
||||||
const selectedEdgesIds = edges.map((e) => e.id)
|
const edgeIds = edges.map((e) => e.id)
|
||||||
|
|
||||||
let changedEdges: EdgeChange[]
|
let changedEdges: EdgeChange[]
|
||||||
if (state.multiSelectionActive) changedEdges = selectedEdgesIds.map((edgeId) => createSelectionChange(edgeId, true))
|
if (state.multiSelectionActive) changedEdges = edgeIds.map((edgeId) => createSelectionChange(edgeId, selected))
|
||||||
else changedEdges = getSelectionChanges(state.edges, selectedEdgesIds, getters.getNode.value)
|
else changedEdges = getSelectionChanges(state.edges, edgeIds, getters.getNode.value)
|
||||||
|
|
||||||
if (changedEdges.length) state.hooks.edgesChange.trigger(changedEdges)
|
if (changedEdges.length) state.hooks.edgesChange.trigger(changedEdges)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const addSelectedNodes: Actions['addSelectedNodes'] = (nodes) => {
|
||||||
|
nodeSelectionHandler(nodes, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const addSelectedEdges: Actions['addSelectedEdges'] = (edges) => {
|
||||||
|
edgeSelectionHandler(edges, true)
|
||||||
|
}
|
||||||
|
|
||||||
const addSelectedElements: Actions['addSelectedElements'] = (elements) => {
|
const addSelectedElements: Actions['addSelectedElements'] = (elements) => {
|
||||||
addSelectedNodes(elements.filter(isGraphNode))
|
addSelectedNodes(elements.filter(isGraphNode))
|
||||||
addSelectedEdges(elements.filter(isGraphEdge))
|
addSelectedEdges(elements.filter(isGraphEdge))
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeSelectedNodes: Actions['removeSelectedNodes'] = (nodes) => {
|
const removeSelectedNodes: Actions['removeSelectedNodes'] = (nodes) => {
|
||||||
const unselectedNodesIds = nodes.map((n) => n.id)
|
nodeSelectionHandler(nodes, false)
|
||||||
|
|
||||||
let changedNodes: NodeChange[]
|
|
||||||
if (state.multiSelectionActive) changedNodes = unselectedNodesIds.map((nodeId) => createSelectionChange(nodeId, false))
|
|
||||||
else changedNodes = getSelectionChanges(state.nodes, unselectedNodesIds, getters.getNode.value)
|
|
||||||
|
|
||||||
if (changedNodes.length) state.hooks.nodesChange.trigger(changedNodes)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeSelectedEdges: Actions['removeSelectedEdges'] = (edges) => {
|
const removeSelectedEdges: Actions['removeSelectedEdges'] = (edges) => {
|
||||||
const unselectedEdgesIds = edges.map((e) => e.id)
|
edgeSelectionHandler(edges, false)
|
||||||
|
|
||||||
let changedEdges: EdgeChange[]
|
|
||||||
if (state.multiSelectionActive) changedEdges = unselectedEdgesIds.map((edgeId) => createSelectionChange(edgeId, false))
|
|
||||||
else changedEdges = getSelectionChanges(state.edges, unselectedEdgesIds, getters.getNode.value)
|
|
||||||
|
|
||||||
if (changedEdges.length) state.hooks.edgesChange.trigger(changedEdges)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeSelectedElements: Actions['removeSelectedElements'] = (elements) => {
|
const removeSelectedElements: Actions['removeSelectedElements'] = (elements) => {
|
||||||
@@ -303,7 +213,13 @@ export default (state: State, getters: ComputedGetters): Actions => {
|
|||||||
const curr = params instanceof Function ? params(state.edges) : params
|
const curr = params instanceof Function ? params(state.edges) : params
|
||||||
|
|
||||||
const changes = curr.reduce((acc, param) => {
|
const changes = curr.reduce((acc, param) => {
|
||||||
const edge = addEdge(param, state.edges)
|
const edge = addEdgeToStore(
|
||||||
|
{
|
||||||
|
...param,
|
||||||
|
...state.defaultEdgeOptions,
|
||||||
|
},
|
||||||
|
state.edges,
|
||||||
|
)
|
||||||
if (edge) {
|
if (edge) {
|
||||||
const sourceNode = getters.getNode.value(edge.source)!
|
const sourceNode = getters.getNode.value(edge.source)!
|
||||||
const targetNode = getters.getNode.value(edge.target)!
|
const targetNode = getters.getNode.value(edge.target)!
|
||||||
@@ -315,10 +231,7 @@ export default (state: State, getters: ComputedGetters): Actions => {
|
|||||||
if (missingTarget || missingSource) return acc
|
if (missingTarget || missingSource) return acc
|
||||||
|
|
||||||
acc.push(
|
acc.push(
|
||||||
createAdditionChange<GraphEdge>(shallowReactive({
|
createAdditionChange<GraphEdge>(shallowReactive(edge)),
|
||||||
...state.defaultEdgeOptions,
|
|
||||||
...edge,
|
|
||||||
})),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ export * from './edge'
|
|||||||
export * from './graph'
|
export * from './graph'
|
||||||
export * from './node'
|
export * from './node'
|
||||||
export * from './changes'
|
export * from './changes'
|
||||||
|
export * from './store'
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
import type { Actions, Connection, CoordinateExtent, Edge, Getters, GraphEdge, GraphNode, Node } from '~/types'
|
||||||
|
import { connectionExists, getEdgeId, isEdge, isGraphEdge, parseEdge, parseNode } from '~/utils/graph'
|
||||||
|
|
||||||
|
export const isDef = <T>(val: T): val is NonNullable<T> => typeof val !== 'undefined'
|
||||||
|
|
||||||
|
export const addEdgeToStore = (edgeParams: Edge | Connection, edges: Edge[]) => {
|
||||||
|
if (!edgeParams.source || !edgeParams.target) {
|
||||||
|
console.warn("[vueflow]: Can't create edge. An edge needs a source and a target.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let edge
|
||||||
|
if (isEdge(edgeParams)) {
|
||||||
|
edge = { ...edgeParams }
|
||||||
|
} else {
|
||||||
|
edge = {
|
||||||
|
...edgeParams,
|
||||||
|
id: getEdgeId(edgeParams),
|
||||||
|
} as Edge
|
||||||
|
}
|
||||||
|
edge = parseEdge(edge)
|
||||||
|
if (connectionExists(edge, edges)) return false
|
||||||
|
return edge
|
||||||
|
}
|
||||||
|
|
||||||
|
export const updateEdgeAction = (edge: GraphEdge, newConnection: Connection, edges: GraphEdge[], add: Actions['addEdges']) => {
|
||||||
|
if (!newConnection.source || !newConnection.target) {
|
||||||
|
console.warn("[vueflow]: Can't create new edge. An edge needs a source and a target.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const foundEdge = edges.find((e) => isGraphEdge(e) && e.id === edge.id)
|
||||||
|
|
||||||
|
if (!foundEdge) {
|
||||||
|
console.warn(`[vueflow]: The old edge with id=${edge.id} does not exist.`)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
edges.splice(edges.indexOf(edge), 1)
|
||||||
|
const newEdge = {
|
||||||
|
...edge,
|
||||||
|
id: getEdgeId(newConnection),
|
||||||
|
source: newConnection.source,
|
||||||
|
target: newConnection.target,
|
||||||
|
sourceHandle: newConnection.sourceHandle,
|
||||||
|
targetHandle: newConnection.targetHandle,
|
||||||
|
}
|
||||||
|
add([newEdge])
|
||||||
|
|
||||||
|
return newEdge
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createGraphNodes = (
|
||||||
|
nodes: Node[],
|
||||||
|
getNode: Getters['getNode'],
|
||||||
|
currGraphNodes: GraphNode[],
|
||||||
|
extent: CoordinateExtent,
|
||||||
|
) => {
|
||||||
|
const parentNodes: Record<string, true> = {}
|
||||||
|
|
||||||
|
const graphNodes = nodes.map((node) => {
|
||||||
|
const parsed = shallowReactive(
|
||||||
|
parseNode(node, extent, {
|
||||||
|
...getNode(node.id),
|
||||||
|
parentNode: node.parentNode,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
if (node.parentNode) {
|
||||||
|
parentNodes[node.parentNode] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed
|
||||||
|
})
|
||||||
|
|
||||||
|
graphNodes.forEach((node) => {
|
||||||
|
const nextNodes = [...graphNodes, ...currGraphNodes]
|
||||||
|
if (node.parentNode && !nextNodes.find((n) => n.id === node.parentNode)) {
|
||||||
|
console.warn(`[vueflow]: Parent node ${node.parentNode} not found`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.parentNode || parentNodes[node.id]) {
|
||||||
|
if (parentNodes[node.id]) {
|
||||||
|
node.isParent = true
|
||||||
|
}
|
||||||
|
const parent = node.parentNode ? getNode(node.parentNode) : undefined
|
||||||
|
if (parent) parent.isParent = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return graphNodes
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user