Fix project export [SCI-10527]

This commit is contained in:
Andrej 2024-04-02 17:26:03 +02:00
parent b15ca0b680
commit 4cf0c7ac00
5 changed files with 67 additions and 56 deletions

View file

@ -21,7 +21,7 @@ module ReportsHelper
children_html = ''.html_safe
# First, recursively render element's children
if element.children.active.present?
element.children.active.each do |child|
element.children.active.find_each do |child|
children_html.safe_concat render_report_element(child, provided_locals)
end
end

View file

@ -4,6 +4,7 @@ require 'fileutils'
require 'csv'
require 'vips'
# rubocop:disable Metrics/BlockLength
class TeamZipExportJob < ZipExportJob
include StringUtility
@ -51,13 +52,13 @@ class TeamZipExportJob < ZipExportJob
# Include all experiments
ex_idx = ex_archive_idx = 0
project.experiments.each do |experiment|
project.experiments.find_each do |experiment|
idx = experiment.archived ? (ex_archive_idx += 1) : (ex_idx += 1)
experiment_path = make_model_dir(project_path, experiment, idx)
# Include all modules
mod_pos = mod_archive_pos = 0
experiment.my_modules.order(:workflow_order).each do |my_module|
experiment.my_modules.order(:workflow_order).find_each do |my_module|
pos = my_module.archived ? (mod_archive_pos += 1) : (mod_pos += 1)
my_module_path = make_model_dir(experiment_path, my_module, pos)
@ -153,19 +154,21 @@ class TeamZipExportJob < ZipExportJob
directory = create_archived_results_folder(directory) if archived && elements.present?
asset_indexes = {}
elements.each_with_index do |element, i|
index = 1
elements.find_each do |element|
asset = element.asset
preview = prepare_preview(asset)
if type == :step
name = "#{directory}/" \
"#{append_file_suffix(asset.file_name, "_#{i}_Step#{element.step.position_plus_one}")}"
"#{append_file_suffix(asset.file_name, "_#{index}_Step#{element.step.position_plus_one}")}"
if preview
preview_name = "#{directory}/" \
"#{append_file_suffix(preview[:file_name], "_#{i}_Step#{element.step.position_plus_one}_preview")}"
"#{append_file_suffix(preview[:file_name],
"_#{index}_Step#{element.step.position_plus_one}_preview")}"
end
elsif type == :result
name = "#{directory}/#{append_file_suffix(asset.file_name, "_#{i}")}"
preview_name = "#{directory}/#{append_file_suffix(preview[:file_name], "_#{i}_preview")}" if preview
name = "#{directory}/#{append_file_suffix(asset.file_name, "_#{index}")}"
preview_name = "#{directory}/#{append_file_suffix(preview[:file_name], "_#{index}_preview")}" if preview
end
if asset.file.attached?
@ -180,6 +183,7 @@ class TeamZipExportJob < ZipExportJob
file: name,
preview: preview_name
}
index += 1
end
asset_indexes
end
@ -218,14 +222,15 @@ class TeamZipExportJob < ZipExportJob
directory = create_archived_results_folder(directory) if archived && elements.present?
table_indexes = {}
elements.each_with_index do |element, i|
index = 0
elements.find_each do |element|
table = element.table
table_name = table.name.presence || 'Table'
table_name += i.to_s
table_name += index.to_s
if type == :step
name = "#{directory}/#{to_filesystem_name(table_name)}" \
"_#{i}_Step#{element.step.position_plus_one}.csv"
"_#{index}_Step#{element.step.position_plus_one}.csv"
elsif type == :result
name = "#{directory}/#{to_filesystem_name(table_name)}.csv"
end
@ -233,6 +238,7 @@ class TeamZipExportJob < ZipExportJob
table_indexes[table.id] = {
file: name
}
index += 1
end
table_indexes
@ -253,7 +259,7 @@ class TeamZipExportJob < ZipExportJob
# Define headers and columns IDs
col_ids = [-3, -4, -5, -6]
col_ids << -9 if Repository.repository_row_connections_enabled?
col_ids += repo.repository_columns.map(&:id)
col_ids += repo.repository_columns.pluck(:id)
# Define callback function for file name
assets = {}
@ -290,3 +296,4 @@ class TeamZipExportJob < ZipExportJob
item: I18n.t('activejob.failure_notifiable_job.items.project'))
end
end
# rubocop:enable Metrics/BlockLength

View file

@ -9,13 +9,11 @@ class ZipExportJob < ApplicationJob
zip_input_dir = FileUtils.mkdir_p(Rails.root.join("tmp/temp_zip_#{Time.now.to_i}").to_s).first
zip_dir = FileUtils.mkdir_p(Rails.root.join('tmp/zip-ready').to_s).first
full_zip_name = File.join(zip_dir, zip_name)
ZipExport.transaction do
@zip_export = ZipExport.create!(user: @user)
fill_content(zip_input_dir, params)
@zip_export.zip!(zip_input_dir, full_zip_name)
@zip_export.zip_file.attach(io: File.open(full_zip_name), filename: zip_name)
generate_notification!
end
@zip_export = ZipExport.create!(user: @user)
fill_content(zip_input_dir, params)
@zip_export.zip!(zip_input_dir, full_zip_name)
@zip_export.zip_file.attach(io: File.open(full_zip_name), filename: zip_name)
generate_notification!
rescue Errno::ENOENT => e
Rails.logger.error(e.message)
ensure

