diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 9715b7a7d..dce5af259 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -102,7 +102,7 @@ export default function ParameterComponent({ }, [info]); function renderTooltips() { - let groupedObj = groupByFamily(myData, tooltipTitle, left); + let groupedObj = groupByFamily(myData, tooltipTitle, left, flow); if (groupedObj) { refNumberComponents.current = groupedObj[0]?.type?.length; @@ -133,7 +133,7 @@ export default function ParameterComponent({ /> - {nodeNames[item.family]} + {nodeNames[item.family] ?? "Unknown"} {" "} {item.type === "" ? "" : " - "} diff --git a/src/frontend/src/components/ui/tooltip.tsx b/src/frontend/src/components/ui/tooltip.tsx index 3d31ab66d..8ea9a9505 100644 --- a/src/frontend/src/components/ui/tooltip.tsx +++ b/src/frontend/src/components/ui/tooltip.tsx @@ -19,7 +19,7 @@ const TooltipContent = React.forwardRef< ref={ref} sideOffset={sideOffset} className={cn( - "overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1", + "overflow-y-auto rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1", className )} {...props} diff --git a/src/frontend/src/utils/utils.ts b/src/frontend/src/utils/utils.ts index 326a72798..df8eb6e32 100644 --- a/src/frontend/src/utils/utils.ts +++ b/src/frontend/src/utils/utils.ts @@ -2,10 +2,9 @@ import clsx, { ClassValue } from "clsx"; import { twMerge } from "tailwind-merge"; import { ADJECTIVES, DESCRIPTIONS, NOUNS } from "../flow_constants"; import { IVarHighlightType } from "../types/components"; -import { FlowType } from "../types/flow"; +import { FlowType, NodeType } from "../types/flow"; import { TabsState } from "../types/tabs"; import { buildTweaks } from "./reactflowUtils"; -import { nodeNames } from "./styleUtils"; export function classNames(...classes: Array) { return classes.filter(Boolean).join(" "); @@ -89,32 +88,75 @@ export function checkUpperWords(str: string) { export const isWrappedWithClass = (event: any, className: string | undefined) => event.target.closest(`.${className}`); -export function groupByFamily(data, baseClasses, left) { - const baseClassesSet = new Set(baseClasses.split("\n")); - let arrOfPossibleInputs = []; - let arrOfPossibleOutputs = []; - - for (const [d, nodes] of Object.entries(data)) { - let tempInputs = [], tempOutputs = []; - - for (const [n, node] of Object.entries(nodes)) { - const hasBaseClassInTemplate = Object.values(node.template).some((t: any) => t.type && baseClassesSet.has(t.type)); - const hasBaseClassInBaseClasses = node.base_classes.some(t => baseClassesSet.has(t)); - - if(hasBaseClassInTemplate) tempInputs.push(n); - if(hasBaseClassInBaseClasses) tempOutputs.push(n); - } - - const totalNodes = Object.keys(nodes).length; - if(tempInputs.length) arrOfPossibleInputs.push({category: d, nodes: tempInputs, full: tempInputs.length === totalNodes}); - if(tempOutputs.length) arrOfPossibleOutputs.push({category: d, nodes: tempOutputs, full: tempOutputs.length === totalNodes}); - } - - return left - ? arrOfPossibleOutputs.map(t => ({family: t.category, type: t.full ? "" : t.nodes.join(", ")})) - : arrOfPossibleInputs.map(t => ({family: t.category, type: t.full ? "" : t.nodes.join(", ")})); +export function groupByFamily(data, baseClasses, left, flow: NodeType[]) { + const baseClassesSet = new Set(baseClasses.split("\n")); + let arrOfPossibleInputs = []; + let arrOfPossibleOutputs = []; + let checkedNodes = new Map(); + + for (const node of flow) { + const hasBaseClassInTemplate = Object.values(node.data.node.template).some( + (t: any) => t.type && baseClassesSet.has(t.type) + ); + const hasBaseClassInBaseClasses = node.data.node.base_classes.some((t) => + baseClassesSet.has(t) + ); + checkedNodes.set(node.data.type, { + hasBaseClassInTemplate, + hasBaseClassInBaseClasses, + }); } + for (const [d, nodes] of Object.entries(data)) { + let tempInputs = [], + tempOutputs = []; + + for (const [n, node] of Object.entries(nodes)) { + let hasBaseClassInTemplate, hasBaseClassInBaseClasses; + const foundNode = checkedNodes.get(n); + + if (foundNode) { + hasBaseClassInBaseClasses = foundNode.hasBaseClassInBaseClasses; + hasBaseClassInTemplate = foundNode.hasBaseClassInTemplate; + } else { + hasBaseClassInTemplate = Object.values(node.template).some( + (t: any) => t.type && baseClassesSet.has(t.type) + ); + hasBaseClassInBaseClasses = node.base_classes.some((t) => + baseClassesSet.has(t) + ); + } + + if (hasBaseClassInTemplate) tempInputs.push(n); + if (hasBaseClassInBaseClasses) tempOutputs.push(n); + } + + const totalNodes = Object.keys(nodes).length; + if (tempInputs.length) + arrOfPossibleInputs.push({ + category: d, + nodes: tempInputs, + full: tempInputs.length === totalNodes, + }); + if (tempOutputs.length) + arrOfPossibleOutputs.push({ + category: d, + nodes: tempOutputs, + full: tempOutputs.length === totalNodes, + }); + } + + return left + ? arrOfPossibleOutputs.map((t) => ({ + family: t.category, + type: t.full ? "" : t.nodes.join(", "), + })) + : arrOfPossibleInputs.map((t) => ({ + family: t.category, + type: t.full ? "" : t.nodes.join(", "), + })); +} + export function buildInputs(tabsState, id) { return tabsState && tabsState[id] &&