Add 'download results as CSV'
This commit is contained in:
parent
d1a58e83a2
commit
1601f4f269
|
@ -100,43 +100,50 @@ const QueryResultComponent = Ember.Component.extend({
|
|||
});
|
||||
}.property('content', 'columns.@each'),
|
||||
|
||||
downloadResult(format) {
|
||||
// Create a frame to submit the form in (?)
|
||||
// to avoid leaving an about:blank behind
|
||||
let windowName = randomIdShort();
|
||||
const newWindowContents = "<body>Click anywhere to close this window once the download finishes.<script>window.onclick=function(){window.close()};</script>";
|
||||
|
||||
let newWindow = window.open('data:text/html;base64,' + btoa(newWindowContents), windowName);
|
||||
|
||||
let form = document.createElement("form");
|
||||
form.setAttribute('id', 'query-download-result');
|
||||
form.setAttribute('method', 'post');
|
||||
form.setAttribute('action', Discourse.getURL('/admin/plugins/explorer/queries/' + this.get('query.id') + '/run.' + format + '?download=1'));
|
||||
form.setAttribute('target', windowName);
|
||||
form.setAttribute('style', 'display:none;');
|
||||
|
||||
function addInput(form, name, value) {
|
||||
let field;
|
||||
field = document.createElement('input');
|
||||
field.setAttribute('name', name);
|
||||
field.setAttribute('value', value);
|
||||
form.appendChild(field);
|
||||
}
|
||||
|
||||
addInput(form, 'params', JSON.stringify(this.get('params')));
|
||||
addInput(form, 'explain', this.get('hasExplain'));
|
||||
addInput(form, 'limit', '1000000');
|
||||
|
||||
Discourse.ajax('/session/csrf.json').then(function(csrf) {
|
||||
addInput(form, 'authenticity_token', csrf.csrf);
|
||||
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
Em.run.next('afterRender', function() {
|
||||
document.body.removeChild(form);
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
downloadResult() {
|
||||
// Create a frame to submit the form in (?)
|
||||
// to avoid leaving an about:blank behind
|
||||
let windowName = randomIdShort();
|
||||
const newWindowContents = "<body>Click anywhere to close this window once the download finishes.<script>window.onclick=function(){window.close()};</script>";
|
||||
|
||||
let newWindow = window.open('data:text/html;base64,' + btoa(newWindowContents), windowName);
|
||||
|
||||
let form = document.createElement("form");
|
||||
form.setAttribute('id', 'query-download-result');
|
||||
form.setAttribute('method', 'post');
|
||||
form.setAttribute('action', Discourse.getURL('/admin/plugins/explorer/queries/' + this.get('query.id') + '/run.json?download=1'));
|
||||
form.setAttribute('target', windowName);
|
||||
form.setAttribute('style', 'display:none;');
|
||||
|
||||
function addInput(form, name, value) {
|
||||
let field;
|
||||
field = document.createElement('input');
|
||||
field.setAttribute('name', name);
|
||||
field.setAttribute('value', value);
|
||||
form.appendChild(field);
|
||||
}
|
||||
|
||||
addInput(form, 'params', JSON.stringify(this.get('params')));
|
||||
addInput(form, 'explain', this.get('hasExplain'));
|
||||
addInput(form, 'limit', '1000000');
|
||||
|
||||
Discourse.ajax('/session/csrf.json').then(function(csrf) {
|
||||
addInput(form, 'authenticity_token', csrf.csrf);
|
||||
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
Em.run.next('afterRender', function() {
|
||||
document.body.removeChild(form);
|
||||
})
|
||||
});
|
||||
downloadResultJson() {
|
||||
this.downloadResult('json');
|
||||
},
|
||||
downloadResultCsv() {
|
||||
this.downloadResult('csv');
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<div class="result-info">
|
||||
{{d-button action="downloadResult" icon="download" label="explorer.download_json"}}
|
||||
{{i18n "explorer.download"}}
|
||||
{{d-button action="downloadResultJson" icon="download" label="explorer.download_json"}}
|
||||
{{d-button action="downloadResultCsv" icon="download" label="explorer.download_csv"}}
|
||||
<div class="result-about">
|
||||
{{duration}}
|
||||
</div>
|
||||
|
|
|
@ -46,13 +46,15 @@ en:
|
|||
edit: "Edit"
|
||||
delete: "Delete"
|
||||
recover: "Undelete Query"
|
||||
download_json: "Download Results"
|
||||
download: "Download Results"
|
||||
download_json: "JSON"
|
||||
download_csv: "CSV"
|
||||
others_dirty: "A query has unsaved changes that will be lost if you navigate away."
|
||||
run_time: "Query completed in {{value}} ms."
|
||||
column: "Column {{number}}"
|
||||
explain_label: "Include query plan?"
|
||||
save_params: "Set Defaults"
|
||||
reset_params: "Reset"
|
||||
https_warning: "Use of the Data Explorer on sites not protected by HTTPS is discouraged. Please be careful to not retrieve sensitive information over insecure links."
|
||||
https_warning: "This site is not protected by HTTPS. Please be careful to not retrieve sensitive information over insecure links."
|
||||
no_queries: "There are no queries. Why not "
|
||||
no_queries_hook: "create one?"
|
||||
|
|
54
plugin.rb
54
plugin.rb
|
@ -917,8 +917,6 @@ SQL
|
|||
check_xhr unless params[:download]
|
||||
query = DataExplorer::Query.find(params[:id].to_i)
|
||||
if params[:download]
|
||||
response.headers['Content-Disposition'] =
|
||||
"attachment; filename=#{query.slug}@#{Slug.for(Discourse.current_hostname, 'discourse')}-#{Date.today}.dcqresult.json"
|
||||
response.sending_file = true
|
||||
end
|
||||
|
||||
|
@ -952,23 +950,45 @@ SQL
|
|||
else
|
||||
pg_result = result[:pg_result]
|
||||
cols = pg_result.fields
|
||||
json = {
|
||||
success: true,
|
||||
errors: [],
|
||||
duration: (result[:duration_secs].to_f * 1000).round(1),
|
||||
params: query_params,
|
||||
columns: cols,
|
||||
}
|
||||
json[:explain] = result[:explain] if opts[:explain]
|
||||
# TODO - special serialization
|
||||
# This is dead code in the client right now
|
||||
# if cols.any? { |col_name| special_serialization? col_name }
|
||||
# json[:relations] = DataExplorer.add_extra_data(pg_result)
|
||||
# end
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
if params[:download]
|
||||
response.headers['Content-Disposition'] =
|
||||
"attachment; filename=#{query.slug}@#{Slug.for(Discourse.current_hostname, 'discourse')}-#{Date.today}.dcqresult.json"
|
||||
end
|
||||
json = {
|
||||
success: true,
|
||||
errors: [],
|
||||
duration: (result[:duration_secs].to_f * 1000).round(1),
|
||||
params: query_params,
|
||||
columns: cols,
|
||||
}
|
||||
json[:explain] = result[:explain] if opts[:explain]
|
||||
# TODO - special serialization
|
||||
# This is dead code in the client right now
|
||||
# if cols.any? { |col_name| special_serialization? col_name }
|
||||
# json[:relations] = DataExplorer.add_extra_data(pg_result)
|
||||
# end
|
||||
|
||||
json[:rows] = pg_result.values
|
||||
json[:rows] = pg_result.values
|
||||
|
||||
render json: json
|
||||
render json: json
|
||||
end
|
||||
format.csv do
|
||||
response.headers['Content-Disposition'] =
|
||||
"attachment; filename=#{query.slug}@#{Slug.for(Discourse.current_hostname, 'discourse')}-#{Date.today}.dcqresult.csv"
|
||||
|
||||
require 'csv'
|
||||
text = CSV.generate do |csv|
|
||||
csv << cols
|
||||
pg_result.values.each do |row|
|
||||
csv << row
|
||||
end
|
||||
end
|
||||
|
||||
render text: text
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue