Commit 7c6bb38f authored by hh1966's avatar hh1966
Browse files

Add reaction field to research plan detail

parent 254b65ec
Pipeline #52867 failed with stage
......@@ -2,6 +2,7 @@ export default {
WELL: 'well',
SAMPLE: 'sample',
MATERIAL: 'material',
REACTION: 'reaction',
WELLPLATE: 'wellplate',
MOLECULE: 'molecule',
RESEARCH_PLAN: 'research_plan',
......
......@@ -20,7 +20,7 @@ const ElementContainer = ({ connectDragSource, sourceType }) => {
return connectDragSource(
<span className="fa fa-home dnd-arrow-enable text-info" />,
);
} else if (sourceType === DragDropItemTypes.WELLPLATE) {
} else if (sourceType === DragDropItemTypes.WELLPLATE || sourceType === DragDropItemTypes.REACTION) {
return connectDragSource(
<span className="fa fa-arrows dnd-arrow-enable text-info" />,
);
......
......@@ -89,6 +89,7 @@ export default class ElementsTableEntries extends Component {
const { currentElement } = ElementStore.getState();
const targets = {
sample: ['reaction', 'wellplate'],
reaction: ['research_plan'],
wellplate: ['screen'],
generalProcedure: ['reaction'],
};
......@@ -124,12 +125,17 @@ export default class ElementsTableEntries extends Component {
el.type === 'sample' && this.isCurrEleDropType('sample');
const isDropForWellPlate =
el.type === 'wellplate' && this.isCurrEleDropType('wellplate');
const isDropForResearchPlan =
el.type === 'reaction' && this.isCurrEleDropType('reaction');
const isDropForGP = el.type === 'reaction' && el.role === 'gp' &&
this.isCurrEleDropType('generalProcedure');
if (isDropForSample) {
sourceType = DragDropItemTypes.SAMPLE;
} else if (isDropForWellPlate) {
sourceType = DragDropItemTypes.WELLPLATE;
} else if (isDropForResearchPlan) {
sourceType = DragDropItemTypes.REACTION;
} else if (isDropForGP) {
sourceType = DragDropItemTypes.GENERALPROCEDURE;
}
......
......@@ -87,6 +87,15 @@ export default class ResearchPlan extends Element {
}
})
break;
case 'reaction':
this.body.push({
id: uuidv4(),
type: 'reaction',
value: {
reaction_id: null
}
})
break;
}
}
......
......@@ -15,15 +15,18 @@ export default class ResearchPlanDetailsAddField extends Component {
<Button bsStyle="primary" bsSize="small" onClick={() => onAdd('table')} >
<i className="fa fa-table"></i>&nbsp;<i className="fa fa-plus"></i>
</Button>
<Button bsStyle="primary" bsSize="small" onClick={() => onAdd('image')} >
<i className="fa fa-picture-o"></i>&nbsp;<i className="fa fa-plus"></i>
</Button>
<Button bsStyle="primary" bsSize="small" onClick={() => onAdd('ketcher')} >
<i className="fa fa-flask"></i>&nbsp;<i className="fa fa-plus"></i>
</Button>
<Button bsStyle="primary" bsSize="small" onClick={() => onAdd('image')} >
<i className="fa fa-picture-o"></i>&nbsp;<i className="fa fa-plus"></i>
</Button>
<Button bsStyle="primary" bsSize="small" onClick={() => onAdd('sample')} >
<i className="icon-sample"></i>&nbsp;<i className="fa fa-plus"></i>
</Button>
<Button bsStyle="primary" bsSize="small" onClick={() => onAdd('reaction')} >
<i className="icon-reaction"></i>&nbsp;<i className="fa fa-plus"></i>
</Button>
</div>
)
}
......
......@@ -10,6 +10,8 @@ import ResearchPlanDetailsFieldKetcher from './ResearchPlanDetailsFieldKetcher'
import ResearchPlanDetailsFieldImage from './ResearchPlanDetailsFieldImage'
import ResearchPlanDetailsFieldTable from './ResearchPlanDetailsFieldTable'
import ResearchPlanDetailsFieldSample from './ResearchPlanDetailsFieldSample'
import ResearchPlanDetailsFieldReaction from './ResearchPlanDetailsFieldReaction'
export default class ResearchPlanDetailsField extends Component {
......@@ -48,6 +50,12 @@ export default class ResearchPlanDetailsField extends Component {
field={field} index={index} disabled={disabled}
onChange={onChange.bind(this)} edit={edit} />
break;
case 'reaction':
label = 'Reaction'
component = <ResearchPlanDetailsFieldReaction key={field.id}
field={field} index={index} disabled={disabled}
onChange={onChange.bind(this)} edit={edit} />
break;
}
let dropTarget, fieldHeader
......
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { DropTarget } from 'react-dnd'
import DragDropItemTypes from '../DragDropItemTypes'
import { Row, Col, Button } from 'react-bootstrap'
import SVG from 'react-inlinesvg';
import ElementActions from '../actions/ElementActions';
import { UrlSilentNavigation } from '../utils/ElementUtils';
import ReactionsFetcher from '../fetchers/ReactionsFetcher'
const spec = {
drop(props, monitor) {
const { field, onChange } = props
onChange({ reaction_id: monitor.getItem().element.id }, field.id)
}
}
const collect = (connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
canDrop: monitor.canDrop()
})
class ResearchPlanDetailsFieldReaction extends Component {
constructor(props) {
super(props);
this.state = {
idle: true,
reaction: {
id: null
}
}
}
componentDidUpdate() {
const { field } = this.props
const { idle, reaction } = this.state
if (idle && field.value.reaction_id !== reaction.id) {
this.setState({ idle: false }, this.fetch)
}
}
fetch() {
const { field } = this.props
ReactionsFetcher.fetchById(field.value.reaction_id).then(reaction => {
this.setState({ idle: true, reaction: reaction })
})
}
showReaction() {
const { reaction } = this.state;
UrlSilentNavigation(reaction);
ElementActions.fetchReactionById(reaction.id)
}
renderReaction(reaction) {
const { edit } = this.props
const style = { height: '200px' };
let link
if (edit) {
link = (
<p className="float-left">
Reaction: <a role="link" tabIndex={0} onClick={() => this.showReaction()} style={{ cursor: 'pointer' }}>
{reaction.title()}
</a>
</p>
)
}
return (
<Row style={style}>
<Col md={12}>
{link}
<div>
<SVG src={reaction.svgPath} className="molecule-mid"/>
</div>
</Col>
</Row>
)
}
renderEdit() {
const { field, index, connectDropTarget, isOver, canDrop } = this.props
const { reaction } = this.state
let className = 'drop-target'
if (isOver) className += ' is-over'
if (canDrop) className += ' can-drop'
return connectDropTarget(
<div className={className}>
{reaction.id ? this.renderReaction(reaction) : 'Drop reaction here.'}
</div>
)
}
renderStatic() {
const { field } = this.props
const { reaction } = this.state
return reaction.id ? this.renderReaction(reaction) : ''
}
render() {
if (this.props.edit) {
return this.renderEdit()
} else {
return this.renderStatic()
}
}
}
ResearchPlanDetailsFieldReaction.propTypes = {
field: PropTypes.object,
index: PropTypes.number,
disabled: PropTypes.bool,
onChange: PropTypes.func,
}
export default DropTarget(DragDropItemTypes.REACTION, spec, collect)(ResearchPlanDetailsFieldReaction);
......@@ -16,8 +16,7 @@ const MWPrecision = 6;
const spec = {
drop(props, monitor) {
const { field, onChange } = props
const sample = monitor.getItem().element
onChange({ sample_id: sample.id }, field.id)
onChange({ sample_id: monitor.getItem().element.id }, field.id)
}
}
......@@ -56,6 +55,12 @@ class ResearchPlanDetailsFieldSample extends Component {
})
}
showSample() {
const { sample } = this.state;
UrlSilentNavigation(sample);
ElementActions.fetchSampleById(sample.id);
}
// copied from SampleDetails.js
sampleAverageMW(sample) {
let mw = sample.molecule_molecular_weight;
......@@ -74,8 +79,9 @@ class ResearchPlanDetailsFieldSample extends Component {
return '';
}
// modified from SampleDetails.js
sampleInfo(sample) {
// modified from sampleInfo in SampleDetails.js
renderSample(sample) {
const { edit } = this.props
const style = { height: '200px' };
const pubchemLcss = sample.pubchem_tag && sample.pubchem_tag.pubchem_lcss ?
sample.pubchem_tag.pubchem_lcss.Record.Section[0].Section[0].Section[0].Information : null;
......@@ -84,8 +90,16 @@ class ResearchPlanDetailsFieldSample extends Component {
const lcssSign = pubchemLcss ?
<PubchemLcss cid={pubchemCid} informArray={pubchemLcss} /> : <div />;
let svgPath = sample.svgPath
let svgClassName = svgPath ? 'svg-container' : 'svg-container-empty'
let link
if (edit) {
link = (
<p>
Sample: <a role="link" tabIndex={0} onClick={() => this.showSample()} style={{ cursor: 'pointer' }}>
{sample.title()}
</a>
</p>
)
}
return (
<Row style={style}>
......@@ -94,31 +108,17 @@ class ResearchPlanDetailsFieldSample extends Component {
<h5>{this.sampleAverageMW(sample)}</h5>
<h5>{this.sampleExactMW(sample)}</h5>
{lcssSign}
<p>
Sample: <a role="link" tabIndex={0} onClick={() => this.handleSampleClick()} style={{ cursor: 'pointer' }}>
{sample.title()}
</a>
</p>
{link}
</Col>
<Col md={8}>
<div>
<SVG src={svgPath} className="molecule-mid"/>
<SVG src={sample.svgPath} className="molecule-mid"/>
</div>
</Col>
</Row>
)
}
handleSampleClick() {
const { sample } = this.state;
UrlSilentNavigation(sample);
ElementActions.showReactionMaterial({ sample });
}
renderSample() {
const { sample } = this.state
}
renderEdit() {
const { field, index, connectDropTarget, isOver, canDrop } = this.props
const { sample } = this.state
......@@ -127,28 +127,17 @@ class ResearchPlanDetailsFieldSample extends Component {
if (isOver) className += ' is-over'
if (canDrop) className += ' can-drop'
let content = 'Drop Sample here.'
if (sample.id !== null) {
content = this.sampleInfo(sample)
}
return connectDropTarget(
<div className={className}>
{content}
{sample.id ? this.renderSample(sample) : 'Drop sample here.'}
</div>
)
}
renderStatic() {
const { field } = this.props
const { sample } = this.state
let content = 'No sample.'
if (sample.id !== null) {
content = this.sampleInfo(sample)
}
return content
return sample.id ? this.renderSample(sample) : ''
}
render() {
......@@ -167,4 +156,4 @@ ResearchPlanDetailsFieldSample.propTypes = {
onChange: PropTypes.func,
}
export default DropTarget([DragDropItemTypes.SAMPLE, DragDropItemTypes.MOLECULE, DragDropItemTypes.MATERIAL], spec, collect)(ResearchPlanDetailsFieldSample);
export default DropTarget(DragDropItemTypes.SAMPLE, spec, collect)(ResearchPlanDetailsFieldSample);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment