diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx
index 91c455d1c..406c66fd5 100644
--- a/src/frontend/src/App.tsx
+++ b/src/frontend/src/App.tsx
@@ -20,6 +20,7 @@ import useAlertStore from "./stores/alertStore";
import { useDarkStore } from "./stores/darkStore";
import useFlowsManagerStore from "./stores/flowsManagerStore";
import { useTypesStore } from "./stores/typesStore";
+import { useStoreStore } from "./stores/storeStore";
export default function App() {
const removeFromTempNotificationList = useAlertStore(
@@ -28,7 +29,6 @@ export default function App() {
const tempNotificationList = useAlertStore(
(state) => state.tempNotificationList
);
- const loading = useAlertStore((state) => state.loading);
const [fetchError, setFetchError] = useState(false);
const isLoading = useFlowsManagerStore((state) => state.isLoading);
@@ -38,9 +38,11 @@ export default function App() {
const { isAuthenticated } = useContext(AuthContext);
const refreshFlows = useFlowsManagerStore((state) => state.refreshFlows);
+ const fetchApiData = useStoreStore((state) => state.fetchApiData);
const getTypes = useTypesStore((state) => state.getTypes);
const refreshVersion = useDarkStore((state) => state.refreshVersion);
const refreshStars = useDarkStore((state) => state.refreshStars);
+ const checkHasStore = useStoreStore((state) => state.checkHasStore);
useEffect(() => {
refreshStars();
@@ -52,6 +54,8 @@ export default function App() {
getTypes().then(() => {
refreshFlows();
});
+ checkHasStore();
+ fetchApiData();
}
}, [isAuthenticated]);
diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx
index a0dfebcd4..22f2a9b28 100644
--- a/src/frontend/src/CustomNodes/GenericNode/index.tsx
+++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx
@@ -167,6 +167,7 @@ export default function GenericNode({
buildStatus: BuildStatus | undefined,
validationStatus: validationStatusType | null
) => {
+ console.log(buildStatus);
const isValid = validationStatus && validationStatus.valid;
if (isValid) {
return "green-status";
@@ -192,7 +193,6 @@ export default function GenericNode({
};
const renderIconPlayOrPauseComponents = (
buildStatus: BuildStatus | undefined,
- validationStatus: validationStatusType | null
) => {
if (buildStatus === BuildStatus.BUILDING) {
return ;
@@ -200,7 +200,7 @@ export default function GenericNode({
return (
);
}
@@ -467,44 +467,21 @@ export default function GenericNode({
variant="secondary"
className={"group h-9 px-1.5"}
onClick={() => {
- if (buildStatus === BuildStatus.BUILDING || isBuilding)
+ if (data?.buildStatus === BuildStatus.BUILDING || isBuilding)
return;
buildFlow(data.id);
}}
>
Building...
- ) : !validationStatus ? (
-
- Build{" "}
- {" "}
- flow to validate status.
-
- ) : (
-
- {typeof validationStatus.params === "string"
- ? `${durationString}\n${validationStatus.params}`
- .split("\n")
- .map((line, index) => (
-
{line}
- ))
- : durationString}
-
- )
+ "Build"
}
side="bottom"
>
{renderIconPlayOrPauseComponents(
buildStatus,
- validationStatus
)}
@@ -513,7 +490,6 @@ export default function GenericNode({
)}
Building...
@@ -529,7 +505,6 @@ export default function GenericNode({
)
}
- side="bottom"
>
{renderIconStatusComponents(
diff --git a/src/frontend/src/components/IOview/index.tsx b/src/frontend/src/components/IOview/index.tsx
index 9fc109e21..735f543d2 100644
--- a/src/frontend/src/components/IOview/index.tsx
+++ b/src/frontend/src/components/IOview/index.tsx
@@ -1,7 +1,11 @@
+import { cloneDeep } from "lodash";
import { useEffect, useState } from "react";
import { CHAT_FORM_DIALOG_SUBTITLE } from "../../constants/constants";
import BaseModal from "../../modals/baseModal";
+import useAlertStore from "../../stores/alertStore";
import useFlowStore from "../../stores/flowStore";
+import { NodeType } from "../../types/flow";
+import { validateNodes } from "../../utils/reactflowUtils";
import { cn } from "../../utils/utils";
import AccordionComponent from "../AccordionComponent";
import IOInputField from "../IOInputField";
@@ -16,19 +20,22 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
const inputs = useFlowStore((state) => state.inputs).filter(
(input) => input.type !== "ChatInput"
);
+ const chatInput = useFlowStore((state) => state.inputs).find(
+ (input) => input.type === "ChatInput"
+ );
const outputs = useFlowStore((state) => state.outputs).filter(
(output) => output.type !== "ChatOutput"
);
+ const chatOutput = useFlowStore((state) => state.outputs).find(
+ (output) => output.type === "ChatOutput"
+ );
const nodes = useFlowStore((state) => state.nodes).filter(
(node) =>
(inputs.some((input) => input.id === node.id) ||
- outputs.some((output) => output.id === node.id)) &&
- node.type !== "ChatInput" &&
- node.type !== "ChatOutput"
- );
- const haveChat = useFlowStore((state) => state.outputs).some(
- (output) => output.type === "ChatOutput"
+ outputs.some((output) => output.id === node.id))
);
+ const haveChat =
+ chatInput || chatOutput
const [selectedTab, setSelectedTab] = useState(
inputs.length > 0 ? 1 : outputs.length > 0 ? 2 : 0
);
@@ -36,6 +43,45 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
{ type: string; id: string } | undefined
>(undefined);
+ const { getNode, setNode, buildFlow, getFlow } = useFlowStore();
+ const { setErrorData } = useAlertStore();
+ const setIsBuilding = useFlowStore((state) => state.setIsBuilding);
+ const [lockChat, setLockChat] = useState(false);
+ const [chatValue, setChatValue] = useState("");
+ const isBuilding = useFlowStore((state) => state.isBuilding);
+
+ async function sendMessage(count = 1): Promise {
+ if (isBuilding) return;
+ const { nodes, edges } = getFlow();
+ let nodeValidationErrors = validateNodes(nodes, edges);
+ if (nodeValidationErrors.length === 0) {
+ setIsBuilding(true);
+ setLockChat(true);
+ setChatValue("");
+ const chatInputNode = nodes.find((node) => node.id === chatInput?.id);
+ if (chatInputNode) {
+ let newNode = cloneDeep(chatInputNode);
+ newNode.data.node!.template["message"].value = chatValue;
+ setNode(chatInput!.id, newNode);
+ }
+ for (let i = 0; i < count; i++) {
+ await buildFlow().catch((err) => {
+ console.error(err);
+ setLockChat(false);
+ });
+ }
+ setLockChat(false);
+
+ //set chat message in the flow and run build
+ //@ts-ignore
+ } else {
+ setErrorData({
+ title: "Oops! Looks like you missed some required information:",
+ list: nodeValidationErrors,
+ });
+ }
+ }
+
useEffect(() => {
setSelectedViewField(undefined);
setSelectedTab(inputs.length > 0 ? 1 : outputs.length > 0 ? 2 : 0);
@@ -43,7 +89,7 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
return (
@@ -60,178 +106,196 @@ export default function IOView({ children, open, setOpen }): JSX.Element {
-
- {selectedTab !== 0 && (
-
-
{
- setSelectedTab(Number(value));
- }}
+
+
+ {selectedTab !== 0 && (
+
-
-
- {inputs.length > 0 && (
- Inputs
- )}
- {outputs.length > 0 && (
- Outputs
- )}
-
-
-
-
{
+ setSelectedTab(Number(value));
+ }}
>
-
-
- Text Inputs
+
+
+ {inputs.length > 0 && (
+ Inputs
+ )}
+ {outputs.length > 0 && (
+ Outputs
+ )}
+
- {nodes
- .filter((node) =>
- inputs.some((input) => input.id === node.id)
- )
- .map((node, index) => {
- const input = inputs.find(
- (input) => input.id === node.id
- )!;
- return (
-
-
-
- {input.id}
-
- {haveChat && (
- {
- event.stopPropagation();
- setSelectedViewField(input);
- }}
- >
-
-
- )}
-
- }
- key={index}
- keyValue={input.id}
- >
-
-
- {input && (
-
- )}
-
-
-
-
- );
- })}
-
-
-
-
- Prompt Outputs
-
- {nodes
- .filter((node) =>
- outputs.some((output) => output.id === node.id)
- )
- .map((node, index) => {
- const output = outputs.find(
- (output) => output.id === node.id
- )!;
- return (
-
-
-
- {output.id}
-
- {haveChat && (
- {
- event.stopPropagation();
- setSelectedViewField(output);
- }}
- >
-
-
- )}
-
- }
- key={index}
- keyValue={output.id}
- >
-
-
- {output && (
-
- )}
-
-
-
-
- );
- })}
-
-
-
- )}
- {haveChat ? (
- selectedViewField ? (
- inputs.some((input) => input.id === selectedViewField.id) ? (
-
+
+
+
+ Text Inputs
+
+ {nodes
+ .filter((node) =>
+ inputs.some((input) => input.id === node.id)
+ )
+ .map((node, index) => {
+ const input = inputs.find(
+ (input) => input.id === node.id
+ )!;
+ return (
+
+
+
+ {input.id}
+
+ {haveChat && (
+ {
+ event.stopPropagation();
+ setSelectedViewField(input);
+ }}
+ >
+
+
+ )}
+
+ }
+ key={index}
+ keyValue={input.id}
+ >
+
+
+ {input && (
+
+ )}
+
+
+
+
+ );
+ })}
+
+
+
+
+ Prompt Outputs
+
+ {nodes
+ .filter((node) =>
+ outputs.some((output) => output.id === node.id)
+ )
+ .map((node, index) => {
+ const output = outputs.find(
+ (output) => output.id === node.id
+ )!;
+ return (
+
+
+
+ {output.id}
+
+ {haveChat && (
+ {
+ event.stopPropagation();
+ setSelectedViewField(output);
+ }}
+ >
+
+
+ )}
+
+ }
+ key={index}
+ keyValue={output.id}
+ >
+
+
+ {output && (
+
+ )}
+
+
+
+
+ );
+ })}
+
+
+
+ )}
+
+ {haveChat ? (
+ selectedViewField ? (
+ inputs.some((input) => input.id === selectedViewField.id) ? (
+
+ ) : (
+
+ )
) : (
-
)
) : (
-
- )
- ) : (
-
+ {!haveChat && (
+
+
)}
diff --git a/src/frontend/src/components/ViewTriggers/chat/index.tsx b/src/frontend/src/components/ViewTriggers/chat/index.tsx
index f61da2969..9610f22ff 100644
--- a/src/frontend/src/components/ViewTriggers/chat/index.tsx
+++ b/src/frontend/src/components/ViewTriggers/chat/index.tsx
@@ -21,7 +21,7 @@ export default function ChatTrigger({}): JSX.Element {
>
diff --git a/src/frontend/src/components/newChatView/chatMessage/index.tsx b/src/frontend/src/components/newChatView/chatMessage/index.tsx
index 36fb3955e..31f4f0345 100644
--- a/src/frontend/src/components/newChatView/chatMessage/index.tsx
+++ b/src/frontend/src/components/newChatView/chatMessage/index.tsx
@@ -70,7 +70,7 @@ export default function ChatMessage({
useEffect(() => {
// This effect is specifically for calling updateChat after streaming ends
- if (!isStreaming && streamUrl === null) {
+ if (!isStreaming && streamUrl) {
if (updateChat) {
updateChat(chat, chatMessage, streamUrl);
}
diff --git a/src/frontend/src/components/newChatView/index.tsx b/src/frontend/src/components/newChatView/index.tsx
index d069ea97c..38a633444 100644
--- a/src/frontend/src/components/newChatView/index.tsx
+++ b/src/frontend/src/components/newChatView/index.tsx
@@ -1,4 +1,4 @@
-import _, { cloneDeep } from "lodash";
+import _ from "lodash";
import { useEffect, useRef, useState } from "react";
import IconComponent from "../../components/genericIconComponent";
import { deleteFlowPool } from "../../controllers/API";
@@ -11,30 +11,21 @@ import {
ChatOutputType,
FlowPoolObjectType,
} from "../../types/chat";
-import { NodeType } from "../../types/flow";
-import { validateNodes } from "../../utils/reactflowUtils";
import { classNames } from "../../utils/utils";
import ChatInput from "./chatInput";
import ChatMessage from "./chatMessage";
-export default function NewChatView(): JSX.Element {
- const [chatValue, setChatValue] = useState("");
- const {
- flowPool,
- outputs,
- inputs,
- getNode,
- setNode,
- buildFlow,
- getFlow,
- CleanFlowPool,
- } = useFlowStore();
- const { setErrorData, setNoticeData } = useAlertStore();
+export default function NewChatView({
+ sendMessage,
+ chatValue,
+ setChatValue,
+ lockChat,
+ setLockChat,
+}): JSX.Element {
+ const { flowPool, outputs, inputs, CleanFlowPool } = useFlowStore();
+ const { setNoticeData } = useAlertStore();
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
- const setIsBuilding = useFlowStore((state) => state.setIsBuilding);
- const [lockChat, setLockChat] = useState(false);
const messagesRef = useRef(null);
- const isBuilding = useFlowStore((state) => state.isBuilding);
const [chatHistory, setChatHistory] = useState([]);
const inputTypes = inputs.map((obj) => obj.type);
@@ -115,40 +106,6 @@ export default function NewChatView(): JSX.Element {
}
}, []);
- async function sendMessage(count = 1): Promise {
- if (isBuilding) return;
- const { nodes, edges } = getFlow();
- let nodeValidationErrors = validateNodes(nodes, edges);
- if (nodeValidationErrors.length === 0) {
- setIsBuilding(true);
- setLockChat(true);
- setChatValue("");
- const chatInputId = inputIds.find((inputId) =>
- inputId.includes("ChatInput")
- );
- const chatInput: NodeType = getNode(chatInputId!) as NodeType;
- if (chatInput) {
- let newNode = cloneDeep(chatInput);
- newNode.data.node!.template["message"].value = chatValue;
- setNode(chatInputId!, newNode);
- }
- for (let i = 0; i < count; i++) {
- await buildFlow().catch((err) => {
- console.error(err);
- setLockChat(false);
- });
- }
- setLockChat(false);
-
- //set chat message in the flow and run build
- //@ts-ignore
- } else {
- setErrorData({
- title: "Oops! Looks like you missed some required information:",
- list: nodeValidationErrors,
- });
- }
- }
function clearChat(): void {
setChatHistory([]);
deleteFlowPool(currentFlowId).then((_) => {
diff --git a/src/frontend/src/modals/baseModal/index.tsx b/src/frontend/src/modals/baseModal/index.tsx
index 860551be9..134093f5c 100644
--- a/src/frontend/src/modals/baseModal/index.tsx
+++ b/src/frontend/src/modals/baseModal/index.tsx
@@ -66,6 +66,7 @@ interface BaseModalProps {
| "small"
| "medium"
| "large"
+ | "large-thin"
| "large-h-full"
| "small-h-full"
| "medium-h-full"
@@ -128,6 +129,10 @@ function BaseModal({
minWidth = "min-w-[80vw]";
height = "h-[80vh]";
break;
+ case "large-thin":
+ minWidth = "min-w-[65vw]";
+ height = "h-[80vh]";
+ break;
case "large-h-full":
minWidth = "min-w-[80vw]";
break;
diff --git a/src/frontend/src/modals/formModal/index.tsx b/src/frontend/src/modals/formModal/index.tsx
index dfaf871ed..af6e9eace 100644
--- a/src/frontend/src/modals/formModal/index.tsx
+++ b/src/frontend/src/modals/formModal/index.tsx
@@ -576,6 +576,7 @@ export default function FormModal({
chatHistory.length - 1 === index ? true : false
}
key={index}
+ updateChat={() => {}}
/>
))
) : (
diff --git a/src/frontend/src/pages/StorePage/index.tsx b/src/frontend/src/pages/StorePage/index.tsx
index 8321be91d..8eeafc28f 100644
--- a/src/frontend/src/pages/StorePage/index.tsx
+++ b/src/frontend/src/pages/StorePage/index.tsx
@@ -39,8 +39,6 @@ export default function StorePage(): JSX.Element {
const loadingApiKey = useStoreStore((state) => state.loadingApiKey);
const setValidApiKey = useStoreStore((state) => state.updateValidApiKey);
- const setLoadingApiKey = useStoreStore((state) => state.updateLoadingApiKey);
- const setHasApiKey = useStoreStore((state) => state.updateHasApiKey);
const { apiKey } = useContext(AuthContext);
@@ -48,6 +46,9 @@ export default function StorePage(): JSX.Element {
const setCurrentFlowId = useFlowsManagerStore(
(state) => state.setCurrentFlowId
);
+ const currentFlowId = useFlowsManagerStore(
+ (state) => state.currentFlowId
+ );
const [loading, setLoading] = useState(true);
const [loadingTags, setLoadingTags] = useState(true);
const { id } = useParams();
@@ -63,10 +64,6 @@ export default function StorePage(): JSX.Element {
const [searchNow, setSearchNow] = useState("");
const [selectFilter, setSelectFilter] = useState("all");
- useEffect(() => {
- handleGetTags();
- }, []);
-
useEffect(() => {
if (!loadingApiKey) {
if (!hasApiKey) {
@@ -86,9 +83,10 @@ export default function StorePage(): JSX.Element {
});
}
}
- }, [loadingApiKey, validApiKey, hasApiKey]);
+ }, [loadingApiKey, validApiKey, hasApiKey, currentFlowId]);
useEffect(() => {
+ handleGetTags();
handleGetComponents();
}, [
tabActive,
@@ -119,7 +117,7 @@ export default function StorePage(): JSX.Element {
}
function handleGetComponents() {
- if (!hasApiKey || loadingApiKey) return;
+ if (loadingApiKey) return;
setLoading(true);
getStoreComponents({
component_id: id,
@@ -176,23 +174,6 @@ export default function StorePage(): JSX.Element {
setPageSize(12);
}
- const fetchApiData = async () => {
- setLoadingApiKey(true);
- try {
- const res = await checkHasApiKey();
- setHasApiKey(res?.has_api_key ?? false);
- setValidApiKey(res?.is_valid ?? false);
- setLoadingApiKey(false);
- } catch (e) {
- setLoadingApiKey(false);
- console.log(e);
- }
- };
-
- useEffect(() => {
- fetchApiData();
- }, [apiKey]);
-
return (
((set) => ({
hasStore: true,
validApiKey: false,
hasApiKey: false,
loadingApiKey: true,
- updateHasStore: (hasStore) => set(() => ({ hasStore: hasStore })),
+ checkHasStore: () => {
+ checkHasStore().then((res) => {
+ set({ hasStore: res?.enabled ?? false });
+ });
+ },
updateValidApiKey: (validApiKey) => set(() => ({ validApiKey: validApiKey })),
updateLoadingApiKey: (loadingApiKey) =>
set(() => ({ loadingApiKey: loadingApiKey })),
updateHasApiKey: (hasApiKey) => set(() => ({ hasApiKey: hasApiKey })),
+ fetchApiData: async () => {
+ set({ loadingApiKey: true });
+ try {
+ const res = await checkHasApiKey();
+ set({
+ validApiKey: res?.is_valid ?? false,
+ hasApiKey: res?.has_api_key ?? false,
+ loadingApiKey: false,
+ });
+ } catch (e) {
+ set({ loadingApiKey: false });
+ console.log(e);
+ }
+ },
}));
-
-checkHasStore().then((res) => {
- useStoreStore.setState({ hasStore: res?.enabled ?? false });
-});
diff --git a/src/frontend/src/style/applies.css b/src/frontend/src/style/applies.css
index 9208c4b17..794032875 100644
--- a/src/frontend/src/style/applies.css
+++ b/src/frontend/src/style/applies.css
@@ -175,7 +175,7 @@
@apply fixed bottom-4 right-4;
}
.message-button-icon {
- @apply fill-chat-trigger stroke-chat-trigger stroke-1;
+ @apply fill-medium-indigo stroke-medium-indigo stroke-1;
}
.disabled-message-button-icon {
@apply fill-chat-trigger-disabled stroke-chat-trigger-disabled stroke-1;
diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts
index 0a0da32ad..bc8582118 100644
--- a/src/frontend/src/types/components/index.ts
+++ b/src/frontend/src/types/components/index.ts
@@ -524,11 +524,7 @@ export type chatMessagePropsType = {
chat: ChatMessageType;
lockChat: boolean;
lastMessage: boolean;
- updateChat?: (
- chat: ChatMessageType,
- message: string,
- stream_url: string | null
- ) => void;
+ updateChat: (chat: ChatMessageType, message: string, stream_url: string) => void;
};
export type formModalPropsType = {
diff --git a/src/frontend/src/types/zustand/store/index.ts b/src/frontend/src/types/zustand/store/index.ts
index 0254c857d..34bf38ad1 100644
--- a/src/frontend/src/types/zustand/store/index.ts
+++ b/src/frontend/src/types/zustand/store/index.ts
@@ -3,8 +3,9 @@ export type StoreStoreType = {
validApiKey: boolean;
hasApiKey: boolean;
loadingApiKey: boolean;
- updateHasStore: (hasStore: boolean) => void;
+ checkHasStore: () => void;
updateValidApiKey: (validApiKey: boolean) => void;
updateHasApiKey: (hasApiKey: boolean) => void;
updateLoadingApiKey: (loadingApiKey: boolean) => void;
+ fetchApiData: () => Promise;
};
diff --git a/src/frontend/src/utils/utils.ts b/src/frontend/src/utils/utils.ts
index 2ca790c7b..c89786ce7 100644
--- a/src/frontend/src/utils/utils.ts
+++ b/src/frontend/src/utils/utils.ts
@@ -58,11 +58,12 @@ export function normalCaseToSnakeCase(str: string): string {
.join("_");
}
-export function toTitleCase(str: string | undefined): string {
+export function toTitleCase(str: string | undefined, isNodeField?: boolean): string {
if (!str) return "";
let result = str
.split("_")
.map((word, index) => {
+ if (isNodeField) return word
if (index === 0) {
return checkUpperWords(
word[0].toUpperCase() + word.slice(1).toLowerCase()
@@ -75,6 +76,7 @@ export function toTitleCase(str: string | undefined): string {
return result
.split("-")
.map((word, index) => {
+ if (isNodeField) return word
if (index === 0) {
return checkUpperWords(
word[0].toUpperCase() + word.slice(1).toLowerCase()
@@ -642,6 +644,6 @@ export function getFieldTitle(
return template[templateField].display_name
? template[templateField].display_name!
: template[templateField].name
- ? toTitleCase(template[templateField].name!)
- : toTitleCase(templateField);
+ ? toTitleCase(template[templateField].name!, true)
+ : toTitleCase(templateField, true);
}