Commit 8daa41aa authored by Florian Hübsch's avatar Florian Hübsch
Browse files

Refactor Sample Details, add external_label to samples.

parent c76d142f
......@@ -76,6 +76,7 @@ module Chemotion
params do
requires :id, type: Integer, desc: "Sample id"
optional :name, type: String, desc: "Sample name"
optional :external_label, type: String, desc: "Sample external label"
optional :amount_value, type: Float, desc: "Sample amount_value"
optional :amount_unit, type: String, desc: "Sample amount_unit"
optional :description, type: String, desc: "Sample description"
......@@ -106,6 +107,7 @@ module Chemotion
desc "Create a sample"
params do
requires :name, type: String, desc: "Sample name"
optional :external_label, type: String, desc: "Sample external label"
requires :amount_value, type: Float, desc: "Sample amount_value"
requires :amount_unit, type: String, desc: "Sample amount_unit"
requires :description, type: String, desc: "Sample description"
......
......@@ -51,6 +51,7 @@ export default class SampleDetails extends React.Component {
return {
id: this.state.sample.id,
name: this.nullOrValue(this.state.sample.name),
external_label: this.nullOrValue(this.state.sample.external_label),
amount_value: this.nullOrValue(this.state.sample.amount_value),
amount_unit: this.nullOrValue(this.state.sample.amount_unit),
description: this.nullOrValue(this.state.sample.description),
......@@ -89,6 +90,14 @@ export default class SampleDetails extends React.Component {
});
}
handleExternalLabelChanged(e) {
let sample = this.state.sample;
sample.external_label = this.refs.externalLabelInput.getValue();
this.setState({
sample: sample
});
}
handleDescriptionChanged(e) {
let sample = this.state.sample;
sample.description = this.refs.descriptionInput.getValue();
......@@ -116,7 +125,7 @@ export default class SampleDetails extends React.Component {
handleDensityChanged(e) {
let sample = this.state.sample;
sample.molecule.density = this.refs.densityInput.getValue();
sample.molecule_density = this.refs.densityInput.getValue();
this.setState({
sample: sample
});
......@@ -132,7 +141,7 @@ export default class SampleDetails extends React.Component {
handleBoilingPointChanged(e) {
let sample = this.state.sample;
sample.molecule.boiling_point = this.refs.boilingPointInput.getValue();
sample.molecule_boiling_point = this.refs.boilingPointInput.getValue();
this.setState({
sample: sample
});
......@@ -156,7 +165,7 @@ export default class SampleDetails extends React.Component {
handleMeltingPointChanged(e) {
let sample = this.state.sample;
sample.molecule.melting_point = this.refs.meltingPointInput.getValue();
sample.molecule_melting_point = this.refs.meltingPointInput.getValue();
this.setState({
sample: sample
});
......@@ -236,9 +245,9 @@ export default class SampleDetails extends React.Component {
_submitLabel() {
if(this.state.sample.id == '_new_') {
return "Save Sample";
return "Create";
} else {
return "Update Sample";
return "Save";
}
}
......@@ -256,8 +265,12 @@ export default class SampleDetails extends React.Component {
}
// Input Components of Sample Details with scoping
isDisabled(sample, method) {
return sample.isRestricted() == true && (sample[method] == undefined && sample.molecule == undefined || sample.molecule[method] == undefined) && sample.id != '_new_'
}
topSecretCheckbox(sample) {
if(sample.is_scoped == false || sample.is_top_secret || sample.id == '_new_') {
if(!this.isDisabled(sample, 'is_top_secret')) {
return (
<Input ref="topSecretInput" type="checkbox" label="Top secret" checked={sample.is_top_secret} onChange={(e) => this.handleTopSecretChanged(e)}/>
)
......@@ -265,29 +278,19 @@ export default class SampleDetails extends React.Component {
}
moleculeInput(sample) {
if(sample.is_scoped == false || sample.molecule || sample.id == '_new_' ) {
return (
<Input type="text" label="Molecule" ref="moleculeInput"
buttonAfter={this.structureEditorButton(false)}
buttonAfter={this.structureEditorButton(this.isDisabled(sample, 'molecule'))}
defaultValue={sample.molecule && (sample.molecule.iupac_name || sample.molecule.sum_formular)}
disabled={this.isDisabled(sample, 'molecule')}
/>
)
} else {
return (
<Input type="text" label="Molecule" ref="moleculeInput"
buttonAfter={this.structureEditorButton(true)}
value="***"
disabled
/>
)
}
}
sampleHeader(sample) {
let sampleAmount = sample.amount_value && sample.amount_unit ? `(${sample.amount_value} ${sample.amount_unit})` : '';
let svgPath = sample.molecule && sample.molecule.molecule_svg_file ? `/images/molecules/${sample.molecule.molecule_svg_file}` : '';
if(sample.is_scoped == false || sampleAmount && svgPath || sample.id == '_new_') {
return (
<table width="100%" height="190px">
<tr>
......@@ -302,187 +305,88 @@ export default class SampleDetails extends React.Component {
</tr>
</table>
)
} else {
return (
<table width="100%" height="190px">
<tr>
<td width="70%">
<h3>{sample.name || '***'}</h3>
<h4>{sampleAmount || '***'}</h4>
<ElementCollectionLabels element={sample} key={sample.id}/>
</td>
<td width="30%">
<SVG key={sample.molecule && sample.molecule.id} src={svgPath} className="molecule-mid"/>
</td>
</tr>
</table>
)
}
}
moleculeInchi(sample) {
if(sample.is_scoped == false || sample.molecule.inchistring || sample.id == '_new_') {
return (
<Input type="text" label="InChI"
defaultValue={sample.molecule && (sample.molecule.inchistring)}
disabled
/>
)
} else {
return (
<Input type="text" label="InChI"
value='***'
defaultValue={sample.molecule_inchistring}
disabled
/>
)
}
}
molecularWeight(sample) {
if(sample.is_scoped == false || sample.molecule.molecular_weight || sample.id == '_new_') {
return (
<Input type="text" label="M. Weight"
defaultValue={sample.molecule && (sample.molecule.molecular_weight)}
disabled
/>
)
} else {
return (
<Input type="text" label="M. Weight"
value='***'
defaultValue={sample.molecule_molecular_weight}
disabled
/>
)
}
}
moleculeDensity(sample) {
if(sample.is_scoped == false || sample.molecule.density || sample.id == '_new_' ) {
return (
<Input type="text" label="Density" ref="densityInput"
value={sample.molecule && (sample.molecule.density)}
value={sample.molecule_density}
onChange={(e) => this.handleDensityChanged(e)}
disabled={this.isDisabled(sample, 'density')}
/>
)
} else {
return (
<Input type="text" label="Density" ref="densityInput"
value='***'
onChange={(e) => this.handleDensityChanged(e)}
disabled
/>
)
}
}
moleculeFormular(sample) {
if(sample.is_scoped == false || sample.molecule.sum_formular || sample.id == '_new_') {
return (
<Input type="text" label="Formula"
defaultValue={sample.molecule && (sample.molecule.sum_formular)}
defaultValue={sample.molecule_formula}
disabled
/>
)
} else {
return (
<Input type="text" label="Formula"
value='***'
disabled
/>
)
}
}
moleculeBoilingPoint(sample) {
if(sample.is_scoped == false || sample.molecule.boiling_point || sample.id == '_new_' ) {
return (
<Input type="text" label="Boiling Point" ref="boilingPointInput"
value={sample.molecule && (sample.molecule.boiling_point) }
value={sample.molecule_boiling_point}
onChange={(e) => this.handleBoilingPointChanged(e)}
disabled={this.isDisabled(sample, 'boiling_point')}
/>
)
} else {
return (
<Input type="text" label="Boiling Point" ref="boilingPointInput"
value="***"
onChange={(e) => this.handleBoilingPointChanged(e)}
disabled
/>
)
}
}
moleculeMeltingPoint(sample) {
if(sample.is_scoped == false || sample.molecule.melting_point || sample.id == '_new_' ) {
return (
<Input type="text" label="Melting Point" ref="meltingPointInput"
value={sample.molecule && (sample.molecule.melting_point) }
value={sample.molecule_melting_point}
onChange={(e) => this.handleMeltingPointChanged(e)}
/>
)
} else {
return (
<Input type="text" label="Melting Point" ref="meltingPointInput"
value="***"
onChange={(e) => this.handleMeltingPointChanged(e)}
disabled
disabled={this.isDisabled(sample, 'melting_point')}
/>
)
}
}
sampleName(sample) {
if(sample.is_scoped == false || sample.name || sample.id == '_new_' ) {
return (
<Input type="text" label="Name" ref="nameInput"
placeholder={sample.name}
value={sample.name}
onChange={(e) => this.handleNameChanged(e)}
disabled={this.isDisabled(sample, 'name')}
/>
)
} else {
return (
<Input type="text" label="Name" ref="nameInput"
value="***"
onChange={(e) => this.handleNameChanged(e)}
disabled
/>
)
}
}
sampleImpurities(sample) {
if(sample.is_scoped == false || sample.impurities || sample.id == '_new_' ) {
return (
<Input type="text" label="Impurities"
ref="impuritiesInput"
value={sample.impurities}
onChange={(e) => this.handleImpuritiesChanged(e)}
/>
)
} else {
return (
<Input type="text" label="Impurities"
ref="impuritiesInput"
value="***"
onChange={(e) => this.handleImpuritiesChanged(e)}
disabled
disabled={this.isDisabled(sample, 'impurities')}
/>
)
}
}
sampleSolvent(sample) {
if(sample.is_scoped == false || sample.solvent || sample.id == '_new_' ) {
return (
<Select ref='solventInput'
name='solvents'
multi={false}
options={solvents}
onChange={(e) => this.handleSolventChanged(e)}
value={sample.solvent}/>
)
} else {
return (
<Select ref='solventInput'
name='solvents'
......@@ -490,49 +394,13 @@ export default class SampleDetails extends React.Component {
options={solvents}
onChange={(e) => this.handleSolventChanged(e)}
value={sample.solvent}
disabled/>
)
}
}
sampleWeight(sample) {
if(sample.is_scoped == false || sample.weight || sample.id == '_new_' ) {
return (
<Input type="text" label="Weight"
defaultValue={sample.weight}
disabled
/>
)
} else {
return (
<Input type="text" label="Weight"
value="***"
disabled
disabled={this.isDisabled(sample, 'solvent')}
/>
)
}
}
sampleVolume(sample) {
if(sample.is_scoped == false || sample.volume || sample.id == '_new_' ) {
return (
<Input type="text" label="Volume"
defaultValue={sample.volume}
disabled
/>
)
} else {
return (
<Input type="text" label="Volume"
value="***"
disabled
/>
)
}
}
sampleAmount(sample) {
if(sample.is_scoped == false || sample.amount_value || sample.id == '_new_' ) {
if(this.isDisabled(sample, 'amount_value') == false) {
return (
<table><tr>
<td>
......@@ -575,71 +443,51 @@ export default class SampleDetails extends React.Component {
}
samplePurity(sample) {
if(sample.is_scoped == false || sample.purity || sample.id == '_new_' ) {
return (
<Input type="text" label="Purity"
ref="purityInput"
value={sample.purity}
numeralFormat='0,0.00'
onChange={(e) => this.handlePurityChanged(e)}
/>
)
} else {
return (
<Input type="text" label="Purity"
ref="purityInput"
value="***"
onChange={(e) => this.handlePurityChanged(e)}
disabled
disabled={this.isDisabled(sample, 'purity')}
/>
)
}
}
sampleLocation(sample) {
if(sample.is_scoped == false || sample.location || sample.id == '_new_') {
return (
<Input type="textarea" label="Location"
ref="locationInput"
value={sample.location}
onChange={(e) => this.handleLocationChanged(e)}
rows={2}
disabled={this.isDisabled(sample, 'location')}
/>
)
} else {
return (
<Input type="textarea" label="Location"
ref="locationInput"
value="***"
onChange={(e) => this.handleLocationChanged(e)}
rows={2}
disabled
/>
)
}
}
sampleDescription(sample) {
if(sample.is_scoped == false || sample.description || sample.id == '_new_' ) {
return (
<Input type="textarea" label="Description" ref="descriptionInput"
placeholder={sample.description}
value={sample.description}
onChange={(e) => this.handleDescriptionChanged(e)}
rows={2}
disabled={this.isDisabled(sample, 'description')}
/>
)
} else {
}
sampleExternalLabel(sample) {
return (
<Input type="textarea" label="Description" ref="descriptionInput"
value="***"
onChange={(e) => this.handleDescriptionChanged(e)}
rows={2}
disabled
<Input type="text" label="External Label"
ref="externalLabelInput"
value={sample.external_label}
onChange={(e) => this.handleExternalLabelChanged(e)}
disabled={this.isDisabled(sample, 'external_label')}
/>
)
}
}
render() {
let sample = this.state.sample || {}
......@@ -705,11 +553,8 @@ export default class SampleDetails extends React.Component {
</td>
</tr>
<tr>
<td width="25%" className="padding-right">
{this.sampleWeight(sample)}
</td>
<td width="25%" className="padding-right">
{this.sampleVolume(sample)}
<td width="50%" className="padding-right" colSpan={2}>
{this.sampleExternalLabel(sample)}
</td>
<td width="25%" className="padding-right">
{this.sampleAmount(sample)}
......@@ -731,7 +576,7 @@ export default class SampleDetails extends React.Component {
</ListGroupItem>
<ListGroupItem>
<ButtonToolbar>
<Button bsStyle="primary" onClick={this.closeDetails.bind(this)}>Back</Button>
<Button bsStyle="primary" onClick={this.closeDetails.bind(this)}>Close</Button>
<Button bsStyle="warning" onClick={this._submitFunction.bind(this)}
disabled={!sampleIsValid}>{this._submitLabel()}</Button>
</ButtonToolbar>
......
......@@ -152,6 +152,7 @@ class ElementActions {
id: '_new_',
type: 'sample',
name: 'New Sample',
external_label: '',
amount_value: 0,
amount_unit: 'g',
description: '',
......
import 'whatwg-fetch';
import Sample from '../models/Sample';
import SampleProxy from '../proxies/SampleProxy';
// TODO: SamplesFetcher also updates Samples and so on...naming?
......@@ -11,7 +12,7 @@ export default class SamplesFetcher {
.then((response) => {
return response.json()
}).then((json) => {
return new Sample(json.sample);
return new SampleProxy(json.sample);
}).catch((errorMessage) => {
console.log(errorMessage);
});
......@@ -52,6 +53,7 @@ export default class SamplesFetcher {
},
body: JSON.stringify({
name: paramObj.name,
external_label: paramObj.external_label,
amount_value: paramObj.amount_value,
amount_unit: paramObj.amount_unit,
description: paramObj.description,
......@@ -79,6 +81,7 @@ export default class SamplesFetcher {
},
body: JSON.stringify({
name: paramObj.name,
external_label: paramObj.external_label,
amount_value: paramObj.amount_value,
amount_unit: paramObj.amount_unit,
description: paramObj.description,
......
......@@ -6,6 +6,11 @@ export default class Sample {
Object.assign(this, args);
}
// methods regarding sharing and sample detail levels
isRestricted() {
return this.is_restricted;
}
get name() {
return this._name
}
......@@ -14,10 +19,42 @@ export default class Sample {
this._name = name
}
get external_label() {
return this._external_label;
}
set external_label(label) {
this._external_label = label;
}
get location() {
return this._location;
}
set location(location) {
this._location = location;
}
get description() {
return this._description;
}
set description(description) {
this._description = description;
}
get impurities() {
return this._impurities;
}
set impurities(impurities) {
this._impurities = impurities;
}
get amount() {
return({
value: amount_value,
unit: amount_unit
value: this.amount_value,
unit: this.amount_unit
})
}
......@@ -66,11 +103,17 @@ export default class Sample {
return amount_mg;
break;
case 'ml':
let molecule_density = this.molecule_density;
if(molecule_density) {
return amount_mg / this.molecule_density;
break;