refactor handle tooltip to it's own component

This commit is contained in:
anovazzi1 2024-05-27 11:44:47 -03:00
commit 70a43c3947
9 changed files with 81 additions and 50 deletions

View file

@ -0,0 +1,31 @@
import { useRef } from "react";
import { TOOLTIP_EMPTY } from "../../../../constants/constants";
import { groupByFamily } from "../../../../utils/utils";
import TooltipRenderComponent from "../tooltipRenderComponent";
import { useTypesStore } from "../../../../stores/typesStore";
import { NodeType } from "../../../../types/flow";
import useFlowStore from "../../../../stores/flowStore";
export default function HandleTooltips({
left,
tooltipTitle,
}: {
left: boolean;
nodes: NodeType[];
tooltipTitle: string;
}) {
const myData = useTypesStore((state) => state.data);
const nodes = useFlowStore((state) => state.nodes);
let groupedObj: any = groupByFamily(myData, tooltipTitle!, left, nodes!);
if (groupedObj && groupedObj.length > 0) {
//@ts-ignore
return groupedObj.map((item, index) => {
return <TooltipRenderComponent index={index} item={item} left={left} />;
});
} else {
//@ts-ignore
return <span data-testid={`empty-tooltip-filter`}>{TOOLTIP_EMPTY}</span>;
}
}

View file

@ -0,0 +1,17 @@
import { NodeDataType } from "../../../../types/flow";
import ComponentOutput from "../ComponentOutput";
export default function ComponentOutputs({ data }: { data: NodeDataType }) {
return (
<div>
{data.node?.outputs?.map((output) => (
<ComponentOutput
nodeId={data.id}
frozen={data.node?.frozen}
types={output.types}
selected={output.selected ?? output.types[0]}
/>
))}
</div>
);
}

View file

