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;