Implement "In Progress" Status for Component Building (#1449)
This pull request introduces a new "In Progress" status for the component building process within our application. This status will bridge the gap between "Not Started" and "Completed," providing more granular visibility into the component's lifecycle.
This commit is contained in:
commit
98ae37f24e
9 changed files with 138 additions and 43 deletions
|
|
@ -7,6 +7,7 @@ import InputComponent from "../../components/inputComponent";
|
|||
import { Button } from "../../components/ui/button";
|
||||
import { Textarea } from "../../components/ui/textarea";
|
||||
import { priorityFields } from "../../constants/constants";
|
||||
import { BuildStatus } from "../../constants/enums";
|
||||
import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent";
|
||||
import useFlowStore from "../../stores/flowStore";
|
||||
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
||||
|
|
@ -71,7 +72,6 @@ export default function GenericNode({
|
|||
|
||||
setHandles(count);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
countHandles();
|
||||
}, [data, data.node]);
|
||||
|
|
@ -157,6 +157,78 @@ export default function GenericNode({
|
|||
);
|
||||
};
|
||||
|
||||
const getIconPlayOrPauseComponent = (name, className) => (
|
||||
<IconComponent
|
||||
name={name}
|
||||
className={`absolute h-5 stroke-2 ${className} ml-0.5`}
|
||||
/>
|
||||
);
|
||||
|
||||
const getStatusClassName = (
|
||||
validationStatus: validationStatusType | null,
|
||||
isBuilding: boolean
|
||||
) => {
|
||||
if (validationStatus && validationStatus.valid) {
|
||||
return "green-status";
|
||||
} else if (validationStatus && !validationStatus.valid) {
|
||||
return "red-status";
|
||||
} else if (!validationStatus || isBuilding) {
|
||||
return "yellow-status";
|
||||
} else {
|
||||
return "status-build-animation";
|
||||
}
|
||||
};
|
||||
|
||||
const renderIconPlayOrPauseComponents = (
|
||||
buildStatus: BuildStatus | undefined,
|
||||
validationStatus: validationStatusType | null,
|
||||
isBuilding: boolean
|
||||
) => {
|
||||
if (buildStatus === BuildStatus.BUILDING) {
|
||||
return getIconPlayOrPauseComponent("Square", "red-status");
|
||||
} else {
|
||||
const className = getStatusClassName(validationStatus, isBuilding);
|
||||
return <>{getIconPlayOrPauseComponent("Play", className)}</>;
|
||||
}
|
||||
};
|
||||
|
||||
const getSpecificClassFromBuildStatus = (
|
||||
buildStatus: BuildStatus | undefined,
|
||||
validationStatus: validationStatusType | null
|
||||
) => {
|
||||
if (
|
||||
buildStatus === BuildStatus.BUILDED &&
|
||||
validationStatus &&
|
||||
!validationStatus.valid
|
||||
) {
|
||||
return "border-none ring ring-red-300";
|
||||
} else if (buildStatus === BuildStatus.BUILDING) {
|
||||
return "border-none ring";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
const getNodeBorderClassName = (
|
||||
selected: boolean,
|
||||
showNode: boolean,
|
||||
buildStatus: BuildStatus | undefined,
|
||||
validationStatus: validationStatusType | null
|
||||
) => {
|
||||
return classNames(
|
||||
getBaseBorderClass(selected),
|
||||
getNodeSizeClass(showNode),
|
||||
"generic-node-div",
|
||||
getSpecificClassFromBuildStatus(buildStatus, validationStatus)
|
||||
);
|
||||
};
|
||||
|
||||
const getBaseBorderClass = (selected) =>
|
||||
selected ? "border border-ring" : "border";
|
||||
|
||||
const getNodeSizeClass = (showNode) =>
|
||||
showNode ? "w-96 rounded-lg" : "w-26 h-26 rounded-full";
|
||||
|
||||
return (
|
||||
<>
|
||||
<NodeToolbar>
|
||||
|
|
@ -181,10 +253,11 @@ export default function GenericNode({
|
|||
</NodeToolbar>
|
||||
|
||||
<div
|
||||
className={classNames(
|
||||
selected ? "border border-ring" : "border",
|
||||
showNode ? " w-96 rounded-lg" : " w-26 h-26 rounded-full",
|
||||
"generic-node-div"
|
||||
className={getNodeBorderClassName(
|
||||
selected,
|
||||
showNode,
|
||||
data?.build_status,
|
||||
validationStatus
|
||||
)}
|
||||
>
|
||||
{data.node?.beta && showNode && (
|
||||
|
|
@ -396,7 +469,8 @@ export default function GenericNode({
|
|||
<div>
|
||||
<Tooltip
|
||||
title={
|
||||
isBuilding ? (
|
||||
isBuilding ||
|
||||
data?.build_status === BuildStatus.BUILDING ? (
|
||||
<span>Building...</span>
|
||||
) : !validationStatus ? (
|
||||
<span className="flex">
|
||||
|
|
@ -421,33 +495,11 @@ export default function GenericNode({
|
|||
}
|
||||
>
|
||||
<div className="generic-node-status-position flex items-center justify-center">
|
||||
<IconComponent
|
||||
name="Play"
|
||||
className={classNames(
|
||||
validationStatus && validationStatus.valid
|
||||
? "green-status"
|
||||
: "status-build-animation",
|
||||
"absolute h-5 stroke-2"
|
||||
)}
|
||||
/>
|
||||
<IconComponent
|
||||
name="AlertCircle"
|
||||
className={classNames(
|
||||
validationStatus && !validationStatus.valid
|
||||
? "red-status"
|
||||
: "status-build-animation",
|
||||
"absolute h-5 stroke-2"
|
||||
)}
|
||||
/>
|
||||
<IconComponent
|
||||
name="Play"
|
||||
className={classNames(
|
||||
!validationStatus || isBuilding
|
||||
? "yellow-status"
|
||||
: "status-build-animation",
|
||||
"absolute h-5 stroke-2"
|
||||
)}
|
||||
/>
|
||||
{renderIconPlayOrPauseComponents(
|
||||
data?.build_status,
|
||||
validationStatus,
|
||||
isBuilding
|
||||
)}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,3 +6,9 @@ export enum TypeModal {
|
|||
TEXT = 1,
|
||||
PROMPT = 2,
|
||||
}
|
||||
|
||||
export enum BuildStatus {
|
||||
BUILDING = "BUILDING",
|
||||
TO_BUILD = "TO_BUILD",
|
||||
BUILDED = "BUILDED",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,7 +205,6 @@ export default function FormModal({
|
|||
if (Array.isArray(data) && data.length > 0) {
|
||||
//set chat history
|
||||
setChatHistory((_) => {
|
||||
console.log(data);
|
||||
let newChatHistory: ChatMessageType[] = [];
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (data[i].type === "prompt" && data[i].prompt) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {
|
|||
} from "reactflow";
|
||||
import { create } from "zustand";
|
||||
import { INPUT_TYPES, OUTPUT_TYPES } from "../constants/constants";
|
||||
import { BuildStatus } from "../constants/enums";
|
||||
import { getFlowPool, updateFlowInDatabase } from "../controllers/API";
|
||||
import {
|
||||
NodeDataType,
|
||||
|
|
@ -380,6 +381,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
|
|||
const setNoticeData = useAlertStore.getState().setNoticeData;
|
||||
function handleBuildUpdate(data: any) {
|
||||
get().addDataToFlowPool(data.data[data.id], data.id);
|
||||
useFlowStore.getState().updateBuildStatus([data.id], BuildStatus.BUILDED);
|
||||
}
|
||||
await updateFlowInDatabase({
|
||||
data: {
|
||||
|
|
@ -403,9 +405,14 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
|
|||
}
|
||||
},
|
||||
onBuildUpdate: handleBuildUpdate,
|
||||
onBuildError: (title, list) => {
|
||||
onBuildError: (title, list, idList) => {
|
||||
useFlowStore.getState().updateBuildStatus(idList, BuildStatus.BUILDED);
|
||||
|
||||
setErrorData({ list, title });
|
||||
},
|
||||
onBuildStart: (idList) => {
|
||||
useFlowStore.getState().updateBuildStatus(idList, BuildStatus.BUILDING);
|
||||
},
|
||||
});
|
||||
},
|
||||
getFlow: () => {
|
||||
|
|
@ -415,6 +422,15 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
|
|||
viewport: get().reactFlowInstance?.getViewport()!,
|
||||
};
|
||||
},
|
||||
updateBuildStatus: (nodeIdList: string[], status: BuildStatus) => {
|
||||
nodeIdList.forEach((id) => {
|
||||
const nodeToUpdate = get().nodes.find((node) => node.id === id);
|
||||
if (nodeToUpdate) {
|
||||
nodeToUpdate.data.build_status = status;
|
||||
get().setNodes(get().nodes);
|
||||
}
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
export default useFlowStore;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { Edge, Node, Viewport } from "reactflow";
|
||||
import { BuildStatus } from "../../constants/enums";
|
||||
import { FlowType } from "../flow";
|
||||
//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 };
|
||||
|
|
@ -36,6 +37,7 @@ export type APIClassType = {
|
|||
| CustomFieldsType
|
||||
| boolean
|
||||
| undefined;
|
||||
build_status?: BuildStatus;
|
||||
};
|
||||
|
||||
export type TemplateVariableType = {
|
||||
|
|
|
|||
|
|
@ -625,7 +625,7 @@ export type crashComponentPropsType = {
|
|||
|
||||
export type validationStatusType = {
|
||||
id: string;
|
||||
data: object;
|
||||
data: object | any;
|
||||
params: string;
|
||||
progress: number;
|
||||
valid: boolean;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { ReactFlowJsonObject, XYPosition } from "reactflow";
|
||||
import { BuildStatus } from "../../constants/enums";
|
||||
import { APIClassType } from "../api/index";
|
||||
|
||||
export type FlowType = {
|
||||
|
|
@ -26,6 +27,7 @@ export type NodeDataType = {
|
|||
node?: APIClassType;
|
||||
id: string;
|
||||
output_types?: string[];
|
||||
build_status?: BuildStatus;
|
||||
};
|
||||
// FlowStyleType is the type of the style object that is used to style the
|
||||
// Flow card with an emoji and a color.
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import {
|
|||
ReactFlowInstance,
|
||||
Viewport,
|
||||
} from "reactflow";
|
||||
import { BuildStatus } from "../../../constants/enums";
|
||||
import { FlowState } from "../../tabs";
|
||||
|
||||
export type chatInputType = {
|
||||
|
|
@ -85,4 +86,5 @@ export type FlowStoreType = {
|
|||
unselectAll: () => void;
|
||||
buildFlow: (nodeId?: string) => Promise<void>;
|
||||
getFlow: () => { nodes: Node[]; edges: Edge[]; viewport: Viewport };
|
||||
updateBuildStatus: (nodeId: string[], status: BuildStatus) => void;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { AxiosError } from "axios";
|
||||
import { BuildStatus } from "../constants/enums";
|
||||
import { getVerticesOrder, postBuildVertex } from "../controllers/API";
|
||||
import useFlowStore from "../stores/flowStore";
|
||||
import { VertexBuildTypeAPI } from "../types/api";
|
||||
|
||||
type BuildVerticesParams = {
|
||||
|
|
@ -8,7 +10,8 @@ type BuildVerticesParams = {
|
|||
onProgressUpdate?: (progress: number) => void; // Replace number with the actual type if it's not a number
|
||||
onBuildUpdate?: (data: any) => void; // Replace any with the actual type of data
|
||||
onBuildComplete?: (allNodesValid: boolean) => void;
|
||||
onBuildError?: (title, list) => void;
|
||||
onBuildError?: (title, list, idList: string[]) => void;
|
||||
onBuildStart?: (idList: string[]) => void;
|
||||
};
|
||||
|
||||
export async function buildVertices({
|
||||
|
|
@ -18,10 +21,12 @@ export async function buildVertices({
|
|||
onBuildUpdate,
|
||||
onBuildComplete,
|
||||
onBuildError,
|
||||
onBuildStart,
|
||||
}: BuildVerticesParams) {
|
||||
let orderResponse = await getVerticesOrder(flowId, nodeId);
|
||||
let verticesOrder: Array<Array<string>> = orderResponse.data.ids;
|
||||
let vertices: Array<Array<string>> = [];
|
||||
|
||||
if (nodeId) {
|
||||
for (let i = 0; i < verticesOrder.length; i += 1) {
|
||||
const innerArray = verticesOrder[i];
|
||||
|
|
@ -40,10 +45,13 @@ export async function buildVertices({
|
|||
vertices = verticesOrder;
|
||||
}
|
||||
|
||||
// Set each vertex state to building
|
||||
const verticesIds = vertices.flatMap((v) => v);
|
||||
useFlowStore.getState().updateBuildStatus(verticesIds, BuildStatus.TO_BUILD);
|
||||
|
||||
// Set each vertex state to building
|
||||
const buildResults: Array<boolean> = [];
|
||||
for (let i = 0; i < vertices.length; i += 1) {
|
||||
if (onBuildStart) onBuildStart(vertices[i]);
|
||||
await Promise.all(
|
||||
vertices[i].map(async (id) => {
|
||||
try {
|
||||
|
|
@ -54,7 +62,11 @@ export async function buildVertices({
|
|||
let data = {};
|
||||
if (!buildData.valid) {
|
||||
if (onBuildError) {
|
||||
onBuildError("Error Building Component", [buildData.params]);
|
||||
onBuildError(
|
||||
"Error Building Component",
|
||||
[buildData.params],
|
||||
verticesIds
|
||||
);
|
||||
}
|
||||
}
|
||||
data[buildData.id] = buildData;
|
||||
|
|
@ -64,10 +76,14 @@ export async function buildVertices({
|
|||
} catch (error) {
|
||||
if (onBuildError) {
|
||||
console.log(error);
|
||||
onBuildError("Error Building Component", [
|
||||
(error as AxiosError<any>).response?.data?.detail ??
|
||||
"Unknown Error",
|
||||
]);
|
||||
onBuildError(
|
||||
"Error Building Component",
|
||||
[
|
||||
(error as AxiosError<any>).response?.data?.detail ??
|
||||
"Unknown Error",
|
||||
],
|
||||
verticesIds
|
||||
);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue