From 07bf4d390d15f9d90a3b70dcc78ab16aeecc9cb1 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Mon, 17 Jun 2024 20:19:56 -0300 Subject: [PATCH] Added colored handle with conic background --- .../components/parameterComponent/index.tsx | 166 ++++++++++++------ .../src/CustomNodes/GenericNode/index.tsx | 76 ++------ .../helpers/get-node-input-colors.ts | 34 ++++ .../helpers/get-node-output-colors.ts | 33 ++++ src/frontend/src/types/components/index.ts | 2 +- 5 files changed, 189 insertions(+), 122 deletions(-) create mode 100644 src/frontend/src/CustomNodes/helpers/get-node-input-colors.ts create mode 100644 src/frontend/src/CustomNodes/helpers/get-node-output-colors.ts diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 09e211a1c..8e8657af4 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -37,9 +37,9 @@ import { isValidConnection, scapedJSONStringfy, } from "../../../../utils/reactflowUtils"; -import { nodeColors } from "../../../../utils/styleUtils"; import { classNames, + cn, groupByFamily, isThereModal, } from "../../../../utils/utils"; @@ -58,7 +58,7 @@ export default function ParameterComponent({ data, tooltipTitle, title, - color, + colors, type, name = "", required = false, @@ -282,39 +282,63 @@ export default function ParameterComponent({ } side={left ? "left" : "right"} > - - isValidConnection(connection, nodes, edges) - } - className={classNames( - left ? "my-12 -ml-0.5" : "my-12 -mr-0.5", - "h-3 w-3 rounded-full border-2 bg-background", - !showNode ? "mt-0" : "", - )} - style={{ - borderColor: color ?? nodeColors.unknown, - }} - onClick={() => { - setFilterEdge( - groupByFamily(myData, tooltipTitle!, left, nodes!), - ); - }} - > +
+ + isValidConnection(connection, nodes, edges) + } + className={classNames( + left ? "my-12 -ml-1" : "my-12 -mr-1", + "h-4 w-4 rounded-full border-2 bg-background", + !showNode ? "mt-0" : "", + )} + style={{ + background: + "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!), + ); + }} + > +
+
@@ -445,28 +469,54 @@ export default function ParameterComponent({ } side={left ? "left" : "right"} > - - isValidConnection(connection, nodes, edges) - } - className={classNames( - left ? "-ml-0.5" : "-mr-0.5", - "h-3 w-3 rounded-full border-2 bg-background", - )} - style={{ borderColor: color ?? nodeColors.unknown }} - onClick={() => { - setFilterEdge( - groupByFamily(myData, tooltipTitle!, left, nodes!), - ); - }} - /> +
+ + isValidConnection(connection, nodes, edges) + } + className={classNames( + left ? "-ml-1" : "-mr-1", + "z-20 h-4 w-4 rounded-full border-none bg-background", + )} + style={{ + background: + "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!), + ); + }} + /> +
+
@@ -486,7 +536,7 @@ export default function ParameterComponent({ // Commenting this out until we have a better // way to display // (data.node?.template[name]?.refresh ? "w-5/6 " : "") + - "flex-grow mt-2" + "mt-2 flex-grow" } > 0 - ? 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 - } + colors={getNodeInputColors( + data.node?.template[templateField].input_types, + data.node?.template[templateField].type, + types, + )} title={getFieldTitle( data.node?.template!, templateField, @@ -739,33 +711,11 @@ export default function GenericNode({ proxy: data.node!.template[templateField].proxy, })} data={data} - color={ - data.node?.template[templateField].input_types && - data.node?.template[templateField].input_types! - .length > 0 - ? 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 - } + colors={getNodeInputColors( + data.node?.template[templateField].input_types, + data.node?.template[templateField].type, + types, + )} title={getFieldTitle( data.node?.template!, templateField, diff --git a/src/frontend/src/CustomNodes/helpers/get-node-input-colors.ts b/src/frontend/src/CustomNodes/helpers/get-node-input-colors.ts new file mode 100644 index 000000000..abff92936 --- /dev/null +++ b/src/frontend/src/CustomNodes/helpers/get-node-input-colors.ts @@ -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]; +} diff --git a/src/frontend/src/CustomNodes/helpers/get-node-output-colors.ts b/src/frontend/src/CustomNodes/helpers/get-node-output-colors.ts new file mode 100644 index 000000000..d846a304e --- /dev/null +++ b/src/frontend/src/CustomNodes/helpers/get-node-output-colors.ts @@ -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]; +} diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index b69346fb9..b197b8591 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -65,7 +65,7 @@ export type ParameterComponentType = { conditionPath?: string | null; key: string; id: sourceHandleType | targetHandleType; - color: string; + colors: string[]; left: boolean; type: string | undefined; required?: boolean;