From 31c80204ebddd2b03864185c78587dca00395eee Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Mon, 8 Jan 2024 14:00:33 -0300 Subject: [PATCH 1/8] Fix copy paste not being able to paste on other flow --- .../pages/FlowPage/components/PageComponent/index.tsx | 10 +++++----- src/frontend/src/stores/flowStore.ts | 4 ++++ src/frontend/src/types/zustand/flow/index.ts | 5 +++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index d4b2b8e3b..1d2264947 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -43,6 +43,7 @@ import { cn, getRandomName, isWrappedWithClass } from "../../../../utils/utils"; import ConnectionLineComponent from "../ConnectionLineComponent"; import SelectionMenu from "../SelectionMenuComponent"; import ExtraSidebar from "../extraSidebarComponent"; +import { stat } from "fs"; const nodeTypes = { genericNode: GenericNode, @@ -64,11 +65,6 @@ export default function Page({ const setFilterEdge = useTypesStore((state) => state.setFilterEdge); const reactFlowWrapper = useRef(null); - const [lastCopiedSelection, setLastCopiedSelection] = useState<{ - nodes: any; - edges: any; - } | null>(null); - const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance); const setReactFlowInstance = useFlowStore( (state) => state.setReactFlowInstance @@ -86,6 +82,10 @@ export default function Page({ const redo = useFlowsManagerStore((state) => state.redo); const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); const paste = useFlowStore((state) => state.paste); + const lastCopiedSelection = useFlowStore((state) => state.lastCopiedSelection); + const setLastCopiedSelection = useFlowStore( + (state) => state.setLastCopiedSelection + ); const position = useRef({ x: 0, y: 0 }); const [lastSelection, setLastSelection] = diff --git a/src/frontend/src/stores/flowStore.ts b/src/frontend/src/stores/flowStore.ts index 273ee2533..dcdd4e82e 100644 --- a/src/frontend/src/stores/flowStore.ts +++ b/src/frontend/src/stores/flowStore.ts @@ -204,6 +204,10 @@ const useFlowStore = create((set, get) => ({ }); set({ edges: newEdges }); }, + lastCopiedSelection: null, + setLastCopiedSelection: (newSelection) => { + set({ lastCopiedSelection: newSelection }); + }, })); export default useFlowStore; diff --git a/src/frontend/src/types/zustand/flow/index.ts b/src/frontend/src/types/zustand/flow/index.ts index cacc7f909..e278517f2 100644 --- a/src/frontend/src/types/zustand/flow/index.ts +++ b/src/frontend/src/types/zustand/flow/index.ts @@ -24,6 +24,11 @@ export type FlowStoreType = { selection: { nodes: any; edges: any }, position: { x: number; y: number; paneX?: number; paneY?: number } ) => void; + lastCopiedSelection: { nodes: any; edges: any } | null; + setLastCopiedSelection: ( + newSelection: { nodes: any; edges: any } | null + ) => void; isBuilt: boolean; setIsBuilt: (isBuilt: boolean) => void; + }; From e2a0990c06f2c533056c9aa13eda893ebe18ed07 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Mon, 8 Jan 2024 14:03:22 -0300 Subject: [PATCH 2/8] Removed typesContext --- src/frontend/src/contexts/typesContext.tsx | 105 ------------------ src/frontend/src/stores/flowsManagerStore.ts | 3 +- src/frontend/src/types/typesContext/index.ts | 89 --------------- .../src/types/zustand/flowsManager/index.ts | 5 + 4 files changed, 6 insertions(+), 196 deletions(-) delete mode 100644 src/frontend/src/contexts/typesContext.tsx delete mode 100644 src/frontend/src/types/typesContext/index.ts diff --git a/src/frontend/src/contexts/typesContext.tsx b/src/frontend/src/contexts/typesContext.tsx deleted file mode 100644 index 16deecf00..000000000 --- a/src/frontend/src/contexts/typesContext.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import _ from "lodash"; -import { - createContext, - ReactNode, - useContext, - useEffect, - useState, -} from "react"; -import { getAll, getHealth } from "../controllers/API"; -import useAlertStore from "../stores/alertStore"; -import { APIKindType } from "../types/api"; -import { typesContextType } from "../types/typesContext"; -import { AuthContext } from "./authContext"; - -//context to share types adn functions from nodes to flow - -const initialValue: typesContextType = { - types: {}, - setTypes: () => {}, - templates: {}, - setTemplates: () => {}, - data: {}, - setData: () => {}, - getTypes: () => {}, - setFetchError: () => {}, - fetchError: false, - setFilterEdge: (filter) => {}, - getFilterEdge: [], -}; - -export const typesContext = createContext(initialValue); - -export function TypesProvider({ children }: { children: ReactNode }) { - const [types, setTypes] = useState({}); - const [templates, setTemplates] = useState({}); - const [data, setData] = useState({}); - const [fetchError, setFetchError] = useState(false); - const setLoading = useAlertStore((state) => state.setLoading); - const [getFilterEdge, setFilterEdge] = useState([]); - - async function getTypes(): Promise { - // We will keep a flag to handle the case where the component is unmounted before the API call resolves. - let isMounted = true; - try { - const result = await getAll(); - // Make sure to only update the state if the component is still mounted. - if (isMounted && result?.status === 200) { - setLoading(false); - let { data } = _.cloneDeep(result); - setData((old) => ({ ...old, ...data })); - setTemplates( - Object.keys(data).reduce((acc, curr) => { - Object.keys(data[curr]).forEach((c: keyof APIKindType) => { - //prevent wrong overwriting of the component template by a group of the same type - if (!data[curr][c].flow) acc[c] = data[curr][c]; - }); - return acc; - }, {}) - ); - // Set the types by reducing over the keys of the result data and updating the accumulator. - setTypes( - // Reverse the keys so the tool world does not overlap - Object.keys(data) - .reverse() - .reduce((acc, curr) => { - Object.keys(data[curr]).forEach((c: keyof APIKindType) => { - acc[c] = curr; - // Add the base classes to the accumulator as well. - data[curr][c].base_classes?.forEach((b) => { - acc[b] = curr; - }); - }); - return acc; - }, {}) - ); - } - } catch (error) { - console.error("An error has occurred while fetching types."); - console.log(error); - await getHealth().catch((e) => { - setFetchError(true); - }); - } - } - - return ( - - {children} - - ); -} diff --git a/src/frontend/src/stores/flowsManagerStore.ts b/src/frontend/src/stores/flowsManagerStore.ts index b076f75e4..dfab1a9df 100644 --- a/src/frontend/src/stores/flowsManagerStore.ts +++ b/src/frontend/src/stores/flowsManagerStore.ts @@ -10,8 +10,7 @@ import { } from "../controllers/API"; import { FlowType, NodeDataType } from "../types/flow"; import { FlowState } from "../types/tabs"; -import { UseUndoRedoOptions } from "../types/typesContext"; -import { FlowsManagerStoreType } from "../types/zustand/flowsManager"; +import { FlowsManagerStoreType, UseUndoRedoOptions } from "../types/zustand/flowsManager"; import { addVersionToDuplicates, createFlowComponent, diff --git a/src/frontend/src/types/typesContext/index.ts b/src/frontend/src/types/typesContext/index.ts deleted file mode 100644 index c7314fea0..000000000 --- a/src/frontend/src/types/typesContext/index.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Edge, Node } from "reactflow"; -import { AlertItemType } from "../alerts"; - -export type alertContextType = { - errorData: { title: string; list?: Array }; - setErrorData: (newState: { title: string; list?: Array }) => void; - errorOpen: boolean; - setErrorOpen: (newState: boolean) => void; - noticeData: { title: string; link?: string }; - setNoticeData: (newState: { title: string; link?: string }) => void; - noticeOpen: boolean; - setNoticeOpen: (newState: boolean) => void; - successData: { title: string }; - setSuccessData: (newState: { title: string }) => void; - successOpen: boolean; - setSuccessOpen: (newState: boolean) => void; - notificationCenter: boolean; - setNotificationCenter: (newState: boolean) => void; - notificationList: Array; - pushNotificationList: (Object: AlertItemType) => void; - clearNotificationList: () => void; - removeFromNotificationList: (index: string) => void; - loading: boolean; - setLoading: (newState: boolean) => void; - modalContextOpen: boolean | null; - setModalContextOpen: (newState: boolean) => void; -}; - -export type darkContextType = { - dark: {}; - setDark: (newState: {}) => void; - stars: number; - setStars: (stars: number) => void; - gradientIndex: number; - setGradientIndex: (index: number) => void; -}; - -export type locationContextType = { - current: Array; - setCurrent: (newState: Array) => void; - isStackedOpen: boolean; - setIsStackedOpen: (newState: boolean) => void; - showSideBar: boolean; - setShowSideBar: (newState: boolean) => void; - extraNavigation: { - title: string; - options?: Array<{ - name: string; - href: string; - icon: React.ElementType; - children?: Array; - }>; - }; - setExtraNavigation: (newState: { - title: string; - options?: Array<{ - name: string; - href: string; - icon: React.ElementType; - children?: Array; - }>; - }) => void; - extraComponent: any; - setExtraComponent: (newState: JSX.Element) => void; -}; - -export type undoRedoContextType = { - undo: () => void; - redo: () => void; - takeSnapshot: () => void; -}; - -export type UseUndoRedoOptions = { - maxHistorySize: number; - enableShortcuts: boolean; -}; - -export type UseUndoRedo = (options?: UseUndoRedoOptions) => { - undo: () => void; - redo: () => void; - takeSnapshot: () => void; - canUndo: boolean; - canRedo: boolean; -}; - -export type HistoryItem = { - nodes: Node[]; - edges: Edge[]; -}; diff --git a/src/frontend/src/types/zustand/flowsManager/index.ts b/src/frontend/src/types/zustand/flowsManager/index.ts index d130c00e6..c90b699a1 100644 --- a/src/frontend/src/types/zustand/flowsManager/index.ts +++ b/src/frontend/src/types/zustand/flowsManager/index.ts @@ -26,3 +26,8 @@ export type FlowsManagerStoreType = { redo: () => void; takeSnapshot: () => void; }; + +export type UseUndoRedoOptions = { + maxHistorySize: number; + enableShortcuts: boolean; +}; \ No newline at end of file From c3304c4b6ebed7a5304aa7bc36bc85bbb502746b Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Mon, 8 Jan 2024 14:11:16 -0300 Subject: [PATCH 3/8] Location Context moved to Zustand --- src/frontend/src/App.tsx | 8 +-- src/frontend/src/contexts/index.tsx | 3 -- src/frontend/src/contexts/locationContext.tsx | 50 ------------------- .../components/PageComponent/index.tsx | 37 +++++++------- src/frontend/src/stores/locationStore.tsx | 29 +++++++++++ .../src/types/zustand/location/index.ts | 28 +++++++++++ 6 files changed, 79 insertions(+), 76 deletions(-) delete mode 100644 src/frontend/src/contexts/locationContext.tsx create mode 100644 src/frontend/src/stores/locationStore.tsx create mode 100644 src/frontend/src/types/zustand/location/index.ts diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 7e4d80f4d..9b7ec8b75 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -16,17 +16,19 @@ import { FETCH_ERROR_MESSAGE, } from "./constants/constants"; import { AuthContext } from "./contexts/authContext"; -import { locationContext } from "./contexts/locationContext"; import { getHealth, getRepoStars, getVersion } from "./controllers/API"; import Router from "./routes"; import useAlertStore from "./stores/alertStore"; import { useTypesStore } from "./stores/typesStore"; import { useDarkStore } from "./stores/darkStore"; import useFlowsManagerStore from "./stores/flowsManagerStore"; +import { useLocationStore } from "./stores/locationStore"; export default function App() { - let { setCurrent, setShowSideBar, setIsStackedOpen } = - useContext(locationContext); + const setCurrent = useLocationStore((state) => state.setCurrent); + const setShowSideBar = useLocationStore((state) => state.setShowSideBar); + const setIsStackedOpen = useLocationStore((state) => state.setIsStackedOpen); + let location = useLocation(); useEffect(() => { setCurrent(location.pathname.replace(/\/$/g, "").split("/")); diff --git a/src/frontend/src/contexts/index.tsx b/src/frontend/src/contexts/index.tsx index 7090b7c40..d026153c9 100644 --- a/src/frontend/src/contexts/index.tsx +++ b/src/frontend/src/contexts/index.tsx @@ -5,7 +5,6 @@ import { TooltipProvider } from "../components/ui/tooltip"; import { ApiInterceptor } from "../controllers/API/api"; import { SSEProvider } from "./SSEContext"; import { AuthProvider } from "./authContext"; -import { LocationProvider } from "./locationContext"; export default function ContextWrapper({ children }: { children: ReactNode }) { //element to wrap all context @@ -15,12 +14,10 @@ export default function ContextWrapper({ children }: { children: ReactNode }) { - {children} - diff --git a/src/frontend/src/contexts/locationContext.tsx b/src/frontend/src/contexts/locationContext.tsx deleted file mode 100644 index b0a9ef8c5..000000000 --- a/src/frontend/src/contexts/locationContext.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { createContext, ReactNode, useState } from "react"; -import { locationContextType } from "../types/typesContext"; - -//initial value for location context -const initialValue = { - //actual - current: window.location.pathname.replace(/\/$/g, "").split("/"), - isStackedOpen: - window.innerWidth > 1024 && window.location.pathname.split("/")[1] - ? true - : false, - setCurrent: () => {}, - setIsStackedOpen: () => {}, - showSideBar: window.location.pathname.split("/")[1] ? true : false, - setShowSideBar: () => {}, - extraNavigation: { title: "" }, - setExtraNavigation: () => {}, - extraComponent: <>, - setExtraComponent: () => {}, -}; - -export const locationContext = createContext(initialValue); - -export function LocationProvider({ children }: { children: ReactNode }) { - const [current, setCurrent] = useState(initialValue.current); - const [isStackedOpen, setIsStackedOpen] = useState( - initialValue.isStackedOpen - ); - const [showSideBar, setShowSideBar] = useState(initialValue.showSideBar); - const [extraNavigation, setExtraNavigation] = useState({ title: "" }); - const [extraComponent, setExtraComponent] = useState(<>); - return ( - - {children} - - ); -} diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index 1d2264947..274eaf10b 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -1,12 +1,5 @@ import _ from "lodash"; -import { - MouseEvent, - useCallback, - useContext, - useEffect, - useRef, - useState, -} from "react"; +import { MouseEvent, useCallback, useEffect, useRef, useState } from "react"; import ReactFlow, { Background, Connection, @@ -18,13 +11,10 @@ import ReactFlow, { SelectionDragHandler, addEdge, updateEdge, - useEdgesState, - useNodesState, } from "reactflow"; import GenericNode from "../../../../CustomNodes/GenericNode"; import Chat from "../../../../components/chatComponent"; import Loading from "../../../../components/ui/loading"; -import { locationContext } from "../../../../contexts/locationContext"; import useAlertStore from "../../../../stores/alertStore"; import useFlowStore from "../../../../stores/flowStore"; import useFlowsManagerStore from "../../../../stores/flowsManagerStore"; @@ -43,7 +33,7 @@ import { cn, getRandomName, isWrappedWithClass } from "../../../../utils/utils"; import ConnectionLineComponent from "../ConnectionLineComponent"; import SelectionMenu from "../SelectionMenuComponent"; import ExtraSidebar from "../extraSidebarComponent"; -import { stat } from "fs"; +import { useLocationStore } from "../../../../stores/locationStore"; const nodeTypes = { genericNode: GenericNode, @@ -82,7 +72,9 @@ export default function Page({ const redo = useFlowsManagerStore((state) => state.redo); const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); const paste = useFlowStore((state) => state.paste); - const lastCopiedSelection = useFlowStore((state) => state.lastCopiedSelection); + const lastCopiedSelection = useFlowStore( + (state) => state.lastCopiedSelection + ); const setLastCopiedSelection = useFlowStore( (state) => state.setLastCopiedSelection ); @@ -163,7 +155,12 @@ export default function Page({ const [selectionMenuVisible, setSelectionMenuVisible] = useState(false); - const { setExtraComponent, setExtraNavigation } = useContext(locationContext); + const setExtraComponent = useLocationStore( + (state) => state.setExtraComponent + ); + const setExtraNavigation = useLocationStore( + (state) => state.setExtraNavigation + ); const setErrorData = useAlertStore((state) => state.setErrorData); const edgeUpdateSuccessful = useRef(true); @@ -224,8 +221,7 @@ export default function Page({ const onMoveEnd: OnMove = useCallback(() => { // 👇 make moving the canvas undoable autoSaveCurrentFlow(nodes, edges, reactFlowInstance?.getViewport()!); - } - , [takeSnapshot, autoSaveCurrentFlow, nodes, edges, reactFlowInstance]); + }, [takeSnapshot, autoSaveCurrentFlow, nodes, edges, reactFlowInstance]); const onSelectionDragStart: SelectionDragHandler = useCallback(() => { // 👇 make dragging a selection undoable @@ -290,14 +286,16 @@ export default function Page({ const newNode: NodeType = { id: newId, type: "genericNode", - position: {x: 0, y:0}, + position: { x: 0, y: 0 }, data: { ...data, id: newId, }, }; - paste({ nodes: [newNode], edges: [] }, {x: event.clientX, y: event.clientY}); - + paste( + { nodes: [newNode], edges: [] }, + { x: event.clientX, y: event.clientY } + ); } else if (event.dataTransfer.types.some((types) => types === "Files")) { takeSnapshot(); if (event.dataTransfer.files.item(0)!.type === "application/json") { @@ -384,7 +382,6 @@ export default function Page({ setFilterEdge([]); }, []); - return (
{!view && } diff --git a/src/frontend/src/stores/locationStore.tsx b/src/frontend/src/stores/locationStore.tsx new file mode 100644 index 000000000..ca3f08289 --- /dev/null +++ b/src/frontend/src/stores/locationStore.tsx @@ -0,0 +1,29 @@ +import { create } from "zustand"; +import { getRepoStars, getVersion } from "../controllers/API"; +import { LocationStoreType } from "../types/zustand/location"; + +export const useLocationStore = create((set, get) => ({ + current: window.location.pathname.replace(/\/$/g, "").split("/"), + isStackedOpen: + window.innerWidth > 1024 && window.location.pathname.split("/")[1] + ? true + : false, + setCurrent: (newState) => { + set({ current: newState }); + }, + setIsStackedOpen: (newState) => { + set({ isStackedOpen: newState }); + }, + showSideBar: window.location.pathname.split("/")[1] ? true : false, + setShowSideBar: (newState) => { + set({ showSideBar: newState }); + }, + extraNavigation: { title: "" }, + setExtraNavigation: (newState) => { + set({ extraNavigation: newState }); + }, + extraComponent: <>, + setExtraComponent: (newState) => { + set({ extraComponent: newState }); + }, +})); diff --git a/src/frontend/src/types/zustand/location/index.ts b/src/frontend/src/types/zustand/location/index.ts new file mode 100644 index 000000000..2d2d44766 --- /dev/null +++ b/src/frontend/src/types/zustand/location/index.ts @@ -0,0 +1,28 @@ +export type LocationStoreType = { + current: Array; + setCurrent: (newState: Array) => void; + isStackedOpen: boolean; + setIsStackedOpen: (newState: boolean) => void; + showSideBar: boolean; + setShowSideBar: (newState: boolean) => void; + extraNavigation: { + title: string; + options?: Array<{ + name: string; + href: string; + icon: React.ElementType; + children?: Array; + }>; + }; + setExtraNavigation: (newState: { + title: string; + options?: Array<{ + name: string; + href: string; + icon: React.ElementType; + children?: Array; + }>; + }) => void; + extraComponent: any; + setExtraComponent: (newState: JSX.Element) => void; +}; From d1f82fa6915da445e2f143c04b75718e9b1e5b69 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Mon, 8 Jan 2024 14:20:03 -0300 Subject: [PATCH 4/8] SSE Context moved to Zustand --- .../src/CustomNodes/GenericNode/index.tsx | 5 +-- .../chatComponent/buildTrigger/index.tsx | 7 ++-- src/frontend/src/contexts/SSEContext.tsx | 34 ------------------- src/frontend/src/contexts/index.tsx | 3 -- src/frontend/src/stores/locationStore.tsx | 1 - src/frontend/src/stores/sseStore.ts | 13 +++++++ src/frontend/src/types/zustand/sse/index.ts | 6 ++++ 7 files changed, 27 insertions(+), 42 deletions(-) delete mode 100644 src/frontend/src/contexts/SSEContext.tsx create mode 100644 src/frontend/src/stores/sseStore.ts create mode 100644 src/frontend/src/types/zustand/sse/index.ts diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx index 339eb73ac..8503a2fa2 100644 --- a/src/frontend/src/CustomNodes/GenericNode/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx @@ -6,7 +6,6 @@ import IconComponent from "../../components/genericIconComponent"; import InputComponent from "../../components/inputComponent"; import { Textarea } from "../../components/ui/textarea"; import { priorityFields } from "../../constants/constants"; -import { useSSE } from "../../contexts/SSEContext"; import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent"; import useFlowStore from "../../stores/flowStore"; import { validationStatusType } from "../../types/components"; @@ -17,6 +16,7 @@ import { classNames, cn, getFieldTitle } from "../../utils/utils"; import ParameterComponent from "./components/parameterComponent"; import { useTypesStore } from "../../stores/typesStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore"; +import { useSSEStore } from "../../stores/sseStore"; export default function GenericNode({ data, @@ -80,7 +80,8 @@ export default function GenericNode({ }, [data, data.node]); // State for outline color - const { sseData, isBuilding } = useSSE(); + const sseData = useSSEStore((state) => state.sseData); + const isBuilding = useSSEStore((state) => state.isBuilding); useEffect(() => { setNodeDescription(data.node!.description); diff --git a/src/frontend/src/components/chatComponent/buildTrigger/index.tsx b/src/frontend/src/components/chatComponent/buildTrigger/index.tsx index 1dcc327ee..860d1dc15 100644 --- a/src/frontend/src/components/chatComponent/buildTrigger/index.tsx +++ b/src/frontend/src/components/chatComponent/buildTrigger/index.tsx @@ -1,7 +1,6 @@ import { Transition } from "@headlessui/react"; import { useContext, useState } from "react"; import Loading from "../../../components/ui/loading"; -import { useSSE } from "../../../contexts/SSEContext"; import { postBuildInit } from "../../../controllers/API"; import { FlowType } from "../../../types/flow"; @@ -13,6 +12,7 @@ import { FlowState } from "../../../types/tabs"; import { validateNodes } from "../../../utils/reactflowUtils"; import RadialProgressComponent from "../../RadialProgress"; import IconComponent from "../../genericIconComponent"; +import { useSSEStore } from "../../../stores/sseStore"; export default function BuildTrigger({ open, @@ -24,7 +24,10 @@ export default function BuildTrigger({ setIsBuilt: any; isBuilt: boolean; }): JSX.Element { - const { updateSSEData, isBuilding, setIsBuilding, sseData } = useSSE(); + const updateSSEData = useSSEStore((state) => state.updateSSEData); + const isBuilding = useSSEStore((state) => state.isBuilding); + const setIsBuilding = useSSEStore((state) => state.setIsBuilding); + const sseData = useSSEStore((state) => state.sseData); const nodes = useFlowStore((state) => state.nodes); const edges = useFlowStore((state) => state.edges); const setErrorData = useAlertStore((state) => state.setErrorData); diff --git a/src/frontend/src/contexts/SSEContext.tsx b/src/frontend/src/contexts/SSEContext.tsx deleted file mode 100644 index 9db32310b..000000000 --- a/src/frontend/src/contexts/SSEContext.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { createContext, useCallback, useContext, useState } from "react"; - -const initialValue = { - updateSSEData: ({}) => {}, - sseData: {}, - isBuilding: false, - setIsBuilding: (isBuilding: boolean) => {}, -}; - -const SSEContext = createContext(initialValue); - -export function useSSE() { - return useContext(SSEContext); -} - -export function SSEProvider({ children }) { - const [sseData, setSSEData] = useState({}); - const [isBuilding, setIsBuilding] = useState(false); - - const updateSSEData = useCallback((newData: any) => { - setSSEData((prevData) => ({ - ...prevData, - ...newData, - })); - }, []); - - return ( - - {children} - - ); -} diff --git a/src/frontend/src/contexts/index.tsx b/src/frontend/src/contexts/index.tsx index d026153c9..f6660e7fe 100644 --- a/src/frontend/src/contexts/index.tsx +++ b/src/frontend/src/contexts/index.tsx @@ -3,7 +3,6 @@ import { BrowserRouter } from "react-router-dom"; import { ReactFlowProvider } from "reactflow"; import { TooltipProvider } from "../components/ui/tooltip"; import { ApiInterceptor } from "../controllers/API/api"; -import { SSEProvider } from "./SSEContext"; import { AuthProvider } from "./authContext"; export default function ContextWrapper({ children }: { children: ReactNode }) { @@ -15,9 +14,7 @@ export default function ContextWrapper({ children }: { children: ReactNode }) { - {children} - diff --git a/src/frontend/src/stores/locationStore.tsx b/src/frontend/src/stores/locationStore.tsx index ca3f08289..247304712 100644 --- a/src/frontend/src/stores/locationStore.tsx +++ b/src/frontend/src/stores/locationStore.tsx @@ -1,5 +1,4 @@ import { create } from "zustand"; -import { getRepoStars, getVersion } from "../controllers/API"; import { LocationStoreType } from "../types/zustand/location"; export const useLocationStore = create((set, get) => ({ diff --git a/src/frontend/src/stores/sseStore.ts b/src/frontend/src/stores/sseStore.ts new file mode 100644 index 000000000..17bb68447 --- /dev/null +++ b/src/frontend/src/stores/sseStore.ts @@ -0,0 +1,13 @@ +import { create } from "zustand"; +import { SSEStoreType } from "../types/zustand/sse"; + +export const useSSEStore = create((set) => ({ + updateSSEData: (sseData) => { + set({ sseData }); + }, + sseData: {}, + isBuilding: false, + setIsBuilding: (isBuilding) => { + set({ isBuilding }); + }, +})); diff --git a/src/frontend/src/types/zustand/sse/index.ts b/src/frontend/src/types/zustand/sse/index.ts new file mode 100644 index 000000000..baa088171 --- /dev/null +++ b/src/frontend/src/types/zustand/sse/index.ts @@ -0,0 +1,6 @@ +export type SSEStoreType = { + updateSSEData: (sseData: object) => void, + sseData: object, + isBuilding: boolean, + setIsBuilding: (isBuilding: boolean) => void, +} \ No newline at end of file From fe6180297297a95a955b1ceefa5c0cf3584a9eb3 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Mon, 8 Jan 2024 14:27:50 -0300 Subject: [PATCH 5/8] Fixed chatComponent not appearing after build --- .../src/components/chatComponent/index.tsx | 5 +-- src/frontend/src/modals/formModal/index.tsx | 45 +++++++++---------- src/frontend/src/types/tabs/index.ts | 10 ++--- src/frontend/src/utils/utils.ts | 14 +++--- 4 files changed, 33 insertions(+), 41 deletions(-) diff --git a/src/frontend/src/components/chatComponent/index.tsx b/src/frontend/src/components/chatComponent/index.tsx index 80d6fb991..853e21a81 100644 --- a/src/frontend/src/components/chatComponent/index.tsx +++ b/src/frontend/src/components/chatComponent/index.tsx @@ -17,7 +17,6 @@ export default function Chat({ flow }: ChatType): JSX.Element { const isBuilt = useFlowStore((state) => state.isBuilt); const setIsBuilt = useFlowStore((state) => state.setIsBuilt); const currentFlowState = useFlowsManagerStore((state) => state.currentFlowState); - useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if ( @@ -60,8 +59,7 @@ export default function Chat({ flow }: ChatType): JSX.Element { } if ( currentFlowState && - currentFlowState.formKeysData && - currentFlowState.formKeysData.input_keys !== null + currentFlowState.input_keys !== null ) { setCanOpen(true); } else { @@ -82,7 +80,6 @@ export default function Chat({ flow }: ChatType): JSX.Element { /> {isBuilt && currentFlowState && - currentFlowState.formKeysData && canOpen && ( { try { - const formKeysData = currentFlowState?.formKeysData; - if (!formKeysData) { - throw new Error("formKeysData is undefined"); + if (!currentFlowState) { + throw new Error("currentFlowState is undefined"); } - const inputKeys = formKeysData.input_keys; - const handleKeys = formKeysData.handle_keys; + const inputKeys = currentFlowState.input_keys; + const handleKeys = currentFlowState.handle_keys; const keyToUse = Object.keys(inputKeys!).find( (key) => !handleKeys?.some((j) => j === key) && inputKeys![key] === "" @@ -68,7 +67,7 @@ export default function FormModal({ }); const [chatHistory, setChatHistory] = useState([]); - const template = useRef(currentFlowState?.formKeysData.template ?? undefined); + const template = useRef(currentFlowState?.template ?? undefined); const { accessToken } = useContext(AuthContext); const setErrorData = useAlertStore((state) => state.setErrorData); const ws = useRef(null); @@ -77,11 +76,11 @@ export default function FormModal({ const messagesRef = useRef(null); const [chatKey, setChatKey] = useState(() => { - if (currentFlowState?.formKeysData?.input_keys) { - return Object.keys(currentFlowState.formKeysData.input_keys!).find( + if (currentFlowState?.input_keys) { + return Object.keys(currentFlowState.input_keys!).find( (key) => - !currentFlowState.formKeysData.handle_keys!.some((j) => j === key) && - currentFlowState.formKeysData.input_keys![key] === "" + !currentFlowState.handle_keys!.some((j) => j === key) && + currentFlowState.input_keys![key] === "" ); } // TODO: return a sensible default @@ -387,7 +386,7 @@ export default function FormModal({ let nodeValidationErrors = validateNodes(nodes, edges); if (nodeValidationErrors.length === 0) { setLockChat(true); - let inputs = currentFlowState?.formKeysData.input_keys; + let inputs = currentFlowState?.input_keys; setChatValue(""); const message = inputs; addChatHistory(message!, true, chatKey!, template.current); @@ -402,7 +401,7 @@ export default function FormModal({ if (currentFlowState && chatKey) { setCurrentFlowState((old: FlowState | undefined) => { let newFlowState = cloneDeep(old!); - newFlowState.formKeysData.input_keys![chatKey] = ""; + newFlowState.input_keys![chatKey] = ""; return newFlowState; }); } @@ -415,7 +414,7 @@ export default function FormModal({ } function clearChat(): void { setChatHistory([]); - template.current = currentFlowState?.formKeysData.template; + template.current = currentFlowState?.template; ws.current?.send(JSON.stringify({ clear_history: true })); if (lockChat) setLockChat(false); } @@ -423,7 +422,7 @@ export default function FormModal({ function handleOnCheckedChange(checked: boolean, i: string) { if (checked === true) { setChatKey(i); - setChatValue(currentFlowState?.formKeysData.input_keys![i] ?? ""); + setChatValue(currentFlowState?.input_keys![i] ?? ""); } else { setChatKey(null!); setChatValue(""); @@ -432,7 +431,7 @@ export default function FormModal({ return ( - {currentFlowState && currentFlowState.formKeysData && ( + {currentFlowState && currentFlowState && ( @@ -468,8 +467,8 @@ export default function FormModal({
- {currentFlowState?.formKeysData?.input_keys - ? Object.keys(currentFlowState?.formKeysData.input_keys!).map( + {currentFlowState?.input_keys + ? Object.keys(currentFlowState?.input_keys!).map( (key, index) => (
t === key )} /> @@ -502,7 +501,7 @@ export default function FormModal({ keyValue={key} >
- {currentFlowState?.formKeysData.handle_keys!.some( + {currentFlowState?.handle_keys!.some( (t) => t === key ) && (
@@ -512,14 +511,14 @@ export default function FormModal({