Skip to content

Commit e7e3f9f

Browse files
Merge remote-tracking branch 'remotes/origin/#453' into allfunctionality
2 parents 3a8363d + b519ede commit e7e3f9f

14 files changed

+987
-461
lines changed

js/components/preview/molecule/moleculeList.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ import { useRouteMatch } from 'react-router-dom';
6060
import { setSortDialogOpen } from './redux/actions';
6161
import { setMoleculeList, setAllMolLists } from '../../../reducers/api/actions';
6262
import { AlertModal } from '../../common/Modal/AlertModal';
63-
import { selectMoleculeGroup } from '../moleculeGroups/redux/dispatchActions';
63+
import {selectMoleculeGroup} from '../moleculeGroups/redux/dispatchActions';
64+
import { onSelectMoleculeGroup } from '../moleculeGroups/redux/dispatchActions';
6465

6566
const useStyles = makeStyles(theme => ({
6667
container: {

js/components/preview/viewerControls/displayControls/editRepresentationMenu.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,15 @@ export const EditRepresentationMenu = memo(
4040
const handleRepresentationPropertyChange = throttle((key, value) => {
4141
const r = comp.reprList.find(rep => rep.uuid === representation.uuid || rep.uuid === representation.lastKnownID);
4242
if (r) {
43+
let oldValue = oldRepresentation.params[key];
44+
let change = { key, value, oldValue };
45+
4346
// update in ngl
4447
r.setParameters({ [key]: value });
4548
//update in redux
4649
oldRepresentation.params[key] = value;
47-
dispatch(updateComponentRepresentation(parentKey, oldRepresentation.uuid, oldRepresentation));
50+
51+
dispatch(updateComponentRepresentation(parentKey, oldRepresentation.uuid, oldRepresentation, change));
4852
}
4953
}, 250);
5054

js/components/preview/viewerControls/index.js

+67-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22
* Created by ricgillams on 28/06/2018.
33
*/
44

5-
import React, { memo, useState } from 'react';
5+
import React, { memo, useState, useContext, useEffect, useCallback } from 'react';
6+
import { useDispatch } from 'react-redux';
67
import { Button } from '../../common/Inputs/Button';
7-
import { Settings, Mouse, PersonalVideo } from '@material-ui/icons';
8+
import { Settings, Mouse, PersonalVideo, Undo, Redo } from '@material-ui/icons';
89
import { ButtonGroup, Grid, makeStyles, Tooltip } from '@material-ui/core';
910
import { SettingControls } from './settingsControls';
1011
import DisplayControls from './displayControls/';
1112
import { MouseControls } from './mouseControls';
13+
import { ActionCreators as UndoActionCreators } from 'redux-undo';
14+
import { undoAction, redoAction, getCanRedo, getCanUndo } from '../../../../js/reducers/tracking/dispatchActions';
15+
import { NglContext } from '../../nglView/nglProvider';
1216

1317
const drawers = {
1418
settings: 'settings',
@@ -27,6 +31,10 @@ const useStyles = makeStyles(theme => ({
2731
export const ViewerControls = memo(({}) => {
2832
const [drawerSettings, setDrawerSettings] = useState(JSON.parse(JSON.stringify(initDrawers)));
2933
const classes = useStyles();
34+
const dispatch = useDispatch();
35+
const { nglViewList } = useContext(NglContext);
36+
const [canUndo, setCanUndo] = useState(true);
37+
const [canRedo, setCanRedo] = useState(false);
3038

3139
const openDrawer = key => {
3240
//close all and open selected by key
@@ -38,11 +46,55 @@ export const ViewerControls = memo(({}) => {
3846
setDrawerSettings(JSON.parse(JSON.stringify(initDrawers)));
3947
};
4048

49+
const doUndo = () => {
50+
dispatch(UndoActionCreators.undo());
51+
setCanRedo(dispatch(getCanRedo()));
52+
setCanUndo(dispatch(getCanUndo()));
53+
dispatch(undoAction(nglViewList));
54+
};
55+
56+
const doRedo = () => {
57+
dispatch(UndoActionCreators.redo());
58+
setCanRedo(dispatch(getCanRedo()));
59+
setCanUndo(dispatch(getCanUndo()));
60+
dispatch(redoAction(nglViewList));
61+
};
62+
63+
const handleUserKeyPress = useCallback(e => {
64+
var evtobj = window.event ? window.event : e;
65+
if (evtobj.keyCode === 90 && evtobj.ctrlKey) {
66+
doUndo();
67+
} else if (evtobj.keyCode === 89 && evtobj.ctrlKey) {
68+
doRedo();
69+
}
70+
});
71+
72+
useEffect(() => {
73+
window.addEventListener('keydown', handleUserKeyPress);
74+
75+
return () => {
76+
window.removeEventListener('keydown', handleUserKeyPress);
77+
};
78+
}, [handleUserKeyPress]);
79+
4180
return (
4281
<>
4382
<Grid container justify="center">
4483
<Grid item>
4584
<ButtonGroup variant="contained" color="primary">
85+
<Tooltip title="Undo">
86+
<Button
87+
size="small"
88+
color="primary"
89+
onClick={() => {
90+
doUndo();
91+
}}
92+
className={classes.button}
93+
disabled={!canUndo}
94+
>
95+
<Undo />
96+
</Button>
97+
</Tooltip>
4698
<Tooltip title="Settings controls">
4799
<Button
48100
size="small"
@@ -68,6 +120,19 @@ export const ViewerControls = memo(({}) => {
68120
<Mouse />
69121
</Button>
70122
</Tooltip>
123+
<Tooltip title="Redo">
124+
<Button
125+
size="small"
126+
color="primary"
127+
onClick={() => {
128+
doRedo();
129+
}}
130+
className={classes.button}
131+
disabled={!canRedo}
132+
>
133+
<Redo />
134+
</Button>
135+
</Tooltip>
71136
</ButtonGroup>
72137
</Grid>
73138
</Grid>

js/components/tracking/trackingModal.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export const TrackingModal = memo(({ openModal, onModalClose }) => {
4040
const { nglViewList } = useContext(NglContext);
4141

4242
const actionList = useSelector(state => state.trackingReducers.truck_actions_list);
43-
const orderedActionList = actionList.sort((a, b) => a.timestamp - b.timestamp);
43+
const orderedActionList = (actionList && actionList.sort((a, b) => a.timestamp - b.timestamp)) || [];
4444

4545
if (openModal === undefined) {
4646
console.log('undefined openModal');

js/reducers/ngl/actions.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ export const deleteNglObject = target => ({
1010
target
1111
});
1212

13-
export const updateComponentRepresentation = (objectInViewID, representationID, newRepresentation) => ({
13+
export const updateComponentRepresentation = (objectInViewID, representationID, newRepresentation, change) => ({
1414
type: CONSTANTS.UPDATE_COMPONENT_REPRESENTATION,
1515
representationID,
1616
newRepresentation,
17-
objectInViewID
17+
objectInViewID,
18+
change
1819
});
1920

2021
export const addComponentRepresentation = (objectInViewID, newRepresentation) => ({

js/reducers/rootReducer.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
import { combineReducers } from 'redux';
55
import apiReducers from './api/apiReducers';
66
import nglReducers from './ngl/nglReducers';
7-
import selectionReducers from './selection/selectionReducers';
7+
import { selectionReducers } from './selection/selectionReducers';
88
import { targetReducers } from '../components/target/redux/reducer';
99
import { snapshotReducers } from '../components/snapshot/redux/reducer';
1010
import { previewReducers } from '../components/preview/redux';
1111
import { projectReducers } from '../components/projects/redux/reducer';
1212
import { issueReducers } from '../components/userFeedback/redux/reducer';
1313
import { datasetsReducers } from '../components/datasets/redux/reducer';
14-
import trackingReducers from './tracking/trackingReducers';
14+
import { trackingReducers, undoableTrackingReducers } from './tracking/trackingReducers';
1515

1616
const rootReducer = combineReducers({
1717
apiReducers,
@@ -23,7 +23,8 @@ const rootReducer = combineReducers({
2323
projectReducers,
2424
issueReducers,
2525
datasetsReducers,
26-
trackingReducers
26+
trackingReducers,
27+
undoableTrackingReducers
2728
});
2829

2930
export { rootReducer };

js/reducers/selection/selectionReducers.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const INITIAL_STATE = {
2828
currentVector: null // selected vector smile (ID) of compoundsOfVectors
2929
};
3030

31-
export default function selectionReducers(state = INITIAL_STATE, action = {}) {
31+
export function selectionReducers(state = INITIAL_STATE, action = {}) {
3232
switch (action.type) {
3333
case constants.SET_TO_BUY_LIST:
3434
return Object.assign({}, state, {

js/reducers/tracking/actions.js

+7
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,10 @@ export const setIsTrackingCompoundsRestoring = function(isTrackingCompoundsResto
3434
isTrackingCompoundsRestoring: isTrackingCompoundsRestoring
3535
};
3636
};
37+
38+
export const setIsUndoRedoAction = function(isUndoRedoAction) {
39+
return {
40+
type: constants.SET_IS_UNDO_REDO_ACTION,
41+
isUndoRedoAction: isUndoRedoAction
42+
};
43+
};

js/reducers/tracking/constants.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ export const constants = {
55
APPEND_ACTIONS_LIST: prefix + 'APPEND_ACTIONS_LIST',
66
SET_CURRENT_ACTIONS_LIST: prefix + 'SET_CURRENT_ACTIONS_LIST',
77
SET_IS_TRACKING_COMPOUNDS_RESTORING: prefix + 'SET_IS_TRACKING_COMPOUNDS_RESTORING',
8-
SET_IS_TRACKING_MOLECULES_RESTORING: prefix + 'SET_IS_TRACKING_MOLECULES_RESTORING'
8+
SET_IS_TRACKING_MOLECULES_RESTORING: prefix + 'SET_IS_TRACKING_MOLECULES_RESTORING',
9+
SET_IS_UNDO_REDO_ACTION: prefix + 'SET_IS_UNDO_REDO_ACTION'
910
};
1011

1112
export const actionType = {
@@ -30,7 +31,9 @@ export const actionType = {
3031
COMPOUND_DESELECTED: 'COMPOUND_DESELECTED',
3132
REPRESENTATION_CHANGED: 'REPRESENTATION_CHANGED',
3233
REPRESENTATION_ADDED: 'REPRESENTATION_ADDED',
33-
REPRESENTATION_REMOVED: 'REPRESENTATION_REMOVED'
34+
REPRESENTATION_REMOVED: 'REPRESENTATION_REMOVED',
35+
UNDO: 'UNDO',
36+
REDO: 'REDO'
3437
};
3538

3639
export const actionDescription = {

0 commit comments

Comments
 (0)