@ -54,6 +54,7 @@ import useHandleOnNewValue from "../../../hooks/use-handle-new-value";
import useHandleNodeClass from "../../../hooks/use-handle-node-class"; import useHandleNodeClass from "../../../hooks/use-handle-node-class";
import useHandleRefreshButtonPress from "../../../hooks/use-handle-refresh-buttons"; import useHandleRefreshButtonPress from "../../../hooks/use-handle-refresh-buttons";
import TooltipRenderComponent from "../tooltipRenderComponent"; import TooltipRenderComponent from "../tooltipRenderComponent";
import HandleTooltips from "../HandleTooltipComponent";
export default function ParameterComponent({ export default function ParameterComponent({
left, left,
@ -72,7 +73,6 @@ export default function ParameterComponent({
index = "", index = "",
}: ParameterComponentType): JSX.Element { }: ParameterComponentType): JSX.Element {
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
const refHtml = useRef<HTMLDivElement & ReactNode>(null);
const infoHtml = useRef<HTMLDivElement & ReactNode>(null); const infoHtml = useRef<HTMLDivElement & ReactNode>(null);
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
const currentFlow = useFlowsManagerStore((state) => state.currentFlow); const currentFlow = useFlowsManagerStore((state) => state.currentFlow);
@ -84,8 +84,6 @@ export default function ParameterComponent({
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const updateNodeInternals = useUpdateNodeInternals(); const updateNodeInternals = useUpdateNodeInternals();
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false); const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
const flow = currentFlow?.data?.nodes ?? null;
const groupedEdge = useRef(null);
const setFilterEdge = useFlowStore((state) => state.setFilterEdge); const setFilterEdge = useFlowStore((state) => state.setFilterEdge);
const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue( const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue(
@ -95,7 +93,6 @@ export default function ParameterComponent({
handleUpdateValues, handleUpdateValues,
debouncedHandleUpdateValues, debouncedHandleUpdateValues,
setNode, setNode,
renderTooltips,
isLoading, isLoading,
setIsLoading, setIsLoading,
); );
@ -106,11 +103,10 @@ export default function ParameterComponent({
takeSnapshot, takeSnapshot,
setNode, setNode,
updateNodeInternals, updateNodeInternals,
renderTooltips,
); );
const { handleRefreshButtonPress: handleRefreshButtonPressHook } = const { handleRefreshButtonPress: handleRefreshButtonPressHook } =
useHandleRefreshButtonPress(setIsLoading, setNode, renderTooltips); useHandleRefreshButtonPress(setIsLoading, setNode);
let disabled = let disabled =
edges.some( edges.some(
@ -122,14 +118,7 @@ export default function ParameterComponent({
handleRefreshButtonPressHook(name, data); handleRefreshButtonPressHook(name, data);
}; };
useFetchDataOnMount( useFetchDataOnMount(data, name, handleUpdateValues, setNode, setIsLoading);
data,
name,
handleUpdateValues,
setNode,
renderTooltips,
setIsLoading,
);
const handleOnNewValue = async ( const handleOnNewValue = async (
newValue: string | string[] | boolean | Object[], newValue: string | string[] | boolean | Object[],
@ -193,32 +182,11 @@ export default function ParameterComponent({
); );
} }
function renderTooltips() {
let groupedObj: any = groupByFamily(myData, tooltipTitle!, left, flow!);
groupedEdge.current = groupedObj;
if (groupedObj && groupedObj.length > 0) {
//@ts-ignore
refHtml.current = groupedObj.map((item, index) => {
return <TooltipRenderComponent index={index} item={item} left={left} />;
});
} else {
//@ts-ignore
refHtml.current = (
<span data-testid={`empty-tooltip-filter`}>{TOOLTIP_EMPTY}</span>
);
}
}
// If optionalHandle is an empty list, then it is not an optional handle // If optionalHandle is an empty list, then it is not an optional handle
if (optionalHandle && optionalHandle.length === 0) { if (optionalHandle && optionalHandle.length === 0) {
optionalHandle = null; optionalHandle = null;
} }
useEffect(() => {
renderTooltips();
}, [tooltipTitle, flow]);
return !showNode ? ( return !showNode ? (
left && LANGFLOW_SUPPORTED_TYPES.has(type ?? "") && !optionalHandle ? ( left && LANGFLOW_SUPPORTED_TYPES.has(type ?? "") && !optionalHandle ? (
<></> <></>
@ -228,7 +196,13 @@ export default function ParameterComponent({
<ShadTooltip <ShadTooltip
styleClasses={"tooltip-fixed-width custom-scroll nowheel"} styleClasses={"tooltip-fixed-width custom-scroll nowheel"}
delayDuration={1000} delayDuration={1000}
content={refHtml.current} content={
<HandleTooltips
left={left}
nodes={nodes}
tooltipTitle={tooltipTitle!}
/>
}
side={left ? "left" : "right"} side={left ? "left" : "right"}
> >
<Handle <Handle
@ -259,7 +233,9 @@ export default function ParameterComponent({
borderColor: color ?? nodeColors.unknown, borderColor: color ?? nodeColors.unknown,
}} }}
onClick={() => { onClick={() => {
setFilterEdge(groupedEdge.current); setFilterEdge(
groupByFamily(myData, tooltipTitle!, left, nodes!),
);
}} }}
></Handle> ></Handle>
</ShadTooltip> </ShadTooltip>
@ -322,7 +298,13 @@ export default function ParameterComponent({
<ShadTooltip <ShadTooltip
styleClasses={"tooltip-fixed-width custom-scroll nowheel"} styleClasses={"tooltip-fixed-width custom-scroll nowheel"}
delayDuration={1000} delayDuration={1000}
content={refHtml.current} content={
<HandleTooltips
left={left}
nodes={nodes}
tooltipTitle={tooltipTitle!}
/>
}
side={left ? "left" : "right"} side={left ? "left" : "right"}
> >
<Handle <Handle
@ -341,7 +323,11 @@ export default function ParameterComponent({
"h-3 w-3 rounded-full border-2 bg-background", "h-3 w-3 rounded-full border-2 bg-background",
)} )}
style={{ borderColor: color ?? nodeColors.unknown }} style={{ borderColor: color ?? nodeColors.unknown }}
onClick={() => setFilterEdge(groupedEdge.current)} onClick={() => {
setFilterEdge(
groupByFamily(myData, tooltipTitle!, left, nodes!),
);
}}
/> />
</ShadTooltip> </ShadTooltip>
</div> </div>

View file

@ -31,6 +31,7 @@ import { classNames, cn } from "../../utils/utils";
import ParameterComponent from "./components/parameterComponent"; import ParameterComponent from "./components/parameterComponent";
import getFieldTitle from "../utils/get-field-title"; import getFieldTitle from "../utils/get-field-title";
import sortFields from "../utils/sort-fields"; import sortFields from "../utils/sort-fields";
import ComponentOutputs from "./components/componentOutputs";
export default function GenericNode({ export default function GenericNode({
data, data,
@ -824,6 +825,9 @@ export default function GenericNode({
> >
{" "} {" "}
</div> </div>
{data.node!.outputs && data.node!.outputs.length > 0 && (
<ComponentOutputs data={data} />
)}
{data.node!.base_classes.length > 0 && ( {data.node!.base_classes.length > 0 && (
<ParameterComponent <ParameterComponent
key={scapedJSONStringfy({ key={scapedJSONStringfy({

View file

@ -8,7 +8,6 @@ const useFetchDataOnMount = (
name, name,
handleUpdateValues, handleUpdateValues,
setNode, setNode,
renderTooltips,
setIsLoading, setIsLoading,
) => { ) => {
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
@ -44,7 +43,6 @@ const useFetchDataOnMount = (
}); });
} }
setIsLoading(false); setIsLoading(false);
renderTooltips();
} }
} }
fetchData(); fetchData();

View file

@ -9,7 +9,6 @@ const useHandleOnNewValue = (
handleUpdateValues, handleUpdateValues,
debouncedHandleUpdateValues, debouncedHandleUpdateValues,
setNode, setNode,
renderTooltips,
isLoading, isLoading,
setIsLoading, setIsLoading,
) => { ) => {
@ -65,8 +64,6 @@ const useHandleOnNewValue = (
return newNode; return newNode;
}); });
renderTooltips();
}; };
return { handleOnNewValue }; return { handleOnNewValue };

View file

@ -6,7 +6,6 @@ const useHandleNodeClass = (
takeSnapshot, takeSnapshot,
setNode, setNode,
updateNodeInternals, updateNodeInternals,
renderTooltips,
) => { ) => {
const handleNodeClass = (newNodeClass, code) => { const handleNodeClass = (newNodeClass, code) => {
if (!data.node) return; if (!data.node) return;
@ -30,8 +29,6 @@ const useHandleNodeClass = (
}); });
updateNodeInternals(data.id); updateNodeInternals(data.id);
renderTooltips();
}; };
return { handleNodeClass }; return { handleNodeClass };

View file

@ -3,7 +3,7 @@ import useAlertStore from "../../stores/alertStore";
import { ResponseErrorDetailAPI } from "../../types/api"; import { ResponseErrorDetailAPI } from "../../types/api";
import { handleUpdateValues } from "../../utils/parameterUtils"; import { handleUpdateValues } from "../../utils/parameterUtils";
const useHandleRefreshButtonPress = (setIsLoading, setNode, renderTooltips) => { const useHandleRefreshButtonPress = (setIsLoading, setNode) => {
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
const handleRefreshButtonPress = async (name, data) => { const handleRefreshButtonPress = async (name, data) => {
@ -30,7 +30,6 @@ const useHandleRefreshButtonPress = (setIsLoading, setNode, renderTooltips) => {
}); });
} }
setIsLoading(false); setIsLoading(false);
renderTooltips();
}; };
return { handleRefreshButtonPress }; return { handleRefreshButtonPress };

View file

@ -27,6 +27,7 @@ export type APIClassType = {
documentation: string; documentation: string;
error?: string; error?: string;
official?: boolean; official?: boolean;
outputs?: Array<{ types: Array<string>; selected?: string }>;
frozen?: boolean; frozen?: boolean;
flow?: FlowType; flow?: FlowType;
field_order?: string[]; field_order?: string[];
@ -38,7 +39,8 @@ export type APIClassType = {
| FlowType | FlowType
| CustomFieldsType | CustomFieldsType
| boolean | boolean
| undefined; | undefined
| Array<{ types: Array<string>; selected?: string }>;
}; };
export type TemplateVariableType = { export type TemplateVariableType = {