Skip to content

Commit

Permalink
#1483 - first round of bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
boriskovar-m2ms committed Nov 25, 2024
1 parent 1e8a744 commit 50c3eca
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 64 deletions.
114 changes: 101 additions & 13 deletions js/components/header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Created by abradley on 14/03/2018.
*/

import React, { memo, useContext, forwardRef, useState, useEffect } from 'react';
import React, { memo, useContext, forwardRef, useState, useEffect, useCallback } from 'react';
import {
Grid,
makeStyles,
Expand Down Expand Up @@ -40,7 +40,7 @@ import {
} from '@material-ui/icons';
import { HeaderContext } from './headerContext';
import { Button } from '../common';
import { URLS } from '../routes/constants';
import { base_url, URLS } from '../routes/constants';
import { useCombinedRefs } from '../../utils/refHelpers';
import { ComputeSize } from '../../utils/computeSize';
import { DJANGO_CONTEXT } from '../../utils/djangoContext';
Expand All @@ -58,15 +58,27 @@ import { setOpenDiscourseErrorModal } from '../../reducers/api/actions';
import { lockLayout, resetCurrentLayout } from '../../reducers/layout/actions';
import { ChangeLayoutButton } from './changeLayoutButton';
import { layouts } from '../../reducers/layout/layouts';
import { setOpenSnapshotSavingDialog } from '../snapshot/redux/actions';
import { activateSnapshotDialog } from '../snapshot/redux/dispatchActions';
import { setAddButton, setProjectModalIsLoading } from '../projects/redux/actions';
import {
setDisableRedirect,
setDontShowShareSnapshot,
setOpenSnapshotSavingDialog,
setSnapshotEditDialogOpen,
setSnapshotToBeEdited
} from '../snapshot/redux/actions';
import { activateSnapshotDialog, createNewSnapshot } from '../snapshot/redux/dispatchActions';
import { setAddButton, setCurrentSnapshot, setProjectModalIsLoading } from '../projects/redux/actions';
import { getVersions } from '../../utils/version';
import { AddProjectDetail } from '../projects/addProjectDetail';
import { ServicesStatusWrapper } from '../services';
import { COMPANIES, get_logo } from '../funders/constants';
import { setEditTargetDialogOpen } from '../target/redux/actions';
import { Upload } from '@mui/icons-material';
import { SnapshotType } from '../projects/redux/constants';
import { NglContext } from '../nglView/nglProvider';
import { VIEWS } from '../../constants/constants';
import moment from 'moment';
import { ToastContext } from '../toast';
import { api } from '../../utils/api';

const useStyles = makeStyles(theme => ({
padding: {
Expand Down Expand Up @@ -117,6 +129,9 @@ export default memo(
const classes = useStyles();
const { headerNavbarTitle, setHeaderNavbarTitle, headerButtons } = useContext(HeaderContext);

const { nglViewList, getNglView } = useContext(NglContext);
const stage = getNglView(VIEWS.MAJOR_VIEW) && getNglView(VIEWS.MAJOR_VIEW).stage;

const [openMenu, setOpenMenu] = useState(false);
const [openFunders, setOpenFunders] = useState(false);
const [openTrackingModal, setOpenTrackingModal] = useState(false);
Expand All @@ -137,10 +152,15 @@ export default memo(

const selectedLayoutName = useSelector(state => state.layoutReducers.selectedLayoutName);

const currentSnapshot = useSelector(state => state.projectReducers.currentSnapshot);
const currentSnapshotId = currentSnapshot && currentSnapshot.id;

const discourseAvailable = isDiscourseAvailable();
const targetDiscourseVisible = discourseAvailable && targetName;
const projectDiscourseVisible = discourseAvailable && currentProject && currentProject.title;

const { toastError, toastInfo } = useContext(ToastContext);

useEffect(() => {
setOpenFunders(isFundersLink);
}, [isFundersLink]);
Expand All @@ -158,6 +178,46 @@ export default memo(
window.open(link, '_blank');
};

const createSnapshot = useCallback(
(title, description) => {
if (!currentSnapshotId || !currentProject || !title || !description) return;
// Prepare snapshot data
const type = SnapshotType.MANUAL;
const author = DJANGO_CONTEXT['pk'] || null;
const parent = currentSnapshotId;
const session_project = currentProject.projectID;

// Prevents redirect and displaying of share snapshot dialog
dispatch(setDisableRedirect(true));
dispatch(setDontShowShareSnapshot(true));

// With the above flags set, createNewSnapshot returns the ID of newly created snapshot as the second item in the array
return dispatch(
createNewSnapshot({
title,
description,
type,
author,
parent,
session_project,
nglViewList,
stage,
overwriteSnapshot: false,
createDiscourse: false
})
);
},
[currentProject, currentSnapshotId, dispatch, nglViewList, stage]
);

const editSnapshot = useCallback(
snapshotCopy => {
dispatch(setSnapshotToBeEdited(snapshotCopy));
dispatch(setSnapshotEditDialogOpen(true));
},
[dispatch]
);

let authListItem;

let username = null;
Expand Down Expand Up @@ -308,15 +368,43 @@ export default memo(
<Button
key="saveSnapshot"
color="primary"
onClick={() => {
dispatch(activateSnapshotDialog(DJANGO_CONTEXT['pk']));
openSaveSnapshotModal === false
? dispatch(setOpenSnapshotSavingDialog(true))
: dispatch(setOpenSnapshotSavingDialog(false));
openSaveSnapshotModal ?? dispatch(setOpenSnapshotSavingDialog(false));
isProjectModalLoading ?? dispatch(setProjectModalIsLoading(false));
onClick={async () => {
// Prevents redirect and displaying of share snapshot dialog
dispatch(setDisableRedirect(true));
dispatch(setDontShowShareSnapshot(true));

dispatch(setAddButton(false));
const title = moment().format('-- YYYY-MM-DD -- HH:mm:ss');
const description = `snapshot generated by ${DJANGO_CONTEXT['username']}`;
createSnapshot(title, description)
.then(newSnapshotId => {
const options = {
link: {
linkAction: editSnapshot,
linkText: 'Click to edit',
linkParams: [{ id: newSnapshotId, title: title, description: description }]
}
};
api({ url: `${base_url}/api/snapshots/${newSnapshotId}` }).then(snapshotResponse => {
dispatch(
setCurrentSnapshot({
id: snapshotResponse.data.id,
type: snapshotResponse.data.type,
title: snapshotResponse.data.title,
author: snapshotResponse.data.author,
description: snapshotResponse.data.description,
created: snapshotResponse.data.created,
children: snapshotResponse.data.children,
parent: snapshotResponse.data.parent,
data: snapshotResponse.data.data
})
);
toastInfo('New snapshot created. Switching to selected snapshot.', options);
});
})
.catch(err => {
toastError('Error creating new snapshot. Unable to switch to selected snapshot.');
console.error(`Save snapshot - error: ${err}`);
});
}}
startIcon={<Save />}
>
Expand Down
43 changes: 21 additions & 22 deletions js/components/preview/projectHistoryPanel/ProjectHistory.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export const ProjectHistory = memo(({ showFullHistory, graphKey, expanded, onExp
const [tryToOpen, setTryToOpen] = useState(false);
const [transitionToSnapshot, setTransitionToSnapshot] = useState(null);

const { toastSuccess, toastError, toastInfo } = useContext(ToastContext);
const { toastError, toastInfo } = useContext(ToastContext);

const [jobPopupInfo, setJobPopupInfo] = useState({
hash: null,
Expand All @@ -129,9 +129,8 @@ export const ProjectHistory = memo(({ showFullHistory, graphKey, expanded, onExp
}, []);

const createSnapshot = useCallback(
title => {
(title, description) => {
// Prepare snapshot data
const description = `snapshot generated by ${DJANGO_CONTEXT['username']}`;
const type = SnapshotType.MANUAL;
const author = DJANGO_CONTEXT['pk'] || null;
const parent = currentSnapshotID;
Expand All @@ -156,13 +155,6 @@ export const ProjectHistory = memo(({ showFullHistory, graphKey, expanded, onExp
createDiscourse: false
})
);
// Create new snapshot
// const newSnapshot = await dispatch(getSnapshotAttributesByID(snapshotId));

// Trigger graph rerender
// dispatch(refreshJobsData());

// return newSnapshot;
},
[currentSessionProject.projectID, currentSnapshotID, dispatch, nglViewList, stage]
);
Expand All @@ -182,18 +174,24 @@ export const ProjectHistory = memo(({ showFullHistory, graphKey, expanded, onExp
if (modifiedResult) {
console.log(`ProjectHistory - useEffect - save first and then switch to snapshot`);
const title = moment().format('-- YYYY-MM-DD -- HH:mm:ss');
createSnapshot(title).then(newSnapshotId => {
const options = {
link: {
linkAction: editSnapshot,
linkText: 'Click to edit',
linkParams: [{ id: newSnapshotId, title: title }]
}
};
dispatch(changeSnapshot(sessionProjectID, transitionToSnapshot.hash, stage));
setTryToOpen(false);
toastInfo('New snapshot created. Switching to selected snapshot.', options);
});
const description = `snapshot generated by ${DJANGO_CONTEXT['username']}`;
createSnapshot(title, description)
.then(newSnapshotId => {
const options = {
link: {
linkAction: editSnapshot,
linkText: 'Click to edit',
linkParams: [{ id: newSnapshotId, title: title, description: description }]
}
};
dispatch(changeSnapshot(sessionProjectID, transitionToSnapshot.hash, stage));
setTryToOpen(false);
toastInfo('New snapshot created. Switching to selected snapshot.', options);
})
.catch(err => {
toastError('Error creating new snapshot. Unable to switch to selected snapshot.');
console.error(`ProjectHistory - useEffect - createSnapshot - error: ${err}`);
});
} else if (!modifiedResult) {
console.log(`ProjectHistory - useEffect - switch to snapshot`);
dispatch(changeSnapshot(sessionProjectID, transitionToSnapshot.hash, stage));
Expand All @@ -210,6 +208,7 @@ export const ProjectHistory = memo(({ showFullHistory, graphKey, expanded, onExp
nglViewList,
sessionProjectID,
stage,
toastError,
toastInfo,
transitionToSnapshot,
tryToOpen
Expand Down
32 changes: 27 additions & 5 deletions js/components/preview/projectHistoryPanel/editSnapshotDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,24 +87,29 @@ export const EditSnapshotDialog = () => {
if (values.name === '') {
errors.name = 'Required';
}
if (values.description === '') {
errors.description = 'Required';
}

return errors;
};

const onSubmitForm = async ({ name }) => {
const onSubmitForm = async ({ name, description }) => {
snapshotToBeEdited &&
api({
url: `${base_url}/api/snapshots/${snapshotToBeEdited.id}/`,
method: METHOD.PATCH,
data: { title: name }
data: { title: name, description: description }
})
.then(resp => {
snapshotToBeEdited.title = name;
dispatch(addToastMessage({ text: `Snapshot renamed successfully to ${name}`, level: TOAST_LEVELS.SUCCESS }));
snapshotToBeEdited.description = description;
dispatch(addToastMessage({ text: `Snapshot saved successfully.`, level: TOAST_LEVELS.SUCCESS }));
onClose();
})
.catch(err => {
dispatch(addToastMessage({ text: 'Error renaming snapshot', level: TOAST_LEVELS.ERROR }));
dispatch(addToastMessage({ text: 'Saving snapshot failed.', level: TOAST_LEVELS.ERROR }));
console.error(`Error while saving the snapshot: ${err}`);
});
};

Expand All @@ -120,7 +125,10 @@ export const EditSnapshotDialog = () => {
</div>
<div className={classes.bodyPopup}>
<Formik
initialValues={{ name: snapshotToBeEdited?.title ? snapshotToBeEdited?.title : '' }}
initialValues={{
name: snapshotToBeEdited?.title ? snapshotToBeEdited?.title : '',
description: snapshotToBeEdited?.description ? snapshotToBeEdited?.description : ''
}}
onSubmit={onSubmitForm}
validate={validate}
>
Expand All @@ -141,6 +149,20 @@ export const EditSnapshotDialog = () => {
autoComplete="off"
/>
</Grid>
<Grid item style={{ display: 'flex', alignItems: 'center' }}>
<label htmlFor="name" style={{ marginRight: '1rem' }}>
Description:
</label>
<Field
component={TextField}
type="text"
name="description"
variant="standard"
margin="none"
disabled={isSubmitting}
autoComplete="off"
/>
</Grid>
</Grid>
<Grid container justifyContent="flex-end" direction="row">
<Grid>
Expand Down
7 changes: 3 additions & 4 deletions js/components/projects/redux/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,9 @@ export const setIsLoadingTree = isLoading => ({
payload: isLoading
});

export const setCurrentSnapshotTree = tree => ({
type: constants.SET_CURRENT_SNAPSHOT_TREE,
payload: tree
});
export const setCurrentSnapshotTree = tree => {
return { type: constants.SET_CURRENT_SNAPSHOT_TREE, payload: tree };
};

export const setCurrentSnapshotList = list => ({
type: constants.SET_CURRENT_SNAPSHOT_LIST,
Expand Down
20 changes: 0 additions & 20 deletions js/components/snapshot/withSnapshotManagement.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,26 +70,6 @@ export const withSnapshotManagement = WrappedComponent => {
}
}
setHeaderButtons([
!target && currentSnapshotID && (
<Button
key="restoreSnapshot"
color="primary"
onClick={() =>
dispatch(
restoreSnapshotActions({
nglViewList,
projectId: sessionProjectId,
snapshotId: currentSnapshot.id,
history
})
)
}
startIcon={<Restore />}
disabled={disableShareButton || false}
>
Restore
</Button>
),
<Button
key="shareSnapshot"
color="primary"
Expand Down

0 comments on commit 50c3eca

Please sign in to comment.