Skip to content

Commit

Permalink
feat: add vessel size property to reaction (#2017)
Browse files Browse the repository at this point in the history
add vessel_size to reactions table and add field reaction vessel size field in reaction scheme tab in frontend
  • Loading branch information
adambasha0 authored Aug 6, 2024
1 parent a3d95d1 commit f00b4f6
Show file tree
Hide file tree
Showing 12 changed files with 120 additions and 20 deletions.
2 changes: 2 additions & 0 deletions app/api/chemotion/reaction_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ class ReactionAPI < Grape::API
optional :rxno, type: String
optional :segments, type: Array
optional :variations, type: [Hash]
optional :vessel_size, type: Hash
end
route_param :id do
after_validation do
Expand Down Expand Up @@ -229,6 +230,7 @@ class ReactionAPI < Grape::API
optional :duration, type: String
optional :rxno, type: String
optional :variations, type: [Hash]
optional :vessel_size, type: Hash
end

post do
Expand Down
1 change: 1 addition & 0 deletions app/api/entities/reaction_entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class ReactionEntity < ApplicationEntity
expose! :tlc_description, unless: :displayed_in_list
expose! :tlc_solvents, unless: :displayed_in_list
expose! :variations, anonymize_with: [], using: 'Entities::ReactionVariationEntity'
expose! :vessel_size
end

expose_timestamps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ export default class ReactionDetails extends Component {
if (type === 'temperatureUnit' || type === 'temperatureData'
|| type === 'description' || type === 'role'
|| type === 'observation' || type === 'durationUnit'
|| type === 'duration' || type === 'rxno') {
|| type === 'duration' || type === 'rxno'
|| type === 'vesselSizeAmount' || type === 'vesselSizeUnit') {
value = event;
} else if (type === 'rfValue') {
value = rfValueFormat(event.target.value) || '';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export default class ReactionDetailsMainProperties extends Component {
this.props.onInputChange('temperatureUnit', unit);
}


render() {
const { reaction, onInputChange } = this.props;
const temperatureTooltip = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ const setReactionByType = (reaction, type, value) => {
case 'rxno':
reaction.rxno = value;
break;
case 'vesselSizeAmount':
reaction.vessel_size.amount = value;
break;
case 'vesselSizeUnit':
reaction.vessel_size.unit = value;
if (value === 'ml') {
reaction.vessel_size.amount = reaction.vessel_size.amount * 1000;
} else if (value === 'l') {
reaction.vessel_size.amount = reaction.vessel_size.amount / 1000;
}
break;
}

return { newReaction: reaction, options: options }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
ListGroup, ListGroupItem, FormGroup, ControlLabel, FormControl,
Row, Col, Collapse, Button, ButtonGroup
Row, Col, Collapse, Button, ButtonGroup, InputGroup, Grid,
} from 'react-bootstrap';
import Select from 'react-select';
import Delta from 'quill-delta';
Expand All @@ -26,6 +26,7 @@ import NotificationActions from 'src/stores/alt/actions/NotificationActions';
import TextTemplateActions from 'src/stores/alt/actions/TextTemplateActions';
import TextTemplateStore from 'src/stores/alt/stores/TextTemplateStore';
import ElementActions from 'src/stores/alt/actions/ElementActions';
import { parseNumericString } from 'src/utilities/MathUtils';

export default class ReactionDetailsScheme extends Component {
constructor(props) {
Expand Down Expand Up @@ -56,6 +57,10 @@ export default class ReactionDetailsScheme extends Component {
this.switchEquiv = this.switchEquiv.bind(this);
this.handleOnConditionSelect = this.handleOnConditionSelect.bind(this);
this.updateTextTemplates = this.updateTextTemplates.bind(this);
this.reactionVesselSize = this.reactionVesselSize.bind(this);
this.updateVesselSize = this.updateVesselSize.bind(this);
this.updateVesselSizeOnBlur = this.updateVesselSizeOnBlur.bind(this);
this.changeVesselSizeUnit = this.changeVesselSizeUnit.bind(this);
}

componentDidMount() {
Expand Down Expand Up @@ -171,23 +176,34 @@ export default class ReactionDetailsScheme extends Component {
}

renderRole() {
const { role } = this.props.reaction;
const accordTo = role === 'parts' ? 'According to' : null;
const { reaction } = this.props;
const { role } = reaction;
let accordTo;
let width;
if (role === 'parts') {
accordTo = 'According to';
width = 2;
} else {
accordTo = null;
width = 4;
}
return (
<span>
<Col md={3} style={{ paddingLeft: '6px' }}>
<>
<Col md={width}>
<FormGroup>
<ControlLabel>Role</ControlLabel>
{this.renderRoleSelect()}
</FormGroup>
</Col>
<Col md={3} style={{ paddingLeft: '6px' }}>
<FormGroup>
<ControlLabel>{accordTo}</ControlLabel>
{this.renderGPDnD()}
</FormGroup>
</Col>
</span>
{role === 'parts' && (
<Col md={2}>
<FormGroup>
<ControlLabel>{accordTo}</ControlLabel>
{this.renderGPDnD()}
</FormGroup>
</Col>
)}
</>
);
}

Expand Down Expand Up @@ -794,6 +810,61 @@ export default class ReactionDetailsScheme extends Component {
);
}

updateVesselSize(e) {
const { onInputChange } = this.props;
const { value } = e.target;
onInputChange('vesselSizeAmount', value);
}

updateVesselSizeOnBlur(e) {
const { onInputChange } = this.props;
const { value } = e.target;
const newValue = parseNumericString(value);
onInputChange('vesselSizeAmount', newValue);
}

changeVesselSizeUnit() {
const { onInputChange, reaction } = this.props;
if (reaction.vessel_size.unit === 'ml') {
onInputChange('vesselSizeUnit', 'l');
} else if (reaction.vessel_size.unit === 'l') {
onInputChange('vesselSizeUnit', 'ml');
}
}

reactionVesselSize() {
const { reaction } = this.props;
return (
<Col md={3} className="vesselSize">
<InputGroup style={{ width: '100%', paddingRight: '40px' }}>
<ControlLabel>Vessel size</ControlLabel>
<FormGroup style={{ display: 'flex' }}>
<FormControl
id="reactionVesselSize"
name="reaction_vessel_size"
type="text"
style={{ height: '36px' }}
value={reaction.vessel_size?.amount || ''}
disabled={false}
onChange={(event) => this.updateVesselSize(event)}
onBlur={(event) => this.updateVesselSizeOnBlur(event)}
/>
<InputGroup.Button>
<Button
disabled={false}
bsStyle="success"
onClick={() => this.changeVesselSizeUnit()}
style={{ width: '44px', height: '36px' }}
>
{reaction.vessel_size?.unit || 'ml'}
</Button>
</InputGroup.Button>
</FormGroup>
</InputGroup>
</Col>
);
}

render() {
const {
reaction,
Expand Down Expand Up @@ -858,7 +929,7 @@ export default class ReactionDetailsScheme extends Component {
headIndex={0}
/>
</ListGroupItem>
<ListGroupItem style={minPadding} >
<ListGroupItem style={minPadding}>
<MaterialGroupContainer
reaction={reaction}
materialGroup="reactants"
Expand Down Expand Up @@ -950,8 +1021,8 @@ export default class ReactionDetailsScheme extends Component {
reaction={reaction}
onInputChange={(type, event) => this.props.onInputChange(type, event)}
/>
<Row>
<Col md={6}>
<Row className="small-padding">
<Col md={5}>
<FormGroup>
<ControlLabel>Type (Name Reaction Ontology)</ControlLabel>
<OlsTreeSelect
Expand All @@ -963,6 +1034,7 @@ export default class ReactionDetailsScheme extends Component {
</FormGroup>
</Col>
{this.renderRole()}
{this.reactionVesselSize()}
</Row>
<Row>
<Col md={12}>
Expand Down
3 changes: 2 additions & 1 deletion app/packs/src/components/OlsComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default class OlsTreeSelect extends Component {
render() {
const { rxnos, chmos, bao } = UserStore.getState();
let treeData = [];
const height = this.props.selectName === 'rxno' ? '35px' : null;
switch (this.props.selectName) {
case 'rxno':
treeData = rxnos;
Expand All @@ -54,7 +55,7 @@ export default class OlsTreeSelect extends Component {
treeDefaultExpandedKeys={[this.props.selectName]}
name={this.props.selectName}
showSearch
style={{ width: '100%' }}
style={{ width: '100%', height }}
value={this.props.selectedValue}
dropdownStyle={{ maxHeight: 300, overflow: 'auto' }}
treeData={treeData}
Expand Down
6 changes: 4 additions & 2 deletions app/packs/src/models/Reaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ export default class Reaction extends Element {
type: 'reaction',
can_update: true,
can_copy: false,
variations: []
variations: [],
vessel_size: { amount: null, unit: 'ml' },
})

reaction.short_label = this.buildReactionShortLabel()
Expand Down Expand Up @@ -194,7 +195,8 @@ export default class Reaction extends Element {
timestamp_start: this.timestamp_start,
timestamp_stop: this.timestamp_stop,
segments: this.segments.map(s => s.serialize()),
variations: this.variations
variations: this.variations,
vessel_size: this.vessel_size,
});
}

Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20240711120833_add_vessel_size_to_reaction.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddVesselSizeToReaction < ActiveRecord::Migration[6.1]
def change
add_column :reactions, :vessel_size, :jsonb, null: true, default: { 'unit' => 'ml', 'amount' => nil }
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2024_07_09_095243) do
ActiveRecord::Schema.define(version: 2024_07_11_120833) do

# These are extensions that must be enabled in order to support this database
enable_extension "hstore"
Expand Down Expand Up @@ -960,6 +960,7 @@
t.jsonb "variations", default: []
t.text "plain_text_description"
t.text "plain_text_observation"
t.jsonb "vessel_size", default: {"unit"=>"ml", "amount"=>nil}
t.index ["deleted_at"], name: "index_reactions_on_deleted_at"
t.index ["rinchi_short_key"], name: "index_reactions_on_rinchi_short_key", order: :desc
t.index ["rinchi_web_key"], name: "index_reactions_on_rinchi_web_key"
Expand Down
1 change: 1 addition & 0 deletions lib/import/import_collections.rb
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ def import_reactions
'duration',
'created_at',
'updated_at',
'vessel_size',
).merge(
created_by: @current_user_id,
collections: fetch_many(
Expand Down
2 changes: 2 additions & 0 deletions spec/api/entities/reaction_entity_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@
timestamp_stop: reaction.timestamp_stop,
tlc_description: reaction.tlc_description,
tlc_solvents: reaction.tlc_solvents,
vessel_size: reaction.vessel_size,
)
end

Expand Down Expand Up @@ -301,6 +302,7 @@
tlc_description: '***',
tlc_solvents: '***',
variations: [],
vessel_size: '***',
)
end

Expand Down

0 comments on commit f00b4f6

Please sign in to comment.