Update reports for plate templates and add headers to docx tables [SCI-8375] (#5373)

Update reports for plate templates and add headers to docx tables [SCI-8375]
This commit is contained in:
ajugo 2023-05-10 16:15:14 +02:00 committed by GitHub
parent 2b82b6a74e
commit 74516da01a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 115 additions and 25 deletions

View file

@ -37,7 +37,6 @@ function generateElnTable(content, tableMetadata) {
}
const decodedContent = hex2a(content);
const isPlateTemplate = tableMetadata.plateTemplate === 'true';
const tableData = JSON.parse(decodedContent);
const numRows = tableData.data.length + 1;
const numCols = tableData.data[0].length + 1;
@ -54,9 +53,9 @@ function generateElnTable(content, tableMetadata) {
if (i > 0 && j > 0 && tableData.data[i - 1][j - 1] !== null) {
cellData = tableData.data[i - 1][j - 1];
} else if (i === 0 && j !== 0) {
cellData = isPlateTemplate ? j.toString() : colName(j - 1);
cellData = tableMetadata.plateTemplate ? j.toString() : colName(j - 1);
} else if (j === 0 && i !== 0) {
cellData = isPlateTemplate ? colName(i - 1) : i.toString();
cellData = tableMetadata.plateTemplate ? colName(i - 1) : i.toString();
}
tableCells = `${tableCells}<td ${cellClass ? `class="${cellClass}"` : ''}>${cellData}</td>`;

View file

@ -52,7 +52,8 @@ class Report < ApplicationRecord
step_checklists: true,
step_files: true,
step_tables: true,
step_comments: true
step_comments: true,
step_well_plates: true
},
file_results: true,
file_results_previews: false,

View file

@ -6,13 +6,19 @@ module Reports::Docx::DrawResultTable
timestamp = table.created_at
color = @color
obj = self
table_data = JSON.parse(table.contents_utf_8)['data']
table_data = obj.add_headers_to_table(table_data, false)
@docx.p
@docx.table JSON.parse(table.contents_utf_8)['data'], border_size: Constants::REPORT_DOCX_TABLE_BORDER_SIZE do
@docx.table table_data, border_size: Constants::REPORT_DOCX_TABLE_BORDER_SIZE do
cell_style rows[0], bold: true, background: color[:concrete]
cell_style cols[0], bold: true, background: color[:concrete]
if table.metadata.present?
JSON.parse(table.metadata)['cells']&.each do |cell|
next unless cell.present? && cell['row'].present? && cell['col'].present? && cell['className'].present?
cell_style rows.dig(cell['row'].to_i, cell['col'].to_i), align: obj.table_cell_alignment(cell['className'])
cell_style rows.dig(cell['row'].to_i + 1, cell['col'].to_i + 1),
align: obj.table_cell_alignment(cell['className'])
end
end
end

View file

@ -24,14 +24,15 @@ module Reports::Docx::DrawStep
), color: color[:gray]
end
step.step_orderable_elements.order(:position).each do |e|
if e.orderable_type == 'StepTable' && @settings.dig('task', 'protocol', 'step_tables')
draw_step_table(e.orderable.table)
step.step_orderable_elements.order(:position).each do |element|
case element.orderable_type
when 'StepTable'
handle_step_table(element.orderable.table)
when 'Checklist'
handle_checklist(element.orderable)
when 'StepText'
handle_step_text(element.orderable)
end
if e.orderable_type == 'Checklist' && @settings.dig('task', 'protocol', 'step_checklists')
draw_step_checklist(e.orderable)
end
draw_step_text(e.orderable) if e.orderable_type == 'StepText' && @settings.dig('task', 'protocol', 'step_texts')
end
if @settings.dig('task', 'protocol', 'step_files')
step.assets.each do |asset|
@ -44,4 +45,27 @@ module Reports::Docx::DrawStep
@docx.p
@docx.p
end
def handle_step_table(table)
has_step_well_plates = @settings.dig('task', 'protocol', 'step_well_plates')
has_step_tables = @settings.dig('task', 'protocol', 'step_tables')
if table.metadata.present?
if has_step_well_plates && table.metadata['plateTemplate']
draw_step_table(table, 'step_well_plates_table')
elsif has_step_tables && !table.metadata['plateTemplate']
draw_step_table(table, 'step_table')
end
elsif has_step_tables
draw_step_table(table, 'step_table')
end
end
def handle_checklist(checklist)
draw_step_checklist(checklist) if @settings.dig('task', 'protocol', 'step_checklists')
end
def handle_step_text(text)
draw_step_text(text) if @settings.dig('task', 'protocol', 'step_texts')
end
end

View file

