Skip to content

Commit

Permalink
Merge 58f95be into 302bdbb
Browse files Browse the repository at this point in the history
  • Loading branch information
JasonYCHuang committed Jan 12, 2017
2 parents 302bdbb + 58f95be commit 445c116
Show file tree
Hide file tree
Showing 51 changed files with 1,029 additions and 687 deletions.
83 changes: 43 additions & 40 deletions app/api/chemotion/report_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ class ReportAPI < Grape::API
end
get :docx do
reaction = Reaction.find(params[:id])
content = Report::Docx::Document.new(reactions: [reaction]).reactions
content = Report::Docx::Document.new(objs: [reaction]).convert

filename = "ELN_Reaction_" + Time.now.strftime("%Y-%m-%dT%H-%M-%S") + ".docx"
template_path = Rails.root.join("lib", "template", "ELN_Reactions.docx")
template_path = Rails.root.join("lib", "template", "ELN_Objs.docx")

content_type MIME::Types.type_for(filename)[0].to_s
env['api.format'] = :binary
header 'Content-Disposition', "attachment; filename*=UTF-8''#{CGI.escape(filename)}"
docx = Sablon.template(template_path).render_to_string(merge(content, all_settings, all_configs))
docx = Sablon.template(template_path).render_to_string(merge(content, all_spl_settings, all_rxn_settings, all_configs))
end

params do
Expand Down Expand Up @@ -102,52 +102,63 @@ class ReportAPI < Grape::API
end

resource :multiple_reports do
desc "Build a multi-reactions report using the contents of a JSON file"
desc "Build a multi-objects report using the contents of a JSON file"

params do
requires :ids
requires :settings
requires :objTags
requires :splSettings
requires :rxnSettings
requires :configs
optional :img_format, default: 'png', values: %w(png eps emf)
end

get :docx do
ids = params[:ids].split("_")
settings = set_settings(params[:settings].split("_"))
configs = set_configs(params[:configs].split("_"))
reactions = ids.map { |id| Reaction.find(id) }
objTags = JSON.parse(params[:objTags])
spl_settings = hashize(JSON.parse(params[:splSettings]))
rxn_settings = hashize(JSON.parse(params[:rxnSettings]))
configs = hashize(JSON.parse(params[:configs]))
puts "- - -- - - "
puts spl_settings

objs = objTags.map { |tag| tag["type"].camelize.constantize.find(tag["id"]) }
contents = Report::Docx::Document.new(
reactions: reactions,
objs: objs,
img_format: params[:img_format]
).reactions
).convert

filename = "ELN_Reactions_" + Time.now.strftime("%Y-%m-%dT%H-%M-%S") + ".docx"
template_path = Rails.root.join("lib", "template", "ELN_Reactions.docx")
filename = "ELN_Report_" + Time.now.strftime("%Y-%m-%dT%H-%M-%S") + ".docx"
template_path = Rails.root.join("lib", "template", "ELN_Objs.docx")

content_type MIME::Types.type_for(filename)[0].to_s
env['api.format'] = :binary
header 'Content-Disposition', "attachment; filename*=UTF-8''#{CGI.escape(filename)}"
docx = Sablon.template(template_path).render_to_string(merge(contents, settings, configs))
docx = Sablon.template(template_path).render_to_string(merge(contents, spl_settings, rxn_settings, configs))
end
end

helpers do
def set_settings(settings)
def hashize(inputs)
output = {}
inputs.each do |inp|
key = inp["text"].to_sym
val = inp["checked"]
output[key] = val
end
output
end

def all_spl_settings
{
formula: settings.index("formula"),
material: settings.index("material"),
description: settings.index("description"),
purification: settings.index("purification"),
tlc: settings.index("tlc"),
observation: settings.index("observation"),
analysis: settings.index("analysis"),
literature: settings.index("literature"),
diagram: true,
collection: true,
analyses_description: true,
analyses_content: true,
}
end

