Merge dev

This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-08-17 10:59:54 -03:00
commit 39e25c294c
14 changed files with 130 additions and 86 deletions

View file

@ -9,6 +9,7 @@ import ErrorAlert from "./alerts/error";
import NoticeAlert from "./alerts/notice"; import NoticeAlert from "./alerts/notice";
import SuccessAlert from "./alerts/success"; import SuccessAlert from "./alerts/success";
import CrashErrorComponent from "./components/CrashErrorComponent"; import CrashErrorComponent from "./components/CrashErrorComponent";
import LoadingComponent from "./components/loadingComponent";
import { alertContext } from "./contexts/alertContext"; import { alertContext } from "./contexts/alertContext";
import { locationContext } from "./contexts/locationContext"; import { locationContext } from "./contexts/locationContext";
import { TabsContext } from "./contexts/tabsContext"; import { TabsContext } from "./contexts/tabsContext";
@ -47,10 +48,6 @@ export default function App() {
}> }>
>([]); >([]);
const isLoginPage = location.pathname.includes("login");
const isAdminPage = location.pathname.includes("admin");
const isSignUpPage = location.pathname.includes("signup");
// Use effect hook to update alertsList when a new alert is added // Use effect hook to update alertsList when a new alert is added
useEffect(() => { useEffect(() => {
// If there is an error alert open with data, add it to the alertsList // If there is an error alert open with data, add it to the alertsList
@ -138,8 +135,15 @@ export default function App() {
}} }}
FallbackComponent={CrashErrorComponent} FallbackComponent={CrashErrorComponent}
> >
{!isLoginPage && !isSignUpPage && <Header />} {loading ? (
<div className="loading-page-panel">
<LoadingComponent remSize={50} />
</div>
) : (
<>
<Router /> <Router />
</>
)}
</ErrorBoundary> </ErrorBoundary>
<div></div> <div></div>
<div className="app-div" style={{ zIndex: 999 }}> <div className="app-div" style={{ zIndex: 999 }}>

View file

@ -34,6 +34,13 @@ export const EditFlowSettings: React.FC<InputProps> = ({
} else { } else {
setIsMaxLength(false); setIsMaxLength(false);
} }
if (invalidName !== undefined) {
if (!nameLists.current.includes(value)) {
setInvalidName(false);
} else {
setInvalidName(true);
}
}
if (!nameLists.current.includes(value)) { if (!nameLists.current.includes(value)) {
setInvalidName!(false); setInvalidName!(false);
} else { } else {
@ -43,13 +50,18 @@ export const EditFlowSettings: React.FC<InputProps> = ({
setCurrentName(value); setCurrentName(value);
}; };
const [desc, setDesc] = useState( const [currentName, setCurrentName] = useState(name);
flows.find((flow) => flow.id === tabId)?.description
); const [currentDescription, setCurrentDescription] = useState(description);
useEffect(() => {
setCurrentName(name);
setCurrentDescription(description);
}, [name, description]);
const handleDescriptionChange = (event: ChangeEvent<HTMLTextAreaElement>) => { const handleDescriptionChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
flows.find((flow) => flow.id === tabId)!.description = event.target.value; flows.find((f) => f.id === tabId).description = event.target.value;
setDesc(flows.find((flow) => flow.id === tabId)?.description); setCurrentDescription(flows.find((f) => f.id === tabId).description);
setDescription(event.target.value); setDescription(event.target.value);
}; };

View file

@ -1,6 +1,7 @@
import * as Form from "@radix-ui/react-form"; import * as Form from "@radix-ui/react-form";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { InputComponentType } from "../../types/components"; import { InputComponentType } from "../../types/components";
import { handleKeyDown } from "../../utils/reactflowUtils";
import { classNames } from "../../utils/utils"; import { classNames } from "../../utils/utils";
import { Input } from "../ui/input"; import { Input } from "../ui/input";
@ -45,6 +46,9 @@ export default function InputComponent({
onChange={(e) => { onChange={(e) => {
onChange(e.target.value); onChange(e.target.value);
}} }}
onKeyDown={(e) => {
handleKeyDown(e, value, "");
}}
/> />
</Form.Control> </Form.Control>
) : ( ) : (
@ -65,6 +69,9 @@ export default function InputComponent({
onChange={(e) => { onChange={(e) => {
onChange(e.target.value); onChange(e.target.value);
}} }}
onKeyDown={(e) => {
handleKeyDown(e, value, "");
}}
/> />
)} )}
{password && ( {password && (

View file

@ -509,6 +509,9 @@ export const URL_EXCLUDED_FROM_ERROR_RETRIES = [
"/api/v1/custom_component", "/api/v1/custom_component",
"/api/v1/validate/prompt", "/api/v1/validate/prompt",
]; ];
export const skipNodeUpdate = ["CustomComponent"];
export const CONTROL_INPUT_STATE = { export const CONTROL_INPUT_STATE = {
password: "", password: "",
cnfPassword: "", cnfPassword: "",

View file

@ -1,4 +1,10 @@
import { createContext, ReactNode, useEffect, useState } from "react"; import {
createContext,
ReactNode,
useContext,
useEffect,
useState,
} from "react";
import { Node, ReactFlowInstance } from "reactflow"; import { Node, ReactFlowInstance } from "reactflow";
import { getAll } from "../controllers/API"; import { getAll } from "../controllers/API";
import { APIKindType } from "../types/api"; import { APIKindType } from "../types/api";

View file

@ -1,4 +1,4 @@
import { ReactNode, forwardRef, useContext, useState } from "react"; import { ReactNode, forwardRef, useContext, useEffect, useState } from "react";
import EditFlowSettings from "../../components/EditFlowSettingsComponent"; import EditFlowSettings from "../../components/EditFlowSettingsComponent";
import IconComponent from "../../components/genericIconComponent"; import IconComponent from "../../components/genericIconComponent";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
@ -10,17 +10,17 @@ import BaseModal from "../baseModal";
const ExportModal = forwardRef( const ExportModal = forwardRef(
(props: { children: ReactNode }, ref): JSX.Element => { (props: { children: ReactNode }, ref): JSX.Element => {
const { flows, tabId, updateFlow, downloadFlow, saveFlow } = const { flows, tabId, updateFlow, downloadFlow } = useContext(TabsContext);
useContext(TabsContext);
const [checked, setChecked] = useState(false); const [checked, setChecked] = useState(false);
const [name, setName] = useState( const flow = flows.find((f) => f.id === tabId);
flows.find((flow) => flow.id === tabId)?.name useEffect(() => {
); setName(flow.name);
const [invalidName, setInvalidName] = useState(false); setDescription(flow.description);
const [description, setDescription] = useState( }, [flow.name, flow.description]);
flows.find((flow) => flow.id === tabId)?.description const [name, setName] = useState(flow.name);
); const [description, setDescription] = useState(flow.description);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
return ( return (
<BaseModal size="smaller" open={open} setOpen={setOpen}> <BaseModal size="smaller" open={open} setOpen={setOpen}>
<BaseModal.Trigger>{props.children}</BaseModal.Trigger> <BaseModal.Trigger>{props.children}</BaseModal.Trigger>
@ -34,19 +34,18 @@ const ExportModal = forwardRef(
</BaseModal.Header> </BaseModal.Header>
<BaseModal.Content> <BaseModal.Content>
<EditFlowSettings <EditFlowSettings
invalidName={invalidName} name={name}
setInvalidName={setInvalidName} description={description}
name={name!}
description={description!}
flows={flows} flows={flows}
tabId={tabId} tabId={tabId}
setName={setName} setName={setName}
setDescription={setDescription} setDescription={setDescription}
updateFlow={updateFlow}
/> />
<div className="mt-3 flex items-center space-x-2"> <div className="mt-3 flex items-center space-x-2">
<Checkbox <Checkbox
id="terms" id="terms"
onCheckedChange={(event: boolean): void => { onCheckedChange={(event: boolean) => {
setChecked(event); setChecked(event);
}} }}
/> />

View file

@ -1,4 +1,4 @@
import { useContext, useState } from "react"; import { useContext, useEffect, useState } from "react";
import EditFlowSettings from "../../components/EditFlowSettingsComponent"; import EditFlowSettings from "../../components/EditFlowSettingsComponent";
import IconComponent from "../../components/genericIconComponent"; import IconComponent from "../../components/genericIconComponent";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
@ -12,16 +12,15 @@ export default function FlowSettingsModal({
open, open,
setOpen, setOpen,
}: FlowSettingsPropsType): JSX.Element { }: FlowSettingsPropsType): JSX.Element {
const { setErrorData, setSuccessData } = useContext(alertContext); const { setSuccessData } = useContext(alertContext);
const ref = useRef();
const { flows, tabId, updateFlow, saveFlow } = useContext(TabsContext); const { flows, tabId, updateFlow, saveFlow } = useContext(TabsContext);
const maxLength = 50; const flow = flows.find((f) => f.id === tabId);
const [name, setName] = useState( useEffect(() => {
flows.find((flow) => flow.id === tabId)!.name setName(flow.name);
); setDescription(flow.description);
const [description, setDescription] = useState( }, [flow.name, flow.description]);
flows.find((flow) => flow.id === tabId)!.description const [name, setName] = useState(flow.name);
); const [description, setDescription] = useState(flow.description);
const [invalidName, setInvalidName] = useState(false); const [invalidName, setInvalidName] = useState(false);
function handleClick(): void { function handleClick(): void {

View file

@ -16,6 +16,7 @@ import { TypeModal } from "../../constants/enums";
import { alertContext } from "../../contexts/alertContext"; import { alertContext } from "../../contexts/alertContext";
import { postValidatePrompt } from "../../controllers/API"; import { postValidatePrompt } from "../../controllers/API";
import { genericModalPropsType } from "../../types/components"; import { genericModalPropsType } from "../../types/components";
import { handleKeyDown } from "../../utils/reactflowUtils";
import { import {
classNames, classNames,
getRandomKeyByssmm, getRandomKeyByssmm,

View file

@ -44,7 +44,13 @@ const nodeTypes = {
genericNode: GenericNode, genericNode: GenericNode,
}; };
export default function Page({ flow }: { flow: FlowType }): JSX.Element { export default function Page({
flow,
view,
}: {
flow: FlowType;
view?: boolean;
}): JSX.Element {
let { let {
updateFlow, updateFlow,
uploadFlow, uploadFlow,
@ -424,7 +430,9 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element {
></Controls> ></Controls>
)} )}
</ReactFlow> </ReactFlow>
{!view && (
<Chat flow={flow} reactFlowInstance={reactFlowInstance!} /> <Chat flow={flow} reactFlowInstance={reactFlowInstance!} />
)}
</div> </div>
) : ( ) : (
<></> <></>

View file

@ -1,5 +1,6 @@
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import Header from "../../components/headerComponent";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import { getVersion } from "../../controllers/API"; import { getVersion } from "../../controllers/API";
import Page from "./components/PageComponent"; import Page from "./components/PageComponent";
@ -22,6 +23,8 @@ export default function FlowPage(): JSX.Element {
}, []); }, []);
return ( return (
<>
<Header />
<div className="flow-page-positioning"> <div className="flow-page-positioning">
{flows.length > 0 && {flows.length > 0 &&
tabId !== "" && tabId !== "" &&
@ -37,5 +40,6 @@ export default function FlowPage(): JSX.Element {
<div className={version ? "mt-2" : "mt-1"}>Created by Logspace</div> <div className={version ? "mt-2" : "mt-1"}>Created by Logspace</div>
</a> </a>
</div> </div>
</>
); );
} }

View file

@ -1,5 +1,6 @@
import { useContext, useEffect } from "react"; import { useContext, useEffect } from "react";
import { useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import { CardComponent } from "../../components/cardComponent";
import IconComponent from "../../components/genericIconComponent"; import IconComponent from "../../components/genericIconComponent";
import Header from "../../components/headerComponent"; import Header from "../../components/headerComponent";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
@ -47,7 +48,7 @@ export default function HomePage(): JSX.Element {
<Button <Button
variant="primary" variant="primary"
onClick={() => { onClick={() => {
addFlow(null, true).then((id) => { addFlow(null!, true).then((id) => {
navigate("/flow/" + id); navigate("/flow/" + id);
}); });
}} }}
@ -60,36 +61,32 @@ export default function HomePage(): JSX.Element {
<span className="main-page-description-text"> <span className="main-page-description-text">
Manage your personal projects. Download or upload your collection. Manage your personal projects. Download or upload your collection.
</span> </span>
<div className="button-div-style"> <div className="main-page-flows-display">
{flows.map((flow, idx) => (
<CardComponent
key={idx}
flow={flow}
id={flow.id}
button={
<Link to={"/flow/" + flow.id}>
<Button <Button
variant="primary" variant="outline"
onClick={() => { size="sm"
downloadFlows(); className="whitespace-nowrap "
}}
> >
<IconComponent name="Download" className="main-page-nav-button" /> <IconComponent
Download Collection name="ExternalLink"
className="main-page-nav-button"
/>
Edit Flow
</Button> </Button>
<Button </Link>
variant="primary" }
onClick={() => { onDelete={() => {
uploadFlows(); removeFlow(flow.id);
}} }}
> />
<IconComponent name="Upload" className="main-page-nav-button" /> ))}
Upload Collection
</Button>
<Button
variant="primary"
onClick={() => {
addFlow(null!, true).then((id) => {
navigate("/flow/" + id);
});
}}
>
<IconComponent name="Plus" className="main-page-nav-button" />
New Project
</Button>
</div> </div>
</div> </div>
</> </>

View file

@ -4,6 +4,7 @@ import LoginAdminPage from "./pages/AdminPage/LoginPage";
import CommunityPage from "./pages/CommunityPage"; import CommunityPage from "./pages/CommunityPage";
import FlowPage from "./pages/FlowPage"; import FlowPage from "./pages/FlowPage";
import HomePage from "./pages/MainPage"; import HomePage from "./pages/MainPage";
import ViewPage from "./pages/ViewPage";
import DeleteAccountPage from "./pages/deleteAccountPage"; import DeleteAccountPage from "./pages/deleteAccountPage";
import LoginPage from "./pages/loginPage"; import LoginPage from "./pages/loginPage";

View file

@ -37,6 +37,8 @@ export type alertContextType = {
pushNotificationList: (Object: AlertItemType) => void; pushNotificationList: (Object: AlertItemType) => void;
clearNotificationList: () => void; clearNotificationList: () => void;
removeFromNotificationList: (index: string) => void; removeFromNotificationList: (index: string) => void;
loading: boolean;
setLoading: (newState: boolean) => void;
}; };
export type darkContextType = { export type darkContextType = {

View file

@ -5,6 +5,7 @@ import {
ReactFlowInstance, ReactFlowInstance,
ReactFlowJsonObject, ReactFlowJsonObject,
} from "reactflow"; } from "reactflow";
import { specialCharsRegex } from "../constants/constants";
import { APITemplateType } from "../types/api"; import { APITemplateType } from "../types/api";
import { FlowType, NodeType } from "../types/flow"; import { FlowType, NodeType } from "../types/flow";
import { cleanEdgesType } from "../types/utils/reactflowUtils"; import { cleanEdgesType } from "../types/utils/reactflowUtils";