Skip to content

Commit

Permalink
Merge pull request #161 from OpenChemistry/owner-module
Browse files Browse the repository at this point in the history
Owner module
  • Loading branch information
bnmajor authored Nov 25, 2019
2 parents 269f220 + cda7f8e commit 14e65a8
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 15 deletions.
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -118,10 +119,12 @@ class App extends Component {
<Switch>
<route.Public exact path='/' component={Home}/>
<route.Public exact path='/molecules/:id' component={MoleculeContainer}/>
<route.Public exact path='/molecules/:id/creator' component={Creator}/>
<route.Public exact path='/molecules/inchikey/:inchikey' component={MoleculeContainer}/>
<route.Public exact path='/molecules' component={Molecules}/>
<route.Public exact path='/chart' component={VibrationalModesChartContainer}/>
<route.Public exact path='/freechart' component={FreeEnergyChartContainer}/>
<route.Public exact path='/calculations/:id/creator' component={Creator}/>
<route.Public path='/calculations/:id/orbital/:iOrbital' component={CalculationContainer}/>
<route.Public path='/calculations/:id' component={CalculationContainer}/>
<route.Public path='/calculations' component={Calculations}/>
Expand Down
27 changes: 26 additions & 1 deletion src/components/calculation/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ class Calculation extends Component {
colors,
colorsX,
opacities,
opacitiesX
opacitiesX,
creator,
onCreatorClick
} = this.props;

const cjson = calculation.cjson;
Expand Down Expand Up @@ -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),
Expand Down
25 changes: 24 additions & 1 deletion src/components/molecule.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [];
Expand Down Expand Up @@ -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),
Expand Down
126 changes: 126 additions & 0 deletions src/components/user/creator-profile.js
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<PageHead>
<Typography color="inherit" gutterBottom variant="display1">
{creator.login}'s Profile
</Typography>
</PageHead>
<PageBody noOverlap>
<Grid container style={{height: '100%'}} alignItems='stretch'>
<Grid
className={classes.column}
item
xs={mediaIds.twitterId ? 16 : 24}
md={mediaIds.twitterId ? 8 : 12} >
<Paper className={classes.paper}>
<div>
<TextField
className={classes.textField}
name='name'
helperText='Name'
value={userInfo.firstName + ' ' + userInfo.lastName}
fullWidth
InputProps={{ readOnly: true }}
/>
</div>
<div>
<TextField
className={classes.textField}
name='email'
helperText='Email Address'
value={userInfo.email}
fullWidth
InputProps={{ readOnly: true }}
/>
</div>
<div>
<TextField
className={classes.textField}
name='twitterId'
helperText='Twitter Handle'
value={mediaIds.twitterId ? mediaIds.twitterId : 'No Associated Twitter Handle'}
InputProps={{
readOnly: true,
startAdornment:
<InputAdornment position='start'>
{mediaIds.twitterId != undefined
? <Link
href={'http://www.twitter.com/' + mediaIds.twitterId}
target='_blank'
>
<OpenInNewIcon/>
</Link>
: null }
</InputAdornment>}}
fullWidth
/>
</div>
<div>
<TextField
className={classes.textField}
name='orcidId'
helperText='Orcid ID'
value={mediaIds.orcidId ? mediaIds.orcidId : 'No Associated Orcid ID'}
InputProps={{
readOnly: true,
startAdornment:
<InputAdornment position='start'>
{mediaIds.orcidId != undefined
? <Link
href={'http://www.orcid.com/' + mediaIds.orcidId}
target='_blank'
>
<OpenInNewIcon color={mediaIds.orcidId ? 'primary' : 'disabled'}/>
</Link>
: null }
</InputAdornment>}}
fullWidth
/>
</div>
</Paper>
</Grid>
{mediaIds.twitterId
? <Grid className={classes.column} item xs={8} md={4} >
<Paper>
<TwitterTimelineEmbed
sourceType="profile"
screenName={mediaIds.twitterId}
options={{height: 500}}
/>
</Paper>
</Grid>
: null}
</Grid>
</PageBody>
</div>
);
}
}

export default withStyles(styles)(CreatorProfile);
13 changes: 11 additions & 2 deletions src/containers/calculation.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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}
/>
</div>
Expand Down Expand Up @@ -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;
Expand All @@ -163,7 +171,8 @@ function mapStateToProps(state, ownProps) {
mo: iOrbital,
cjson,
calculationInput,
molecule
molecule,
creator
}

const params = new URLSearchParams(ownProps.location.search);
Expand Down
19 changes: 16 additions & 3 deletions src/containers/molecule.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<Molecule molecule={molecule} calculations={calculations} onCalculationClick={this.onCalculationClick}/>
<Molecule
molecule={molecule}
calculations={calculations}
onCalculationClick={this.onCalculationClick}
creator={creator}
onCreatorClick={this.onCreatorClick}
/>
);
} else {
return null;
Expand All @@ -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);
Expand Down
50 changes: 50 additions & 0 deletions src/containers/user/creator-profile.js
Original file line number Diff line number Diff line change
@@ -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 (
<CreatorProfile
{...this.props}
/>
);
}
}

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;

0 comments on commit 14e65a8

Please sign in to comment.