feat: implement createNodeWithEdgeToTarget mutation for enhanced node connections
- Added a new mutation to create nodes connected to existing nodes, allowing for more dynamic interactions on the canvas. - Updated the CanvasPlacementContext to include the new mutation, improving the workflow for node creation and edge management. - Enhanced optimistic updates for immediate UI feedback during node and edge creation processes. - Refactored related components to support the new connection method, streamlining user interactions.
This commit is contained in:
@@ -81,6 +81,29 @@ type CreateNodeWithEdgeFromSourceMutation = ReactMutation<
|
||||
>
|
||||
>;
|
||||
|
||||
type CreateNodeWithEdgeToTargetMutation = ReactMutation<
|
||||
FunctionReference<
|
||||
"mutation",
|
||||
"public",
|
||||
{
|
||||
canvasId: Id<"canvases">;
|
||||
type: string;
|
||||
positionX: number;
|
||||
positionY: number;
|
||||
width: number;
|
||||
height: number;
|
||||
data: unknown;
|
||||
parentId?: Id<"nodes">;
|
||||
zIndex?: number;
|
||||
clientRequestId?: string;
|
||||
targetNodeId: Id<"nodes">;
|
||||
sourceHandle?: string;
|
||||
targetHandle?: string;
|
||||
},
|
||||
Id<"nodes">
|
||||
>
|
||||
>;
|
||||
|
||||
type FlowPoint = { x: number; y: number };
|
||||
|
||||
type CreateNodeWithIntersectionInput = {
|
||||
@@ -105,6 +128,12 @@ export type CreateNodeConnectedFromSourceInput = CreateNodeWithIntersectionInput
|
||||
targetHandle?: string;
|
||||
};
|
||||
|
||||
export type CreateNodeConnectedToTargetInput = CreateNodeWithIntersectionInput & {
|
||||
targetNodeId: Id<"nodes">;
|
||||
sourceHandle?: string;
|
||||
targetHandle?: string;
|
||||
};
|
||||
|
||||
type CanvasPlacementContextValue = {
|
||||
createNodeWithIntersection: (
|
||||
input: CreateNodeWithIntersectionInput,
|
||||
@@ -112,6 +141,9 @@ type CanvasPlacementContextValue = {
|
||||
createNodeConnectedFromSource: (
|
||||
input: CreateNodeConnectedFromSourceInput,
|
||||
) => Promise<Id<"nodes">>;
|
||||
createNodeConnectedToTarget: (
|
||||
input: CreateNodeConnectedToTargetInput,
|
||||
) => Promise<Id<"nodes">>;
|
||||
};
|
||||
|
||||
const CanvasPlacementContext = createContext<CanvasPlacementContextValue | null>(
|
||||
@@ -172,6 +204,7 @@ interface CanvasPlacementProviderProps {
|
||||
createNode: CreateNodeMutation;
|
||||
createNodeWithEdgeSplit: CreateNodeWithEdgeSplitMutation;
|
||||
createNodeWithEdgeFromSource: CreateNodeWithEdgeFromSourceMutation;
|
||||
createNodeWithEdgeToTarget: CreateNodeWithEdgeToTargetMutation;
|
||||
onCreateNodeSettled?: (payload: {
|
||||
clientRequestId?: string;
|
||||
realId: Id<"nodes">;
|
||||
@@ -184,6 +217,7 @@ export function CanvasPlacementProvider({
|
||||
createNode,
|
||||
createNodeWithEdgeSplit,
|
||||
createNodeWithEdgeFromSource,
|
||||
createNodeWithEdgeToTarget,
|
||||
onCreateNodeSettled,
|
||||
children,
|
||||
}: CanvasPlacementProviderProps) {
|
||||
@@ -327,9 +361,65 @@ export function CanvasPlacementProvider({
|
||||
[canvasId, createNodeWithEdgeFromSource, onCreateNodeSettled],
|
||||
);
|
||||
|
||||
const createNodeConnectedToTarget = useCallback(
|
||||
async ({
|
||||
type,
|
||||
position,
|
||||
width,
|
||||
height,
|
||||
data,
|
||||
zIndex,
|
||||
clientRequestId,
|
||||
targetNodeId,
|
||||
sourceHandle,
|
||||
targetHandle,
|
||||
}: CreateNodeConnectedToTargetInput) => {
|
||||
const defaults = NODE_DEFAULTS[type] ?? {
|
||||
width: 200,
|
||||
height: 100,
|
||||
data: {},
|
||||
};
|
||||
|
||||
const effectiveWidth = width ?? defaults.width;
|
||||
const effectiveHeight = height ?? defaults.height;
|
||||
|
||||
const payload = {
|
||||
canvasId,
|
||||
type,
|
||||
positionX: position.x,
|
||||
positionY: position.y,
|
||||
width: effectiveWidth,
|
||||
height: effectiveHeight,
|
||||
data: {
|
||||
...defaults.data,
|
||||
...(data ?? {}),
|
||||
canvasId,
|
||||
},
|
||||
...(zIndex !== undefined ? { zIndex } : {}),
|
||||
...(clientRequestId !== undefined ? { clientRequestId } : {}),
|
||||
targetNodeId,
|
||||
sourceHandle,
|
||||
targetHandle,
|
||||
};
|
||||
|
||||
const realId = await createNodeWithEdgeToTarget(payload);
|
||||
onCreateNodeSettled?.({ clientRequestId, realId });
|
||||
return realId;
|
||||
},
|
||||
[canvasId, createNodeWithEdgeToTarget, onCreateNodeSettled],
|
||||
);
|
||||
|
||||
const value = useMemo(
|
||||
() => ({ createNodeWithIntersection, createNodeConnectedFromSource }),
|
||||
[createNodeConnectedFromSource, createNodeWithIntersection],
|
||||
() => ({
|
||||
createNodeWithIntersection,
|
||||
createNodeConnectedFromSource,
|
||||
createNodeConnectedToTarget,
|
||||
}),
|
||||
[
|
||||
createNodeConnectedFromSource,
|
||||
createNodeConnectedToTarget,
|
||||
createNodeWithIntersection,
|
||||
],
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user