Bugfix: saving all the time, scroll on chat IO / Feat: Changing building status on navigation bar (#1460)

* 🐛 fix(menuBar/index.tsx): add isBuilding state to handle display of build status
✨ feat(menuBar/index.tsx): add printByBuildStatus function to display appropriate build status based on isBuilding and saveLoading states
🐛 fix(api.tsx): set isBuilding state to false when encountering a 500 error response
🐛 fix(buildUtils.ts): set isBuilding state to true before building vertices and set it to false after build completion

* 🐛 fix(chatMessage): scroll to last chat message when rendering a new message to improve user experience
🔥 refactor(chatMessage): remove unused state and variables to improve code readability and maintainability
🔥 refactor(flowsManagerStore): remove redundant code and improve code readability

* Add logger and session imports, and update build_vertex function

* Fix conditional rendering bug in IOView component

* Remove unused imports from chat.py

* add last message to end

* 🔧 fix(chatMessage): add useEffect hook to scroll to last chat message after rendering
🔧 fix(chatMessage): add dependency array to useEffect hook to prevent unnecessary re-renders

---------

Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@logspace.ai>
This commit is contained in:
Cristhian Zanforlin Lousa 2024-02-22 14:44:35 -03:00 • committed by GitHub
commit e2a79a57e1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 228 additions and 195 deletions

View file

@ -33,6 +33,7 @@ export const MenuBar = ({
const n = useFlowStore((state) => state.nodes);
const navigate = useNavigate();
const isBuilding = useFlowStore((state) => state.isBuilding);
function handleAddFlow() {
try {
@ -45,6 +46,15 @@ export const MenuBar = ({
}
}
function printByBuildStatus() {
if (isBuilding) {
return "Building...";
} else if (saveLoading) {
return "Saving...";
}
return "Saved";
}
return currentFlow ? (
<div className="round-button-div">
<button
@ -127,13 +137,13 @@ export const MenuBar = ({
>
<div className="flex items-center gap-1.5 text-sm text-muted-foreground">
<IconComponent
name={saveLoading ? "Loader2" : "CheckCircle2"}
name={isBuilding || saveLoading ? "Loader2" : "CheckCircle2"}
className={cn(
"h-4 w-4",
saveLoading ? "animate-spin" : "animate-wiggle"
isBuilding || saveLoading ? "animate-spin" : "animate-wiggle"
)}
/>
{saveLoading ? "Saving..." : "Saved"}
{printByBuildStatus()}
</div>
</Tooltip>
</div>

View file

@ -1,5 +1,5 @@
import Convert from "ansi-to-html";
import { useMemo, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import Markdown from "react-markdown";
import rehypeMathjax from "rehype-mathjax";
import remarkGfm from "remark-gfm";
@ -23,9 +23,23 @@ export default function ChatMessage({
const template = chat.template;
const [promptOpen, setPromptOpen] = useState(false);
const chat_message = chat.message.toString();
useEffect(() => {
const element = document.getElementById("last-chat-message");
if (element) {
setTimeout(() => {
element.scrollIntoView({ behavior: "smooth" });
}, 200);
}
}, [lastMessage]);
return (
<>
<div
className={classNames("form-modal-chat-position", chat.isSend ? "" : " ")}
className={classNames(
"form-modal-chat-position",
chat.isSend ? "" : " "
)}
>
<div className={classNames("form-modal-chatbot-icon ")}>
{!chat.isSend ? (
@ -130,7 +144,10 @@ export default function ChatMessage({
image:
"https://curl.se/logo/curl-symbol-transparent.png",
language: (match && match[1]) || "",
code: String(children).replace(/\n$/, ""),
code: String(children).replace(
/\n$/,
""
),
},
]}
activeTab={"0"}
@ -183,7 +200,8 @@ export default function ChatMessage({
<IconComponent
name="ChevronDown"
className={
"h-3 w-3 transition-all " + (promptOpen ? "rotate-180" : "")
"h-3 w-3 transition-all " +
(promptOpen ? "rotate-180" : "")
}
/>
</button>
@ -226,5 +244,7 @@ export default function ChatMessage({
</div>
)}
</div>
<div id={lastMessage ? "last-chat-message" : ""}></div>
</>
);
}

View file

@ -124,6 +124,7 @@ function ApiInterceptor() {
if (error?.response?.status === 500) {
const vertices = useFlowStore.getState().verticesBuild;
useFlowStore.getState().updateBuildStatus(vertices, BuildStatus.BUILT);
useFlowStore.getState().setIsBuilding(false);
}
}

View file

@ -83,7 +83,6 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
if (saveTimeoutId) {
clearTimeout(saveTimeoutId);
}
set({ saveLoading: true });
// Set up a new timeout.
saveTimeoutId = setTimeout(() => {
if (get().currentFlow) {
@ -92,10 +91,11 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
true
);
}
}, 300); // Delay of 300ms.
set({ saveLoading: true });
}, 1000); // Delay of 1000ms.
},
saveFlow: (flow: FlowType, silent?: boolean) => {
set({ saveLoading: true })
set({ saveLoading: true });
return new Promise<void>((resolve, reject) => {
updateFlowInDatabase(flow)
.then((updatedFlow) => {
@ -117,7 +117,7 @@ const useFlowsManagerStore = create<FlowsManagerStoreType>((set, get) => ({
//update tabs state
resolve();
set({ saveLoading: false })
set({ saveLoading: false });
}
})
.catch((err) => {

View file

@ -49,6 +49,7 @@ export async function buildVertices({
const verticesIds = vertices_layers.flat();
useFlowStore.getState().updateBuildStatus(verticesIds, BuildStatus.TO_BUILD);
useFlowStore.getState().updateVerticesBuild(verticesIds);
useFlowStore.getState().setIsBuilding(true);
// Set each vertex state to building
const buildResults: Array<boolean> = [];
@ -76,6 +77,7 @@ export async function buildVertices({
if (onBuildComplete) {
const allNodesValid = buildResults.every((result) => result);
onBuildComplete(allNodesValid);
useFlowStore.getState().setIsBuilding(false);
}
}