mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-21 15:36:22 +08:00
commit
7ced8621e7
2
Gemfile
2
Gemfile
|
@ -84,7 +84,7 @@ gem 'silencer' # Silence certain Rails logs
|
|||
gem 'sneaky-save', git: 'https://github.com/einzige/sneaky-save'
|
||||
gem 'turbolinks', '~> 5.1.1'
|
||||
gem 'underscore-rails'
|
||||
gem 'wicked_pdf', '~> 1.4.0'
|
||||
gem 'wicked_pdf'
|
||||
gem 'wkhtmltopdf-heroku', '2.12.5'
|
||||
|
||||
gem 'aws-sdk-rails'
|
||||
|
|
10
Gemfile.lock
10
Gemfile.lock
|
@ -210,7 +210,7 @@ GEM
|
|||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.12.2)
|
||||
concurrent-ruby (1.1.8)
|
||||
concurrent-ruby (1.1.9)
|
||||
crack (0.4.5)
|
||||
rexml
|
||||
crass (1.0.6)
|
||||
|
@ -300,7 +300,7 @@ GEM
|
|||
httparty (0.17.3)
|
||||
mime-types (~> 3.0)
|
||||
multi_xml (>= 0.5.2)
|
||||
i18n (1.8.7)
|
||||
i18n (1.8.10)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-js (3.8.0)
|
||||
i18n (>= 0.6.6)
|
||||
|
@ -366,7 +366,7 @@ GEM
|
|||
mini_magick (4.11.0)
|
||||
mini_mime (1.0.2)
|
||||
mini_portile2 (2.5.1)
|
||||
minitest (5.14.3)
|
||||
minitest (5.14.4)
|
||||
momentjs-rails (2.17.1)
|
||||
railties (>= 3.1)
|
||||
msgpack (1.4.2)
|
||||
|
@ -614,7 +614,7 @@ GEM
|
|||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.5)
|
||||
whacamole (1.2.0)
|
||||
wicked_pdf (1.4.0)
|
||||
wicked_pdf (2.1.0)
|
||||
activesupport
|
||||
wkhtmltopdf-heroku (2.12.5.0)
|
||||
xpath (3.2.0)
|
||||
|
@ -732,7 +732,7 @@ DEPENDENCIES
|
|||
webmock
|
||||
webpacker (~> 4.0.0)
|
||||
whacamole
|
||||
wicked_pdf (~> 1.4.0)
|
||||
wicked_pdf
|
||||
wkhtmltopdf-heroku (= 2.12.5)
|
||||
yomu!
|
||||
|
||||
|
|
|
@ -1020,19 +1020,21 @@ function reportHandsonTableConverter() {
|
|||
});
|
||||
|
||||
// Project content
|
||||
reportData.project_content = { experiments: [], tasks: {}, repositories: [] };
|
||||
reportData.project_content = { experiments: [], repositories: [] };
|
||||
$.each($('.project-contents-container .experiment-element'), function(i, experiment) {
|
||||
let expCheckbox = $(experiment).find('.report-experiment-checkbox');
|
||||
if (!expCheckbox.prop('checked') && !expCheckbox.prop('indeterminate')) return;
|
||||
|
||||
let experimentId = $(experiment).find('.report-experiment-checkbox').val();
|
||||
reportData.project_content.tasks[experimentId] = [];
|
||||
reportData.project_content.experiments.push(experimentId);
|
||||
let experimentData = {};
|
||||
experimentData.id = parseInt($(experiment).find('.report-experiment-checkbox').val(), 10);
|
||||
experimentData.my_module_ids = [];
|
||||
$.each($(experiment).find('.report-my-module-checkbox:checked'), function(j, myModule) {
|
||||
reportData.project_content.tasks[experimentId].push(parseInt(myModule.value, 10));
|
||||
experimentData.my_module_ids.push(parseInt(myModule.value, 10));
|
||||
});
|
||||
reportData.project_content.experiments.push(experimentData);
|
||||
});
|
||||
$.each($('.task-contents-container .repositories-contents .sci-checkbox:checked'), function(i, e) {
|
||||
|
||||
$.each($('.task-contents-container .repositories-contents .repositories-setting:checked'), function(i, e) {
|
||||
reportData.project_content.repositories.push(parseInt(e.value, 10));
|
||||
});
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
${I18n.t('projects.reports.index.previous_docx')})
|
||||
</a>`;
|
||||
}
|
||||
return `<span class="processing-error">
|
||||
return `<span class="processing-error docx">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
${I18n.t('projects.reports.index.error')}${oldLink}
|
||||
</span>`;
|
||||
|
@ -101,7 +101,7 @@
|
|||
${I18n.t('projects.reports.index.previous_pdf')})
|
||||
</a>`;
|
||||
}
|
||||
return `<span class="processing-error">
|
||||
return `<span class="processing-error pdf">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
${I18n.t('projects.reports.index.error')}${oldLink}
|
||||
</span>`;
|
||||
|
|
|
@ -226,26 +226,24 @@
|
|||
clearDropdownResultsCallback(INVENTORY_PICKER);
|
||||
}
|
||||
|
||||
function initializeSubmitAction() {
|
||||
$('#content-reports-index').on('click', '#savePDFtoInventorySubmit', function() {
|
||||
animateSpinner();
|
||||
$.ajax({
|
||||
url: $('#savePDFtoInventorySubmit').data('target-url'),
|
||||
data: SELECTED_IDS,
|
||||
type: 'POST',
|
||||
success: function(data) {
|
||||
animateSpinner(null, false);
|
||||
HelperModule.flashAlertMsg(data.message, 'success');
|
||||
$('#savePDFtoInventory').modal('hide');
|
||||
},
|
||||
error: function(xhr) {
|
||||
animateSpinner(null, false);
|
||||
HelperModule.flashAlertMsg(xhr.responseJSON.message, 'danger');
|
||||
$('#savePDFtoInventory').modal('hide');
|
||||
}
|
||||
});
|
||||
$('#content-reports-index').on('click', '#savePDFtoInventorySubmit', function() {
|
||||
animateSpinner();
|
||||
$.ajax({
|
||||
url: $('#savePDFtoInventorySubmit').data('target-url'),
|
||||
data: SELECTED_IDS,
|
||||
type: 'POST',
|
||||
success: function(data) {
|
||||
animateSpinner(null, false);
|
||||
HelperModule.flashAlertMsg(data.message, 'success');
|
||||
$('#savePDFtoInventory').modal('hide');
|
||||
},
|
||||
error: function(xhr) {
|
||||
animateSpinner(null, false);
|
||||
HelperModule.flashAlertMsg(xhr.responseJSON.message, 'danger');
|
||||
$('#savePDFtoInventory').modal('hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* INITIALIZERS
|
||||
|
@ -254,7 +252,6 @@
|
|||
function initializeSavePDFtoInventoryModal() {
|
||||
$('#content-reports-index').on('shown.bs.modal', '#savePDFtoInventory', function() {
|
||||
initInventoriesSelectPicker();
|
||||
initializeSubmitAction();
|
||||
clearErrors();
|
||||
// refresh the dropdown state
|
||||
$('#selectInventory').parent().find('input').trigger('keyup');
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
padding-top: .25em;
|
||||
|
||||
&::after {
|
||||
background: linear-gradient(to right, transparent, $color-white 50%);
|
||||
background: linear-gradient(to right, $color-transparent, $color-white 50%);
|
||||
bottom: .75em;
|
||||
content: "";
|
||||
height: 1.75em;
|
||||
|
@ -270,7 +270,7 @@
|
|||
|
||||
&:hover {
|
||||
.description-text::after {
|
||||
background: linear-gradient(to right, transparent, $color-concrete 50%);
|
||||
background: linear-gradient(to right, $color-transparent, $color-concrete 50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -323,7 +323,7 @@
|
|||
}
|
||||
|
||||
.description-text::after {
|
||||
background: linear-gradient(to right, transparent, $color-concrete 50%);
|
||||
background: linear-gradient(to right, $color-transparent, $color-concrete 50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -341,7 +341,7 @@
|
|||
|
||||
&:hover {
|
||||
.description-text::after {
|
||||
background: linear-gradient(to right, transparent, $color-alto 50%);
|
||||
background: linear-gradient(to right, $color-transparent, $color-alto 50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ $color-alto: #d0d0d8;
|
|||
$color-silver-chalice: #a0a0a8;
|
||||
$color-volcano: #404048;
|
||||
$color-black: #231f20;
|
||||
|
||||
$color-transparent: rgba(255, 255, 255, 0);
|
||||
|
||||
|
||||
// Theme colors
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
margin-bottom: 0;
|
||||
|
||||
& > li > a {
|
||||
padding: 8px 20px;
|
||||
padding: 8px 38px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,17 @@
|
|||
}
|
||||
}
|
||||
|
||||
#support-link {
|
||||
#knowledge-center-link {
|
||||
.fas {
|
||||
margin-left: -26px;
|
||||
padding: 3px;
|
||||
position: absolute
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#support-link,
|
||||
#knowledge-center-link {
|
||||
color: $brand-primary;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ class ApplicationController < ActionController::Base
|
|||
before_action :authenticate_user!
|
||||
helper_method :current_team
|
||||
before_action :update_current_team, if: :user_signed_in?
|
||||
before_action :set_date_format, if: :user_signed_in?
|
||||
around_action :set_date_format, if: :user_signed_in?
|
||||
around_action :set_time_zone, if: :current_user
|
||||
layout 'main'
|
||||
|
||||
|
@ -102,7 +102,9 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def set_date_format
|
||||
I18n.backend.date_format =
|
||||
current_user.settings[:date_format] || Constants::DEFAULT_DATE_FORMAT
|
||||
I18n.backend.date_format = current_user.settings[:date_format]
|
||||
yield
|
||||
ensure
|
||||
I18n.backend.date_format = nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,186 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ReportActions
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def in_params?(val)
|
||||
params.include? val and params[val] == '1'
|
||||
end
|
||||
|
||||
def generate_new_el(hide)
|
||||
el = {}
|
||||
el[:html] = render_to_string(
|
||||
partial: 'reports/elements/new_element.html.erb',
|
||||
locals: { hide: hide }
|
||||
)
|
||||
el[:children] = []
|
||||
el[:new_element] = true
|
||||
el
|
||||
end
|
||||
|
||||
def generate_el(partial, locals)
|
||||
el = {}
|
||||
el[:html] = render_to_string(
|
||||
partial: partial,
|
||||
locals: locals
|
||||
)
|
||||
el[:children] = []
|
||||
el[:new_element] = false
|
||||
el
|
||||
end
|
||||
|
||||
def generate_project_contents_json
|
||||
res = []
|
||||
if params.include? :modules
|
||||
module_ids = (params[:modules].select { |_, p| p == '1' }).keys.collect(&:to_i)
|
||||
|
||||
# Get unique experiments from given modules
|
||||
experiments = @project.experiments.distinct.joins(:my_modules).where('my_modules.id': module_ids)
|
||||
experiments.each do |experiment|
|
||||
res << generate_new_el(false)
|
||||
el = generate_el(
|
||||
'reports/elements/experiment_element.html.erb',
|
||||
experiment: experiment
|
||||
)
|
||||
selected_modules = experiment.my_modules.includes(:tags).where(id: module_ids)
|
||||
el[:children] = generate_experiment_contents_json(selected_modules)
|
||||
res << el
|
||||
end
|
||||
end
|
||||
res << generate_new_el(false)
|
||||
res
|
||||
end
|
||||
|
||||
def generate_experiment_contents_json(selected_modules)
|
||||
res = []
|
||||
selected_modules.order(:workflow_order).each do |my_module|
|
||||
res << generate_new_el(false)
|
||||
el = generate_el(
|
||||
'reports/elements/my_module_element.html.erb',
|
||||
my_module: my_module
|
||||
)
|
||||
el[:children] = generate_module_contents_json(my_module)
|
||||
res << el
|
||||
end
|
||||
res << generate_new_el(false)
|
||||
res
|
||||
end
|
||||
|
||||
def generate_module_contents_json(my_module)
|
||||
res = []
|
||||
|
||||
ReportExtends::MODULE_CONTENTS.each do |contents|
|
||||
elements = []
|
||||
contents.values.each do |element|
|
||||
if contents.has_many
|
||||
elements = params.select { |k| k.starts_with?("module_#{element}") }
|
||||
elements = elements.select { |_, v| v == '1' }.keys
|
||||
elements.map! { |el| el.gsub('module_', '') }.map! { |el| el.split('_') }
|
||||
elements.map! { |el| [el[0].to_sym, el[1].to_i] }
|
||||
break unless elements.empty?
|
||||
else
|
||||
present = in_params?("module_#{element}".to_sym) || in_params?(element.to_sym)
|
||||
if present
|
||||
elements << [element.to_sym, nil]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
next if elements.empty?
|
||||
|
||||
elements.each do |_, el_id|
|
||||
if contents.children
|
||||
contents.collection(my_module, params).each do |report_el|
|
||||
res << generate_new_el(false)
|
||||
locals = contents.parse_locals([report_el])
|
||||
locals[:element_id] = el_id if el_id
|
||||
el = generate_el(
|
||||
"reports/elements/my_module_#{contents.element.to_s.singularize}"\
|
||||
"_element.html.erb",
|
||||
locals
|
||||
)
|
||||
if :step.in? contents.locals
|
||||
el[:children] = generate_step_contents_json(report_el)
|
||||
elsif :result.in? contents.locals
|
||||
el[:children] = generate_result_contents_json(report_el)
|
||||
end
|
||||
res << el
|
||||
end
|
||||
else
|
||||
file_name = contents.file_name
|
||||
res << generate_new_el(false)
|
||||
locals = contents.parse_locals([my_module, :asc])
|
||||
locals[:element_id] = el_id if el_id
|
||||
res << generate_el(
|
||||
"reports/elements/my_module_#{file_name}_element.html.erb",
|
||||
locals
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
res << generate_new_el(false)
|
||||
res
|
||||
end
|
||||
|
||||
def generate_step_contents_json(step)
|
||||
res = []
|
||||
if in_params? :step_checklists
|
||||
step.checklists.asc.each do |checklist|
|
||||
res << generate_new_el(false)
|
||||
res << generate_el(
|
||||
'reports/elements/step_checklist_element.html.erb', checklist: checklist
|
||||
)
|
||||
end
|
||||
end
|
||||
if in_params? :step_assets
|
||||
sort_value = step.current_view_state(current_user).state.dig('assets', 'sort')
|
||||
step.assets.order(view_mode: :desc).sort_assets(sort_value).each do |asset|
|
||||
res << generate_new_el(false)
|
||||
res << generate_el(
|
||||
'reports/elements/step_asset_element.html.erb', asset: asset
|
||||
)
|
||||
end
|
||||
end
|
||||
if in_params? :step_tables
|
||||
step.tables.each do |table|
|
||||
res << generate_new_el(false)
|
||||
res << generate_el(
|
||||
'reports/elements/step_table_element.html.erb', table: table
|
||||
)
|
||||
end
|
||||
end
|
||||
if in_params? :step_comments
|
||||
res << generate_new_el(false)
|
||||
res << generate_el(
|
||||
'reports/elements/step_comments_element.html.erb', step: step, order: :asc
|
||||
)
|
||||
end
|
||||
res << generate_new_el(false)
|
||||
res
|
||||
end
|
||||
|
||||
def generate_result_contents_json(result)
|
||||
res = []
|
||||
if in_params? :result_comments
|
||||
res << generate_new_el(true)
|
||||
res << generate_el(
|
||||
'reports/elements/result_comments_element.html.erb', result: result, order: :asc
|
||||
)
|
||||
else
|
||||
res << generate_new_el(false)
|
||||
end
|
||||
res
|
||||
end
|
||||
|
||||
def elements_empty?(elements)
|
||||
return true if elements.blank? || elements.count.zero?
|
||||
|
||||
if elements.count == 1
|
||||
el = elements[0]
|
||||
return true if el.include?(:new_element) && el[:new_element]
|
||||
|
||||
return false
|
||||
end
|
||||
false
|
||||
end
|
||||
end
|
|
@ -2,6 +2,7 @@ class ReportsController < ApplicationController
|
|||
include TeamsHelper
|
||||
include ReportActions
|
||||
include ReportsHelper
|
||||
include StringUtility
|
||||
|
||||
BEFORE_ACTION_METHODS = %i(
|
||||
create
|
||||
|
@ -9,23 +10,14 @@ class ReportsController < ApplicationController
|
|||
update
|
||||
generate_pdf
|
||||
generate_docx
|
||||
save_modal
|
||||
new_template_values
|
||||
project_contents
|
||||
experiment_contents_modal
|
||||
module_contents_modal
|
||||
step_contents_modal
|
||||
result_contents_modal
|
||||
experiment_contents
|
||||
module_contents
|
||||
step_contents
|
||||
result_contents
|
||||
).freeze
|
||||
|
||||
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: BEFORE_ACTION_METHODS
|
||||
before_action :load_visible_projects, only: %i(new edit)
|
||||
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_manage_permissions, only: BEFORE_ACTION_METHODS
|
||||
|
@ -51,7 +43,6 @@ class ReportsController < ApplicationController
|
|||
# Report grouped by modules
|
||||
def new
|
||||
@templates = Extends::REPORT_TEMPLATES
|
||||
@repositories = Repository.accessible_by_teams(current_team).active.select(:id, :name).order(:name)
|
||||
@report = current_team.reports.new
|
||||
end
|
||||
|
||||
|
@ -112,9 +103,7 @@ class ReportsController < ApplicationController
|
|||
|
||||
def edit
|
||||
@edit = true
|
||||
@templates = Extends::REPORT_TEMPLATES
|
||||
@active_template = @report.settings[:template]
|
||||
@repositories = Repository.accessible_by_teams(current_team).active.select(:id, :name).order(:name)
|
||||
@report.settings = Report::DEFAULT_SETTINGS if @report.settings.blank?
|
||||
|
||||
@project_contents = {
|
||||
|
@ -128,7 +117,9 @@ class ReportsController < ApplicationController
|
|||
# Updating existing report from the _save modal of the new page
|
||||
def update
|
||||
@report.last_modified_by = current_user
|
||||
@report.assign_attributes(report_params)
|
||||
@report.assign_attributes(
|
||||
report_params.merge(project_id: @project.id)
|
||||
)
|
||||
|
||||
ReportActions::ReportContent.new(
|
||||
@report,
|
||||
|
@ -205,6 +196,8 @@ class ReportsController < ApplicationController
|
|||
format.json do
|
||||
@report.docx_processing!
|
||||
log_activity(:generate_docx_report)
|
||||
|
||||
ensure_report_template!
|
||||
Reports::DocxJob.perform_later(@report.id, current_user, root_url)
|
||||
render json: {
|
||||
message: I18n.t('projects.reports.index.generation.accepted_message')
|
||||
|
@ -245,58 +238,6 @@ class ReportsController < ApplicationController
|
|||
render json: { message: e.message }, status: :internal_server_error
|
||||
end
|
||||
|
||||
# Modal for saving the existsing/new report
|
||||
def save_modal
|
||||
# Assume user is updating existing report
|
||||
@report = @project.reports.find_by_id(params[:id])
|
||||
@method = :put
|
||||
|
||||
# Case when saving a new report
|
||||
if @report.blank?
|
||||
@report = Report.new
|
||||
@method = :post
|
||||
@url = project_reports_path(@project, format: :json)
|
||||
else
|
||||
@url = project_report_path(@project, @report, format: :json)
|
||||
end
|
||||
|
||||
render_403 and return unless params.include? :contents
|
||||
|
||||
@report_contents = params[:contents]
|
||||
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: {
|
||||
html: render_to_string(
|
||||
partial: 'reports/new/modal/save.html.erb'
|
||||
)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Experiment for adding contents into experiment element
|
||||
def experiment_contents_modal
|
||||
experiment = @project.experiments.find_by_id(params[:experiment_id])
|
||||
|
||||
respond_to do |format|
|
||||
if experiment.blank?
|
||||
format.json do
|
||||
render json: {}, status: :not_found
|
||||
end
|
||||
else
|
||||
format.json do
|
||||
render json: {
|
||||
html: render_to_string(
|
||||
partial: 'reports/new/modal/experiment_contents.html.erb',
|
||||
locals: { project: @project, experiment: experiment }
|
||||
)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Modal for adding contents into module element
|
||||
def module_contents_modal
|
||||
my_module = MyModule.find_by_id(params[:my_module_id])
|
||||
|
@ -375,105 +316,6 @@ class ReportsController < ApplicationController
|
|||
}
|
||||
end
|
||||
|
||||
def experiment_contents
|
||||
experiment = @project.experiments.find_by(id: params[:id])
|
||||
module_ids = (params[:modules].select { |_, p| p == '1' }).keys.collect(&:to_i)
|
||||
selected_modules = experiment.my_modules.where(id: module_ids)
|
||||
|
||||
respond_to do |format|
|
||||
if experiment.blank?
|
||||
format.json { render json: {}, status: :not_found }
|
||||
elsif selected_modules.blank?
|
||||
format.json { render json: {}, status: :no_content }
|
||||
else
|
||||
elements = generate_experiment_contents_json(selected_modules)
|
||||
end
|
||||
|
||||
if elements_empty? elements
|
||||
format.json { render json: {}, status: :no_content }
|
||||
else
|
||||
format.json do
|
||||
render json: {
|
||||
status: :ok,
|
||||
elements: elements
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def module_contents
|
||||
my_module = MyModule.find_by_id(params[:id])
|
||||
return render_403 unless my_module.experiment.project == @project
|
||||
|
||||
respond_to do |format|
|
||||
if my_module.blank?
|
||||
format.json { render json: {}, status: :not_found }
|
||||
else
|
||||
elements = generate_module_contents_json(my_module)
|
||||
|
||||
if elements_empty? elements
|
||||
format.json { render json: {}, status: :no_content }
|
||||
else
|
||||
format.json do
|
||||
render json: {
|
||||
status: :ok,
|
||||
elements: elements
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def step_contents
|
||||
step = Step.find_by_id(params[:id])
|
||||
return render_403 unless step.my_module.experiment.project == @project
|
||||
|
||||
respond_to do |format|
|
||||
if step.blank?
|
||||
format.json { render json: {}, status: :not_found }
|
||||
else
|
||||
elements = generate_step_contents_json(step)
|
||||
|
||||
if elements_empty? elements
|
||||
format.json { render json: {}, status: :no_content }
|
||||
else
|
||||
format.json {
|
||||
render json: {
|
||||
status: :ok,
|
||||
elements: elements
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def result_contents
|
||||
result = Result.find_by_id(params[:id])
|
||||
return render_403 unless result.my_module.experiment.project == @project
|
||||
|
||||
respond_to do |format|
|
||||
if result.blank?
|
||||
format.json { render json: {}, status: :not_found }
|
||||
else
|
||||
elements = generate_result_contents_json(result)
|
||||
|
||||
if elements_empty? elements
|
||||
format.json { render json: {}, status: :no_content }
|
||||
else
|
||||
format.json {
|
||||
render json: {
|
||||
status: :ok,
|
||||
elements: elements
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def available_repositories
|
||||
render json: { results: @available_repositories }, status: :ok
|
||||
end
|
||||
|
@ -490,7 +332,6 @@ class ReportsController < ApplicationController
|
|||
|
||||
private
|
||||
|
||||
include StringUtility
|
||||
AvailableRepository = Struct.new(:id, :name)
|
||||
|
||||
def load_vars
|
||||
|
@ -505,12 +346,14 @@ class ReportsController < ApplicationController
|
|||
render_403 unless can_read_project?(@project)
|
||||
end
|
||||
|
||||
def check_manage_permissions
|
||||
render_403 unless can_manage_reports?(@project.team)
|
||||
end
|
||||
|
||||
def load_visible_projects
|
||||
render_404 unless current_team
|
||||
def load_wizard_vars
|
||||
@templates = Extends::REPORT_TEMPLATES
|
||||
live_repositories = Repository.accessible_by_teams(current_team)
|
||||
snapshots_of_deleted = RepositorySnapshot.left_outer_joins(:original_repository)
|
||||
.where(team: current_team)
|
||||
.where.not(original_repository: live_repositories)
|
||||
.select('DISTINCT ON ("repositories"."parent_id") "repositories".*')
|
||||
@repositories = (live_repositories + snapshots_of_deleted).sort_by { |r| r.name.downcase }
|
||||
@visible_projects = Project.active
|
||||
.viewable_by_user(current_user, current_team)
|
||||
.joins(experiments: :my_modules)
|
||||
|
@ -519,6 +362,10 @@ class ReportsController < ApplicationController
|
|||
.select(:id, :name)
|
||||
end
|
||||
|
||||
def check_manage_permissions
|
||||
render_403 unless can_manage_reports?(@project.team)
|
||||
end
|
||||
|
||||
def load_available_repositories
|
||||
@available_repositories = []
|
||||
repositories = Repository.active
|
||||
|
@ -562,6 +409,15 @@ class ReportsController < ApplicationController
|
|||
|
||||
@report.pdf_processing!
|
||||
log_activity(:generate_pdf_report)
|
||||
|
||||
ensure_report_template!
|
||||
Reports::PdfJob.perform_later(@report.id, current_user)
|
||||
end
|
||||
|
||||
def ensure_report_template!
|
||||
return if @report.settings['template'].present?
|
||||
|
||||
@report.settings['template'] = 'scinote_template'
|
||||
@report.save
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,99 +3,24 @@
|
|||
module ReportsHelper
|
||||
include StringUtility
|
||||
|
||||
def render_new_element(hide)
|
||||
render partial: 'reports/elements/new_element.html.erb',
|
||||
locals: { hide: hide }
|
||||
end
|
||||
|
||||
def render_report_element(element, provided_locals = nil)
|
||||
# Determine partial
|
||||
file_name = element.type_of
|
||||
if element.type_of.in? ReportExtends::MY_MODULE_CHILDREN_ELEMENTS
|
||||
file_name = "my_module_#{element.type_of.singularize}"
|
||||
end
|
||||
view = "reports/elements/#{file_name}_element.html.erb"
|
||||
view = "reports/elements/#{element.type_of}_element.html.erb"
|
||||
|
||||
# Set locals
|
||||
|
||||
locals = provided_locals.nil? ? {} : provided_locals.clone
|
||||
|
||||
children_html = ''.html_safe
|
||||
# First, recursively render element's children
|
||||
if element.comments? || element.project_header?
|
||||
# Render no children
|
||||
elsif element.result?
|
||||
# Special handling for result comments
|
||||
if element.children.active.present?
|
||||
children_html.safe_concat render_new_element(true)
|
||||
element.children.active.each do |child|
|
||||
children_html
|
||||
.safe_concat render_report_element(child, provided_locals)
|
||||
end
|
||||
else
|
||||
children_html.safe_concat render_new_element(false)
|
||||
if element.children.active.present?
|
||||
element.children.active.each do |child|
|
||||
children_html.safe_concat render_report_element(child, provided_locals)
|
||||
end
|
||||
else
|
||||
if element.children.active.present?
|
||||
element.children.active.each do |child|
|
||||
children_html.safe_concat render_new_element(false)
|
||||
children_html
|
||||
.safe_concat render_report_element(child, provided_locals)
|
||||
end
|
||||
end
|
||||
children_html.safe_concat render_new_element(false)
|
||||
end
|
||||
locals[:report_element] = element
|
||||
locals[:children] = children_html
|
||||
|
||||
if provided_locals[:export_all]
|
||||
# Set path and filename locals for files and tables in export all ZIP
|
||||
|
||||
if element['type_of'] == 'my_module_repository'
|
||||
obj_id = element[:repository_id]
|
||||
elsif element['type_of'].in? %w(step_asset step_table result_asset
|
||||
result_table)
|
||||
|
||||
parent_el = ReportElement.find(element['parent_id'])
|
||||
parent_type = parent_el[:type_of]
|
||||
parent = parent_type.singularize.classify.constantize
|
||||
.find(parent_el["#{parent_type}_id"])
|
||||
|
||||
if parent.class == Step
|
||||
obj_id = if element['type_of'] == 'step_asset'
|
||||
element[:asset_id]
|
||||
elsif element['type_of'] == 'step_table'
|
||||
element[:table_id]
|
||||
end
|
||||
elsif parent.class == MyModule
|
||||
result = Result.find(element[:result_id])
|
||||
obj_id = if element['type_of'] == 'result_asset'
|
||||
result.asset.id
|
||||
elsif element['type_of'] == 'result_table'
|
||||
result.table.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if obj_id
|
||||
file = provided_locals[:obj_filenames][element['type_of'].to_sym][obj_id]
|
||||
locals[:path] = {
|
||||
file: file[:file].sub(%r{/usr/src/app/tmp/temp-zip-\d+/}, ''),
|
||||
preview: file[:preview]&.sub(%r{/usr/src/app/tmp/temp-zip-\d+/}, '')
|
||||
}
|
||||
locals[:filename] = locals[:path][:file].split('/').last
|
||||
end
|
||||
end
|
||||
|
||||
# ReportExtends is located in config/initializers/extends/report_extends.rb
|
||||
ReportElement.type_ofs.keys.each do |type|
|
||||
next unless element.public_send("#{type}?")
|
||||
|
||||
element.element_references.each do |el_ref|
|
||||
locals[el_ref.class.name.underscore.to_sym] = el_ref
|
||||
end
|
||||
end
|
||||
|
||||
(render partial: view, locals: locals).html_safe
|
||||
render partial: view, locals: locals
|
||||
end
|
||||
|
||||
# "Hack" to omit file preview URL because of WKHTML issues
|
||||
|
@ -106,46 +31,15 @@ module ReportsHelper
|
|||
image_tag('icon_small/missing.png')
|
||||
end
|
||||
|
||||
# "Hack" to load Glyphicons css directly from the CDN
|
||||
# site so they work in report
|
||||
def bootstrap_cdn_link_tag
|
||||
specs = Gem.loaded_specs['bootstrap-sass']
|
||||
return '' unless specs.present?
|
||||
|
||||
stylesheet_link_tag("http://netdna.bootstrapcdn.com/bootstrap/" \
|
||||
"#{specs.version.version}/css/bootstrap.min.css",
|
||||
media: 'all')
|
||||
end
|
||||
|
||||
def font_awesome_cdn_link_tag
|
||||
stylesheet_link_tag(
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/fontawesome.min.css',
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/regular.min.css',
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/solid.min.css'
|
||||
)
|
||||
end
|
||||
|
||||
def assigned_repository_or_snapshot(my_module, element_id, snapshot, repository)
|
||||
if element_id
|
||||
repository = Repository.accessible_by_teams(my_module.experiment.project.team).find_by(id: element_id)
|
||||
# Check for default set snapshots when repository still exists
|
||||
if repository
|
||||
selected_snapshot = repository.repository_snapshots.where(my_module: my_module).find_by(selected: true)
|
||||
repository = selected_snapshot if selected_snapshot
|
||||
end
|
||||
repository ||= RepositorySnapshot.joins(my_module: { experiment: :project })
|
||||
.where(my_module: { experiments: { project: my_module.experiment.project } })
|
||||
.find_by(id: element_id)
|
||||
def assigned_repository_or_snapshot(my_module, repository)
|
||||
if repository.is_a?(RepositorySnapshot)
|
||||
return my_module.repository_snapshots.find_by(parent_id: repository.parent_id, selected: true)
|
||||
end
|
||||
repository || snapshot
|
||||
end
|
||||
|
||||
def assigned_repositories_in_project_list(project)
|
||||
live_repositories = Repository.assigned_to_project(project)
|
||||
snapshots = RepositorySnapshot.of_unassigned_from_project(project)
|
||||
return nil unless my_module.assigned_repositories.exists?(id: repository.id)
|
||||
|
||||
snapshots.each { |snapshot| snapshot.name = "#{snapshot.name} #{t('projects.reports.index.deleted')}" }
|
||||
(live_repositories + snapshots).sort_by { |r| r.name.downcase }
|
||||
selected_snapshot = repository.repository_snapshots.find_by(my_module: my_module, selected: true)
|
||||
selected_snapshot || repository
|
||||
end
|
||||
|
||||
def step_status_label(step)
|
||||
|
@ -159,18 +53,12 @@ module ReportsHelper
|
|||
"<span class=\"label step-label-#{style}\">[#{text}]</span>".html_safe
|
||||
end
|
||||
|
||||
# Fixes issues with avatar images in reports
|
||||
def fix_smart_annotation_image(html)
|
||||
html_doc = Nokogiri::HTML(html)
|
||||
html_doc.search('.atwho-user-popover').each do |el|
|
||||
text = el.content
|
||||
el.replace("<a href='#' style='margin-left: 5px'>#{text}</a>")
|
||||
end
|
||||
html_doc.search('[ref="missing-img"]').each do |el|
|
||||
tag = wicked_pdf_image_tag('icon_small/missing.png')
|
||||
el.replace(tag)
|
||||
end
|
||||
html_doc.to_s
|
||||
def font_awesome_cdn_link_tag
|
||||
stylesheet_link_tag(
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/fontawesome.min.css',
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/regular.min.css',
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/solid.min.css'
|
||||
)
|
||||
end
|
||||
|
||||
def filter_steps_for_report(steps, settings)
|
||||
|
@ -215,19 +103,4 @@ module ReportsHelper
|
|||
.where(id: report.report_elements.my_module.select(:my_module_id))
|
||||
repository.repository_rows.joins(:my_modules).where(my_modules: my_modules)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def obj_name_to_filename(obj, filename_suffix = '')
|
||||
obj_name = if obj.class == Asset
|
||||
obj_name, extension = obj.file_name.split('.')
|
||||
extension&.prepend('.')
|
||||
obj_name
|
||||
elsif obj.class.in? [Table, Result, Repository]
|
||||
extension = '.csv'
|
||||
obj.name.present? ? obj.name : obj.class.name
|
||||
end
|
||||
obj_name = to_filesystem_name(obj_name)
|
||||
obj_name + "#{filename_suffix}#{extension}"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,7 +37,7 @@ module Reports
|
|||
report = Report.find(report_id)
|
||||
file = Tempfile.new(['report', '.docx'])
|
||||
begin
|
||||
I18n.backend.date_format = user.settings[:date_format] || Constants::DEFAULT_DATE_FORMAT
|
||||
I18n.backend.date_format = user.settings[:date_format]
|
||||
docx = Caracal::Document.new(file.path)
|
||||
Reports::Docx.new(report, docx, user: user, scinote_url: root_url).draw
|
||||
docx.save
|
||||
|
@ -52,9 +52,11 @@ module Reports
|
|||
report_link: "<a href='#{report_path}'>#{sanitize_input(report.name)}</a>",
|
||||
team_name: sanitize_input(report.team.name))
|
||||
)
|
||||
|
||||
Reports::DocxPreviewJob.perform_now(report.id)
|
||||
notification.create_user_notification(user)
|
||||
ensure
|
||||
I18n.backend.date_format = Constants::DEFAULT_DATE_FORMAT
|
||||
I18n.backend.date_format = nil
|
||||
file.close
|
||||
file.unlink
|
||||
end
|
||||
|
|
53
app/jobs/reports/docx_preview_job.rb
Normal file
53
app/jobs/reports/docx_preview_job.rb
Normal file
|
@ -0,0 +1,53 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Provides asynchronous generation of image previews for ActiveStorage::Blob records.
|
||||
module Reports
|
||||
class DocxPreviewJob < ApplicationJob
|
||||
queue_as :reports
|
||||
|
||||
discard_on StandardError do |job, error|
|
||||
Rails.logger.error(
|
||||
"Couldn't generate PDF preview for DOCX Report with id: #{job.arguments.first}. Error:\n #{error}"
|
||||
)
|
||||
end
|
||||
|
||||
discard_on ActiveRecord::RecordNotFound
|
||||
|
||||
def perform(report_id)
|
||||
report = Report.find(report_id)
|
||||
blob = report.docx_file.blob
|
||||
blob.open(tmpdir: tempdir) do |input|
|
||||
work_dir = File.dirname(input.path)
|
||||
preview_filename = "#{File.basename(input.path, '.*')}.pdf"
|
||||
preview_file = File.join(work_dir, preview_filename)
|
||||
Rails.logger.info "Starting preparing document preview for file #{blob.filename.sanitized}..."
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
success = system(
|
||||
libreoffice_path, '--headless', '--invisible', '--convert-to', 'pdf', '--outdir', work_dir, input.path
|
||||
)
|
||||
unless success && File.file?(preview_file)
|
||||
raise StandardError, "There was an error generating PDF preview, blob id: #{blob.id}"
|
||||
end
|
||||
|
||||
ActiveRecord::Base.no_touching do
|
||||
report.docx_preview_file.attach(io: File.open(preview_file), filename: "#{blob.filename.base}.pdf")
|
||||
end
|
||||
Rails.logger.info("Finished preparing PDF preview for file #{blob.filename.sanitized}.")
|
||||
end
|
||||
ensure
|
||||
File.delete(preview_file) if File.file?(preview_file)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def tempdir
|
||||
Rails.root.join('tmp')
|
||||
end
|
||||
|
||||
def libreoffice_path
|
||||
ENV['LIBREOFFICE_PATH'] || 'soffice'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,6 +6,8 @@ module Reports
|
|||
include InputSanitizeHelper
|
||||
include ReportsHelper
|
||||
|
||||
PDFUNITE_ENCRYPTED_PDF_ERROR_STRING = 'Unimplemented Feature: Could not merge encrypted files'
|
||||
|
||||
queue_as :reports
|
||||
|
||||
discard_on StandardError do |job, error|
|
||||
|
@ -49,7 +51,7 @@ module Reports
|
|||
|
||||
raise StandardError, 'Report template not found!' if template.blank?
|
||||
|
||||
I18n.backend.date_format = user.settings[:date_format] || Constants::DEFAULT_DATE_FORMAT
|
||||
I18n.backend.date_format = user.settings[:date_format]
|
||||
ActionController::Renderer::RACK_KEY_TRANSLATION['warden'] ||= 'warden'
|
||||
proxy = Warden::Proxy.new({}, Warden::Manager.new({}))
|
||||
proxy.set_user(user, scope: :user, store: false)
|
||||
|
@ -58,10 +60,10 @@ module Reports
|
|||
|
||||
file << renderer.render(
|
||||
pdf: 'report', header: { html: { template: "reports/templates/#{template}/header",
|
||||
locals: { report: report, user: user },
|
||||
locals: { report: report, user: user, logo: report_logo },
|
||||
layout: 'reports/footer_header.html.erb' } },
|
||||
footer: { html: { template: "reports/templates/#{template}/footer",
|
||||
locals: { report: report, user: user },
|
||||
locals: { report: report, user: user, logo: report_logo },
|
||||
layout: 'reports/footer_header.html.erb' } },
|
||||
assigns: { settings: report.settings },
|
||||
locals: { report: report },
|
||||
|
@ -89,7 +91,7 @@ module Reports
|
|||
)
|
||||
notification.create_user_notification(user)
|
||||
ensure
|
||||
I18n.backend.date_format = Constants::DEFAULT_DATE_FORMAT
|
||||
I18n.backend.date_format = nil
|
||||
file.close(true)
|
||||
end
|
||||
end
|
||||
|
@ -119,12 +121,22 @@ module Reports
|
|||
|
||||
def merge_pdf_files(file, report_file)
|
||||
merged_file = Tempfile.new(['report', '.pdf'], binmode: true)
|
||||
success = system(
|
||||
|
||||
_output, error, status = Open3.capture3(
|
||||
'pdfunite', report_file.path, file.path, merged_file.path
|
||||
)
|
||||
|
||||
unless success && File.file?(merged_file)
|
||||
raise StandardError, 'There was an error merging report and PDF file preview'
|
||||
# don't raise error if the issue was an encrypted pdf, which pdfunite doesn't support
|
||||
if error.include?(PDFUNITE_ENCRYPTED_PDF_ERROR_STRING)
|
||||
Rails.logger.warn("Cannot merge encrypted PDF #{file.path}, skipping!")
|
||||
|
||||
file.close(true)
|
||||
merged_file.close(true)
|
||||
|
||||
# return the report file unchanged, as no merge was done
|
||||
return report_file
|
||||
elsif !status.success? || !File.file?(merged_file)
|
||||
raise StandardError, "There was an error merging report and PDF file preview (#{error})"
|
||||
end
|
||||
|
||||
file.close(true)
|
||||
|
@ -152,7 +164,7 @@ module Reports
|
|||
title_page << renderer.render(
|
||||
pdf: 'report', inline: renderer.render_to_string("reports/templates/#{template}/cover.html.erb",
|
||||
layout: false,
|
||||
locals: { report: report, total_pages: total_pages.to_i }),
|
||||
locals: { report: report, total_pages: total_pages.to_i, logo: report_logo }),
|
||||
disable_javascript: false,
|
||||
template: 'reports/report.pdf.erb'
|
||||
)
|
||||
|
@ -170,5 +182,10 @@ module Reports
|
|||
|
||||
merged_file
|
||||
end
|
||||
|
||||
def report_logo
|
||||
'logo.png'
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -216,7 +216,7 @@ class Project < ApplicationRecord
|
|||
|
||||
def assigned_repositories_and_snapshots
|
||||
live_repositories = Repository.assigned_to_project(self)
|
||||
snapshots = RepositorySnapshot.of_unassigned_from_project(self)
|
||||
snapshots = RepositorySnapshot.assigned_to_project(self)
|
||||
(live_repositories + snapshots).sort_by { |r| r.name.downcase }
|
||||
end
|
||||
|
||||
|
@ -267,15 +267,15 @@ class Project < ApplicationRecord
|
|||
ActionController::Renderer::RACK_KEY_TRANSLATION['warden'] ||= 'warden'
|
||||
proxy = Warden::Proxy.new({}, Warden::Manager.new({}))
|
||||
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 = Report.generate_whole_project_report(self, user, team)
|
||||
|
||||
page_html_string =
|
||||
renderer.render 'reports/new_old.html.erb',
|
||||
locals: { export_all: true,
|
||||
obj_filenames: obj_filenames },
|
||||
assigns: { project: self, report: report }
|
||||
renderer.render 'reports/export.html.erb',
|
||||
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')
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ class Report < ApplicationRecord
|
|||
# ActiveStorage configuration
|
||||
has_one_attached :pdf_file
|
||||
has_one_attached :docx_file
|
||||
has_one_attached :docx_preview_file
|
||||
|
||||
auto_strip_attributes :name, :description, nullify: false
|
||||
validates :name,
|
||||
|
@ -93,61 +94,27 @@ class Report < ApplicationRecord
|
|||
report_elements.active.where(parent: nil).order(:position)
|
||||
end
|
||||
|
||||
# Clean report elements from report
|
||||
# the function runs before the report is edit
|
||||
def cleanup_report
|
||||
report_elements.each(&:clean_removed_or_archived_elements)
|
||||
end
|
||||
|
||||
def self.generate_whole_project_report(project, current_user, current_team)
|
||||
# report_contents = gen_element_content(project, Extends::EXPORT_ALL_PROJECT_ELEMENTS)
|
||||
content = {
|
||||
'experiments' => [],
|
||||
'tasks' => {},
|
||||
'repositories' => Repository.accessible_by_teams(project.team).pluck(:id)
|
||||
'repositories' => project.assigned_repositories_and_snapshots.pluck(:id)
|
||||
}
|
||||
project.experiments.includes(:my_modules).each do |experiment|
|
||||
content['experiments'].push(experiment.id)
|
||||
content['tasks'][experiment.id] = experiment.my_modules.pluck(:id)
|
||||
content['experiments'].push(
|
||||
{ id: experiment.id, my_module_ids: experiment.my_module_ids }
|
||||
)
|
||||
end
|
||||
|
||||
report = Report.new
|
||||
report.name = loop do
|
||||
dummy_name = SecureRandom.hex(10)
|
||||
break dummy_name unless Report.where(name: dummy_name).exists?
|
||||
break dummy_name unless Report.exists?(name: dummy_name)
|
||||
end
|
||||
report.project = project
|
||||
report.user = current_user
|
||||
report.team = current_team
|
||||
report.last_modified_by = current_user
|
||||
ReportActions::ReportContent.new(report, content, {}, current_user).save_with_content
|
||||
# report.save_with_contents(report_contents)
|
||||
report
|
||||
end
|
||||
|
||||
def self.gen_element_content(parent, children)
|
||||
elements = []
|
||||
|
||||
children.each do |element|
|
||||
element_hash = lambda { |object|
|
||||
hash_object = {
|
||||
'type_of' => element[:type_of] || element[:type_of_lambda].call(object),
|
||||
'id' => { element[:id_key] => object.id },
|
||||
'sort_order' => element[:sort_order],
|
||||
'children' => gen_element_content(object, element[:children] || [])
|
||||
}
|
||||
hash_object['id'][element[:parent_id_key]] = parent.id if element[:parent_id_key]
|
||||
hash_object
|
||||
}
|
||||
|
||||
if element[:relation]
|
||||
(element[:relation].inject(parent) { |p, method| p.public_send(method) }).each do |child|
|
||||
elements.push(element_hash.call(child))
|
||||
end
|
||||
else
|
||||
elements.push(element_hash.call(parent))
|
||||
end
|
||||
end
|
||||
elements
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,6 @@ class ReportElement < ApplicationRecord
|
|||
validates :position, presence: true
|
||||
validates :report, presence: true
|
||||
validates :type_of, presence: true
|
||||
validate :has_one_of_referenced_elements
|
||||
|
||||
belongs_to :report, inverse_of: :report_elements
|
||||
|
||||
|
@ -33,71 +32,7 @@ class ReportElement < ApplicationRecord
|
|||
belongs_to :checklist, inverse_of: :report_elements, optional: true
|
||||
belongs_to :asset, inverse_of: :report_elements, optional: true
|
||||
belongs_to :table, inverse_of: :report_elements, optional: true
|
||||
belongs_to :repository, inverse_of: :report_elements, optional: true,
|
||||
foreign_key: :repository_id, class_name: 'RepositoryBase'
|
||||
belongs_to :repository, inverse_of: :report_elements, optional: true, class_name: 'RepositoryBase'
|
||||
|
||||
scope :active, -> { where(type_of: ReportExtends::ACTIVE_REPORT_ELEMENTS) }
|
||||
|
||||
def result?
|
||||
result_asset? or result_table? or result_text?
|
||||
end
|
||||
|
||||
def comments?
|
||||
step_comments? or result_comments?
|
||||
end
|
||||
|
||||
# Get the referenced elements (previously, element's type_of must be set)
|
||||
def element_references
|
||||
ReportExtends::ELEMENT_REFERENCES.each do |el_ref|
|
||||
if el_ref.check(self)
|
||||
return el_ref.elements.map { |el| eval(el.gsub('_id', '')) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Set the element references (previously, element's type_of must be set)
|
||||
def set_element_references(ref_ids)
|
||||
ReportExtends::SET_ELEMENT_REFERENCES_LIST.each do |el_ref|
|
||||
check = el_ref.check(self)
|
||||
next unless check
|
||||
el_ref.elements.each do |element|
|
||||
public_send("#{element}=", ref_ids[element])
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
# removes element that are archived or deleted
|
||||
def clean_removed_or_archived_elements
|
||||
parent_model = ''
|
||||
%w(project
|
||||
experiment
|
||||
my_module
|
||||
step
|
||||
result
|
||||
checklist
|
||||
asset
|
||||
table
|
||||
repository)
|
||||
.each do |el|
|
||||
parent_model = el if send el
|
||||
end
|
||||
|
||||
if parent_model == 'experiment'
|
||||
destroy unless send(parent_model).project == report.project
|
||||
else
|
||||
destroy unless (send(parent_model).active? rescue send(parent_model))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def has_one_of_referenced_elements
|
||||
element_references.each do |el|
|
||||
next unless el.nil?
|
||||
errors.add(:base,
|
||||
'Report element doesn\'t have correct element references.')
|
||||
break
|
||||
end
|
||||
end
|
||||
scope :active, -> { where(type_of: Extends::ACTIVE_REPORT_ELEMENTS) }
|
||||
end
|
||||
|
|
|
@ -86,9 +86,9 @@ class Repository < RepositoryBase
|
|||
repository_rows = readable_rows.where(id: repository_row_matches)
|
||||
repository_rows = repository_rows.or(readable_rows.where(id: matched_by_user))
|
||||
|
||||
Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each do |field, include_hash|
|
||||
custom_cell_matches = readable_rows.joins(repository_cells: include_hash)
|
||||
.where_attributes_like(field, query, options)
|
||||
Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each do |_data_type, config|
|
||||
custom_cell_matches = repository_rows.joins(repository_cells: config[:includes])
|
||||
.where_attributes_like(config[:field], query, options)
|
||||
repository_rows = repository_rows.or(readable_rows.where(id: custom_cell_matches))
|
||||
end
|
||||
|
||||
|
|
|
@ -26,6 +26,12 @@ class RepositorySnapshot < RepositoryBase
|
|||
.order(:parent_id, updated_at: :desc)
|
||||
}
|
||||
|
||||
scope :assigned_to_project, lambda { |project|
|
||||
where(team: project.team)
|
||||
.joins(my_module: { experiment: :project })
|
||||
.where(my_module: { experiments: { project: project } })
|
||||
}
|
||||
|
||||
def self.create_preliminary(repository, my_module, created_by = nil)
|
||||
created_by ||= repository.created_by
|
||||
repository_snapshot = repository.dup.becomes(RepositorySnapshot)
|
||||
|
|
|
@ -49,8 +49,7 @@ class TeamZipExport < ZipExport
|
|||
project_path = make_model_dir(team_path, p, idx)
|
||||
project_name = project_path.split('/')[-1]
|
||||
|
||||
obj_filenames = { my_module_repository: {}, step_asset: {},
|
||||
step_table: {}, result_asset: {}, result_table: {} }
|
||||
obj_filenames = { repositories: {}, assets: {}, tables: {} }
|
||||
|
||||
# Change current dir for correct generation of relative links
|
||||
Dir.chdir(project_path)
|
||||
|
@ -63,7 +62,9 @@ class TeamZipExport < ZipExport
|
|||
|
||||
# Iterate through every inventory repo and save it to CSV
|
||||
repositories.each_with_index do |repo, repo_idx|
|
||||
obj_filenames[:my_module_repository][repo.id] = {
|
||||
next if obj_filenames[:repositories][repo.id].present?
|
||||
|
||||
obj_filenames[:repositories][repo.id] = {
|
||||
file: save_inventories_to_csv(inventories, repo, repo_idx)
|
||||
}
|
||||
end
|
||||
|
@ -88,16 +89,16 @@ class TeamZipExport < ZipExport
|
|||
|
||||
# Export protocols
|
||||
steps = my_module.protocols.map(&:steps).flatten
|
||||
obj_filenames[:step_asset].merge!(
|
||||
obj_filenames[:assets].merge!(
|
||||
export_assets(StepAsset.where(step: steps), :step, protocol_path)
|
||||
)
|
||||
obj_filenames[:step_table].merge!(
|
||||
obj_filenames[:tables].merge!(
|
||||
export_tables(StepTable.where(step: steps), :step, protocol_path)
|
||||
)
|
||||
|
||||
# Export results
|
||||
[false, true].each do |archived|
|
||||
obj_filenames[:result_asset].merge!(
|
||||
obj_filenames[:assets].merge!(
|
||||
export_assets(
|
||||
ResultAsset.where(result: my_module.results.where(archived: archived)),
|
||||
:result,
|
||||
|
@ -108,7 +109,7 @@ class TeamZipExport < ZipExport
|
|||
end
|
||||
|
||||
[false, true].each do |archived|
|
||||
obj_filenames[:result_table].merge!(
|
||||
obj_filenames[:tables].merge!(
|
||||
export_tables(
|
||||
ResultTable.where(result: my_module.results.where(archived: archived)),
|
||||
:result,
|
||||
|
|
|
@ -25,9 +25,11 @@ Canaid::Permissions.register_for(Asset) do
|
|||
when Result
|
||||
can_manage_result?(object)
|
||||
when RepositoryCell
|
||||
return false if object.repository_column.repository.is_a?(RepositorySnapshot)
|
||||
|
||||
can_manage_repository?(user, object.repository_column.repository)
|
||||
if object.repository_column.repository.is_a?(RepositorySnapshot)
|
||||
false
|
||||
else
|
||||
can_manage_repository?(user, object.repository_column.repository)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ module Api
|
|||
belongs_to :project_folder, serializer: ProjectFolderSerializer
|
||||
|
||||
def start_date
|
||||
I18n.l(object.created_at, format: :full)
|
||||
object.created_at
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,11 +3,33 @@
|
|||
module Api
|
||||
module V1
|
||||
class ReportSerializer < ActiveModel::Serializer
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
type :reports
|
||||
attributes :id, :name, :description
|
||||
attribute :pdf_file_size, if: -> { object.pdf_file.attached? }
|
||||
attribute :pdf_file_url, if: -> { object.pdf_file.attached? }
|
||||
attribute :docx_file_size, if: -> { object.docx_file.attached? }
|
||||
attribute :docx_file_url, if: -> { object.docx_file.attached? }
|
||||
belongs_to :user, serializer: UserSerializer
|
||||
belongs_to :project, serializer: ProjectSerializer,
|
||||
unless: -> { instance_options[:hide_project] }
|
||||
|
||||
def pdf_file_size
|
||||
object.pdf_file.blob.byte_size
|
||||
end
|
||||
|
||||
def pdf_file_url
|
||||
rails_blob_path(object.pdf_file, disposition: 'attachment')
|
||||
end
|
||||
|
||||
def docx_file_size
|
||||
object.docx_file.blob.byte_size
|
||||
end
|
||||
|
||||
def docx_file_url
|
||||
rails_blob_path(object.docx_file, disposition: 'attachment')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,14 @@
|
|||
module Api
|
||||
module V1
|
||||
class RepositoryDateRangeValueSerializer < ActiveModel::Serializer
|
||||
attribute :formatted, key: :date_range
|
||||
attribute :date_range
|
||||
|
||||
def date_range
|
||||
{
|
||||
from: object.start_time.to_date,
|
||||
to: object.end_time.to_date
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,14 @@
|
|||
module Api
|
||||
module V1
|
||||
class RepositoryDateTimeRangeValueSerializer < ActiveModel::Serializer
|
||||
attribute :formatted, key: :date_time_range
|
||||
attribute :date_time_range
|
||||
|
||||
def date_time_range
|
||||
{
|
||||
from: object.start_time,
|
||||
to: object.end_time
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
module Api
|
||||
module V1
|
||||
class RepositoryDateTimeValueSerializer < ActiveModel::Serializer
|
||||
attribute :formatted, key: :date_time
|
||||
attribute :date_time
|
||||
|
||||
def date_time
|
||||
object.data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
module Api
|
||||
module V1
|
||||
class RepositoryDateValueSerializer < ActiveModel::Serializer
|
||||
attribute :formatted, key: :date
|
||||
attribute :date
|
||||
|
||||
def date
|
||||
object.data.to_date
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,14 @@
|
|||
module Api
|
||||
module V1
|
||||
class RepositoryTimeRangeValueSerializer < ActiveModel::Serializer
|
||||
attribute :formatted, key: :time_range
|
||||
attribute :time_range
|
||||
|
||||
def time_range
|
||||
{
|
||||
from: object.start_time.strftime('%H:%M:%S.%3NZ'),
|
||||
to: object.start_time.strftime('%H:%M:%S.%3NZ')
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
module Api
|
||||
module V1
|
||||
class RepositoryTimeValueSerializer < ActiveModel::Serializer
|
||||
attribute :formatted, key: :time
|
||||
attribute :time
|
||||
|
||||
def time
|
||||
object.data.strftime('%H:%M:%S.%3NZ')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
module ReportActions
|
||||
class ReportContent
|
||||
include Canaid::Helpers::PermissionsHelper
|
||||
include ReportsHelper
|
||||
|
||||
MY_MODULE_ADDONS_ELEMENTS = []
|
||||
|
||||
|
@ -13,8 +14,9 @@ module ReportActions
|
|||
@element_position = 0
|
||||
@report = report
|
||||
@template_values = template_values
|
||||
@repositories = Repository.accessible_by_teams(report.project.team)
|
||||
.where(id: @content['repositories']).active
|
||||
@repositories = report.project
|
||||
.assigned_repositories_and_snapshots
|
||||
.select { |repository| @content['repositories'].include?(repository.id) }
|
||||
end
|
||||
|
||||
def save_with_content
|
||||
|
@ -57,47 +59,48 @@ module ReportActions
|
|||
private
|
||||
|
||||
def generate_content
|
||||
@content['experiments'].each do |exp_id|
|
||||
generate_experiment_content(exp_id, @content['tasks'][exp_id])
|
||||
save_element!({ 'project_id' => @report.project_id }, :project_header, nil)
|
||||
|
||||
@content['experiments'].each do |experiment|
|
||||
generate_experiment_content(experiment[:id], experiment[:my_module_ids])
|
||||
end
|
||||
end
|
||||
|
||||
def generate_experiment_content(exp_id, my_modules)
|
||||
experiment = Experiment.find_by(id: exp_id)
|
||||
def generate_experiment_content(experiment_id, my_module_ids)
|
||||
experiment = Experiment.find_by(id: experiment_id)
|
||||
return if !experiment && !can_read_experiment?(experiment, @user)
|
||||
|
||||
experiment_element = save_element!({ 'experiment_id' => experiment.id }, :experiment, nil)
|
||||
generate_my_modules_content(experiment, experiment_element, my_modules)
|
||||
generate_my_modules_content(experiment, experiment_element, my_module_ids)
|
||||
end
|
||||
|
||||
def generate_my_modules_content(experiment, experiment_element, selected_my_modules)
|
||||
def generate_my_modules_content(experiment, experiment_element, my_module_ids)
|
||||
my_modules = experiment.my_modules
|
||||
.active
|
||||
.where(id: selected_my_modules)
|
||||
my_modules.sort_by { |m| selected_my_modules.index m.id }.each do |my_module|
|
||||
.where(id: my_module_ids)
|
||||
my_modules.sort_by { |m| my_module_ids.index m.id }.each do |my_module|
|
||||
my_module_element = save_element!({ 'my_module_id' => my_module.id }, :my_module, experiment_element)
|
||||
|
||||
@repositories.each do |repository|
|
||||
repository = assigned_repository_or_snapshot(my_module, repository)
|
||||
next unless repository
|
||||
|
||||
save_element!(
|
||||
{ 'my_module_id' => my_module.id, 'repository_id' => repository.id },
|
||||
:my_module_repository,
|
||||
my_module_element
|
||||
)
|
||||
end
|
||||
|
||||
MY_MODULE_ADDONS_ELEMENTS.each do |e|
|
||||
public_send("generate_#{e}_content", my_module, my_module_element)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def save_element!(reference, type_of, parent)
|
||||
def save_element!(references, type_of, parent)
|
||||
el = ReportElement.new
|
||||
el.position = @element_position
|
||||
el.report = @report
|
||||
el.parent = parent
|
||||
el.type_of = type_of
|
||||
el.set_element_references(reference)
|
||||
el.assign_attributes(references)
|
||||
el.save!
|
||||
|
||||
@element_position += 1
|
||||
|
|
|
@ -11,7 +11,10 @@ module ReportActions
|
|||
end
|
||||
|
||||
def save
|
||||
ActiveRecord::Base.transaction do
|
||||
# we lock the row, to prevent two repository cells being created at the same location
|
||||
# as the RepositoryCell validation would pass in both concurrent transactions
|
||||
|
||||
@repository_row.with_lock do
|
||||
asset = create_new_asset
|
||||
delete_old_repository_cell
|
||||
@new_cell_value = create_new_cell_value(asset)
|
||||
|
|
|
@ -4,7 +4,10 @@ module Reports::Docx::DrawMyModuleRepository
|
|||
def draw_my_module_repository(subject)
|
||||
my_module = subject.my_module
|
||||
repository = subject.repository
|
||||
return unless can_read_experiment?(@user, my_module.experiment) && can_read_repository?(@user, repository)
|
||||
repository = assigned_repository_or_snapshot(my_module, repository)
|
||||
|
||||
return unless repository && can_read_experiment?(@user, my_module.experiment) &&
|
||||
(repository.is_a?(RepositorySnapshot) || can_read_repository?(@user, repository))
|
||||
|
||||
repository_data = my_module.repository_docx_json(repository)
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@ module Reports
|
|||
elements = []
|
||||
temp_p = []
|
||||
raw_elements.each do |elem|
|
||||
next unless elem
|
||||
|
||||
if %w(image newline table ol ul).include? elem[:type]
|
||||
unless temp_p.empty?
|
||||
elements.push(type: 'p', children: temp_p)
|
||||
|
|
|
@ -83,9 +83,13 @@ class RepositoryDatatableService
|
|||
results = repository_rows.where(id: repository_row_matches)
|
||||
results = results.or(repository_rows.where(id: matched_by_user))
|
||||
|
||||
Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each do |field, include_hash|
|
||||
custom_cell_matches = repository_rows.joins(repository_cells: include_hash)
|
||||
.where_attributes_like(field, search_value)
|
||||
data_types = @repository.repository_columns.pluck(:data_type).uniq
|
||||
|
||||
Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each do |data_type, config|
|
||||
next unless data_types.include?(data_type.to_s)
|
||||
|
||||
custom_cell_matches = repository_rows.joins(repository_cells: config[:includes])
|
||||
.where_attributes_like(config[:field], search_value)
|
||||
results = results.or(repository_rows.where(id: custom_cell_matches))
|
||||
end
|
||||
|
||||
|
|
|
@ -36,9 +36,13 @@ class RepositorySnapshotDatatableService < RepositoryDatatableService
|
|||
results = repository_rows.where(id: repository_row_matches)
|
||||
results = results.or(repository_rows.where(id: matched_by_user))
|
||||
|
||||
Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each do |field, include_hash|
|
||||
custom_cell_matches = repository_rows.joins(repository_cells: include_hash)
|
||||
.where_attributes_like(field, search_value)
|
||||
data_types = @repository.repository_columns.pluck(:data_type).uniq
|
||||
|
||||
Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each do |data_type, config|
|
||||
next unless data_types.include?(data_type.to_s)
|
||||
|
||||
custom_cell_matches = repository_rows.joins(repository_cells: config[:includes])
|
||||
.where_attributes_like(config[:field], search_value)
|
||||
results = results.or(repository_rows.where(id: custom_cell_matches))
|
||||
end
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<%= link_to protocols_path, {class: "new-protocol btn btn-secondary"} do %>
|
||||
<i class="fas fa-edit"></i><%= t("dashboard.quick_start.new_protocol") %>
|
||||
<% end %>
|
||||
<%= link_to reports_path, {class: "new-report btn btn-secondary"} do %>
|
||||
<%= link_to new_report_path, {class: "new-report btn btn-secondary"} do %>
|
||||
<i class="fas fa-clipboard-check"></i><%= t("dashboard.quick_start.new_report") %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
<div class="file-preview-container">
|
||||
<% if report_type == 'pdf' %>
|
||||
<%= render partial: 'shared/pdf_viewer.html.erb', locals: { asset: report.pdf_file, report_document: true } %>
|
||||
<% elsif report_type == 'docx' %>
|
||||
<%= render partial: 'shared/pdf_viewer.html.erb', locals: { asset: report.docx_preview_file, report_document: true } %>
|
||||
<% else %>
|
||||
<div>
|
||||
<i class="fas fa-10x fa-file-word"></i>
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<% if !defined? show_sort then show_sort = false end %>
|
||||
<% if !defined? show_move_up then show_move_up = true end %>
|
||||
<% if !defined? show_move_down then show_move_down = true end %>
|
||||
<% if !defined? show_remove then show_remove = true end %>
|
||||
|
||||
<%if show_sort %>
|
||||
<a href="" data-action="sort-asc" title="<%=t "projects.reports.elements.all.sort_asc" %>"><span class="fas fa-sort-by-attributes"></span></a>
|
||||
<a href="" data-action="sort-desc" title="<%=t "projects.reports.elements.all.sort_desc" %>"><span class="fas fa-sort-by-attributes-alt"></span></a>
|
||||
<% end %>
|
||||
<% if show_move_up %>
|
||||
<a href="" data-action="move-up" title="<%=t "projects.reports.elements.all.move_up" %>"><span class="fas fa-chevron-up"></span></a>
|
||||
<% end %>
|
||||
<% if show_move_down %>
|
||||
<a href="" data-action="move-down" title="<%=t "projects.reports.elements.all.move_down" %>"><span class="fas fa-chevron-down"></span></a>
|
||||
<% end %>
|
||||
<% if show_remove %>
|
||||
<a href="" data-action="remove" title="<%=t "projects.reports.elements.all.remove" %>"><span class="fas fa-times"></span></a>
|
||||
<% end %>
|
|
@ -1,22 +1,13 @@
|
|||
<% experiment ||= report_element.experiment %>
|
||||
<% timestamp = experiment.created_at %>
|
||||
<% name = experiment.name %>
|
||||
<% for_export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-experiment-element"
|
||||
data-ts="<%= timestamp.to_i %>"
|
||||
data-type="experiment"
|
||||
data-id='{ "experiment_id": <%= experiment.id %> }'
|
||||
data-scroll-id="<%= experiment.id %>"
|
||||
data-modal-title="<%=t "projects.reports.elements.modals.experiment_contents.head_title",
|
||||
experiment: experiment.name %>" data-name="<%= name %>" data-icon-class="fas fa-flask">
|
||||
<% export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-experiment-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left user-time">
|
||||
<%=t "projects.reports.elements.experiment.user_time", timestamp: l(timestamp, format: :full) %>
|
||||
<%= t('projects.reports.elements.experiment.user_time', timestamp: l(timestamp, format: :full)) %>
|
||||
<b><%= link_to t('projects.reports.elements.all.scinote_link'),canvas_experiment_url(experiment), target: :_blank %></b>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: "reports/elements/element_controls.html.erb", locals: { show_sort: true } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-element-body" data-hook="report-experiment-element">
|
||||
|
@ -24,9 +15,9 @@
|
|||
<div class="pull-left experiment-name">
|
||||
<h4>
|
||||
<i class="fas fa-flask"></i>
|
||||
<%= name %>
|
||||
<%= experiment.name %>
|
||||
<% if experiment.archived? %>
|
||||
<span class="label label-warning"><%=t 'search.index.archived' %></span>
|
||||
<span class="label label-warning"><%= t('search.index.archived') %></span>
|
||||
<% end %>
|
||||
</h4>
|
||||
</div>
|
||||
|
@ -34,9 +25,9 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<% if experiment.description.present? %>
|
||||
<%= custom_auto_link(experiment.description, team: current_team, base64_encoded_imgs: for_export_all) %>
|
||||
<%= custom_auto_link(experiment.description, team: current_team, base64_encoded_imgs: export_all) %>
|
||||
<% else %>
|
||||
<em><%=t "projects.reports.elements.experiment.no_description" %></em>
|
||||
<em><%= t('projects.reports.elements.experiment.no_description') %></em>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,45 +1,39 @@
|
|||
<% my_module ||= @my_module %>
|
||||
<% timestamp = Time.current + 1.year - 2.days %>
|
||||
<% my_module ||= report_element.my_module %>
|
||||
<% activities = ActivitiesService.my_module_activities(my_module).order(created_at: :desc) %>
|
||||
<div class="report-element report-module-activity-element" data-ts="<%= timestamp.to_i %>" data-type="my_module_activity" data-id='{ "my_module_id": <%= my_module.id %> }' data-scroll-id="<%= my_module.id %>" data-name="<%=t "projects.reports.elements.module_activity.sidebar_name" %>" data-icon-class="fas fa-list">
|
||||
<div class="report-element report-module-activity-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left activity-icon">
|
||||
<span class="fas fa-list"></span>
|
||||
</div>
|
||||
<div class="pull-left activity-name">
|
||||
<%=t "projects.reports.elements.module_activity.name", my_module: my_module.name %>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: "reports/elements/element_controls.html.erb", locals: { show_sort: true } %>
|
||||
<%= t('projects.reports.elements.module_activity.name', my_module: my_module.name) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-element-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 activity-container">
|
||||
<% if activities.any? %>
|
||||
<!-- TODO: This might become potentially very big! -->
|
||||
<% if activities.present? %>
|
||||
<ul class="no-style activity-list">
|
||||
<% activities.each do |activity| %>
|
||||
<% activity_ts = activity.created_at %>
|
||||
<li class="activity" data-ts="<%= activity_ts.to_i %>">
|
||||
<li class="activity">
|
||||
<span class="activity-prefix">
|
||||
<%=l activity_ts, format: :full %>
|
||||
<%= l(activity.created_at, format: :full) %>
|
||||
</span>
|
||||
<span class="activity-message">
|
||||
|
||||
<% if activity.old_activity? %>
|
||||
<%= sanitize_input(activity.message) %>
|
||||
<%= activity.message %>
|
||||
<% else %>
|
||||
<%= sanitize_input(generate_activity_content(activity, no_links: true)) %>
|
||||
<%= generate_activity_content(activity, no_links: true) %>
|
||||
<% end %>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>
|
||||
<em><%=t "projects.reports.elements.module_activity.no_activity" %></em>
|
||||
<em><%= t('projects.reports.elements.module_activity.no_activity') %></em>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
<% if my_module.blank? and @my_module.present? then my_module = @my_module end %>
|
||||
<% my_module ||= report_element.my_module %>
|
||||
<% timestamp = my_module.created_at %>
|
||||
<% name = my_module.name %>
|
||||
<% for_export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-module-element" data-ts="<%= timestamp.to_i %>" data-type="my_module" data-id='{ "my_module_id": <%= my_module.id %> }' data-scroll-id="<%= my_module.id %>" data-modal-title="<%=t "projects.reports.elements.modals.module_contents.head_title", module: my_module.name %>" data-name="<%= name %>" data-icon-class="fas fa-credit-card">
|
||||
<% export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-module-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left user-time">
|
||||
<%= t("projects.reports.elements.module.user_time", timestamp: l(timestamp, format: :full)) %>
|
||||
<%= t('projects.reports.elements.module.user_time', timestamp: l(timestamp, format: :full)) %>
|
||||
<b><%= link_to t('projects.reports.elements.all.scinote_link'), protocols_my_module_url(my_module), target: :_blank %></b>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: "reports/elements/element_controls.html.erb", locals: { show_sort: true } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-element-body">
|
||||
|
@ -19,9 +15,9 @@
|
|||
<div class="pull-left module-name">
|
||||
<h4>
|
||||
<span class="fas fa-credit-card"></span>
|
||||
<%= name %>
|
||||
<%= my_module.name %>
|
||||
<% if my_module.archived? %>
|
||||
<span class="label label-warning"><%=t 'search.index.archived' %></span>
|
||||
<span class="label label-warning"><%= t('search.index.archived') %></span>
|
||||
<% end %>
|
||||
</h4>
|
||||
</div>
|
||||
|
@ -30,32 +26,34 @@
|
|||
<% if my_module.started_on.present? %>
|
||||
<%= t('projects.reports.elements.module.started_on', started_on: l(my_module.started_on, format: :full)) %>
|
||||
<% else %>
|
||||
<em><%= t("projects.reports.elements.module.no_start_date") %></em>
|
||||
<em><%= t('projects.reports.elements.module.no_start_date') %></em>
|
||||
<% end %>
|
||||
</p>
|
||||
<p class="module-due-date">
|
||||
<% if my_module.due_date.present? %>
|
||||
<%= t("projects.reports.elements.module.due_date", due_date: l(my_module.due_date, format: :full)) %>
|
||||
<%= t('projects.reports.elements.module.due_date', due_date: l(my_module.due_date, format: :full)) %>
|
||||
<% else %>
|
||||
<em><%= t("projects.reports.elements.module.no_due_date") %></em>
|
||||
<em><%= t('projects.reports.elements.module.no_due_date') %></em>
|
||||
<% end %>
|
||||
</p>
|
||||
<p class="module-status">
|
||||
<% status = my_module.my_module_status %>
|
||||
<%= t("projects.reports.elements.module.status") %>
|
||||
<span class="status-block" style="background: <%= status.color %>"><%= status.name %></span>
|
||||
<%= t('projects.reports.elements.module.status') %>
|
||||
<span class="status-block" style="background: <%= status.color %>">
|
||||
<%= status.name %>
|
||||
</span>
|
||||
<% if my_module.completed? %>
|
||||
<span style="margin-left: 10px;">
|
||||
<%= t("my_modules.states.completed") %>
|
||||
<%= t('my_modules.states.completed') %>
|
||||
<%= l(my_module.completed_on, format: :full) %>
|
||||
</span>
|
||||
<% end %>
|
||||
</p>
|
||||
<div class="row module-tags">
|
||||
<div class="pull-left">
|
||||
<%= t("projects.reports.elements.module.tags_header") %>
|
||||
<%= t('projects.reports.elements.module.tags_header') %>
|
||||
</div>
|
||||
<% if my_module.tags.any? %>
|
||||
<% if my_module.tags.present? %>
|
||||
<% my_module.tags.each do |tag| %>
|
||||
<div class="pull-left module-tag" style="background-color: <%= tag.color %>;">
|
||||
<%= tag.name %>
|
||||
|
@ -63,19 +61,19 @@
|
|||
<% end %>
|
||||
<% else %>
|
||||
<div class="pull-left module-no-tag">
|
||||
<em><%= t("projects.reports.elements.module.no_tags") %></em>
|
||||
<em><%= t('projects.reports.elements.module.no_tags') %></em>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<% if my_module.description.present? %>
|
||||
<%= custom_auto_link(my_module.prepare_for_report(:description, for_export_all),
|
||||
<%= custom_auto_link(my_module.prepare_for_report(:description, export_all),
|
||||
team: current_team,
|
||||
simple_format: false,
|
||||
base64_encoded_imgs: for_export_all) %>
|
||||
base64_encoded_imgs: export_all) %>
|
||||
<% else %>
|
||||
<em><%= t("projects.reports.elements.module.no_description") %></em>
|
||||
<em><%= t('projects.reports.elements.module.no_description') %></em>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -86,16 +84,16 @@
|
|||
<% end %>
|
||||
|
||||
<% filter_steps_for_report(my_module.protocol.steps, @settings).order(:position).each do |step| %>
|
||||
<%= render partial: 'reports/elements/my_module_step_element.html.erb', locals: { step: step } %>
|
||||
<%= render partial: 'reports/elements/my_module_step_element.html.erb', locals: { step: step, export_all: export_all } %>
|
||||
<% end %>
|
||||
|
||||
<% order_results_for_report(my_module.results, @settings.dig('task', 'result_order')).each do |result| %>
|
||||
<% if result.is_asset && @settings.dig('task', 'file_results') %>
|
||||
<%= render partial: 'reports/elements/my_module_result_asset_element.html.erb', locals: { result: result, report: report } %>
|
||||
<%= render partial: 'reports/elements/my_module_result_asset_element.html.erb', locals: { result: result, report: report, export_all: export_all } %>
|
||||
<% elsif result.is_table && @settings.dig('task', 'table_results') %>
|
||||
<%= render partial: 'reports/elements/my_module_result_table_element.html.erb', locals: { result: result } %>
|
||||
<%= render partial: 'reports/elements/my_module_result_table_element.html.erb', locals: { result: result, export_all: export_all } %>
|
||||
<% elsif result.is_text && @settings.dig('task', 'text_results') %>
|
||||
<%= render partial: 'reports/elements/my_module_result_text_element.html.erb', locals: { result: result } %>
|
||||
<%= render partial: 'reports/elements/my_module_result_text_element.html.erb', locals: { result: result, export_all: export_all } %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
@ -108,7 +106,7 @@
|
|||
|
||||
<% if @settings.dig('task', 'activities') %>
|
||||
<div class="report-element-children">
|
||||
<%= render partial: 'reports/elements/my_module_activity_element.html.erb', locals: { my_module: my_module } %>
|
||||
<%= render partial: 'reports/elements/my_module_activity_element.html.erb', locals: { my_module: my_module, export_all: export_all } %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -1,24 +1,20 @@
|
|||
<% protocol ||= my_module.protocol %>
|
||||
<% my_module = protocol.my_module %>
|
||||
<% for_export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-module-protocol-element" data-ts="<%= protocol.created_at %>" data-type="my_module_protocol" data-id='{ "my_module_id": <%= my_module.id %> }' data-scroll-id="<%= protocol.id %>">
|
||||
<% protocol ||= report_element.my_module.protocol %>
|
||||
<% export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-module-protocol-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left user-time">
|
||||
<%=t "projects.reports.elements.module.protocol.user_time", timestamp: l(protocol.created_at, format: :full) %>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: "reports/elements/element_controls.html.erb", locals: { show_sort: true } %>
|
||||
<%= t('projects.reports.elements.module.protocol.user_time', timestamp: l(protocol.created_at, format: :full)) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-element-body">
|
||||
<div class="row module-protocol-description">
|
||||
<% if protocol.description.present? %>
|
||||
<%= custom_auto_link(protocol.prepare_for_report(:description, for_export_all),
|
||||
<%= custom_auto_link(protocol.prepare_for_report(:description, export_all),
|
||||
team: current_team,
|
||||
simple_format: false,
|
||||
base64_encoded_imgs: for_export_all) %>
|
||||
base64_encoded_imgs: export_all) %>
|
||||
<% else %>
|
||||
<em><%= t('my_modules.protocols.protocol_status_bar.no_description') %></em>
|
||||
<% end %>
|
||||
|
|
|
@ -1,55 +1,45 @@
|
|||
<% my_module ||= @my_module %>
|
||||
<% repository ||= nil %>
|
||||
<% element_id ||= repository&.id %>
|
||||
<% repository_snapshot ||= nil %>
|
||||
<% repository = assigned_repository_or_snapshot(my_module, element_id, repository, repository_snapshot) %>
|
||||
<% timestamp = Time.current + 1.year - 1.days %>
|
||||
<% rows_json = my_module.repository_json_hot(repository, :desc) %>
|
||||
<div class="report-element report-module-repository-element"
|
||||
data-sort-hot="1"
|
||||
data-ts="<%= timestamp.to_i %>"
|
||||
data-type="my_module_repository"
|
||||
data-id='{ "my_module_id": <%= my_module.id %>, "repository_id": <%= repository.id %> }'
|
||||
data-scroll-id="<%= "#{my_module.id}_#{repository.id}" %>"
|
||||
data-name="<%= repository.name %>"
|
||||
data-icon-class="fas fa-list-alt">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left repository-icon">
|
||||
<i class="fas fa-list-alt"></i>
|
||||
</div>
|
||||
<div class="pull-left repository-name">
|
||||
<%= t('projects.reports.elements.module_repository.name', repository: repository.name, my_module: my_module.name) %>
|
||||
<i><%= t('projects.reports.index.deleted') if repository.is_a?(RepositorySnapshot) && !repository.original_repository %></i>
|
||||
</div>
|
||||
<% if defined?(export_all) && export_all %>
|
||||
<div class="pull-left table-name">
|
||||
<a href="<%= path[:file] %>">
|
||||
<em><%= t('projects.reports.elements.module_repository.table_name', name: filename) %></em>
|
||||
</a>
|
||||
<% my_module ||= report_element.my_module %>
|
||||
<% repository ||= report_element.repository %>
|
||||
<% repository = assigned_repository_or_snapshot(my_module, repository) %>
|
||||
<% if repository %>
|
||||
<% rows_json = my_module.repository_json_hot(repository, :desc) %>
|
||||
<div class="report-element report-module-repository-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left repository-icon">
|
||||
<i class="fas fa-list-alt"></i>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: "reports/elements/element_controls.html.erb", locals: { show_sort: true } %>
|
||||
<div class="pull-left repository-name">
|
||||
<%= t('projects.reports.elements.module_repository.name', repository: repository.name, my_module: my_module.name) %>
|
||||
<i><%= t('projects.reports.index.deleted') if repository.is_a?(RepositorySnapshot) && !repository.original_repository %></i>
|
||||
</div>
|
||||
<% if defined?(export_all) && export_all %>
|
||||
<div class="pull-left table-name">
|
||||
<% file_link = @obj_filenames.dig(:repositories, repository.id, :file) %>
|
||||
<a href="<%= file_link %>">
|
||||
<em><%= t('projects.reports.elements.module_repository.table_name', name: file_link&.split('/')&.last) %></em>
|
||||
</a>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-element-body">
|
||||
<% if rows_json[:data].count > 0 %>
|
||||
<input type="hidden" class="hot-table-contents hot-repository-items" value='<%= rows_json.to_json.force_encoding(Encoding::UTF_8) %>' />
|
||||
<div class="hot-table-container"></div>
|
||||
<table class="report-common-table-format"></table>
|
||||
<% else %>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<em><%= t('projects.reports.elements.module_repository.no_items') %></em>
|
||||
<div class="report-element-body">
|
||||
<% if rows_json[:data].count > 0 %>
|
||||
<input type="hidden" class="hot-table-contents hot-repository-items" value='<%= rows_json.to_json.force_encoding(Encoding::UTF_8) %>' />
|
||||
<div class="hot-table-container"></div>
|
||||
<table class="report-common-table-format"></table>
|
||||
<% else %>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<em><%= t('projects.reports.elements.module_repository.no_items') %></em>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if defined?(children) %>
|
||||
<div class="report-element-children">
|
||||
<%= children %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if defined?(children) %>
|
||||
<div class="report-element-children">
|
||||
<%= children %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -1,16 +1,7 @@
|
|||
<% result ||= @result %>
|
||||
<% result ||= report_element.result %>
|
||||
<% asset = result.asset %>
|
||||
<% comments = result.result_comments %>
|
||||
<% timestamp = asset.created_at %>
|
||||
<% icon_class = 'fas ' + file_fa_icon_class(asset) if asset.file_name %>
|
||||
<div class="report-element report-result-element report-result-asset-element"
|
||||
data-ts="<%= timestamp.to_i %>"
|
||||
data-type="result_asset"
|
||||
data-id='{ "result_id": <%= result.id %> }'
|
||||
data-scroll-id="<%= result.id %>"
|
||||
data-modal-title="<%= t("projects.reports.elements.modals.result_contents.head_title", result: result.name) %>"
|
||||
data-name="<%= result.name %>"
|
||||
data-icon-class="<%= icon_class %>">
|
||||
<div class="report-element report-result-element report-result-asset-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left result-icon">
|
||||
|
@ -24,8 +15,9 @@
|
|||
</div>
|
||||
<div class="pull-left file-name">
|
||||
<% if defined? export_all and export_all %>
|
||||
<a href="<%= path[:file] %>">
|
||||
<em><%= t("projects.reports.elements.result_asset.file_name", file: filename) %></em>
|
||||
<% file_link = @obj_filenames.dig(:assets, asset.id, :file) %>
|
||||
<a href="<%= file_link %>">
|
||||
<em><%= t("projects.reports.elements.result_asset.file_name", file: file_link&.split('/')&.last) %></em>
|
||||
</a>
|
||||
<% else %>
|
||||
<em>
|
||||
|
@ -41,9 +33,6 @@
|
|||
<%= t('projects.reports.elements.result_asset.full_preview_attached') %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: "reports/elements/element_controls.html.erb" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row"></div>
|
||||
|
@ -52,7 +41,7 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12 file-image">
|
||||
<% if defined?(export_all) && export_all %>
|
||||
<img class="report-export-img" src="<%= path[:preview] %>">
|
||||
<img class="report-export-img" src="<%= @obj_filenames.dig(:assets, asset.id, :preview) %>">
|
||||
<% else %>
|
||||
<%= report_image_asset_url(asset) %>
|
||||
<% end %>
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
<% result ||= @result %>
|
||||
<% result ||= report_element.result %>
|
||||
<% table = result.table %>
|
||||
<% comments = result.result_comments %>
|
||||
<% timestamp = table.created_at %>
|
||||
<div class="report-element report-result-element report-result-table-element" data-ts="<%= timestamp.to_i %>" data-type="result_table" data-id='{ "result_id": <%= result.id %> }' data-scroll-id="<%= result.id %>" data-modal-title="<%=t "projects.reports.elements.modals.result_contents.head_title", result: result.name %>" data-name="<%= result.name %>" data-icon-class="fas fa-table">
|
||||
<div class="report-element report-result-element report-result-table-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left result-name-container">
|
||||
|
@ -12,23 +11,19 @@
|
|||
<div class="pull-left result-name">
|
||||
<%= result.name %>
|
||||
<% if result.archived? %>
|
||||
<span class="label label-warning"><%=t 'search.index.archived' %></span>
|
||||
<span class="label label-warning"><%= t('search.index.archived') %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if defined? export_all and export_all %>
|
||||
<div class="pull-left table-name">
|
||||
<a href="<%= path[:file] %>">
|
||||
<em><%=t "projects.reports.elements.result_table.table_name",
|
||||
name: filename %></em>
|
||||
|
||||
</a>
|
||||
<% file_link = @obj_filenames.dig(:tables, table.id, :file) %>
|
||||
<a href="<%= file_link %>">
|
||||
<em><%=t "projects.reports.elements.result_table.table_name", name: file_link&.split('/')&.last %></em>
|
||||
</a>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="pull-left user-time">
|
||||
<%=t "projects.reports.elements.result_table.user_time", user: result.user.full_name , timestamp: l(timestamp, format: :full) %>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: "reports/elements/element_controls.html.erb" %>
|
||||
<%= t('projects.reports.elements.result_table.user_time', user: result.user.full_name , timestamp: l(timestamp, format: :full)) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
<% if result.blank? and @result.present? then result = @result end %>
|
||||
<% result ||= report_element.result %>
|
||||
<% result_text = result.result_text %>
|
||||
<% comments = result.result_comments %>
|
||||
<% timestamp = result.created_at %>
|
||||
<% name = result.name %>
|
||||
<% for_export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-result-element report-result-text-element" data-ts="<%= timestamp.to_i %>" data-type="result_text" data-id='{ "result_id": <%= result.id %> }' data-scroll-id="<%= result.id %>" data-modal-title="<%=t "projects.reports.elements.modals.result_contents.head_title", result: result.name %>" data-name="<%= name %>" data-icon-class="fas fa-asterisk">
|
||||
<% export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-result-element report-result-text-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left result-icon">
|
||||
|
@ -13,25 +12,22 @@
|
|||
<div class="pull-left result-name">
|
||||
<%= name %>
|
||||
<% if result.archived? %>
|
||||
<span class="label label-warning"><%=t 'search.index.archived' %></span>
|
||||
<span class="label label-warning"><%= t('search.index.archived') %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="pull-left user-time">
|
||||
<%=t "projects.reports.elements.result_text.user_time", user: result.user.full_name, timestamp: l(timestamp, format: :full) %>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: "reports/elements/element_controls.html.erb" %>
|
||||
<%= t('projects.reports.elements.result_text.user_time', user: result.user.full_name, timestamp: l(timestamp, format: :full)) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-element-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 text-container ql-editor">
|
||||
<%= custom_auto_link(result_text.prepare_for_report(:text, for_export_all),
|
||||
<%= custom_auto_link(result_text.prepare_for_report(:text, export_all),
|
||||
team: current_team,
|
||||
simple_format: false,
|
||||
tags: %w(img),
|
||||
base64_encoded_imgs: for_export_all) %>
|
||||
base64_encoded_imgs: export_all) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,26 +1,16 @@
|
|||
<% step ||= @step %>
|
||||
<% step ||= report_element.step %>
|
||||
<% step_type_str = step.completed ? 'completed' : 'uncompleted' %>
|
||||
<% user = step.completed? ? step.last_modified_by : step.user %>
|
||||
<% timestamp = step.completed ? step.completed_on : step.created_at %>
|
||||
<% tables = step.tables %>
|
||||
<% assets = step.assets %>
|
||||
<% checklists = step.checklists %>
|
||||
<% for_export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-step-element"
|
||||
data-ts="<%= timestamp.to_i %>"
|
||||
data-type="step"
|
||||
data-id='{ "step_id": <%= step.id %> }'
|
||||
data-scroll-id="<%= step.id %>"
|
||||
data-modal-title="<%=t "projects.reports.elements.modals.step_contents.head_title", step: step.name %>"
|
||||
data-name="<%=t "projects.reports.elements.step.sidebar_name", pos: (step.position_plus_one), name: step.name %>"
|
||||
data-icon-class="fas fa-arrow-circle-right">
|
||||
<% export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-step-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left user-time">
|
||||
<%=t "projects.reports.elements.step.#{step_type_str}.user_time", user: user.full_name , timestamp: l(timestamp, format: :full) %>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: "reports/elements/element_controls.html.erb", locals: { show_sort: true } %>
|
||||
<%= t("projects.reports.elements.step.#{step_type_str}.user_time", user: user.full_name , timestamp: l(timestamp, format: :full)) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -29,7 +19,7 @@
|
|||
<div class="pull-left step-name">
|
||||
<h5>
|
||||
<span class="fas fa-arrow-circle-right"></span>
|
||||
<b><%=t "projects.reports.elements.step.step_pos", pos: (step.position_plus_one) %></b> <%= step.name %>
|
||||
<b><%= t('projects.reports.elements.step.step_pos', pos: (step.position_plus_one)) %></b> <%= step.name %>
|
||||
<%= step_status_label(step) %>
|
||||
</h5>
|
||||
</div>
|
||||
|
@ -37,13 +27,13 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12 ql-editor">
|
||||
<% if step.description.present? %>
|
||||
<%= custom_auto_link(step.prepare_for_report(:description, for_export_all),
|
||||
<%= custom_auto_link(step.prepare_for_report(:description, export_all),
|
||||
team: current_team,
|
||||
simple_format: false,
|
||||
tags: %w(img),
|
||||
base64_encoded_imgs: for_export_all) %>
|
||||
base64_encoded_imgs: export_all) %>
|
||||
<% else %>
|
||||
<em><%=t "projects.reports.elements.step.no_description" %></em>
|
||||
<em><%= t('projects.reports.elements.step.no_description') %></em>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -51,21 +41,21 @@
|
|||
<div class="report-element-children">
|
||||
<% if @settings.dig('task', 'protocol', 'step_tables') %>
|
||||
<% tables.each do |table| %>
|
||||
<%= render partial: 'reports/elements/step_table_element.html.erb', locals: { table: table } %>
|
||||
<%= render partial: 'reports/elements/step_table_element.html.erb', locals: { table: table, export_all: export_all } %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if @settings.dig('task', 'protocol', 'step_files') %>
|
||||
<% assets.each do |asset| %>
|
||||
<%= render partial: 'reports/elements/step_asset_element.html.erb', locals: { asset: asset } %>
|
||||
<%= render partial: 'reports/elements/step_asset_element.html.erb', locals: { asset: asset, export_all: export_all } %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if @settings.dig('task', 'protocol', 'step_checklists') %>
|
||||
<% checklists.each do |checklist| %>
|
||||
<%= render partial: 'reports/elements/step_checklist_element.html.erb', locals: { checklist: checklist } %>
|
||||
<%= render partial: 'reports/elements/step_checklist_element.html.erb', locals: { checklist: checklist, export_all: export_all } %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if @settings.dig('task', 'protocol', 'step_comments') %>
|
||||
<%= render partial: 'reports/elements/step_comments_element.html.erb', locals: { step: step } %>
|
||||
<%= render partial: 'reports/elements/step_comments_element.html.erb', locals: { step: step, export_all: export_all } %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if defined?(children) %>
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
<% if !defined? hide then hide = false end %>
|
||||
<% if !defined? initial then initial = false end %>
|
||||
<div class="new-element <%= "hidden" if hide %> <%= "initial" if initial %>" data-ts="ignore" data-type="new" title="<%=t "projects.reports.elements.new_element.title" %>">
|
||||
<a href="" class="new-element-href" data-action="add-new-elements">
|
||||
<div class="line left-line">
|
||||
<div class="filler-wrapper">
|
||||
<div class="filler"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="plus-icon">
|
||||
<span class="fas fa-plus"></span>
|
||||
</div>
|
||||
<div class="line right-line">
|
||||
<div class="filler-wrapper">
|
||||
<div class="filler"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</a>
|
||||
</div>
|
|
@ -1,10 +1,9 @@
|
|||
<% if project.blank? and @project.present? then project = @project end %>
|
||||
<% name = t("projects.reports.elements.project_header.title", project: project.name) %>
|
||||
<div class="report-element report-project-header-element" data-ts="ignore" data-type="project_header" data-id='{ "project_id": <%= project.id %> }' data-scroll-id="<%= project.id %>" data-name="<%= name %>" data-icon-class="fas fa-heading">
|
||||
<% project ||= report_element.project %>
|
||||
<div class="report-element report-project-header-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left user-time">
|
||||
<%=t "projects.reports.elements.project_header.user_time", timestamp: l(project.created_at, format: :full) %>
|
||||
<%= t('projects.reports.elements.project_header.user_time', timestamp: l(project.created_at, format: :full)) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -12,9 +11,9 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12 project-name">
|
||||
<h2>
|
||||
<%= name %>
|
||||
<%= t('projects.reports.elements.project_header.title', project: project.name) %>
|
||||
<% if project.archived? %>
|
||||
<span class="label label-warning"><%=t 'search.index.archived' %></span>
|
||||
<span class="label label-warning"><%= t('search.index.archived') %></span>
|
||||
<% end %>
|
||||
</h2>
|
||||
</div>
|
||||
|
|
|
@ -1,33 +1,29 @@
|
|||
<% result ||= @result %>
|
||||
<% result ||= report_element.result %>
|
||||
<% comments = result.result_comments.order(created_at: :desc) %>
|
||||
<% timestamp = Time.current + 1.year %>
|
||||
<% for_export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-comments-element report-result-comments-element" data-ts="<%= timestamp.to_i %>" data-type="result_comments" data-id='{ "result_id": <%= result.id %> }' data-scroll-id="<%= result.id %>" data-name="<%=t "projects.reports.elements.result_comments.sidebar_name" %>" data-icon-class="fas fa-comment">
|
||||
<% export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-comments-element report-result-comments-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left comments-icon">
|
||||
<span class="fas fa-comment"></span>
|
||||
</div>
|
||||
<div class="pull-left comments-name">
|
||||
<%=t "projects.reports.elements.result_comments.name", result: result.name %>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: "reports/elements/element_controls.html.erb", locals: { show_sort: true, show_move_up: false, show_move_down: false } %>
|
||||
<%= t('projects.reports.elements.result_comments.name', result: result.name) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-element-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 comments-container simple">
|
||||
<% if comments.any? %>
|
||||
<% if comments.present? %>
|
||||
<ul class="no-style content-comments">
|
||||
<% comments.each do |comment| %>
|
||||
<%= render partial: 'shared/comments/item.html.erb',
|
||||
locals: { comment: comment, readonly: true, report: true, export_all: for_export_all } %>
|
||||
locals: { comment: comment, readonly: true, report: true, export_all: export_all } %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>
|
||||
<em><%=t "projects.reports.elements.result_comments.no_comments" %></em>
|
||||
<em><%= t('projects.reports.elements.result_comments.no_comments') %></em>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<% asset ||= @asset %>
|
||||
<% asset ||= report_element.asset %>
|
||||
<% timestamp = asset.created_at %>
|
||||
<% icon_class = file_fa_icon_class(asset) if asset.file_name %>
|
||||
<div class="report-element report-step-attachment-element report-step-asset-element" data-ts="<%= timestamp.to_i %>" data-type="step_asset" data-id='{ "asset_id": <%= asset.id %> }' data-scroll-id="<%= asset.id %>" data-name="<%=t "projects.reports.elements.step_asset.sidebar_name", file: asset.file_name %>" data-icon-class="<%= icon_class %>">
|
||||
<div class="report-element report-step-attachment-element report-step-asset-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left attachment-icon <%= defined?(export_all) && export_all ? 'export-all-icons' : '' %>">
|
||||
|
@ -9,8 +8,9 @@
|
|||
</div>
|
||||
<div class="pull-left file-name">
|
||||
<% if defined? export_all and export_all %>
|
||||
<a href="<%= path[:file] %>">
|
||||
<em><%= t('projects.reports.elements.step_asset.file_name', file: filename) %></em>
|
||||
<% file_link = @obj_filenames.dig(:assets, asset.id, :file) %>
|
||||
<a href="<%= file_link %>">
|
||||
<em><%= t('projects.reports.elements.step_asset.file_name', file: file_link&.split('/')&.last) %></em>
|
||||
</a>
|
||||
<% else %>
|
||||
<em>
|
||||
|
@ -18,14 +18,10 @@
|
|||
file: truncate(asset.file_name, length: Constants::FILENAME_TRUNCATION_LENGTH)) %>
|
||||
<%= link_to t('projects.reports.elements.download'), asset_download_url(asset, disposition: 'attachment'), class: 'download-link', target: :_blank %>
|
||||
</em>
|
||||
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="pull-left user-time">
|
||||
<%=t 'projects.reports.elements.step_asset.user_time', timestamp: l(timestamp, format: :full) %>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: 'reports/elements/element_controls.html.erb' %>
|
||||
<%= t('projects.reports.elements.step_asset.user_time', timestamp: l(timestamp, format: :full)) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -34,7 +30,7 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12 file-image">
|
||||
<% if defined?(export_all) && export_all %>
|
||||
<img class="report-export-img" src="<%= path[:preview] %>">
|
||||
<img class="report-export-img" src="<%= @obj_filenames.dig(:assets, asset.id, :preview) %>">
|
||||
<% else %>
|
||||
<%= report_image_asset_url(asset) %>
|
||||
<% end %>
|
||||
|
|
|
@ -1,24 +1,21 @@
|
|||
<% if checklist.blank? and @checklist.present? then checklist = @checklist end %>
|
||||
<% checklist ||= report_element.checklist %>
|
||||
<% items = checklist.checklist_items %>
|
||||
<% timestamp = checklist.created_at %>
|
||||
<% for_export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-step-attachment-element report-step-checklist-element" data-ts="<%= timestamp.to_i %>" data-type="step_checklist" data-id='{ "checklist_id": <%= checklist.id %> }' data-scroll-id="<%= checklist.id %>" data-name="<%= checklist.name %>" data-icon-class="fas fa-tasks">
|
||||
<% export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-step-attachment-element report-step-checklist-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left attachment-icon">
|
||||
<span class="fas fa-tasks"></span>
|
||||
<span class="fas fa-tasks"></span>
|
||||
</div>
|
||||
<div class="pull-left checklist-name">
|
||||
<%= custom_auto_link(t('projects.reports.elements.step_checklist.checklist_name',
|
||||
name: checklist.name),
|
||||
team: current_team,
|
||||
base64_encoded_imgs: for_export_all) %>
|
||||
name: checklist.name),
|
||||
team: current_team,
|
||||
base64_encoded_imgs: export_all) %>
|
||||
</div>
|
||||
<div class="pull-left user-time">
|
||||
<%=t 'projects.reports.elements.step_checklist.user_time', timestamp: l(timestamp, format: :full) %>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: 'reports/elements/element_controls.html.erb' %>
|
||||
<%= t('projects.reports.elements.step_checklist.user_time', timestamp: l(timestamp, format: :full)) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -32,7 +29,7 @@
|
|||
team: current_team,
|
||||
simple_format: true,
|
||||
wrapper_tag: { wrapper_tag: 'span'},
|
||||
base64_encoded_imgs: for_export_all) %>
|
||||
base64_encoded_imgs: export_all) %>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
|
|
|
@ -1,33 +1,29 @@
|
|||
<% if step.blank? and @step.present? then step = @step end %>
|
||||
<% step ||= report_element.step %>
|
||||
<% comments = step.step_comments.order(created_at: :desc) %>
|
||||
<% timestamp = Time.current + 1.year %>
|
||||
<% for_export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-comments-element report-step-comments-element" data-ts="<%= timestamp.to_i %>" data-order="asc" data-type="step_comments" data-id='{ "step_id": <%= step.id %> }' data-scroll-id="<%= step.id %>" data-name="<%=t "projects.reports.elements.step_comments.sidebar_name" %>" data-icon-class="fas fa-comment">
|
||||
<% export_all = defined?(export_all) && export_all %>
|
||||
<div class="report-element report-comments-element report-step-comments-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left comments-icon">
|
||||
<span class="fas fa-comment"></span>
|
||||
</div>
|
||||
<div class="pull-left comments-name">
|
||||
<%=t "projects.reports.elements.step_comments.name", step: step.name %>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: "reports/elements/element_controls.html.erb", locals: { show_sort: true } %>
|
||||
<%= t('projects.reports.elements.step_comments.name', step: step.name) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-element-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 comments-container simple">
|
||||
<% if comments.any? %>
|
||||
<% if comments.present? %>
|
||||
<ul class="no-style content-comments">
|
||||
<% comments.each do |comment| %>
|
||||
<%= render partial: 'shared/comments/item.html.erb',
|
||||
locals: { comment: comment, readonly: true, report: true, export_all: for_export_all } %>
|
||||
locals: { comment: comment, readonly: true, report: true, export_all: export_all } %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>
|
||||
<em><%=t "projects.reports.elements.step_comments.no_comments" %></em>
|
||||
<em><%= t('projects.reports.elements.step_comments.no_comments') %></em>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,30 +1,29 @@
|
|||
<% table ||= @table %>
|
||||
<% table ||= report_element.table %>
|
||||
<% timestamp = table.created_at %>
|
||||
<div class="report-element report-step-attachment-element report-step-table-element" data-ts="<%= timestamp.to_i %>" data-type="step_table" data-id='{ "table_id": <%= table.id %> }' data-scroll-id="<%= table.id %>" data-name="<%= table.name %>" data-icon-class="fas fa-table">
|
||||
<div class="report-element report-step-attachment-element report-step-table-element">
|
||||
<div class="report-element-header">
|
||||
<div class="row">
|
||||
<div class="pull-left attachment-icon">
|
||||
<span class="fas fa-table"></span>
|
||||
<span class="fas fa-table"></span>
|
||||
</div>
|
||||
<div class="pull-left table-name">
|
||||
<% if defined? export_all and export_all %>
|
||||
<a href="<%= path[:file] %>">
|
||||
<em><%=t 'projects.reports.elements.step_table.table_name',
|
||||
name: filename %></em>
|
||||
<% file_link = @obj_filenames.dig(:tables, table.id, :file) %>
|
||||
<a href="<%= file_link %>">
|
||||
<em>
|
||||
<%= t('projects.reports.elements.step_table.table_name', name: file_link&.split('/')&.last) %>
|
||||
</em>
|
||||
</a>
|
||||
<% else %>
|
||||
<% if table.try(:name) %>
|
||||
<em><%=t 'projects.reports.elements.step_table.table_name',
|
||||
name: truncate(table.name,
|
||||
length: Constants::FILENAME_TRUNCATION_LENGTH) %></em>
|
||||
<em>
|
||||
<%= t('projects.reports.elements.step_table.table_name', name: truncate(table.name, length: Constants::FILENAME_TRUNCATION_LENGTH)) %>
|
||||
</em>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="pull-left user-time">
|
||||
<%=t 'projects.reports.elements.step_table.user_time', timestamp: l(timestamp, format: :full) %>
|
||||
</div>
|
||||
<div class="pull-right controls">
|
||||
<%= render partial: 'reports/elements/element_controls.html.erb' %>
|
||||
<%= t('projects.reports.elements.step_table.user_time', timestamp: l(timestamp, format: :full)) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
20
app/views/reports/export.html.erb
Normal file
20
app/views/reports/export.html.erb
Normal file
|
@ -0,0 +1,20 @@
|
|||
<div class="content-pane" id="report-new">
|
||||
<div class="report-container">
|
||||
<!-- Report "preview" -->
|
||||
<div id="report-content">
|
||||
|
||||
<% report.root_elements.each do |el| %>
|
||||
<%= render_report_element(el, local_assigns) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<%= javascript_include_tag "handsontable.full" %>
|
||||
|
||||
<!-- Libraries for formulas -->
|
||||
<%= render partial: "shared/formulas_libraries.html.erb" %>
|
||||
|
||||
<%= javascript_include_tag("reports/new") %>
|
||||
<%= javascript_include_tag 'reports/save_pdf_to_inventory' %>
|
|
@ -46,7 +46,7 @@
|
|||
<%= t("projects.reports.wizard.statuses.step_#{i + 1}") %>
|
||||
</span>
|
||||
</div>
|
||||
<% if @edit %>
|
||||
<% if @edit && @report.settings["template"].present? %>
|
||||
<div class="change-step" data-step-id="<%= i + 1 %>">
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
<div class="navbar-report">
|
||||
<div class="center-block" id="report-menu">
|
||||
|
||||
<div class="dropdown" id="sort-report">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<span class="fas fa-sort visible-xs-inline"></span>
|
||||
<span class="hidden-xs"><%= t'projects.reports.new.nav_sort_by' %></span>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
<li><a href="#" data-sort="desc" data-turbolinks="false"><%= t('projects.reports.new.nav_sort_desc') %></a></li>
|
||||
<li><a href="#" data-sort="asc" data-turbolinks="false"><%= t('projects.reports.new.nav_sort_asc') %></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<%= link_to "", class: "btn btn-secondary", remote: true, id: "print-report" do %>
|
||||
<span class="fas fa-print"></span>
|
||||
<span class="hidden-xs"><%=t "projects.reports.new.nav_print" %></span>
|
||||
<% end %>
|
||||
|
||||
|
||||
<div class="dropdown" id="download-report">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<span class="fas fa-download"></span>
|
||||
<span class="hidden-xs"><%= t("projects.reports.new.nav_download") %><span>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onclick="$('#savePDFtoInventory').modal('show')"
|
||||
class="btn btn-secondary">
|
||||
<span class="fas fa-save">
|
||||
</span>
|
||||
<%=t 'projects.reports.new.save_PDF_to_inventory'%>
|
||||
</button>
|
||||
|
||||
<div class="pull-right">
|
||||
<%= link_to reports_path, data: { no_turbolink: false }, id: "cancel-report-link", class: "btn btn-secondary" do %>
|
||||
<span class="hidden-xs"><%=t "projects.reports.new.nav_close" %></span>
|
||||
<% end %>
|
||||
<%= link_to "", class: "btn btn-primary", remote: true, id: "save-report-link" do %>
|
||||
<span class="hidden-xs"><%=t "projects.reports.new.nav_save" %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -1,36 +0,0 @@
|
|||
<%= bootstrap_form_tag remote: true, url: experiment_contents_project_reports_path(project, format: :json), method: :post, html: { id: "add-contents-form" } do |f| %>
|
||||
<%= hidden_field_tag :id, experiment.id %>
|
||||
<div>
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active">
|
||||
<a href="#tasks-tab" aria-controls="tasks-tab" role="tab" data-toggle="tab">
|
||||
<span class="fas fa-credit-card visible-xs"></span>
|
||||
<span class="hidden-xs"><%= t("projects.reports.elements.modals.project_contents.tasks_tab") %></span>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="#content-tab" aria-controls="content-tab" role="tab" data-toggle="tab">
|
||||
<span class="fas fa-link visible-xs"></span>
|
||||
<span class="hidden-xs"><%= t("projects.reports.elements.modals.project_contents.content_tab") %></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="tasks-tab">
|
||||
<h5 class="visible-xs"><%= t("projects.reports.elements.modals.project_contents.tasks_tab") %></h5>
|
||||
<%= render partial: "reports/new/modal/experiment_contents_inner.html.erb", locals: { form: f, experiment: experiment } %>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="content-tab">
|
||||
<h5 class="visible-xs"><%= t("projects.reports.elements.modals.project_contents.content_tab") %></h5>
|
||||
<%= render partial: "reports/new/modal/module_contents_inner.html.erb", locals: { form: f } %>
|
||||
<hr>
|
||||
<%= render partial: "reports/new/modal/step_contents_inner.html.erb", locals: { form: f } %>
|
||||
<hr>
|
||||
<%= render partial: "reports/new/modal/result_contents_inner.html.erb", locals: { form: f } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
|
@ -1,41 +0,0 @@
|
|||
<div>
|
||||
<em>
|
||||
<%= t("projects.reports.elements.modals.experiment_contents_inner.instructions") %>
|
||||
</em>
|
||||
</div>
|
||||
|
||||
<% if experiment.my_modules.exists? %>
|
||||
<div class="checkbox-tree">
|
||||
<ul>
|
||||
<li>
|
||||
<%= form.check_box :experiment_all, label: experiment.name %>
|
||||
<ul>
|
||||
|
||||
<% experiment.my_module_groups.each do |my_module_group| %>
|
||||
<% if my_module_group.my_modules.exists? then %>
|
||||
<% my_module_group.my_modules.workflow_ordered.each do |my_module| %>
|
||||
<li>
|
||||
<%= form.check_box "modules[#{my_module.id}]", label: my_module.name %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<!-- Tasks without groups -->
|
||||
<% experiment.my_modules.without_group.each do |my_module| %>
|
||||
<li>
|
||||
<%= form.check_box "modules[#{my_module.id}]", label: my_module.name %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<% else %>
|
||||
<div>
|
||||
<em>
|
||||
<%= t("projects.reports.elements.modals.experiment_contents_inner.no_modules") %>
|
||||
</em>
|
||||
</div>
|
||||
<% end %>
|
|
@ -1,26 +0,0 @@
|
|||
<%= bootstrap_form_tag remote: true, url: module_contents_project_reports_path(project, format: :json), method: :post, html: { id: "add-contents-form" } do |f| %>
|
||||
<%= hidden_field_tag :id, my_module.id %>
|
||||
<div>
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active">
|
||||
<a href="#content-tab" aria-controls="content-tab" role="tab" data-toggle="tab">
|
||||
<span class="fas fa-link visible-xs"></span>
|
||||
<span class="hidden-xs"><%= t("projects.reports.elements.modals.project_contents.content_tab") %></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="content-tab">
|
||||
<h5 class="visible-xs"><%= t("projects.reports.elements.modals.project_contents.content_tab") %></h5>
|
||||
<%= render partial: "reports/new/modal/module_contents_inner.html.erb", locals: { form: f } %>
|
||||
<hr>
|
||||
<%= render partial: "reports/new/modal/step_contents_inner.html.erb", locals: { form: f } %>
|
||||
<hr>
|
||||
<%= render partial: "reports/new/modal/result_contents_inner.html.erb", locals: { form: f } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
|
@ -1,79 +0,0 @@
|
|||
<% my_module_undefined = !defined? my_module or my_module.blank? %>
|
||||
<div>
|
||||
<em>
|
||||
<%= t("projects.reports.elements.modals.module_contents_inner.instructions") %>
|
||||
</em>
|
||||
</div>
|
||||
|
||||
<div class="checkbox-tree">
|
||||
<ul data-hook="module-content-list">
|
||||
<li>
|
||||
<%= form.check_box :module_all, label: t("projects.reports.elements.modals.module_contents_inner.check_all") %>
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<%= form.check_box :module_protocol, label: t("projects.reports.elements.modals.module_contents_inner.protocol") %>
|
||||
</li>
|
||||
|
||||
<% if my_module_undefined or my_module.protocol.steps.exists? %>
|
||||
<li>
|
||||
<%= form.check_box :module_steps, label: t("projects.reports.elements.modals.module_contents_inner.steps") %>
|
||||
<ul>
|
||||
<li>
|
||||
<%= form.check_box :module_completed_steps, label: t("projects.reports.elements.modals.module_contents_inner.completed_steps") %>
|
||||
</li>
|
||||
<li>
|
||||
<%= form.check_box :module_uncompleted_steps, label: t("projects.reports.elements.modals.module_contents_inner.uncompleted_steps") %>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<% else %>
|
||||
<div>
|
||||
<em>
|
||||
<%= t("projects.reports.elements.modals.module_contents_inner.no_steps") %>
|
||||
</em>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if my_module_undefined or (my_module.results.select { |r| r.active? }).exists? %>
|
||||
<li>
|
||||
<%= form.check_box :module_results, label: t("projects.reports.elements.modals.module_contents_inner.results") %>
|
||||
<ul data-hook="result-types-list">
|
||||
<% if my_module_undefined or (my_module.results.select { |r| r.is_asset && r.active? }).exists? %>
|
||||
<li>
|
||||
<%= form.check_box :module_result_assets, label: t("projects.reports.elements.modals.module_contents_inner.result_assets") %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if my_module_undefined or (my_module.results.select { |r| r.is_table && r.active? }).exists? %>
|
||||
<li>
|
||||
<%= form.check_box :module_result_tables, label: t("projects.reports.elements.modals.module_contents_inner.result_tables") %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if my_module_undefined or (my_module.results.select { |r| r.is_text && r.active? }).exists? %>
|
||||
<li>
|
||||
<%= form.check_box :module_result_texts, label: t("projects.reports.elements.modals.module_contents_inner.result_texts") %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
<% else %>
|
||||
<div>
|
||||
<em>
|
||||
<%= t("projects.reports.elements.modals.module_contents_inner.no_results") %>
|
||||
</em>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<li>
|
||||
<%= form.check_box :module_activity, label: t("projects.reports.elements.modals.module_contents_inner.activity") %>
|
||||
</li>
|
||||
<% assigned_repositories_in_project_list(@project).each do |repository| %>
|
||||
<li>
|
||||
<%= form.check_box "module_repository_#{repository.id}", label: repository.name.capitalize, data: { id: repository.id } %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
|
@ -1,38 +0,0 @@
|
|||
<%= bootstrap_form_tag remote: true, url: project_contents_project_reports_path(project, format: :json), method: :post, html: { id: "add-contents-form" } do |f| %>
|
||||
<%= hidden_field_tag :id, project.id %>
|
||||
<div>
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active">
|
||||
<a href="#tasks-tab" aria-controls="tasks-tab" role="tab" data-toggle="tab">
|
||||
<span class="fas fa-credit-card visible-xs"></span>
|
||||
<span class="hidden-xs"><%= t("projects.reports.elements.modals.project_contents.tasks_tab") %></span>
|
||||
</a>
|
||||
</li>
|
||||
<% if project.project_my_modules.active.exists? %>
|
||||
<li role="presentation">
|
||||
<a href="#content-tab" aria-controls="content-tab" role="tab" data-toggle="tab">
|
||||
<span class="fas fa-link visible-xs"></span>
|
||||
<span class="hidden-xs"><%= t("projects.reports.elements.modals.project_contents.content_tab") %></span>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="tasks-tab">
|
||||
<h5 class="visible-xs"><%= t("projects.reports.elements.modals.project_contents.tasks_tab") %></h5>
|
||||
<%= render partial: "reports/new/modal/project_contents_inner.html.erb", locals: { form: f, project: project } %>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="content-tab">
|
||||
<h5 class="visible-xs"><%= t("projects.reports.elements.modals.project_contents.content_tab") %></h5>
|
||||
<%= render partial: "reports/new/modal/module_contents_inner.html.erb", locals: { form: f } %>
|
||||
<hr>
|
||||
<%= render partial: "reports/new/modal/step_contents_inner.html.erb", locals: { form: f } %>
|
||||
<hr>
|
||||
<%= render partial: "reports/new/modal/result_contents_inner.html.erb", locals: { form: f } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
|
@ -1,49 +0,0 @@
|
|||
<div>
|
||||
<em>
|
||||
<%= t("projects.reports.elements.modals.project_contents_inner.instructions") %>
|
||||
</em>
|
||||
</div>
|
||||
|
||||
<% if project.project_my_modules.active.exists? %>
|
||||
<div class="checkbox-tree">
|
||||
<ul>
|
||||
<li>
|
||||
<%= form.check_box :project, label: project.name %>
|
||||
<ul>
|
||||
|
||||
<% project.experiments.includes(:my_module_groups).active.each do |experiment| %>
|
||||
<% next unless experiment.my_modules.active.exists? %>
|
||||
<li>
|
||||
<%= form.check_box "experiment_#{experiment.id}", label: experiment.name %>
|
||||
<ul>
|
||||
|
||||
<% experiment.my_module_groups.each do |my_module_group| %>
|
||||
<% my_module_group.my_modules.workflow_ordered.active.each do |my_module| %>
|
||||
<li>
|
||||
<%= form.check_box "modules[#{my_module.id}]", label: my_module.name %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<!-- Tasks without groups -->
|
||||
<% experiment.my_modules.without_group.each do |my_module| %>
|
||||
<li>
|
||||
<%= form.check_box "modules[#{my_module.id}]", label: my_module.name %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<% else %>
|
||||
<div>
|
||||
<em>
|
||||
<%= t("projects.reports.elements.modals.project_contents_inner.no_modules") %>
|
||||
</em>
|
||||
</div>
|
||||
<% end %>
|
|
@ -1,4 +0,0 @@
|
|||
<%= bootstrap_form_tag remote: true, url: result_contents_project_reports_path(project, format: :json), method: :post, html: { id: "add-contents-form" } do |f| %>
|
||||
<%= hidden_field_tag :id, result.id %>
|
||||
<%= render partial: "reports/new/modal/result_contents_inner.html.erb", locals: { form: f } %>
|
||||
<% end %>
|
|
@ -1,18 +0,0 @@
|
|||
<div>
|
||||
<em>
|
||||
<%= t("projects.reports.elements.modals.result_contents_inner.instructions") %>
|
||||
</em>
|
||||
</div>
|
||||
|
||||
<div class="checkbox-tree">
|
||||
<ul>
|
||||
<li>
|
||||
<%= form.label :result_all, t("projects.reports.elements.modals.result_contents_inner.check_all"), class: "checkbox" %>
|
||||
<ul>
|
||||
<li>
|
||||
<%= form.check_box :result_comments, label: t("projects.reports.elements.modals.result_contents_inner.comments") %>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
|
@ -1,5 +0,0 @@
|
|||
<%= bootstrap_form_for [@project, @report], remote: true, url: @url, method: @method, html: { id: "save-report-form" } do |f| %>
|
||||
<%= f.text_field :name, label: t("projects.reports.elements.modals.save_report.name"), placeholder: t("projects.reports.elements.modals.save_report.name_placeholder") %>
|
||||
<%= f.smart_text_area :description, label: t("projects.reports.elements.modals.save_report.description"), placeholder: t("projects.reports.elements.modals.save_report.description_placeholder") %>
|
||||
<%= hidden_field_tag :report_contents, @report_contents %>
|
||||
<% end %>
|
|
@ -1,4 +0,0 @@
|
|||
<%= bootstrap_form_tag remote: true, url: step_contents_project_reports_path(project, format: :json), method: :post, html: { id: "add-contents-form" } do |f| %>
|
||||
<%= hidden_field_tag :id, step.id %>
|
||||
<%= render partial: "reports/new/modal/step_contents_inner.html.erb", locals: { form: f, step: step } %>
|
||||
<% end %>
|
|
@ -1,58 +0,0 @@
|
|||
<% step_undefined = !defined? step or step.blank? %>
|
||||
|
||||
<div>
|
||||
<em>
|
||||
<%= t("projects.reports.elements.modals.step_contents_inner.instructions") %>
|
||||
</em>
|
||||
</div>
|
||||
|
||||
<div class="checkbox-tree">
|
||||
<ul>
|
||||
<li>
|
||||
<%= form.check_box :step_all, label: t("projects.reports.elements.modals.step_contents_inner.check_all") %>
|
||||
<ul>
|
||||
|
||||
<% if step_undefined or step.checklists.exists? %>
|
||||
<li>
|
||||
<%= form.check_box :step_checklists, label: t("projects.reports.elements.modals.step_contents_inner.checklists") %>
|
||||
</li>
|
||||
<% else %>
|
||||
<div>
|
||||
<em>
|
||||
<%= t("projects.reports.elements.modals.step_contents_inner.no_checklists") %>
|
||||
</em>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if step_undefined or step.assets.exists? %>
|
||||
<li>
|
||||
<%= form.check_box :step_assets, label: t("projects.reports.elements.modals.step_contents_inner.assets") %>
|
||||
</li>
|
||||
<% else %>
|
||||
<div>
|
||||
<em>
|
||||
<%= t("projects.reports.elements.modals.step_contents_inner.no_assets") %>
|
||||
</em>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if step_undefined or step.tables.exists? %>
|
||||
<li>
|
||||
<%= form.check_box :step_tables, label: t("projects.reports.elements.modals.step_contents_inner.tables") %>
|
||||
</li>
|
||||
<% else %>
|
||||
<div>
|
||||
<em>
|
||||
<%= t("projects.reports.elements.modals.step_contents_inner.no_tables") %>
|
||||
</em>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<li>
|
||||
<%= form.check_box :step_comments, label: t("projects.reports.elements.modals.step_contents_inner.comments") %>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
|
@ -1,90 +0,0 @@
|
|||
<% content_for :head do %>
|
||||
<meta name="turbolinks-cache-control" content="no-cache">
|
||||
<meta name="turbolinks-visit-control" content="reload">
|
||||
<% end %>
|
||||
|
||||
<% @settings = @report.settings %>
|
||||
|
||||
|
||||
<% provide(:head_title, t("projects.reports.new.head_title", project: h(@project.name)).html_safe) %>
|
||||
|
||||
<%= render partial: "reports/new/report_navigation" %>
|
||||
|
||||
<div class="content-pane" id="report-new">
|
||||
<div class="report-container">
|
||||
<div
|
||||
id="data-holder"
|
||||
class="hidden"
|
||||
data-project-modal-title="<%=t "projects.reports.elements.modals.project_contents.head_title" %>"
|
||||
data-add-project-contents-url="<%= project_contents_modal_project_reports_url(@project) %>"
|
||||
data-add-experiment-contents-url="<%= experiment_contents_modal_project_reports_url(@project) %>"
|
||||
data-add-module-contents-url="<%= module_contents_modal_project_reports_url(@project) %>"
|
||||
data-add-step-contents-url="<%= step_contents_modal_project_reports_url(@project) %>"
|
||||
data-add-result-contents-url="<%= result_contents_modal_project_reports_url(@project) %>"
|
||||
data-stylesheet-url="<%= stylesheet_path "application" %>"
|
||||
data-print-title="<%=t "projects.reports.print_title", project: @project.name %>"
|
||||
data-project-id="<%= @project.id %>"
|
||||
data-save-report-url="<%= save_modal_project_reports_url(@project) %>"
|
||||
data-report-id="<%= @report.present? ? @report.id : "" %>"
|
||||
data-unsaved-work-text="<%=t "projects.reports.new.unsaved_work" %>"
|
||||
data-global-sort-text="<%=t "projects.reports.new.global_sort" %>"></div>
|
||||
|
||||
<!-- Report "preview" -->
|
||||
<div id="report-content">
|
||||
|
||||
<% if @report.present? %>
|
||||
<% @report.root_elements.each do |el| %>
|
||||
<%= render_report_element(el, local_assigns) %>
|
||||
<%= render_new_element(false) %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= render partial: "reports/elements/project_header_element", locals: { project: @project } %>
|
||||
<%= render partial: "reports/elements/new_element", locals: { initial: true } %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<!-- Add elements modal -->
|
||||
<div class="modal" id="add-contents-modal" tabindex="-1" role="dialog" aria-labelledby="add-contents-modal-label">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="add-contents-modal-label"></h4>
|
||||
</div>
|
||||
<div class="modal-body"></div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%=t "general.cancel" %></button>
|
||||
<button type="button" data-action="add" class="btn btn-primary"><%=t "projects.reports.elements.modals.add" %></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Save report modal -->
|
||||
<div class="modal" id="save-report-modal" tabindex="-1" role="dialog" aria-labelledby="save-report-modal-label">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="save-report-modal-label"><%=t "projects.reports.elements.modals.save_report.head_title" %></h4>
|
||||
</div>
|
||||
<div class="modal-body"></div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%=t "general.cancel" %></button>
|
||||
<button type="button" data-action="save" class="btn btn-primary"><%=t "projects.reports.elements.modals.save_report.save" %></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<%= javascript_include_tag "handsontable.full" %>
|
||||
|
||||
<!-- Libraries for formulas -->
|
||||
<%= render partial: "shared/formulas_libraries.html.erb" %>
|
||||
|
||||
<%= javascript_include_tag("reports/new") %>
|
||||
<%= javascript_include_tag 'reports/save_pdf_to_inventory' %>
|
|
@ -4,7 +4,6 @@
|
|||
<meta charset='utf-8' />
|
||||
<%= wicked_pdf_stylesheet_link_tag "application" %>
|
||||
<%= wicked_pdf_stylesheet_link_tag "reports_pdf" %>
|
||||
<%= bootstrap_cdn_link_tag %>
|
||||
<%= font_awesome_cdn_link_tag %>
|
||||
<%= wicked_pdf_javascript_include_tag "jquery" %>
|
||||
<%= wicked_pdf_javascript_include_tag "handsontable.full" %>
|
||||
|
@ -25,7 +24,6 @@
|
|||
<div class="print-report">
|
||||
<% report.root_elements.each do |el| %>
|
||||
<%= render_report_element(el, local_assigns) %>
|
||||
<%= render_new_element(false) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
</style>
|
||||
<div class="print-header">
|
||||
<div class="logo-img">
|
||||
<%= image_tag wicked_pdf_asset_base64('logo.png') %>
|
||||
<%= wicked_pdf_image_tag logo %>
|
||||
</div>
|
||||
<div class="page-numbers pagination" data-page-offset="0">
|
||||
Page <span class="page"></span> of <span class="topage"></span>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="project-selector-container">
|
||||
<%= render partial: 'reports/wizard/project_template_selector', locals: {report: report} %>
|
||||
</div>
|
||||
<div class="report-template-values-container <%= 'hidden' if report.new_record? %>">
|
||||
<div class="report-template-values-container <%= 'hidden' if report.settings["template"].blank? %>">
|
||||
</div>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
options_for_select(@templates.invert, @active_template),
|
||||
prompt: t('projects.reports.wizard.first_step.select_template'),
|
||||
data: {
|
||||
disable_on_load: report.settings[:template].blank?,
|
||||
disable_on_load: report.settings[:template].blank? && report.new_record?,
|
||||
placeholder: t('projects.reports.wizard.first_step.select_template'),
|
||||
selected_template: report.settings[:template],
|
||||
values_editor_path: reports_new_template_values_path(report_id: report.id)
|
||||
|
|
|
@ -69,10 +69,24 @@
|
|||
<% @repositories.each do |repository| %>
|
||||
<li>
|
||||
<span class="sci-checkbox-container">
|
||||
<input type="checkbox" class="sci-checkbox repositories-setting" value="<%= repository.id %>" <%= 'checked' if report.new_record? || @project_contents[:repositories].include?(repository.id) %> />
|
||||
<input type="checkbox"
|
||||
class="sci-checkbox repositories-setting"
|
||||
value="<%= repository.id %>"
|
||||
<%= 'checked' if report.new_record? ||
|
||||
@project_contents[:repositories].include?(repository.id) ||
|
||||
(repository.is_a?(Repository) && repository.repository_snapshots.exists?(id: @project_contents[:repositories])) %> />
|
||||
<span class="sci-checkbox-label"></span>
|
||||
</span>
|
||||
<%= repository.name %>
|
||||
<% if repository.archived? %>
|
||||
<span class="archived">
|
||||
<%= t("projects.reports.wizard.third_step.archived") %>
|
||||
</span>
|
||||
<% elsif repository.is_a?(RepositorySnapshot) %>
|
||||
<span class="deleted">
|
||||
<%= t("projects.reports.wizard.third_step.deleted") %>
|
||||
</span>
|
||||
<% end %>
|
||||
<div class="divider"></div>
|
||||
</li>
|
||||
<% end %>
|
||||
|
|
|
@ -94,9 +94,12 @@
|
|||
<span><%= t('left_menu_bar.support') %></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" data-hook="support-dropdown">
|
||||
<li><%= link_to t('left_menu_bar.support_links.support'),
|
||||
Constants::SUPPORT_URL,
|
||||
target: "_blank" %></li>
|
||||
<li>
|
||||
<%= link_to Constants::SUPPORT_URL, target: "_blank", id: "knowledge-center-link" do %>
|
||||
<i class="fas fa-question-circle"></i>
|
||||
<%= t('left_menu_bar.support_links.support') %>
|
||||
<% end %>
|
||||
</li>
|
||||
<li><%= link_to t('left_menu_bar.support_links.tutorials'),
|
||||
Constants::TUTORIALS_URL,
|
||||
target: "_blank" %></li>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<% if @notification.system_message? %>
|
||||
<% # We assume the system notification is clean %>
|
||||
<%= @notification.message.html_safe %>
|
||||
<% elsif @notification.deliver? %>
|
||||
<% elsif @notification.deliver? && @notification.message.match?(/data-id=('|")(\d*)('|")/) %>
|
||||
<%= I18n.t("notifications.deliver.download_link") %>
|
||||
<% # work around the problem with inserting the link of zipExport %>
|
||||
<% zip_id = /data-id=('|")(\d*)('|")/.match(@notification.message)[2] %>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<div class="date-format-selector-container">
|
||||
<%= select_tag "date-format-input-field",
|
||||
options_for_select(
|
||||
Constants::SUPPORTED_DATE_FORMATS.uniq.map{ |df|
|
||||
Constants::SUPPORTED_DATE_FORMATS.map { |df|
|
||||
["#{l(Time.new(2019, 11, 25), format: :full_date, date_format: df)}", df]
|
||||
},
|
||||
@user.settings[:date_format]
|
||||
|
|
|
@ -42,83 +42,7 @@ class Extends
|
|||
my_module_repository: 17,
|
||||
my_module_protocol: 18 }
|
||||
|
||||
EXPORT_ALL_PROJECT_ELEMENTS = [
|
||||
{
|
||||
type_of: 'project_header',
|
||||
id_key: 'project_id'
|
||||
},
|
||||
{
|
||||
type_of: 'experiment',
|
||||
id_key: 'experiment_id',
|
||||
relation: %w(experiments),
|
||||
children: [
|
||||
{
|
||||
type_of: 'my_module',
|
||||
id_key: 'my_module_id',
|
||||
relation: %w(my_modules),
|
||||
children: [
|
||||
{
|
||||
type_of: 'my_module_protocol',
|
||||
id_key: 'my_module_id'
|
||||
},
|
||||
{
|
||||
type_of: 'step',
|
||||
relation: %w(protocol steps),
|
||||
id_key: 'step_id',
|
||||
children: [
|
||||
{
|
||||
type_of: 'step_asset',
|
||||
relation: %w(assets),
|
||||
id_key: 'asset_id'
|
||||
},
|
||||
{
|
||||
type_of: 'step_table',
|
||||
relation: %w(tables),
|
||||
id_key: 'table_id'
|
||||
},
|
||||
{
|
||||
type_of: 'step_checklist',
|
||||
relation: %w(checklists),
|
||||
id_key: 'checklist_id'
|
||||
},
|
||||
{
|
||||
type_of: 'step_comments',
|
||||
id_key: 'step_id',
|
||||
sort_order: 'asc'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type_of_lambda: lambda { |result|
|
||||
(result.result_asset ||
|
||||
result.result_table ||
|
||||
result.result_text).class.to_s.underscore
|
||||
},
|
||||
relation: %w(results),
|
||||
id_key: 'result_id',
|
||||
children: [{
|
||||
type_of: 'result_comments',
|
||||
id_key: 'result_id',
|
||||
sort_order: 'asc'
|
||||
}]
|
||||
},
|
||||
{
|
||||
type_of: 'my_module_activity',
|
||||
id_key: 'my_module_id',
|
||||
sort_order: 'asc'
|
||||
},
|
||||
{
|
||||
type_of: 'my_module_repository',
|
||||
relation: %w(experiment project assigned_repositories_and_snapshots),
|
||||
id_key: 'repository_id',
|
||||
parent_id_key: 'my_module_id',
|
||||
sort_order: 'asc'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
ACTIVE_REPORT_ELEMENTS = %i(project_header my_module experiment my_module_repository)
|
||||
|
||||
# Data type name should match corresponding model's name
|
||||
REPOSITORY_DATA_TYPES = { RepositoryTextValue: 0,
|
||||
|
@ -143,16 +67,25 @@ class Extends
|
|||
REPOSITORY_IMPORT_COLUMN_PRELOADS = %i(repository_list_items repository_status_items repository_checklist_items)
|
||||
|
||||
# Extra attributes used for search in repositories, 'filed_name' => include_hash
|
||||
REPOSITORY_EXTRA_SEARCH_ATTR = {'repository_text_values.data' => :repository_text_value,
|
||||
'repository_number_values.data' => :repository_number_value,
|
||||
'repository_list_items.data' => { repository_list_value: :repository_list_item },
|
||||
'repository_checklist_items.data' =>
|
||||
{ repository_checklist_value:
|
||||
{ repository_checklist_items_values: :repository_checklist_item } },
|
||||
'repository_status_items.status' =>
|
||||
{ repository_status_value: :repository_status_item },
|
||||
'active_storage_blobs.filename' =>
|
||||
{ repository_asset_value: { asset: { file_attachment: :blob } } } }
|
||||
REPOSITORY_EXTRA_SEARCH_ATTR = {
|
||||
RepositoryTextValue: {
|
||||
field: 'repository_text_values.data', includes: :repository_text_value
|
||||
}, RepositoryNumberValue: {
|
||||
field: 'repository_number_values.data', includes: :repository_number_value
|
||||
}, RepositoryListValue: {
|
||||
field: 'repository_list_items.data',
|
||||
includes: { repository_list_value: :repository_list_item }
|
||||
}, RepositoryChecklistValue: {
|
||||
field: 'repository_checklist_items.data',
|
||||
includes: { repository_checklist_value: { repository_checklist_items_values: :repository_checklist_item } }
|
||||
}, RepositoryStatusValue: {
|
||||
field: 'repository_status_items.status',
|
||||
includes: { repository_status_value: :repository_status_item }
|
||||
}, RepositoryAssetValue: {
|
||||
field: 'active_storage_blobs.filename',
|
||||
includes: { repository_asset_value: { asset: { file_attachment: :blob } } }
|
||||
}
|
||||
}
|
||||
|
||||
# Array of includes used in search query for repository rows
|
||||
REPOSITORY_SEARCH_INCLUDES = [:repository_text_value,
|
||||
|
|
|
@ -1,227 +0,0 @@
|
|||
#########################################################
|
||||
# EXTENDS METHODS. Here you can extend the arrays, #
|
||||
# hashes,.. which is used in methods. Please specify #
|
||||
# the method name and location! #
|
||||
#########################################################
|
||||
|
||||
module ReportExtends
|
||||
# path: app/controllers/concerns/ReportActions
|
||||
# method: generate_module_contents_json
|
||||
|
||||
# ModuleElement struct creates an argument objects which is needed in
|
||||
# generate_module_contents_json method. It takes 3 parameters a Proc and
|
||||
# additional options wich can be extended.
|
||||
# :values => name of the hook/identifier for specific module element state
|
||||
# :element => name of module element in plural
|
||||
# :children => bolean if element has children elements in report
|
||||
# :locals => an array of names of local variables which are passed in the view
|
||||
# :coll => a procedure which the my_module is passed and have to return a
|
||||
# collection of elements
|
||||
# :singular => true by defaut; change the enum type to singular - needed when
|
||||
# querying partials by name
|
||||
# :has_many => false by default; whether the element can have many
|
||||
# manifestations, and its id will be appended.
|
||||
|
||||
ModuleElement = Struct.new(:values,
|
||||
:element,
|
||||
:children,
|
||||
:locals,
|
||||
:coll,
|
||||
:singular,
|
||||
:has_many) do
|
||||
def initialize(values,
|
||||
element,
|
||||
children,
|
||||
locals,
|
||||
coll = nil,
|
||||
singular = true,
|
||||
has_many = false)
|
||||
super(values, element, children, locals, coll, singular, has_many)
|
||||
end
|
||||
|
||||
def collection(my_module, params2)
|
||||
coll.call(my_module, params2) if coll
|
||||
end
|
||||
|
||||
def parse_locals(values)
|
||||
container = {}
|
||||
locals.each_with_index do |local, index|
|
||||
container[local] = values[index]
|
||||
end
|
||||
container
|
||||
end
|
||||
|
||||
def file_name
|
||||
return element.to_s unless singular
|
||||
element.to_s.singularize
|
||||
end
|
||||
end
|
||||
|
||||
ACTIVE_REPORT_ELEMENTS = %i(project_header my_module project_activity experiment my_module_repository)
|
||||
|
||||
# Module contents element
|
||||
MODULE_CONTENTS = [
|
||||
ModuleElement.new([:protocol],
|
||||
:protocol,
|
||||
false,
|
||||
[:my_module]),
|
||||
ModuleElement.new(%i(completed_steps uncompleted_steps),
|
||||
:steps,
|
||||
true,
|
||||
[:step],
|
||||
proc do |my_module, params2|
|
||||
steps = []
|
||||
steps << true if params2["module_completed_steps"] == '1'
|
||||
steps << false if params2["module_uncompleted_steps"] == '1'
|
||||
my_module.protocol.steps.where(completed: steps).order(:position)
|
||||
end),
|
||||
ModuleElement.new([:result_assets],
|
||||
:result_assets,
|
||||
true,
|
||||
[:result],
|
||||
proc do |my_module|
|
||||
my_module.results.joins(:result_asset).select(&:active?)
|
||||
end),
|
||||
ModuleElement.new([:result_tables],
|
||||
:result_tables,
|
||||
true,
|
||||
[:result],
|
||||
proc do |my_module|
|
||||
my_module.results.joins(:result_table).select(&:active?)
|
||||
end),
|
||||
ModuleElement.new([:result_texts],
|
||||
:result_texts,
|
||||
true,
|
||||
[:result],
|
||||
proc do |my_module|
|
||||
my_module.results.joins(:result_text).select(&:active?)
|
||||
end),
|
||||
ModuleElement.new([:activity],
|
||||
:activity,
|
||||
false,
|
||||
%i(my_module order)),
|
||||
ModuleElement.new([:repository],
|
||||
:repository,
|
||||
false,
|
||||
%i(my_module order),
|
||||
nil,
|
||||
true,
|
||||
true)
|
||||
]
|
||||
|
||||
# path: app/helpers/reports_helpers.rb
|
||||
# method: render_report_element
|
||||
|
||||
# sets local :my_module to the listed my_module child elements
|
||||
MY_MODULE_ELEMENTS = %w(my_module
|
||||
my_module_protocol
|
||||
my_module_activity
|
||||
my_module_repository)
|
||||
|
||||
# sets local name to first element of the listed elements
|
||||
FIRST_PART_ELEMENTS = %w(result_comments
|
||||
result_text
|
||||
result_asset
|
||||
result_table
|
||||
project_header
|
||||
step_comments)
|
||||
|
||||
MY_MODULE_CHILDREN_ELEMENTS = %w(step result_asset result_table result_text)
|
||||
|
||||
# path: app/models/report_element.rb
|
||||
# method: set_element_reference
|
||||
|
||||
ElementReference = Struct.new(:checker, :elements) do
|
||||
def initialize(checker, elements = :element_reference_needed!)
|
||||
super(checker, elements)
|
||||
end
|
||||
|
||||
def check(report_element)
|
||||
checker.call(report_element)
|
||||
end
|
||||
end
|
||||
|
||||
SET_ELEMENT_REFERENCES_LIST = [
|
||||
ElementReference.new(
|
||||
proc do |report_element|
|
||||
report_element.project_header?
|
||||
end,
|
||||
['project_id']
|
||||
),
|
||||
ElementReference.new(proc(&:experiment?), ['experiment_id']),
|
||||
ElementReference.new(
|
||||
proc do |report_element|
|
||||
report_element.my_module? ||
|
||||
report_element.my_module_protocol? ||
|
||||
report_element.my_module_activity?
|
||||
end,
|
||||
['my_module_id']
|
||||
),
|
||||
ElementReference.new(
|
||||
proc(&:my_module_repository?),
|
||||
%w(my_module_id repository_id)
|
||||
),
|
||||
ElementReference.new(
|
||||
proc do |report_element|
|
||||
report_element.step? || report_element.step_comments?
|
||||
end,
|
||||
['step_id']
|
||||
),
|
||||
ElementReference.new(
|
||||
proc do |report_element|
|
||||
report_element.result_asset? ||
|
||||
report_element.result_table? ||
|
||||
report_element.result_text? ||
|
||||
report_element.result_comments?
|
||||
end,
|
||||
['result_id']
|
||||
),
|
||||
ElementReference.new(proc(&:step_checklist?), ['checklist_id']),
|
||||
ElementReference.new(proc(&:step_asset?), ['asset_id']),
|
||||
ElementReference.new(proc(&:step_table?), ['table_id'])
|
||||
]
|
||||
|
||||
# path: app/models/report_element.rb
|
||||
# method: element_reference
|
||||
|
||||
ELEMENT_REFERENCES = [
|
||||
ElementReference.new(
|
||||
proc do |report_element|
|
||||
report_element.project_header?
|
||||
end,
|
||||
['project_id']
|
||||
),
|
||||
ElementReference.new(proc(&:experiment?), ['experiment_id']),
|
||||
ElementReference.new(
|
||||
proc do |report_element|
|
||||
report_element.my_module? ||
|
||||
report_element.my_module_protocol? ||
|
||||
report_element.my_module_activity?
|
||||
end,
|
||||
['my_module_id']
|
||||
),
|
||||
ElementReference.new(
|
||||
proc(&:my_module_repository?),
|
||||
%w(my_module_id repository_id)
|
||||
),
|
||||
ElementReference.new(
|
||||
proc do |report_element|
|
||||
report_element.step? ||
|
||||
report_element.step_comments?
|
||||
end,
|
||||
['step_id']
|
||||
),
|
||||
ElementReference.new(
|
||||
proc do |report_element|
|
||||
report_element.result_asset? ||
|
||||
report_element.result_table? ||
|
||||
report_element.result_text? ||
|
||||
report_element.result_comments?
|
||||
end,
|
||||
['result_id']
|
||||
),
|
||||
ElementReference.new(proc(&:step_checklist?), ['checklist_id']),
|
||||
ElementReference.new(proc(&:step_asset?), ['asset_id']),
|
||||
ElementReference.new(proc(&:step_table?), ['table_id'])
|
||||
]
|
||||
end
|
|
@ -65,7 +65,7 @@ en:
|
|||
linkedin:
|
||||
provider_name: "LinkedIn"
|
||||
complete_sign_up: "You have to complete the sign up process"
|
||||
email_already_taken: "SciNote account with email %{email} alreday exists"
|
||||
email_already_taken: "SciNote account with email %{email} already exists"
|
||||
failed_to_save: "Failed to create new user"
|
||||
azure:
|
||||
provider_name: "Azure Active Directory"
|
||||
|
@ -315,7 +315,7 @@ en:
|
|||
edit: "Edit"
|
||||
delete: "Delete"
|
||||
delete_confirm: "Are you sure you wish to delete this comment?"
|
||||
delete_error: "Error occured while deleting comment."
|
||||
delete_error: "Error occurred while deleting comment."
|
||||
|
||||
projects:
|
||||
index:
|
||||
|
@ -352,7 +352,7 @@ en:
|
|||
manage_users: "Manage users"
|
||||
no_notifications: "There are no overdue tasks at the moment"
|
||||
no_results_found: "No results found..."
|
||||
no_results_description: "Try resetting your filter or choose a different search querry"
|
||||
no_results_description: "Try resetting your filter or choose a different search query"
|
||||
module_overdue_html: "Task <em>%{module}</em> is overdue (%{days})."
|
||||
module_overdue_days:
|
||||
one: "1 day"
|
||||
|
@ -381,7 +381,7 @@ en:
|
|||
archive_option: "Archive"
|
||||
archive_confirm: "Are you sure you want to archive this project?"
|
||||
restore_option: "Restore"
|
||||
comments_option: "Show commments (%{comments_count})"
|
||||
comments_option: "Show comments (%{comments_count})"
|
||||
activities_option: "Open activities"
|
||||
comment_placeholder: "Your Message"
|
||||
more_comments: "More Comments"
|
||||
|
@ -474,7 +474,7 @@ en:
|
|||
error_flash: "Project <strong>%{name}</strong> not archived."
|
||||
archive_group:
|
||||
success_flash: "<strong>%{number}</strong> project(s) successfully archived."
|
||||
error_flash: "Failed to arhive project(s)."
|
||||
error_flash: "Failed to archive project(s)."
|
||||
restore_group:
|
||||
success_flash: "<strong>%{number}</strong> project(s) successfully restored."
|
||||
error_flash: "Failed to restore project(s)."
|
||||
|
@ -518,7 +518,7 @@ en:
|
|||
regeneration_modal_title: "Report content"
|
||||
regeneration_modal_body: "The content of Project, Experiments and Tasks included in this report might have been updated in SciNote since the report was last generated. Therefore the content of the report you are about to generate might be different from the saved version."
|
||||
regeneration_modal_confirmation: "Do you want to continue?"
|
||||
accepted_message: "Your report is succesfully added to the generator queue. We will notify you when it is done!"
|
||||
accepted_message: "Your report is successfully added to the generator queue. We will notify you when it is done!"
|
||||
completed_docx_notification_title: "Your report .DOCX was generated successfully."
|
||||
completed_pdf_notification_title: "Your report .PDF was generated successfully."
|
||||
completed_notification_message: "Report: %{report_link} | Team: %{team_name}"
|
||||
|
@ -548,8 +548,8 @@ en:
|
|||
header: "Header"
|
||||
cover: "Title page"
|
||||
footer: "Footer"
|
||||
no_values_title: "No additional data requiered"
|
||||
no_values_description: "SciNote template doesn’t need any additional input for it to be succesfully generated."
|
||||
no_values_title: "No additional data required"
|
||||
no_values_description: "SciNote template doesn’t need any additional input for it to be successfully generated."
|
||||
second_step:
|
||||
select_project_content: "Select and reorder experiments and tasks"
|
||||
collapse_all: "Collapse all"
|
||||
|
@ -586,6 +586,8 @@ en:
|
|||
results_comments: "Include all result comments"
|
||||
additional_content: "Additional content"
|
||||
task_activity: "Include task activity"
|
||||
archived: "[archived]"
|
||||
deleted: "[deleted]"
|
||||
|
||||
new:
|
||||
report_name_placeholder: "Name your report"
|
||||
|
@ -593,7 +595,7 @@ en:
|
|||
generate_button: "Start generating"
|
||||
generate_as_button: "Generate as"
|
||||
save_as_new_report: "A new report"
|
||||
update_report: "Overwrite current reprot"
|
||||
update_report: "Overwrite current report"
|
||||
head_title: "%{project} | New report"
|
||||
nav_title: "Report for: "
|
||||
nav_print: "Print"
|
||||
|
@ -642,7 +644,7 @@ en:
|
|||
confirmation: "Do you want to continue?"
|
||||
project_warning_modal:
|
||||
title: "Task selection will refresh"
|
||||
description: "You’re about to switch to a different project. The task selections you made will be completly refreshed."
|
||||
description: "You’re about to switch to a different project. The task selections you made will be completely refreshed."
|
||||
confirmation: "Do you want to continue?"
|
||||
generate_PDF:
|
||||
generated_on: "Report generated by SciNote on: %{timestamp}"
|
||||
|
@ -652,71 +654,6 @@ en:
|
|||
appended_table: "Appended table"
|
||||
elements:
|
||||
download: "[Download]"
|
||||
modals:
|
||||
project_contents:
|
||||
head_title: "Add contents to report"
|
||||
tasks_tab: "Choose tasks"
|
||||
content_tab: "Choose content"
|
||||
project_contents_inner:
|
||||
instructions: "To create a project report select one or multiple experiment. You can include an entire experiment or individual experimental tasks."
|
||||
no_modules: "The project contains no tasks"
|
||||
no_module_group: "No workflow"
|
||||
module_contents:
|
||||
head_title: "Add contents to task %{module}"
|
||||
module_tab: "Task content"
|
||||
steps_tab: "Protocols content"
|
||||
results_tab: "Results content"
|
||||
module_contents_inner:
|
||||
instructions: "Select the information from your task that you would like to include to your report."
|
||||
check_all: "All tasks content"
|
||||
protocol: "Protocol"
|
||||
steps: "Steps"
|
||||
completed_steps: "Completed"
|
||||
uncompleted_steps: "Uncompleted"
|
||||
no_steps: "Task has no steps"
|
||||
results: "Results"
|
||||
result_assets: "Files"
|
||||
result_tables: "Tables"
|
||||
result_texts: "Texts"
|
||||
no_results: "Task contains no results"
|
||||
activity: "Activity"
|
||||
experiment_contents:
|
||||
head_title: "Add contents to experiment %{experiment}"
|
||||
experiment_tab: "Experiment content"
|
||||
module_tab: "Task content"
|
||||
steps_tab: "Protocols content"
|
||||
results_tab: "Results content"
|
||||
experiment_contents_inner:
|
||||
instructions: "Select tasks to include in the report"
|
||||
no_modules: "The experiment contains no tasks"
|
||||
step_contents:
|
||||
head_title: "Add contents to step %{step}"
|
||||
step_tab: "Step content"
|
||||
results_tab: "Results content"
|
||||
step_contents_inner:
|
||||
instructions: "Select the information from task protocol step/s to include in the report"
|
||||
check_all: "All protocols steps content"
|
||||
tables: "Tables"
|
||||
no_tables: "Step contains no tables"
|
||||
assets: "Files"
|
||||
no_assets: "Step contains no uploaded files"
|
||||
checklists: "Checklists"
|
||||
no_checklists: "Step contains no checklists"
|
||||
comments: "Comments"
|
||||
result_contents:
|
||||
head_title: "Add contents to result %{result}"
|
||||
result_contents_inner:
|
||||
instructions: "Include result/s comments in the report?"
|
||||
check_all: "All results content"
|
||||
comments: "Comments"
|
||||
add: "Add"
|
||||
save_report:
|
||||
head_title: "Save report"
|
||||
name: "Report name"
|
||||
name_placeholder: "My report"
|
||||
description: "Report description"
|
||||
description_placeholder: "My report description..."
|
||||
save: "Save"
|
||||
all:
|
||||
sort_asc: "Sort report element contents by oldest on top"
|
||||
sort_desc: "Sort report element contents by newest on top"
|
||||
|
@ -724,8 +661,6 @@ en:
|
|||
move_down: "Move report element down"
|
||||
remove: "Remove report element from the report"
|
||||
scinote_link: "SciNote link"
|
||||
new_element:
|
||||
title: "Add new report element/s here"
|
||||
project_header:
|
||||
user_time: "Project created on %{timestamp}."
|
||||
title: "Report for project %{project}"
|
||||
|
@ -824,7 +759,7 @@ en:
|
|||
update_role: "Change Role"
|
||||
create:
|
||||
select_user_role: "Please select a user role."
|
||||
add_user_generic_error: "An error occured. "
|
||||
add_user_generic_error: "An error occurred. "
|
||||
can_add_user_to_project: "Can not add user to the project."
|
||||
|
||||
my_modules:
|
||||
|
@ -882,7 +817,7 @@ en:
|
|||
head_title: "%{project} | %{module} | Archive"
|
||||
option_delete: "Delete"
|
||||
confirm_delete: "Are you sure you want to permanently delete result?"
|
||||
delete_flash: "Sucessfully removed result <strong>%{result}</strong> from task <strong>%{module}</strong>."
|
||||
delete_flash: "Successfully removed result <strong>%{result}</strong> from task <strong>%{module}</strong>."
|
||||
archived_on: "Archived on"
|
||||
archived_on_title: "Result archived on %{date} at %{time}."
|
||||
option_download: "Download"
|
||||
|
@ -906,7 +841,7 @@ en:
|
|||
template_updated: "Template updated on:"
|
||||
protocol_updated: "Protocol updated on:"
|
||||
messages:
|
||||
template_updated_html: "There is a new version of this protocol avaliable in the protocol repository.<br>Would you like to update it?"
|
||||
template_updated_html: "There is a new version of this protocol available in the protocol repository.<br>Would you like to update it?"
|
||||
protocol_updated: "The version of this protocol in the task is modified, do you wish to save it as a new protocol template?"
|
||||
unlinked: "This protocol is not linked to the repository."
|
||||
btns:
|
||||
|
@ -1063,7 +998,7 @@ en:
|
|||
description: 'Try another search request'
|
||||
unshared_inventory:
|
||||
title_html: The inventory <b>%{inventory_name}</b> is no longer shared with your team.
|
||||
body_html: This inventory has been ushared with your team by the inventory’s owner. To view the item/s that are assigned to your task/s contact the <b>%{team_name}</b> team administrator <b>%{admin_name}</b> (<b>%{admin_email}</b>).
|
||||
body_html: This inventory has been unshared with your team by the inventory’s owner. To view the item/s that are assigned to your task/s contact the <b>%{team_name}</b> team administrator <b>%{admin_name}</b> (<b>%{admin_email}</b>).
|
||||
open_mobile_app: "Open mobile app"
|
||||
experiments:
|
||||
header:
|
||||
|
@ -1300,7 +1235,7 @@ en:
|
|||
wopi_edit_file: "Edit in %{app}"
|
||||
wopi_word: "Word for the web"
|
||||
wopi_excel: "Excel for the web"
|
||||
wopi_powerpoint: "Powerpoint for the web"
|
||||
wopi_powerpoint: "PowerPoint for the web"
|
||||
error_flash: 'Something went wrong! Please try again later.'
|
||||
|
||||
result_tables:
|
||||
|
@ -1344,7 +1279,7 @@ en:
|
|||
columns: "Columns"
|
||||
edit_inventory: "Edit Inventory"
|
||||
share_inventory: "Share"
|
||||
view_only_permission_label: "You have veiw-only permission"
|
||||
view_only_permission_label: "You have view-only permission"
|
||||
show_per_page: "Show %{number} per page"
|
||||
filter_inventory: "Filter inventories"
|
||||
no_inventories: "No inventories here"
|
||||
|
@ -1517,7 +1452,7 @@ en:
|
|||
js:
|
||||
permission_error: "You don't have permission to edit this item."
|
||||
not_found_error: "This inventory item does not exist."
|
||||
column_added: "New column was sucessfully created."
|
||||
column_added: "New column was successfully created."
|
||||
empty_column_name: "Please enter column name."
|
||||
create:
|
||||
success_flash: "Successfully added item <strong>%{record}</strong> to inventory <strong>%{repository}</strong>"
|
||||
|
@ -1797,7 +1732,7 @@ en:
|
|||
next: "Next"
|
||||
step_3:
|
||||
title: "3. Enter the code given by your authenticator app"
|
||||
description: "Enter the generated code into the fields below to finalize the setup of the two-factor authorisation."
|
||||
description: "Enter the generated code into the fields below to finalize the setup of the two-factor authorization."
|
||||
enter_code: "Enter authenticator code"
|
||||
verify: "Verify"
|
||||
step_4:
|
||||
|
@ -1807,7 +1742,7 @@ en:
|
|||
download_codes: "Download codes"
|
||||
disable:
|
||||
title: "Disable two-factor authentication"
|
||||
description: "Enter your password below to confirm disableing 2FA. This will remove authentication, from your account and make you more vulnerable to potential attacks."
|
||||
description: "Enter your password below to confirm disabling 2FA. This will remove authentication, from your account and make you more vulnerable to potential attacks."
|
||||
password_label: "Enter password"
|
||||
disable_2fa: "Disable 2FA"
|
||||
2fa_errors:
|
||||
|
@ -1863,7 +1798,7 @@ en:
|
|||
head_title: "Settings | Connected Accounts"
|
||||
title: "Connected Accounts"
|
||||
not_connected: "You have no Connected accounts"
|
||||
unlink_success: "Sucessfully unlinked"
|
||||
unlink_success: "Successfully unlinked"
|
||||
azure_ad:
|
||||
title: "Your Azure AD Account"
|
||||
connect_hint: "Allows you to sign in with your Azure AD account."
|
||||
|
@ -1951,7 +1886,7 @@ en:
|
|||
destroy_uo_alert_line_3: "all repository protocols in the team belonging to user will be reassigned onto you;"
|
||||
destroy_uo_alert_line_4: "all inventory items in the team added by user will be reassigned onto you."
|
||||
destroy_uo_confirm: "Remove"
|
||||
leave_flash: "Successfuly left team %{team}."
|
||||
leave_flash: "Successfully left team %{team}."
|
||||
|
||||
protocols:
|
||||
protocols_io_import:
|
||||
|
@ -2106,13 +2041,13 @@ en:
|
|||
description: "Archived protocols can only be seen by you. Restoring protocols will return them to their previous location (team/my protocols)."
|
||||
restore: "Restore"
|
||||
make_private_unauthorized: "You do not have permission to move selected protocols to My protocols."
|
||||
make_private_error: "Error occured while moving selected protocols to My protocols."
|
||||
make_private_error: "Error occurred while moving selected protocols to My protocols."
|
||||
publish_unauthorized: "You do not have permission to move selected protocols to Team protocols."
|
||||
publish_error: "Error occured while moving selected protocols to Team protocols."
|
||||
publish_error: "Error occurred while moving selected protocols to Team protocols."
|
||||
archive_unauthorized: "You do not have permission to archive selected protocols."
|
||||
archive_error: "Error occured while archiving selected protocols."
|
||||
archive_error: "Error occurred while archiving selected protocols."
|
||||
restore_unauthorized: "You do not have permission to restore selected protocols."
|
||||
restore_error: "Error occured while restoring selected protocols."
|
||||
restore_error: "Error occurred while restoring selected protocols."
|
||||
row_renamed_html: "%{old_name}<i> to </i>%{new_name}"
|
||||
no_protocol_name: "(no name)"
|
||||
create:
|
||||
|
@ -2286,7 +2221,7 @@ en:
|
|||
user_exists_unconfirmed_invited_to_team: "User is already a member of SciNote but is not confirmed yet - successfully invited to team %{team} as %{role}."
|
||||
user_exists_and_in_team: "User is already a member of SciNote and team %{team} as %{role}."
|
||||
user_exists_invited_to_team: "User was already a member of SciNote - successfully invited to team %{team} as %{role}."
|
||||
user_created: "User succesfully invited to SciNote."
|
||||
user_created: "User successfully invited to SciNote."
|
||||
user_created_invited_to_team: "User successfully invited to SciNote and team %{team} as %{role}."
|
||||
user_invalid: "Invalid email."
|
||||
too_many_emails: "Only invited first %{nr} emails. To invite more users, "
|
||||
|
@ -2379,7 +2314,7 @@ en:
|
|||
size_label: "Size: %{size}"
|
||||
wopi_supported_text_formats_title: 'Only .docx, .docm, .odt file formats are supported for editing in Word Online.'
|
||||
wopi_supported_table_formats_title: 'Only .xlsx, .xlsm, .xlsb, .ods file formats are supported for editing in Excel Online.'
|
||||
wopi_supported_presentation_formats_title: 'Only .pptx, ppsx, .odp file formats are supported for editing in Powerpoint Online.'
|
||||
wopi_supported_presentation_formats_title: 'Only .pptx, ppsx, .odp file formats are supported for editing in PowerPoint Online.'
|
||||
create_wopi_file:
|
||||
button_text: 'New Office file'
|
||||
li_text: "Office file"
|
||||
|
@ -2624,8 +2559,8 @@ en:
|
|||
generic_error_message: "Something went wrong! Please try again later."
|
||||
user_teams:
|
||||
permission_error: "You don't have permission to manage users."
|
||||
leave_team_error: "An error occured."
|
||||
leave_flash: "Successfuly left team %{team}."
|
||||
leave_team_error: "An error occurred."
|
||||
leave_flash: "Successfully left team %{team}."
|
||||
teams:
|
||||
create_permission_error: "You don't have permission to create team."
|
||||
update_permission_error: "You don't have permission to edit this team."
|
||||
|
|
|
@ -255,42 +255,7 @@ Rails.application.routes.draw do
|
|||
end
|
||||
|
||||
collection do
|
||||
# The posts following here should in theory be gets,
|
||||
# but are posts because of parameters payload
|
||||
get 'new/', to: 'reports#new'
|
||||
get 'new/project_contents_modal',
|
||||
to: 'reports#project_contents_modal',
|
||||
as: :project_contents_modal
|
||||
post 'new/project_contents',
|
||||
to: 'reports#project_contents',
|
||||
as: :project_contents
|
||||
get 'new/experiment_contents_modal',
|
||||
to: 'reports#experiment_contents_modal',
|
||||
as: :experiment_contents_modal
|
||||
post 'new/experiment_contents',
|
||||
to: 'reports#experiment_contents',
|
||||
as: :experiment_contents
|
||||
get 'new/module_contents_modal',
|
||||
to: 'reports#module_contents_modal',
|
||||
as: :module_contents_modal
|
||||
post 'new/module_contents',
|
||||
to: 'reports#module_contents',
|
||||
as: :module_contents
|
||||
get 'new/step_contents_modal',
|
||||
to: 'reports#step_contents_modal',
|
||||
as: :step_contents_modal
|
||||
post 'new/step_contents',
|
||||
to: 'reports#step_contents',
|
||||
as: :step_contents
|
||||
get 'new/result_contents_modal',
|
||||
to: 'reports#result_contents_modal',
|
||||
as: :result_contents_modal
|
||||
post 'new/result_contents',
|
||||
to: 'reports#result_contents',
|
||||
as: :result_contents
|
||||
post '_save',
|
||||
to: 'reports#save_modal',
|
||||
as: :save_modal
|
||||
get 'new', to: 'reports#new'
|
||||
end
|
||||
end
|
||||
resources :experiments, only: %i(new create), defaults: { format: 'json' } do
|
||||
|
|
|
@ -7234,6 +7234,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||
('20210312185911'),
|
||||
('20210325152257'),
|
||||
('20210407143303'),
|
||||
('20210410100006'),
|
||||
('20210506125657');
|
||||
|
||||
|
||||
|
|
|
@ -3,8 +3,18 @@
|
|||
class CustomI18nBackend < I18n::Backend::Simple
|
||||
attr_accessor :date_format
|
||||
|
||||
# Gets I18n configuration object.
|
||||
def date_format
|
||||
Thread.current[:i18n_date_format] ||= Constants::DEFAULT_DATE_FORMAT
|
||||
end
|
||||
|
||||
# Sets I18n configuration object.
|
||||
def date_format=(value)
|
||||
Thread.current[:i18n_date_format] = value
|
||||
end
|
||||
|
||||
def localize(locale, object, format = :default, options = {})
|
||||
options[:date_format] ||= @date_format || Constants::DEFAULT_DATE_FORMAT
|
||||
options[:date_format] ||= date_format
|
||||
super(locale, object, format, options)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -369,10 +369,11 @@ RSpec.describe 'Api::V1::InventoryCellsController', type: :request do
|
|||
), headers: @valid_headers
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_item.repository_cells,
|
||||
each_serializer: Api::V1::InventoryCellSerializer)
|
||||
.as_json[:data]
|
||||
JSON.parse(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_item.repository_cells, each_serializer: Api::V1::InventoryCellSerializer)
|
||||
.to_json
|
||||
)['data']
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -548,10 +549,11 @@ RSpec.describe 'Api::V1::InventoryCellsController', type: :request do
|
|||
expect(response).to have_http_status 201
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(RepositoryCell.last,
|
||||
serializer: Api::V1::InventoryCellSerializer)
|
||||
.as_json[:data]
|
||||
JSON.parse(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(RepositoryCell.last, serializer: Api::V1::InventoryCellSerializer)
|
||||
.to_json
|
||||
)['data']
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -602,10 +604,11 @@ RSpec.describe 'Api::V1::InventoryCellsController', type: :request do
|
|||
expect(response).to have_http_status 201
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(RepositoryCell.last,
|
||||
serializer: Api::V1::InventoryCellSerializer)
|
||||
.as_json[:data]
|
||||
JSON.parse(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(RepositoryCell.last, serializer: Api::V1::InventoryCellSerializer)
|
||||
.to_json
|
||||
)['data']
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -836,10 +839,12 @@ RSpec.describe 'Api::V1::InventoryCellsController', type: :request do
|
|||
expect(response).to have_http_status 200
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_item.repository_cells.where(repository_column: @date_column).first,
|
||||
serializer: Api::V1::InventoryCellSerializer)
|
||||
.as_json[:data]
|
||||
JSON.parse(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_item.repository_cells.where(repository_column: @date_column).first,
|
||||
serializer: Api::V1::InventoryCellSerializer)
|
||||
.to_json
|
||||
)['data']
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -872,10 +877,12 @@ RSpec.describe 'Api::V1::InventoryCellsController', type: :request do
|
|||
expect(response).to have_http_status 200
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_item.repository_cells.where(repository_column: @date_time_column).first,
|
||||
serializer: Api::V1::InventoryCellSerializer)
|
||||
.as_json[:data]
|
||||
JSON.parse(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_item.repository_cells.where(repository_column: @date_time_column).first,
|
||||
serializer: Api::V1::InventoryCellSerializer)
|
||||
.to_json
|
||||
)['data']
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -890,10 +897,12 @@ RSpec.describe 'Api::V1::InventoryCellsController', type: :request do
|
|||
expect(response).to have_http_status 200
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_item.repository_cells.where(repository_column: @date_range_column).first,
|
||||
serializer: Api::V1::InventoryCellSerializer)
|
||||
.as_json[:data]
|
||||
JSON.parse(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_item.repository_cells.where(repository_column: @date_range_column).first,
|
||||
serializer: Api::V1::InventoryCellSerializer)
|
||||
.to_json
|
||||
)['data']
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -33,10 +33,11 @@ RSpec.describe 'Api::V1::ProjectsController', type: :request do
|
|||
headers: @valid_headers
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@teams.first.projects,
|
||||
each_serializer: Api::V1::ProjectSerializer)
|
||||
.as_json[:data]
|
||||
JSON.parse(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@teams.first.projects, each_serializer: Api::V1::ProjectSerializer)
|
||||
.to_json
|
||||
)['data']
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -66,10 +67,11 @@ RSpec.describe 'Api::V1::ProjectsController', type: :request do
|
|||
headers: @valid_headers
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@teams.first.projects.first,
|
||||
serializer: Api::V1::ProjectSerializer)
|
||||
.as_json[:data]
|
||||
JSON.parse(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@teams.first.projects.first, serializer: Api::V1::ProjectSerializer)
|
||||
.to_json
|
||||
)['data']
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -20,10 +20,9 @@ RSpec.describe 'Api::V1::TasksController', type: :request do
|
|||
last_modified_by: @user, project: @valid_project)
|
||||
@unaccessible_experiment = create(:experiment, created_by: @user,
|
||||
last_modified_by: @user, project: @unaccessible_project)
|
||||
|
||||
create_list(:my_module, 3, created_by: @user,
|
||||
create_list(:my_module, 3, :with_due_date, created_by: @user,
|
||||
last_modified_by: @user, experiment: @valid_experiment)
|
||||
create_list(:my_module, 3, created_by: @user,
|
||||
create_list(:my_module, 3, :with_due_date, created_by: @user,
|
||||
last_modified_by: @user, experiment: @unaccessible_experiment)
|
||||
|
||||
@valid_headers =
|
||||
|
@ -40,10 +39,11 @@ RSpec.describe 'Api::V1::TasksController', type: :request do
|
|||
), headers: @valid_headers
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_experiment.my_modules,
|
||||
each_serializer: Api::V1::TaskSerializer)
|
||||
.as_json[:data]
|
||||
JSON.parse(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_experiment.my_modules, each_serializer: Api::V1::TaskSerializer)
|
||||
.to_json
|
||||
)['data']
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -95,10 +95,11 @@ RSpec.describe 'Api::V1::TasksController', type: :request do
|
|||
), headers: @valid_headers
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_experiment.my_modules.first,
|
||||
serializer: Api::V1::TaskSerializer)
|
||||
.as_json[:data]
|
||||
JSON.parse(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_experiment.my_modules.first, serializer: Api::V1::TaskSerializer)
|
||||
.to_json
|
||||
)['data']
|
||||
)
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue