Skip to content

Commit

Permalink
Merge pull request #7795 from aignatov-bio/ai-sci-10967-prepare-custo…
Browse files Browse the repository at this point in the history
…m-docx-reports

Add basic support for custom templates docx [SCI-10967]
  • Loading branch information
aignatov-bio authored Aug 13, 2024
2 parents 3a6888b + 5841fbd commit 2f9bd1f
Show file tree
Hide file tree
Showing 25 changed files with 552 additions and 87 deletions.
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ gem 'aspector' # Aspect-oriented programming for Rails
gem 'auto_strip_attributes', '~> 2.1' # Removes unnecessary whitespaces AR
gem 'bcrypt', '~> 3.1.10'
# gem 'caracal'
gem 'caracal',
git: 'https://github.com/scinote-eln/caracal.git', branch: 'rubyzip2' # Build docx report
# gem 'caracal', git: 'https://github.com/scinote-eln/caracal.git', branch: 'rubyzip2' # Build docx report
gem 'caracal_the_curve', '~> 1.4', '>= 1.4.6'
gem 'caxlsx' # Build XLSX files
gem 'deface', '~> 1.9'
gem 'down', '~> 5.0'
Expand Down
18 changes: 6 additions & 12 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ GIT
docile (>= 1.1.0)
rails (>= 4)

GIT
remote: https://github.com/scinote-eln/caracal.git
revision: f8e4c279adfee7801eb1024e1d6a18bb06c9c76a
branch: rubyzip2
specs:
caracal (1.4.1)
nokogiri (~> 1.6)
rubyzip (>= 2.3)
tilt (>= 1.4)

