Implemented types context at Zustand and at the whole project
This commit is contained in:
parent
7f8f5d3f7b
commit
03d7020185
16 changed files with 143 additions and 168 deletions
|
|
@ -18,10 +18,10 @@ import {
|
||||||
import { AuthContext } from "./contexts/authContext";
|
import { AuthContext } from "./contexts/authContext";
|
||||||
import { FlowsContext } from "./contexts/flowsContext";
|
import { FlowsContext } from "./contexts/flowsContext";
|
||||||
import { locationContext } from "./contexts/locationContext";
|
import { locationContext } from "./contexts/locationContext";
|
||||||
import { typesContext } from "./contexts/typesContext";
|
|
||||||
import { getVersion } from "./controllers/API";
|
import { getVersion } from "./controllers/API";
|
||||||
import Router from "./routes";
|
import Router from "./routes";
|
||||||
import useAlertStore from "./stores/alertStore";
|
import useAlertStore from "./stores/alertStore";
|
||||||
|
import { useTypesStore } from "./stores/typesStore";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
let { setCurrent, setShowSideBar, setIsStackedOpen } =
|
let { setCurrent, setShowSideBar, setIsStackedOpen } =
|
||||||
|
|
@ -43,8 +43,7 @@ export default function App() {
|
||||||
const successOpen = useAlertStore((state) => state.successOpen);
|
const successOpen = useAlertStore((state) => state.successOpen);
|
||||||
const setSuccessOpen = useAlertStore((state) => state.setSuccessOpen);
|
const setSuccessOpen = useAlertStore((state) => state.setSuccessOpen);
|
||||||
const loading = useAlertStore((state) => state.loading);
|
const loading = useAlertStore((state) => state.loading);
|
||||||
|
const fetchError = useAlertStore((state) => state.fetchError);
|
||||||
const { fetchError } = useContext(typesContext);
|
|
||||||
|
|
||||||
// Initialize state variable for the list of alerts
|
// Initialize state variable for the list of alerts
|
||||||
const [alertsList, setAlertsList] = useState<
|
const [alertsList, setAlertsList] = useState<
|
||||||
|
|
@ -132,14 +131,15 @@ export default function App() {
|
||||||
|
|
||||||
const { isAuthenticated } = useContext(AuthContext);
|
const { isAuthenticated } = useContext(AuthContext);
|
||||||
const { refreshFlows, setVersion } = useContext(FlowsContext);
|
const { refreshFlows, setVersion } = useContext(FlowsContext);
|
||||||
const { getTypes } = useContext(typesContext);
|
const getTypes = useTypesStore((state) => state.getTypes);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// If the user is authenticated, fetch the types. This code is important to check if the user is auth because of the execution order of the useEffect hooks.
|
// If the user is authenticated, fetch the types. This code is important to check if the user is auth because of the execution order of the useEffect hooks.
|
||||||
if (isAuthenticated === true) {
|
if (isAuthenticated === true) {
|
||||||
// get data from db
|
// get data from db
|
||||||
refreshFlows();
|
getTypes().then(() => {
|
||||||
getTypes();
|
refreshFlows();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getVersion().then((data) => {
|
getVersion().then((data) => {
|
||||||
|
|
@ -156,16 +156,14 @@ export default function App() {
|
||||||
}}
|
}}
|
||||||
FallbackComponent={CrashErrorComponent}
|
FallbackComponent={CrashErrorComponent}
|
||||||
>
|
>
|
||||||
{loading ? (
|
{fetchError ? (
|
||||||
|
<FetchErrorComponent
|
||||||
|
description={FETCH_ERROR_DESCRIPION}
|
||||||
|
message={FETCH_ERROR_MESSAGE}
|
||||||
|
></FetchErrorComponent>
|
||||||
|
) : loading ? (
|
||||||
<div className="loading-page-panel">
|
<div className="loading-page-panel">
|
||||||
{fetchError ? (
|
<LoadingComponent remSize={50} />
|
||||||
<FetchErrorComponent
|
|
||||||
description={FETCH_ERROR_DESCRIPION}
|
|
||||||
message={FETCH_ERROR_MESSAGE}
|
|
||||||
></FetchErrorComponent>
|
|
||||||
) : (
|
|
||||||
<LoadingComponent remSize={50} />
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ import {
|
||||||
TOOLTIP_EMPTY,
|
TOOLTIP_EMPTY,
|
||||||
} from "../../../../constants/constants";
|
} from "../../../../constants/constants";
|
||||||
import { FlowsContext } from "../../../../contexts/flowsContext";
|
import { FlowsContext } from "../../../../contexts/flowsContext";
|
||||||
import { typesContext } from "../../../../contexts/typesContext";
|
|
||||||
import { undoRedoContext } from "../../../../contexts/undoRedoContext";
|
import { undoRedoContext } from "../../../../contexts/undoRedoContext";
|
||||||
import { postCustomComponentUpdate } from "../../../../controllers/API";
|
import { postCustomComponentUpdate } from "../../../../controllers/API";
|
||||||
import useAlertStore from "../../../../stores/alertStore";
|
import useAlertStore from "../../../../stores/alertStore";
|
||||||
|
|
@ -48,6 +47,7 @@ import {
|
||||||
nodeNames,
|
nodeNames,
|
||||||
} from "../../../../utils/styleUtils";
|
} from "../../../../utils/styleUtils";
|
||||||
import { classNames, groupByFamily } from "../../../../utils/utils";
|
import { classNames, groupByFamily } from "../../../../utils/utils";
|
||||||
|
import { useTypesStore } from "../../../../stores/typesStore";
|
||||||
|
|
||||||
export default function ParameterComponent({
|
export default function ParameterComponent({
|
||||||
left,
|
left,
|
||||||
|
|
@ -78,14 +78,15 @@ export default function ParameterComponent({
|
||||||
|
|
||||||
const groupedEdge = useRef(null);
|
const groupedEdge = useRef(null);
|
||||||
|
|
||||||
const { setFilterEdge } = useContext(typesContext);
|
const setFilterEdge = useTypesStore((state) => state.setFilterEdge);
|
||||||
|
|
||||||
let disabled =
|
let disabled =
|
||||||
edges.some(
|
edges.some(
|
||||||
(edge) =>
|
(edge) =>
|
||||||
edge.targetHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id)
|
edge.targetHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id)
|
||||||
) ?? false;
|
) ?? false;
|
||||||
|
|
||||||
const { data: myData } = useContext(typesContext);
|
const myData = useTypesStore((state) => state.data);
|
||||||
|
|
||||||
const { takeSnapshot } = useContext(undoRedoContext);
|
const { takeSnapshot } = useContext(undoRedoContext);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import InputComponent from "../../components/inputComponent";
|
||||||
import { Textarea } from "../../components/ui/textarea";
|
import { Textarea } from "../../components/ui/textarea";
|
||||||
import { priorityFields } from "../../constants/constants";
|
import { priorityFields } from "../../constants/constants";
|
||||||
import { useSSE } from "../../contexts/SSEContext";
|
import { useSSE } from "../../contexts/SSEContext";
|
||||||
import { typesContext } from "../../contexts/typesContext";
|
|
||||||
import { undoRedoContext } from "../../contexts/undoRedoContext";
|
import { undoRedoContext } from "../../contexts/undoRedoContext";
|
||||||
import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent";
|
import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent";
|
||||||
import useFlowStore from "../../stores/flowStore";
|
import useFlowStore from "../../stores/flowStore";
|
||||||
|
|
@ -17,6 +16,7 @@ import { handleKeyDown, scapedJSONStringfy } from "../../utils/reactflowUtils";
|
||||||
import { nodeColors, nodeIconsLucide } from "../../utils/styleUtils";
|
import { nodeColors, nodeIconsLucide } from "../../utils/styleUtils";
|
||||||
import { classNames, cn, getFieldTitle } from "../../utils/utils";
|
import { classNames, cn, getFieldTitle } from "../../utils/utils";
|
||||||
import ParameterComponent from "./components/parameterComponent";
|
import ParameterComponent from "./components/parameterComponent";
|
||||||
|
import { useTypesStore } from "../../stores/typesStore";
|
||||||
|
|
||||||
export default function GenericNode({
|
export default function GenericNode({
|
||||||
data,
|
data,
|
||||||
|
|
@ -29,7 +29,7 @@ export default function GenericNode({
|
||||||
xPos: number;
|
xPos: number;
|
||||||
yPos: number;
|
yPos: number;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { types } = useContext(typesContext);
|
const types = useTypesStore((state) => state.types);
|
||||||
const deleteNode = useFlowStore((state) => state.deleteNode);
|
const deleteNode = useFlowStore((state) => state.deleteNode);
|
||||||
const setNode = useFlowStore((state) => state.setNode);
|
const setNode = useFlowStore((state) => state.setNode);
|
||||||
const name = nodeIconsLucide[data.type] ? data.type : types[data.type];
|
const name = nodeIconsLucide[data.type] ? data.type : types[data.type];
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ import {
|
||||||
getRandomDescription,
|
getRandomDescription,
|
||||||
getRandomName,
|
getRandomName,
|
||||||
} from "../utils/utils";
|
} from "../utils/utils";
|
||||||
import { typesContext } from "./typesContext";
|
import { useTypesStore } from "../stores/typesStore";
|
||||||
|
|
||||||
const uid = new ShortUniqueId({ length: 5 });
|
const uid = new ShortUniqueId({ length: 5 });
|
||||||
|
|
||||||
|
|
@ -76,8 +76,7 @@ export function FlowsProvider({ children }: { children: ReactNode }) {
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [flows, setFlows] = useState<Array<FlowType>>([]);
|
const [flows, setFlows] = useState<Array<FlowType>>([]);
|
||||||
const [tabsState, setTabsState] = useState<FlowsState>({});
|
const [tabsState, setTabsState] = useState<FlowsState>({});
|
||||||
const { setData } = useContext(typesContext);
|
const setData = useTypesStore((state) => state.setData);
|
||||||
|
|
||||||
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 reactFlowInstance = useFlowStore((state) => state.reactFlowInstance);
|
const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import { AuthProvider } from "./authContext";
|
||||||
import { FlowsProvider } from "./flowsContext";
|
import { FlowsProvider } from "./flowsContext";
|
||||||
import { LocationProvider } from "./locationContext";
|
import { LocationProvider } from "./locationContext";
|
||||||
|
|
||||||
import { TypesProvider } from "./typesContext";
|
|
||||||
import { UndoRedoProvider } from "./undoRedoContext";
|
import { UndoRedoProvider } from "./undoRedoContext";
|
||||||
|
|
||||||
export default function ContextWrapper({ children }: { children: ReactNode }) {
|
export default function ContextWrapper({ children }: { children: ReactNode }) {
|
||||||
|
|
@ -19,16 +18,14 @@ export default function ContextWrapper({ children }: { children: ReactNode }) {
|
||||||
<AuthProvider>
|
<AuthProvider>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<ReactFlowProvider>
|
<ReactFlowProvider>
|
||||||
<TypesProvider>
|
<LocationProvider>
|
||||||
<LocationProvider>
|
<ApiInterceptor />
|
||||||
<ApiInterceptor />
|
<SSEProvider>
|
||||||
<SSEProvider>
|
<FlowsProvider>
|
||||||
<FlowsProvider>
|
<UndoRedoProvider>{children}</UndoRedoProvider>
|
||||||
<UndoRedoProvider>{children}</UndoRedoProvider>
|
</FlowsProvider>
|
||||||
</FlowsProvider>
|
</SSEProvider>
|
||||||
</SSEProvider>
|
</LocationProvider>
|
||||||
</LocationProvider>
|
|
||||||
</TypesProvider>
|
|
||||||
</ReactFlowProvider>
|
</ReactFlowProvider>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
|
|
|
||||||
|
|
@ -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<typesContextType>(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<void> {
|
|
||||||
// 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 (
|
|
||||||
<typesContext.Provider
|
|
||||||
value={{
|
|
||||||
types,
|
|
||||||
setTypes,
|
|
||||||
setTemplates,
|
|
||||||
templates,
|
|
||||||
data,
|
|
||||||
setData,
|
|
||||||
getTypes,
|
|
||||||
fetchError,
|
|
||||||
setFetchError,
|
|
||||||
setFilterEdge,
|
|
||||||
getFilterEdge,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</typesContext.Provider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -25,7 +25,6 @@ import Chat from "../../../../components/chatComponent";
|
||||||
import Loading from "../../../../components/ui/loading";
|
import Loading from "../../../../components/ui/loading";
|
||||||
import { FlowsContext } from "../../../../contexts/flowsContext";
|
import { FlowsContext } from "../../../../contexts/flowsContext";
|
||||||
import { locationContext } from "../../../../contexts/locationContext";
|
import { locationContext } from "../../../../contexts/locationContext";
|
||||||
import { typesContext } from "../../../../contexts/typesContext";
|
|
||||||
import { undoRedoContext } from "../../../../contexts/undoRedoContext";
|
import { undoRedoContext } from "../../../../contexts/undoRedoContext";
|
||||||
import useAlertStore from "../../../../stores/alertStore";
|
import useAlertStore from "../../../../stores/alertStore";
|
||||||
import useFlowStore from "../../../../stores/flowStore";
|
import useFlowStore from "../../../../stores/flowStore";
|
||||||
|
|
@ -42,6 +41,7 @@ import { cn, getRandomName, isWrappedWithClass } from "../../../../utils/utils";
|
||||||
import ConnectionLineComponent from "../ConnectionLineComponent";
|
import ConnectionLineComponent from "../ConnectionLineComponent";
|
||||||
import SelectionMenu from "../SelectionMenuComponent";
|
import SelectionMenu from "../SelectionMenuComponent";
|
||||||
import ExtraSidebar from "../extraSidebarComponent";
|
import ExtraSidebar from "../extraSidebarComponent";
|
||||||
|
import { useTypesStore } from "../../../../stores/typesStore";
|
||||||
|
|
||||||
const nodeTypes = {
|
const nodeTypes = {
|
||||||
genericNode: GenericNode,
|
genericNode: GenericNode,
|
||||||
|
|
@ -55,7 +55,9 @@ export default function Page({
|
||||||
view?: boolean;
|
view?: boolean;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
let { uploadFlow, saveFlow } = useContext(FlowsContext);
|
let { uploadFlow, saveFlow } = useContext(FlowsContext);
|
||||||
const { types, templates, setFilterEdge } = useContext(typesContext);
|
const types = useTypesStore((state) => state.types);
|
||||||
|
const templates = useTypesStore((state) => state.templates);
|
||||||
|
const setFilterEdge = useTypesStore((state) => state.setFilterEdge);
|
||||||
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const [lastCopiedSelection, setLastCopiedSelection] = useState<{
|
const [lastCopiedSelection, setLastCopiedSelection] = useState<{
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import IconComponent from "../../../../components/genericIconComponent";
|
||||||
import { Input } from "../../../../components/ui/input";
|
import { Input } from "../../../../components/ui/input";
|
||||||
import { Separator } from "../../../../components/ui/separator";
|
import { Separator } from "../../../../components/ui/separator";
|
||||||
import { FlowsContext } from "../../../../contexts/flowsContext";
|
import { FlowsContext } from "../../../../contexts/flowsContext";
|
||||||
import { typesContext } from "../../../../contexts/typesContext";
|
|
||||||
import ApiModal from "../../../../modals/ApiModal";
|
import ApiModal from "../../../../modals/ApiModal";
|
||||||
import ExportModal from "../../../../modals/exportModal";
|
import ExportModal from "../../../../modals/exportModal";
|
||||||
import ShareModal from "../../../../modals/shareModal";
|
import ShareModal from "../../../../modals/shareModal";
|
||||||
|
|
@ -25,10 +24,13 @@ import {
|
||||||
} from "../../../../utils/utils";
|
} from "../../../../utils/utils";
|
||||||
import DisclosureComponent from "../DisclosureComponent";
|
import DisclosureComponent from "../DisclosureComponent";
|
||||||
import SidebarDraggableComponent from "./sideBarDraggableComponent";
|
import SidebarDraggableComponent from "./sideBarDraggableComponent";
|
||||||
|
import { useTypesStore } from "../../../../stores/typesStore";
|
||||||
|
|
||||||
export default function ExtraSidebar(): JSX.Element {
|
export default function ExtraSidebar(): JSX.Element {
|
||||||
const { data, templates, getFilterEdge, setFilterEdge } =
|
const data = useTypesStore((state) => state.data);
|
||||||
useContext(typesContext);
|
const templates = useTypesStore((state) => state.templates);
|
||||||
|
const getFilterEdge = useTypesStore((state) => state.getFilterEdge);
|
||||||
|
const setFilterEdge = useTypesStore((state) => state.setFilterEdge);
|
||||||
const { flows, tabId, uploadFlow, saveFlow } = useContext(FlowsContext);
|
const { flows, tabId, uploadFlow, saveFlow } = useContext(FlowsContext);
|
||||||
|
|
||||||
const hasStore = useStoreStore((state) => state.hasStore);
|
const hasStore = useStoreStore((state) => state.hasStore);
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,10 @@ const useAlertStore = create<AlertStoreType>((set, get) => ({
|
||||||
notificationCenter: false,
|
notificationCenter: false,
|
||||||
notificationList: [],
|
notificationList: [],
|
||||||
loading: true,
|
loading: true,
|
||||||
|
fetchError: false,
|
||||||
|
setFetchError: (newState: boolean) => {
|
||||||
|
set({ fetchError: newState });
|
||||||
|
},
|
||||||
setErrorData: (newState: { title: string; list?: Array<string> }) => {
|
setErrorData: (newState: { title: string; list?: Array<string> }) => {
|
||||||
if (newState.title && newState.title !== "") {
|
if (newState.title && newState.title !== "") {
|
||||||
set({
|
set({
|
||||||
|
|
|
||||||
52
src/frontend/src/stores/typesStore.ts
Normal file
52
src/frontend/src/stores/typesStore.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import { create } from "zustand";
|
||||||
|
import { getAll, getHealth } from "../controllers/API";
|
||||||
|
import { APIDataType, APIKindType } from "../types/api";
|
||||||
|
import { TypesStoreType } from "../types/zustand/types";
|
||||||
|
import useAlertStore from "./alertStore";
|
||||||
|
import { templatesGenerator, typesGenerator } from "../utils/reactflowUtils";
|
||||||
|
|
||||||
|
export const useTypesStore = create<TypesStoreType>((set, get) => ({
|
||||||
|
types: {},
|
||||||
|
templates: {},
|
||||||
|
data: {},
|
||||||
|
getFilterEdge: [],
|
||||||
|
getTypes: () => {
|
||||||
|
return new Promise<void>(async (resolve, reject) => {
|
||||||
|
getAll()
|
||||||
|
.then((response) => {
|
||||||
|
const data = response.data;
|
||||||
|
useAlertStore.setState({ loading: false });
|
||||||
|
set((old) => ({
|
||||||
|
types: typesGenerator(data),
|
||||||
|
data: { ...old.data, ...data },
|
||||||
|
templates: templatesGenerator(data),
|
||||||
|
}));
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("An error has occurred while fetching types.");
|
||||||
|
console.log(error);
|
||||||
|
getHealth().catch((e) => {
|
||||||
|
useAlertStore.setState({
|
||||||
|
fetchError: true,
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
reject();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setTypes: (newState: {}) => {
|
||||||
|
set({ types: newState });
|
||||||
|
},
|
||||||
|
setTemplates: (newState: {}) => {
|
||||||
|
set({ templates: newState });
|
||||||
|
},
|
||||||
|
setData: (change: APIDataType | ((old: APIDataType) => APIDataType)) => {
|
||||||
|
let newChange = typeof change === "function" ? change(get().data) : change;
|
||||||
|
set({ data: newChange });
|
||||||
|
},
|
||||||
|
setFilterEdge: (newState) => {
|
||||||
|
set({ getFilterEdge: newState });
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
@ -2,8 +2,8 @@ import { Edge, Node, Viewport } from "reactflow";
|
||||||
import { FlowType } from "../flow";
|
import { FlowType } from "../flow";
|
||||||
//kind and class are just representative names to represent the actual structure of the object received by the API
|
//kind and class are just representative names to represent the actual structure of the object received by the API
|
||||||
export type APIDataType = { [key: string]: APIKindType };
|
export type APIDataType = { [key: string]: APIKindType };
|
||||||
export type APIObjectType = { kind: APIKindType; [key: string]: APIKindType };
|
export type APIObjectType = { [key: string]: APIKindType };
|
||||||
export type APIKindType = { class: APIClassType; [key: string]: APIClassType };
|
export type APIKindType = { [key: string]: APIClassType };
|
||||||
export type APITemplateType = {
|
export type APITemplateType = {
|
||||||
[key: string]: TemplateVariableType;
|
[key: string]: TemplateVariableType;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ import { ReactFlowJsonObject, XYPosition } from "reactflow";
|
||||||
import { APIClassType, APITemplateType, TemplateVariableType } from "../api";
|
import { APIClassType, APITemplateType, TemplateVariableType } from "../api";
|
||||||
import { ChatMessageType } from "../chat";
|
import { ChatMessageType } from "../chat";
|
||||||
import { FlowStyleType, FlowType, NodeDataType, NodeType } from "../flow/index";
|
import { FlowStyleType, FlowType, NodeDataType, NodeType } from "../flow/index";
|
||||||
import { typesContextType } from "../typesContext";
|
|
||||||
import { sourceHandleType, targetHandleType } from "./../flow/index";
|
import { sourceHandleType, targetHandleType } from "./../flow/index";
|
||||||
|
import { TypesStoreType } from "../zustand/types";
|
||||||
export type InputComponentType = {
|
export type InputComponentType = {
|
||||||
autoFocus?: boolean;
|
autoFocus?: boolean;
|
||||||
onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
|
onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
|
||||||
|
|
@ -48,7 +48,6 @@ export type ParameterComponentType = {
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
name?: string;
|
name?: string;
|
||||||
tooltipTitle: string | undefined;
|
tooltipTitle: string | undefined;
|
||||||
dataContext?: typesContextType;
|
|
||||||
optionalHandle?: Array<String> | null;
|
optionalHandle?: Array<String> | null;
|
||||||
info?: string;
|
info?: string;
|
||||||
proxy?: { field: string; id: string };
|
proxy?: { field: string; id: string };
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,5 @@
|
||||||
import { Edge, Node } from "reactflow";
|
import { Edge, Node } from "reactflow";
|
||||||
import { AlertItemType } from "../alerts";
|
import { AlertItemType } from "../alerts";
|
||||||
import { APIClassType, APIDataType } from "../api";
|
|
||||||
|
|
||||||
const types: { [char: string]: string } = {};
|
|
||||||
const template: { [char: string]: APIClassType } = {};
|
|
||||||
const data: { [char: string]: string } = {};
|
|
||||||
|
|
||||||
export type typesContextType = {
|
|
||||||
types: typeof types;
|
|
||||||
setTypes: (newState: {}) => void;
|
|
||||||
templates: typeof template;
|
|
||||||
setTemplates: (newState: {}) => void;
|
|
||||||
data: APIDataType;
|
|
||||||
setData: (newState: {}) => void;
|
|
||||||
getTypes: () => void;
|
|
||||||
fetchError: boolean;
|
|
||||||
setFetchError: (newState: boolean) => void;
|
|
||||||
setFilterEdge: (newState) => void;
|
|
||||||
getFilterEdge: any[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type alertContextType = {
|
export type alertContextType = {
|
||||||
errorData: { title: string; list?: Array<string> };
|
errorData: { title: string; list?: Array<string> };
|
||||||
|
|
|
||||||
|
|
@ -20,4 +20,6 @@ export type AlertStoreType = {
|
||||||
removeFromNotificationList: (index: string) => void;
|
removeFromNotificationList: (index: string) => void;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
setLoading: (newState: boolean) => void;
|
setLoading: (newState: boolean) => void;
|
||||||
|
fetchError: boolean;
|
||||||
|
setFetchError: (newState: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
13
src/frontend/src/types/zustand/types/index.ts
Normal file
13
src/frontend/src/types/zustand/types/index.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { APIClassType, APIDataType } from "../../api";
|
||||||
|
|
||||||
|
export type TypesStoreType = {
|
||||||
|
types: { [char: string]: string };
|
||||||
|
setTypes: (newState: {}) => void;
|
||||||
|
templates: { [char: string]: APIClassType };
|
||||||
|
setTemplates: (newState: {}) => void;
|
||||||
|
data: APIDataType;
|
||||||
|
setData: (newState: {}) => void;
|
||||||
|
getTypes: () => Promise<void>;
|
||||||
|
setFilterEdge: (newState) => void;
|
||||||
|
getFilterEdge: any[];
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,12 @@ import {
|
||||||
LANGFLOW_SUPPORTED_TYPES,
|
LANGFLOW_SUPPORTED_TYPES,
|
||||||
specialCharsRegex,
|
specialCharsRegex,
|
||||||
} from "../constants/constants";
|
} from "../constants/constants";
|
||||||
import { APITemplateType, TemplateVariableType } from "../types/api";
|
import {
|
||||||
|
APIKindType,
|
||||||
|
APIObjectType,
|
||||||
|
APITemplateType,
|
||||||
|
TemplateVariableType,
|
||||||
|
} from "../types/api";
|
||||||
import {
|
import {
|
||||||
FlowType,
|
FlowType,
|
||||||
NodeDataType,
|
NodeDataType,
|
||||||
|
|
@ -1138,3 +1143,28 @@ export function removeFileNameFromComponents(flow: FlowType) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function typesGenerator(data: APIObjectType) {
|
||||||
|
return 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;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function templatesGenerator(data: APIObjectType) {
|
||||||
|
return 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;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue