Allow custom repositories to be added to reports

This commit is contained in:
Luka Murn 2017-06-02 13:36:06 +02:00
parent bb20d2661f
commit b5f6d1da94
9 changed files with 162 additions and 42 deletions

View file

@ -100,8 +100,8 @@ function initializeElementControls(el) {
sortCommentsElement(el, true);
} else if (el.hasClass("report-module-activity-element")) {
sortModuleActivityElement(el, true);
} else if (el.hasClass("report-module-samples-element")) {
sortModuleSamplesElement(el, true);
} else if (el.is("[data-sort-hot]")) {
sortModuleHotElement(el, true);
} else {
sortElementChildren(el, true, false);
}
@ -115,8 +115,8 @@ function initializeElementControls(el) {
sortCommentsElement(el, false);
} else if (el.hasClass("report-module-activity-element")) {
sortModuleActivityElement(el, false);
} else if (el.hasClass("report-module-samples-element")) {
sortModuleSamplesElement(el, false);
} else if (el.is("[data-sort-hot]")) {
sortModuleHotElement(el, false);
} else {
sortElementChildren(el, false, false);
}
@ -814,17 +814,18 @@ function sortModuleActivityElement(el, asc) {
}
/**
* Sort the module samples element (special handling needs
* Sort the module HoT element (special handling needs
* to be done in this case).
* @param el - The module samples element in the report.
* @param el - The module element in the report that contains handsontables.
* @param asc - True to sort in ascending order, false to sort
* in descending order.
*/
function sortModuleSamplesElement(el, asc) {
function sortModuleHotElement(el, asc) {
var hotEl = el.find(".report-element-body .hot-table-container");
var hotInstance = hotEl.handsontable("getInstance");
var col = el.attr('data-sort-hot');
hotInstance.sort(3, asc);
hotInstance.sort(col, asc);
// Update data attribute on sorting on the element
el.attr("data-order", asc ? "asc" : "desc");

View file

@ -509,6 +509,25 @@ label {
}
}
/** Module repository element */
.report-module-repository-element {
margin-bottom: 0;
.report-element-header {
border-bottom: none;
.repository-name {
margin-left: 5px;
}
}
&:hover > .report-element-header {
.repository-icon,.repository-name {
color: $color-theme-primary;
}
}
}
/** Module activity element */
.report-module-activity-element {
margin-bottom: 0;

View file

@ -70,37 +70,54 @@ module ReportActions
def generate_module_contents_json(my_module)
res = []
ReportExtends::MODULE_CONTENTS.each do |contents|
present = false
elements = []
contents.values.each do |element|
present = in_params?("module_#{element}".to_sym) ||
in_params?(element.to_sym)
break if present
end
next unless present
if contents.children
contents.collection(my_module, params).each do |report_el|
res << generate_new_el(false)
el = generate_el(
"reports/elements/my_module_#{contents.element.to_s.singularize}"\
"_element.html.erb",
contents.parse_locals([report_el])
)
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)
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 if elements.size > 0
else
present = in_params?("module_#{element}".to_sym) ||
in_params?(element.to_sym)
if present
elements << [element.to_sym, nil]
break
end
res << el
end
else
file_name = contents.file_name
file_name = contents.element if contents.element == :samples
res << generate_new_el(false)
res << generate_el(
"reports/elements/my_module_#{file_name}_element.html.erb",
contents.parse_locals([my_module, :asc])
)
end
next unless elements.size > 0
elements.each do |element, 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.merge!({ 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
file_name = contents.element if contents.element == :samples
res << generate_new_el(false)
locals = contents.parse_locals([my_module, :asc])
locals.merge!({ 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)

View file

@ -313,6 +313,29 @@ class MyModule < ActiveRecord::Base
{ data: data, headers: headers }
end
# Generate the repository rows belonging to this module
# in JSON form, suitable for display in handsontable.js
def repository_json_hot(repository_id, order)
data = []
repository_rows
.where(repository_id: repository_id)
.order(created_at: order).find_each do |row|
row_json = []
row_json << row.name
row_json << I18n.l(row.created_at, format: :full)
row_json << row.created_by.full_name
data << row_json
end
# Prepare column headers
headers = [
I18n.t('repositories.table.name'),
I18n.t('repositories.table.created_at'),
I18n.t('repositories.table.created_by')
]
{ data: data, headers: headers }
end
def deep_clone(current_user)
deep_clone_to_experiment(current_user, experiment)
end

View file

@ -0,0 +1,36 @@
<% repository = Repository.find(element_id) %>
<% if my_module.blank? and @my_module.present? then my_module = @my_module end %>
<% rows = my_module.repository_rows.where(repository: repository) %>
<% if order.blank? and @order.present? then order = @order end %>
<% timestamp = Time.current + 1.year - 1.days %>
<% rows_json = my_module.repository_json_hot(element_id, order) %>
<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}_#{repository.id}" %>" data-order="<%= order == :asc ? "asc" : "desc" %>" data-name="<%= repository.name %>" data-icon-class="glyphicon-oil">
<div class="report-element-header">
<div class="row">
<div class="pull-left repository-icon">
<span class="glyphicon glyphicon-oil"></span>
</div>
<div class="pull-left repository-name">
<%=t "projects.reports.elements.module_repository.name", repository: repository.name, my_module: my_module.name %>
</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">
<% if rows_json[:data].count > 0 %>
<input type="hidden" class="hot-table-contents hot-samples" value='<%= rows_json.to_json.force_encoding(Encoding::UTF_8) %>' />
<div class="hot-table-container"></div>
<% else %>
<div class="row">
<div class="col-xs-12">
<em><%=t "projects.reports.elements.module_repository.no_items" %></em>
</div>
</div>
<% end %>
</div>
<div class="report-element-children">
<%= children if (defined? children and children.present?) %>
</div>
</div>

View file

@ -2,7 +2,7 @@
<% if order.blank? and @order.present? then order = @order end %>
<% timestamp = Time.current + 1.year - 1.days %>
<% samples_json = my_module.samples_json_hot(order) %>
<div class="report-element report-module-samples-element" data-ts="<%= timestamp.to_i %>" data-type="my_module_samples" data-id="<%= my_module.id %>" data-order="<%= order == :asc ? "asc" : "desc" %>" data-name="<%=t "projects.reports.elements.module_samples.sidebar_name" %>" data-icon-class="glyphicon-tint">
<div class="report-element report-module-samples-element" data-sort-hot="3" data-ts="<%= timestamp.to_i %>" data-type="my_module_samples" data-id="<%= my_module.id %>" data-order="<%= order == :asc ? "asc" : "desc" %>" data-name="<%=t "projects.reports.elements.module_samples.sidebar_name" %>" data-icon-class="glyphicon-tint">
<div class="report-element-header">
<div class="row">
<div class="pull-left samples-icon">

View file

@ -69,7 +69,12 @@
<li>
<%= form.check_box :module_samples, label: t("projects.reports.elements.modals.module_contents_inner.samples") %>
</li>
<% # List all repositories, no matter whether rows are assigned or not %>
<% Repository.where(team: @project.team).order(created_at: :asc).select(:id, :name).find_each do |repository| %>
<li>
<%= form.check_box "module_repository_#{repository.id}", label: repository.name.capitalize, data: { id: repository.id } %>
</li>
<% end %>
</ul>
</li>
</ul>

View file

@ -19,15 +19,18 @@ module ReportExtends
# 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) do
def initialize(values, element, children, locals, coll = nil, singular = true)
super(values, element, children, locals, coll, singular)
: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)
@ -88,7 +91,14 @@ module ReportExtends
ModuleElement.new([:samples],
:samples,
false,
[:my_module, :order])
[:my_module, :order]),
ModuleElement.new([:repository],
:repository,
false,
[:my_module, :order],
nil,
true,
true)
]
# path: app/helpers/reports_helpers.rb

View file

@ -371,6 +371,9 @@ en:
name: "Samples of task %{my_module}"
sidebar_name: "Samples"
no_samples: "No samples"
module_repository:
name: "%{repository} of task %{my_module}"
no_items: "No items"
result_asset:
file_name: "[ %{file} ]"
user_time: "Uploaded by %{user} on %{timestamp}."
@ -1027,6 +1030,12 @@ en:
destroy_modal_submit: 'Permanently delete sample type'
destroy_flash: "\"%{name}\" sample type was successfully deleted!"
repositories:
table:
name: 'Name'
created_at: 'Added on'
created_by: 'Added by'
custom_fields:
new:
title_html: "Add new column to team <strong>%{team}</strong>"