From c13cfd09cfc0a2f81f406dde77ff9d815e86b084 Mon Sep 17 00:00:00 2001 From: Cayal Walker Date: Thu, 6 Apr 2023 13:09:03 -0400 Subject: [PATCH 1/2] Modifies frontend chatComponent to itemize validation errors --- .../src/components/chatComponent/index.tsx | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/src/frontend/src/components/chatComponent/index.tsx b/src/frontend/src/components/chatComponent/index.tsx index 59cc54b4c..a6040c2dd 100644 --- a/src/frontend/src/components/chatComponent/index.tsx +++ b/src/frontend/src/components/chatComponent/index.tsx @@ -18,6 +18,7 @@ import { classNames, nodeColors } from "../../utils"; import { TabsContext } from "../../contexts/tabsContext"; import { ChatType } from "../../types/chat"; import ChatMessage from "./chatMessage"; +import { NodeType } from "../../types/flow"; const _ = require("lodash"); @@ -73,36 +74,44 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) { useEffect(() => { if (ref.current) ref.current.scrollIntoView({ behavior: "smooth" }); }, [chatHistory]); - function validateNodes() { - if ( - reactFlowInstance.getNodes().some( - (n) => - n.data.node && - Object.keys(n.data.node.template).some((t: any) => { - return ( - n.data.node.template[t].required && - (!n.data.node.template[t].value || - n.data.node.template[t].value === "") && - !reactFlowInstance - .getEdges() - .some( - (e) => - e.targetHandle.split("|")[1] === t && - e.targetHandle.split("|")[2] === n.id - ) - ); - }) - ) - ) { - return false; + + function validateNode(n: NodeType): Array { + if (!n.data?.node?.template || + !Object.keys(n.data.node.template)) { + console.warn("There is a broken node in the flow. Please submit a bug report and include your exported flow file."); + return []; } - return true; + + const { type, node: { template } } = n.data; + + return Object.keys(template).reduce((errors: Array, t) => + errors.concat( + template[t].required && + (!template[t].value || + template[t].value === "") && + !reactFlowInstance + .getEdges() + .some( + (e) => + e.targetHandle.split("|")[1] === t && + e.targetHandle.split("|")[2] === n.id + ) + ? [`${type} is missing ${template[t].name}.`] + : [] + ), [] as string[] + ); + }; + + function validateNodes() { + return reactFlowInstance.getNodes().flatMap((n: NodeType) => validateNode(n)) } + const ref = useRef(null); function sendMessage() { if (chatValue !== "") { - if (validateNodes()) { + let nodeValidationErrors = validateNodes(); + if (nodeValidationErrors.length === 0) { setLockChat(true); let message = chatValue; setChatValue(""); @@ -138,7 +147,8 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) { setErrorData({ title: "Error sending message", list: [ - "Oops! Looks like you missed some required information. Please fill in all the required fields before continuing.", + "Oops! Looks like you missed some required information. Please fill in all the required fields before continuing:", + ...nodeValidationErrors ], }); } From c7d5139ecca53815c25fde35ecaf29e3a7523b00 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Thu, 6 Apr 2023 16:24:53 -0300 Subject: [PATCH 2/2] review pull request #126 and changed some error messages --- .../src/components/chatComponent/index.tsx | 67 +++++++++++-------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/src/frontend/src/components/chatComponent/index.tsx b/src/frontend/src/components/chatComponent/index.tsx index a6040c2dd..0d598b300 100644 --- a/src/frontend/src/components/chatComponent/index.tsx +++ b/src/frontend/src/components/chatComponent/index.tsx @@ -14,7 +14,7 @@ import { } from "react"; import { sendAll } from "../../controllers/API"; import { alertContext } from "../../contexts/alertContext"; -import { classNames, nodeColors } from "../../utils"; +import { classNames, nodeColors, snakeToNormalCase } from "../../utils"; import { TabsContext } from "../../contexts/tabsContext"; import { ChatType } from "../../types/chat"; import ChatMessage from "./chatMessage"; @@ -29,7 +29,7 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) { const [open, setOpen] = useState(true); const [chatValue, setChatValue] = useState(""); const [chatHistory, setChatHistory] = useState(flow.chat); - const { setErrorData } = useContext(alertContext); + const { setErrorData, setNoticeData } = useContext(alertContext); const addChatHistory = ( message: string, isSend: boolean, @@ -76,34 +76,48 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) { }, [chatHistory]); function validateNode(n: NodeType): Array { - if (!n.data?.node?.template || - !Object.keys(n.data.node.template)) { - console.warn("There is a broken node in the flow. Please submit a bug report and include your exported flow file."); + if (!n.data?.node?.template || !Object.keys(n.data.node.template)) { + setNoticeData({ + title: + "We've noticed a potential issue with a node in the flow. Please review it and, if necessary, submit a bug report with your exported flow file. Thank you for your help!", + }); return []; } - const { type, node: { template } } = n.data; + const { + type, + node: { template }, + } = n.data; - return Object.keys(template).reduce((errors: Array, t) => - errors.concat( - template[t].required && - (!template[t].value || - template[t].value === "") && - !reactFlowInstance - .getEdges() - .some( - (e) => - e.targetHandle.split("|")[1] === t && - e.targetHandle.split("|")[2] === n.id - ) - ? [`${type} is missing ${template[t].name}.`] - : [] - ), [] as string[] + return Object.keys(template).reduce( + (errors: Array, t) => + errors.concat( + template[t].required && + (!template[t].value || template[t].value === "") && + !reactFlowInstance + .getEdges() + .some( + (e) => + e.targetHandle.split("|")[1] === t && + e.targetHandle.split("|")[2] === n.id + ) + ? [ + `${type} is missing ${ + template.display_name + ? template.display_name + : snakeToNormalCase(template[t].name) + }.`, + ] + : [] + ), + [] as string[] ); - }; + } function validateNodes() { - return reactFlowInstance.getNodes().flatMap((n: NodeType) => validateNode(n)) + return reactFlowInstance + .getNodes() + .flatMap((n: NodeType) => validateNode(n)); } const ref = useRef(null); @@ -145,11 +159,8 @@ export default function Chat({ flow, reactFlowInstance }: ChatType) { }); } else { setErrorData({ - title: "Error sending message", - list: [ - "Oops! Looks like you missed some required information. Please fill in all the required fields before continuing:", - ...nodeValidationErrors - ], + title: "Oops! Looks like you missed some required information:", + list: nodeValidationErrors, }); } } else {