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:
parent
46a66a57c1
commit
a4dc5381b2
3 changed files with 80 additions and 23 deletions
26
src/frontend/src/modals/buildInProgressModal/index.tsx
Normal file
26
src/frontend/src/modals/buildInProgressModal/index.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
|
|
@ -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}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
|
|||
isBuilding: false,
|
||||
stopBuilding: () => {
|
||||
get().buildController.abort();
|
||||
set({ isBuilding: false });
|
||||
},
|
||||
isPending: true,
|
||||
setHasIO: (hasIO) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue