Adding progress bar on build

This commit is contained in:
Cristhian Zanforlin Lousa 2023-06-19 22:45:55 -03:00
commit 625f22c024
10 changed files with 4733 additions and 7420 deletions

File diff suppressed because it is too large Load diff

View file

@ -8,15 +8,16 @@
"@headlessui/react": "^1.7.10",
"@heroicons/react": "^2.0.15",
"@mui/material": "^5.11.9",
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-menubar": "^1.0.3",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.4",
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-menubar": "^1.0.3",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.6",
"@tabler/icons-react": "^2.18.0",
"@tailwindcss/forms": "^0.5.3",

View file

@ -0,0 +1,21 @@
import { ReactElement, useContext, useEffect, useRef, useState } from "react";
import { ProgressBarType } from "../../types/components";
import { Progress } from "../../components/ui/progress";
import { progressContext } from "../../contexts/ProgressContext";
import { setInterval } from "timers/promises";
export default function ProgressBarComponent({
value,
children,
}: ProgressBarType) {
const ref = useRef(0);
const reff = useRef();
const { progress } = useContext(progressContext);
useEffect(() => {
ref.current = progress * 100;
console.log(progress);
}, [progress]);
return <Progress className="h-2.5" value={ref.current} />;
}

View file

@ -1,4 +1,4 @@
import { useContext } from "react";
import { useContext, useEffect, useRef, useState } from "react";
import { Transition } from "@headlessui/react";
import { Zap } from "lucide-react";
import { validateNodes } from "../../../utils";
@ -8,6 +8,11 @@ import { useSSE } from "../../../contexts/SSEContext";
import { typesContext } from "../../../contexts/typesContext";
import { alertContext } from "../../../contexts/alertContext";
import { postBuildInit } from "../../../controllers/API";
import ProgressBarComponent from "../../ProgressBarComponent";
import {
progressContext,
useProgress,
} from "../../../contexts/ProgressContext";
export default function BuildTrigger({
open,
@ -20,9 +25,11 @@ export default function BuildTrigger({
setIsBuilt: any;
isBuilt: boolean;
}) {
const { updateSSEData, isBuilding, setIsBuilding } = useSSE();
const { updateSSEData, isBuilding, setIsBuilding, sseData } = useSSE();
const { setProgress } = useContext(progressContext);
const { reactFlowInstance } = useContext(typesContext);
const { setErrorData, setSuccessData } = useContext(alertContext);
const [isIconTouched, setIsIconTouched] = useState(false);
async function handleBuild(flow: FlowType) {
try {
@ -63,7 +70,7 @@ export default function BuildTrigger({
// Step 1: Make a POST request to send the flow data and receive a unique session ID
const response = await postBuildInit(flow);
const { flowId } = response.data;
let loadProgress = [];
// Step 2: Use the session ID to establish an SSE connection using EventSource
let validationResults = [];
let finished = false;
@ -79,13 +86,15 @@ export default function BuildTrigger({
// if the event is the end of the stream, close the connection
if (parsedData.end_of_stream) {
eventSource.close();
return;
} else if (parsedData.log) {
// If the event is a log, log it
// TODO: implement the progress
setSuccessData({ title: parsedData.log });
setSuccessData({ title: parsedData.progress });
setProgress(parsedData.progress);
loadProgress.push(parsedData.progress);
} else {
// Otherwise, process the data
const isValid = processStreamResult(parsedData);
@ -129,6 +138,14 @@ export default function BuildTrigger({
}
}
const handleMouseEnter = () => {
setIsIconTouched(true);
};
const handleMouseLeave = () => {
setIsIconTouched(false);
};
return (
<Transition
show={!open}
@ -141,12 +158,20 @@ export default function BuildTrigger({
leaveTo="translate-y-96"
>
<div className={`fixed right-4` + (isBuilt ? " bottom-20" : " bottom-4")}>
<div className="mb-2">
{isIconTouched && isBuilding && (
<ProgressBarComponent></ProgressBarComponent>
)}
</div>
<div
className="flex justify-center align-center py-1 px-3 w-12 h-12 rounded-full shadow-md shadow-[#0000002a] hover:shadow-[#00000032]
bg-[#E2E7EE] dark:border-gray-600 cursor-pointer"
onClick={() => {
handleBuild(flow);
}}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<button>
<div className="flex gap-3 items-center">

View file

@ -69,34 +69,34 @@ export default function Header() {
</div>
<div className="flex justify-end px-2 w-96">
<div className="ml-auto mr-2 flex gap-5 items-center">
<a
href="https://github.com/logspace-ai/langflow"
target="_blank"
rel="noreferrer"
className="inline-flex items-center justify-center text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background text-gray-600 dark:text-gray-300 border border-input hover:bg-accent hover:text-accent-foreground h-9 px-3 pr-0 rounded-md"
>
<FaGithub className="h-5 w-5 mr-2" />
Star
<div className="ml-2 flex text-sm bg-background rounded-md rounded-l-none border px-2 h-9 -mr-px items-center justify-center">
{stars}
</div>
</a>
<a
href="https://twitter.com/logspace_ai"
target="_blank"
rel="noreferrer"
className="text-muted-foreground"
>
<FaTwitter className="h-5 w-5" />
</a>
<a
href="https://discord.gg/EqksyE2EX9"
target="_blank"
rel="noreferrer"
className="text-muted-foreground"
>
<FaDiscord className="h-5 w-5" />
</a>
<a
href="https://github.com/logspace-ai/langflow"
target="_blank"
rel="noreferrer"
className="inline-flex items-center justify-center text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background text-gray-600 dark:text-gray-300 border border-input hover:bg-accent hover:text-accent-foreground h-9 px-3 pr-0 rounded-md"
>
<FaGithub className="h-5 w-5 mr-2" />
Star
<div className="ml-2 flex text-sm bg-background rounded-md rounded-l-none border px-2 h-9 -mr-px items-center justify-center">
{stars}
</div>
</a>
<a
href="https://twitter.com/logspace_ai"
target="_blank"
rel="noreferrer"
className="text-muted-foreground"
>
<FaTwitter className="h-5 w-5" />
</a>
<a
href="https://discord.gg/EqksyE2EX9"
target="_blank"
rel="noreferrer"
className="text-muted-foreground"
>
<FaDiscord className="h-5 w-5" />
</a>
{/* <button
className="text-gray-600 hover:text-gray-500 dark:text-gray-300 dark:hover:text-gray-200"
onClick={() => {

View file

@ -0,0 +1,27 @@
"use client";
import * as React from "react";
import * as ProgressPrimitive from "@radix-ui/react-progress";
import { cn } from "../../utils";
const Progress = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
>(({ className, value, ...props }, ref) => (
<ProgressPrimitive.Root
ref={ref}
className={cn(
"relative h-4 w-full overflow-hidden rounded-full bg-secondary",
className
)}
{...props}
>
<ProgressPrimitive.Indicator
className="h-full w-full flex-1 bg-primary transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>
));
Progress.displayName = ProgressPrimitive.Root.displayName;
export { Progress };

View file

@ -0,0 +1,30 @@
import { createContext, useContext, useState } from "react";
import _ from "lodash";
//types for progressContext
type progressContextType = {
setProgress: (newState: number) => void;
progress: number;
};
const initialValue = {
setProgress: () => {},
progress: 0,
};
export const progressContext = createContext<progressContextType>(initialValue);
export function useProgress() {
return useContext(progressContext);
}
export function ProgressProvider({ children }) {
const [progress, setProgress] = useState(0);
return (
<progressContext.Provider
value={{
setProgress,
progress,
}}
>
{children}
</progressContext.Provider>
);
}

View file

@ -8,6 +8,7 @@ import { TypesProvider } from "./typesContext";
import { ReactFlowProvider } from "reactflow";
import { UndoRedoProvider } from "./undoRedoContext";
import { SSEProvider } from "./SSEContext";
import { ProgressProvider } from "./ProgressContext";
export default function ContextWrapper({ children }: { children: ReactNode }) {
//element to wrap all context
@ -21,7 +22,9 @@ export default function ContextWrapper({ children }: { children: ReactNode }) {
<SSEProvider>
<TabsProvider>
<UndoRedoProvider>
<PopUpProvider>{children}</PopUpProvider>
<ProgressProvider>
<PopUpProvider>{children}</PopUpProvider>
</ProgressProvider>
</UndoRedoProvider>
</TabsProvider>
</SSEProvider>

View file

@ -22,7 +22,9 @@ const GITHUB_API_URL = "https://api.github.com";
export async function getRepoStars(owner, repo) {
try {
const response = await axios.get(`${GITHUB_API_URL}/repos/${owner}/${repo}`);
const response = await axios.get(
`${GITHUB_API_URL}/repos/${owner}/${repo}`
);
return response.data.stargazers_count;
} catch (error) {
console.error("Error fetching repository data:", error);

View file

@ -98,3 +98,9 @@ export type TooltipComponentType = {
| "top-start"
| "top";
};
export type ProgressBarType = {
children?: ReactElement;
value?: number;
max?: number;
};