From 4c1888e9d0d752edb9db845f601cf446845f1d47 Mon Sep 17 00:00:00 2001 From: Nicholas Lee Date: Wed, 24 Dec 2025 17:14:13 -0800 Subject: [PATCH] fix: added unsaved changes guard to new project butotn, and fixed bug with annotations not being saved --- .../Buttons/CreateProjectButton.tsx | 49 ++++++++++++++----- .../src/helpers/Annotation.helpers.tsx | 7 ++- .../src/pages/Study/hooks/useSaveStudy.tsx | 4 +- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/compose/neurosynth-frontend/src/components/Buttons/CreateProjectButton.tsx b/compose/neurosynth-frontend/src/components/Buttons/CreateProjectButton.tsx index 8555387f..07f37de9 100644 --- a/compose/neurosynth-frontend/src/components/Buttons/CreateProjectButton.tsx +++ b/compose/neurosynth-frontend/src/components/Buttons/CreateProjectButton.tsx @@ -1,16 +1,17 @@ import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; -import { ButtonGroup } from '@mui/material'; import LoadingButton from 'components/Buttons/LoadingButton'; +import ConfirmationDialog from 'components/Dialogs/ConfirmationDialog'; import NavToolbarStyles from 'components/Navbar/NavToolbar.styles'; +import { hasUnsavedChanges, unsetUnloadHandler } from 'helpers/BeforeUnload.helpers'; import { useCreateProject } from 'hooks'; import { generateNewProjectData } from 'pages/Project/store/ProjectStore.helpers'; -import { useRef } from 'react'; +import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; const CreateProjectButton: React.FC = () => { const { mutate, isLoading: createProjectIsLoading } = useCreateProject(); const navigate = useNavigate(); - const buttonGroupRef = useRef(null); + const [confirmationDialogIsOpen, setConfirmationDialogIsOpen] = useState(false); const handleCreateProject = () => { mutate(generateNewProjectData('Untitled', ''), { @@ -20,24 +21,48 @@ const CreateProjectButton: React.FC = () => { }); }; + const handleButtonClick = () => { + const unsavedChangesExist = hasUnsavedChanges(); + if (unsavedChangesExist) { + setConfirmationDialogIsOpen(true); + return; + } else { + handleCreateProject(); + } + }; + + const handleConfirmationDialogClose = (ok: boolean | undefined) => { + if (ok) { + unsetUnloadHandler('project'); + unsetUnloadHandler('study'); + unsetUnloadHandler('annotation'); + handleCreateProject(); + } + setConfirmationDialogIsOpen(false); + }; + return ( - + <> + } text="NEW PROJECT" /> - + ); }; diff --git a/compose/neurosynth-frontend/src/helpers/Annotation.helpers.tsx b/compose/neurosynth-frontend/src/helpers/Annotation.helpers.tsx index e37d9102..bf5c1531 100644 --- a/compose/neurosynth-frontend/src/helpers/Annotation.helpers.tsx +++ b/compose/neurosynth-frontend/src/helpers/Annotation.helpers.tsx @@ -8,7 +8,7 @@ export const setAnalysesInAnnotationAsIncluded = async (annotationId: string) => annotationId )) as AxiosResponse; - let notes = (annotation.data.notes || []) as NoteCollectionReturn[]; + const notes = (annotation.data.notes || []) as NoteCollectionReturn[]; await API.NeurostoreServices.AnnotationsService.annotationsIdPut(annotationId, { notes: notes.map((x) => ({ @@ -18,7 +18,10 @@ export const setAnalysesInAnnotationAsIncluded = async (annotationId: string) => ...x.note, // included can be null meaning it has not been instantiated. We only want to set it to true // if it has not been instantiated as that will overwrite the value is the user previously set it to false - included: (x.note as any)?.included === false ? false : true, + // null ?? true === true + // undefined ?? true === true + // false ?? true === false + included: (x.note as any)?.included ?? true, }, })), }); diff --git a/compose/neurosynth-frontend/src/pages/Study/hooks/useSaveStudy.tsx b/compose/neurosynth-frontend/src/pages/Study/hooks/useSaveStudy.tsx index 9319ce26..ee160c39 100644 --- a/compose/neurosynth-frontend/src/pages/Study/hooks/useSaveStudy.tsx +++ b/compose/neurosynth-frontend/src/pages/Study/hooks/useSaveStudy.tsx @@ -128,7 +128,9 @@ const useSaveStudy = () => { const handleUpdateDB = async () => { try { - if (studyHasBeenEdited && annotationIsEdited) { + const newAnalysesWereCreated = storeStudy.analyses.some((analysis) => analysis.isNew); + + if (studyHasBeenEdited && (annotationIsEdited || newAnalysesWereCreated)) { await handleUpdateBothInDB(); } else if (studyHasBeenEdited) { await handleUpdateStudyInDB();