style: reformated DragDropSidebar.tsx to be compliant with code standards
ref: N25B-114
This commit is contained in:
@@ -1,137 +1,152 @@
|
|||||||
import { useDraggable } from '@neodrag/react';
|
import {useDraggable} from '@neodrag/react';
|
||||||
import {
|
import {
|
||||||
useReactFlow,
|
useReactFlow,
|
||||||
type XYPosition
|
type XYPosition
|
||||||
} from '@xyflow/react';
|
} from '@xyflow/react';
|
||||||
import {
|
import {
|
||||||
type ReactNode,
|
type ReactNode,
|
||||||
useCallback,
|
useCallback,
|
||||||
useRef,
|
useRef,
|
||||||
useState
|
useState
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
|
|
||||||
// improve later to create better automatic IDs
|
|
||||||
let id = 0;
|
let id = 0;
|
||||||
const getId = () => `dndnode_${id++}`;
|
const getId = () => `dndnode_${id++}`;
|
||||||
|
|
||||||
|
|
||||||
interface DraggableNodeProps {
|
interface DraggableNodeProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
nodeType: string;
|
nodeType: string;
|
||||||
onDrop: (nodeType: string, position: XYPosition) => void;
|
onDrop: (nodeType: string, position: XYPosition) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function DraggableNode({ className, children, nodeType, onDrop }: DraggableNodeProps) {
|
function DraggableNode({className, children, nodeType, onDrop}: DraggableNodeProps) {
|
||||||
const draggableRef = useRef<HTMLDivElement>(null);
|
const draggableRef = useRef<HTMLDivElement>(null);
|
||||||
const [position, setPosition] = useState<XYPosition>({ x: 0, y: 0 });
|
const [position, setPosition] = useState<XYPosition>({x: 0, y: 0});
|
||||||
|
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
useDraggable(draggableRef, {
|
useDraggable(draggableRef, {
|
||||||
position: position,
|
position: position,
|
||||||
onDrag: ({ offsetX, offsetY }) => {
|
onDrag: ({offsetX, offsetY}) => {
|
||||||
// Calculate position relative to the viewport
|
// Calculate position relative to the viewport
|
||||||
setPosition({
|
setPosition({
|
||||||
x: offsetX,
|
x: offsetX,
|
||||||
y: offsetY,
|
y: offsetY,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onDragEnd: ({ event }) => {
|
onDragEnd: ({event}) => {
|
||||||
setPosition({ x: 0, y: 0 });
|
setPosition({x: 0, y: 0});
|
||||||
onDrop(nodeType, {
|
onDrop(nodeType, {
|
||||||
x: event.clientX,
|
x: event.clientX,
|
||||||
y: event.clientY,
|
y: event.clientY,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className === "default" ? "draggable-node" : "draggable-node" + "__" + className} ref={draggableRef}>
|
<div className={className === "default" ? "draggable-node" : "draggable-node" + "__" + className}
|
||||||
{children}
|
ref={draggableRef}>
|
||||||
</div>
|
{children}
|
||||||
);
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Sidebar() {
|
export function Sidebar() {
|
||||||
const { setNodes, screenToFlowPosition } = useReactFlow();
|
const {setNodes, screenToFlowPosition} = useReactFlow();
|
||||||
|
|
||||||
const handleNodeDrop = useCallback(
|
const handleNodeDrop = useCallback(
|
||||||
(nodeType: string, screenPosition: XYPosition) => {
|
(nodeType: string, screenPosition: XYPosition) => {
|
||||||
const flow = document.querySelector('.react-flow');
|
const flow = document.querySelector('.react-flow');
|
||||||
const flowRect = flow?.getBoundingClientRect();
|
const flowRect = flow?.getBoundingClientRect();
|
||||||
const isInFlow =
|
const isInFlow =
|
||||||
flowRect &&
|
flowRect &&
|
||||||
screenPosition.x >= flowRect.left &&
|
screenPosition.x >= flowRect.left &&
|
||||||
screenPosition.x <= flowRect.right &&
|
screenPosition.x <= flowRect.right &&
|
||||||
screenPosition.y >= flowRect.top &&
|
screenPosition.y >= flowRect.top &&
|
||||||
screenPosition.y <= flowRect.bottom;
|
screenPosition.y <= flowRect.bottom;
|
||||||
|
|
||||||
// Create a new node and add it to the flow
|
// Create a new node and add it to the flow
|
||||||
if (isInFlow) {
|
if (isInFlow) {
|
||||||
const position = screenToFlowPosition(screenPosition);
|
const position = screenToFlowPosition(screenPosition);
|
||||||
|
|
||||||
const newNode = () => {
|
const newNode = () => {
|
||||||
switch (nodeType) {
|
switch (nodeType) {
|
||||||
case "phase":
|
case "phase":
|
||||||
return {
|
return {
|
||||||
id: getId(),
|
id: getId(),
|
||||||
type: nodeType,
|
type: nodeType,
|
||||||
position,
|
position,
|
||||||
data: {label: `"new"`, number: (-1)},
|
data: {label: `"new"`, number: (-1)},
|
||||||
};
|
};
|
||||||
case "start":
|
case "start":
|
||||||
return {
|
return {
|
||||||
id: getId(),
|
id: getId(),
|
||||||
type: nodeType,
|
type: nodeType,
|
||||||
position,
|
position,
|
||||||
data: {label: `new start node`},
|
data: {label: `new start node`},
|
||||||
};
|
};
|
||||||
case "end":
|
case "end":
|
||||||
return {
|
return {
|
||||||
id: getId(),
|
id: getId(),
|
||||||
type: nodeType,
|
type: nodeType,
|
||||||
position,
|
position,
|
||||||
data: {label: `new end node`},
|
data: {label: `new end node`},
|
||||||
};
|
};
|
||||||
case "norm":
|
case "norm":
|
||||||
return {
|
return {
|
||||||
id: getId(),
|
id: getId(),
|
||||||
type: nodeType,
|
type: nodeType,
|
||||||
position,
|
position,
|
||||||
data: {label: `new norm node`},
|
data: {label: `new norm node`},
|
||||||
};
|
};
|
||||||
default: {
|
default: {
|
||||||
return {
|
return {
|
||||||
id: getId(),
|
id: getId(),
|
||||||
type: nodeType,
|
type: nodeType,
|
||||||
position,
|
position,
|
||||||
data: {label: `new default node`},
|
data: {label: `new default node`},
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setNodes((nds) => nds.concat(newNode()));
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
[setNodes, screenToFlowPosition],
|
}
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
setNodes((nds) => nds.concat(newNode()));
|
||||||
<aside style={{padding: '10px 10px',outline: '2.5pt solid black',borderRadius: '0pt 0pt 5pt 5pt', borderColor:'dimgrey', backgroundColor:'canvas', display:'flex', flexDirection: 'column', gap: '1rem'}}>
|
}
|
||||||
<div className="description">
|
},
|
||||||
You can drag these nodes to the pane to create new nodes.
|
[setNodes, screenToFlowPosition],
|
||||||
</div>
|
);
|
||||||
<div className="DraggableNodeContainer" style={{backgroundColor:'canvas', display: 'flex', flexDirection: 'row', gap: '1rem', justifyContent: 'center'}}>
|
|
||||||
<DraggableNode className="phase" nodeType="phase" onDrop={handleNodeDrop}>
|
return (
|
||||||
phase Node
|
<aside style={{
|
||||||
</DraggableNode>
|
padding: '10px 10px',
|
||||||
<DraggableNode className="norm" nodeType="norm" onDrop={handleNodeDrop}>
|
outline: '2.5pt solid black',
|
||||||
norm Node
|
borderRadius: '0pt 0pt 5pt 5pt',
|
||||||
</DraggableNode>
|
borderColor: 'dimgrey',
|
||||||
</div>
|
backgroundColor: 'canvas',
|
||||||
</aside>
|
display: 'flex',
|
||||||
);
|
flexDirection: 'column',
|
||||||
|
gap: '1rem'
|
||||||
|
}}>
|
||||||
|
<div className="description">
|
||||||
|
You can drag these nodes to the pane to create new nodes.
|
||||||
|
</div>
|
||||||
|
<div className="DraggableNodeContainer" style={{
|
||||||
|
backgroundColor: 'canvas',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
gap: '1rem',
|
||||||
|
justifyContent: 'center'
|
||||||
|
}}>
|
||||||
|
<DraggableNode className="phase" nodeType="phase" onDrop={handleNodeDrop}>
|
||||||
|
phase Node
|
||||||
|
</DraggableNode>
|
||||||
|
<DraggableNode className="norm" nodeType="norm" onDrop={handleNodeDrop}>
|
||||||
|
norm Node
|
||||||
|
</DraggableNode>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user