def all_settings
def all_rxn_settings
{
formula: true,
diagram: true,
material: true,
description: true,
purification: true,
Expand All @@ -158,29 +169,21 @@ def all_settings
}
end

def set_configs(configs)
{
pageBreak: configs.index("pagebreak"),
wholeFormula: configs.index("showallmater"),
productFormula: !configs.index("showallmater")
}
end

def all_configs
{
pageBreak: true,
wholeFormula: true,
productFormula: false
page_break: true,
whole_diagram: true,
}
end

def merge(contents, settings, configs)
def merge(contents, spl_settings, rxn_settings, configs)
{
date: Time.now.strftime("%d.%m.%Y"),
author: "#{current_user.first_name} #{current_user.last_name}",
settings: settings,
spl_settings: spl_settings,
rxn_settings: rxn_settings,
configs: configs,
reactions: contents
objs: contents
}
end

Expand Down
1 change: 1 addition & 0 deletions app/api/chemotion/sample_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ def self.updated_embedded_analyses(analyses)
id: ana.id,
type: ana.type,
name: ana.name,
report: ana.report,
kind: ana.kind,
status: ana.status,
content: ana.content,
Expand Down
10 changes: 4 additions & 6 deletions app/assets/javascripts/components/Analysis.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, {Component} from 'react';
import {Col, FormControl,FormGroup, ControlLabel} from 'react-bootstrap';
import Select from 'react-select'
import AnalysisDatasets from './AnalysisDatasets';
import QuillEditor from './QuillEditor'

