From 1ba733d783ca9c2c4b82045793e4c90f16b1be15 Mon Sep 17 00:00:00 2001 From: Sivan Duijn <sivanduijn@gmail.com> Date: Sun, 6 Mar 2022 17:28:43 +0100 Subject: [PATCH] feat(querybuilder): split logic up in usecases --- .../components/querybuilder/querybuilder.tsx | 32 +++++++++++++------ libs/querybuilder/usecases/src/index.ts | 4 ++- .../src/lib/createReactFlowElements.ts | 5 ++- .../src/lib/dragging/dragAttribute.ts | 12 +++++++ .../src/lib/dragging/dragAttributesAlong.ts | 27 ++++++++++++++++ .../{connPointsOnPills.ts => pillHandles.ts} | 0 6 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 libs/querybuilder/usecases/src/lib/dragging/dragAttribute.ts create mode 100644 libs/querybuilder/usecases/src/lib/dragging/dragAttributesAlong.ts rename libs/querybuilder/usecases/src/lib/{connPointsOnPills.ts => pillHandles.ts} (100%) diff --git a/apps/web-graphpolaris/src/components/querybuilder/querybuilder.tsx b/apps/web-graphpolaris/src/components/querybuilder/querybuilder.tsx index 8e42ebf76..031156107 100644 --- a/apps/web-graphpolaris/src/components/querybuilder/querybuilder.tsx +++ b/apps/web-graphpolaris/src/components/querybuilder/querybuilder.tsx @@ -1,4 +1,8 @@ -import { createReactFlowElements } from '@graphpolaris/querybuilder/usecases'; +import { + createReactFlowElements, + DragAttributePill, + DragAttributesAlong, +} from '@graphpolaris/querybuilder/usecases'; import { setQuerybuilderNodes, useAppDispatch, @@ -15,6 +19,7 @@ import ReactFlow, { FlowElement, Background, Node, + isNode, } from 'react-flow-renderer'; import styles from './querybuilder.module.scss'; import ConnectionLine from './customFlowLines/connection'; @@ -46,20 +51,27 @@ const QueryBuilder = (props: {}) => { event: React.MouseEvent<Element, MouseEvent>, node: Node<any> ) => { - const attr = nodes.getNodeAttributes(node.id); - const dx = node.position.x - attr.x; - const dy = node.position.y - attr.y; + const pNode = elements.find((e) => e.id == node.id); + if (!(pNode && isNode(pNode))) return; - nodes.forEachInNeighbor(node.id, (nb) => { - if (nodes.getNodeAttribute(nb, 'type') == 'attribute') { - nodes.updateNodeAttribute(nb, 'x', (x) => x + dx); - nodes.updateNodeAttribute(nb, 'y', (y) => y + dy); - } - }); + const dx = node.position.x - pNode.position.x; + const dy = node.position.y - pNode.position.y; nodes.setNodeAttribute(node.id, 'x', node.position.x); nodes.setNodeAttribute(node.id, 'y', node.position.y); + switch (nodes.getNodeAttribute(node.id, 'type')) { + case 'attribute': + DragAttributePill(node.id, nodes, dx, dy); + break; + case 'entity': + DragAttributesAlong(node.id, nodes, dx, dy); + break; + case 'relation': + DragAttributesAlong(node.id, nodes, dx, dy); + break; + } + dispatch(setQuerybuilderNodes(nodes.export())); }; diff --git a/libs/querybuilder/usecases/src/index.ts b/libs/querybuilder/usecases/src/index.ts index 587b11ec5..b84282029 100644 --- a/libs/querybuilder/usecases/src/index.ts +++ b/libs/querybuilder/usecases/src/index.ts @@ -1,4 +1,6 @@ export * from './lib/attribute/getAttributeBoolOperators'; export * from './lib/attribute/checkInput'; export * from './lib/createReactFlowElements'; -export * from './lib/connPointsOnPills'; +export * from './lib/pillHandles'; +export * from './lib/dragging/dragAttribute'; +export * from './lib/dragging/dragAttributesAlong'; diff --git a/libs/querybuilder/usecases/src/lib/createReactFlowElements.ts b/libs/querybuilder/usecases/src/lib/createReactFlowElements.ts index 76b9e83c4..1757b3291 100644 --- a/libs/querybuilder/usecases/src/lib/createReactFlowElements.ts +++ b/libs/querybuilder/usecases/src/lib/createReactFlowElements.ts @@ -12,7 +12,6 @@ export function createReactFlowElements(graph: Graph): Elements<Node | Edge> { switch (attributes.type) { case 'entity': data = { - name: attributes.name, isConnected: graph .neighbors(node) .some((nb) => graph.getNodeAttribute(nb, 'type') == 'relation'), @@ -20,7 +19,6 @@ export function createReactFlowElements(graph: Graph): Elements<Node | Edge> { break; case 'relation': data = { - name: attributes.name, isFromEntityConnected: graph .inNeighbors(node) .some((nb) => graph.getNodeAttribute(nb, 'type') == 'entity'), @@ -38,7 +36,6 @@ export function createReactFlowElements(graph: Graph): Elements<Node | Edge> { if (ERNeighbors.length > 0) attributeOfA = graph.getNodeAttribute(ERNeighbors[0], 'type'); data = { - name: attributes.name, datatype: attributes.datatype, operator: attributes.operator, attributeOfA: attributeOfA, @@ -46,6 +43,8 @@ export function createReactFlowElements(graph: Graph): Elements<Node | Edge> { break; } } + // Each pill should have a name and type + data = { ...data, name: attributes.name }; const RFNode: Node = { id: node, diff --git a/libs/querybuilder/usecases/src/lib/dragging/dragAttribute.ts b/libs/querybuilder/usecases/src/lib/dragging/dragAttribute.ts new file mode 100644 index 000000000..332ca29cd --- /dev/null +++ b/libs/querybuilder/usecases/src/lib/dragging/dragAttribute.ts @@ -0,0 +1,12 @@ +import Graph from 'graphology'; + +export function DragAttributePill( + id: string, + nodes: Graph, + dx: number, + dy: number +) { + // if the attribute is still connected to an entity or relation pill, disconnect + const es = nodes.outEdges(id); + es.forEach((e) => nodes.dropEdge(e)); +} diff --git a/libs/querybuilder/usecases/src/lib/dragging/dragAttributesAlong.ts b/libs/querybuilder/usecases/src/lib/dragging/dragAttributesAlong.ts new file mode 100644 index 000000000..56697ab3f --- /dev/null +++ b/libs/querybuilder/usecases/src/lib/dragging/dragAttributesAlong.ts @@ -0,0 +1,27 @@ +import Graph from 'graphology'; + +/** + * Changes the position of connected attributes. + * @param id The id of the node which could have attributes connected to it (entity or relation) + * @param nodes The graphology query builder object + * @param dx The change in x + * @param dy The change in y + * @returns True if any attribute positions were changed + */ +export function DragAttributesAlong( + id: string, + nodes: Graph, + dx: number, + dy: number +): boolean { + let didChangeAttributes = false; + nodes.forEachInNeighbor(id, (nb) => { + if (nodes.getNodeAttribute(nb, 'type') == 'attribute') { + nodes.updateNodeAttribute(nb, 'x', (x) => x + dx); + nodes.updateNodeAttribute(nb, 'y', (y) => y + dy); + didChangeAttributes = true; + } + }); + + return didChangeAttributes; +} diff --git a/libs/querybuilder/usecases/src/lib/connPointsOnPills.ts b/libs/querybuilder/usecases/src/lib/pillHandles.ts similarity index 100% rename from libs/querybuilder/usecases/src/lib/connPointsOnPills.ts rename to libs/querybuilder/usecases/src/lib/pillHandles.ts -- GitLab