Refactor ImportModal code to use useState and useContext hooks

This commit refactors the code for the ImportModal component to use hooks like useState and useContext, resulting in improved readability and maintainability. It also adds functionality to load prebuilt examples and handle local file uploads.
This commit is contained in:
Gabriel Almeida 2023-04-25 11:02:09 -03:00 • committed by Gabriel Luiz Freitas Almeida
commit c522727d6e

View file

@ -1,11 +1,11 @@
import { Dialog, Transition } from "@headlessui/react"; import { Dialog, Transition } from "@headlessui/react";
import { import {
XMarkIcon, XMarkIcon,
ArrowDownTrayIcon, ArrowDownTrayIcon,
DocumentDuplicateIcon, DocumentDuplicateIcon,
ComputerDesktopIcon, ComputerDesktopIcon,
ArrowUpTrayIcon, ArrowUpTrayIcon,
ArrowLeftIcon, ArrowLeftIcon,
} from "@heroicons/react/24/outline"; } from "@heroicons/react/24/outline";
import { Fragment, useContext, useRef, useState } from "react"; import { Fragment, useContext, useRef, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext"; import { PopUpContext } from "../../contexts/popUpContext";
@ -19,211 +19,214 @@ import { FlowType } from "../../types/flow";
import { classNames } from "../../utils"; import { classNames } from "../../utils";
export default function ImportModal() { export default function ImportModal() {
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
const { setErrorData } = useContext(alertContext); const { setErrorData } = useContext(alertContext);
const { closePopUp } = useContext(PopUpContext); const { closePopUp } = useContext(PopUpContext);
const ref = useRef(); const ref = useRef();
const [showExamples, setShowExamples] = useState(false); const [showExamples, setShowExamples] = useState(false);
const [loadingExamples, setLoadingExamples] = useState(false); const [loadingExamples, setLoadingExamples] = useState(false);
const [examples, setExamples] = useState<FlowType[]>([]); const [examples, setExamples] = useState<FlowType[]>([]);
const { uploadFlow, addFlow } = useContext(TabsContext); const { uploadFlow, addFlow } = useContext(TabsContext);
function setModalOpen(x: boolean) { function setModalOpen(x: boolean) {
setOpen(x); setOpen(x);
if (x === false) { if (x === false) {
setTimeout(() => { setTimeout(() => {
closePopUp(); closePopUp();
}, 300); }, 300);
} }
} }
function handleExamples() { function handleExamples() {
setLoadingExamples(true); setLoadingExamples(true);
getExamples() getExamples()
.then((result) => { .then((result) => {
setLoadingExamples(false); setLoadingExamples(false);
setExamples(result); setExamples(result);
}) })
.catch((error) => .catch((error) =>
setErrorData({ setErrorData({
title: "there was an error loading examples, please try again", title: "there was an error loading examples, please try again",
list: [error.message], list: [error.message],
}) })
); );
} }
return ( return (
<Transition.Root show={open} appear={true} as={Fragment}> <Transition.Root show={open} appear={true} as={Fragment}>
<Dialog <Dialog
as="div" as="div"
className="relative z-10" className="relative z-10"
onClose={setModalOpen} onClose={setModalOpen}
initialFocus={ref} initialFocus={ref}
> >
<Transition.Child <Transition.Child
as={Fragment} as={Fragment}
enter="ease-out duration-300" enter="ease-out duration-300"
enterFrom="opacity-0" enterFrom="opacity-0"
enterTo="opacity-100" enterTo="opacity-100"
leave="ease-in duration-200" leave="ease-in duration-200"
leaveFrom="opacity-100" leaveFrom="opacity-100"
leaveTo="opacity-0" leaveTo="opacity-0"
> >
<div className="fixed inset-0 bg-gray-500 dark:bg-gray-600 dark:bg-opacity-75 bg-opacity-75 transition-opacity" /> <div className="fixed inset-0 bg-gray-500 dark:bg-gray-600 dark:bg-opacity-75 bg-opacity-75 transition-opacity" />
</Transition.Child> </Transition.Child>
<div className="fixed inset-0 z-10 overflow-y-auto"> <div className="fixed inset-0 z-10 overflow-y-auto">
<div className="flex h-full items-end justify-center p-4 text-center sm:items-center sm:p-0"> <div className="flex h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<Transition.Child <Transition.Child
as={Fragment} as={Fragment}
enter="ease-out duration-300" enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100" enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200" leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100" leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
> >
<Dialog.Panel className="relative flex flex-col justify-between transform h-[600px] overflow-hidden rounded-lg bg-white dark:bg-gray-800 text-left shadow-xl transition-all sm:my-8 w-[700px]"> <Dialog.Panel className="relative flex flex-col justify-between transform h-[600px] overflow-hidden rounded-lg bg-white dark:bg-gray-800 text-left shadow-xl transition-all sm:my-8 w-[700px]">
<div className=" z-50 absolute top-0 right-0 hidden pt-4 pr-4 sm:block"> <div className=" z-50 absolute top-0 right-0 hidden pt-4 pr-4 sm:block">
<button <button
type="button" type="button"
className="rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2" className="rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
onClick={() => { onClick={() => {
setModalOpen(false); setModalOpen(false);
}} }}
> >
<span className="sr-only">Close</span> <span className="sr-only">Close</span>
<XMarkIcon className="h-6 w-6" aria-hidden="true" /> <XMarkIcon className="h-6 w-6" aria-hidden="true" />
</button> </button>
</div> </div>
{showExamples && ( {showExamples && (
<> <>
<div className="z-50 absolute top-2 left-0 hidden pt-4 pl-4 sm:block"> <div className="z-50 absolute top-2 left-0 hidden pt-4 pl-4 sm:block">
<button <button
type="button" type="button"
className="rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2" className="rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
onClick={() => { onClick={() => {
setShowExamples(false); setShowExamples(false);
}} }}
> >
<span className="sr-only">Close</span> <span className="sr-only">Close</span>
<ArrowLeftIcon className="h-6 w-6" aria-hidden="true" /> <ArrowLeftIcon className="h-6 w-6" aria-hidden="true" />
</button> </button>
</div> </div>
<div className="z-50 absolute bottom-2 left-0 hidden pt-4 pl-2 sm:block"> <div className="z-50 absolute bottom-2 left-1/2 transform -translate-x-1/2 hidden pt-4 pl-2 sm:block text-center">
<a <a
href="https://github.com/logspace-ai/langflow_examples" href="https://github.com/logspace-ai/langflow_examples"
target="_blank" target="_blank"
> className="flex items-center justify-center"
<svg rel="noreferrer"
width="24" >
viewBox="0 0 98 96" <svg
xmlns="http://www.w3.org/2000/svg" width="24"
> viewBox="0 0 98 96"
<path xmlns="http://www.w3.org/2000/svg"
fill-rule="evenodd" >
clip-rule="evenodd" <path
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill-rule="evenodd"
fill="#24292f" clip-rule="evenodd"
/> d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"
</svg> fill="#24292f"
</a> />
</div> </svg>
</> <span className="ml-2">LangFlow Examples</span>
)} </a>
<div className="h-full w-full flex flex-col justify-center items-center"> </div>
<div className="flex w-full pb-4 z-10 justify-center shadow-sm"> </>
<div className="mx-auto mt-4 flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-blue-100 dark:bg-gray-900 sm:mx-0 sm:h-10 sm:w-10"> )}
<ArrowUpTrayIcon <div className="h-full w-full flex flex-col justify-center items-center">
className="h-6 w-6 text-blue-600" <div className="flex w-full pb-4 z-10 justify-center shadow-sm">
aria-hidden="true" <div className="mx-auto mt-4 flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-blue-100 dark:bg-gray-900 sm:mx-0 sm:h-10 sm:w-10">
/> <ArrowUpTrayIcon
</div> className="h-6 w-6 text-blue-600"
<div className="mt-4 text-center sm:ml-4 sm:text-left"> aria-hidden="true"
<Dialog.Title />
as="h3" </div>
className="text-lg font-medium dark:text-white leading-10 text-gray-900" <div className="mt-4 text-center sm:ml-4 sm:text-left">
> <Dialog.Title
{showExamples ?"Select an example":"Import from"} as="h3"
</Dialog.Title> className="text-lg font-medium dark:text-white leading-10 text-gray-900"
</div> >
</div> {showExamples ? "Select an example" : "Import from"}
<div </Dialog.Title>
className={classNames( </div>
"h-full w-full bg-gray-200 dark:bg-gray-900 gap-4", </div>
showExamples && !loadingExamples <div
? "flex flex-row start justify-start items-start p-9 flex-wrap overflow-auto" className={classNames(
: "flex flex-row justify-center items-center p-4" "h-full w-full bg-gray-200 dark:bg-gray-900 gap-4",
)} showExamples && !loadingExamples
> ? "flex flex-row start justify-start items-start p-9 flex-wrap overflow-auto"
{!showExamples && ( : "flex flex-row justify-center items-center p-4"
<div className="flex h-full w-full justify-evenly items-center"> )}
<ButtonBox >
size="big" {!showExamples && (
bgColor="bg-emerald-500" <div className="flex h-full w-full justify-evenly items-center">
description="Prebuilt Examples" <ButtonBox
icon={ size="big"
<DocumentDuplicateIcon className="h-10 w-10 flex-shrink-0" /> bgColor="bg-emerald-500"
} description="Prebuilt Examples"
onClick={() => { icon={
setShowExamples(true); <DocumentDuplicateIcon className="h-10 w-10 flex-shrink-0" />
handleExamples(); }
}} onClick={() => {
textColor="text-emerald-400" setShowExamples(true);
title="Examples" handleExamples();
></ButtonBox> }}
<ButtonBox textColor="text-emerald-400"
size="big" title="Examples"
bgColor="bg-blue-500" ></ButtonBox>
description="Import from Local" <ButtonBox
icon={ size="big"
<ComputerDesktopIcon className="h-10 w-10 flex-shrink-0" /> bgColor="bg-blue-500"
} description="Import from Local"
onClick={() => { icon={
uploadFlow(); <ComputerDesktopIcon className="h-10 w-10 flex-shrink-0" />
setModalOpen(false); }
}} onClick={() => {
textColor="text-blue-500" uploadFlow();
title="Local file" setModalOpen(false);
></ButtonBox> }}
</div> textColor="text-blue-500"
)} title="Local file"
{showExamples && loadingExamples && ( ></ButtonBox>
<div className="flex align-middle justify-center items-center"> </div>
<LoadingComponent remSize={30} /> )}
</div> {showExamples && loadingExamples && (
)} <div className="flex align-middle justify-center items-center">
{showExamples && <LoadingComponent remSize={30} />
!loadingExamples && </div>
examples.map((example, index) => { )}
return ( {showExamples &&
<div id="index"> !loadingExamples &&
{" "} examples.map((example, index) => {
<ButtonBox return (
size="small" <div id="index">
bgColor="bg-emerald-500" {" "}
description={ <ButtonBox
example.description ?? "Prebuilt Examples" size="small"
} bgColor="bg-emerald-500"
icon={ description={
<DocumentDuplicateIcon className="h-6 w-6 flex-shrink-0" /> example.description ?? "Prebuilt Examples"
} }
onClick={() => { icon={
addFlow(example); <DocumentDuplicateIcon className="h-6 w-6 flex-shrink-0" />
setModalOpen(false); }
}} onClick={() => {
textColor="text-emerald-400" addFlow(example);
title={example.name} setModalOpen(false);
></ButtonBox> }}
</div> textColor="text-emerald-400"
); title={example.name}
})} ></ButtonBox>
</div> </div>
</div> );
</Dialog.Panel> })}
</Transition.Child> </div>
</div> </div>
</div> </Dialog.Panel>
</Dialog> </Transition.Child>
</Transition.Root> </div>
); </div>
</Dialog>
</Transition.Root>
);
} }