comment on some functions using chatgpt
This commit is contained in:
parent
2a87d2362d
commit
188bf1fc4d
10 changed files with 165 additions and 102 deletions
|
|
@ -35,38 +35,45 @@ export default function App() {
|
|||
setSuccessOpen,
|
||||
} = useContext(alertContext);
|
||||
|
||||
const [alertsList, setAlertsList] = useState<Array<{type:string,data:{title:string,list?:Array<string>,link?:string},id:string}>>([]);
|
||||
// Initialize state variable for the list of alerts
|
||||
const [alertsList, setAlertsList] = useState<Array<{type:string,data:{title:string,list?:Array<string>,link?:string},id:string}>>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (errorOpen && errorData) {
|
||||
setErrorOpen(false);
|
||||
setAlertsList((old) => {
|
||||
let newAlertsList = [
|
||||
...old,
|
||||
{ type: "error", data: _.cloneDeep(errorData), id: _.uniqueId() },
|
||||
];
|
||||
return newAlertsList;
|
||||
});
|
||||
} else if (noticeOpen && noticeData) {
|
||||
setNoticeOpen(false);
|
||||
setAlertsList((old) => {
|
||||
let newAlertsList = [
|
||||
...old,
|
||||
{ type: "notice", data: _.cloneDeep(noticeData), id: _.uniqueId() },
|
||||
];
|
||||
return newAlertsList;
|
||||
});
|
||||
} else if (successOpen && successData) {
|
||||
setSuccessOpen(false);
|
||||
setAlertsList((old) => {
|
||||
let newAlertsList = [
|
||||
...old,
|
||||
{ type: "success", data: _.cloneDeep(successData), id: _.uniqueId() },
|
||||
];
|
||||
return newAlertsList;
|
||||
});
|
||||
}
|
||||
}, [_, errorData, errorOpen, noticeData, noticeOpen, setErrorOpen, setNoticeOpen, setSuccessOpen, successData, successOpen]);
|
||||
// Use effect hook to update alertsList when a new alert is added
|
||||
useEffect(() => {
|
||||
// If there is an error alert open with data, add it to the alertsList
|
||||
if (errorOpen && errorData) {
|
||||
setErrorOpen(false);
|
||||
setAlertsList((old) => {
|
||||
let newAlertsList = [
|
||||
...old,
|
||||
{ type: "error", data: _.cloneDeep(errorData), id: _.uniqueId() },
|
||||
];
|
||||
return newAlertsList;
|
||||
});
|
||||
}
|
||||
// If there is a notice alert open with data, add it to the alertsList
|
||||
else if (noticeOpen && noticeData) {
|
||||
setNoticeOpen(false);
|
||||
setAlertsList((old) => {
|
||||
let newAlertsList = [
|
||||
...old,
|
||||
{ type: "notice", data: _.cloneDeep(noticeData), id: _.uniqueId() },
|
||||
];
|
||||
return newAlertsList;
|
||||
});
|
||||
}
|
||||
// If there is a success alert open with data, add it to the alertsList
|
||||
else if (successOpen && successData) {
|
||||
setSuccessOpen(false);
|
||||
setAlertsList((old) => {
|
||||
let newAlertsList = [
|
||||
...old,
|
||||
{ type: "success", data: _.cloneDeep(successData), id: _.uniqueId() },
|
||||
];
|
||||
return newAlertsList;
|
||||
});
|
||||
}
|
||||
}, [_, errorData, errorOpen, noticeData, noticeOpen, setErrorOpen, setNoticeOpen, setSuccessOpen, successData, successOpen]);
|
||||
|
||||
const removeAlert = (id: string) => {
|
||||
setAlertsList((prevAlertsList) =>
|
||||
|
|
|
|||
|
|
@ -73,52 +73,68 @@ export function AlertProvider({ children }:{children:ReactNode}) {
|
|||
return newNotificationList;
|
||||
});
|
||||
};
|
||||
function setErrorData(newState: { title: string; list?: Array<string> }) {
|
||||
setErrorDataState(newState);
|
||||
setErrorOpen(true);
|
||||
if (newState.title) {
|
||||
setNotificationCenter(true);
|
||||
pushNotificationList({
|
||||
type: "error",
|
||||
title: newState.title,
|
||||
list: newState.list,
|
||||
id: _.uniqueId(),
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Sets the error data state, opens the error dialog and pushes the new error notification to the notification list
|
||||
* @param newState An object containing the new error data, including title and optional list of error messages
|
||||
*/
|
||||
function setErrorData(newState: { title: string; list?: Array<string> }) {
|
||||
setErrorDataState(newState);
|
||||
setErrorOpen(true);
|
||||
if (newState.title) {
|
||||
setNotificationCenter(true);
|
||||
pushNotificationList({
|
||||
type: "error",
|
||||
title: newState.title,
|
||||
list: newState.list,
|
||||
id: _.uniqueId(),
|
||||
});
|
||||
}
|
||||
function setNoticeData(newState: { title: string; link?: string }) {
|
||||
setNoticeDataState(newState);
|
||||
setNoticeOpen(true);
|
||||
if (newState.title) {
|
||||
setNotificationCenter(true);
|
||||
pushNotificationList({
|
||||
type: "notice",
|
||||
title: newState.title,
|
||||
link: newState.link,
|
||||
id: _.uniqueId(),
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sets the state of the notice data and opens the notice modal, also adds a new notice to the notification center if the title is defined.
|
||||
* @param newState An object containing the title of the notice and optionally a link.
|
||||
*/
|
||||
function setNoticeData(newState: { title: string; link?: string }) {
|
||||
setNoticeDataState(newState);
|
||||
setNoticeOpen(true);
|
||||
if (newState.title) {
|
||||
// Add new notice to notification center
|
||||
setNotificationCenter(true);
|
||||
pushNotificationList({
|
||||
type: "notice",
|
||||
title: newState.title,
|
||||
link: newState.link,
|
||||
id: _.uniqueId(),
|
||||
});
|
||||
}
|
||||
function setSuccessData(newState: { title: string }) {
|
||||
setSuccessDataState(newState);
|
||||
setSuccessOpen(true);
|
||||
if (newState.title) {
|
||||
setNotificationCenter(true);
|
||||
pushNotificationList({
|
||||
type: "success",
|
||||
title: newState.title,
|
||||
id: _.uniqueId(),
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Update the success data state and show a success alert notification.
|
||||
* @param newState - A state object with a "title" property to set in the success data state.
|
||||
*/
|
||||
function setSuccessData(newState: { title: string }) {
|
||||
setSuccessDataState(newState); // update the success data state with the provided new state
|
||||
setSuccessOpen(true); // open the success alert
|
||||
|
||||
// If the new state has a "title" property, add a new success notification to the list
|
||||
if (newState.title) {
|
||||
setNotificationCenter(true); // show the notification center
|
||||
pushNotificationList({ // add the new notification to the list
|
||||
type: "success",
|
||||
title: newState.title,
|
||||
id: _.uniqueId(),
|
||||
});
|
||||
}
|
||||
}
|
||||
function clearNotificationList() {
|
||||
setNotificationList([]);
|
||||
}
|
||||
function removeFromNotificationList(index: string) {
|
||||
// set the notification list to a new array that filters out the alert with the matching id
|
||||
setNotificationList((prevAlertsList) =>
|
||||
prevAlertsList.filter((alert) => alert.id !== index)
|
||||
prevAlertsList.filter((alert) => alert.id !== index)
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<alertContext.Provider
|
||||
value={{
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
import { createContext, useEffect, useState, useRef, ReactNode } from "react";
|
||||
import {FlowType} from "../types/flow"
|
||||
import { FlowType } from "../types/flow";
|
||||
import { TabsContextType } from "../types/tabs";
|
||||
|
||||
|
||||
|
||||
const TabsContextInitialValue:TabsContextType = {
|
||||
const TabsContextInitialValue: TabsContextType = {
|
||||
tabIndex: 0,
|
||||
setTabIndex: (index: number) => {},
|
||||
flows: [],
|
||||
|
|
@ -20,7 +18,7 @@ export const TabsContext = createContext<TabsContextType>(
|
|||
TabsContextInitialValue
|
||||
);
|
||||
|
||||
export function TabsProvider({ children }:{children:ReactNode}) {
|
||||
export function TabsProvider({ children }: { children: ReactNode }) {
|
||||
const [tabIndex, setTabIndex] = useState(0);
|
||||
const [flows, setFlows] = useState<Array<FlowType>>([]);
|
||||
const [id, setId] = useState(0);
|
||||
|
|
@ -31,6 +29,7 @@ export function TabsProvider({ children }:{children:ReactNode}) {
|
|||
return newNodeId.current;
|
||||
}
|
||||
useEffect(() => {
|
||||
//save tabs locally
|
||||
if (flows.length !== 0)
|
||||
window.localStorage.setItem(
|
||||
"tabsData",
|
||||
|
|
@ -39,6 +38,7 @@ export function TabsProvider({ children }:{children:ReactNode}) {
|
|||
}, [flows, id, tabIndex, newNodeId]);
|
||||
|
||||
useEffect(() => {
|
||||
//get tabs locally saved
|
||||
let cookie = window.localStorage.getItem("tabsData");
|
||||
if (cookie) {
|
||||
let cookieObject = JSON.parse(cookie);
|
||||
|
|
@ -49,27 +49,47 @@ export function TabsProvider({ children }:{children:ReactNode}) {
|
|||
}
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Downloads the current flow as a JSON file
|
||||
*/
|
||||
function downloadFlow() {
|
||||
// create a data URI with the current flow data
|
||||
const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent(
|
||||
JSON.stringify(flows[tabIndex])
|
||||
)}`;
|
||||
|
||||
// create a link element and set its properties
|
||||
const link = document.createElement("a");
|
||||
link.href = jsonString;
|
||||
link.download = `${flows[tabIndex].name}.json`;
|
||||
|
||||
// simulate a click on the link element to trigger the download
|
||||
link.click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a file input and listens to a change event to upload a JSON flow file.
|
||||
* If the file type is application/json, the file is read and parsed into a JSON object.
|
||||
* The resulting JSON object is passed to the addFlow function.
|
||||
*/
|
||||
function uploadFlow() {
|
||||
// create a file input
|
||||
const input = document.createElement("input");
|
||||
input.type = "file";
|
||||
// add a change event listener to the file input
|
||||
input.onchange = (e: Event) => {
|
||||
// check if the file type is application/json
|
||||
if ((e.target as HTMLInputElement).files[0].type === "application/json") {
|
||||
// get the file from the file input
|
||||
const file = (e.target as HTMLInputElement).files[0];
|
||||
// read the file as text
|
||||
file.text().then((text) => {
|
||||
// parse the text into a JSON object
|
||||
addFlow(JSON.parse(text));
|
||||
});
|
||||
}
|
||||
};
|
||||
// trigger the file input click event to open the file dialog
|
||||
input.click();
|
||||
}
|
||||
/**
|
||||
|
|
@ -94,21 +114,38 @@ export function TabsProvider({ children }:{children:ReactNode}) {
|
|||
return newFlows;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Add a new flow to the list of flows.
|
||||
* @param flow Optional flow to add.
|
||||
*/
|
||||
function addFlow(flow?: FlowType) {
|
||||
// Get data from the flow or set it to null if there's no flow provided.
|
||||
const data = flow?.data ? flow.data : null;
|
||||
|
||||
// Create a new flow with a default name if no flow is provided.
|
||||
let newFlow: FlowType = {
|
||||
name: flow ? flow.name : "flow" + id,
|
||||
id: id.toString(),
|
||||
data,
|
||||
chat: flow ? flow.chat : [],
|
||||
};
|
||||
|
||||
// Increment the ID counter.
|
||||
setId((old) => old + 1);
|
||||
|
||||
// Add the new flow to the list of flows.
|
||||
setFlows((prevState) => {
|
||||
const newFlows = [...prevState, newFlow];
|
||||
return newFlows;
|
||||
});
|
||||
|
||||
// Set the tab index to the new flow.
|
||||
setTabIndex(flows.length);
|
||||
}
|
||||
/**
|
||||
* Updates an existing flow with new data
|
||||
* @param newFlow - The new flow object containing the updated data
|
||||
*/
|
||||
function updateFlow(newFlow: FlowType) {
|
||||
setFlows((prevState) => {
|
||||
const newFlows = [...prevState];
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import axios, { AxiosResponse } from "axios";
|
|||
const backendUrl = process.env.BACKEND || "http://localhost:5003";
|
||||
|
||||
export async function getAll():Promise<AxiosResponse<APIObjectType>> {
|
||||
return await axios.get(`${backendUrl}/all`);
|
||||
return await axios.get(`${backendUrl}/`);
|
||||
}
|
||||
|
||||
export async function sendAll(data:sendAllProps) {
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
export enum apiEnum
|
||||
{
|
||||
PromptTemplate="PromptTemplate"
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
import {
|
||||
HomeIcon,
|
||||
} from '@heroicons/react/24/outline'
|
||||
|
||||
|
||||
export const sidebarNavigation = [
|
||||
{ name: 'Home', href: '/', icon: HomeIcon, current: true },
|
||||
// { name: 'Table', href: '/table/', icon: TableCellsIcon, current: false },
|
||||
// //{ name: 'Train', href: '#', icon: BoltIcon, current: false },
|
||||
// //{ name: 'Model Details', href: '#', icon: LightBulbIcon, current: false },
|
||||
// //{ name: 'Deploy', href: '#', icon: RocketLaunchIcon, current: false },
|
||||
// { name: 'Settings', href: '/settings/', icon: Cog6ToothIcon, current: false },
|
||||
]
|
||||
|
|
@ -16,18 +16,26 @@ export default function ExtraSidebar() {
|
|||
|
||||
useEffect(() => {
|
||||
async function getTypes():Promise<void>{
|
||||
// Define an object with initial values for the types.
|
||||
const initialValue:{[char: string]: string} = {
|
||||
str: "advanced",
|
||||
bool: "advanced",
|
||||
chatOutput: "chat",
|
||||
}
|
||||
|
||||
// Make an asynchronous API call to retrieve all data.
|
||||
let result = await getAll();
|
||||
|
||||
// Update the state of the component with the retrieved data.
|
||||
setData(result.data);
|
||||
|
||||
// Set the types by reducing over the keys of the result data and updating the accumulator.
|
||||
setTypes(
|
||||
Object.keys(result.data).reduce(
|
||||
(acc, curr) => {
|
||||
Object.keys(result.data[curr]).forEach((c:keyof APIKindType) => {
|
||||
acc[c] = curr;
|
||||
// Add the base classes to the accumulator as well.
|
||||
result.data[curr][c].base_classes?.forEach((b) => {
|
||||
acc[b] = curr;
|
||||
});
|
||||
|
|
@ -38,11 +46,13 @@ export default function ExtraSidebar() {
|
|||
)
|
||||
);
|
||||
}
|
||||
// Call the getTypes function.
|
||||
getTypes();
|
||||
}, [setTypes]);
|
||||
|
||||
|
||||
function onDragStart(event: React.DragEvent<any>, data:{type:string,node?:APIClassType}) {
|
||||
//start drag event
|
||||
event.dataTransfer.effectAllowed = "move";
|
||||
event.dataTransfer.setData("json", JSON.stringify(data));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,10 +58,6 @@ export default function TabComponent({ selected, flow, onClick }:{flow:FlowType,
|
|||
>
|
||||
{flow.name}
|
||||
</span>
|
||||
{/* <ArrowDownTrayIcon
|
||||
onClick={() => downloadFlow()}
|
||||
className="w-4 h-4 hover:text-blue-500 cursor-pointer"
|
||||
/> */}
|
||||
</div>
|
||||
)}
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import FlowPage from "../..";
|
|||
export default function TabsManagerComponent() {
|
||||
const { flows, addFlow, tabIndex, setTabIndex } = useContext(TabsContext);
|
||||
useEffect(() => {
|
||||
//create the first flow
|
||||
if (flows.length === 0) {
|
||||
addFlow();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
|
|||
|
||||
const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
|
||||
const { setErrorData } = useContext(alertContext);
|
||||
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(
|
||||
flow.data?.nodes ?? []
|
||||
);
|
||||
|
|
@ -64,16 +63,15 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
|
|||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [nodes, edges]);
|
||||
|
||||
//update flow when tabs change
|
||||
useEffect(() => {
|
||||
console.log('oi')
|
||||
setNodes(flow?.data?.nodes ?? []);
|
||||
setEdges(flow?.data?.edges ?? []);
|
||||
if (reactFlowInstance) {
|
||||
setViewport(flow?.data?.viewport ?? { x: 1, y: 0, zoom: 1 });
|
||||
}
|
||||
}, [flow, reactFlowInstance, setEdges, setNodes, setViewport]);
|
||||
|
||||
//set extra sidebar
|
||||
useEffect(() => {
|
||||
setExtraComponent(<ExtraSidebar />);
|
||||
setExtraNavigation({ title: "Componets" });
|
||||
|
|
@ -111,24 +109,34 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
|
|||
const onDrop = useCallback(
|
||||
(event:React.DragEvent) => {
|
||||
event.preventDefault();
|
||||
|
||||
|
||||
// Helper function to generate a unique node ID
|
||||
function getId() {
|
||||
return `dndnode_` + incrementNodeId();
|
||||
}
|
||||
|
||||
|
||||
// Get the current bounds of the ReactFlow wrapper element
|
||||
const reactflowBounds = reactFlowWrapper.current.getBoundingClientRect();
|
||||
|
||||
// Extract the data from the drag event and parse it as a JSON object
|
||||
let data:{type:string,node?:APIClassType} = JSON.parse(event.dataTransfer.getData("json"));
|
||||
|
||||
// If data type is not "chatInput" or if there are no "chatInputNode" nodes present in the ReactFlow instance, create a new node
|
||||
if (
|
||||
data.type !== "chatInput" ||
|
||||
(data.type === "chatInput" &&
|
||||
!reactFlowInstance.getNodes().some((n) => n.type === "chatInputNode"))
|
||||
) {
|
||||
// Calculate the position where the node should be created
|
||||
const position = reactFlowInstance.project({
|
||||
x: event.clientX - reactflowBounds.left,
|
||||
y: event.clientY - reactflowBounds.top,
|
||||
});
|
||||
|
||||
// Generate a unique node ID
|
||||
let newId = getId();
|
||||
|
||||
|
||||
// Create a new node object
|
||||
const newNode:NodeType = {
|
||||
id: newId,
|
||||
type:
|
||||
|
|
@ -146,16 +154,21 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
|
|||
value: null,
|
||||
},
|
||||
};
|
||||
|
||||
// Add the new node to the list of nodes in state
|
||||
setNodes((nds) => nds.concat(newNode));
|
||||
} else {
|
||||
// If a chat input node already exists, set an error message
|
||||
setErrorData({
|
||||
title: "Error creating node",
|
||||
list: ["There can't be more than one chat input."],
|
||||
});
|
||||
}
|
||||
},
|
||||
// Specify dependencies for useCallback
|
||||
[incrementNodeId, reactFlowInstance, setErrorData, setNodes]
|
||||
);
|
||||
|
||||
|
||||
return (
|
||||
<div className="w-full h-full" ref={reactFlowWrapper}>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue