Skip to content

Commit

Permalink
fix: Fix position offset while dragging nodes on canvas (#1906)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dreammy23 authored Aug 27, 2024
2 parents 875b758 + 97bb8b2 commit 47777da
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 67 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ thirdparty
#web
# dependencies
/web/node_modules
/web/yarn.lock

.idea
# next.js
Expand All @@ -171,7 +172,6 @@ thirdparty
/web/npm-debug.log*
/web/yarn-debug.log*
/web/yarn-error.log*
/web/yarn.lock

# local env files
/web/.env.prod
Expand Down
2 changes: 1 addition & 1 deletion web/components/flow/add-nodes-sider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ const AddNodesSider: React.FC = () => {

return (
<Sider
className=' flex justify-center items-start nodrag bg-[#ffffff80] border-r border-[#d5e5f6] dark:bg-[#ffffff29] dark:border-[#ffffff66]'
className='flex justify-center items-start nodrag bg-[#ffffff80] border-r border-[#d5e5f6] dark:bg-[#ffffff29] dark:border-[#ffffff66]'
theme={mode}
width={280}
collapsible={true}
Expand Down
131 changes: 66 additions & 65 deletions web/pages/construct/flow/canvas/index.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import { apiInterceptors, getFlowById } from "@/client/api";
import MuiLoading from "@/components/common/loading";
import AddNodes from "@/components/flow/add-nodes";
import AddNodesSider from "@/components/flow/add-nodes-sider";
import ButtonEdge from "@/components/flow/button-edge";
import CanvasNode from "@/components/flow/canvas-node";
import { IFlowData, IFlowUpdateParam } from "@/types/flow";
import { apiInterceptors, getFlowById } from '@/client/api';
import MuiLoading from '@/components/common/loading';
import AddNodes from '@/components/flow/add-nodes';
import AddNodesSider from '@/components/flow/add-nodes-sider';
import ButtonEdge from '@/components/flow/button-edge';
import CanvasNode from '@/components/flow/canvas-node';
import { IFlowData, IFlowUpdateParam } from '@/types/flow';
import {
checkFlowDataRequied,
getUniqueNodeId,
mapUnderlineToHump,
} from "@/utils/flow";
} from '@/utils/flow';
import {
ExportOutlined,
FrownOutlined,
ImportOutlined,
SaveOutlined,
} from "@ant-design/icons";
import { Divider, Space, Tooltip, message, notification } from "antd";
import { useSearchParams } from "next/navigation";
} from '@ant-design/icons';
import { Divider, Space, Tooltip, message, notification } from 'antd';
import { useSearchParams } from 'next/navigation';
import React, {
DragEvent,
useCallback,
useEffect,
useRef,
useState,
} from "react";
import { useTranslation } from "react-i18next";
} from 'react';
import { useTranslation } from 'react-i18next';
import ReactFlow, {
Background,
Connection,
Expand All @@ -36,13 +36,13 @@ import ReactFlow, {
useNodesState,
useReactFlow,
Node,
} from "reactflow";
import "reactflow/dist/style.css";
} from 'reactflow';
import 'reactflow/dist/style.css';
import {
SaveFlowModal,
ExportFlowModal,
ImportFlowModal,
} from "@/components/flow/canvas-modal";
} from '@/components/flow/canvas-modal';

interface Props {
// Define your component props here
Expand All @@ -54,7 +54,7 @@ const Canvas: React.FC<Props> = () => {
const { t } = useTranslation();

const searchParams = useSearchParams();
const id = searchParams?.get("id") || "";
const id = searchParams?.get('id') || '';
const reactFlow = useReactFlow();

const [loading, setLoading] = useState(false);
Expand Down Expand Up @@ -87,10 +87,10 @@ const Canvas: React.FC<Props> = () => {
event.returnValue = message;
};

window.addEventListener("beforeunload", handleBeforeUnload);
window.addEventListener('beforeunload', handleBeforeUnload);

return () => {
window.removeEventListener("beforeunload", handleBeforeUnload);
window.removeEventListener('beforeunload', handleBeforeUnload);
};
}, []);

