From bc3b1b477e796f0799c604f09a884b6fad61d21f Mon Sep 17 00:00:00 2001 From: Alex Turchyn Date: Sun, 20 Aug 2023 15:18:15 +0300 Subject: [PATCH] add export button --- Gemfile | 1 + Gemfile.lock | 5 + .../submissions_export_controller.rb | 28 ++++ app/javascript/application.js | 21 +++ app/javascript/elements/turbo_modal.js | 6 +- app/views/shared/_clipboard_copy.html.erb | 10 ++ app/views/shared/_turbo_modal.html.erb | 2 +- app/views/submissions_export/new.html.erb | 32 ++++ app/views/templates/show.html.erb | 18 ++- config/initializers/csv.rb | 3 + config/routes.rb | 1 + lib/submissions/generate_export_files.rb | 137 ++++++++++++++++++ 12 files changed, 256 insertions(+), 8 deletions(-) create mode 100644 app/controllers/submissions_export_controller.rb create mode 100644 app/views/submissions_export/new.html.erb create mode 100644 config/initializers/csv.rb create mode 100644 lib/submissions/generate_export_files.rb diff --git a/Gemfile b/Gemfile index 9e47f8f3..2acbdb86 100644 --- a/Gemfile +++ b/Gemfile @@ -28,6 +28,7 @@ gem 'rails_autolink' gem 'rails-i18n' gem 'rollbar', require: ENV.key?('ROLLBAR_ACCESS_TOKEN') gem 'ruby-vips' +gem 'rubyXL' gem 'shakapacker' gem 'sidekiq', require: ENV.key?('REDIS_URL') gem 'sqlite3', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 66557037..fa4781da 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -458,6 +458,10 @@ GEM ruby-vips (2.1.4) ffi (~> 1.12) ruby2_keywords (0.0.5) + rubyXL (3.4.25) + nokogiri (>= 1.10.8) + rubyzip (>= 1.3.0) + rubyzip (2.3.2) semantic_range (3.0.0) shakapacker (7.0.0) activesupport (>= 5.2) @@ -566,6 +570,7 @@ DEPENDENCIES rubocop-rails rubocop-rspec ruby-vips + rubyXL shakapacker sidekiq simplecov diff --git a/app/controllers/submissions_export_controller.rb b/app/controllers/submissions_export_controller.rb new file mode 100644 index 00000000..33045b1d --- /dev/null +++ b/app/controllers/submissions_export_controller.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +class SubmissionsExportController < ApplicationController + before_action :load_template + + def index + submissions = @template.submissions.active + .preload(submitters: { documents_attachments: :blob, + attachments_attachments: :blob }) + .order(id: :asc) + + if params[:format] == 'csv' + send_data Submissions::GenerateExportFiles.call(submissions, format: params[:format]), + filename: "#{@template.name}.csv" + elsif params[:format] == 'xlsx' + send_data Submissions::GenerateExportFiles.call(submissions, format: params[:format]), + filename: "#{@template.name}.xlsx" + end + end + + def new; end + + private + + def load_template + @template = current_account.templates.find(params[:template_id]) + end +end diff --git a/app/javascript/application.js b/app/javascript/application.js index 70d8578c..496bbbf4 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -45,6 +45,27 @@ window.customElements.define('set-timezone', SetTimezone) window.customElements.define('autoresize-textarea', AutoresizeTextarea) document.addEventListener('turbo:before-fetch-request', encodeMethodIntoRequestBody) +document.addEventListener('turbo:submit-end', async (event) => { + const resp = event.detail?.formSubmission?.result?.fetchResponse?.response + + if (!resp?.headers?.get('content-disposition')?.includes('attachment')) { + return + } + + const url = URL.createObjectURL(await resp.blob()) + const link = document.createElement('a') + + link.href = url + link.setAttribute('download', decodeURIComponent(resp.headers.get('content-disposition').split('"')[1])) + + document.body.appendChild(link) + + link.click() + + document.body.removeChild(link) + + URL.revokeObjectURL(url) +}) window.customElements.define('template-builder', class extends HTMLElement { connectedCallback () { diff --git a/app/javascript/elements/turbo_modal.js b/app/javascript/elements/turbo_modal.js index 810a69fc..5009f60b 100644 --- a/app/javascript/elements/turbo_modal.js +++ b/app/javascript/elements/turbo_modal.js @@ -5,8 +5,12 @@ export default actionable(class extends HTMLElement { document.body.classList.add('overflow-hidden') document.addEventListener('keyup', this.onEscKey) - document.addEventListener('turbo:submit-end', this.onSubmit) + document.addEventListener('turbo:before-cache', this.close) + + if (this.dataset.closeAfterSubmit !== 'false') { + document.addEventListener('turbo:submit-end', this.onSubmit) + } } disconnectedCallback () { diff --git a/app/views/shared/_clipboard_copy.html.erb b/app/views/shared/_clipboard_copy.html.erb index c4579794..1c9fdc25 100644 --- a/app/views/shared/_clipboard_copy.html.erb +++ b/app/views/shared/_clipboard_copy.html.erb @@ -6,12 +6,22 @@ + <% if local_assigns[:copy_title_md] %> + + <%= local_assigns[:copy_title_md] %> + + <% end %> diff --git a/app/views/shared/_turbo_modal.html.erb b/app/views/shared/_turbo_modal.html.erb index c4fee1b4..33af1175 100644 --- a/app/views/shared/_turbo_modal.html.erb +++ b/app/views/shared/_turbo_modal.html.erb @@ -1,5 +1,5 @@ - +