mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-03-03 19:24:48 +08:00
Merge branch 'master' of https://github.com/biosistemika/scinote-web into zd_SCI_765
This commit is contained in:
commit
0996c14449
36 changed files with 856 additions and 547 deletions
2
Gemfile
2
Gemfile
|
@ -68,8 +68,6 @@ gem 'tinymce-rails' # Rich text editor
|
|||
|
||||
gem 'base62' # Used for smart annotations
|
||||
|
||||
gem 'nokogiri' # XML parser
|
||||
|
||||
group :development, :test do
|
||||
gem 'byebug'
|
||||
gem 'better_errors'
|
||||
|
|
|
@ -224,6 +224,32 @@ var HelperModule = (function(){
|
|||
}
|
||||
}
|
||||
|
||||
helpers.flashAlertMsg = function(message, type) {
|
||||
var alertType;
|
||||
var glyphSign;
|
||||
$('#notifications').html('');
|
||||
if (type === 'success') {
|
||||
alertType = ' alert-success ';
|
||||
glyphSign = ' glyphicon-ok-sign ';
|
||||
} else if (type === 'danger') {
|
||||
alertType = ' alert-danger ';
|
||||
glyphSign = ' glyphicon-exclamation-sign ';
|
||||
}
|
||||
var htmlSnippet = '<div class="alert alert' + alertType +
|
||||
'alert-dismissable alert-floating">' +
|
||||
'<div class="container">' +
|
||||
'<button type="button" class="close" ' +
|
||||
'data-dismiss="alert" aria-label="Close">' +
|
||||
'<span aria-hidden="true">×</span></button>' +
|
||||
'<span class="glyphicon' + glyphSign + '"></span>' +
|
||||
'<span>' + message + '</span>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
$('#notifications').html(htmlSnippet);
|
||||
$('#content-wrapper').addClass('alert-shown');
|
||||
helpers.hideFlashMsg();
|
||||
}
|
||||
|
||||
$( document ).ready(function() {
|
||||
helpers.treeLinkTruncation();
|
||||
helpers.hideFlashMsg();
|
||||
|
|
|
@ -503,7 +503,9 @@ function onClickEdit() {
|
|||
},
|
||||
error: function (e, data, status, xhr) {
|
||||
if (e.status == 403) {
|
||||
sampleAlertMsg(I18n.t("samples.js.permission_error"), "danger");
|
||||
HelperModule.flashAlertMsg(
|
||||
I18n.t('samples.js.permission_error'), 'danger'
|
||||
);
|
||||
changeToViewMode();
|
||||
updateButtons();
|
||||
}
|
||||
|
@ -565,7 +567,7 @@ function onClickSave() {
|
|||
dataType: "json",
|
||||
data: data,
|
||||
success: function (data) {
|
||||
sampleAlertMsg(data.flash, "success");
|
||||
HelperModule.flashAlertMsg(data.flash, 'success');
|
||||
onClickCancel();
|
||||
},
|
||||
error: function (e, eData, status, xhr) {
|
||||
|
@ -573,12 +575,16 @@ function onClickSave() {
|
|||
clearAllErrors();
|
||||
|
||||
if (e.status == 404) {
|
||||
sampleAlertMsg(I18n.t("samples.js.not_found_error"), "danger");
|
||||
HelperModule.flashAlertMsg(
|
||||
I18n.t('samples.js.not_found_error'), 'danger'
|
||||
);
|
||||
changeToViewMode();
|
||||
updateButtons();
|
||||
}
|
||||
else if (e.status == 403) {
|
||||
sampleAlertMsg(I18n.t("samples.js.permission_error"), "danger");
|
||||
HelperModule.flashAlertMsg(
|
||||
I18n.t('samples.js.permission_error'), 'danger'
|
||||
);
|
||||
changeToViewMode();
|
||||
updateButtons();
|
||||
}
|
||||
|
@ -794,7 +800,9 @@ function onClickAddSample() {
|
|||
},
|
||||
error: function (e, eData, status, xhr) {
|
||||
if (e.status == 403)
|
||||
sampleAlertMsg(I18n.t("samples.js.permission_error"), "danger");
|
||||
HelperModule.flashAlertMsg(
|
||||
I18n.t('samples.js.permission_error'), 'danger'
|
||||
);
|
||||
changeToViewMode();
|
||||
updateButtons();
|
||||
}
|
||||
|
@ -967,6 +975,7 @@ function changeToEditMode() {
|
|||
'<th class="custom-field" id="' + data.id + '" ' +
|
||||
'data-editable data-deletable ' +
|
||||
'data-edit-url="' + data.edit_url + '" ' +
|
||||
'data-update-url="' + data.update_url + '" ' +
|
||||
'data-destroy-html-url="' + data.destroy_html_url + '"' +
|
||||
'>' + generateColumnNameTooltip(data.name) + '</th>');
|
||||
|
||||
|
@ -1050,6 +1059,7 @@ function changeToEditMode() {
|
|||
'data-position="' + colIndex + '" ' +
|
||||
'data-id="' + $(el).attr('id') + '" ' +
|
||||
'data-edit-url=' + $(el).attr('data-edit-url') + ' ' +
|
||||
'data-update-url=' + $(el).attr('data-update-url') + ' ' +
|
||||
'data-destroy-html-url=' + $(el).attr('data-destroy-html-url') + ' ' +
|
||||
'class="' + visLi + '"' +
|
||||
'>' +
|
||||
|
@ -1151,7 +1161,7 @@ function changeToEditMode() {
|
|||
var text = li.find('.text');
|
||||
var textEdit = li.find('.text-edit');
|
||||
var newName = textEdit.val().trim();
|
||||
var url = li.attr('data-edit-url');
|
||||
var url = li.attr('data-update-url');
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
|
@ -1193,34 +1203,57 @@ function changeToEditMode() {
|
|||
|
||||
cancelEditMode();
|
||||
|
||||
var self = $(this);
|
||||
var li = self.closest('li');
|
||||
var text = li.find('.text');
|
||||
if ($(text).find('.modal-tooltiptext').length > 0) {
|
||||
text = $(text).find('.modal-tooltiptext');
|
||||
var li = $(this).closest('li');
|
||||
var url = li.attr('data-edit-url');
|
||||
ajaxCallEvent();
|
||||
|
||||
function ajaxCallEvent(){
|
||||
$.ajax({
|
||||
url: url,
|
||||
success: function() {
|
||||
var text, textEdit, controls, controlsEdit;
|
||||
text = li.find('.text');
|
||||
if ($(text).find('.modal-tooltiptext').length > 0) {
|
||||
text = $(text).find('.modal-tooltiptext');
|
||||
}
|
||||
textEdit = li.find('.text-edit');
|
||||
controls = li.find('.controls .vis,.edit,.del');
|
||||
controlsEdit = li.find('.controls .ok,.cancel');
|
||||
|
||||
// Toggle edit mode
|
||||
columnEditMode = true;
|
||||
li.addClass('editing');
|
||||
|
||||
// Set the text-edit's value
|
||||
textEdit.val(text.text().trim());
|
||||
|
||||
// Toggle elements
|
||||
text.hide();
|
||||
controls.hide();
|
||||
textEdit.css('display', ''); // show() doesn't work
|
||||
controlsEdit.css('display', ''); // show() doesn't work
|
||||
dropdownList.sortable('disable');
|
||||
dropdownList.on('click', function(ev) {
|
||||
ev.stopPropagation();
|
||||
});
|
||||
// Focus input
|
||||
textEdit.focus();
|
||||
},
|
||||
error: function(e) {
|
||||
$(li).clearFormErrors();
|
||||
var msg = $.parseJSON(e.responseText);
|
||||
|
||||
renderFormError(undefined,
|
||||
$(li).find('.text-edit'),
|
||||
Object.keys(msg)[0] + ' ' + msg.name.toString());
|
||||
var verticalHeight = $(li).offset().top;
|
||||
dropdownList.scrollTo(verticalHeight,0);
|
||||
setTimeout(function() {
|
||||
$(li).clearFormErrors();
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
}
|
||||
var textEdit = li.find('.text-edit');
|
||||
var controls = li.find('.controls .vis,.edit,.del');
|
||||
var controlsEdit = li.find('.controls .ok,.cancel');
|
||||
|
||||
// Toggle edit mode
|
||||
columnEditMode = true;
|
||||
li.addClass('editing');
|
||||
|
||||
// Set the text-edit's value
|
||||
textEdit.val(text.text().trim());
|
||||
|
||||
// Toggle elements
|
||||
text.hide();
|
||||
controls.hide();
|
||||
textEdit.css('display', ''); // show() doesn't work
|
||||
controlsEdit.css('display', ''); // show() doesn't work
|
||||
dropdownList.sortable('disable');
|
||||
dropdownList.on('click', function(ev) {
|
||||
ev.stopPropagation();
|
||||
});
|
||||
// Focus input
|
||||
textEdit.focus();
|
||||
});
|
||||
|
||||
// On hiding dropdown, cancel edit mode throughout dropdown
|
||||
|
|
|
@ -70,6 +70,17 @@
|
|||
});
|
||||
|
||||
clearModal('#modal-delete');
|
||||
},
|
||||
error: function (e) {
|
||||
$(li).clearFormErrors();
|
||||
var msg = $.parseJSON(e.responseText);
|
||||
|
||||
renderFormError(undefined,
|
||||
$(li).find('.text-edit'),
|
||||
Object.keys(msg)[0] + ' ' + msg.name.toString());
|
||||
setTimeout(function() {
|
||||
$(li).clearFormErrors();
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -161,6 +172,17 @@
|
|||
$(this).find('#sample_type_name'),
|
||||
Object.keys(msg)[0] + ' '+ msg.name.toString());
|
||||
});
|
||||
},
|
||||
error: function (e) {
|
||||
$(li).clearFormErrors();
|
||||
var msg = $.parseJSON(e.responseText);
|
||||
|
||||
renderFormError(undefined,
|
||||
$(li).find('.text-edit'),
|
||||
Object.keys(msg)[0] + ' ' + msg.name.toString());
|
||||
setTimeout(function() {
|
||||
$(li).clearFormErrors();
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -202,6 +224,40 @@
|
|||
$(this).find('#sample_group_name'),
|
||||
Object.keys(msg)[0] + ' '+ msg.name.toString());
|
||||
});
|
||||
},
|
||||
error: function (e) {
|
||||
$(li).clearFormErrors();
|
||||
var msg = $.parseJSON(e.responseText);
|
||||
|
||||
renderFormError(undefined,
|
||||
$(li).find('.text-edit'),
|
||||
Object.keys(msg)[0] + ' ' + msg.name.toString());
|
||||
setTimeout(function() {
|
||||
$(li).clearFormErrors();
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function editSampleGroupColor() {
|
||||
$('.color-picker').on('click', function() {
|
||||
var li = $(this).closest('li');
|
||||
$.ajax({
|
||||
url: li.attr('data-edit'),
|
||||
success: function(data) {
|
||||
},
|
||||
error: function (e) {
|
||||
$('.dropdown-colorselector.open').removeClass('open');
|
||||
$(li).clearFormErrors();
|
||||
var msg = $.parseJSON(e.responseText);
|
||||
|
||||
renderFormError(undefined,
|
||||
$(li).find('.text-edit'),
|
||||
Object.keys(msg)[0] + ' ' + msg.name.toString());
|
||||
setTimeout(function() {
|
||||
$(li).clearFormErrors();
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -269,6 +325,7 @@
|
|||
bindNewSampleGroupAction();
|
||||
appendCarretToColorPickerDropdown();
|
||||
sampleTypeGroupEditMode();
|
||||
editSampleGroupColor();
|
||||
}
|
||||
|
||||
// initialize sample types/groups actions
|
||||
|
|
|
@ -53,32 +53,6 @@ function updateSamplesTypesandGroups() {
|
|||
});
|
||||
}
|
||||
|
||||
function sampleAlertMsg(message, type) {
|
||||
var alertType;
|
||||
var glyphSign;
|
||||
$('#notifications').html('');
|
||||
if (type === 'success') {
|
||||
alertType = ' alert-success ';
|
||||
glyphSign = ' glyphicon-ok-sign ';
|
||||
} else if (type === 'danger') {
|
||||
alertType = ' alert-danger ';
|
||||
glyphSign = ' glyphicon-exclamation-sign ';
|
||||
}
|
||||
var htmlSnippet = '<div class="alert alert' + alertType +
|
||||
'alert-dismissable alert-floating">' +
|
||||
'<div class="container">' +
|
||||
'<button type="button" class="close" ' +
|
||||
'data-dismiss="alert" aria-label="Close">' +
|
||||
'<span aria-hidden="true">×</span></button>' +
|
||||
'<span class="glyphicon' + glyphSign + '"></span>' +
|
||||
'<span>' + message + '</span>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
$('#notifications').html(htmlSnippet);
|
||||
$('#content-wrapper').addClass('alert-shown');
|
||||
HelperModule.hideFlashMsg();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes tutorial
|
||||
*/
|
||||
|
|
169
app/controllers/concerns/report_actions.rb
Normal file
169
app/controllers/concerns/report_actions.rb
Normal file
|
@ -0,0 +1,169 @@
|
|||
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
|
||||
modules = (params[:modules].select { |_, p| p == '1' })
|
||||
.keys
|
||||
.collect(&:to_i)
|
||||
|
||||
# Get unique experiments from given modules
|
||||
experiments = MyModule.where(id: modules).map(&:experiment).uniq
|
||||
experiments.each do |experiment|
|
||||
res << generate_new_el(false)
|
||||
el = generate_el(
|
||||
'reports/elements/experiment_element.html.erb',
|
||||
experiment: experiment
|
||||
)
|
||||
el[:children] = generate_experiment_contents_json(experiment, modules)
|
||||
res << el
|
||||
end
|
||||
end
|
||||
res << generate_new_el(false)
|
||||
res
|
||||
end
|
||||
|
||||
def generate_experiment_contents_json(experiment, selected_modules)
|
||||
res = []
|
||||
experiment.my_modules.each do |my_module|
|
||||
next unless selected_modules.include?(my_module.id)
|
||||
|
||||
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|
|
||||
protocol = contents.element == :step ? my_module.protocol.present? : true
|
||||
next unless in_params?("module_#{contents.element}".to_sym) && protocol
|
||||
res << generate_new_el(false)
|
||||
if contents.children
|
||||
contents.collection(my_module).each do |report_el|
|
||||
el = generate_el(
|
||||
"reports/elements/my_module_#{contents
|
||||
.element
|
||||
.to_s
|
||||
.singularize}_element.html.erb",
|
||||
contents.parse_locals([report_el])
|
||||
)
|
||||
if contents.element == :step
|
||||
el[:children] = generate_step_contents_json(report_el)
|
||||
elsif contents.element == :result
|
||||
el[:children] = generate_result_contents_json(report_el)
|
||||
end
|
||||
res << el
|
||||
end
|
||||
else
|
||||
file_name = contents.file_name
|
||||
file_name = contents.element if contents.element == :samples
|
||||
res << generate_el(
|
||||
"reports/elements/my_module_#{file_name}_element.html.erb",
|
||||
contents.parse_locals([my_module, :asc])
|
||||
)
|
||||
end
|
||||
end
|
||||
res << generate_new_el(false)
|
||||
res
|
||||
end
|
||||
|
||||
def generate_step_contents_json(step)
|
||||
res = []
|
||||
if in_params? :step_checklists
|
||||
step.checklists.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
|
||||
step.assets.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 == 0
|
||||
|
||||
if elements.count == 1
|
||||
el = elements[0]
|
||||
return true if el.include?(:new_element) && el[:new_element]
|
||||
return false
|
||||
end
|
||||
false
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
class CustomFieldsController < ApplicationController
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :load_vars, only: [:update, :destroy, :destroy_html]
|
||||
before_action :load_vars, except: :create
|
||||
before_action :load_vars_nested, only: [:create, :destroy_html]
|
||||
before_action :check_create_permissions, only: :create
|
||||
before_action :check_update_permissions, only: :update
|
||||
|
@ -19,6 +19,8 @@ class CustomFieldsController < ApplicationController
|
|||
id: @custom_field.id,
|
||||
name: escape_input(@custom_field.name),
|
||||
edit_url:
|
||||
edit_team_custom_field_path(@team, @custom_field),
|
||||
update_url:
|
||||
team_custom_field_path(@team, @custom_field),
|
||||
destroy_html_url:
|
||||
team_custom_field_destroy_html_path(
|
||||
|
@ -36,6 +38,14 @@ class CustomFieldsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: { status: :ok }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
|
|
|
@ -521,7 +521,9 @@ class ProtocolsController < ApplicationController
|
|||
transaction_error = false
|
||||
Protocol.transaction do
|
||||
begin
|
||||
import_into_existing(@protocol, @protocol_json, current_user)
|
||||
import_into_existing(
|
||||
@protocol, @protocol_json, current_user, current_team
|
||||
)
|
||||
rescue Exception
|
||||
transaction_error = true
|
||||
raise ActiveRecord:: Rollback
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
class ReportsController < ApplicationController
|
||||
include TeamsHelper
|
||||
include ReportActions
|
||||
# Ignore CSRF protection just for PDF generation (because it's
|
||||
# used via target='_blank')
|
||||
protect_from_forgery with: :exception, :except => :generate
|
||||
protect_from_forgery with: :exception, except: :generate
|
||||
|
||||
before_action :load_vars, only: [
|
||||
:edit,
|
||||
|
@ -28,7 +29,7 @@ class ReportsController < ApplicationController
|
|||
:result_contents
|
||||
]
|
||||
|
||||
before_action :check_view_permissions, only: [:index]
|
||||
before_action :check_view_permissions, only: :index
|
||||
before_action :check_create_permissions, only: [
|
||||
:new,
|
||||
:create,
|
||||
|
@ -46,9 +47,9 @@ class ReportsController < ApplicationController
|
|||
:step_contents,
|
||||
:result_contents
|
||||
]
|
||||
before_action :check_destroy_permissions, only: [:destroy]
|
||||
before_action :check_destroy_permissions, only: :destroy
|
||||
|
||||
layout "fluid"
|
||||
layout 'fluid'
|
||||
|
||||
# Index showing all reports of a single project
|
||||
def index
|
||||
|
@ -73,7 +74,7 @@ class ReportsController < ApplicationController
|
|||
@report.user = current_user
|
||||
@report.last_modified_by = current_user
|
||||
|
||||
if continue and @report.save_with_contents(report_contents)
|
||||
if continue && @report.save_with_contents(report_contents)
|
||||
# record an activity
|
||||
Activity.create(
|
||||
type_of: :create_report,
|
||||
|
@ -86,15 +87,15 @@ class ReportsController < ApplicationController
|
|||
)
|
||||
)
|
||||
respond_to do |format|
|
||||
format.json {
|
||||
format.json do
|
||||
render json: { url: project_reports_path(@project) }, status: :ok
|
||||
}
|
||||
end
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.json {
|
||||
format.json do
|
||||
render json: @report.errors, status: :unprocessable_entity
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -118,7 +119,7 @@ class ReportsController < ApplicationController
|
|||
@report.last_modified_by = current_user
|
||||
@report.assign_attributes(report_params)
|
||||
|
||||
if continue and @report.save_with_contents(report_contents)
|
||||
if continue && @report.save_with_contents(report_contents)
|
||||
# record an activity
|
||||
Activity.create(
|
||||
type_of: :edit_report,
|
||||
|
@ -131,25 +132,21 @@ class ReportsController < ApplicationController
|
|||
)
|
||||
)
|
||||
respond_to do |format|
|
||||
format.json {
|
||||
format.json do
|
||||
render json: { url: project_reports_path(@project) }, status: :ok
|
||||
}
|
||||
end
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.json {
|
||||
format.json do
|
||||
render json: @report.errors, status: :unprocessable_entity
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Destroy multiple entries action
|
||||
def destroy
|
||||
unless params.include? :report_ids
|
||||
render_404
|
||||
end
|
||||
|
||||
begin
|
||||
report_ids = JSON.parse(params[:report_ids])
|
||||
rescue
|
||||
|
@ -158,21 +155,19 @@ class ReportsController < ApplicationController
|
|||
|
||||
report_ids.each do |report_id|
|
||||
report = Report.find_by_id(report_id)
|
||||
|
||||
if report.present?
|
||||
# record an activity
|
||||
Activity.create(
|
||||
type_of: :delete_report,
|
||||
project: report.project,
|
||||
user: current_user,
|
||||
message: I18n.t(
|
||||
'activities.delete_report',
|
||||
user: current_user.full_name,
|
||||
report: report.name
|
||||
)
|
||||
next unless report.present?
|
||||
# record an activity
|
||||
Activity.create(
|
||||
type_of: :delete_report,
|
||||
project: report.project,
|
||||
user: current_user,
|
||||
message: I18n.t(
|
||||
'activities.delete_report',
|
||||
user: current_user.full_name,
|
||||
report: report.name
|
||||
)
|
||||
report.destroy
|
||||
end
|
||||
)
|
||||
report.destroy
|
||||
end
|
||||
|
||||
redirect_to project_reports_path(@project)
|
||||
|
@ -182,15 +177,13 @@ class ReportsController < ApplicationController
|
|||
# Currently, only .PDF is supported
|
||||
def generate
|
||||
respond_to do |format|
|
||||
format.pdf {
|
||||
format.pdf do
|
||||
@html = params[:html]
|
||||
if @html.blank? then
|
||||
@html = "<h1>No content</h1>"
|
||||
end
|
||||
render pdf: "report",
|
||||
@html = '<h1>No content</h1>' if @html.blank?
|
||||
render pdf: 'report',
|
||||
header: { right: '[page] of [topage]' },
|
||||
template: "reports/report.pdf.erb"
|
||||
}
|
||||
template: 'reports/report.pdf.erb'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -209,33 +202,32 @@ class ReportsController < ApplicationController
|
|||
@url = project_report_path(@project, @report, format: :json)
|
||||
end
|
||||
|
||||
if !params.include? :contents
|
||||
render_403 and return
|
||||
end
|
||||
render_403 and return unless params.include? :contents
|
||||
|
||||
@report_contents = params[:contents]
|
||||
|
||||
respond_to do |format|
|
||||
format.json {
|
||||
format.json do
|
||||
render json: {
|
||||
html: render_to_string({
|
||||
partial: "reports/new/modal/save.html.erb"
|
||||
})
|
||||
html: render_to_string(
|
||||
partial: 'reports/new/modal/save.html.erb'
|
||||
)
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Modal for adding contents into project element
|
||||
def project_contents_modal
|
||||
respond_to do |format|
|
||||
format.json {
|
||||
format.json do
|
||||
render json: {
|
||||
html: render_to_string({
|
||||
partial: "reports/new/modal/project_contents.html.erb",
|
||||
html: render_to_string(
|
||||
partial: 'reports/new/modal/project_contents.html.erb',
|
||||
locals: { project: @project }
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -274,7 +266,7 @@ class ReportsController < ApplicationController
|
|||
format.json do
|
||||
render json: {
|
||||
html: render_to_string(
|
||||
partial: "reports/new/modal/module_contents.html.erb",
|
||||
partial: 'reports/new/modal/module_contents.html.erb',
|
||||
locals: { project: @project, my_module: my_module }
|
||||
)
|
||||
}
|
||||
|
@ -289,18 +281,18 @@ class ReportsController < ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
if step.blank?
|
||||
format.json {
|
||||
format.json do
|
||||
render json: {}, status: :not_found
|
||||
}
|
||||
end
|
||||
else
|
||||
format.json {
|
||||
format.json do
|
||||
render json: {
|
||||
html: render_to_string({
|
||||
partial: "reports/new/modal/step_contents.html.erb",
|
||||
html: render_to_string(
|
||||
partial: 'reports/new/modal/step_contents.html.erb',
|
||||
locals: { project: @project, step: step }
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -311,18 +303,18 @@ class ReportsController < ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
if result.blank?
|
||||
format.json {
|
||||
format.json do
|
||||
render json: {}, status: :not_found
|
||||
}
|
||||
end
|
||||
else
|
||||
format.json {
|
||||
format.json do
|
||||
render json: {
|
||||
html: render_to_string({
|
||||
partial: "reports/new/modal/result_contents.html.erb",
|
||||
html: render_to_string(
|
||||
partial: 'reports/new/modal/result_contents.html.erb',
|
||||
locals: { project: @project, result: result }
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -384,12 +376,12 @@ class ReportsController < ApplicationController
|
|||
if elements_empty? elements
|
||||
format.json { render json: {}, status: :no_content }
|
||||
else
|
||||
format.json {
|
||||
format.json do
|
||||
render json: {
|
||||
status: :ok,
|
||||
elements: elements
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -442,242 +434,31 @@ class ReportsController < ApplicationController
|
|||
|
||||
private
|
||||
|
||||
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
|
||||
modules = (params[:modules].select { |_, p| p == '1' })
|
||||
.keys
|
||||
.collect(&:to_i)
|
||||
|
||||
# Get unique experiments from given modules
|
||||
experiments = MyModule.where(id: modules).map(&:experiment).uniq
|
||||
experiments.each do |experiment|
|
||||
res << generate_new_el(false)
|
||||
el = generate_el(
|
||||
'reports/elements/experiment_element.html.erb',
|
||||
experiment: experiment
|
||||
)
|
||||
el[:children] = generate_experiment_contents_json(experiment, modules)
|
||||
res << el
|
||||
end
|
||||
end
|
||||
res << generate_new_el(false)
|
||||
res
|
||||
end
|
||||
|
||||
def generate_experiment_contents_json(experiment, selected_modules)
|
||||
res = []
|
||||
experiment.my_modules.each do |my_module|
|
||||
next unless selected_modules.include?(my_module.id)
|
||||
|
||||
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 = []
|
||||
if (in_params? :module_steps) && my_module.protocol.present? then
|
||||
my_module.protocol.completed_steps.each do |step|
|
||||
res << generate_new_el(false)
|
||||
el = generate_el(
|
||||
"reports/elements/step_element.html.erb",
|
||||
{ step: step }
|
||||
)
|
||||
el[:children] = generate_step_contents_json(step)
|
||||
res << el
|
||||
end
|
||||
end
|
||||
if in_params? :module_result_assets then
|
||||
(my_module.results.select { |r| r.is_asset && r.active? }).each do |result_asset|
|
||||
res << generate_new_el(false)
|
||||
el = generate_el(
|
||||
"reports/elements/result_asset_element.html.erb",
|
||||
{ result: result_asset }
|
||||
)
|
||||
el[:children] = generate_result_contents_json(result_asset)
|
||||
res << el
|
||||
end
|
||||
end
|
||||
if in_params? :module_result_tables then
|
||||
(my_module.results.select { |r| r.is_table && r.active? }).each do |result_table|
|
||||
res << generate_new_el(false)
|
||||
el = generate_el(
|
||||
"reports/elements/result_table_element.html.erb",
|
||||
{ result: result_table }
|
||||
)
|
||||
el[:children] = generate_result_contents_json(result_table)
|
||||
res << el
|
||||
end
|
||||
end
|
||||
if in_params? :module_result_texts then
|
||||
(my_module.results.select { |r| r.is_text && r.active? }).each do |result_text|
|
||||
res << generate_new_el(false)
|
||||
el = generate_el(
|
||||
"reports/elements/result_text_element.html.erb",
|
||||
result: result_text
|
||||
)
|
||||
el[:children] = generate_result_contents_json(result_text)
|
||||
res << el
|
||||
end
|
||||
end
|
||||
if in_params? :module_activity then
|
||||
res << generate_new_el(false)
|
||||
res << generate_el(
|
||||
"reports/elements/my_module_activity_element.html.erb",
|
||||
{ my_module: my_module, order: :asc }
|
||||
)
|
||||
end
|
||||
if in_params? :module_samples then
|
||||
res << generate_new_el(false)
|
||||
res << generate_el(
|
||||
"reports/elements/my_module_samples_element.html.erb",
|
||||
{ my_module: my_module, order: :asc }
|
||||
)
|
||||
end
|
||||
res << generate_new_el(false)
|
||||
res
|
||||
end
|
||||
|
||||
def generate_step_contents_json(step)
|
||||
res = []
|
||||
if in_params? :step_checklists then
|
||||
step.checklists.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 then
|
||||
step.assets.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 then
|
||||
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 then
|
||||
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 then
|
||||
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)
|
||||
if elements.blank?
|
||||
return true
|
||||
elsif elements.count == 0 then
|
||||
return true
|
||||
elsif elements.count == 1
|
||||
el = elements[0]
|
||||
if el.include? :new_element and el[:new_element]
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def load_vars
|
||||
@report = Report.find_by_id(params[:id])
|
||||
|
||||
unless @report
|
||||
render_404
|
||||
end
|
||||
render_404 unless @report
|
||||
end
|
||||
|
||||
def load_vars_nested
|
||||
@project = Project.find_by_id(params[:project_id])
|
||||
|
||||
unless @project
|
||||
render_404
|
||||
end
|
||||
render_404 unless @project
|
||||
end
|
||||
|
||||
def check_view_permissions
|
||||
unless can_view_reports(@project)
|
||||
render_403
|
||||
end
|
||||
render_403 unless can_view_reports(@project)
|
||||
end
|
||||
|
||||
def check_create_permissions
|
||||
unless can_create_new_report(@project)
|
||||
render_403
|
||||
end
|
||||
render_403 unless can_create_new_report(@project)
|
||||
end
|
||||
|
||||
def check_destroy_permissions
|
||||
unless can_delete_reports(@project)
|
||||
render_403
|
||||
end
|
||||
render_403 unless can_delete_reports(@project)
|
||||
render_404 unless params.include? :report_ids
|
||||
end
|
||||
|
||||
def report_params
|
||||
params.require(:report).permit(:name, :description, :grouped_by, :report_contents)
|
||||
params.require(:report)
|
||||
.permit(:name, :description, :grouped_by, :report_contents)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -29,6 +29,7 @@ class ResultAssetsController < ApplicationController
|
|||
@asset = Asset.new(result_params[:asset_attributes])
|
||||
@asset.created_by = current_user
|
||||
@asset.last_modified_by = current_user
|
||||
@asset.team = current_team
|
||||
@result = Result.new(
|
||||
user: current_user,
|
||||
my_module: @my_module,
|
||||
|
@ -98,6 +99,7 @@ class ResultAssetsController < ApplicationController
|
|||
asset = Asset.find_by_id(update_params[:asset_attributes][:id])
|
||||
asset.created_by = current_user
|
||||
asset.last_modified_by = current_user
|
||||
asset.team = current_team
|
||||
@result.asset = asset
|
||||
end
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ class ResultTablesController < ApplicationController
|
|||
def create
|
||||
@table = Table.new(result_params[:table_attributes])
|
||||
@table.created_by = current_user
|
||||
@table.team = current_team
|
||||
@table.last_modified_by = current_user
|
||||
@result = Result.new(
|
||||
user: current_user,
|
||||
|
@ -92,6 +93,7 @@ class ResultTablesController < ApplicationController
|
|||
update_params = result_params
|
||||
@result.last_modified_by = current_user
|
||||
@result.table.last_modified_by = current_user
|
||||
@result.table.team = current_team
|
||||
@result.assign_attributes(update_params)
|
||||
flash_success = t("result_tables.update.success_flash",
|
||||
module: @my_module.name)
|
||||
|
@ -218,6 +220,4 @@ class ResultTablesController < ApplicationController
|
|||
]
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -33,6 +33,14 @@ class StepsController < ApplicationController
|
|||
@step.protocol = @protocol
|
||||
@step.user = current_user
|
||||
@step.last_modified_by = current_user
|
||||
@step.assets.each do |asset|
|
||||
asset.created_by = current_user
|
||||
asset.team = current_team
|
||||
end
|
||||
@step.tables.each do |table|
|
||||
table.created_by = current_user
|
||||
table.team = current_team
|
||||
end
|
||||
|
||||
# Update default checked state
|
||||
@step.checklists.each do |checklist|
|
||||
|
@ -133,6 +141,18 @@ class StepsController < ApplicationController
|
|||
@step.assign_attributes(step_params_all)
|
||||
@step.last_modified_by = current_user
|
||||
|
||||
@step.assets.each do |asset|
|
||||
asset.created_by = current_user if asset.new_record?
|
||||
asset.last_modified_by = current_user unless asset.new_record?
|
||||
asset.team = current_team
|
||||
end
|
||||
|
||||
@step.tables.each do |table|
|
||||
table.created_by = current_user if table.new_record?
|
||||
table.last_modified_by = current_user unless table.new_record?
|
||||
table.team = current_team
|
||||
end
|
||||
|
||||
if @step.save
|
||||
@step.reload
|
||||
|
||||
|
|
|
@ -1,99 +1,95 @@
|
|||
module ReportsHelper
|
||||
def render_new_element(hide)
|
||||
render partial: 'reports/elements/new_element.html.erb',
|
||||
locals: { hide: hide }
|
||||
end
|
||||
|
||||
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)
|
||||
children_html = ''.html_safe
|
||||
|
||||
def render_report_element(element, provided_locals = nil)
|
||||
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.has_children?
|
||||
children_html.safe_concat render_new_element(true)
|
||||
element.children.each do |child|
|
||||
children_html.safe_concat render_report_element(child, provided_locals)
|
||||
# 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.has_children?
|
||||
children_html.safe_concat render_new_element(true)
|
||||
element.children.each do |child|
|
||||
children_html
|
||||
.safe_concat render_report_element(child, provided_locals)
|
||||
end
|
||||
else
|
||||
children_html.safe_concat render_new_element(false)
|
||||
end
|
||||
else
|
||||
if element.has_children?
|
||||
element.children.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
|
||||
else
|
||||
if element.has_children?
|
||||
element.children.each do |child|
|
||||
children_html.safe_concat render_new_element(false)
|
||||
children_html.safe_concat render_report_element(child, provided_locals)
|
||||
end
|
||||
|
||||
file_name = element.type_of
|
||||
if element.type_of.in? %w(step result_asset result_table result_text)
|
||||
file_name = "my_module_#{element.type_of.singularize}"
|
||||
end
|
||||
children_html.safe_concat render_new_element(false)
|
||||
view = "reports/elements/#{file_name}_element.html.erb"
|
||||
|
||||
locals = provided_locals.nil? ? {} : provided_locals.clone
|
||||
locals[:children] = children_html
|
||||
|
||||
# ReportExtends is located in config/initializers/extends/report_extends.rb
|
||||
|
||||
ReportElement.type_ofs.keys.each do |type|
|
||||
next unless element.public_send("#{type}?")
|
||||
local_sym = type.split('_').last.to_sym
|
||||
local_sym = type
|
||||
.split('_')
|
||||
.first
|
||||
.to_sym if type.in? ReportExtends::FIRST_PART_ELEMENTS
|
||||
local_sym = :my_module if type.in? ReportExtends::MY_MODULE_ELEMENTS
|
||||
locals[local_sym] = element.element_reference
|
||||
locals[:order] = element
|
||||
.sort_order if type.in? ReportExtends::SORTED_ELEMENTS
|
||||
end
|
||||
|
||||
(render partial: view, locals: locals).html_safe
|
||||
end
|
||||
|
||||
view = "reports/elements/#{element.type_of}_element.html.erb"
|
||||
|
||||
locals = provided_locals.nil? ? {} : provided_locals.clone
|
||||
locals[:children] = children_html
|
||||
|
||||
if element.project_header?
|
||||
locals[:project] = element.element_reference
|
||||
elsif element.experiment?
|
||||
locals[:experiment] = element.element_reference
|
||||
elsif element.my_module?
|
||||
locals[:my_module] = element.element_reference
|
||||
elsif element.step?
|
||||
locals[:step] = element.element_reference
|
||||
elsif element.result_asset?
|
||||
locals[:result] = element.element_reference
|
||||
elsif element.result_table?
|
||||
locals[:result] = element.element_reference
|
||||
elsif element.result_text?
|
||||
locals[:result] = element.element_reference
|
||||
elsif element.my_module_activity?
|
||||
locals[:my_module] = element.element_reference
|
||||
locals[:order] = element.sort_order
|
||||
elsif element.my_module_samples?
|
||||
locals[:my_module] = element.element_reference
|
||||
locals[:order] = element.sort_order
|
||||
elsif element.step_checklist?
|
||||
locals[:checklist] = element.element_reference
|
||||
elsif element.step_asset?
|
||||
locals[:asset] = element.element_reference
|
||||
elsif element.step_table?
|
||||
locals[:table] = element.element_reference
|
||||
elsif element.step_comments?
|
||||
locals[:step] = element.element_reference
|
||||
locals[:order] = element.sort_order
|
||||
elsif element.result_comments?
|
||||
locals[:result] = element.element_reference
|
||||
locals[:order] = element.sort_order
|
||||
elsif element.project_activity?
|
||||
# TODO
|
||||
elsif element.project_samples?
|
||||
# TODO
|
||||
# "Hack" to omit file preview URL because of WKHTML issues
|
||||
def report_image_asset_url(asset)
|
||||
prefix = ''
|
||||
if ENV['PAPERCLIP_STORAGE'].present? &&
|
||||
ENV['MAIL_SERVER_URL'].present? &&
|
||||
ENV['PAPERCLIP_STORAGE'] == 'filesystem'
|
||||
prefix = ENV['MAIL_SERVER_URL']
|
||||
end
|
||||
if !prefix.empty? &&
|
||||
!prefix.include?('http://') &&
|
||||
!prefix.include?('https://')
|
||||
prefix = "http://#{prefix}"
|
||||
end
|
||||
url = prefix + asset.url(:medium, timeout: Constants::URL_LONG_EXPIRE_TIME)
|
||||
image_tag(url)
|
||||
end
|
||||
|
||||
return (render partial: view, locals: locals).html_safe
|
||||
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
|
||||
|
||||
# "Hack" to omit file preview URL because of WKHTML issues
|
||||
def report_image_asset_url(asset)
|
||||
prefix = (ENV["PAPERCLIP_STORAGE"].present? && ENV["MAIL_SERVER_URL"].present? && ENV["PAPERCLIP_STORAGE"] == "filesystem") ? ENV["MAIL_SERVER_URL"] : ""
|
||||
prefix = (!prefix.empty? && !prefix.include?("http://") && !prefix.include?("https://")) ? "http://#{prefix}" : prefix
|
||||
url = prefix + asset.url(:medium, timeout: Constants::URL_LONG_EXPIRE_TIME)
|
||||
image_tag(url)
|
||||
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"]
|
||||
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://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css'
|
||||
)
|
||||
end
|
||||
def font_awesome_cdn_link_tag
|
||||
stylesheet_link_tag(
|
||||
'https://maxcdn.bootstrapcdn.com/font-awesome' \
|
||||
'/4.6.3/css/font-awesome.min.css'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -48,6 +48,7 @@ class Asset < ActiveRecord::Base
|
|||
belongs_to :last_modified_by,
|
||||
foreign_key: 'last_modified_by_id',
|
||||
class_name: 'User'
|
||||
belongs_to :team
|
||||
has_one :step_asset,
|
||||
inverse_of: :asset,
|
||||
dependent: :destroy
|
||||
|
|
|
@ -291,8 +291,6 @@ class Protocol < ActiveRecord::Base
|
|||
)
|
||||
item2.created_by = current_user
|
||||
item2.last_modified_by = current_user
|
||||
p item
|
||||
p item2
|
||||
item2.save
|
||||
end
|
||||
|
||||
|
@ -306,6 +304,7 @@ class Protocol < ActiveRecord::Base
|
|||
asset.file_file_size
|
||||
)
|
||||
asset2.created_by = current_user
|
||||
asset2.team = dest.team
|
||||
asset2.last_modified_by = current_user
|
||||
asset2.file_processing = true if asset.is_image?
|
||||
asset2.save
|
||||
|
@ -323,6 +322,7 @@ class Protocol < ActiveRecord::Base
|
|||
table2 = Table.new(name: table.name, contents: table.contents)
|
||||
table2.created_by = current_user
|
||||
table2.last_modified_by = current_user
|
||||
table2.team = dest.team
|
||||
step2.tables << table2
|
||||
end
|
||||
end
|
||||
|
|
|
@ -105,12 +105,13 @@ class Report < ActiveRecord::Base
|
|||
el.position = index
|
||||
el.report = self
|
||||
el.parent = parent
|
||||
el.type_of = json_element["type_of"]
|
||||
el.sort_order = json_element["sort_order"]
|
||||
el.set_element_reference(json_element["id"])
|
||||
el.type_of = json_element['type_of']
|
||||
el.sort_order = json_element['sort_order']
|
||||
el.set_element_reference(json_element['id'])
|
||||
el.save!
|
||||
if json_element["children"].present?
|
||||
json_element["children"].each_with_index do |child, i|
|
||||
|
||||
if json_element['children'].present?
|
||||
json_element['children'].each_with_index do |child, i|
|
||||
save_json_element(child, i, el)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,22 +1,5 @@
|
|||
class ReportElement < ActiveRecord::Base
|
||||
enum type_of: {
|
||||
project_header: 0,
|
||||
my_module: 1,
|
||||
step: 2,
|
||||
result_asset: 3,
|
||||
result_table: 4,
|
||||
result_text: 5,
|
||||
my_module_activity: 6,
|
||||
my_module_samples: 7,
|
||||
step_checklist: 8,
|
||||
step_asset: 9,
|
||||
step_table: 10,
|
||||
step_comments: 11,
|
||||
result_comments: 12,
|
||||
project_activity: 13, # TODO
|
||||
project_samples: 14, # TODO
|
||||
experiment: 15
|
||||
}
|
||||
enum type_of: Extends::REPORT_ELEMENT_TYPES
|
||||
|
||||
# This is only used by certain elements
|
||||
enum sort_order: {
|
||||
|
@ -32,8 +15,12 @@ class ReportElement < ActiveRecord::Base
|
|||
belongs_to :report, inverse_of: :report_elements
|
||||
|
||||
# Hierarchical structure representation
|
||||
has_many :children, -> { order(:position) }, class_name: "ReportElement", foreign_key: "parent_id", dependent: :destroy
|
||||
belongs_to :parent, class_name: "ReportElement"
|
||||
has_many :children,
|
||||
-> { order(:position) },
|
||||
class_name: 'ReportElement',
|
||||
foreign_key: 'parent_id',
|
||||
dependent: :destroy
|
||||
belongs_to :parent, class_name: 'ReportElement'
|
||||
|
||||
# References to various report entities
|
||||
belongs_to :project, inverse_of: :report_elements
|
||||
|
@ -59,44 +46,18 @@ class ReportElement < ActiveRecord::Base
|
|||
|
||||
# Get the referenced element (previously, element's type_of must be set)
|
||||
def element_reference
|
||||
if project_header? or project_activity? or project_samples?
|
||||
return project
|
||||
elsif experiment?
|
||||
return experiment
|
||||
elsif my_module? or my_module_activity? or my_module_samples?
|
||||
return my_module
|
||||
elsif step? or step_comments?
|
||||
return step
|
||||
elsif result_asset? or result_table? or result_text? or result_comments?
|
||||
return result
|
||||
elsif step_checklist?
|
||||
return checklist
|
||||
elsif step_asset?
|
||||
return asset
|
||||
elsif step_table?
|
||||
return table
|
||||
ReportExtends::ELEMENT_REFERENCES.each do |el_ref|
|
||||
return eval(el_ref.element.gsub('_id', '')) if el_ref.check(self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Set the element reference (previously, element's type_of must be set)
|
||||
def set_element_reference(ref_id)
|
||||
if project_header? or project_activity? or project_samples?
|
||||
self.project_id = ref_id
|
||||
elsif experiment?
|
||||
self.experiment_id = ref_id
|
||||
elsif my_module? or my_module_activity? or my_module_samples?
|
||||
self.my_module_id = ref_id
|
||||
elsif step? or step_comments?
|
||||
self.step_id = ref_id
|
||||
elsif result_asset? or result_table? or result_text? or result_comments?
|
||||
self.result_id = ref_id
|
||||
elsif step_checklist?
|
||||
self.checklist_id = ref_id
|
||||
elsif step_asset?
|
||||
self.asset_id = ref_id
|
||||
elsif step_table?
|
||||
self.table_id = ref_id
|
||||
ReportExtends::SET_ELEMENT_REFERENCES_LIST.each do |el_ref|
|
||||
check = el_ref.check(self)
|
||||
next unless check
|
||||
public_send("#{el_ref.element}=", ref_id)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -120,18 +81,17 @@ class ReportElement < ActiveRecord::Base
|
|||
private
|
||||
|
||||
def has_one_of_referenced_elements
|
||||
num_of_refs = [
|
||||
project,
|
||||
experiment,
|
||||
my_module,
|
||||
step,
|
||||
result,
|
||||
checklist,
|
||||
asset,
|
||||
table
|
||||
].count { |r| r.present? }
|
||||
num_of_refs = [project,
|
||||
experiment,
|
||||
my_module,
|
||||
step,
|
||||
result,
|
||||
checklist,
|
||||
asset,
|
||||
table].count { |r| r.present? }
|
||||
if num_of_refs != 1
|
||||
errors.add(:base, "Report element must have exactly one element reference.")
|
||||
errors.add(:base,
|
||||
'Report element must have exactly one element reference.')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,7 @@ class Table < ActiveRecord::Base
|
|||
|
||||
belongs_to :created_by, foreign_key: 'created_by_id', class_name: 'User'
|
||||
belongs_to :last_modified_by, foreign_key: 'last_modified_by_id', class_name: 'User'
|
||||
belongs_to :team
|
||||
has_one :step_table, inverse_of: :table
|
||||
has_one :step, through: :step_table
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
module DelayedUploaderTutorial
|
||||
# Get asset from tutorial_files folder
|
||||
def self.get_asset(user, file_name)
|
||||
def self.get_asset(user, team, file_name)
|
||||
Asset.new(
|
||||
file: File.open(
|
||||
"#{Rails.root}/app/assets/tutorial_files/#{file_name}", 'r'
|
||||
),
|
||||
created_by: user,
|
||||
team: team,
|
||||
last_modified_by: user
|
||||
)
|
||||
end
|
||||
|
@ -15,11 +16,12 @@ module DelayedUploaderTutorial
|
|||
def self.generate_result_asset(
|
||||
my_module:,
|
||||
current_user:,
|
||||
current_team:,
|
||||
result_name:,
|
||||
created_at: Time.now,
|
||||
file_name:
|
||||
)
|
||||
temp_asset = get_asset(current_user, file_name)
|
||||
temp_asset = get_asset(current_user, current_team, file_name)
|
||||
temp_result = Result.new(
|
||||
created_at: created_at,
|
||||
user: current_user,
|
||||
|
@ -48,8 +50,9 @@ module DelayedUploaderTutorial
|
|||
end
|
||||
|
||||
# Adds asset to existing step
|
||||
def self.add_step_asset(step:, current_user:, file_name:)
|
||||
temp_asset = DelayedUploaderTutorial.get_asset(current_user, file_name)
|
||||
def self.add_step_asset(step:, current_user:, current_team:, file_name:)
|
||||
temp_asset =
|
||||
DelayedUploaderTutorial.get_asset(current_user, current_team, file_name)
|
||||
step.assets << temp_asset
|
||||
temp_asset.post_process_file(step.my_module.experiment.project.team)
|
||||
end
|
||||
|
|
|
@ -422,6 +422,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
my_module: my_modules[0],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
result_name: 'sF',
|
||||
created_at: generate_random_time(my_modules[0].created_at, 2.days),
|
||||
file_name: 'samples.txt'
|
||||
|
@ -440,6 +441,7 @@ module FirstTimeDataGenerator
|
|||
)
|
||||
temp_result.table = Table.new(
|
||||
created_by: user,
|
||||
team: team,
|
||||
contents: tab_content['module1']['experimental_design']
|
||||
)
|
||||
temp_result.save
|
||||
|
@ -467,6 +469,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
step: my_modules[1].protocol.steps.where('position = 0').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
file_name: 'sample-potatoe.txt'
|
||||
)
|
||||
|
||||
|
@ -474,6 +477,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
my_module: my_modules[1],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
result_name: 'PVY-inoculated plant, symptoms',
|
||||
created_at: generate_random_time(my_modules[1].created_at, 1.days),
|
||||
file_name: 'DSCN0660.JPG'
|
||||
|
@ -482,6 +486,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
my_module: my_modules[1],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
result_name: 'mock-inoculated plant',
|
||||
created_at: generate_random_time(my_modules[1].created_at, 2.days),
|
||||
file_name: 'DSCN0354.JPG'
|
||||
|
@ -490,6 +495,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
my_module: my_modules[1],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
result_name: 'Height of plants at 6dpi',
|
||||
created_at: generate_random_time(my_modules[1].created_at, 3.days),
|
||||
file_name: '6dpi_height.JPG'
|
||||
|
@ -541,6 +547,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
step: my_modules[2].protocol.steps.where('position = 1').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
file_name: 'RNeasy-Plant-Mini-Kit-EN.pdf'
|
||||
)
|
||||
|
||||
|
@ -559,6 +566,7 @@ module FirstTimeDataGenerator
|
|||
)
|
||||
temp_result.table = Table.new(
|
||||
created_by: user,
|
||||
team: team,
|
||||
contents: tab_content['module3']['nanodrop']
|
||||
)
|
||||
temp_result.save
|
||||
|
@ -581,6 +589,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
my_module: my_modules[2],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
result_name: 'Agarose gel electrophoresis of totRNA samples',
|
||||
created_at: generate_random_time(my_modules[2].created_at, 3.days),
|
||||
file_name: 'totRNA_gel.jpg'
|
||||
|
@ -599,6 +608,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
step: my_modules[3].protocol.steps.where('position = 0').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
file_name: 'G2938-90034_KitRNA6000Nano_ebook.pdf'
|
||||
)
|
||||
|
||||
|
@ -606,6 +616,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
my_module: my_modules[3],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
result_name: 'Result of RNA integrity',
|
||||
created_at: generate_random_time(my_modules[3].created_at, 2.days),
|
||||
file_name: 'Bioanalyser_result.JPG'
|
||||
|
@ -671,24 +682,28 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
step: my_modules[5].protocol.steps.where('position = 0').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
file_name: 'sample_preparation.JPG'
|
||||
)
|
||||
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
step: my_modules[5].protocol.steps.where('position = 1').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
file_name: 'reaction_setup.JPG'
|
||||
)
|
||||
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
step: my_modules[5].protocol.steps.where('position = 2').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
file_name: 'cycling_conditions.JPG'
|
||||
)
|
||||
|
||||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
step: my_modules[5].protocol.steps.where('position = 3').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
file_name: '96plate.doc'
|
||||
)
|
||||
|
||||
|
@ -702,6 +717,7 @@ module FirstTimeDataGenerator
|
|||
)
|
||||
temp_result.table = Table.new(
|
||||
created_by: user,
|
||||
team: team,
|
||||
contents: tab_content['module6']['distribution'] % {
|
||||
sample0: samples_to_assign[0].name,
|
||||
sample1: samples_to_assign[1].name,
|
||||
|
@ -729,6 +745,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
my_module: my_modules[5],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
result_name: 'Mixtures and plate setup',
|
||||
created_at: generate_random_time(my_modules[5].created_at, 2.days),
|
||||
file_name: 'Mixes_Templats.xls'
|
||||
|
@ -737,6 +754,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
my_module: my_modules[5],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
result_name: 'Raw data from ABI 7300',
|
||||
created_at: generate_random_time(my_modules[5].created_at, 3.days),
|
||||
file_name: 'BootCamp-Experiment-results-20122.sds'
|
||||
|
@ -745,6 +763,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
my_module: my_modules[5],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
result_name: 'All results - curves',
|
||||
created_at: generate_random_time(my_modules[5].created_at, 4.days),
|
||||
file_name: 'curves.JPG'
|
||||
|
@ -791,6 +810,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).add_step_asset(
|
||||
step: my_modules[7].protocol.steps.where('position = 0').take,
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
file_name: 'ddCq-quantification_diagnostics-template.xls'
|
||||
)
|
||||
|
||||
|
@ -798,6 +818,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
my_module: my_modules[7],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
result_name: 'Results of ddCq method',
|
||||
created_at: generate_random_time(my_modules[7].created_at, 1.days),
|
||||
file_name: 'ddCq-quantification_diagnostics-results.xls'
|
||||
|
@ -806,6 +827,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
my_module: my_modules[7],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
result_name: 'Dilution curve and efficiency',
|
||||
created_at: generate_random_time(my_modules[7].created_at, 2.days),
|
||||
file_name: 'dilution_curve-efficiency.JPG'
|
||||
|
@ -814,6 +836,7 @@ module FirstTimeDataGenerator
|
|||
DelayedUploaderTutorial.delay(queue: :tutorial).generate_result_asset(
|
||||
my_module: my_modules[7],
|
||||
current_user: user,
|
||||
current_team: team,
|
||||
result_name: 'Relative quantification results',
|
||||
created_at: generate_random_time(my_modules[7].created_at, 3.days),
|
||||
file_name: 'result-ddCq.JPG'
|
||||
|
|
|
@ -22,18 +22,18 @@ module ProtocolsImporter
|
|||
protocol.save!
|
||||
|
||||
# Protocol is saved, populate it
|
||||
populate_protocol(protocol, protocol_json, user)
|
||||
populate_protocol(protocol, protocol_json, user, team)
|
||||
|
||||
return protocol
|
||||
end
|
||||
|
||||
def import_into_existing(protocol, protocol_json, user)
|
||||
def import_into_existing(protocol, protocol_json, user, team)
|
||||
# Firstly, destroy existing protocol's contents
|
||||
protocol.destroy_contents(user)
|
||||
protocol.reload
|
||||
|
||||
# Alright, now populate the protocol
|
||||
populate_protocol(protocol, protocol_json, user)
|
||||
populate_protocol(protocol, protocol_json, user, team)
|
||||
protocol.reload
|
||||
|
||||
# Unlink the protocol
|
||||
|
@ -43,7 +43,7 @@ module ProtocolsImporter
|
|||
|
||||
private
|
||||
|
||||
def populate_protocol(protocol, protocol_json, user)
|
||||
def populate_protocol(protocol, protocol_json, user, team)
|
||||
protocol.reload
|
||||
|
||||
asset_ids = []
|
||||
|
@ -93,7 +93,8 @@ module ProtocolsImporter
|
|||
name: table_json['name'],
|
||||
contents: Base64.decode64(table_json['contents']),
|
||||
created_by: user,
|
||||
last_modified_by: user
|
||||
last_modified_by: user,
|
||||
team: team
|
||||
)
|
||||
StepTable.create!(
|
||||
step: step,
|
||||
|
@ -106,7 +107,8 @@ module ProtocolsImporter
|
|||
step_json["assets"].values.each do |asset_json|
|
||||
asset = Asset.new(
|
||||
created_by: user,
|
||||
last_modified_by: user
|
||||
last_modified_by: user,
|
||||
team: team
|
||||
)
|
||||
|
||||
# Decode the file bytes
|
||||
|
|
|
@ -18,4 +18,4 @@
|
|||
<div class="report-element-children">
|
||||
<%= children if (defined? children and children.present?) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,15 +5,18 @@
|
|||
team_sample_group_destroy_confirmation_path(team, sample_group) %>"
|
||||
data-color="<%= sample_group.color %>">
|
||||
<span class="sample-type-group-name"><%= sample_group.name %></span>
|
||||
<span class="pull-right sample-group-controls">
|
||||
<span class="color-picker">
|
||||
<%= bootstrap_form_for [team, sample_group], remote: true do |f| %>
|
||||
<%= f.color_picker_select :color,
|
||||
Constants::TAG_COLORS,
|
||||
class: 'edit-sample-group-color' %>
|
||||
<% end %>
|
||||
<span class="form-group">
|
||||
<input class="text-edit" style="display: none;" />
|
||||
<span class="pull-right sample-group-controls">
|
||||
<span class="color-picker">
|
||||
<%= bootstrap_form_for [team, sample_group], remote: true do |f| %>
|
||||
<%= f.color_picker_select :color,
|
||||
Constants::TAG_COLORS,
|
||||
class: 'edit-sample-group-color' %>
|
||||
<% end %>
|
||||
</span>
|
||||
<span class="edit-sample-group glyphicon glyphicon-pencil"></span>
|
||||
<span class="delete glyphicon glyphicon-trash"></span>
|
||||
</span>
|
||||
<span class="edit-sample-group glyphicon glyphicon-pencil"></span>
|
||||
<span class="delete glyphicon glyphicon-trash"></span>
|
||||
</span>
|
||||
</li>
|
||||
|
|
|
@ -4,8 +4,11 @@
|
|||
team_sample_type_destroy_confirmation_path(team, sample_type)
|
||||
%>">
|
||||
<span class="sample-type-group-name"><%= sample_type.name %></span>
|
||||
<span class="pull-right">
|
||||
<span class="edit-sample-type glyphicon glyphicon-pencil"></span>
|
||||
<span class="delete glyphicon glyphicon-trash"></span>
|
||||
<span class="form-group">
|
||||
<input class="text-edit" style="display: none;" />
|
||||
<span class="pull-right">
|
||||
<span class="edit-sample-type glyphicon glyphicon-pencil"></span>
|
||||
<span class="delete glyphicon glyphicon-trash"></span>
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
|
|
|
@ -86,7 +86,8 @@
|
|||
</span>
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu ">
|
||||
<ul class="dropdown-menu"
|
||||
data-hook="teams-dropdown">
|
||||
<%= form_for(current_user,
|
||||
url: user_current_team_path,
|
||||
method: :post) do |f| %>
|
||||
|
@ -103,9 +104,11 @@
|
|||
<% end %>
|
||||
<% end %>
|
||||
<% if current_user.teams.length > 1 %>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li data-hook="new-team-btn"
|
||||
role="separator"
|
||||
class="divider"></li>
|
||||
<% end %>
|
||||
<li>
|
||||
<li data-hook="new-team-btn">
|
||||
<%= link_to new_team_path do %>
|
||||
<span class="glyphicon glyphicon-plus"></span>
|
||||
<%= t('users.settings.teams.index.new_team') %>
|
||||
|
|
|
@ -145,7 +145,8 @@
|
|||
id="<%= cf.id %>"
|
||||
<%= 'data-editable' if can_edit_custom_field(cf) %>
|
||||
<%= 'data-deletable' if can_delete_custom_field(cf) %>
|
||||
<%= "data-edit-url='#{team_custom_field_path(@team, cf)}'" %>
|
||||
<%= "data-edit-url='#{edit_team_custom_field_path(@team, cf)}'" %>
|
||||
<%= "data-update-url='#{team_custom_field_path(@team, cf)}'" %>
|
||||
<%= "data-destroy-html-url='#{team_custom_field_destroy_html_path(@team, cf)}'" %>
|
||||
>
|
||||
<%= display_tooltip(cf.name) %>
|
||||
|
|
|
@ -190,7 +190,7 @@ class Constants
|
|||
#=============================================================================
|
||||
|
||||
# Application version
|
||||
APP_VERSION = '1.8.1'.freeze
|
||||
APP_VERSION = '1.9.0'.freeze
|
||||
|
||||
TEXT_EXTRACT_FILE_TYPES = [
|
||||
'application/pdf',
|
||||
|
|
|
@ -10,7 +10,7 @@ class Extends
|
|||
# > end
|
||||
# >
|
||||
|
||||
# Notification types. Should not be freezed, as modules might append to this.
|
||||
# Extends enum types. Should not be freezed, as modules might append to this.
|
||||
# !!!Check all addons for the correct order!!!
|
||||
NOTIFICATIONS_TYPES = { assignment: 0,
|
||||
recent_changes: 1,
|
||||
|
@ -19,4 +19,22 @@ class Extends
|
|||
|
||||
TASKS_STATES = { uncompleted: 0,
|
||||
completed: 1 }
|
||||
|
||||
REPORT_ELEMENT_TYPES = { project_header: 0,
|
||||
my_module: 1,
|
||||
step: 2,
|
||||
result_asset: 3,
|
||||
result_table: 4,
|
||||
result_text: 5,
|
||||
my_module_activity: 6,
|
||||
my_module_samples: 7,
|
||||
step_checklist: 8,
|
||||
step_asset: 9,
|
||||
step_table: 10,
|
||||
step_comments: 11,
|
||||
result_comments: 12,
|
||||
project_activity: 13, # TODO
|
||||
project_samples: 14, # TODO
|
||||
experiment: 15 }
|
||||
|
||||
end
|
||||
|
|
195
config/initializers/extends/report_extends.rb
Normal file
195
config/initializers/extends/report_extends.rb
Normal file
|
@ -0,0 +1,195 @@
|
|||
#########################################################
|
||||
# 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.
|
||||
# :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 prock which the my_module is passed and have to return a
|
||||
# collection of element
|
||||
# :singular => true by defaut change the enum type to singular
|
||||
# needed when querying partials by name
|
||||
|
||||
ModuleElement = Struct.new(:element,
|
||||
:children,
|
||||
:locals,
|
||||
:coll,
|
||||
:singular) do
|
||||
def initialize(element, children, locals, coll = nil, singular = true)
|
||||
super(element, children, locals, coll, singular)
|
||||
end
|
||||
|
||||
def collection(my_module)
|
||||
coll.call(my_module) 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
|
||||
|
||||
# Module contents element
|
||||
MODULE_CONTENTS = [
|
||||
ModuleElement.new(:steps,
|
||||
true,
|
||||
[:step],
|
||||
proc do |my_module|
|
||||
my_module.protocol.completed_steps
|
||||
end),
|
||||
ModuleElement.new(:result_assets,
|
||||
true,
|
||||
[:result],
|
||||
proc do |my_module|
|
||||
my_module.results.select { |r| r.is_asset && r.active? }
|
||||
end),
|
||||
ModuleElement.new(:result_tables,
|
||||
true,
|
||||
[:result],
|
||||
proc do |my_module|
|
||||
my_module.results.select { |r| r.is_table && r.active? }
|
||||
end),
|
||||
ModuleElement.new(:result_texts,
|
||||
true,
|
||||
[:result],
|
||||
proc do |my_module|
|
||||
my_module.results.select { |r| r.is_text && r.active? }
|
||||
end),
|
||||
ModuleElement.new(:activity,
|
||||
false,
|
||||
[:my_module, :order]),
|
||||
ModuleElement.new(:samples,
|
||||
false,
|
||||
[:my_module, :order])
|
||||
]
|
||||
|
||||
# path: app/helpers/reports_helpers.rb
|
||||
# method: render_report_element
|
||||
|
||||
# adds :order local to listed elements views
|
||||
# ADD REPORT ELEMENT TYPE WHICH YOU WANT TO PASS 'ORDER' LOCAL IN THE PARTIAL
|
||||
SORTED_ELEMENTS = %w(my_module_activity
|
||||
my_module_samples
|
||||
step_comments
|
||||
result_comments)
|
||||
# sets local :my_module to the listed my_module child elements
|
||||
MY_MODULE_ELEMENTS = %w(my_module my_module_activity my_module_samples)
|
||||
|
||||
# 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)
|
||||
|
||||
# path: app/models/report_element.rb
|
||||
# method: set_element_reference
|
||||
|
||||
ElementReference = Struct.new(:checker, :element) do
|
||||
def initialize(checker, element = :element_reference_needed!)
|
||||
super(checker, element)
|
||||
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? ||
|
||||
report_element.project_activity? ||
|
||||
report_element.project_samples?
|
||||
end,
|
||||
'project_id'
|
||||
),
|
||||
ElementReference.new(proc(&:experiment?), 'experiment_id'),
|
||||
ElementReference.new(
|
||||
proc do |report_element|
|
||||
report_element.my_module? ||
|
||||
report_element.my_module_activity? ||
|
||||
report_element.my_module_samples?
|
||||
end,
|
||||
'my_module_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? ||
|
||||
report_element.project_activity? ||
|
||||
report_element.project_samples?
|
||||
end,
|
||||
'project_id'
|
||||
),
|
||||
ElementReference.new(proc(&:experiment?), 'experiment_id'),
|
||||
ElementReference.new(
|
||||
proc do |report_element|
|
||||
report_element.my_module? ||
|
||||
report_element.my_module_activity? ||
|
||||
report_element.my_module_samples?
|
||||
end,
|
||||
'my_module_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
|
|
@ -1040,6 +1040,12 @@ en:
|
|||
start_edit_wopi_file_result: "<i>%{user}</i> started editing File %{file} on Result <strong>%{result}</strong>."
|
||||
unlock_wopi_file_step: "<i>%{user}</i> closed File %{file} for editing on Step %{step} <strong>%{step_name}</strong>."
|
||||
unlock_wopi_file_result: "<i>%{user}</i> started editing File %{file} on Result <strong>%{result}</strong>."
|
||||
load_protocol_from_file: "<i>%{user}</i> loaded protocol <strong>%{protocol}</strong> from file."
|
||||
load_protocol_from_repository: "<i>%{user}</i> loaded protocol <strong>%{protocol}</strong> from repository."
|
||||
revert_protocol: "<i>%{user}</i> reverted protocol <strong>%{protocol}</strong> from repository."
|
||||
create_report: "<i>%{user}</i> created report <strong>%{report}</strong>."
|
||||
delete_report: "<i>%{user}</i> deleted report <strong>%{report}</strong>."
|
||||
edit_report: "<i>%{user}</i> edited report <strong>%{report}</strong>."
|
||||
|
||||
user_my_modules:
|
||||
new:
|
||||
|
@ -1071,14 +1077,6 @@ en:
|
|||
create: "Add comment"
|
||||
create:
|
||||
success_flash: "Successfully added comment to result."
|
||||
load_protocol_from_file: "<i>%{user}</i> loaded protocol <strong>%{protocol}</strong> from file."
|
||||
load_protocol_from_repository: "<i>%{user}</i> loaded protocol <strong>%{protocol}</strong> from repository."
|
||||
revert_protocol: "<i>%{user}</i> reverted protocol <strong>%{protocol}</strong> from repository."
|
||||
create_report: "<i>%{user}</i> created report <strong>%{report}</strong>."
|
||||
delete_report: "<i>%{user}</i> deleted report <strong>%{report}</strong>."
|
||||
edit_report: "<i>%{user}</i> edited report <strong>%{report}</strong>."
|
||||
assign_sample: "<i>%{user}</i> assigned sample(s) <strong>%{samples}</strong> to task(s) <strong>%{tasks}</strong>."
|
||||
unassign_sample: "<i>%{user}</i> unassigned sample(s) <strong>%{samples}</strong> from task(s) <strong>%{tasks}</strong>."
|
||||
|
||||
users:
|
||||
enums:
|
||||
|
|
|
@ -132,7 +132,7 @@ Rails.application.routes.draw do
|
|||
get 'sample_group_element', to: 'sample_groups#sample_group_element'
|
||||
get 'destroy_confirmation', to: 'sample_groups#destroy_confirmation'
|
||||
end
|
||||
resources :custom_fields, only: [:create, :update, :destroy] do
|
||||
resources :custom_fields, only: [:create, :edit, :update, :destroy] do
|
||||
get 'destroy_html'
|
||||
end
|
||||
member do
|
||||
|
|
29
db/migrate/20170322095856_add_team_id_to_asset_and_tables.rb
Normal file
29
db/migrate/20170322095856_add_team_id_to_asset_and_tables.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
class AddTeamIdToAssetAndTables < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :assets, :team_id, :integer
|
||||
add_index :assets, :team_id
|
||||
|
||||
add_column :tables, :team_id, :integer
|
||||
add_index :tables, :team_id
|
||||
|
||||
Asset.find_each do |asset|
|
||||
if asset.result
|
||||
asset.update_columns(
|
||||
team_id: asset.result.my_module.experiment.project.team_id
|
||||
)
|
||||
elsif asset.step
|
||||
asset.update_columns(team_id: asset.step.protocol.team_id)
|
||||
end
|
||||
end
|
||||
|
||||
Table.find_each do |table|
|
||||
if table.result
|
||||
table.update_columns(
|
||||
team_id: table.result.my_module.experiment.project.team_id
|
||||
)
|
||||
elsif table.step
|
||||
table.update_columns(team_id: table.step.protocol.team_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue