feat(nodes): add start node and create new node function

This commit is contained in:
2025-08-06 12:19:55 +05:00
parent 65ed6b9561
commit ee4051f523
7 changed files with 285 additions and 41 deletions

View File

@@ -1,13 +1,16 @@
import { Handle, Node, NodeProps, Position } from "@xyflow/react";
import DEFAULT_HANDLE_STYLE from "./defaultHandleStyle";
import { Handle, Node, NodeProps, Position, Edge } from "@xyflow/react";
import { HANDLE_STYLE_CONNECTED } from "./defaultHandleStyle";
import { useTranslation } from "react-i18next";
type AppropriationNodeData = { value: string };
type AppropriationNodeData = { value: string; edges?: Edge[] };
export default function AppropriationNode({
data,
}: NodeProps<Node & AppropriationNodeData>) {
id,
edges = [],
}: NodeProps<Node & AppropriationNodeData> & { edges?: Edge[] }) {
const { t } = useTranslation();
return (
<div
style={{
@@ -48,7 +51,9 @@ export default function AppropriationNode({
{data.value as string}
</div>
<Handle
style={{ ...DEFAULT_HANDLE_STYLE }}
style={{
...HANDLE_STYLE_CONNECTED,
}}
type="target"
position={Position.Top}
id="input"

View File

@@ -1,13 +1,31 @@
import { Handle, NodeProps, Position, Node } from "@xyflow/react";
import DEFAULT_HANDLE_STYLE from "./defaultHandleStyle";
import { Handle, NodeProps, Position, Node, Edge } from "@xyflow/react";
import {
HANDLE_STYLE_CONNECTED,
HANDLE_STYLE_CONNECTED_V,
HANDLE_STYLE_DISCONNECTED,
HANDLE_STYLE_DISCONNECTED_V,
} from "./defaultHandleStyle";
import { useTranslation } from "react-i18next";
import { useState } from "react";
interface IfElseNodeProps extends Node {
condition: string;
edges?: Edge[];
}
export default function IfElseNode({ id, data }: NodeProps<IfElseNodeProps>) {
export default function IfElseNode({
id,
data,
edges = [],
}: NodeProps<IfElseNodeProps> & { edges?: Edge[] }) {
const { t } = useTranslation();
const isHandle1Connected = edges.some(
(e: Edge) => e.source === id && e.sourceHandle === "1"
);
const isHandle2Connected = edges.some(
(e: Edge) => e.source === id && e.sourceHandle === "2"
);
return (
<>
<div
@@ -16,7 +34,8 @@ export default function IfElseNode({ id, data }: NodeProps<IfElseNodeProps>) {
borderRadius: 8,
backgroundColor: "white",
width: "248px",
height: "144px",
minHeight: "144px",
position: "relative",
}}
>
<div
@@ -43,12 +62,26 @@ export default function IfElseNode({ id, data }: NodeProps<IfElseNodeProps>) {
style={{
display: "flex",
alignItems: "center",
paddingLeft: "12px",
padding: "12px",
fontSize: "14px",
height: "48px",
minHeight: "48px",
position: "relative",
}}
>
{t("conditionIf", { condition: data.condition })}
<Handle
type="source"
position={Position.Right}
id="1"
style={{
...(isHandle1Connected
? { ...HANDLE_STYLE_CONNECTED_V }
: { ...HANDLE_STYLE_DISCONNECTED_V }),
position: "absolute",
top: "50%",
transform: "translateY(-50%)",
}}
/>
</div>
<div style={{ height: "1px", backgroundColor: "#E2E2E2" }}></div>
@@ -64,18 +97,21 @@ export default function IfElseNode({ id, data }: NodeProps<IfElseNodeProps>) {
{t("conditionElse")}
</div>
<Handle type="target" position={Position.Top} id="input" />
<Handle
type="source"
position={Position.Right}
id="1"
style={{ ...DEFAULT_HANDLE_STYLE }}
type="target"
position={Position.Top}
id="input"
style={{ ...HANDLE_STYLE_CONNECTED }}
/>
<Handle
type="source"
position={Position.Bottom}
id="2"
style={{ ...DEFAULT_HANDLE_STYLE }}
style={
isHandle2Connected
? { ...HANDLE_STYLE_CONNECTED }
: { ...HANDLE_STYLE_DISCONNECTED }
}
/>
</div>
</>

View File

@@ -0,0 +1,83 @@
import { Edge, Handle, Node, NodeProps, Position } from "@xyflow/react";
import { useTranslation } from "react-i18next";
import {
HANDLE_STYLE_CONNECTED,
HANDLE_STYLE_DISCONNECTED,
} from "./defaultHandleStyle";
import { useState } from "react";
interface StartNodeProps extends Node {
edges?: Edge[];
}
export default function StartNode({
id,
edges = [],
}: NodeProps<StartNodeProps> & { edges?: Edge[] }) {
const { t } = useTranslation();
const isHandleConnected = edges.some(
(e: Edge) => e.source === id && e.sourceHandle === "1"
);
return (
<div
style={{
border: "0px solid",
borderRadius: 8,
backgroundColor: "white",
width: "248px",
}}
>
<div
style={{
display: "flex",
alignItems: "center",
paddingLeft: "12px",
height: "40px",
fontWeight: "600px",
fontSize: "16px",
gap: "12px",
backgroundColor: "#D4E0BD",
borderRadius: "8px 8px 0 0",
}}
>
<div
style={{
height: "24px",
width: "24px",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<img
style={{ height: "16px", width: "18px" }}
src="/icons/node/home.svg"
alt="start logo"
/>
</div>
{t("startNode")}
</div>
<div style={{ height: "1px", backgroundColor: "#E2E2E2" }}></div>
<div
style={{
display: "flex",
alignItems: "center",
padding: "12px",
fontSize: "14px",
}}
>
{t("startNodeDescription")}
</div>
<Handle
type="source"
position={Position.Bottom}
id="1"
style={
isHandleConnected
? { ...HANDLE_STYLE_CONNECTED }
: { ...HANDLE_STYLE_DISCONNECTED }
}
/>
</div>
);
}

View File

@@ -1,7 +1,34 @@
const DEFAULT_HANDLE_STYLE = {
// horizontal
const HANDLE_STYLE_CONNECTED = {
width: 8,
height: 8,
backgroundColor: "#BDBDBD",
};
export default DEFAULT_HANDLE_STYLE;
// horizontal
const HANDLE_STYLE_DISCONNECTED = {
width: 20,
height: 20,
backgroundColor: "#C7D95A",
borderColor: "#606060",
borderWidth: 2,
};
// vertical
const HANDLE_STYLE_CONNECTED_V = {
...HANDLE_STYLE_CONNECTED,
right: "-4px",
};
// vertical
const HANDLE_STYLE_DISCONNECTED_V = {
...HANDLE_STYLE_DISCONNECTED,
right: "-10px",
};
export {
HANDLE_STYLE_CONNECTED,
HANDLE_STYLE_DISCONNECTED,
HANDLE_STYLE_CONNECTED_V,
HANDLE_STYLE_DISCONNECTED_V,
};