Skip to content

Commit

Permalink
refactor: improve designer logic
Browse files Browse the repository at this point in the history
fixes #216
  • Loading branch information
macjuul committed Apr 25, 2024
1 parent a11899f commit 9069915
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 22 deletions.
4 changes: 3 additions & 1 deletion src/views/designer/TableGraphPane/helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ export function buildFlowNodes(tables: TableInfo[]): [Node[], Edge[]] {
return [nodes, edges];
}

type DimensionNode = { id: string, width: number, height: number };

/**
* Apply a layout to the given nodes and edges
*
Expand All @@ -119,7 +121,7 @@ export function buildFlowNodes(tables: TableInfo[]): [Node[], Edge[]] {
* @returns The changes to apply
*/
export async function applyNodeLayout(
nodes: InternalNode[],
nodes: DimensionNode[],
edges: Edge[],
direction: DiagramDirection
): Promise<NodeChange[]> {
Expand Down
62 changes: 41 additions & 21 deletions src/views/designer/TableGraphPane/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import classes from "./style.module.scss";
import { Icon } from "~/components/Icon";
import { ContentPane } from "~/components/Pane";
import { ActionIcon, Box, Button, Group, Kbd, Loader, Modal, Popover, Stack, Text, Title, Tooltip } from "@mantine/core";
import { Background, ReactFlow, useEdgesState, useNodesState, useReactFlow, useStore } from "reactflow";
import { Background, NodeChange, ReactFlow, useEdgesState, useNodesState, useReactFlow } from "reactflow";
import { ElementRef, useEffect, useLayoutEffect, useRef, useState } from "react";
import { InternalNode, NODE_TYPES, applyNodeLayout, buildFlowNodes, createSnapshot } from "./helpers";
import { NODE_TYPES, applyNodeLayout, buildFlowNodes, createSnapshot } from "./helpers";
import { DiagramDirection, DiagramMode, TableInfo } from "~/types";
import { useStable } from "~/hooks/stable";
import { useIsLight } from "~/hooks/theme";
Expand Down Expand Up @@ -61,32 +61,50 @@ export function TableGraphPane(props: TableGraphPaneProps) {
const isLight = useIsLight();

const { fitView, getViewport, setViewport } = useReactFlow();
const [nodes, setNodes, onNodesChange] = useNodesState([]);
const [nodes, setNodes, handleOnNodesChange] = useNodesState([]);
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
const internals = useStore(s => s.nodeInternals);

const [computing, setComputing] = useState(false);
const doFit = useRef(false);

useLayoutEffect(() => {
if (doFit.current) {
fitView();
doFit.current = false;
} else if (computing) {
const layoutNodes = [...internals.values()] as InternalNode[];
const direction = activeSession.diagramDirection;
const doLayoutRef = useRef(false);
const doFitRef = useRef(false);

const onNodesChange = useStable(async (changes: NodeChange[]) => {
handleOnNodesChange(changes);

applyNodeLayout(layoutNodes, edges, direction).then(async changes => {
if (changes.length === 0) {
return;
if (doLayoutRef.current) {
doLayoutRef.current = false;

const direction = activeSession.diagramDirection;
const dimNodes = changes.flatMap(change => {
if (change.type !== "dimensions" || !change.dimensions) {
return [];
}

onNodesChange(changes);
setComputing(false);
doFit.current = true;
return {
id: change.id,
width: change.dimensions.width,
height: change.dimensions.height,
};
});

const layoutChanges = await applyNodeLayout(dimNodes, edges, direction);

setComputing(false);

if (changes.length > 0) {
doFitRef.current = true;
handleOnNodesChange(layoutChanges);
fitView();
}
}
}, [internals]);
});

useEffect(() => {
if (doFitRef.current) {
doFitRef.current = false;
fitView();
}
}, [nodes]);

const renderGraph = useStable(async () => {
const [nodes, edges] = buildFlowNodes(props.tables);
Expand All @@ -101,6 +119,8 @@ export function TableGraphPane(props: TableGraphPaneProps) {
setNodes(nodes);
setEdges(edges);
setComputing(true);

doLayoutRef.current = true;
});

const saveImage = useStable(async (type: 'png' | 'svg') => {
Expand Down Expand Up @@ -243,7 +263,7 @@ export function TableGraphPane(props: TableGraphPaneProps) {
{
key: 'view',
icon: <Icon path={iconFullscreen} />,
title: 'Reset viewport',
title: 'Fit viewport',
onClick: () => fitView()
},
{
Expand Down

0 comments on commit 9069915

Please sign in to comment.