fix(validate.py): raise an exception with a message when node is not found

feat(GenericNode): add node validation with outline color feedback
feat(tailwind.config.js): add styles for outline colors and animations
This commit is contained in:
Gabriel Almeida 2023-04-24 13:43:52 -03:00
commit f122151b12
3 changed files with 100 additions and 33 deletions

View file

@ -47,7 +47,7 @@ def post_validate_node(node_id: str, data: dict):
if node is not None: if node is not None:
_ = node.build() _ = node.build()
return node.params return node.params
raise raise Exception(f"Node {node_id} not found")
except Exception as e: except Exception as e:
logger.exception(e) logger.exception(e)
raise HTTPException(status_code=500, detail=str(e)) from e raise HTTPException(status_code=500, detail=str(e)) from e

View file

@ -7,9 +7,10 @@ import {
} from "../../utils"; } from "../../utils";
import ParameterComponent from "./components/parameterComponent"; import ParameterComponent from "./components/parameterComponent";
import { typesContext } from "../../contexts/typesContext"; import { typesContext } from "../../contexts/typesContext";
import { useContext, useRef } from "react"; import { useContext, useState, useEffect, useRef } from "react";
import { NodeDataType } from "../../types/flow"; import { NodeDataType } from "../../types/flow";
import { alertContext } from "../../contexts/alertContext"; import { alertContext } from "../../contexts/alertContext";
import { useCallback } from 'react';
export default function GenericNode({ export default function GenericNode({
data, data,
@ -22,6 +23,53 @@ export default function GenericNode({
const showError = useRef(true); const showError = useRef(true);
const { types, deleteNode } = useContext(typesContext); const { types, deleteNode } = useContext(typesContext);
const Icon = nodeIcons[types[data.type]]; const Icon = nodeIcons[types[data.type]];
// State for outline color
const [isGreenOutline, setIsGreenOutline] = useState(false);
const [isRedOutline, setIsRedOutline] = useState(false);
const { reactFlowInstance } = useContext(typesContext);
const validateNode = useCallback(async () => {
try {
const response = await fetch(`/validate/node/${data.id}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(reactFlowInstance.toObject()),
});
if (response.status === 200) {
setIsGreenOutline(true);
setIsRedOutline(false);
} else if (response.status === 500) {
setIsRedOutline(true);
setIsGreenOutline(false);
}
} catch (error) {
console.error('Error validating node:', error);
setIsRedOutline(true);
}
}, [data.id, reactFlowInstance]);
useEffect(() => {
validateNode();
}, [
validateNode,
...Object.values(data.node.template).flatMap((t) => Object.values(t)),
]);
useEffect(() => {
if (isGreenOutline) {
setTimeout(() => {
setIsGreenOutline(false);
}, 1000);
}
}, [isGreenOutline]);
const outlineColor = isGreenOutline ? 'animate-pulse-green' : isRedOutline ? 'border-red-outline' : '';
if (!Icon) { if (!Icon) {
if (showError.current) { if (showError.current) {
setErrorData({ setErrorData({
@ -34,9 +82,11 @@ export default function GenericNode({
deleteNode(data.id); deleteNode(data.id);
return; return;
} }
return ( return (
<div <div
className={classNames( className={classNames(
outlineColor,
selected ? "border border-blue-500" : "border dark:border-gray-700", selected ? "border border-blue-500" : "border dark:border-gray-700",
"prompt-node relative bg-white dark:bg-gray-900 w-96 rounded-lg flex flex-col justify-center" "prompt-node relative bg-white dark:bg-gray-900 w-96 rounded-lg flex flex-col justify-center"
)} )}
@ -98,8 +148,8 @@ export default function GenericNode({
data.node.template[t].display_name data.node.template[t].display_name
? data.node.template[t].display_name ? data.node.template[t].display_name
: data.node.template[t].name : data.node.template[t].name
? snakeToNormalCase(data.node.template[t].name) ? snakeToNormalCase(data.node.template[t].name)
: snakeToNormalCase(t) : snakeToNormalCase(t)
} }
name={t} name={t}
tooltipTitle={ tooltipTitle={

View file

@ -1,45 +1,62 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
const plugin = require('tailwindcss/plugin') const plugin = require("tailwindcss/plugin");
module.exports = { module.exports = {
content: ["./src/**/*.{js,ts,tsx,jsx}"], content: ["./src/**/*.{js,ts,tsx,jsx}"],
darkMode: 'class', darkMode: "class",
important:true, important: true,
theme: { theme: {
extend: {}, extend: {
borderColor: {
"red-outline": "rgba(255, 0, 0, 0.8)",
"green-outline": "rgba(72, 187, 120, 0.7)",
},
boxShadow: {
"red-outline": "0 0 5px rgba(255, 0, 0, 0.5)",
"green-outline": "0 0 5px rgba(72, 187, 120, 0.7)",
},
animation: {
"pulse-green": "pulseGreen 1s linear",
},
keyframes: {
pulseGreen: {
"0%": { boxShadow: "0 0 0 0 rgba(72, 187, 120, 0.7)" },
"100%": { boxShadow: "0 0 0 10px rgba(72, 187, 120, 0)" },
},
},
},
}, },
plugins: [ plugins: [
require("@tailwindcss/forms")({ require("@tailwindcss/forms")({
strategy: 'class', // only generate classes strategy: "class", // only generate classes
}), }),
plugin(function ({ addUtilities }) { plugin(function ({ addUtilities }) {
addUtilities({ addUtilities({
'.scrollbar-hide': { ".scrollbar-hide": {
/* IE and Edge */ /* IE and Edge */
'-ms-overflow-style': 'none', "-ms-overflow-style": "none",
/* Firefox */ /* Firefox */
'scrollbar-width': 'none', "scrollbar-width": "none",
/* Safari and Chrome */ /* Safari and Chrome */
'&::-webkit-scrollbar': { "&::-webkit-scrollbar": {
display: 'none' display: "none",
}
},
'.arrow-hide':{
'&::-webkit-inner-spin-button':{
'-webkit-appearance': 'none',
'margin': 0
},
'&::-webkit-outer-spin-button':{
'-webkit-appearance': 'none',
'margin': 0
}, },
}, },
'.password':{ ".arrow-hide": {
"-webkit-text-security":"disc", "&::-webkit-inner-spin-button": {
"font-family": "text-security-disc" "-webkit-appearance": "none",
margin: 0,
} },
} "&::-webkit-outer-spin-button": {
) "-webkit-appearance": "none",
}) margin: 0,
},
},
".password": {
"-webkit-text-security": "disc",
"font-family": "text-security-disc",
},
});
}),
], ],
} };