From 0a9a6563131c476811c577207961e7e113fe58aa Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Wed, 14 Apr 2021 15:45:51 +0200 Subject: [PATCH] Add flash message and notification for generated reports [SCI-5552] --- .../javascripts/reports/reports_datatable.js | 38 ++++++++++++++++++- .../shared_styles/constants/colors.scss | 2 + .../stylesheets/themes/main_navigation.scss | 4 +- app/controllers/reports_controller.rb | 36 ++++++++++-------- app/datatables/report_datatable.rb | 4 +- app/jobs/reports/docx_job.rb | 15 +++++++- app/services/reports/docx.rb | 8 ++-- app/services/reports/docx/draw_experiment.rb | 6 +-- app/services/reports/docx/draw_my_module.rb | 6 +-- .../reports/docx/draw_my_module_activity.rb | 2 +- .../reports/docx/draw_my_module_repository.rb | 3 +- .../reports/docx/draw_project_header.rb | 2 +- .../reports/docx/draw_result_asset.rb | 6 +-- .../reports/docx/draw_result_comments.rb | 2 +- .../reports/docx/draw_result_table.rb | 6 +-- app/services/reports/docx/draw_result_text.rb | 6 +-- app/services/reports/docx/draw_step.rb | 6 +-- app/services/reports/docx/draw_step_asset.rb | 2 +- .../reports/docx/draw_step_checklist.rb | 2 +- app/services/reports/docx/draw_step_table.rb | 2 +- app/views/reports/_index_toolbar.html.erb | 6 +-- .../reports/new/_report_navigation.html.erb | 4 +- config/locales/en.yml | 4 ++ config/routes.rb | 3 +- 24 files changed, 117 insertions(+), 58 deletions(-) diff --git a/app/assets/javascripts/reports/reports_datatable.js b/app/assets/javascripts/reports/reports_datatable.js index 0f11cf5a8..2aee35cf1 100644 --- a/app/assets/javascripts/reports/reports_datatable.js +++ b/app/assets/javascripts/reports/reports_datatable.js @@ -1,4 +1,4 @@ -/* global I18n DataTableHelpers animateSpinner */ +/* global I18n DataTableHelpers animateSpinner HelperModule */ (function() { 'use strict'; @@ -113,6 +113,8 @@ $(row).addClass('report-row') .attr('data-edit-path', data.edit) .attr('data-status-path', data.status) + .attr('data-generate-pdf-path', data.generate_pdf) + .attr('data-generate-docx-path', data.generate_docx) .attr('data-retry-count', 0) .attr('data-id', data['0']); if (data['3'].processing || data['4'].processing) { @@ -244,6 +246,38 @@ }); } + function initGeneratePDFReport() { + $('.generate-pdf').click(function(ev) { + ev.stopPropagation(); + ev.preventDefault(); + animateSpinner(); + if (CHECKED_REPORTS.length === 1) { + let row = $(".report-row[data-id='" + CHECKED_REPORTS[0] + "']"); + $.post(row.data('generate-pdf-path'), function(response) { + animateSpinner(null, false); + HelperModule.flashAlertMsg(response.message, 'success'); + setTimeout(() => { checkProcessingStatus(row.data('id')); }, START_POLLING_INTERVAL); + }); + } + }); + } + + function initGenerateDocxReport() { + $('.generate-docx').click(function(ev) { + ev.stopPropagation(); + ev.preventDefault(); + animateSpinner(); + if (CHECKED_REPORTS.length === 1) { + let row = $(".report-row[data-id='" + CHECKED_REPORTS[0] + "']"); + $.post(row.data('generate-docx-path'), function(response) { + animateSpinner(null, false); + HelperModule.flashAlertMsg(response.message, 'success'); + setTimeout(() => { checkProcessingStatus(row.data('id')); }, START_POLLING_INTERVAL); + }); + } + }); + } + function initEditReport() { $('#edit-report-btn').click(function(e) { e.preventDefault(); @@ -271,6 +305,8 @@ } initDatatable(); + initGeneratePDFReport(); + initGenerateDocxReport(); initEditReport(); initDeleteReports(); }()); diff --git a/app/assets/stylesheets/shared_styles/constants/colors.scss b/app/assets/stylesheets/shared_styles/constants/colors.scss index 68bd15b3f..3a4012f98 100644 --- a/app/assets/stylesheets/shared_styles/constants/colors.scss +++ b/app/assets/stylesheets/shared_styles/constants/colors.scss @@ -17,6 +17,8 @@ $brand-primary-light: #7094cb; $brand-academy: #a52068; $brand-academy-dark: #8c1b58; +$brand-accent: #a52068; + $brand-focus: #609fff; $brand-focus-light: #dfecff; diff --git a/app/assets/stylesheets/themes/main_navigation.scss b/app/assets/stylesheets/themes/main_navigation.scss index 4c0843fe8..8025e0496 100644 --- a/app/assets/stylesheets/themes/main_navigation.scss +++ b/app/assets/stylesheets/themes/main_navigation.scss @@ -19,8 +19,8 @@ } #count-notifications { - background-color: $brand-primary; - border-radius: 5px; + background-color: $brand-accent; + border-radius: 8px; color: $color-concrete; display: none; font-size: 11px; diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 5aca5606e..347b153df 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -1,15 +1,13 @@ class ReportsController < ApplicationController include TeamsHelper include ReportActions - # Ignore CSRF protection just for PDF generation (because it's - # used via target='_blank') - protect_from_forgery with: :exception, except: :generate BEFORE_ACTION_METHODS = %i( create edit update - generate + generate_pdf + generate_docx save_modal project_contents experiment_contents_modal @@ -22,7 +20,7 @@ class ReportsController < ApplicationController result_contents ).freeze - before_action :load_vars, only: %i(edit update document_preview generate status) + before_action :load_vars, only: %i(edit update document_preview generate_pdf generate_docx status) before_action :load_vars_nested, only: BEFORE_ACTION_METHODS before_action :load_visible_projects, only: %i(new edit) before_action :load_available_repositories, @@ -188,21 +186,27 @@ class ReportsController < ApplicationController end end - # Generation action - def generate + # Generation actions + def generate_pdf respond_to do |format| - format.pdf do - render pdf: 'report', header: { html: { template: 'reports/header.pdf.erb' }}, - footer: { html: { template: 'reports/footer.pdf.erb', - locals: { current_time: I18n.l(Time.zone.now, format: :full) }}}, - locals: { content: content }, - template: 'reports/report.pdf.erb', - disable_javascript: true + format.json do + @report.update!(pdf_file_processing: true) + Reports::PdfJob.perform_later(@report, 'template_1', current_user) + render json: { + message: I18n.t('projects.reports.index.generation.accepted_message') + } end + end + end + + def generate_docx + respond_to do |format| format.json do @report.update!(docx_file_processing: true) - Reports::DocxJob.perform_now(@report, params[:data], current_user, current_team, root_url) - render json: {}, status: :accepted + Reports::DocxJob.perform_later(@report, current_user, current_team, root_url) + render json: { + message: I18n.t('projects.reports.index.generation.accepted_message') + } end end end diff --git a/app/datatables/report_datatable.rb b/app/datatables/report_datatable.rb index 1316658db..fb7c6bf96 100644 --- a/app/datatables/report_datatable.rb +++ b/app/datatables/report_datatable.rb @@ -61,7 +61,9 @@ class ReportDatatable < CustomDatatable '7' => I18n.l(record.created_at, format: :full), '8' => I18n.l(record.updated_at, format: :full), 'edit' => edit_project_report_path(record.project_id, record.id), - 'status' => status_project_report_path(record.project_id, record.id) + 'status' => status_project_report_path(record.project_id, record.id), + 'generate_pdf' => generate_pdf_project_report_path(record.project_id, record.id), + 'generate_docx' => generate_docx_project_report_path(record.project_id, record.id) } end end diff --git a/app/jobs/reports/docx_job.rb b/app/jobs/reports/docx_job.rb index cfa82f412..3be28c252 100644 --- a/app/jobs/reports/docx_job.rb +++ b/app/jobs/reports/docx_job.rb @@ -2,16 +2,27 @@ module Reports class DocxJob < ApplicationJob + include InputSanitizeHelper + queue_as :reports - def perform(report, data, user, team, root_url) + def perform(report, user, team, root_url) file = Tempfile.new(['report', '.docx']) begin docx = Caracal::Document.new(file.path) - Reports::Docx.new(data, docx, user: user, team: team, scinote_url: root_url).draw + Reports::Docx.new(report, docx, user: user, team: team, scinote_url: root_url).draw docx.save report.docx_file.attach(io: file, filename: 'report.docx') report.update!(docx_file_processing: false) + report_path = Rails.application.routes.url_helpers.reports_path + notification = Notification.create( + type_of: :deliver, + title: I18n.t('projects.reports.index.generation.completed_notification_title'), + message: I18n.t('projects.reports.index.generation.completed_notification_message', + report_link: "#{sanitize_input(report.name)}", + team_name: sanitize_input(report.team.name)) + ) + notification.create_user_notification(user) ensure file.close file.unlink diff --git a/app/services/reports/docx.rb b/app/services/reports/docx.rb index 75686b989..1ae20dadd 100644 --- a/app/services/reports/docx.rb +++ b/app/services/reports/docx.rb @@ -16,8 +16,8 @@ class Reports::Docx include "Reports::Docx::#{include_module}".constantize end - def initialize(json, docx, options) - @json = JSON.parse(json) + def initialize(report, docx, options) + @report = report @docx = docx @user = options[:user] @report_team = options[:team] @@ -29,8 +29,8 @@ class Reports::Docx def draw initial_document_load - @json.each do |subject| - public_send("draw_#{subject['type_of']}", subject) + @report.root_elements.each do |subject| + public_send("draw_#{subject.type_of}", subject) end @docx end diff --git a/app/services/reports/docx/draw_experiment.rb b/app/services/reports/docx/draw_experiment.rb index b1aa74350..af80f1339 100644 --- a/app/services/reports/docx/draw_experiment.rb +++ b/app/services/reports/docx/draw_experiment.rb @@ -5,7 +5,7 @@ module Reports::Docx::DrawExperiment color = @color link_style = @link_style scinote_url = @scinote_url - experiment = Experiment.find_by(id: subject['id']['experiment_id']) + experiment = Experiment.find_by(id: subject.experiment_id) return unless experiment && can_read_experiment?(@user, experiment) @docx.h2 experiment.name, size: Constants::REPORT_DOCX_EXPERIMENT_TITLE_SIZE @@ -25,8 +25,8 @@ module Reports::Docx::DrawExperiment Reports::HtmlToWordConverter.new(@docx, { scinote_url: scinote_url, link_style: link_style }).html_to_word_converter(html) @docx.p - subject['children'].each do |child| - public_send("draw_#{child['type_of']}", child, experiment) + subject.children.each do |child| + public_send("draw_#{child.type_of}", child, experiment) end end end diff --git a/app/services/reports/docx/draw_my_module.rb b/app/services/reports/docx/draw_my_module.rb index c18b2896b..eeab0831f 100644 --- a/app/services/reports/docx/draw_my_module.rb +++ b/app/services/reports/docx/draw_my_module.rb @@ -5,7 +5,7 @@ module Reports::Docx::DrawMyModule color = @color link_style = @link_style scinote_url = @scinote_url - my_module = experiment.my_modules.find_by(id: subject['id']['my_module_id']) + my_module = experiment.my_modules.find_by(id: subject.my_module_id) tags = my_module.tags return unless my_module @@ -73,8 +73,8 @@ module Reports::Docx::DrawMyModule end @docx.p - subject['children'].each do |child| - public_send("draw_#{child['type_of']}", child, my_module) + subject.children.each do |child| + public_send("draw_#{child.type_of}", child, my_module) end end end diff --git a/app/services/reports/docx/draw_my_module_activity.rb b/app/services/reports/docx/draw_my_module_activity.rb index 3ad27b6ef..75597e2ee 100644 --- a/app/services/reports/docx/draw_my_module_activity.rb +++ b/app/services/reports/docx/draw_my_module_activity.rb @@ -4,7 +4,7 @@ module Reports::Docx::DrawMyModuleActivity def draw_my_module_activity(subject, my_module) return unless my_module - activities = ActivitiesService.my_module_activities(my_module).order(created_at: subject['sort_order']) + activities = ActivitiesService.my_module_activities(my_module).order(created_at: subject.sort_order) return false unless activities.any? diff --git a/app/services/reports/docx/draw_my_module_repository.rb b/app/services/reports/docx/draw_my_module_repository.rb index b0ceebc8b..5d263d218 100644 --- a/app/services/reports/docx/draw_my_module_repository.rb +++ b/app/services/reports/docx/draw_my_module_repository.rb @@ -4,8 +4,7 @@ module Reports::Docx::DrawMyModuleRepository def draw_my_module_repository(subject, my_module) return unless my_module - repository_id = subject['id']['repository_id'] - repository = ::RepositoryBase.find(repository_id) + repository = ::RepositoryBase.find(subject.repository_id) repository_data = my_module.repository_docx_json(repository) return false unless repository_data[:rows].any? && can_read_repository?(@user, repository) diff --git a/app/services/reports/docx/draw_project_header.rb b/app/services/reports/docx/draw_project_header.rb index fbeb18489..af09d8d64 100644 --- a/app/services/reports/docx/draw_project_header.rb +++ b/app/services/reports/docx/draw_project_header.rb @@ -2,7 +2,7 @@ module Reports::Docx::DrawProjectHeader def draw_project_header(subject) - project = Project.find_by(id: subject['id']['project_id']) + project = Project.find_by(id: subject.project_id) return unless project && can_read_project?(@user, project) @docx.p I18n.t('projects.reports.elements.project_header.user_time', diff --git a/app/services/reports/docx/draw_result_asset.rb b/app/services/reports/docx/draw_result_asset.rb index 5edb70978..5b8f97308 100644 --- a/app/services/reports/docx/draw_result_asset.rb +++ b/app/services/reports/docx/draw_result_asset.rb @@ -2,7 +2,7 @@ module Reports::Docx::DrawResultAsset def draw_result_asset(subject, my_module) - result = my_module.results.find_by(id: subject['id']['result_id']) + result = my_module.results.find_by(id: subject.result_id) return unless result asset = result.asset @@ -24,8 +24,8 @@ module Reports::Docx::DrawResultAsset Reports::DocxRenderer.render_asset_image(@docx, asset) if asset.previewable? && !asset.list? - subject['children'].each do |child| - public_send("draw_#{child['type_of']}", child, result) + subject.children.each do |child| + public_send("draw_#{child.type_of}", child, result) end end end diff --git a/app/services/reports/docx/draw_result_comments.rb b/app/services/reports/docx/draw_result_comments.rb index 101290b24..03b065438 100644 --- a/app/services/reports/docx/draw_result_comments.rb +++ b/app/services/reports/docx/draw_result_comments.rb @@ -4,7 +4,7 @@ module Reports::Docx::DrawResultComments def draw_result_comments(subject, result) return unless result - comments = result.result_comments.order(created_at: subject['sort_order']) + comments = result.result_comments.order(created_at: subject.sort_order) return if comments.count.zero? @docx.p diff --git a/app/services/reports/docx/draw_result_table.rb b/app/services/reports/docx/draw_result_table.rb index be1fe229b..fa2c0ed12 100644 --- a/app/services/reports/docx/draw_result_table.rb +++ b/app/services/reports/docx/draw_result_table.rb @@ -2,7 +2,7 @@ module Reports::Docx::DrawResultTable def draw_result_table(subject, my_module) - result = my_module.results.find_by(id: subject['id']['result_id']) + result = my_module.results.find_by(id: subject.result_id) return unless result table = result.table @@ -19,8 +19,8 @@ module Reports::Docx::DrawResultTable timestamp: I18n.l(timestamp, format: :full), user: result.user.full_name), color: color[:gray] end @docx.table JSON.parse(table.contents_utf_8)['data'], border_size: Constants::REPORT_DOCX_TABLE_BORDER_SIZE - subject['children'].each do |child| - public_send("draw_#{child['type_of']}", child, result) + subject.children.each do |child| + public_send("draw_#{child.type_of}", child, result) end end end diff --git a/app/services/reports/docx/draw_result_text.rb b/app/services/reports/docx/draw_result_text.rb index 33abb9867..e28518c07 100644 --- a/app/services/reports/docx/draw_result_text.rb +++ b/app/services/reports/docx/draw_result_text.rb @@ -2,7 +2,7 @@ module Reports::Docx::DrawResultText def draw_result_text(subject, my_module) - result = my_module.results.find_by(id: subject['id']['result_id']) + result = my_module.results.find_by(id: subject.result_id) return unless result result_text = result.result_text @@ -20,8 +20,8 @@ module Reports::Docx::DrawResultText Reports::HtmlToWordConverter.new(@docx, { scinote_url: @scinote_url, link_style: @link_style }).html_to_word_converter(html) - subject['children'].each do |child| - public_send("draw_#{child['type_of']}", child, result) + subject.children.each do |child| + public_send("draw_#{child.type_of}", child, result) end end end diff --git a/app/services/reports/docx/draw_step.rb b/app/services/reports/docx/draw_step.rb index 1a212bd56..4d3db59ef 100644 --- a/app/services/reports/docx/draw_step.rb +++ b/app/services/reports/docx/draw_step.rb @@ -3,7 +3,7 @@ module Reports::Docx::DrawStep def draw_step(subject, my_module) color = @color - step = my_module.protocols.first.steps.find_by(id: subject['id']['step_id']) + step = my_module.protocols.first.steps.find_by(id: subject.step_id) return unless step step_type_str = step.completed ? 'completed' : 'uncompleted' @@ -33,8 +33,8 @@ module Reports::Docx::DrawStep @docx.p I18n.t 'projects.reports.elements.step.no_description' end - subject['children'].each do |child| - public_send("draw_#{child['type_of']}", child, step) + subject.children.each do |child| + public_send("draw_#{child.type_of}", child, step) end @docx.p @docx.p diff --git a/app/services/reports/docx/draw_step_asset.rb b/app/services/reports/docx/draw_step_asset.rb index 657148833..817066347 100644 --- a/app/services/reports/docx/draw_step_asset.rb +++ b/app/services/reports/docx/draw_step_asset.rb @@ -2,7 +2,7 @@ module Reports::Docx::DrawStepAsset def draw_step_asset(subject, step) - asset = step.assets.find_by(id: subject['id']['asset_id']) + asset = step.assets.find_by(id: subject.asset_id) return unless asset timestamp = asset.created_at diff --git a/app/services/reports/docx/draw_step_checklist.rb b/app/services/reports/docx/draw_step_checklist.rb index d1448732c..7a83e96ea 100644 --- a/app/services/reports/docx/draw_step_checklist.rb +++ b/app/services/reports/docx/draw_step_checklist.rb @@ -4,7 +4,7 @@ module Reports::Docx::DrawStepChecklist def draw_step_checklist(subject, step) team = @report_team user = @user - checklist = step.checklists.find_by(id: subject['id']['checklist_id']) + checklist = step.checklists.find_by(id: subject.checklist_id) return unless checklist items = checklist.checklist_items diff --git a/app/services/reports/docx/draw_step_table.rb b/app/services/reports/docx/draw_step_table.rb index 227537374..2313d44cf 100644 --- a/app/services/reports/docx/draw_step_table.rb +++ b/app/services/reports/docx/draw_step_table.rb @@ -2,7 +2,7 @@ module Reports::Docx::DrawStepTable def draw_step_table(subject, step) - table = step.tables.find_by(id: subject['id']['table_id']) + table = step.tables.find_by(id: subject.table_id) return unless table color = @color diff --git a/app/views/reports/_index_toolbar.html.erb b/app/views/reports/_index_toolbar.html.erb index d6db8f53d..ea6930b29 100644 --- a/app/views/reports/_index_toolbar.html.erb +++ b/app/views/reports/_index_toolbar.html.erb @@ -12,7 +12,7 @@