Get data from Validate Nodes and display it on Tooltip
This commit is contained in:
parent
8810a0392a
commit
b8c95fb7ec
6 changed files with 39 additions and 23 deletions
|
|
@ -10,6 +10,7 @@ from langflow.api.base import (
|
|||
from langflow.interface.run import build_graph
|
||||
from langflow.utils.logger import logger
|
||||
from langflow.utils.validate import validate_code
|
||||
import json
|
||||
|
||||
# build router
|
||||
router = APIRouter(prefix="/validate", tags=["validate"])
|
||||
|
|
@ -46,8 +47,8 @@ def post_validate_node(node_id: str, data: dict):
|
|||
node = graph.get_node(node_id)
|
||||
if node is not None:
|
||||
_ = node.build()
|
||||
return str(node.params)
|
||||
raise Exception(f"Node {node_id} not found")
|
||||
return json.dumps({'valid': True, 'params': str(node.params)})
|
||||
else:
|
||||
return json.dumps({'valid': False})
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Cog6ToothIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||
import { BugAntIcon, Cog6ToothIcon, ExclamationCircleIcon, InformationCircleIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||
import {
|
||||
classNames,
|
||||
nodeColors,
|
||||
|
|
@ -7,7 +7,7 @@ import {
|
|||
} from "../../utils";
|
||||
import ParameterComponent from "./components/parameterComponent";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import { useContext, useState, useEffect, useRef } from "react";
|
||||
import { useContext, useState, useEffect, useRef, Fragment } from "react";
|
||||
import { NodeDataType } from "../../types/flow";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
|
|
@ -15,6 +15,7 @@ import NodeModal from "../../modals/NodeModal";
|
|||
import { useCallback } from "react";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { debounce } from "../../utils";
|
||||
import Tooltip from "../../components/TooltipComponent";
|
||||
export default function GenericNode({
|
||||
data,
|
||||
selected,
|
||||
|
|
@ -27,7 +28,7 @@ export default function GenericNode({
|
|||
const { types, deleteNode } = useContext(typesContext);
|
||||
const { openPopUp } = useContext(PopUpContext);
|
||||
const Icon = nodeIcons[types[data.type]];
|
||||
const [validationStatus, setValidationStatus] = useState("idle");
|
||||
const [validationStatus, setValidationStatus] = useState(null);
|
||||
// State for outline color
|
||||
const [isValid, setIsValid] = useState(false);
|
||||
const { save } = useContext(TabsContext);
|
||||
|
|
@ -53,9 +54,14 @@ export default function GenericNode({
|
|||
});
|
||||
|
||||
if (response.status === 200) {
|
||||
setValidationStatus("success");
|
||||
} else if (response.status === 500) {
|
||||
setValidationStatus("error");
|
||||
let jsonResponse = await response.json();
|
||||
let jsonResponseParsed = await JSON.parse(jsonResponse);
|
||||
console.log(jsonResponseParsed);
|
||||
if(jsonResponseParsed.valid){
|
||||
setValidationStatus(jsonResponseParsed.params);
|
||||
} else {
|
||||
setValidationStatus("error");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// console.error("Error validating node:", error);
|
||||
|
|
@ -71,7 +77,7 @@ export default function GenericNode({
|
|||
}, [params, validateNode]);
|
||||
|
||||
useEffect(() => {
|
||||
if (validationStatus === "success") {
|
||||
if (validationStatus !== "error") {
|
||||
setIsValid(true);
|
||||
} else {
|
||||
setIsValid(false);
|
||||
|
|
@ -100,14 +106,23 @@ export default function GenericNode({
|
|||
)}
|
||||
>
|
||||
<div className="w-full dark:text-white flex items-center justify-between p-4 gap-8 bg-gray-50 rounded-t-lg dark:bg-gray-800 border-b dark:border-b-gray-700 ">
|
||||
<div className="w-full flex items-center truncate gap-4 text-lg">
|
||||
<div className="w-full flex items-center truncate gap-2 text-lg">
|
||||
<Icon
|
||||
className="w-10 h-10 p-1 rounded"
|
||||
style={{
|
||||
color: nodeColors[types[data.type]] ?? nodeColors.unknown,
|
||||
}}
|
||||
/>
|
||||
<div className="truncate">{data.type}</div>
|
||||
<div className="ml-2 truncate">{data.type}</div>
|
||||
{validationStatus && validationStatus !== "error" ?
|
||||
<Tooltip title={
|
||||
<div className="max-h-96 overflow-auto">
|
||||
{validationStatus}
|
||||
</div>}>
|
||||
<ExclamationCircleIcon className="w-5 hover:text-gray-500 hover:dark:text-gray-300" />
|
||||
</Tooltip>
|
||||
: <></>
|
||||
}
|
||||
</div>
|
||||
<div className="flex gap-3">
|
||||
<button
|
||||
|
|
@ -134,7 +149,7 @@ export default function GenericNode({
|
|||
)
|
||||
? ""
|
||||
: "hidden",
|
||||
"w-6 h-6 dark:text-gray-500 hover:animate-spin"
|
||||
"w-6 h-6 dark:text-gray-300 hover:animate-spin"
|
||||
)}
|
||||
></Cog6ToothIcon>
|
||||
</button>
|
||||
|
|
@ -143,13 +158,13 @@ export default function GenericNode({
|
|||
deleteNode(data.id);
|
||||
}}
|
||||
>
|
||||
<TrashIcon className="w-6 h-6 hover:text-red-500 dark:text-gray-500 dark:hover:text-red-500"></TrashIcon>
|
||||
<TrashIcon className="w-6 h-6 hover:text-red-500 dark:text-gray-300 dark:hover:text-red-500"></TrashIcon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full h-full py-5">
|
||||
<div className="w-full text-gray-500 px-5 pb-3 text-sm">
|
||||
<div className="w-full text-gray-500 dark:text-gray-300 px-5 pb-3 text-sm">
|
||||
{data.node.description}
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export default function InputComponent({
|
|||
}}
|
||||
/>
|
||||
<button
|
||||
className="absolute inset-y-0 right-0 items-center px-4 text-gray-600"
|
||||
className="absolute inset-y-0 right-0 items-center px-4 text-gray-600 dark:text-gray-300"
|
||||
onClick={() => {
|
||||
setPwdVisible(!pwdVisible);
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export default function TextAreaComponent({ value, onChange, disabled }:TextArea
|
|||
<div className="w-full flex items-center gap-3">
|
||||
<span onClick={()=>{openPopUp(<TextAreaModal value={myValue} setValue={(t:string) => {setMyValue(t); onChange(t);}}/>)}}
|
||||
className={
|
||||
"truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" +
|
||||
"truncate block w-full text-gray-500 dark:text-gray-100 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" +
|
||||
(disabled ? " bg-gray-200" : "")
|
||||
}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -57,18 +57,18 @@ export default function TabsManagerComponent() {
|
|||
<div className="ml-auto mr-2 flex gap-3">
|
||||
<button
|
||||
onClick={() => openPopUp(<ImportModal />)}
|
||||
className="flex items-center gap-1 pr-2 border-gray-400 border-r text-sm text-gray-600 hover:text-gray-500"
|
||||
className="flex items-center gap-1 pr-2 border-gray-400 border-r text-sm text-gray-600 hover:text-gray-500 dark:text-gray-300 dark:hover:text-gray-200"
|
||||
>
|
||||
Import <ArrowUpTrayIcon className="w-5 h-5" />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => openPopUp(<ExportModal />)}
|
||||
className="flex items-center gap-1 mr-2 text-sm text-gray-600 hover:text-gray-500"
|
||||
className="flex items-center gap-1 mr-2 text-sm text-gray-600 hover:text-gray-500 dark:text-gray-300 dark:hover:text-gray-200"
|
||||
>
|
||||
Export <ArrowDownTrayIcon className="h-5 w-5" />
|
||||
</button>
|
||||
<button
|
||||
className="text-gray-600 hover:text-gray-500 "
|
||||
className="text-gray-600 hover:text-gray-500 dark:text-gray-300 dark:hover:text-gray-200"
|
||||
onClick={() => {
|
||||
setDark(!dark);
|
||||
}}
|
||||
|
|
@ -80,7 +80,7 @@ export default function TabsManagerComponent() {
|
|||
)}
|
||||
</button>
|
||||
<button
|
||||
className="text-gray-600 hover:text-gray-500 relative"
|
||||
className="text-gray-600 hover:text-gray-500 dark:text-gray-300 dark:hover:text-gray-200 relative"
|
||||
onClick={(event: React.MouseEvent<HTMLElement>) => {
|
||||
setNotificationCenter(false);
|
||||
const top = (event.target as Element).getBoundingClientRect().top;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ForwardRefExoticComponent, ReactElement, ReactNode } from "react";
|
||||
import { ForwardRefExoticComponent, ReactElement, ReactFragment, ReactNode } from "react";
|
||||
import { NodeDataType } from "../flow/index";
|
||||
export type InputComponentType = {
|
||||
value: string;
|
||||
|
|
@ -68,7 +68,7 @@ export type FloatComponentType = {
|
|||
|
||||
export type TooltipComponentType = {
|
||||
children: ReactElement;
|
||||
title: string;
|
||||
title: string | ReactElement;
|
||||
placement?:
|
||||
| "bottom-end"
|
||||
| "bottom-start"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue