Added colored handle with conic background

This commit is contained in:
Lucas Oliveira 2024-06-17 20:19:56 -03:00
commit 07bf4d390d
5 changed files with 189 additions and 122 deletions

View file

@ -37,9 +37,9 @@ import {
isValidConnection, isValidConnection,
scapedJSONStringfy, scapedJSONStringfy,
} from "../../../../utils/reactflowUtils"; } from "../../../../utils/reactflowUtils";
import { nodeColors } from "../../../../utils/styleUtils";
import { import {
classNames, classNames,
cn,
groupByFamily, groupByFamily,
isThereModal, isThereModal,
} from "../../../../utils/utils"; } from "../../../../utils/utils";
@ -58,7 +58,7 @@ export default function ParameterComponent({
data, data,
tooltipTitle, tooltipTitle,
title, title,
color, colors,
type, type,
name = "", name = "",
required = false, required = false,
@ -282,39 +282,63 @@ export default function ParameterComponent({
} }
side={left ? "left" : "right"} side={left ? "left" : "right"}
> >
<Handle <div>
data-test-id={`handle-${title.toLowerCase()}-${ <Handle
left ? "target" : "source" data-test-id={`handle-${title.toLowerCase()}-${
}`} left ? "target" : "source"
type={left ? "target" : "source"} }`}
position={left ? Position.Left : Position.Right} type={left ? "target" : "source"}
key={ position={left ? Position.Left : Position.Right}
proxy key={
? scapedJSONStringfy({ ...id, proxy }) proxy
: scapedJSONStringfy(id) ? scapedJSONStringfy({ ...id, proxy })
} : scapedJSONStringfy(id)
id={ }
proxy id={
? scapedJSONStringfy({ ...id, proxy }) proxy
: scapedJSONStringfy(id) ? scapedJSONStringfy({ ...id, proxy })
} : scapedJSONStringfy(id)
isValidConnection={(connection) => }
isValidConnection(connection, nodes, edges) isValidConnection={(connection) =>
} isValidConnection(connection, nodes, edges)
className={classNames( }
left ? "my-12 -ml-0.5" : "my-12 -mr-0.5", className={classNames(
"h-3 w-3 rounded-full border-2 bg-background", left ? "my-12 -ml-1" : "my-12 -mr-1",
!showNode ? "mt-0" : "", "h-4 w-4 rounded-full border-2 bg-background",
)} !showNode ? "mt-0" : "",
style={{ )}
borderColor: color ?? nodeColors.unknown, style={{
}} background:
onClick={() => { "conic-gradient(" +
setFilterEdge( colors
groupByFamily(myData, tooltipTitle!, left, nodes!), .map(
); (color, index) =>
}} color +
></Handle> " " +
(360 / colors.length) * index +
"deg " +
(360 / colors.length) * (index + 1) +
"deg",
)
.join(" ,") +
")",
WebkitMaskImage:
"radial-gradient(transparent 40%, black 44%)",
maskImage: "radial-gradient(transparent 40%, black 44%)",
}}
onClick={() => {
setFilterEdge(
groupByFamily(myData, tooltipTitle!, left, nodes!),
);
}}
></Handle>
<div
className={cn(
left ? "my-12 -ml-1" : "my-12 -mr-1",
"absolute -left-[4px] top-[50%] z-10 h-4 w-4 translate-y-[-50%] rounded-full bg-background",
)}
/>
</div>
</ShadTooltip> </ShadTooltip>
</div> </div>
</Button> </Button>
@ -445,28 +469,54 @@ export default function ParameterComponent({
} }
side={left ? "left" : "right"} side={left ? "left" : "right"}
> >
<Handle <div>
data-test-id={`handle-${title.toLowerCase()}-${ <Handle
left ? "left" : "right" data-test-id={`handle-${title.toLowerCase()}-${
}`} left ? "left" : "right"
type={left ? "target" : "source"} }`}
position={left ? Position.Left : Position.Right} type={left ? "target" : "source"}
key={scapedJSONStringfy(proxy ? { ...id, proxy } : id)} position={left ? Position.Left : Position.Right}
id={scapedJSONStringfy(proxy ? { ...id, proxy } : id)} key={scapedJSONStringfy(proxy ? { ...id, proxy } : id)}
isValidConnection={(connection) => id={scapedJSONStringfy(proxy ? { ...id, proxy } : id)}
isValidConnection(connection, nodes, edges) isValidConnection={(connection) =>
} isValidConnection(connection, nodes, edges)
className={classNames( }
left ? "-ml-0.5" : "-mr-0.5", className={classNames(
"h-3 w-3 rounded-full border-2 bg-background", left ? "-ml-1" : "-mr-1",
)} "z-20 h-4 w-4 rounded-full border-none bg-background",
style={{ borderColor: color ?? nodeColors.unknown }} )}
onClick={() => { style={{
setFilterEdge( background:
groupByFamily(myData, tooltipTitle!, left, nodes!), "conic-gradient(" +
); colors
}} .map(
/> (color, index) =>
color +
" " +
(360 / colors.length) * index +
"deg " +
(360 / colors.length) * (index + 1) +
"deg",
)
.join(" ,") +
")",
WebkitMaskImage:
"radial-gradient(transparent 40%, black 44%)",
maskImage: "radial-gradient(transparent 40%, black 44%)",
}}
onClick={() => {
setFilterEdge(
groupByFamily(myData, tooltipTitle!, left, nodes!),
);
}}
/>
<div
className={cn(
"absolute top-[50%] z-10 h-4 w-4 translate-y-[-50%] rounded-full bg-background",
left ? "-left-[4px] -ml-1" : "-right-[4px] -mr-1",
)}
/>
</div>
</ShadTooltip> </ShadTooltip>
</div> </div>
</Button> </Button>
@ -486,7 +536,7 @@ export default function ParameterComponent({
// Commenting this out until we have a better // Commenting this out until we have a better
// way to display // way to display
// (data.node?.template[name]?.refresh ? "w-5/6 " : "") + // (data.node?.template[name]?.refresh ? "w-5/6 " : "") +
"flex-grow mt-2" "mt-2 flex-grow"
} }
> >
<InputListComponent <InputListComponent

View file

@ -32,6 +32,8 @@ import { nodeColors, nodeIconsLucide } from "../../utils/styleUtils";
import { classNames, cn } from "../../utils/utils"; import { classNames, cn } from "../../utils/utils";
import { countHandlesFn } from "../helpers/count-handles"; import { countHandlesFn } from "../helpers/count-handles";
import { getSpecificClassFromBuildStatus } from "../helpers/get-class-from-build-status"; import { getSpecificClassFromBuildStatus } from "../helpers/get-class-from-build-status";
import { getNodeInputColors } from "../helpers/get-node-input-colors";
import { getNodeOutputColors } from "../helpers/get-node-output-colors";
import useCheckCodeValidity from "../hooks/use-check-code-validity"; import useCheckCodeValidity from "../hooks/use-check-code-validity";
import useIconNodeRender from "../hooks/use-icon-render"; import useIconNodeRender from "../hooks/use-icon-render";
import useIconStatus from "../hooks/use-icons-status"; import useIconStatus from "../hooks/use-icons-status";
@ -279,12 +281,7 @@ export default function GenericNode({
}) + idx }) + idx
} }
data={data} data={data}
color={ colors={getNodeOutputColors(output, data, types)}
nodeColors[output.selected ?? output.types[0]] ??
nodeColors[types[output.selected ?? output.types[0]]] ??
nodeColors[types[data.type]] ??
nodeColors.unknown
}
outputProxy={output.proxy} outputProxy={output.proxy}
title={output.display_name ?? output.name} title={output.display_name ?? output.name}
tooltipTitle={output.selected ?? output.types[0]} tooltipTitle={output.selected ?? output.types[0]}
@ -477,36 +474,11 @@ export default function GenericNode({
proxy: data.node!.template[templateField].proxy, proxy: data.node!.template[templateField].proxy,
})} })}
data={data} data={data}
color={ colors={getNodeInputColors(
data.node?.template[templateField].input_types && data.node?.template[templateField].input_types,
data.node?.template[templateField].input_types! data.node?.template[templateField].type,
.length > 0 types,
? nodeColors[ )}
data.node?.template[templateField]
.input_types![
data.node?.template[templateField]
.input_types!.length - 1
]
] ??
nodeColors[
types[
data.node?.template[templateField]
.input_types![
data.node?.template[templateField]
.input_types!.length - 1
]
]
]
: nodeColors[
data.node?.template[templateField].type!
] ??
nodeColors[
types[
data.node?.template[templateField].type!
]
] ??
nodeColors.unknown
}
title={getFieldTitle( title={getFieldTitle(
data.node?.template!, data.node?.template!,
templateField, templateField,
@ -739,33 +711,11 @@ export default function GenericNode({
proxy: data.node!.template[templateField].proxy, proxy: data.node!.template[templateField].proxy,
})} })}
data={data} data={data}
color={ colors={getNodeInputColors(
data.node?.template[templateField].input_types && data.node?.template[templateField].input_types,
data.node?.template[templateField].input_types! data.node?.template[templateField].type,
.length > 0 types,
? nodeColors[ )}
data.node?.template[templateField].input_types![
data.node?.template[templateField]
.input_types!.length - 1
]
] ??
nodeColors[
types[
data.node?.template[templateField]
.input_types![
data.node?.template[templateField]
.input_types!.length - 1
]
]
]
: nodeColors[
data.node?.template[templateField].type!
] ??
nodeColors[
types[data.node?.template[templateField].type!]
] ??
nodeColors.unknown
}
title={getFieldTitle( title={getFieldTitle(
data.node?.template!, data.node?.template!,
templateField, templateField,

View file

@ -0,0 +1,34 @@
import { nodeColors } from "../../utils/styleUtils";
export function getNodeInputColors(input_types, type, types) {
// Helper function to get the color based on type
const getColorByType = (type) => nodeColors[type] ?? nodeColors.unknown;
// If input_types is not null and has elements, map colors based on input_types
if (input_types && input_types.length > 0) {
// Map through input_types and get colors from nodeColors
const colorsFromInputs = input_types
.map((input) => nodeColors[input])
.filter((color) => color);
if (colorsFromInputs.length > 0) {
return colorsFromInputs;
}
// If no valid colors found in the previous step, map colors based on types[nodeColors[input]]
const colorsFromInputTypes = input_types
.map((input) => getColorByType(types[input]))
.filter((color) => color);
if (colorsFromInputTypes.length > 0) {
return colorsFromInputTypes;
}
}
// If input_types is null or empty, use the fallback logic
const fallbackColors = [getColorByType(type)];
if (fallbackColors.length > 0) {
return fallbackColors;
}
// Default to unknown color
return [nodeColors.unknown];
}

View file

@ -0,0 +1,33 @@
import { nodeColors } from "../../utils/styleUtils";
export function getNodeOutputColors(output, data, types): string[] {
// Helper function to get the color based on type
const getColorByType = (type) => nodeColors[type] ?? nodeColors.unknown;
// Try to get the color based on the selected node
let color: string = nodeColors[output.selected];
if (color) return [color];
// Try to get the colors based on the output types
let colors: string[] = output.types
.map((type) => nodeColors[type])
.filter((color) => color);
if (colors.length > 0) return colors;
// Try to get the color based on the type of the selected node
color = nodeColors[types[output.selected]];
if (color) return [color];
// Try to get the colors based on the types of output
colors = output.types
.map((type) => getColorByType(types[type]))
.filter((color) => color);
if (colors.length > 0) return colors;
// Try to get the color based on the type in data
color = nodeColors[types[data.type]];
if (color) return [color];
// Default to unknown color
return [nodeColors.unknown];
}

View file

@ -65,7 +65,7 @@ export type ParameterComponentType = {
conditionPath?: string | null; conditionPath?: string | null;
key: string; key: string;
id: sourceHandleType | targetHandleType; id: sourceHandleType | targetHandleType;
color: string; colors: string[];
left: boolean; left: boolean;
type: string | undefined; type: string | undefined;
required?: boolean; required?: boolean;