export default class Analysis extends Component {
constructor(props) {
Expand Down Expand Up @@ -93,13 +94,10 @@ export default class Analysis extends Component {
<Col md={12}>
<FormGroup>
<ControlLabel>Content</ControlLabel>
<FormControl
componentClass="textarea"
label="Content"
value={analysis.content || ''}
<QuillEditor
value={analysis.content || { "ops": [{ "insert": "" }] }}
disabled={readOnly}
onChange={event => this.handleInputChange('content', event)}
/>
onChange={event => this.handleInputChange('content', {target: {value: event}})} />
</FormGroup>
<FormGroup>
<ControlLabel>Description</ControlLabel>
Expand Down
3 changes: 2 additions & 1 deletion app/assets/javascripts/components/DragDropItemTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export default {
MATERIAL: 'material',
WELLPLATE: 'wellplate',
RESEARCH_PLAN: 'research_plan',
LAYOUT: 'layout'
LAYOUT: 'layout',
GENERAL: 'general',
};
43 changes: 43 additions & 0 deletions app/assets/javascripts/components/QuillViewer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react'
import ReactDOM from 'react-dom'
import Quill from 'quill'

export default class QuillViewer extends React.Component {
constructor (props) {
super(props);

this.viewer = false;
}

componentDidMount() {
this.initQuill();
}

initQuill() {
if (!this.viewer) {
const quillViewer = ReactDOM.findDOMNode(this.refs.quillViewer);
const defaultOptions = {
theme: this.theme,
readOnly: this.readOnly,
};

this.viewer = new Quill(quillViewer, defaultOptions);
this.viewer.setContents(this.props.value);
}
}

render() {
this.theme = 'bubble';
this.readOnly = true;

return (
<div className="quill-viewer">
<div ref="quillViewer"></div>
</div>
);
}
}

QuillViewer.propTypes = {
value: React.PropTypes.object,
}
66 changes: 53 additions & 13 deletions app/assets/javascripts/components/SampleDetailsAnalyses.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ export default class SampleDetailsAnalyses extends Component {
this.props.parent.setState({sample: sample})
}

handleAccordionOpen(key) {
this.setState({activeAnalysis: key});
handleAccordionOpen(newKey) {
const currentKey = this.state.activeAnalysis;
if(currentKey !== newKey) {
this.setState({activeAnalysis: newKey});
}
}

addButton() {
Expand All @@ -60,28 +63,65 @@ export default class SampleDetailsAnalyses extends Component {
}
}

toggleAddToReport(e, analysis) {
e.stopPropagation();
analysis.report = !analysis.report;
this.handleChange(analysis);
}

analysisHeader(analysis, readOnly) {
const confirmDelete = () => {
if(confirm('Delete the analysis?')) {
this.handleRemove(analysis)
}
};
const kind = (analysis.kind && analysis.kind != '')
? (' - Type: ' + analysis.kind)
: ''
const status = (analysis.status && analysis.status != '')
? (' - Status: ' + analysis.status)
:''
const inReport = analysis.report === true;

return (
<div style={{width: '100%'}}>
{analysis.name}
{kind}
{status}
<div className="button-right">
<label>
<input onClick={(e) => this.toggleAddToReport(e, analysis)}
type="checkbox"
checked={inReport} />
<span>Add to Report</span>
</label>
<Button bsSize="xsmall"
bsStyle="danger"
className="g-marginLeft--20"
disabled={readOnly}
onClick={confirmDelete}>
<i className="fa fa-trash"></i>
</Button>
</div>
</div>
);
}

render() {
const {sample, activeAnalysis} = this.state;
const {readOnly} = this.props;

let analysisHeader = (analysis) => <p style={{width: '100%'}}>{analysis.name}
{(analysis.kind && analysis.kind != '') ? (' - Type: ' + analysis.kind) : ''}
{(analysis.status && analysis.status != '') ? (' - Status: ' + analysis.status) :''}
<Button bsSize="xsmall" bsStyle="danger"
className="button-right" disabled={readOnly}
onClick={() => {if(confirm('Delete the analysis?')) {this.handleRemove(analysis)}}}>
<i className="fa fa-trash"></i>
</Button></p>

if(sample.analyses.length > 0) {
return (
<div>
<p>&nbsp;{this.addButton()}</p>
<PanelGroup defaultActiveKey={0} activeKey={activeAnalysis} accordion>
{sample.analyses.map(
(analysis, key) =>
<Panel header={analysisHeader(analysis)} eventKey={key}
key={key} onClick={() => this.handleAccordionOpen(key)}>
<Panel header={this.analysisHeader(analysis, readOnly)}
eventKey={key}
key={key}
onClick={() => this.handleAccordionOpen(key)}>
<AnalysisComponent
readOnly={readOnly}
analysis={analysis}
Expand Down
20 changes: 14 additions & 6 deletions app/assets/javascripts/components/actions/ReportActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@ class ReportActions {
return value;
}

updateSettings(target) {
updateSplSettings(target) {
return target;
}

toggleSettingsCheckAll() {
toggleSplSettingsCheckAll() {
return null;
}

updateRxnSettings(target) {
return target;
}

toggleRxnSettingsCheckAll() {
return null;
}

Expand All @@ -26,12 +34,12 @@ class ReportActions {
return null;
}

updateCheckedIds(ids) {
return ids;
updateCheckedTags(tags) {
return tags;
}

move({sourceId, targetId}) {
return {sourceId, targetId};
move({sourceTag, targetTag}) {
return {sourceTag, targetTag};
}
}

Expand Down
5 changes: 0 additions & 5 deletions app/assets/javascripts/components/constant/ItemTypes.js

This file was deleted.

5 changes: 4 additions & 1 deletion app/assets/javascripts/components/models/Analysis.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import Dataset from './Dataset';

export default class Analysis extends Element {
static buildEmpty() {
const content_default = { "ops": [{ "insert": "" }] }
return new Analysis({
name: 'new Analysis',
type: 'analysis',
report: true,
kind: '',
status: '',
content: '',
content: content_default,
description: '',
datasets: []
})
Expand Down Expand Up @@ -50,6 +52,7 @@ export default class Analysis extends Element {
serialize() {
return super.serialize({
name: this.name,
report: this.report,
kind: this.kind,
status: this.status,
content: this.content,
Expand Down
Loading

0 comments on commit 445c116

Please sign in to comment.