View file

@ -252,6 +252,7 @@ class Project < ApplicationRecord
project_comments
end
# rubocop:disable Metrics/BlockLength
def generate_teams_export_report_html(
user, team, html_title, obj_filenames = nil
)
@ -260,50 +261,54 @@ class Project < ApplicationRecord
proxy.set_user(user, scope: :user, store: false)
ApplicationController.renderer.defaults[:http_host] = Rails.application.routes.default_url_options[:host]
renderer = ApplicationController.renderer.new(warden: proxy)
report = nil
parsed_html = ''
report = Report.generate_whole_project_report(self, user, team)
Report.transaction do
report = Report.generate_whole_project_report(self, user, team)
page_html_string =
renderer.render 'reports/export',
locals: { report: report, export_all: true },
assigns: { settings: report.settings, obj_filenames: obj_filenames }
parsed_page_html = Nokogiri::HTML(page_html_string)
parsed_html = parsed_page_html.at_css('#report-content')
page_html_string =
renderer.render 'reports/export',
locals: { report: report, export_all: true },
assigns: { settings: report.settings, obj_filenames: obj_filenames }
parsed_page_html = Nokogiri::HTML(page_html_string)
parsed_html = parsed_page_html.at_css('#report-content')
# Style tables (mimick frontend processing)
# Style tables (mimick frontend processing)
tables = parsed_html.css('.hot-table-contents')
.zip(parsed_html.css('.hot-table-container'), parsed_html.css('.hot-table-metadata'))
tables.each do |table_input, table_container, metadata|
is_plate_template = JSON.parse(metadata['value'])['plateTemplate'] if metadata && metadata['value'].present?
table_vals = JSON.parse(table_input['value'])
table_data = table_vals['data']
table_headers = table_vals['headers']
table_headers ||= Array.new(table_data[0].count) do |index|
is_plate_template ? index + 1 : convert_index_to_letter(index)
end
tables = parsed_html.css('.hot-table-contents')
.zip(parsed_html.css('.hot-table-container'), parsed_html.css('.hot-table-metadata'))
tables.each do |table_input, table_container, metadata|
is_plate_template = JSON.parse(metadata['value'])['plateTemplate'] if metadata && metadata['value'].present?
table_vals = JSON.parse(table_input['value'])
table_data = table_vals['data']
table_headers = table_vals['headers']
table_headers ||= Array.new(table_data[0].count) do |index|
is_plate_template ? index + 1 : convert_index_to_letter(index)
end
table_el = table_container.add_child('<table class="handsontable"></table>').first
table_el = table_container.add_child('<table class="handsontable"></table>').first
# Add header row
header_cell = '<th><div class="relative"><span>%s</span></div></th>'
# Add header row
header_cell = '<th><div class="relative"><span>%s</span></div></th>'
header_el = table_el.add_child('<thead></thead>').first
row_el = header_el.add_child('<tr></tr>').first
row_el.add_child(format(header_cell, '')).first
table_headers.each do |col|
row_el.add_child(format(header_cell, col)).first
end
header_el = table_el.add_child('<thead></thead>').first
row_el = header_el.add_child('<tr></tr>').first
row_el.add_child(format(header_cell, '')).first
table_headers.each do |col|
row_el.add_child(format(header_cell, col)).first
end
# Add body rows
body_cell = '<td>%s</td>'
body_el = table_el.add_child('<tbody></tbody>').first
table_data.each.with_index(1) do |row, idx|
row_name = is_plate_template ? convert_index_to_letter(idx - 1) : idx
row_el = body_el.add_child('<tr></tr>').first
row_el.add_child(format(header_cell, row_name)).first
row.each do |col|
row_el.add_child(format(body_cell, col)).first
# Add body rows
body_cell = '<td>%s</td>'
body_el = table_el.add_child('<tbody></tbody>').first
table_data.each.with_index(1) do |row, idx|
row_name = is_plate_template ? convert_index_to_letter(idx - 1) : idx
row_el = body_el.add_child('<tr></tr>').first
row_el.add_child(format(header_cell, row_name)).first
row.each do |col|
row_el.add_child(format(body_cell, col)).first
end
end
end
end
@ -321,6 +326,7 @@ class Project < ApplicationRecord
ensure
report.destroy if report.present?
end
# rubocop:enable Metrics/BlockLength
def archived_branch?
archived?

View file

@ -116,7 +116,7 @@ class Report < ApplicationRecord
'experiments' => [],
'repositories' => project.assigned_repositories_and_snapshots.pluck(:id)
}
project.experiments.includes(:my_modules).each do |experiment|
project.experiments.includes(:my_modules).find_each do |experiment|
content['experiments'].push(
{ id: experiment.id, my_module_ids: experiment.my_module_ids }
)