GIT
remote: https://github.com/scinote-eln/img2zpl
revision: 23d61cfc3e90ac4caa62dd08546fa0d7590a5140
Expand Down Expand Up @@ -227,6 +217,10 @@ GEM
capybara-email (3.0.2)
capybara (>= 2.4, < 4.0)
mail
caracal_the_curve (1.4.6)
nokogiri (~> 1.6)
rubyzip (>= 1.1.0, < 3.0)
tilt (>= 1.4)
case_transform (0.2)
activesupport
caxlsx (4.0.0)
Expand Down Expand Up @@ -725,7 +719,7 @@ GEM
tailwindcss-rails (2.4.0-x86_64-linux)
railties (>= 6.0.0)
thor (1.3.1)
tilt (2.2.0)
tilt (2.4.0)
timecop (0.9.6)
timeout (0.4.1)
turbolinks (5.2.1)
Expand Down Expand Up @@ -805,7 +799,7 @@ DEPENDENCIES
canaid!
capybara
capybara-email
caracal!
caracal_the_curve (~> 1.4, >= 1.4.6)
caxlsx
cssbundling-rails
cucumber-rails
Expand Down
79 changes: 73 additions & 6 deletions app/assets/javascripts/reports/new.js
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,7 @@ function reportHandsonTableConverter() {

// Settings
reportData.report.settings.template = dropdownSelector.getValues('#templateSelector');
reportData.report.settings.docx_template = dropdownSelector.getValues('#docxTemplateSelector');
reportData.report.settings.all_tasks = $('.project-contents-container .select-all-my-modules-checkbox')
.prop('checked');
$.each($('.task-contents-container .content-element .protocol-setting'), function(i, e) {
Expand Down Expand Up @@ -1254,7 +1255,8 @@ function reportHandsonTableConverter() {

function reCheckContinueButton() {
if (dropdownSelector.getValues('#projectSelector').length > 0
&& dropdownSelector.getValues('#templateSelector').length > 0) {
&& dropdownSelector.getValues('#templateSelector').length > 0
&& dropdownSelector.getValues('#docxTemplateSelector').length > 0) {
$('.continue-button').attr('disabled', false);
} else {
$('.continue-button').attr('disabled', true);
Expand All @@ -1276,9 +1278,12 @@ function reportHandsonTableConverter() {
}
if (dropdownSelector.getValues('#projectSelector').length > 0) {
dropdownSelector.enableSelector('#templateSelector');
dropdownSelector.enableSelector('#docxTemplateSelector');
} else {
dropdownSelector.selectValues('#templateSelector', '');
dropdownSelector.disableSelector('#templateSelector');
dropdownSelector.selectValues('#docxTemplateSelector', '');
dropdownSelector.disableSelector('#docxTemplateSelector');
}
reCheckContinueButton();
}
Expand All @@ -1292,12 +1297,12 @@ function reportHandsonTableConverter() {
disableSearch: true,
onSelect: function() {
if (dropdownSelector.getValues('#templateSelector').length === 0) {
$('.report-template-values-container').html('').addClass('hidden');
$('.report-template-values-container.pdf').html('').addClass('hidden');
reCheckContinueButton();
return;
}

let filledFieldsCount = $('.report-template-values-container')
let filledFieldsCount = $('.report-template-values-container.pdf')
.find('input.sci-input-field, textarea.sci-input-field').filter(function() {
return !!this.value;
}).length;
Expand All @@ -1311,9 +1316,39 @@ function reportHandsonTableConverter() {
}
});

dropdownSelector.init('#docxTemplateSelector', {
singleSelect: true,
closeOnSelect: true,
noEmptyOption: true,
selectAppearance: 'simple',
disableSearch: true,
onSelect: function() {
if (dropdownSelector.getValues('#docxTemplateSelector').length === 0) {
$('.report-template-values-container.docx').html('').addClass('hidden');
reCheckContinueButton();
return;
}

let filledFieldsCount = $('.report-template-values-container.docx')
.find('input.sci-input-field, textarea.sci-input-field').filter(function() {
return !!this.value;
}).length;

if (filledFieldsCount === 0) {
loadDocxTemplate();
} else {
$('#templateReportWarningModal').modal('show');
}
reCheckContinueButton();
}
});

if (dropdownSelector.getValues('#templateSelector').length > 0) {
loadTemplate();
}
if (dropdownSelector.getValues('#docxTemplateSelector').length > 0) {
loadDocxTemplate();
}
}

function loadTemplate() {
Expand All @@ -1325,8 +1360,38 @@ function reportHandsonTableConverter() {

$('#templateSelector').data('selected-template', template);
$.get($('#templateSelector').data('valuesEditorPath'), params, function(result) {
$('.report-template-values-container').removeClass('hidden');
$('.report-template-values-container').html(result.html);
$('.report-template-values-container.pdf').removeClass('hidden');
$('.report-template-values-container.pdf').html(result.html);

$('.section').each(function() {
var section = $(this);
var collapseButton = section.find('.sn-icon-down');
var valuesContainer = section.find('.values-container');

if (valuesContainer.children().length === 0) {
collapseButton.hide();
}
});

$('.report-template-value-dropdown').each(function() {
dropdownSelector.init($(this), {
noEmptyOption: true
});
});
});
}

function loadDocxTemplate() {
let template = $('#docxTemplateSelector').val();
let params = {
project_id: dropdownSelector.getValues('#projectSelector'),
template: template
};

$('#docxTemplateSelector').data('selected-template', template);
$.get($('#docxTemplateSelector').data('valuesEditorPath'), params, function(result) {
$('.report-template-values-container.docx').removeClass('hidden');
$('.report-template-values-container.docx').html(result.html);

$('.section').each(function() {
var section = $(this);
Expand Down Expand Up @@ -1448,7 +1513,9 @@ function reportHandsonTableConverter() {
.on('hide.bs.modal', function() {
if (!$('#templateReportWarningModal').hasClass('skip-hide-event')) {
let previousTemplate = $('#templateSelector').data('selected-template');
let previousDocxTemplate = $('#docxTemplateSelector').data('selected-template');
dropdownSelector.selectValues('#templateSelector', previousTemplate);
dropdownSelector.selectValues('#docxTemplateSelector', previousDocxTemplate);
}
$('#templateReportWarningModal').removeClass('skip-hide-event');
});
Expand All @@ -1461,7 +1528,7 @@ function reportHandsonTableConverter() {

$('#reportWizardEditWarning').modal('show');
$('.experiment-contents').sortable();

initNameContainerFocus();
initGenerateButton();
initReportWizard();
Expand Down
11 changes: 11 additions & 0 deletions app/components/reports/repositories_input_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<% if @editing %>
<div class="sci-select-container">
<%= label_tag @name, @label %>
<%= select_tag @name, options_from_collection_for_select(@repositories, :id, :name, @value), placeholder: @placeholder, class: 'sci-input-field report-template-value-dropdown', data: { type: 'RepositoriesInputComponent' }, multiple: true %>
</div>
<% else %>
<% @project_members.where(id: @value).each do |member| %>
<%= member.public_send(@displayed_field) %>
<br>
<% end %>
<% end %>
18 changes: 18 additions & 0 deletions app/components/reports/repositories_input_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

module Reports
class RepositoriesInputComponent < TemplateValueComponent
def initialize(report:, name:, label:, placeholder: nil, editing: true, displayed_field: :name)
super(report: report, name: name, label: label, placeholder: placeholder, editing: editing)

live_repositories = Repository.accessible_by_teams(report.team).sort_by { |r| r.name.downcase }
snapshots_of_deleted = RepositorySnapshot.left_outer_joins(:original_repository)
.where(team: report.team)
.where.not(original_repository: live_repositories)
.select('DISTINCT ON ("repositories"."parent_id") "repositories".*')
.sort_by { |r| r.name.downcase }
@repositories = live_repositories + snapshots_of_deleted
@displayed_field = displayed_field
end
end
end
42 changes: 39 additions & 3 deletions app/controllers/reports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ class ReportsController < ApplicationController
before_action :load_vars, only: %i(edit update document_preview generate_pdf generate_docx status
save_pdf_to_inventory_modal save_pdf_to_inventory_item)
before_action :load_vars_nested, only: %i(create edit update generate_pdf
generate_docx new_template_values project_contents)
generate_docx new_template_values new_docx_template_values project_contents)
before_action :load_wizard_vars, only: %i(new edit)
before_action :load_available_repositories, only: %i(index save_pdf_to_inventory_modal available_repositories)
before_action :check_project_read_permissions, only: %i(create edit update generate_pdf
generate_docx new_template_values project_contents)
generate_docx new_template_values new_docx_template_values project_contents)
before_action :check_read_permissions, except: %i(index new create edit update destroy actions_toolbar generate_pdf
generate_docx new_template_values project_contents
generate_docx new_template_values project_contents new_docx_template_values
available_repositories)
before_action :check_create_permissions, only: %i(new create)
before_action :check_manage_permissions, only: %i(edit update generate_pdf generate_docx)
Expand All @@ -37,6 +37,7 @@ def index
# Report grouped by modules
def new
@templates = Extends::REPORT_TEMPLATES
@docx_templates = Extends::DOCX_REPORT_TEMPLATES
@report = current_team.reports.new
end

Expand Down Expand Up @@ -73,6 +74,39 @@ def new_template_values
end
end

def new_docx_template_values
if Extends::DOCX_REPORT_TEMPLATES.key?(params[:template]&.to_sym)
template = params[:template]
else
return render_404
end

report = current_team.reports.where(project: @project).find_by(id: params[:report_id])
if report.present?
return render_403 unless can_manage_report?(report)
else
return render_403 unless can_create_reports?(current_team)

report = current_team.reports.new(project: @project)
end

if lookup_context.any_templates?("reports/docx_templates/#{template}/edit")
render json: {
html: render_to_string(
template: "reports/docx_templates/#{template}/edit",
layout: 'reports/template_values_editor',
locals: { report: report },
formats: :html
)
}
else
render json: {
html: render_to_string(partial: 'reports/wizard/no_template_values',
formats: :html)
}
end
end

# Creating new report from the _save modal of the new page
def create
@report = Report.new(report_params)
Expand Down Expand Up @@ -102,6 +136,7 @@ def create
def edit
@edit = true
@active_template = @report.settings[:template]
@active_docx_template = @report.settings[:docx_template]
@report.settings = Report::DEFAULT_SETTINGS if @report.settings.blank?

@project_contents = {
Expand Down Expand Up @@ -312,6 +347,7 @@ def load_vars_nested

def load_wizard_vars
@templates = Extends::REPORT_TEMPLATES
@docx_templates = Extends::DOCX_REPORT_TEMPLATES
live_repositories = Repository.accessible_by_teams(current_team).sort_by { |r| r.name.downcase }
snapshots_of_deleted = RepositorySnapshot.left_outer_joins(:original_repository)
.where(team: current_team)
Expand Down
2 changes: 2 additions & 0 deletions app/jobs/reports/docx_job.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require 'caracal'

module Reports
class DocxJob < ApplicationJob
extend InputSanitizeHelper
Expand Down
18 changes: 15 additions & 3 deletions app/services/reports/docx.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

# rubocop:disable Style/ClassAndModuleChildren

Dir[Rails.root.join('app/views/reports/docx_templates/**/docx.rb')].each do |file|
require file
end

class Reports::Docx
include ActionView::Helpers::TextHelper
include ActionView::Helpers::UrlHelper
Expand All @@ -26,15 +30,23 @@ def initialize(report, docx, options)
@link_style = {}
@color = {}
@scinote_url = options[:scinote_url][0..-2]
@template = @settings[:docx_template] || 'scinote_template'

extend "#{@template.camelize}Docx".constantize
end

def draw
initial_document_load

@report.root_elements.each do |subject|
public_send("draw_#{subject.type_of}", subject)
end
prepare_docx

@docx
end

private

def get_template_value(name)
@report.report_template_values.find_by(name: name)&.value
end
end
# rubocop:enable Style/ClassAndModuleChildren
Loading

0 comments on commit 2f9bd1f

Please sign in to comment.