mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-02-26 08:44:31 +08:00
Add flash message and notification for generated reports [SCI-5552]
This commit is contained in:
parent
6695c00d4f
commit
0a9a656313
24 changed files with 117 additions and 58 deletions
|
@ -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();
|
||||
}());
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: "<a href='#{report_path}'>#{sanitize_input(report.name)}</a>",
|
||||
team_name: sanitize_input(report.team.name))
|
||||
)
|
||||
notification.create_user_notification(user)
|
||||
ensure
|
||||
file.close
|
||||
file.unlink
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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?
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
</button>
|
||||
<ul id="reportMenuDropdown" class="dropdown-menu report-actions-menu" aria-labelledby="reportMenu">
|
||||
<li>
|
||||
<%= link_to '#', remote: true, id: 'updatePdf' do %>
|
||||
<%= link_to '#', remote: true, id: 'updatePdf', class: 'generate-pdf' do %>
|
||||
<i class="fas fa-file-pdf"></i>
|
||||
<%= t("projects.reports.index.update_pdf") %>
|
||||
<% end %>
|
||||
|
@ -24,13 +24,13 @@
|
|||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to '#', remote: true, id: 'requestDocx' do %>
|
||||
<%= link_to '#', remote: true, id: 'requestDocx', class: 'generate-docx' do %>
|
||||
<i class="fas fa-file-word"></i>
|
||||
<%= t("projects.reports.index.request_docx") %>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to '#', remote: true, id: 'updateDocx' do %>
|
||||
<%= link_to '#', remote: true, id: 'updateDocx', class: 'generate-docx' do %>
|
||||
<i class="fas fa-file-word"></i>
|
||||
<%= t("projects.reports.index.update_docx") %>
|
||||
<% end %>
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
<li><%= link_to t("projects.reports.new.nav_pdf"), generate_project_report_path(@project, @report, format: :pdf), id: "get-report-pdf" %></li>
|
||||
<li><%= link_to t("projects.reports.new.nav_docx"), generate_project_report_path(@project, @report, format: :json), id: "get-report-docx" %></li>
|
||||
<li><%= link_to t("projects.reports.new.nav_pdf"), generate_pdf_project_report_path(@project, @report), id: "get-report-pdf" %></li>
|
||||
<li><%= link_to t("projects.reports.new.nav_docx"), generate_docx_project_report_path(@project, @report), id: "get-report-docx" %></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -512,6 +512,10 @@ en:
|
|||
error: "Error"
|
||||
generating: "Generating"
|
||||
generate: "Generate"
|
||||
generation:
|
||||
accepted_message: "Your report is succesfully added to the generator queue. We will notify you when it is done!"
|
||||
completed_notification_title: "Your report .DOCX was generated successfully."
|
||||
completed_notification_message: "Report: %{report_link} | Team: %{team_name}"
|
||||
modal_delete:
|
||||
head_title: "Delete report/s"
|
||||
message: "Are you sure to delete selected report/s?"
|
||||
|
|
|
@ -250,7 +250,8 @@ Rails.application.routes.draw do
|
|||
path: '/reports',
|
||||
only: %i(edit update create) do
|
||||
member do
|
||||
post 'generate', to: 'reports#generate', format: %w(pdf json)
|
||||
post 'generate_pdf', to: 'reports#generate_pdf'
|
||||
post 'generate_docx', to: 'reports#generate_docx'
|
||||
get 'status', to: 'reports#status', format: %w(json)
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue