feat: add build in progress modal when trying to exit (#3695)

* Changed store to stop the isBuilding state as well

* Create Build In Progress modal

* Use blocker to stop if its building as well
This commit is contained in:
Lucas Oliveira 2024-09-05 10:50:12 -03:00 committed by GitHub
commit a4dc5381b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 80 additions and 23 deletions

View file

@ -0,0 +1,26 @@
import ConfirmationModal from "../confirmationModal";
export function BuildInProgressModal({
onStopBuild,
onCancel,
}: {
onStopBuild: () => void;
onCancel: () => void;
}): JSX.Element {
return (
<ConfirmationModal
open={true}
onClose={onCancel}
title="Build in Progress"
cancelText="Cancel"
confirmationText="Stop Build"
onConfirm={onStopBuild}
onCancel={onCancel}
size="x-small"
>
<ConfirmationModal.Content>
The flow is currently building. Do you want to stop the build and exit?
</ConfirmationModal.Content>
</ConfirmationModal>
);
}

View file

@ -8,6 +8,7 @@ import { customStringify } from "@/utils/reactflowUtils";
import { useEffect } from "react";
import { useBlocker, useParams } from "react-router-dom";
import FlowToolbar from "../../components/chatComponent";
import { BuildInProgressModal } from "../../modals/buildInProgressModal";
import { useDarkStore } from "../../stores/darkStore";
import useFlowStore from "../../stores/flowStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
@ -23,7 +24,9 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
customStringify(currentFlow) !== customStringify(currentSavedFlow) &&
(currentFlow?.data?.nodes?.length ?? 0) > 0;
const blocker = useBlocker(changesNotSaved);
const isBuilding = useFlowStore((state) => state.isBuilding);
const blocker = useBlocker(changesNotSaved || isBuilding);
const version = useDarkStore((state) => state.version);
const setOnFlowPage = useFlowStore((state) => state.setOnFlowPage);
const { id } = useParams();
@ -41,13 +44,30 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
const autoSaving = useFlowsManagerStore((state) => state.autoSaving);
const stopBuilding = useFlowStore((state) => state.stopBuilding);
const handleSave = () => {
saveFlow().then(() => (blocker.proceed ? blocker.proceed() : null));
};
const handleStopBuild = () => {
stopBuilding();
if (blocker.proceed) blocker.proceed();
};
const handleExit = () => {
if (isBuilding) {
// Do nothing, let the blocker handle it
} else if (changesNotSaved) {
if (blocker.proceed) blocker.proceed();
} else {
navigate("/all");
}
};
useEffect(() => {
const handleBeforeUnload = (event: BeforeUnloadEvent) => {
if (changesNotSaved) {
if (changesNotSaved || isBuilding) {
event.preventDefault();
event.returnValue = ""; // Required for Chrome
}
@ -58,7 +78,7 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
return () => {
window.removeEventListener("beforeunload", handleBeforeUnload);
};
}, [changesNotSaved, navigate]);
}, [changesNotSaved, isBuilding]);
// Set flow tab id
useEffect(() => {
@ -118,26 +138,36 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
</a>
)}
</div>
{blocker.state === "blocked" && currentSavedFlow && (
<SaveChangesModal
onSave={handleSave}
onCancel={() => (blocker.reset ? blocker.reset() : null)}
onProceed={() => (blocker.proceed ? blocker.proceed() : null)}
flowName={currentSavedFlow.name}
unsavedChanges={changesNotSaved}
lastSaved={
updatedAt
? new Date(updatedAt).toLocaleString("en-US", {
hour: "numeric",
minute: "numeric",
second: "numeric",
month: "numeric",
day: "numeric",
})
: undefined
}
autoSave={autoSaving}
/>
{blocker.state === "blocked" && (
<>
{isBuilding && (
<BuildInProgressModal
onStopBuild={handleStopBuild}
onCancel={() => blocker.reset?.()}
/>
)}
{!isBuilding && currentSavedFlow && (
<SaveChangesModal
onSave={handleSave}
onCancel={() => blocker.reset?.()}
onProceed={handleExit}
flowName={currentSavedFlow.name}
unsavedChanges={changesNotSaved}
lastSaved={
updatedAt
? new Date(updatedAt).toLocaleString("en-US", {
hour: "numeric",
minute: "numeric",
second: "numeric",
month: "numeric",
day: "numeric",
})
: undefined
}
autoSave={autoSaving}
/>
)}
</>
)}
</>
);

View file

@ -81,6 +81,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
isBuilding: false,
stopBuilding: () => {
get().buildController.abort();
set({ isBuilding: false });
},
isPending: true,
setHasIO: (hasIO) => {