diff --git a/app/packs/src/apps/mydb/elements/details/NumeralInputWithUnitsCompo.js b/app/packs/src/apps/mydb/elements/details/NumeralInputWithUnitsCompo.js index fe01aa05c9..da724b5c80 100644 --- a/app/packs/src/apps/mydb/elements/details/NumeralInputWithUnitsCompo.js +++ b/app/packs/src/apps/mydb/elements/details/NumeralInputWithUnitsCompo.js @@ -111,7 +111,7 @@ export default class NumeralInputWithUnitsCompo extends Component { togglePrefix(currentUnit) { const units = ['TON/h', 'TON/m', 'TON/s', '°C', '°F', 'K', 'h', 'm', 's']; - const excludedUnits = ['ppm', 'TON']; + const excludedUnits = ['ppm', 'TON', '%']; const { onMetricsChange, unit } = this.props; if (units.includes(currentUnit)) { // eslint-disable-next-line no-unused-expressions diff --git a/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetails.js b/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetails.js index 48114fa714..801fe6de3e 100644 --- a/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetails.js +++ b/app/packs/src/apps/mydb/elements/details/reactions/ReactionDetails.js @@ -485,6 +485,8 @@ export default class ReactionDetails extends Component { offColor="#d3d3d3" tooltipOn="Click to enable Default mode" tooltipOff="Click to enable Gas mode" + fontSize="14px" + fontWeight="normal" /> diff --git a/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/Material.js b/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/Material.js index 85b7ac1072..0974905f8b 100644 --- a/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/Material.js +++ b/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/Material.js @@ -123,6 +123,7 @@ class Material extends Component { this.gasFieldsUnitsChanged = this.gasFieldsUnitsChanged.bind(this); this.handleCoefficientChange = this.handleCoefficientChange.bind(this); this.debounceHandleAmountUnitChange = debounce(this.handleAmountUnitChange, 500); + this.yieldOrConversionRate = this.yieldOrConversionRate.bind(this); } handleMaterialClick(sample) { @@ -241,22 +242,44 @@ class Material extends Component { return result > 1 ? '100%' : `${(result * 100).toFixed(0)}%`; } - equivalentOrYield(material) { - const { reaction, materialGroup } = this.props; - if (materialGroup === 'products') { - const refMaterial = reaction.getReferenceMaterial(); - let calculateYield = material.equivalent; - if (material.gas_type === 'gas') { - calculateYield = this.recalculateYieldForGasProduct(material, reaction); - } else if (reaction.hasPolymers()) { - calculateYield = `${((material.equivalent || 0) * 100).toFixed(0)}%`; - } else if (refMaterial && (refMaterial.decoupled || material.decoupled)) { - calculateYield = 'n.a.'; - } else if (material.purity < 1 && material.equivalent > 1) { - calculateYield = `${((material.purity / 100 * (material.amount_g * 1000)) * 100).toFixed(1)}%`; - } else { - calculateYield = `${((material.equivalent <= 1 ? material.equivalent || 0 : 1) * 100).toFixed(0)}%`; - } + calculateYield(material, reaction) { + const refMaterial = reaction.getReferenceMaterial(); + let calculateYield = material.equivalent; + if (material.gas_type === 'gas') { + calculateYield = this.recalculateYieldForGasProduct(material, reaction); + } else if (reaction.hasPolymers()) { + calculateYield = `${((material.equivalent || 0) * 100).toFixed(0)}%`; + } else if (refMaterial && (refMaterial.decoupled || material.decoupled)) { + calculateYield = 'n.a.'; + } else if (material.purity < 1 && material.equivalent > 1) { + calculateYield = `${((material.purity / 100 * (material.amount_g * 1000)) * 100).toFixed(1)}%`; + } else { + calculateYield = `${((material.equivalent <= 1 ? material.equivalent || 0 : 1) * 100).toFixed(0)}%`; + } + return calculateYield; + } + + conversionRateField(material) { + const { reaction } = this.props; + const condition = material.conversion_rate / 100 > 1; + const allowedConversionRateValue = material.conversion_rate && condition + ? 100 : material.conversion_rate; + return ( +
+ this.handleConversionRateChange(e)} + /> +
+ ); + } + + yieldOrConversionRate(material) { + const { reaction, displayYieldField } = this.props; + if (displayYieldField) { return (
); } + return this.conversionRateField(material); + } + + equivalentOrYield(material) { + const { materialGroup } = this.props; + if (materialGroup === 'products') { + return this.yieldOrConversionRate(material); + } return ( { + dropMaterial, dropSample, switchEquiv, lockEquivColumn, displayYieldField, + switchYield +}) { const contents = []; let index = headIndex; if (materials && materials.length > 0) { @@ -36,6 +38,7 @@ const MaterialGroup = ({ dropMaterial={dropMaterial} dropSample={dropSample} lockEquivColumn={lockEquivColumn} + displayYieldField={displayYieldField} /> )); @@ -74,9 +77,11 @@ const MaterialGroup = ({ addDefaultSolvent={addDefaultSolvent} switchEquiv={switchEquiv} lockEquivColumn={lockEquivColumn} + displayYieldField={displayYieldField} + switchYield={switchYield} /> ); -}; +} const switchEquivTooltip = () => ( Lock/unlock Equiv
for target amounts
@@ -99,7 +104,7 @@ const SwitchEquivButton = (lockEquivColumn, switchEquiv) => { function GeneralMaterialGroup({ contents, materialGroup, showLoadingColumn, reaction, addDefaultSolvent, - switchEquiv, lockEquivColumn + switchEquiv, lockEquivColumn, displayYieldField, switchYield }) { const isReactants = materialGroup === 'reactants'; let headers = { @@ -151,9 +156,26 @@ function GeneralMaterialGroup({ ); } + const yieldConversionRateFields = () => ( +
+ +
+ ); + if (materialGroup === 'products') { headers.group = 'Products'; - headers.eq = 'Yield'; + headers.eq = yieldConversionRateFields(); } const refTHead = (materialGroup !== 'products') ? headers.ref : null; @@ -310,7 +332,9 @@ MaterialGroup.propTypes = { dropMaterial: PropTypes.func.isRequired, dropSample: PropTypes.func.isRequired, switchEquiv: PropTypes.func.isRequired, - lockEquivColumn: PropTypes.bool + lockEquivColumn: PropTypes.bool, + displayYieldField: PropTypes.bool, + switchYield: PropTypes.func.isRequired }; GeneralMaterialGroup.propTypes = { @@ -320,7 +344,9 @@ GeneralMaterialGroup.propTypes = { addDefaultSolvent: PropTypes.func.isRequired, contents: PropTypes.arrayOf(PropTypes.shape).isRequired, switchEquiv: PropTypes.func.isRequired, - lockEquivColumn: PropTypes.bool + lockEquivColumn: PropTypes.bool, + displayYieldField: PropTypes.bool, + switchYield: PropTypes.func.isRequired }; SolventsMaterialGroup.propTypes = { @@ -332,13 +358,14 @@ SolventsMaterialGroup.propTypes = { MaterialGroup.defaultProps = { showLoadingColumn: false, - lockEquivColumn: false + lockEquivColumn: false, + displayYieldField: true }; GeneralMaterialGroup.defaultProps = { showLoadingColumn: false, - lockEquivColumn: false + lockEquivColumn: false, + displayYieldField: true }; - export { MaterialGroup, GeneralMaterialGroup, SolventsMaterialGroup }; diff --git a/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/MaterialGroupContainer.js b/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/MaterialGroupContainer.js index 6a5db73e3a..6af2658d64 100644 --- a/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/MaterialGroupContainer.js +++ b/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/MaterialGroupContainer.js @@ -55,7 +55,8 @@ class MaterialGroupContainer extends Component { const { materials, materialGroup, showLoadingColumn, headIndex, isOver, canDrop, connectDropTarget, - deleteMaterial, onChange, reaction, dropSample, dropMaterial, switchEquiv, lockEquivColumn + deleteMaterial, onChange, reaction, dropSample, dropMaterial, switchEquiv, lockEquivColumn, + displayYieldField, switchYield, } = this.props; const style = { padding: '2px 5px', @@ -82,6 +83,8 @@ class MaterialGroupContainer extends Component { headIndex={headIndex} switchEquiv={switchEquiv} lockEquivColumn={lockEquivColumn} + displayYieldField={displayYieldField} + switchYield={switchYield} /> , ); @@ -108,7 +111,9 @@ MaterialGroupContainer.propTypes = { canDrop: PropTypes.bool.isRequired, connectDropTarget: PropTypes.func.isRequired, switchEquiv: PropTypes.func, - lockEquivColumn: PropTypes.bool + lockEquivColumn: PropTypes.bool, + displayYieldField: PropTypes.bool.isRequired, + switchYield: PropTypes.func.isRequired, }; MaterialGroupContainer.defaultProps = { diff --git a/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/ReactionDetailsScheme.js b/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/ReactionDetailsScheme.js index 6f70c58ad8..3a2a3ffc91 100644 --- a/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/ReactionDetailsScheme.js +++ b/app/packs/src/apps/mydb/elements/details/reactions/schemeTab/ReactionDetailsScheme.js @@ -46,6 +46,7 @@ export default class ReactionDetailsScheme extends Component { this.state = { reaction, lockEquivColumn: false, + displayYieldField: true, cCon: false, reactionDescTemplate: textTemplate.toJS(), open: true, @@ -63,6 +64,7 @@ export default class ReactionDetailsScheme extends Component { this.dropMaterial = this.dropMaterial.bind(this); this.dropSample = this.dropSample.bind(this); this.switchEquiv = this.switchEquiv.bind(this); + this.switchYield = this.switchYield.bind(this); this.handleOnConditionSelect = this.handleOnConditionSelect.bind(this); this.updateTextTemplates = this.updateTextTemplates.bind(this); this.reactionVesselSize = this.reactionVesselSize.bind(this); @@ -137,6 +139,11 @@ export default class ReactionDetailsScheme extends Component { this.setState({ lockEquivColumn: !lockEquivColumn }); } + switchYield() { + const { displayYieldField } = this.state; + this.setState({ displayYieldField: !displayYieldField }); + } + handleOnConditionSelect(eventKey) { const { reaction } = this.props; const val = eventKey.value; @@ -363,6 +370,11 @@ export default class ReactionDetailsScheme extends Component { this.updatedReactionForGasFieldsUnitsChange(changeEvent) ); break; + case 'conversionRateChanged': + this.onReactionChange( + this.updatedReactionForConversionRateChange(changeEvent) + ); + break; default: break; } @@ -635,6 +647,22 @@ export default class ReactionDetailsScheme extends Component { ); } + updatedReactionForConversionRateChange(changeEvent) { + const { reaction } = this.props; + const { sampleID, conversionRate } = changeEvent; + const updatedSample = reaction.sampleById(sampleID); + + updatedSample.conversion_rate = conversionRate; + if (conversionRate / 100 > 1) { + NotificationActions.add({ + message: 'conversion rate cannot be more than 100%', + level: 'warning' + }); + } + + return this.updatedReactionWithSample(this.updatedSamplesForConversionRateChange.bind(this), updatedSample); + } + calculateEquivalent(refM, updatedSample) { if (!refM.contains_residues) { NotificationActions.add({ @@ -1022,6 +1050,15 @@ export default class ReactionDetailsScheme extends Component { }); } + updatedSamplesForConversionRateChange(samples, updatedSample) { + return samples.map((sample) => { + if (sample.id === updatedSample.id) { + sample.conversion_rate = updatedSample.conversion_rate; + } + return sample; + }); + } + updatedReactionWithSample(updateFunction, updatedSample, type) { const { reaction } = this.state; reaction.starting_materials = updateFunction(reaction.starting_materials, updatedSample, 'starting_materials', type); @@ -1138,7 +1175,8 @@ export default class ReactionDetailsScheme extends Component { const { reaction, lockEquivColumn, - reactionDescTemplate + reactionDescTemplate, + displayYieldField, } = this.state; const minPadding = { padding: '1px 2px 2px 0px' }; if (reaction.editedSample !== undefined) { @@ -1229,6 +1267,8 @@ export default class ReactionDetailsScheme extends Component { onChange={changeEvent => this.handleMaterialsChange(changeEvent)} switchEquiv={this.switchEquiv} lockEquivColumn={this.state.lockEquivColumn} + switchYield={this.switchYield} + displayYieldField={displayYieldField} headIndex={0} /> diff --git a/app/packs/src/components/common/ToggleButton.js b/app/packs/src/components/common/ToggleButton.js index ba3546b37c..8e8a873c5f 100644 --- a/app/packs/src/components/common/ToggleButton.js +++ b/app/packs/src/components/common/ToggleButton.js @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; export default function ToggleButton({ isToggledInitial, onToggle, onChange, onLabel, offLabel, - onColor, offColor, tooltipOn, tooltipOff + onColor, offColor, tooltipOn, tooltipOff, fontSize, fontWeight }) { const [isToggled, setIsToggled] = useState(isToggledInitial); @@ -26,7 +26,7 @@ export default function ToggleButton({ onClick={handleChange} style={{ backgroundColor: buttonColor, minWidth: '50px', border: 'none' }} > - {isToggled ? onLabel : offLabel} + {isToggled ? onLabel : offLabel} ); @@ -42,6 +42,8 @@ ToggleButton.propTypes = { offColor: PropTypes.string, tooltipOn: PropTypes.string, tooltipOff: PropTypes.string, + fontWeight: PropTypes.string, + fontSize: PropTypes.string, }; ToggleButton.defaultProps = { @@ -53,4 +55,6 @@ ToggleButton.defaultProps = { offColor: '#d3d3d3', tooltipOn: 'Click to switch off', tooltipOff: 'Click to switch on', + fontWeight: 'normal', + fontSize: '1em', }; diff --git a/app/packs/src/models/Sample.js b/app/packs/src/models/Sample.js index 5e3947ec76..cc1ec53abb 100644 --- a/app/packs/src/models/Sample.js +++ b/app/packs/src/models/Sample.js @@ -1047,6 +1047,7 @@ export default class Sample extends Element { coefficient: this.coefficient, gas_type: this.gas_type || false, gas_phase_data: this.gas_phase_data, + conversion_rate: this.conversion_rate, }; _.merge(params, extra_params); return params; diff --git a/spec/javascripts/packs/src/components/common/ToggleButton.spec.js b/spec/javascripts/packs/src/components/common/ToggleButton.spec.js index 5e2ffefc27..429ff5c112 100644 --- a/spec/javascripts/packs/src/components/common/ToggleButton.spec.js +++ b/spec/javascripts/packs/src/components/common/ToggleButton.spec.js @@ -27,6 +27,8 @@ describe('', () => { offColor="#d3d3d3" tooltipOn="Click to enable Default mode" tooltipOff="Click to enable Gas mode" + fontSize="1em" + fontWeight="normal" /> ); });