chore(vue-flow,store): move store utils to separate file

This commit is contained in:
Braks
2022-05-27 23:36:01 +02:00
parent ec7901ef34
commit 78d8190f58
3 changed files with 122 additions and 117 deletions
+30 -117
View File
@@ -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,
})),
) )
} }
+1
View File
@@ -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'
+91
View File
@@ -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
}