Skip to content

Commit 29e4ff4

Browse files
author
Adriána Kohanová
committed
Merge remote-tracking branch 'remotes/origin/allfunctionality' into #485
2 parents 030155a + bc7ee58 commit 29e4ff4

File tree

10 files changed

+280
-124
lines changed

10 files changed

+280
-124
lines changed

js/components/preview/viewerControls/displayControls/index.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import { NglContext } from '../../../nglView/nglProvider';
99
import {
1010
addComponentRepresentation,
1111
removeComponentRepresentation,
12-
updateComponentRepresentation
12+
updateComponentRepresentation,
13+
changeComponentRepresentation
1314
} from '../../../../reducers/ngl/actions';
1415
import { deleteObject } from '../../../../reducers/ngl/dispatchActions';
1516
import { MOL_REPRESENTATION, OBJECT_TYPE, SELECTION_TYPE } from '../../../nglView/constants';
@@ -71,10 +72,12 @@ export default memo(({ open, onClose }) => {
7172
oldRepresentation.lastKnownID
7273
);
7374
// add new representation to redux
74-
dispatch(addComponentRepresentation(parentKey, newRepresentation));
75+
dispatch(addComponentRepresentation(parentKey, newRepresentation, true));
7576

7677
// remove previous representation from NGL
77-
removeRepresentation(representation, parentKey);
78+
removeRepresentation(representation, parentKey, true);
79+
80+
dispatch(changeComponentRepresentation(parentKey, oldRepresentation, newRepresentation));
7881
};
7982