Expand All @@ -116,7 +116,7 @@ const Canvas: React.FC<Props> = () => {
function onConnect(connection: Connection) {
const newEdge = {
...connection,
type: "buttonedge",
type: 'buttonedge',
id: `${connection.source}|${connection.target}`,
};
setEdges((eds) => addEdge(newEdge, eds));
Expand All @@ -126,21 +126,26 @@ const Canvas: React.FC<Props> = () => {
(event: DragEvent) => {
event.preventDefault();
const reactFlowBounds = reactFlowWrapper.current!.getBoundingClientRect();
let nodeStr = event.dataTransfer.getData("application/reactflow");
if (!nodeStr || typeof nodeStr === "undefined") {
const sidebarWidth = (
document.getElementsByClassName('ant-layout-sider')?.[0] as HTMLElement
)?.offsetWidth; // get sidebar width

let nodeStr = event.dataTransfer.getData('application/reactflow');
if (!nodeStr || typeof nodeStr === 'undefined') {
return;
}

const nodeData = JSON.parse(nodeStr);
const position = reactFlow.screenToFlowPosition({
x: event.clientX - reactFlowBounds.left,
x: event.clientX - reactFlowBounds.left + sidebarWidth,
y: event.clientY - reactFlowBounds.top,
});
const nodeId = getUniqueNodeId(nodeData, reactFlow.getNodes());
nodeData.id = nodeId;
const newNode = {
id: nodeId,
position,
type: "customNode",
type: 'customNode',
data: nodeData,
};
setNodes((nds) =>
Expand All @@ -165,7 +170,7 @@ const Canvas: React.FC<Props> = () => {

const onDragOver = useCallback((event: DragEvent) => {
event.preventDefault();
event.dataTransfer.dropEffect = "move";
event.dataTransfer.dropEffect = 'move';
}, []);

function onSave() {
Expand All @@ -189,9 +194,9 @@ const Canvas: React.FC<Props> = () => {
})
);
return notification.error({
message: "Error",
message: 'Error',
description: message,
icon: <FrownOutlined className="text-red-600" />,
icon: <FrownOutlined className='text-red-600' />,
});
}
setIsSaveFlowModalOpen(true);
Expand All @@ -205,53 +210,49 @@ const Canvas: React.FC<Props> = () => {
setIsImportFlowModalOpen(true);
}

const getButtonList = () => {
const buttonList = [
{
title: t('Import'),
icon: <ImportOutlined className='block text-xl' onClick={onImport} />,
},
{
title: t('save'),
icon: <SaveOutlined className='block text-xl' onClick={onSave} />,
},
];

if (id !== '') {
buttonList.unshift({
title: t('Export'),
icon: <ExportOutlined className='block text-xl' onClick={onExport} />,
});
}

return buttonList;
};

return (
<>
<div className="flex flex-row">
<div className='flex flex-row'>
<AddNodesSider />

<div className="flex flex-col flex-1">
<Space className="my-2 mx-4 flex flex-row justify-end">
{[
{
title: t("Import"),
icon: (
<ImportOutlined
className="block text-xl"
onClick={onImport}
/>
),
},
(id !== '' && {
title: t("Export"),
icon: (
<ExportOutlined
className="block text-xl"
onClick={onExport}
/>
)
}
),
{
title: t("save"),
icon: (
<SaveOutlined className="block text-xl" onClick={onSave} />
),
},
].map(({ title, icon }) => (
<div className='flex flex-col flex-1'>
<Space className='my-2 mx-4 flex flex-row justify-end'>
{getButtonList().map(({ title, icon }) => (
<Tooltip
key={title}
title={title}
className="w-8 h-8 rounded-md bg-stone-300 dark:bg-zinc-700 dark:text-zinc-200 hover:text-blue-500 dark:hover:text-zinc-100"
className='w-8 h-8 rounded-md bg-stone-300 dark:bg-zinc-700 dark:text-zinc-200 hover:text-blue-500 dark:hover:text-zinc-100'
>
{icon}
</Tooltip>
))}
</Space>

<Divider className="mt-0 mb-0" />
<Divider className='mt-0 mb-0' />

<div className="h-[calc(100vh-48px)] w-full" ref={reactFlowWrapper}>
<div className='h-[calc(100vh-48px)] w-full' ref={reactFlowWrapper}>
<ReactFlow
nodes={nodes}
edges={edges}
Expand All @@ -265,13 +266,13 @@ const Canvas: React.FC<Props> = () => {
onDragOver={onDragOver}
minZoom={0.1}
fitView
deleteKeyCode={["Backspace", "Delete"]}
deleteKeyCode={['Backspace', 'Delete']}
>
<Controls
className="flex flex-row items-center"
position="bottom-center"
className='flex flex-row items-center'
position='bottom-center'
/>
<Background color="#aaa" gap={16} />
<Background color='#aaa' gap={16} />
{/* <AddNodes /> */}
</ReactFlow>
</div>
Expand Down Expand Up @@ -310,4 +311,4 @@ export default function CanvasWrapper() {
<Canvas />
</ReactFlowProvider>
);
}
}

0 comments on commit 47777da

Please sign in to comment.