Commit f15a6ce9 authored by hh1966's avatar hh1966
Browse files

Refactor export

parent 5c2fbea1
Pipeline #53709 failed with stage
......@@ -187,7 +187,6 @@ module Chemotion
desc "Export research plan by id"
params do
requires :id, type: Integer, desc: "Research plan id"
requires :html, type: String, desc: "Client side rendered html"
optional :export_format, type: Symbol, desc: "Export format", values: [:docx, :odt, :html, :markdown, :latex]
end
route_param :id do
......@@ -195,9 +194,12 @@ module Chemotion
error!('401 Unauthorized', 401) unless ElementPolicy.new(current_user, ResearchPlan.find(params[:id])).read?
end
post :export do
get :export do
research_plan = ResearchPlan.find(params[:id])
# convert researhc plan
export = Export::ExportResearchPlan.new current_user, research_plan, params[:export_format]
# return the response "as is"
env['api.format'] = :binary
......@@ -206,8 +208,6 @@ module Chemotion
content_type "application/octet-stream"
# init the export object
export = Export::ExportResearchPlan.new params[:html], params[:export_format]
if [:html, :markdown, :latex].include? params[:export_format]
header['Content-Disposition'] = "attachment; filename=\"#{research_plan.name}.zip\""
present export.to_zip
......@@ -217,7 +217,7 @@ module Chemotion
end
else
# return plain html
present params[:html]
present export.to_html
end
end
end
......
......@@ -122,19 +122,15 @@ export default class ResearchPlansFetcher {
return promise();
}
static export(researchPlan, html, exportFormat) {
static export(researchPlan, exportFormat) {
let file_name
const promise = fetch('/api/v1/research_plans/' + researchPlan.id + '/export/', {
const promise = fetch(`/api/v1/research_plans/${researchPlan.id}/export/?export_format=${exportFormat}`, {
credentials: 'same-origin',
method: 'post',
method: 'get',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
html: html,
export_format: exportFormat
})
}
}).then((response) => {
if (response.ok) {
file_name = getFileName(response)
......@@ -152,7 +148,7 @@ export default class ResearchPlansFetcher {
static exportTable(researchPlan, field) {
let file_name
const promise = fetch('/api/v1/research_plans/' + researchPlan.id + '/export_table/' + field.id, {
const promise = fetch(`/api/v1/research_plans/${researchPlan.id}/export_table/${field.id}/`, {
credentials: 'same-origin',
method: 'get',
headers: {
......@@ -184,13 +180,10 @@ export default class ResearchPlansFetcher {
}
}).then((response) => {
if (response.ok) {
file_name = getFileName(response)
return response.blob()
return response.json()
} else {
throw Error(response.statusText);
}
}).then((blob) => {
downloadBlob(file_name, blob)
}).catch((errorMessage) => {
console.log(errorMessage);
});
......
......@@ -28,9 +28,7 @@ export default class ResearchPlanDetails extends Component {
this.state = {
research_plan,
update: false
};
this.nameRef = React.createRef()
this.bodyRef = React.createRef()
}
}
componentWillReceiveProps(nextProps) {
......@@ -173,21 +171,7 @@ export default class ResearchPlanDetails extends Component {
handleExport(exportFormat) {
const { research_plan } = this.state;
const name = ReactDOM.findDOMNode(this.nameRef.current)
const body = ReactDOM.findDOMNode(this.bodyRef.current)
let html = name.innerHTML
Array.from(body.getElementsByClassName('research-plan-field')).map(field => {
const editors = field.getElementsByClassName('ql-editor')
if (editors.length) {
html += editors[0].innerHTML
} else {
html += field.innerHTML
}
})
ResearchPlansFetcher.export(research_plan, html, exportFormat)
ResearchPlansFetcher.export(research_plan, exportFormat)
}
handleExportField(field) {
......@@ -236,8 +220,7 @@ export default class ResearchPlanDetails extends Component {
<ResearchPlanDetailsName value={name}
disabled={research_plan.isMethodDisabled('name')}
onChange={this.handleNameChange.bind(this)}
edit={false}
ref={this.nameRef} />
edit={false} />
<ResearchPlanDetailsBody body={body}
disabled={research_plan.isMethodDisabled('body')}
......@@ -247,8 +230,7 @@ export default class ResearchPlanDetails extends Component {
onDelete={this.handleBodyDelete.bind(this)}
onExport={this.handleExportField.bind(this)}
update={update}
edit={false}
ref={this.bodyRef} />
edit={false} />
</ListGroupItem>
</ListGroup>
)
......@@ -263,8 +245,7 @@ export default class ResearchPlanDetails extends Component {
<ResearchPlanDetailsName value={name}
disabled={research_plan.isMethodDisabled('name')}
onChange={this.handleNameChange.bind(this)}
edit={true}
ref={this.nameRef} />
edit={true} />
<ResearchPlanDetailsBody body={body}
disabled={research_plan.isMethodDisabled('body')}
......@@ -274,8 +255,7 @@ export default class ResearchPlanDetails extends Component {
onDelete={this.handleBodyDelete.bind(this)}
onExport={this.handleExportField.bind(this)}
update={update}
edit={true}
ref={this.bodyRef} />
edit={true} />
</ListGroupItem>
</ListGroup>
)
......
%h1= @name
- @fields.each do |field|
- case field[:type]
- when 'richtext'
%div= field[:text].html_safe
- when 'table'
%div
%table{'border' => 1}
%thead
%tr
- field[:columns].each do |column|
%th= column['name']
%tbody
- field[:rows].each do |row|
%tr
- field[:columns].each do |column|
%td= row[column['key']]
- when 'ketcher'
%div
%img{"src" => field[:src]}
- when 'image'
%div
%img{"src" => field[:src]}
- when 'sample'
%div
%img{"src" => field[:src]}
%p= field[:p]
- when 'reaction'
%div
%img{"src" => field[:src]}
%p= field[:p]
......@@ -3,22 +3,78 @@ require 'tempfile'
module Export
class ExportResearchPlan
def initialize(html, export_format)
# make src in html relative
@html = html
@html.gsub! 'src="/images/', 'src="images/'
def initialize(current_user, research_plan, export_format)
@current_user = current_user
@name = research_plan.name
@fields = []
@export_format = export_format
research_plan.body.each do |field|
case field['type']
when 'richtext'
@fields << {
:type => field['type'],
:text => Chemotion::QuillToHtml.new.convert(field['value'])
}
when 'table'
@fields << {
:type => field['type'],
:columns => field['value']['columns'],
:rows => field['value']['rows']
}
when 'ketcher'
@fields << {
:type => field['type'],
:src => "/images/research_plans/#{field['value']['svg_file']}"
}
when 'image'
@fields << {
:type => field['type'],
:src => "/images/research_plans/#{field['value']['public_name']}"
}
when 'sample'
sample = Sample.find(field['value']['sample_id'])
if ElementPolicy.new(@current_user, sample).read?
@fields << {
:type => field['type'],
:src => "/images/samples/#{sample['sample_svg_file']}",
:p => sample['name']
}
end
when 'reaction'
reaction = Reaction.find(field['value']['reaction_id'])
if ElementPolicy.new(@current_user, reaction).read?
@fields << {
:type => field['type'],
:src => "/images/reactions/#{reaction['reaction_svg_file']}",
:p => reaction['name']
}
end
end
end
end
def to_html()
view = ActionView::Base.new(ActionController::Base.view_paths, {})
view.assign(name: @name, fields: @fields)
view.render(file: 'export/research_plan')
end
def to_relative_html()
# make src in html relative
to_html.gsub "src='/images/", "src='images/"
end
def to_file
PandocRuby.convert(@html, :from => :html, :to => @export_format, :resource_path => Rails.public_path)
PandocRuby.convert(to_relative_html, :from => :html, :to => @export_format, :resource_path => Rails.public_path)
end
def to_zip
Dir.mktmpdir('chemotion') do |tmpdir|
# convert the html string using pandoc and save the images in tmpdir
document = PandocRuby.convert(@html, :from => :html, :to => @export_format, :resource_path => Rails.public_path, :extract_media => tmpdir)
document = PandocRuby.convert(to_relative_html, :from => :html, :to => @export_format, :resource_path => Rails.public_path, :extract_media => tmpdir)
# substitute tmp dir with images in the document
document.gsub! tmpdir, 'images'
......
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