8083
const addMolecularRepresentation = (parentKey, e) => {
@@ -88,7 +91,7 @@ export default memo(({ open, onClose }) => {
8891
dispatch(addComponentRepresentation(parentKey, newRepresentation));
8992
};
9093

91-
const removeRepresentation = (representation, parentKey) => {
94+
const removeRepresentation = (representation, parentKey, skipTracking) => {
9295
const nglView = getNglView(objectsInView[parentKey].display_div);
9396
const comp = nglView.stage.getComponentsByName(parentKey).first;
9497
let foundedRepresentation = undefined;
@@ -107,7 +110,7 @@ export default memo(({ open, onClose }) => {
107110
// remove from nglReducer and selectionReducer
108111
dispatch(deleteObject(targetObject, nglView.stage, true));
109112
} else {
110-
dispatch(removeComponentRepresentation(parentKey, representation));
113+
dispatch(removeComponentRepresentation(parentKey, representation, skipTracking));
111114
}
112115
}
113116
};

js/components/snapshot/modals/newSnapshotForm.js

+49-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { memo, useState, useContext } from 'react';
2-
import { Grid, makeStyles, Typography } from '@material-ui/core';
2+
import { Grid, makeStyles, Typography, Checkbox, FormControlLabel } from '@material-ui/core';
33
import { useDispatch, useSelector } from 'react-redux';
44
import { DJANGO_CONTEXT } from '../../../utils/djangoContext';
55
import { Form, Formik, Field } from 'formik';
@@ -28,6 +28,9 @@ const useStyles = makeStyles(theme => ({
2828
formControl: {
2929
margin: theme.spacing(1),
3030
width: 400
31+
},
32+
checkbox: {
33+
margin: theme.spacing(0)
3134
}
3235
}));
3336

@@ -36,15 +39,25 @@ export const NewSnapshotForm = memo(({ handleCloseModal }) => {
3639
const [state, setState] = useState();
3740
const dispatch = useDispatch();
3841
const { nglViewList } = useContext(NglContext);
42+
const [overwriteSnapshot, setoverwriteSnapshot] = useState(false);
3943

4044
const currentSnapshot = useSelector(state => state.projectReducers.currentSnapshot);
4145
const currentProject = useSelector(state => state.projectReducers.currentProject);
4246
const isLoadingSnapshotDialog = useSelector(state => state.snapshotReducers.isLoadingSnapshotDialog);
4347
const isForceProjectCreated = useSelector(state => state.projectReducers.isForceProjectCreated);
4448

49+
const currentSnapshotId = currentSnapshot && currentSnapshot.id;
4550
const loggedInUserID = DJANGO_CONTEXT['pk'];
4651
const username = DJANGO_CONTEXT['username'];
4752

53+
const toggleoverwriteSnapshot = () => {
54+
if (overwriteSnapshot === true) {
55+
setoverwriteSnapshot(false);
56+
} else {
57+
setoverwriteSnapshot(true);
58+
}
59+
};
60+
4861
return (
4962
<>
5063
<Typography variant="h3">Snapshot details</Typography>
@@ -73,13 +86,22 @@ export const NewSnapshotForm = memo(({ handleCloseModal }) => {
7386
const parent = isForceProjectCreated === false ? currentSnapshot.id : null;
7487
const session_project = currentProject.projectID;
7588

76-
dispatch(createNewSnapshot({ title, description, type, author, parent, session_project, nglViewList })).catch(
77-
error => {
78-
setState(() => {
79-
throw error;
80-
});
81-
}
82-
);
89+
dispatch(
90+
createNewSnapshot({
91+
title,
92+
description,
93+
type,
94+
author,
95+
parent,
96+
session_project,
97+
nglViewList,
98+
overwriteSnapshot
99+
})
100+
).catch(error => {
101+
setState(() => {
102+
throw error;
103+
});
104+
});
83105
}}
84106
>
85107
{({ submitForm, isSubmitting }) => (
@@ -115,6 +137,25 @@ export const NewSnapshotForm = memo(({ handleCloseModal }) => {
115137
}
116138
/>
117139
</Grid>
140+
{currentSnapshotId && (
141+
<Grid item>
142+
<FormControlLabel
143+
control={
144+
<Checkbox
145+
name="overwrite"
146+
color="primary"
147+
onChange={() => {
148+
toggleoverwriteSnapshot();
149+
}}
150+
/>
151+
}
152+
label="Overwrite current snapshot"
153+
labelPlacement="end"
154+
className={classes.checkbox}
155+
disabled={isLoadingSnapshotDialog || isSubmitting}
156+
/>
157+
</Grid>
158+
)}
118159
</Grid>
119160
<Grid container justify="flex-end" direction="row">
120161
<Grid item>

js/components/snapshot/redux/dispatchActions.js

+85-57
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@ import { base_url, URLS } from '../../routes/constants';
2525
import { resetCurrentSnapshot, setCurrentSnapshot, setForceCreateProject } from '../../projects/redux/actions';
2626
import { selectFirstMolGroup } from '../../preview/moleculeGroups/redux/dispatchActions';
2727
import { reloadDatasetsReducer } from '../../datasets/redux/actions';
28-
import { saveCurrentActionsList } from '../../../reducers/tracking/dispatchActions';
29-
import { sendTrackingActionsByProjectId, manageSendTrackingActions } from '../../../reducers/tracking/dispatchActions';
28+
import {
29+
saveCurrentActionsList,
30+
addCurrentActionsListToSnapshot,
31+
sendTrackingActionsByProjectId,
32+
manageSendTrackingActions
33+
} from '../../../reducers/tracking/dispatchActions';
3034
import { captureScreenOfSnapshot } from '../../userFeedback/browserApi';
3135

3236
export const getListOfSnapshots = () => (dispatch, getState) => {
@@ -179,71 +183,95 @@ export const createInitSnapshotFromCopy = ({
179183
return Promise.reject('ProjectID is missing');
180184
};
181185

182-
export const createNewSnapshot = ({ title, description, type, author, parent, session_project, nglViewList }) => (
183-
dispatch,
184-
getState
185-
) => {
186+
export const createNewSnapshot = ({
187+
title,
188+
description,
189+
type,
190+
author,
191+
parent,
192+
session_project,
193+
nglViewList,
194+
overwriteSnapshot
195+
}) => (dispatch, getState) => {
186196
const state = getState();
187197
const selectedSnapshotToSwitch = state.snapshotReducers.selectedSnapshotToSwitch;
188198
const disableRedirect = state.snapshotReducers.disableRedirect;
199+
const currentSnapshot = state.projectReducers.currentSnapshot;
200+
const currentSnapshotId = currentSnapshot && currentSnapshot.id;
189201

190202
if (!session_project) {
191203
return Promise.reject('Project ID is missing!');
192204
}
193205

194-
let newType = type;
195-
196-
return Promise.all([
197-
dispatch(setIsLoadingSnapshotDialog(true)),
198-
api({ url: `${base_url}/api/snapshots/?session_project=${session_project}&type=INIT` }).then(response => {
199-
if (response.data.count === 0) {
200-
newType = SnapshotType.INIT;
206+
if (overwriteSnapshot === true && currentSnapshotId) {
207+
dispatch(setIsLoadingSnapshotDialog(true));
208+
let project = { projectID: session_project, authorID: author };
209+
210+
return Promise.resolve(dispatch(addCurrentActionsListToSnapshot(currentSnapshot, project, nglViewList))).then(
211+
() => {
212+
if (disableRedirect === false && selectedSnapshotToSwitch != null) {
213+
window.location.replace(`${URLS.projects}${session_project}/${selectedSnapshotToSwitch}`);
214+
} else {
215+
dispatch(setIsLoadingSnapshotDialog(false));
216+
dispatch(setOpenSnapshotSavingDialog(false));
217+
}
201218
}
219+
);
220+
} else {
221+
let newType = type;
202222

203-
return api({
204-
url: `${base_url}/api/snapshots/`,
205-
data: {
206-
title,
207-
description,
208-
type: newType,
209-
author,
210-
parent,
211-
session_project,
212-
data: '[]',
213-
children: []
214-
},
215-
method: METHOD.POST
216-
}).then(res => {
217-
// redirect to project with newest created snapshot /:projectID/:snapshotID
218-
if (res.data.id && session_project) {
219-
let snapshot = { id: res.data.id, title: title };
220-
let project = { projectID: session_project, authorID: author };
221-
222-
Promise.resolve(dispatch(saveCurrentActionsList(snapshot, project, nglViewList))).then(() => {
223-
if (disableRedirect === false) {
224-
// Really bad usage or redirection. Hint for everybody in this line ignore it, but in other parts of code
225-
// use react-router !
226-
window.location.replace(
227-
`${URLS.projects}${session_project}/${
228-
selectedSnapshotToSwitch === null ? res.data.id : selectedSnapshotToSwitch
229-
}`
230-
);
231-
} else {
232-
dispatch(setOpenSnapshotSavingDialog(false));
233-
dispatch(setIsLoadingSnapshotDialog(false));
234-
dispatch(
235-
setSharedSnapshot({
236-
title,
237-
description,
238-
url: `${base_url}${URLS.projects}${session_project}/${res.data.id}`
239-
})
240-
);
241-
}
242-
});
223+
return Promise.all([
224+
dispatch(setIsLoadingSnapshotDialog(true)),
225+
api({ url: `${base_url}/api/snapshots/?session_project=${session_project}&type=INIT` }).then(response => {
226+
if (response.data.count === 0) {
227+
newType = SnapshotType.INIT;
243228
}
244-
});
245-
})
246-
]);
229+
230+
return api({
231+
url: `${base_url}/api/snapshots/`,
232+
data: {
233+
title,
234+
description,
235+
type: newType,
236+
author,
237+
parent,
238+
session_project,
239+
data: '[]',
240+
children: []
241+
},
242+
method: METHOD.POST
243+
}).then(res => {
244+
// redirect to project with newest created snapshot /:projectID/:snapshotID
245+
if (res.data.id && session_project) {
246+
let snapshot = { id: res.data.id, title: title };
247+
let project = { projectID: session_project, authorID: author };
248+
249+
Promise.resolve(dispatch(saveCurrentActionsList(snapshot, project, nglViewList))).then(() => {
250+
if (disableRedirect === false) {
251+
// Really bad usage or redirection. Hint for everybody in this line ignore it, but in other parts of code
252+
// use react-router !
253+
window.location.replace(
254+
`${URLS.projects}${session_project}/${
255+
selectedSnapshotToSwitch === null ? res.data.id : selectedSnapshotToSwitch
256+
}`
257+
);
258+
} else {
259+
dispatch(setOpenSnapshotSavingDialog(false));
260+
dispatch(setIsLoadingSnapshotDialog(false));
261+
dispatch(
262+
setSharedSnapshot({
263+
title,
264+
description,
265+
url: `${base_url}${URLS.projects}${session_project}/${res.data.id}`
266+
})
267+
);
268+
}
269+
});
270+
}
271+
});
272+
})
273+
]);
274+
}
247275
};
248276

249277
export const activateSnapshotDialog = (loggedInUserID = undefined, finallyShareSnapshot = false) => (
@@ -329,7 +357,7 @@ export const createNewSnapshotWithoutStateModification = ({
329357

330358
let snapshot = { id: res.data.id, title: title };
331359
let project = { projectID: session_project, authorID: author };
332-
dispatch(saveCurrentActionsList(snapshot, project, nglViewList));
360+
dispatch(saveCurrentActionsList(snapshot, project, nglViewList, true));
333361
}
334362
});
335363
});

js/index.js

-22
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { DJANGO_CONTEXT } from './utils/djangoContext';
55
// Sentry logging
66
import { init, configureScope } from '@sentry/browser';
77
// Setup log rocket logging
8-
import LogRocket from 'logrocket';
98
import { Provider } from 'react-redux';
109
import { applyMiddleware, createStore } from 'redux';
1110
import { rootReducer } from './reducers/rootReducer';
@@ -16,27 +15,6 @@ import { composeWithDevTools } from 'redux-devtools-extension';
1615

1716
require('react-hot-loader/patch');
1817

19-
if (process.env.NODE_ENV === 'production') {
20-
LogRocket.init('eoalzb/fragalysis');
21-
// This is the log rocket setup
22-
23-
LogRocket.identify(DJANGO_CONTEXT['username'], {
24-
pk: DJANGO_CONTEXT['pk'],
25-
name: DJANGO_CONTEXT['name'],
26-
email: DJANGO_CONTEXT['email']
27-
});
28-
29-
init({
30-
dsn: 'https://27fa0675f555431aa02ca552e93d8cfb@sentry.io/1298290'
31-
});
32-
33-
LogRocket.getSessionURL(sessionURL => {
34-
configureScope(scope => {
35-
scope.setExtra('logRocketURL', sessionURL);
36-
});
37-
});
38-
}
39-
4018
const middlewareEnhancer = applyMiddleware(
4119
//loggerMiddleware,
4220
thunkMiddleware,

js/reducers/ngl/actions.js

+13-4
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,24 @@ export const updateComponentRepresentation = (objectInViewID, representationID,
2020
change
2121
});
2222

23-
export const addComponentRepresentation = (objectInViewID, newRepresentation) => ({
23+
export const addComponentRepresentation = (objectInViewID, newRepresentation, skipTracking = false) => ({
2424
type: CONSTANTS.ADD_COMPONENT_REPRESENTATION,
2525
newRepresentation,
26-
objectInViewID
26+
objectInViewID,
27+
skipTracking
2728
});
2829

29-
export const removeComponentRepresentation = (objectInViewID, representation) => ({
30+
export const removeComponentRepresentation = (objectInViewID, representation, skipTracking = false) => ({
3031
type: CONSTANTS.REMOVE_COMPONENT_REPRESENTATION,
3132
representation,
33+
objectInViewID,
34+
skipTracking
35+
});
36+
37+
export const changeComponentRepresentation = (objectInViewID, oldRepresentation, newRepresentation) => ({
38+
type: CONSTANTS.CHANGE_COMPONENT_REPRESENTATION,
39+
oldRepresentation,
40+
newRepresentation,
3241
objectInViewID
3342
});
3443

@@ -91,5 +100,5 @@ export const removeMoleculeOrientation = moleculeGroupID => ({
91100

92101
export const addToPdbCache = (name, cacheItem) => ({
93102
type: CONSTANTS.ADD_TO_PDB_CACHE,
94-
payload: {name: name, cacheItem: cacheItem}
103+
payload: { name: name, cacheItem: cacheItem }
95104
});

js/reducers/ngl/constants.js

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const CONSTANTS = {
77
UPDATE_COMPONENT_REPRESENTATION: prefix + 'UPDATE_COMPONENT_REPRESENTATION',
88
REMOVE_COMPONENT_REPRESENTATION: prefix + 'REMOVE_COMPONENT_REPRESENTATION',
99
ADD_COMPONENT_REPRESENTATION: prefix + 'ADD_COMPONENT_REPRESENTATION',
10+
CHANGE_COMPONENT_REPRESENTATION: prefix + 'CHANGE_COMPONENT_REPRESENTATION',
1011

1112
SET_NGL_VIEW_PARAMS: prefix + 'SET_NGL_VIEW_PARAMS',
1213
SET_ORIENTATION: prefix + 'SET_ORIENTATION',

0 commit comments

Comments
 (0)