Skip to content

Commit

Permalink
feat: update edit study page
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoalee committed Oct 1, 2024
1 parent 966daa3 commit 8e89dcb
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 55 deletions.
38 changes: 38 additions & 0 deletions compose/neurosynth-frontend/src/helpers/BeforeUnload.helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
enum EUnloadStatus {
STUDYSTORE = 'study-store-unsaved-changes',
PROJECTSTORE = 'project-store-unsaved-changes',
ANNOTATIONSTORE = 'annotation-store-unsaved-changes',
}

const onUnloadHandler = (event: BeforeUnloadEvent) => {
return (event.returnValue = 'Are you sure you want to leave?');
};

export const setUnloadHandler = (store: 'project' | 'study' | 'annotation') => {
if (store === 'project') {
window.sessionStorage.setItem(EUnloadStatus.PROJECTSTORE, 'true');
} else if (store === 'study') {
window.sessionStorage.setItem(EUnloadStatus.STUDYSTORE, 'true');
} else if (store === 'annotation') {
window.sessionStorage.setItem(EUnloadStatus.ANNOTATIONSTORE, 'true');
}
if (!window.onbeforeunload) window.onbeforeunload = onUnloadHandler;
};

export const unsetUnloadHandler = (store: 'project' | 'study' | 'annotation') => {
if (store === 'project') {
window.sessionStorage.removeItem(EUnloadStatus.PROJECTSTORE);
} else if (store === 'study') {
window.sessionStorage.removeItem(EUnloadStatus.STUDYSTORE);
} else if (store === 'annotation') {
window.sessionStorage.removeItem(EUnloadStatus.ANNOTATIONSTORE);
}

if (
window.sessionStorage.getItem(EUnloadStatus.PROJECTSTORE) === null &&
window.sessionStorage.getItem(EUnloadStatus.STUDYSTORE) === null &&
window.sessionStorage.getItem(EUnloadStatus.ANNOTATIONSTORE) === null
) {
window.onbeforeunload = null;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ const ExtractionTable: React.FC = () => {
))}
</Box>
<Box>
<Typography sx={{ whiteSpace: 'nowrap' }}>
<Box sx={{ whiteSpace: 'nowrap' }}>
{columnFilters.length > 0 ? (
<Typography>
Viewing {table.getFilteredRowModel().rows.length} /{' '}
Expand All @@ -428,7 +428,7 @@ const ExtractionTable: React.FC = () => {
) : (
<Typography>Total: {data.length} studies</Typography>
)}
</Typography>
</Box>
</Box>
</Box>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ import { useParams } from 'react-router-dom';
import API from 'utils/api';
import { create } from 'zustand';
import { TProjectStore } from './ProjectStore.types';

const onUnloadHandler = (event: BeforeUnloadEvent) => {
return (event.returnValue = 'Are you sure you want to leave?');
};
import { setUnloadHandler, unsetUnloadHandler } from 'helpers/BeforeUnload.helpers';

const useProjectStore = create<TProjectStore>()((set, get) => {
return {
Expand Down Expand Up @@ -148,7 +145,7 @@ const useProjectStore = create<TProjectStore>()((set, get) => {

if (existingTimeout && oldDebouncedStoreData.id === prevId)
clearTimeout(existingTimeout);
window.addEventListener('beforeunload', onUnloadHandler);
setUnloadHandler('project');

const newTimeout = setTimeout(async () => {
const { data } = await API.NeurosynthServices.ProjectsService.projectsIdGet(
Expand Down Expand Up @@ -177,7 +174,7 @@ const useProjectStore = create<TProjectStore>()((set, get) => {
{ variant: 'error', persist: true }
);
}
window.removeEventListener('beforeunload', onUnloadHandler);
unsetUnloadHandler('project');
return;
}

Expand Down Expand Up @@ -248,7 +245,7 @@ const useProjectStore = create<TProjectStore>()((set, get) => {
}
},
onSettled: () => {
window.removeEventListener('beforeunload', onUnloadHandler);
unsetUnloadHandler('project');
},
}
);
Expand Down
22 changes: 19 additions & 3 deletions compose/neurosynth-frontend/src/pages/Study/EditStudyPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,19 @@ const EditStudyPage: React.FC = (props) => {
</Box>
<Box sx={EditStudyPageStyles.loadingButtonContainer}>
{/* <EditStudySwapVersionButton /> */}
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Box sx={{ width: '33%', justifyContent: 'flex-start' }}>
<Button color="error" variant="outlined">
Back
</Button>
</Box>
<Box
sx={{
width: '33%',
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-start',
}}
>
<Button
startIcon={<ArrowLeft />}
disableElevation
Expand Down Expand Up @@ -129,8 +141,12 @@ const EditStudyPage: React.FC = (props) => {
</Box>
</Button>
</Box>
<DisplayExtractionTableState />
<EditStudySaveButton />
{/* <Box sx={{ width: '33%', display: 'flex', justifyContent: 'center' }}>
<DisplayExtractionTableState />
</Box> */}
<Box sx={{ width: '33%', display: 'flex', justifyContent: 'flex-end' }}>
<EditStudySaveButton />
</Box>
</Box>
</StateHandlerComponent>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { storeNotesToDBNotes } from 'stores/AnnotationStore.helpers';
import API from 'utils/api';
import { arrayToMetadata } from './EditStudyMetadata';
import { hasDuplicateStudyAnalysisNames, hasEmptyStudyPoints } from './EditStudySaveButton.helpers';
import { unsetUnloadHandler } from 'helpers/BeforeUnload.helpers';

const EditStudySaveButton: React.FC = React.memo((props) => {
const { user } = useAuth0();
Expand Down Expand Up @@ -91,6 +92,8 @@ const EditStudySaveButton: React.FC = React.memo((props) => {
});
updateAnnotationNotes(updatedNotes);
await updateAnnotationInDB();
unsetUnloadHandler('study');
unsetUnloadHandler('annotation');

queryClient.invalidateQueries('studies');
queryClient.invalidateQueries('annotations');
Expand All @@ -105,6 +108,8 @@ const EditStudySaveButton: React.FC = React.memo((props) => {
const handleUpdateStudyInDB = async () => {
try {
await updateStudyInDB(annotationId as string);
unsetUnloadHandler('study');
unsetUnloadHandler('annotation');
queryClient.invalidateQueries('studies');
queryClient.invalidateQueries('annotations');

Expand All @@ -118,6 +123,8 @@ const EditStudySaveButton: React.FC = React.memo((props) => {
const handleUpdateAnnotationInDB = async () => {
try {
await updateAnnotationInDB();
unsetUnloadHandler('study');
unsetUnloadHandler('annotation');
queryClient.invalidateQueries('annotations');
enqueueSnackbar('Annotation saved', { variant: 'success' });
} catch (e) {
Expand Down Expand Up @@ -227,6 +234,9 @@ const EditStudySaveButton: React.FC = React.memo((props) => {
},
});

unsetUnloadHandler('study');
unsetUnloadHandler('annotation');

navigate(`/projects/${projectId}/extraction/studies/${clonedStudyId}/edit`);
enqueueSnackbar('Saved successfully. You are now the owner of this study', {
variant: 'success',
Expand Down Expand Up @@ -271,13 +281,13 @@ const EditStudySaveButton: React.FC = React.memo((props) => {

return (
<LoadingButton
text="save"
text="complete"
isLoading={updateStudyIsLoading || updateAnnotationIsLoading || isCloning}
variant="contained"
color="success"
loaderColor="secondary"
disabled={!studyHasBeenEdited && !annotationHasBeenEdited}
disableElevation
sx={{ width: '280px', height: '36px' }}
sx={{ width: '200px', height: '36px' }}
onClick={handleSave}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ const EditStudyToolbarStyles: Style = {
},
toolbarContainer: {
position: 'absolute',
right: 'calc(-10%)',
right: '-9%',
transform: 'translateX(-8px)',
borderRadius: '4px',
border: '1px solid',
borderColor: 'primary.main',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ import { useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import EditStudyToolbarStyles from './EditStudyToolbar.styles';
import SaveIcon from '@mui/icons-material/Save';
import {
ArrowBack,
ArrowForward,
KeyboardArrowLeft,
KeyboardArrowRight,
} from '@mui/icons-material';

const EditStudyToolbar: React.FC<{ isViewOnly?: boolean }> = ({ isViewOnly = false }) => {
const navigate = useNavigate();
Expand Down Expand Up @@ -197,48 +203,82 @@ const EditStudyToolbar: React.FC<{ isViewOnly?: boolean }> = ({ isViewOnly = fal
</Tooltip>
)}
</Box>
<Box sx={{ marginBottom: '1rem' }}>
<Fab color="secondary" size="small" sx={{ boxShadow: 'none' }}>
<Box sx={{ marginBottom: '0.5rem' }}>
<Button
color="secondary"
variant="contained"
disableElevation
size="small"
sx={{ minWidth: '0', width: '40px', height: '40px' }}
>
<SwapHorizIcon />
</Fab>
</Button>
</Box>
<Box sx={{ marginBottom: '0.5rem' }}>
<Button
onClick={() =>
handleClickStudyListStatus(EExtractionStatus.SAVEDFORLATER)
}
sx={{ minWidth: '0', width: '40px', height: '40px' }}
disableElevation
variant={
extractionStatus?.status === EExtractionStatus.SAVEDFORLATER
? 'contained'
: 'outlined'
}
>
<BookmarkIcon />
</Button>
{/* <Fab color="success" size="small" sx={{ boxShadow: 'none' }}>
</Fab> */}
</Box>
<Box sx={{ marginBottom: '1rem' }}>
<ButtonGroup orientation="vertical">
<Button
variant="contained"
disableElevation
sx={{ minWidth: '0', width: '40px', height: '40px' }}
>
<SaveIcon />
</Button>
{/* <Fab color="success" size="small" sx={{ boxShadow: 'none' }}>
</Fab> */}
</Box>
<Box>
<ButtonGroup
color="info"
orientation="vertical"
sx={{ minWidth: '0px' }}
>
<Button
onClick={() =>
handleClickStudyListStatus(EExtractionStatus.COMPLETED)
}
sx={{ padding: '0.5rem 0', height: '40px' }}
disableElevation
variant={
extractionStatus?.status === EExtractionStatus.COMPLETED
? 'contained'
: 'outlined'
}
// onClick={() =>
// handleClickStudyListStatus(EExtractionStatus.COMPLETED)
// }
sx={{ height: '40px', width: '40px', minWidth: '0' }}
// disableElevation
// variant={
// extractionStatus?.status === EExtractionStatus.COMPLETED
// ? 'contained'
// : 'outlined'
// }
>
<CheckIcon />
<KeyboardArrowLeft />
</Button>
<Button
onClick={() =>
handleClickStudyListStatus(EExtractionStatus.SAVEDFORLATER)
}
sx={{ padding: '0.5rem 0', height: '40px' }}
disableElevation
variant={
extractionStatus?.status === EExtractionStatus.SAVEDFORLATER
? 'contained'
: 'outlined'
}
// onClick={() =>
// handleClickStudyListStatus(EExtractionStatus.SAVEDFORLATER)
// }
sx={{ height: '40px', width: '40px', minWidth: '0' }}
// disableElevation
// variant={
// extractionStatus?.status === EExtractionStatus.SAVEDFORLATER
// ? 'contained'
// : 'outlined'
// }
>
<BookmarkIcon />
<KeyboardArrowRight />
</Button>
</ButtonGroup>
</Box>
<Box sx={{ marginBottom: '1rem' }}>
<Fab color="success" size="small" sx={{ boxShadow: 'none' }}>
<SaveIcon />
</Fab>
</Box>

{/* <Box sx={{ marginBottom: '1rem' }}>
<Tooltip placement="right" title="move to completed">
Expand Down
Loading

0 comments on commit 8e89dcb

Please sign in to comment.