Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/origin/#469' into allfunctionality
Browse files Browse the repository at this point in the history
  • Loading branch information
boriskovar-m2ms committed Dec 17, 2020
2 parents 8b7779c + 02190a1 commit 9550632
Show file tree
Hide file tree
Showing 13 changed files with 834 additions and 192 deletions.
110 changes: 80 additions & 30 deletions js/components/projects/projectDetailDrawer/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import React, { memo, useContext } from 'react';
import { IconButton, makeStyles, Drawer, Typography, Grid } from '@material-ui/core';
import React, { memo } from 'react';
import { IconButton, makeStyles, Drawer, Typography, Grid, Box } from '@material-ui/core';
import { Share, Close } from '@material-ui/icons';
import { Gitgraph, templateExtend, TemplateName } from '@gitgraph/react';
import { base_url, URLS } from '../../routes/constants';
import moment from 'moment';
import Modal from '../../common/Modal';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory, useRouteMatch } from 'react-router-dom';
import palette from '../../../theme/palette';
import { setIsOpenModalBeforeExit, setSelectedSnapshotToSwitch, setSharedSnapshot } from '../../snapshot/redux/actions';
import { NglContext } from '../../nglView/nglProvider';
import Gallery from 'react-grid-gallery';

const useStyles = makeStyles(theme => ({
drawer: {
Expand Down Expand Up @@ -72,46 +71,67 @@ const options = {
export const ProjectDetailDrawer = memo(({ showHistory, setShowHistory }) => {
const [open, setOpen] = React.useState(false);
const classes = useStyles();
let history = useHistory();
let match = useRouteMatch();
const { nglViewList } = useContext(NglContext);
const dispatch = useDispatch();
const projectID = match && match.params && match.params.projectId;
const currentProjectID = useSelector(state => state.projectReducers.currentProject.projectID);
const currentSnapshotID = useSelector(state => state.projectReducers.currentSnapshot.id);
const currentSnapshotList = useSelector(state => state.projectReducers.currentSnapshotList);
const currentSnapshotTree = useSelector(state => state.projectReducers.currentSnapshotTree);
const isLoadingTree = useSelector(state => state.projectReducers.isLoadingTree);
const currentSnapshotImageList = useSelector(state => state.trackingReducers.snapshotActionImageList);

const handleClickOnCommit = commit => {
dispatch(setSelectedSnapshotToSwitch(commit.hash));
dispatch(setIsOpenModalBeforeExit(true));
};

const commitFunction = ({ title, description, photo, author, email, hash, isSelected, created }) => ({
const commitFunction = ({ title, description, photo, author, email, hash, isSelected, created, images }) => ({
hash: `${hash}`,
subject: `${title}`,
body: (
<>
{/*<img src={require('../../../img/xchemLogo.png')} className={classes.thumbnail} onClick={() => setOpen(true)} />*/}
{/*<IconButton>*/}
{/* <Delete />*/}
{/*</IconButton>*/}
{/*<br />*/}
<Typography variant="caption">
<b>{`${moment(created).format('LLL')}, ${email}: `}</b>
{description}
</Typography>
<IconButton
disabled={!currentProjectID || !hash}
onClick={() => {
dispatch(
setSharedSnapshot({ title, description, url: `${base_url}${URLS.projects}${currentProjectID}/${hash}` })
);
}}
>
<Share />
</IconButton>
<Grid container justify="flex-start" direction="row" alignItems="center" className={classes.title}>
{
<Box xs={6} flexShrink={1} className={classes.titleMargin}>
{/*<img src={require('../../../img/xchemLogo.png')} className={classes.thumbnail} onClick={() => setOpen(true)} />*/}
{/*<IconButton>*/}
{/* <Delete />*/}
{/*</IconButton>*/}
{/*<br />*/}
<Typography variant="caption">
<b>{`${moment(created).format('LLL')}, ${email}: `}</b>
{description}
</Typography>
</Box>
}
{
<IconButton
disabled={!currentProjectID || !hash}
onClick={() => {
dispatch(
setSharedSnapshot({
title,
description,
url: `${base_url}${URLS.projects}${currentProjectID}/${hash}`
})
);
}}
>
<Share />
</IconButton>
}
{
<Grid item xs={2}>
<Gallery
images={images}
enableImageSelection={false}
backdropClosesModal={true}
showImageCount={false}
lightboxWidth={2048}
rowHeight={30}
/>
</Grid>
}
</Grid>
</>
),
onMessageClick: handleClickOnCommit,
Expand All @@ -128,6 +148,20 @@ export const ProjectDetailDrawer = memo(({ showHistory, setShowHistory }) => {
name: node.title
});

let currentSnapshotImage = currentSnapshotImageList.find(i => i.id === node.id);
const nodeImages =
currentSnapshotImage != null
? [
{
src: currentSnapshotImage.image,
thumbnail: currentSnapshotImage.image,
thumbnailWidth: 0,
thumbnailHeight: 0,
caption: currentSnapshotImage.title
}
]
: [];

newBranch.commit(
commitFunction({
title: node.title || '',
Expand All @@ -136,7 +170,8 @@ export const ProjectDetailDrawer = memo(({ showHistory, setShowHistory }) => {
email: (node.author && node.author.email) || '',
hash: node.id,
isSelected: currentSnapshotID === node.id,
created: node.created
created: node.created,
images: nodeImages
})
);

Expand All @@ -150,6 +185,20 @@ export const ProjectDetailDrawer = memo(({ showHistory, setShowHistory }) => {
setShowHistory(false);
};

let image = currentSnapshotTree != null ? currentSnapshotImageList.find(i => i.id === currentSnapshotTree.id) : null;
const images =
image != null
? [
{
src: image.image,
thumbnail: image.image,
thumbnailWidth: 0,
thumbnailHeight: 0,
caption: image.title
}
]
: [];

return (
<>
<Drawer anchor="bottom" open={showHistory} onClose={handleCloseHistory}>
Expand Down Expand Up @@ -187,7 +236,8 @@ export const ProjectDetailDrawer = memo(({ showHistory, setShowHistory }) => {
email: (currentSnapshotTree.author && currentSnapshotTree.author.email) || '',
hash: currentSnapshotTree.id,
isSelected: currentSnapshotID === currentSnapshotTree.id,
created: currentSnapshotTree.created
created: currentSnapshotTree.created,
images
})
);

Expand Down
7 changes: 3 additions & 4 deletions js/components/projects/redux/dispatchActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,9 @@ export const createProjectFromScratch = ({ title, description, target, author, t
});
};

export const createProjectWithoutStateModification = data => dispatch => {
return api({ url: `${base_url}/api/session-projects/`, method: METHOD.POST, data }).then(response => {
return response.data.id;
});
export const createProjectWithoutStateModification = data => async () => {
const response = await api({ url: `${base_url}/api/session-projects/`, method: METHOD.POST, data });
return response.data.id;
};

export const createInitSnapshotToProjectWitActions = (session_project, author, parent, target) => (
Expand Down
75 changes: 41 additions & 34 deletions js/components/snapshot/redux/dispatchActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { selectFirstMolGroup } from '../../preview/moleculeGroups/redux/dispatch
import { reloadDatasetsReducer } from '../../datasets/redux/actions';
import { saveCurrentActionsList } from '../../../reducers/tracking/dispatchActions';
import { sendTrackingActionsByProjectId, manageSendTrackingActions } from '../../../reducers/tracking/dispatchActions';
import { captureScreenOfSnapshot } from '../../userFeedback/browserApi';

export const getListOfSnapshots = () => (dispatch, getState) => {
const userID = DJANGO_CONTEXT['pk'] || null;
Expand Down Expand Up @@ -215,7 +216,10 @@ export const createNewSnapshot = ({ title, description, type, author, parent, se
}).then(res => {
// redirect to project with newest created snapshot /:projectID/:snapshotID
if (res.data.id && session_project) {
Promise.resolve(dispatch(saveCurrentActionsList(res.data.id, session_project, nglViewList))).then(() => {
let snapshot = { id: res.data.id, title: title };
let project = { projectID: session_project, authorID: author };

Promise.resolve(dispatch(saveCurrentActionsList(snapshot, project, nglViewList))).then(() => {
if (disableRedirect === false) {
// Really bad usage or redirection. Hint for everybody in this line ignore it, but in other parts of code
// use react-router !
Expand Down Expand Up @@ -251,6 +255,7 @@ export const activateSnapshotDialog = (loggedInUserID = undefined, finallyShareS
const projectID = state.projectReducers.currentProject.projectID;
const currentSnapshotAuthor = state.projectReducers.currentSnapshot.author;

dispatch(captureScreenOfSnapshot());
dispatch(manageSendTrackingActions());
dispatch(setDisableRedirect(finallyShareSnapshot));

Expand Down Expand Up @@ -321,20 +326,24 @@ export const createNewSnapshotWithoutStateModification = ({
disableRedirect: true
})
);
dispatch(saveCurrentActionsList(res.data.id, session_project, nglViewList));

let snapshot = { id: res.data.id, title: title };
let project = { projectID: session_project, authorID: author };
dispatch(saveCurrentActionsList(snapshot, project, nglViewList));
}
});
});
};

export const saveAndShareSnapshot = nglViewList => (dispatch, getState) => {
export const saveAndShareSnapshot = nglViewList => async (dispatch, getState) => {
const state = getState();
const targetId = state.apiReducers.target_on;
const loggedInUserID = DJANGO_CONTEXT['pk'];

dispatch(setDisableRedirect(true));

if (targetId) {
dispatch(captureScreenOfSnapshot());
dispatch(setIsLoadingSnapshotDialog(true));
const data = {
title: ProjectCreationType.READ_ONLY,
Expand All @@ -344,36 +353,34 @@ export const saveAndShareSnapshot = nglViewList => (dispatch, getState) => {
tags: '[]'
};

dispatch(createProjectWithoutStateModification(data))
.then(projectID => {
const username = DJANGO_CONTEXT['username'];
const title = moment().format('-- YYYY-MM-DD -- HH:mm:ss');
const description =
loggedInUserID === undefined ? 'Snapshot generated by anonymous user' : `snapshot generated by ${username}`;
const type = SnapshotType.MANUAL;
const author = loggedInUserID || null;
const parent = null;
const session_project = projectID;

dispatch(sendTrackingActionsByProjectId(projectID, author));

return dispatch(
createNewSnapshotWithoutStateModification({
title,
description,
type,
author,
parent,
session_project,
nglViewList
})
);
})
.catch(error => {
throw new Error(error);
})
.finally(() => {
dispatch(setIsLoadingSnapshotDialog(false));
});
try {
let projectID = await dispatch(createProjectWithoutStateModification(data));
const username = DJANGO_CONTEXT['username'];
const title = moment().format('-- YYYY-MM-DD -- HH:mm:ss');
const description =
loggedInUserID === undefined ? 'Snapshot generated by anonymous user' : `snapshot generated by ${username}`;
const type = SnapshotType.MANUAL;
const author = loggedInUserID || null;
const parent = null;
const session_project = projectID;

await dispatch(sendTrackingActionsByProjectId(projectID, author));

await dispatch(
createNewSnapshotWithoutStateModification({
title,
description,
type,
author,
parent,
session_project,
nglViewList
})
);

dispatch(setIsLoadingSnapshotDialog(false));
} catch (error) {
throw new Error(error);
}
}
};
68 changes: 68 additions & 0 deletions js/components/tracking/EditableText.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useState, useRef, useEffect } from 'react';
import { makeStyles, TextField, IconButton, Tooltip, Grid } from '@material-ui/core';
import { Edit } from '@material-ui/icons';

const useStyles = makeStyles(theme => ({
search: {
width: '100%'
},
fontSizeSmall: {
fontSize: '0.82rem'
}
}));

const EditableInput = ({ dataText, index, updateText }) => {
const inputRef = useRef(null);
const [inputVisible, setInputVisible] = useState(false);
const [text, setText] = useState(dataText);
const classes = useStyles();

const onClickOutSide = e => {
if (inputRef.current && !inputRef.current.contains(e.target)) {
setInputVisible(false);
if (updateText && text !== dataText) {
updateText(text);
}
}
};

useEffect(() => {
// Handle outside clicks on mounted state
if (inputVisible) {
document.addEventListener('mousedown', onClickOutSide);
}

// This is a necessary step to "dismount" unnecessary events when we destroy the component
return () => {
document.removeEventListener('mousedown', onClickOutSide);
};
});

return (
<React.Fragment>
{inputVisible ? (
<TextField
className={classes.search}
ref={inputRef}
value={text}
onChange={e => {
setText(e.target.value);
}}
/>
) : (
<Grid item key={index}>
{<span onClick={() => setInputVisible(true)}>{text}</span>}
{
<IconButton color={'primary'} size="small" onClick={() => setInputVisible(true)}>
<Tooltip title="Edit">
<Edit className={classes.fontSizeSmall} />
</Tooltip>
</IconButton>
}
</Grid>
)}
</React.Fragment>
);
};

export default EditableInput;
Loading

0 comments on commit 9550632

Please sign in to comment.