refactor: improve NodeOutputField and NodeInputField components (#3235)

* remove refhtml and create new component

* refactor: refactor NodeOutputField component in GenericNode

* refactor: refactor NodeOutputField component in GenericNode

* refactor: refactor NodeInputField component in GenericNode

* refactor: remove output shortcut

* [autofix.ci] apply automated fixes

* refactor: remove console.log statements in NodeOutputField component

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
anovazzi1 2024-08-13 16:52:26 -03:00 • committed by GitHub
commit 62b1b88644
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 85 additions and 108 deletions

View file

@ -14,6 +14,7 @@ import {
import { scapedJSONStringfy } from "../../../../utils/reactflowUtils"; import { scapedJSONStringfy } from "../../../../utils/reactflowUtils";
import useFetchDataOnMount from "../../../hooks/use-fetch-data-on-mount"; import useFetchDataOnMount from "../../../hooks/use-fetch-data-on-mount";
import useHandleOnNewValue from "../../../hooks/use-handle-new-value"; import useHandleOnNewValue from "../../../hooks/use-handle-new-value";
import NodeInputInfo from "../NodeInputInfo";
import HandleRenderComponent from "../handleRenderComponent"; import HandleRenderComponent from "../handleRenderComponent";
export default function NodeInputField({ export default function NodeInputField({
@ -31,7 +32,6 @@ export default function NodeInputField({
showNode, showNode,
}: NodeInputFieldComponentType): JSX.Element { }: NodeInputFieldComponentType): JSX.Element {
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
const infoHtml = useRef<HTMLDivElement & ReactNode>(null);
const nodes = useFlowStore((state) => state.nodes); const nodes = useFlowStore((state) => state.nodes);
const edges = useFlowStore((state) => state.edges); const edges = useFlowStore((state) => state.edges);
const myData = useTypesStore((state) => state.data); const myData = useTypesStore((state) => state.data);
@ -57,19 +57,6 @@ export default function NodeInputField({
useFetchDataOnMount(data.node!, handleNodeClass, name, postTemplateValue); useFetchDataOnMount(data.node!, handleNodeClass, name, postTemplateValue);
useEffect(() => {
// @ts-ignore
infoHtml.current = (
<div className="h-full w-full break-words">
{info.split("\n").map((line, index) => (
<p key={index} className="block">
{line}
</p>
))}
</div>
);
}, [info]);
useEffect(() => { useEffect(() => {
if (optionalHandle && optionalHandle.length === 0) { if (optionalHandle && optionalHandle.length === 0) {
optionalHandle = null; optionalHandle = null;
@ -77,24 +64,29 @@ export default function NodeInputField({
}, [optionalHandle]); }, [optionalHandle]);
const displayHandle = const displayHandle =
!LANGFLOW_SUPPORTED_TYPES.has(type ?? "") || optionalHandle; !LANGFLOW_SUPPORTED_TYPES.has(type ?? "") ||
(optionalHandle && optionalHandle.length > 0);
const Handle = (
<HandleRenderComponent
left={true}
nodes={nodes}
tooltipTitle={tooltipTitle}
proxy={proxy}
id={id}
title={title}
edges={edges}
myData={myData}
colors={colors}
setFilterEdge={setFilterEdge}
showNode={showNode}
testIdComplement={`${data?.type?.toLowerCase()}-${showNode ? "shownode" : "noshownode"}`}
/>
);
return !showNode ? ( return !showNode ? (
displayHandle ? ( displayHandle ? (
<HandleRenderComponent Handle
left={true}
nodes={nodes}
tooltipTitle={tooltipTitle}
proxy={proxy}
id={id}
title={title}
edges={edges}
myData={myData}
colors={colors}
setFilterEdge={setFilterEdge}
showNode={showNode}
testIdComplement={`${data?.type?.toLowerCase()}-noshownode`}
/>
) : ( ) : (
<></> <></>
) )
@ -125,7 +117,7 @@ export default function NodeInputField({
</span> </span>
<div className=""> <div className="">
{info !== "" && ( {info !== "" && (
<ShadTooltip content={infoHtml.current}> <ShadTooltip content={<NodeInputInfo info={info} />}>
{/* put div to avoid bug that does not display tooltip */} {/* put div to avoid bug that does not display tooltip */}
<div className="cursor-help"> <div className="cursor-help">
<IconComponent <IconComponent
@ -137,24 +129,8 @@ export default function NodeInputField({
)} )}
</div> </div>
</div> </div>
{(Array.isArray(displayHandle)
? displayHandle.length > 0 {displayHandle && Handle}
: displayHandle) && (
<HandleRenderComponent
left={true}
nodes={nodes}
tooltipTitle={tooltipTitle}
proxy={proxy}
id={id}
title={title}
edges={edges}
myData={myData}
colors={colors}
setFilterEdge={setFilterEdge}
showNode={showNode}
testIdComplement={`${data?.type?.toLowerCase()}-shownode`}
/>
)}
{data.node?.template[name] !== undefined && ( {data.node?.template[name] !== undefined && (
<div className="mt-2 w-full"> <div className="mt-2 w-full">
<ParameterRenderComponent <ParameterRenderComponent

View file

@ -0,0 +1,11 @@
export default function NodeInputInfo({ info }: { info: string }) {
return (
<div className="h-full w-full break-words">
{info.split("\n").map((line, index) => (
<p key={index} className="block">
{line}
</p>
))}
</div>
);
}

View file

@ -85,12 +85,10 @@ export default function NodeOutputField({
function handleOutputWShortcut() { function handleOutputWShortcut() {
if (!displayOutputPreview || unknownOutput) return; if (!displayOutputPreview || unknownOutput) return;
if (isThereModal() && !openOutputModal) return;
if (selected) { if (selected) {
setOpenOutputModal((state) => !state); setOpenOutputModal((state) => !state);
} }
} }
const output = useShortcutsStore((state) => state.output); const output = useShortcutsStore((state) => state.output);
useHotkeys(output, handleOutputWShortcut, { preventDefault }); useHotkeys(output, handleOutputWShortcut, { preventDefault });
@ -123,7 +121,7 @@ export default function NodeOutputField({
} }
}, [disabledOutput]); }, [disabledOutput]);
return !showNode ? ( const Handle = (
<HandleRenderComponent <HandleRenderComponent
left={false} left={false}
nodes={nodes} nodes={nodes}
@ -135,8 +133,12 @@ export default function NodeOutputField({
colors={colors} colors={colors}
setFilterEdge={setFilterEdge} setFilterEdge={setFilterEdge}
showNode={showNode} showNode={showNode}
testIdComplement={`${data?.type?.toLowerCase()}-noshownode`} testIdComplement={`${data?.type?.toLowerCase()}-${showNode ? "shownode" : "noshownode"}`}
/> />
);
return !showNode ? (
Handle
) : ( ) : (
<div <div
ref={ref} ref={ref}
@ -161,12 +163,12 @@ export default function NodeOutputField({
/> />
</Button> </Button>
</div> </div>
<Case condition={data.node?.frozen}>
{data.node?.frozen && (
<div className="pr-1"> <div className="pr-1">
<IconComponent className="h-5 w-5 text-ice" name={"Snowflake"} /> <IconComponent className="h-5 w-5 text-ice" name={"Snowflake"} />
</div> </div>
</Case> )}
<div className="flex gap-2"> <div className="flex gap-2">
<span className={data.node?.frozen ? "text-ice" : ""}> <span className={data.node?.frozen ? "text-ice" : ""}>
<OutputComponent <OutputComponent
@ -192,53 +194,40 @@ export default function NodeOutputField({
: "Please build the component first" : "Please build the component first"
} }
> >
<Button <OutputModal
unstyled
disabled={!displayOutputPreview || unknownOutput} disabled={!displayOutputPreview || unknownOutput}
onClick={() => setOpenOutputModal(true)} nodeId={flowPoolId}
data-testid={`output-inspection-${title.toLowerCase()}`} outputName={internalOutputName}
> >
{errorOutput ? ( <Button
<IconComponent unstyled
className={classNames("h-5 w-5 rounded-md text-status-red")} disabled={!displayOutputPreview || unknownOutput}
name={"X"} data-testid={`output-inspection-${title.toLowerCase()}`}
/> >
) : ( {errorOutput ? (
<IconComponent <IconComponent
className={classNames( className={classNames(
"h-5 w-5 rounded-md", "h-5 w-5 rounded-md text-status-red",
displayOutputPreview && !unknownOutput )}
? "hover:text-medium-indigo" name={"X"}
: "cursor-not-allowed text-muted-foreground", />
)} ) : (
name={"ScanEye"} <IconComponent
/> className={classNames(
)} "h-5 w-5 rounded-md",
</Button> displayOutputPreview && !unknownOutput
? "hover:text-medium-indigo"
: "cursor-not-allowed text-muted-foreground",
)}
name={"ScanEye"}
/>
)}
</Button>
</OutputModal>
</ShadTooltip> </ShadTooltip>
</div> </div>
</div> </div>
<HandleRenderComponent {Handle}
left={false}
nodes={nodes}
tooltipTitle={tooltipTitle}
id={id}
title={title}
edges={edges}
myData={myData}
colors={colors}
setFilterEdge={setFilterEdge}
showNode={showNode}
testIdComplement={`${data?.type?.toLowerCase()}-shownode`}
/>
{openOutputModal && (
<OutputModal
open={openOutputModal}
nodeId={flowPoolId}
setOpen={setOpenOutputModal}
outputName={internalOutputName}
/>
)}
</> </>
</div> </div>
); );

View file

@ -5,14 +5,14 @@ import BaseModal from "../../../../modals/baseModal";
import SwitchOutputView from "./components/switchOutputView"; import SwitchOutputView from "./components/switchOutputView";
export default function OutputModal({ export default function OutputModal({
open,
setOpen,
nodeId, nodeId,
outputName, outputName,
children,
disabled,
}): JSX.Element { }): JSX.Element {
const [activeTab, setActiveTab] = useState<"Outputs" | "Logs">("Outputs"); const [activeTab, setActiveTab] = useState<"Outputs" | "Logs">("Outputs");
return ( return (
<BaseModal open={open} setOpen={setOpen} size="large"> <BaseModal disable={disabled} size="large">
<BaseModal.Header description="Inspect the output of the component below."> <BaseModal.Header description="Inspect the output of the component below.">
<div className="flex items-center"> <div className="flex items-center">
<span className="pr-2">Component Output</span> <span className="pr-2">Component Output</span>
@ -37,13 +37,8 @@ export default function OutputModal({
type={activeTab} type={activeTab}
/> />
</BaseModal.Content> </BaseModal.Content>
<BaseModal.Footer> <BaseModal.Footer close></BaseModal.Footer>
<div className="flex w-full justify-end pt-2"> <BaseModal.Trigger>{children}</BaseModal.Trigger>
<Button className="flex gap-2 px-3" onClick={() => setOpen(false)}>
Close
</Button>
</div>
</BaseModal.Footer>
</BaseModal> </BaseModal>
); );
} }

View file

@ -88,7 +88,8 @@ const Footer: React.FC<{
dataTestId?: string; dataTestId?: string;
onClick?: () => void; onClick?: () => void;
}; };
}> = ({ children, submit }) => { close?: boolean;
}> = ({ children, submit, close }) => {
return ( return (
<div className="flex flex-shrink-0 flex-row-reverse"> <div className="flex flex-shrink-0 flex-row-reverse">
{submit ? ( {submit ? (
@ -115,6 +116,11 @@ const Footer: React.FC<{
) : ( ) : (
<>{children && children}</> <>{children && children}</>
)} )}
{close && (
<DialogClose asChild>
<Button type="button">Close</Button>
</DialogClose>
)}
</div> </div>
); );
}; };