diff --git a/package.json b/package.json index 3ade9c9..e3db896 100644 --- a/package.json +++ b/package.json @@ -14,14 +14,14 @@ "@material-ui/core": "^3.9.2", "@material-ui/icons": "^3.0.2", "@material-ui/lab": "^3.0.0-alpha.30", - "@openchemistry/girder-redux": "^0.0.33", - "@openchemistry/girder-client": "^0.0.24", - "@openchemistry/girder-ui": "^0.0.40", - "@openchemistry/molecule": "^0.4.31", - "@openchemistry/redux": "^0.3.29", - "@openchemistry/rest": "^0.3.31", - "@openchemistry/sagas": "^0.3.43", - "@openchemistry/utils": "^0.6.19", + "@openchemistry/girder-redux": "^0.0.34", + "@openchemistry/girder-client": "^0.0.25", + "@openchemistry/girder-ui": "^0.0.41", + "@openchemistry/molecule": "^0.4.32", + "@openchemistry/redux": "^0.3.30", + "@openchemistry/rest": "^0.3.32", + "@openchemistry/sagas": "^0.3.44", + "@openchemistry/utils": "^0.6.20", "connected-react-router": "^6.4.0", "core-js": "^2.6.5", "enumify": "^1.0.4", diff --git a/src/App.js b/src/App.js index ea33559..3d4b8f6 100644 --- a/src/App.js +++ b/src/App.js @@ -26,6 +26,7 @@ import JupyterIntegration from './containers/jupyterlab-integration/instructions import Groups from './containers/administrator/group-manager'; import Members from './containers/administrator/member-manager'; import User from './containers/user/user-profile'; +import Creator from './containers/user/creator-profile'; import { history } from './store'; @@ -118,10 +119,12 @@ class App extends Component { + + diff --git a/src/components/calculation/index.js b/src/components/calculation/index.js index ee1cc24..20c865f 100644 --- a/src/components/calculation/index.js +++ b/src/components/calculation/index.js @@ -97,7 +97,9 @@ class Calculation extends Component { colors, colorsX, opacities, - opacitiesX + opacitiesX, + creator, + onCreatorClick } = this.props; const cjson = calculation.cjson; @@ -172,6 +174,29 @@ class Calculation extends Component { sections.push(outputSection); + let creatorName = []; + if (has(creator, 'firstName')) { + creatorName.push({label: 'First', value: creator.firstName}); + } else { + creatorName.push({label: 'First', value:'Unknown'}); + } + if (has(creator, 'lastName')) { + creatorName.push({label: 'Last', value: creator.lastName}); + } else { + creatorName.push({label: 'Last', value: 'Unknown'}); + } + const creatorSection = { + label: 'Creator', + items: [ + { + properties: creatorName, + onClick: () => {onCreatorClick(creator)} + } + ] + } + + sections.push(creatorSection); + const fileFormats = ['cjson', 'xyz']; const fileOptions = fileFormats.map(format => ({ label: toUpperCase(format), diff --git a/src/components/molecule.js b/src/components/molecule.js index 95aa8d5..3272788 100644 --- a/src/components/molecule.js +++ b/src/components/molecule.js @@ -76,7 +76,7 @@ class Molecule extends Component { } render = () => { - const {molecule, calculations, onCalculationClick, classes} = this.props; + const {molecule, calculations, onCalculationClick, creator, onCreatorClick, classes} = this.props; const sections = []; let moleculeProperties = []; @@ -115,6 +115,29 @@ class Molecule extends Component { sections.push(calculationsSection); + let creatorName = []; + if (has(creator, 'firstName')) { + creatorName.push({label: 'First', value: creator.firstName}); + } else { + creatorName.push({label: 'First', value:'Unknown'}); + } + if (has(creator, 'lastName')) { + creatorName.push({label: 'Last', value: creator.lastName}); + } else { + creatorName.push({label: 'Last', value: 'Unknown'}); + } + const creatorSection = { + label: 'Creator', + items: [ + { + properties: creatorName, + onClick: () => {onCreatorClick(creator)} + } + ] + } + + sections.push(creatorSection); + const fileFormats = ['cjson', 'xyz', 'sdf', 'cml']; const fileOptions = fileFormats.map(format => ({ label: toUpperCase(format), diff --git a/src/components/user/creator-profile.js b/src/components/user/creator-profile.js new file mode 100644 index 0000000..99bbb74 --- /dev/null +++ b/src/components/user/creator-profile.js @@ -0,0 +1,126 @@ +import React, { Component } from 'react'; + +import { withStyles, TextField, Link, InputAdornment, Paper, Grid, Typography } from '@material-ui/core'; +import OpenInNewIcon from '@material-ui/icons/OpenInNew' + +import PageHead from '../page-head'; +import PageBody from '../page-body'; + +import { TwitterTimelineEmbed } from 'react-twitter-embed'; + +const styles = theme => ({ + paper: { + padding: '10px' + }, + textField: { + marginTop: '8px' + }, + column: { + padding: theme.spacing.unit * 3 + } +}); + +class CreatorProfile extends Component { + render () { + const {userInfo, mediaIds, classes} = this.props; + const { creator } = this.props.location.state; + return ( +
+ + + {creator.login}'s Profile + + + + + + +
+ +
+
+ +
+
+ + {mediaIds.twitterId != undefined + ? + + + : null } + }} + fullWidth + /> +
+
+ + {mediaIds.orcidId != undefined + ? + + + : null } + }} + fullWidth + /> +
+
+
+ {mediaIds.twitterId + ? + + + + + : null} +
+
+
+ ); + } +} + +export default withStyles(styles)(CreatorProfile); diff --git a/src/containers/calculation.js b/src/containers/calculation.js index 3456d17..e46f789 100644 --- a/src/containers/calculation.js +++ b/src/containers/calculation.js @@ -77,8 +77,13 @@ class CalculationContainer extends Component { dispatch(push(`/molecules/${molecule._id}`)); } + onCreatorClick = (creator) => { + const { id, dispatch } = this.props; + dispatch(push(`/calculations/${id}/creator`, {creator, type:'calculation', id:id})); + } + render() { - const { id, calculation, showNotebooks, molecule} = this.props; + const { id, calculation, showNotebooks, molecule, creator} = this.props; if (isNil(calculation) || isNil(calculation.cjson)) { return null; } @@ -88,9 +93,11 @@ class CalculationContainer extends Component { calculation={calculation} molecule={molecule} id={id} + creator={creator} onIOrbitalChanged={this.onIOrbitalChanged} onMoleculeClick={this.onMoleculeClick} showNotebooks={showNotebooks} + onCreatorClick={this.onCreatorClick} {...this.props} /> @@ -154,6 +161,7 @@ CalculationContainer.defaultProps = { function mapStateToProps(state, ownProps) { let id = ownProps.match.params.id; let iOrbital = ownProps.match.params.iOrbital; + let creator = selectors.calculations.getCalculationCreator(state); let cjson; let calculationInput; let molecule; @@ -163,7 +171,8 @@ function mapStateToProps(state, ownProps) { mo: iOrbital, cjson, calculationInput, - molecule + molecule, + creator } const params = new URLSearchParams(ownProps.location.search); diff --git a/src/containers/molecule.js b/src/containers/molecule.js index d5e5d93..1b0d195 100644 --- a/src/containers/molecule.js +++ b/src/containers/molecule.js @@ -42,12 +42,23 @@ class MoleculeContainer extends Component { dispatch(push(`/calculations/${calculation._id}`)); } + onCreatorClick = (creator) => { + const { id, dispatch } = this.props; + dispatch(push(`/molecules/${id}/creator`, {creator, type:'molecule', id:id})); + } + render() { - const { molecule, calculations } = this.props; + const { molecule, calculations, creator } = this.props; if (molecule) { return ( - + ); } else { return null; @@ -72,9 +83,11 @@ MoleculeContainer.defaultProps = { function mapStateToProps(state, ownProps) { let id = ownProps.match.params.id || null; let inchikey = ownProps.match.params.inchikey || null; + let creator = selectors.molecules.getMoleculeCreator(state); let props = { id, - inchikey + inchikey, + creator } let molecules = selectors.molecules.getMoleculesById(state); diff --git a/src/containers/user/creator-profile.js b/src/containers/user/creator-profile.js new file mode 100644 index 0000000..8e89ff0 --- /dev/null +++ b/src/containers/user/creator-profile.js @@ -0,0 +1,50 @@ +import React, { Component } from 'react'; +import { connect } from 'react-redux'; + +import CreatorProfile from '../../components/user/creator-profile'; + +import { calculations, molecules, selectors } from '@openchemistry/redux'; + +class CreatorContainer extends Component { + + componentDidMount() { + const { location, dispatch } = this.props; + const { type, id } = location.state; + if (type === 'calculation') { + dispatch(calculations.loadCalculationById(id)) + } else { + dispatch(molecules.loadMoleculeById(id)) + } + } + + render() { + return ( + + ); + } +} + +function mapStateToProps(state) { + const userInfo = selectors.calculations.getCalculationCreator(state); + let twitterId = userInfo.twitterId; + let orcidId = userInfo.orcidId; + + if (!twitterId) { + twitterId = undefined + } + if (!orcidId) { + orcidId = undefined + } + const mediaIds = {twitterId, orcidId} + + return { + userInfo, + mediaIds + }; +} + +CreatorContainer = connect(mapStateToProps)(CreatorContainer) + +export default CreatorContainer;