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

Editing of sample name, add needed action for updating sample.

parent 4fe7b43b
......@@ -26,6 +26,10 @@ A user is seeded with email `test@ninjaconcept.com` and password `ninjaconcept`.
`/api/v1/collections/roots`
* Get serialized samples by collection id
`/api/v1/collections/:collection_id/samples`
* Get serialized sample by id
`/api/v1/samples/:id`
class API < Grape::API
prefix 'api'
version 'v1'
format :json
formatter :json, Grape::Formatter::ActiveModelSerializers
mount Chemotion::CollectionAPI
......
......@@ -5,6 +5,17 @@ module Chemotion
get :roots do
Collection.roots
end
desc "Return serialized samples for given collection id"
params do
requires :id, type: Integer, desc: "Collection id"
end
route_param :id do
get :samples do
Collection.find(params[:id]).samples
end
end
end
end
end
module Chemotion
class SampleAPI < Grape::API
# TODO ensure user is authenticated
resource :samples do
desc "Return serialized sample by id"
params do
......@@ -10,6 +12,17 @@ module Chemotion
Sample.find(params[:id])
end
end
desc "Update sample by id"
params do
requires :id, type: Integer, desc: "Sample id"
requires :name, type: String, desc: "Sample name"
end
put ':id' do
Sample.find(params[:id]).update({
name: params[:name]
})
end
end
end
end
......@@ -3,6 +3,7 @@ import {Button} from 'react-bootstrap';
import UIStore from './stores/UIStore';
import UIActions from './actions/UIActions';
import ElementStore from './stores/ElementStore';
import ElementActions from './actions/ElementActions';
class CollectionSubtree extends React.Component {
......@@ -26,8 +27,8 @@ class CollectionSubtree extends React.Component {
componentWillUpdate(nextProps, nextState) {
if(nextState.selected) {
// TODO updateElements for reactions and so on
ElementActions.updateElements({samples: this.state.root.samples, type: 'sample'});
// TODO also for reactions and so on
ElementActions.fetchSamplesByCollectionId(this.state.root.id)
}
}
......
import React from 'react';
import {FormControls, Input, Modal} from 'react-bootstrap';
import {Button, FormControls, Input, Modal} from 'react-bootstrap';
import ElementActions from './actions/ElementActions';
import ElementStore from './stores/ElementStore';
......@@ -42,6 +42,13 @@ class SampleDetails extends React.Component {
return sample ? sample.created_at : '';
}
updateSample() {
ElementActions.updateSample({
id: this.state.id,
name: this.refs.nameInput.getValue() || this.state.sample.name
})
}
render() {
return (
<div>
......@@ -51,8 +58,9 @@ class SampleDetails extends React.Component {
</Modal.Header>
<Modal.Body>
<form>
<Input type="text" label="Name" placeholder={this.sampleName()} />
<Input type="text" label="Name" ref="nameInput" placeholder={this.sampleName()} />
<FormControls.Static label="Created at" value={this.createdAt()} />
<Button bsStyle="warning" onClick={this.updateSample.bind(this)}>Update Sample</Button>
</form>
</Modal.Body>
</Modal>
......
......@@ -11,6 +11,25 @@ class ElementActions {
});
}
fetchSamplesByCollectionId(id) {
SamplesFetcher.fetchByCollectionId(id)
.then((result) => {
// TODO adjust when CollectionAPI fixed
this.dispatch(result[':id']);
}).catch((errorMessage) => {
console.log(errorMessage);
});
}
updateSample(paramObj) {
SamplesFetcher.update(paramObj)
.then((result) => {
this.dispatch(paramObj.id)
}).catch((errorMessage) => {
console.log(errorMessage);
});
}
updateElements(elements) {
this.dispatch(elements);
}
......
// TODO: SamplesFetcher also updates Samples and so on...naming?
var SamplesFetcher = {
fetchById(id) {
var promise = fetch('/api/v1/samples/' + id + '.json')
......@@ -9,6 +10,34 @@ var SamplesFetcher = {
console.log(errorMessage);
});
return promise;
},
fetchByCollectionId(id) {
var promise = fetch('/api/v1/collections/' + id + '/samples.json')
.then((response) => {
return response.json()
}).then((json) => {
return json;
}).catch((errorMessage) => {
console.log(errorMessage);
});
return promise;
},
update(paramObj) {
var promise = fetch('/api/v1/samples/' + paramObj.id, {
method: 'put',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: paramObj.name
})
})
return promise;
}
}
......
......@@ -9,7 +9,8 @@ class ElementStore {
this.bindListeners({
handleFetchSampleById: ElementActions.fetchSampleById,
handleUpdateElements: ElementActions.updateElements
handleFetchSamplesByCollectionId: ElementActions.fetchSamplesByCollectionId,
handleUpdateSample: ElementActions.updateSample
})
}
......@@ -17,12 +18,13 @@ class ElementStore {
this.state.samples = [result];
}
handleUpdateElements(elements) {
switch(elements.type) {
case 'sample':
this.state.samples = elements.samples;
break;
}
handleFetchSamplesByCollectionId(result) {
this.state.samples = result;
}
// update stored sample if it has been updated
handleUpdateSample(sampleId) {
ElementActions.fetchSampleById(sampleId);
}
}
......
......@@ -2,7 +2,6 @@ class CollectionSerializer < ActiveModel::Serializer
attributes :id, :label
has_many :children
has_many :samples
def children
object.children
......
class SampleSerializer < ActiveModel::Serializer
attributes :id, :name, :created_at, :collection_labels
def created_at
object.created_at.strftime("%d.%m.%Y, %H:%M")
end
def collection_labels
object.collections.flat_map(&:label)
end
......
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