@ -1,25 +1,31 @@
# frozen_string_literal: true
module Reports::Docx::DrawStepTable
def draw_step_table(table)
def draw_step_table(table, table_type)
color = @color
timestamp = table.created_at
obj = self
table_data = JSON.parse(table.contents_utf_8)['data']
table_data = obj.add_headers_to_table(table_data, table_type == 'step_well_plates_table')
@docx.p
@docx.table JSON.parse(table.contents_utf_8)['data'], border_size: Constants::REPORT_DOCX_TABLE_BORDER_SIZE do
if table.metadata
table.metadata['cells'].each do |cell|
@docx.table table_data, border_size: Constants::REPORT_DOCX_TABLE_BORDER_SIZE do
cell_style rows[0], bold: true, background: color[:concrete]
cell_style cols[0], bold: true, background: color[:concrete]
if table.metadata.present?
table.metadata['cells']&.each do |cell|
data = cell[1]
next unless data.present? && data['row'].present? && data['col'].present? && data['className'].present?
cell_style rows.dig(data['row'].to_i, data['col'].to_i), align: obj.table_cell_alignment(data['className'])
cell_style rows.dig(data['row'].to_i + 1, data['col'].to_i + 1),
align: obj.table_cell_alignment(data['className'])
end
end
end
@docx.p do
text I18n.t('projects.reports.elements.step_table.table_name', name: table.name), italic: true
text I18n.t("projects.reports.elements.#{table_type}.table_name", name: table.name), italic: true
text ' '
text I18n.t('projects.reports.elements.step_table.user_time',
text I18n.t("projects.reports.elements.#{table_type}.user_time",
timestamp: I18n.l(timestamp, format: :full)), color: color[:gray]
end
end

View file

@ -91,7 +91,8 @@ module Reports::Docx::PrivateMethods
@color = {
gray: 'a0a0a0',
green: '2dbe61'
green: '2dbe61',
concrete: 'f0f0f6'
}
end
end

View file

@ -14,6 +14,35 @@ module Reports
:left
end
end
def add_headers_to_table(table, is_well_plate)
table.each_with_index do |row, index|
row.unshift(is_well_plate ? convert_index_to_letter(index) : index + 1)
end
header_row = Array.new(table.first.length) do |index|
if index.zero?
''
else
is_well_plate ? index : convert_index_to_letter(index - 1)
end
end
table.unshift(header_row)
end
def convert_index_to_letter(index)
ord_a = 'A'.ord
ord_z = 'Z'.ord
len = (ord_z - ord_a) + 1
num = index
col_name = ''
while num >= 0
col_name = ((num % len) + ord_a).chr + col_name
num = (num / len).floor - 1
end
col_name
end
end
end
end

View file

@ -16,8 +16,16 @@
</div>
<div class="report-element-children">
<% step.step_orderable_elements.order(:position).each do |e| %>
<% if e.orderable_type == 'StepTable' && @settings.dig('task', 'protocol', 'step_tables') %>
<%= render partial: 'reports/elements/step_table_element.html.erb', locals: { table: e.orderable.table, export_all: export_all } %>
<% if e.orderable_type == 'StepTable' %>
<% if e.orderable.table.metadata.present? %>
<% if @settings.dig('task', 'protocol', 'step_well_plates') && e.orderable.table.metadata['plateTemplate'] %>
<%= render partial: 'reports/elements/step_table_element.html.erb', locals: { table: e.orderable.table, export_all: export_all, table_type: 'step_well_plates_table' } %>
<% elsif @settings.dig('task', 'protocol', 'step_tables') && !e.orderable.table.metadata['plateTemplate'] %>
<%= render partial: 'reports/elements/step_table_element.html.erb', locals: { table: e.orderable.table, export_all: export_all, table_type: 'step_table' } %>
<% end %>
<% elsif @settings.dig('task', 'protocol', 'step_tables') %>
<%= render partial: 'reports/elements/step_table_element.html.erb', locals: { table: e.orderable.table, export_all: export_all, table_type: 'step_table' } %>
<% end %>
<% end %>
<% if e.orderable_type == 'Checklist' && @settings.dig('task', 'protocol', 'step_checklists') %>
<%= render partial: 'reports/elements/step_checklist_element.html.erb', locals: { checklist: e.orderable, export_all: export_all } %>

View file

@ -19,7 +19,7 @@
<% end %>
</div>
<div class="user-time">
<%= t('projects.reports.elements.step_table.user_time', timestamp: l(timestamp, format: :full)) %>
<%= t("projects.reports.elements.#{table_type}.user_time", timestamp: l(timestamp, format: :full)) %>
</div>
</div>
<div class="report-element-body">

View file

@ -33,7 +33,7 @@
<%= t("projects.reports.wizard.third_step.protocol_step") %>
<div class="divider"></div>
<ul class="step-contents report-protocol-settings">
<% %i(completed_steps uncompleted_steps step_texts step_checklists step_files step_tables step_comments).each do |step_content| %>
<% %i(completed_steps uncompleted_steps step_texts step_checklists step_files step_tables step_well_plates step_comments).each do |step_content| %>
<li>
<span class="sci-checkbox-container">
<input type="checkbox" class="sci-checkbox protocol-setting" value="<%= step_content %>" <%= 'checked' if report.settings.dig(:task, :protocol, step_content) %> />

View file

@ -678,6 +678,7 @@ en:
step_checklists: "Step checklists"
step_files: "Step files"
step_tables: "Step tables"
step_well_plates: "Step well plates"
step_comments: "Step comments"
assigned_items: "Assigned items"
assigned_items_description: "Inventories selected below will only contain the items that you assigned to the tasks directly."
@ -823,6 +824,9 @@ en:
step_table:
table_name: "%{name}"
user_time: "Table created on %{timestamp}."
step_well_plates_table:
table_name: "%{name}"
user_time: "Well plate created on %{timestamp}."
step_asset:
file_name: "%{file}"
sidebar_name: "File %{file}"

View file

@ -0,0 +1,12 @@
# frozen_string_literal: true
class AddWellPlateDefaultToReports < ActiveRecord::Migration[6.1]
def change
Report.find_each do |report|
next unless report.settings.dig('task', 'protocol')
report.settings['task']['protocol']['step_well_plates'] = true
report.save!(touch: false)
end
end
end