Merge branch 'improved-sample-table' of https://github.com/biosistemika/scinote-web into zd_SCI_789

This commit is contained in:
zmagod 2016-12-15 11:03:19 +01:00
commit 9083f84396
27 changed files with 377 additions and 200 deletions

View file

@ -138,6 +138,9 @@ function dataTableInit() {
table.column(i).visible(visibility);
}
oSettings._colReorder.fnOrder(myData.ColReorder);
table.on('mousedown', function() {
$('#samples-columns-dropdown').removeClass('open');
});
}
});
@ -746,7 +749,9 @@ function createSampleTypeSelect(data, selected) {
var $selectType = $('<select></select>')
.attr('name', 'sample_type_id').addClass('show-tick');
var $option = $("<option href='/organizations/1/sample_types'></option>")
var sampleTypesLink = $('#samples').attr('data-sample-types-link');
var $option = $("<option href='" + sampleTypesLink + "'></option>")
.attr('value', -2)
.text(I18n.t('samples.table.add_sample_type'));
$selectType.append($option);
@ -774,7 +779,9 @@ function createSampleGroupSelect(data, selected) {
var $selectGroup = $('<select></select>')
.attr('name', 'sample_group_id').addClass('show-tick');
var $option = $("<option href='/organizations/1/sample_groups'></option>")
var sampleGroupsLink = $('#samples').attr('data-sample-groups-link');
var $option = $("<option href='" + sampleGroupsLink + "'></option>")
.text(I18n.t('samples.table.add_sample_group'));
$selectGroup.append($option);
$option = $('<option></option>')
@ -857,8 +864,7 @@ function changeToEditMode() {
'data-editable data-deletable ' +
'data-edit-url="' + data.edit_url + '" ' +
'data-destroy-html-url="' + data.destroy_html_url + '"' +
'>' +
data.name + '</th>');
'>' + generateColumnNameTooltip(data.name) + '</th>');
var colOrder = table.colReorder.order();
colOrder.push(colOrder.length);
// Remove all event handlers as we re-initialize them later with
@ -873,6 +879,7 @@ function changeToEditMode() {
table = dataTableInit();
table.on('init.dt', function() {
loadColumnsNames();
dropdownOverflow();
});
},
url: url
@ -914,7 +921,9 @@ function changeToEditMode() {
// loads the columns names in the dropdown list
function loadColumnsNames() {
// First, clear the list
// Save scroll position
var scrollPosition = dropdownList.scrollTop();
// Clear the list
dropdownList.find('li[data-position]').remove();
_.each(table.columns().header(), function(el, index) {
if (index > 1) {
@ -936,21 +945,20 @@ function changeToEditMode() {
'class="' + visLi + '"' +
'>' +
'<i class="grippy"></i> ' +
'<span class="text">' + el.innerText + '</span> ' +
'<span class="text">' + generateColumnNameTooltip(el.innerText) + '</span> ' +
'<span class="form-group"><input type="text" class="text-edit form-control" style="display: none;" />' +
'<span class="pull-right controls">' +
'<span class="ok glyphicon glyphicon-ok" style="display: none;"></span>' +
'<span class="cancel glyphicon glyphicon-remove" style="display: none;"></span>' +
'<span class="vis glyphicon ' + visClass + '"></span> ' +
'<span class="edit glyphicon glyphicon-pencil ' + editClass + '">' +
'</span>' +
'<span class="del glyphicon glyphicon-trash ' + delClass + '">' +
'</span></span>' +
'</span>' +
'</li>';
'<span class="edit glyphicon glyphicon-pencil ' + editClass + '"></span>' +
'<span class="del glyphicon glyphicon-trash ' + delClass + '"></span>' +
'</span></span></li>';
dropdownList.append(html);
}
});
// Restore scroll position
dropdownList.scrollTop(scrollPosition);
toggleColumnVisibility();
// toggles grip img
customLiHoverEffect();
@ -1033,9 +1041,11 @@ function changeToEditMode() {
dataType: 'json',
success: function() {
dropdownList.sortable('enable');
text.text(newName);
$(table.columns().header()).filter('#' + id).text(newName);
$(li).clearFormErrors();
text.html(generateColumnNameTooltip(newName));
$(table.columns().header()).filter('#' + id)
.html(generateColumnNameTooltip(newName));
cancelEditMode();
},
error: function(xhr, ajaxOptions, thrownError) {
@ -1142,11 +1152,13 @@ function changeToEditMode() {
var self = $(this);
var li = self.closest('li');
var url = li.attr('data-destroy-html-url');
var colIndex = originalHeader.find('#' + li.attr('data-id')).index();
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
data: {column_index: colIndex},
success: function(data) {
var modalBody = modal.find('.modal-body');
@ -1217,6 +1229,28 @@ function changeToEditMode() {
});
}
// calculate the max height of window and adjust dropdown max-height
function dropdownOverflow() {
var windowHeight = $( window ).height();
var offset = windowHeight - dropdownList.offset().top;
if(dropdownList.height() >= offset) {
dropdownList.css('maxHeight', offset);
}
}
function generateColumnNameTooltip(name) {
if( $.trim(name).length >
<%= Constants::NAME_TRUNCATION_LENGTH_DROPDOWN %>) {
return '<div class="modal-tooltip">' +
truncateLongString(name,
<%= Constants::NAME_TRUNCATION_LENGTH_DROPDOWN %>) +
'<span class="modal-tooltiptext">' + name + '</span></div>';
} else {
return name;
}
}
// initialze dropdown after the table is loaded
function initDropdown() {
table.on('init.dt', function() {
@ -1230,6 +1264,10 @@ function changeToEditMode() {
loadColumnsNames();
dropdownList.sortable('enable');
});
$('#samples-columns-dropdown').on('shown.bs.dropdown', function() {
dropdownOverflow();
})
}
initDropdown();

View file

@ -2,6 +2,7 @@
'use strict';
function showNewSampleTypeGroupForm() {
$('#create-resource').off();
$('#create-resource').on('click', function() {
$('.new-resource-form').slideDown();
$('#name-input').focus();
@ -9,20 +10,15 @@
}
function newSampleTypeFormCancel() {
$('#remove').off();
$('#remove').on('click', function() {
$('#name-input').val('');
$('.new-resource-form').slideUp();
});
}
function newSampleTypeGroupFormSubmit() {
$('#submit').on('click', function() {
var form = $(this).closest('form');
form.submit();
});
}
function submitEditSampleTypeGroupForm(button) {
function submitEditSampleTypeGroupForm() {
$('.edit-confirm').off();
$('.edit-confirm').on('click', function() {
var form = $(this).closest('form');
form.submit();
@ -30,11 +26,12 @@
}
function abortEditSampleTypeGroupAction() {
$('.abort').off();
$('.abort').on('click', function() {
var li = $(this).closest('li');
var href = $(this).attr('data-element');
var id = $(li).attr('data-id');
$().clearFormErrors();
$.ajax({
url: href,
data: { id: id },
@ -42,7 +39,7 @@
$(li).replaceWith($.parseHTML(data.html));
editSampleTypeForm();
destroySampleTypeGroup();
initSampleGroupColor();
initSampleColorPicker(li)
appendCarretToColorPickerDropdown();
editSampleGroupColor();
editSampleGroupForm();
@ -53,6 +50,7 @@
}
function destroySampleTypeGroup() {
$('.delete').off();
$('.delete').on('click', function() {
var li = $(this).closest('li');
var href = li.attr('data-delete');
@ -81,6 +79,7 @@
}
function bindNewSampleTypeAction() {
$('#new_sample_type').off();
$('#new_sample_type').bind('ajax:success', function(ev, data) {
var li = $.parseHTML(data.html);
$('#name-input').val('');
@ -88,6 +87,7 @@
$(li).insertAfter('.new-resource-form');
editSampleTypeForm();
destroySampleTypeGroup();
$('#new_sample_type').clearFormErrors();
}).bind('ajax:error', function(ev, error) {
$(this).clearFormErrors();
var msg = $.parseJSON(error.responseText);
@ -109,6 +109,7 @@
function editSampleGroupColor() {
$(document).ready(function() {
$('.edit_sample_group a.color-btn').off();
$('.edit_sample_group a.color-btn').on('click', function() {
var color = $(this).attr('data-value');
var form = $(this).closest('form');
@ -120,16 +121,18 @@
}
function bindNewSampleGroupAction() {
$('#new_sample_group').off();
$('#new_sample_group').bind('ajax:success', function(ev, data) {
var li = $.parseHTML(data.html);
$('#name-input').val('');
$('.new-resource-form').slideUp();
$(li).insertAfter('.new-resource-form');
initSampleGroupColor();
initSampleColorPicker(li);
appendCarretToColorPickerDropdown();
editSampleGroupColor();
editSampleGroupForm();
destroySampleTypeGroup();
$('#new_sample_group').clearFormErrors();
}).bind('ajax:error', function(ev, error) {
$(this).clearFormErrors();
var msg = $.parseJSON(error.responseText);
@ -140,7 +143,8 @@
}
function editSampleTypeForm() {
$('.edit').on('click', function() {
$('.edit-sample-type').off();
$('.edit-sample-type').on('click', function() {
var li = $(this).closest('li');
$.ajax({
url: li.attr('data-edit'),
@ -150,7 +154,12 @@
submitEditSampleTypeGroupForm();
abortEditSampleTypeGroupAction();
destroySampleTypeGroup();
$('#edit_sample_type_' + data.id)
.find('[name="sample_type[name]"]')
.focus();
$('#edit_sample_type_' + data.id).off();
$('#edit_sample_type_' + data.id)
.bind('ajax:success', function(ev, data) {
$(this).closest('li').replaceWith($.parseHTML(data.html));
@ -169,7 +178,8 @@
}
function editSampleGroupForm() {
$('.edit').on('click', function() {
$('.edit-sample-group').off();
$('.edit-sample-group').on('click', function() {
var li = $(this).closest('li');
$.ajax({
url: li.attr('data-edit'),
@ -179,16 +189,21 @@
submitEditSampleTypeGroupForm();
abortEditSampleTypeGroupAction();
destroySampleTypeGroup();
initSampleGroupColor();
initSampleColorPicker(li);
appendCarretToColorPickerDropdown();
editSampleGroupColor();
$('#edit_sample_group_' + data.id)
.find('[name="sample_group[name]"]')
.focus();
$('#edit_sample_group_' + data.id).off();
$('#edit_sample_group_' + data.id)
.bind('ajax:success', function(ev, data) {
$(this).closest('li').replaceWith($.parseHTML(data.html));
editSampleGroupForm();
destroySampleTypeGroup();
initSampleGroupColor();
initSampleColorPicker($(this).closest('li'));
appendCarretToColorPickerDropdown();
editSampleGroupColor();
}).bind('ajax:error', function(ev, error){
@ -212,6 +227,12 @@
});
}
function initSampleColorPicker(el) {
var element = $(el).find('.edit-sample-group-color');
var color = $(element).closest('[data-color]').attr('data-color');
$(element).colorselector('setColor', color);
}
/**
* Opens adding mode when redirected from samples page, when clicking link for
* adding sample type or group link
@ -225,7 +246,6 @@
function initSampleTypesGroups() {
showNewSampleTypeGroupForm();
newSampleTypeFormCancel();
newSampleTypeGroupFormSubmit();
bindNewSampleTypeAction();
editSampleTypeForm();
destroySampleTypeGroup();

View file

@ -1,31 +1,5 @@
//= require datatables
// Create sample group ajax
$("#modal-create-sample-group").on("show.bs.modal", function(event) {
// Clear input when modal is opened
input = $(this).find("input#name-input");
input.val("");
input.closest(".form-group").removeClass("has-error");
input.closest(".form-group").find(".help-block").remove();
});
$("#modal-create-sample-group").on("shown.bs.modal", function(event) {
$(this).find("input#name-input").focus();
});
$("form#new_sample_group").on("ajax:success", function(ev, data, status) {
$("#modal-create-sample-group").modal("hide");
updateSamplesTypesandGroups();
sampleAlertMsg(data.flash, "success");
currentMode = "viewMode";
updateButtons();
});
$("form#new_sample_group").on("ajax:error", function(e, data, status, xhr) {
$('form').renderFormErrors('sample_group', data.responseJSON, true, e);
});
// Create import samples ajax
$("#modal-import-samples").on("show.bs.modal", function(event) {
formGroup = $(this).find(".form-group");

View file

@ -2,15 +2,24 @@
* Truncate long strings where is necessary.
*/
function truncateLongString( el, chars ) {
var input = $.trim(el.text());
if($.type(el) !== 'string'){
var input = $.trim(el.text());
} else {
var input = $.trim(el);
}
var html = "";
if( el.children().hasClass("glyphicon") ){
if( $.type(el) !== 'string' &&
el.children().hasClass("glyphicon")) {
html = el.children()[0];
}
if( input.length >= chars ){
var newText = el.text().slice(0, chars);
if($.type(el) != 'string') {
var newText = el.text().slice(0, chars);
}else {
var newText = el.slice(0, chars);
}
for( var i = newText.length; i > 0; i--){
if(newText[i] === ' ' && i > 10){
newText = newText.slice(0, i);
@ -21,8 +30,14 @@ function truncateLongString( el, chars ) {
if ( html ) {
el.html(html.outerHTML + newText + '...' );
} else {
if($.type(el) === 'string'){
return newText + '...';
} else {
el.html(newText + '...' );
}
}
} else {
return el;
}
}

View file

@ -3,6 +3,11 @@
.sample_types_groups_list {
margin-top: 50px;
.sample-type-group-name {
display: inline-block;
width: 80%;
}
li {
border-bottom: 1px solid $color-alto;
padding: 15px 5px;
@ -21,13 +26,16 @@
#remove {
margin-left: 5px;
margin-top: 10px;
}
}
.form-inline .form-group,
.form-inline .form-control {
width: 100%;
}
#name-input {
padding: 5px;
width: 203px;
}
.new-resource-form {
@ -82,26 +90,6 @@
color: $color-black;
}
}
.sample-group-controls {
.edit {
margin-top: 3px;
}
.delete {
margin-top: 3px;
}
}
.sample-group-submit {
display: inline-block;
vertical-align: top;
#submit {
margin-top: 8px;
}
}
}
#new_sample_group .color-picker {

View file

@ -1453,6 +1453,7 @@ html.turbolinks-progress-bar::before {
text-align: center;
visibility: hidden;
width: 200px;
word-wrap: break-word;
z-index: $infinity;
}
}
@ -1596,11 +1597,15 @@ textarea.textarea-sm {
// new smart dropdown styles
.smart-dropdown {
max-height: 400px;
overflow-y: auto;
padding: 0;
width: 300px;
.modal-tooltiptext {
margin-left: 0;
z-index: 99999999;
}
li {
background: $color-white;
border: 1px solid $color-alto;
@ -1702,3 +1707,8 @@ textarea.textarea-sm {
.add-new-column-form .help-block {
margin-left: 0;
}
th.custom-field .modal-tooltiptext {
margin-left: 0;
z-index: 99999999;
}

View file

@ -53,7 +53,8 @@ class CustomFieldsController < ApplicationController
format.json do
render json: {
html: render_to_string(
partial: 'samples/delete_custom_field_modal_body.html.erb'
partial: 'samples/delete_custom_field_modal_body.html.erb',
locals: { column_index: params[:column_index] }
)
}
end
@ -61,9 +62,14 @@ class CustomFieldsController < ApplicationController
end
def destroy
@del_custom_field = @custom_field.dup
respond_to do |format|
format.json do
if @custom_field.destroy
SamplesTable.update_samples_table_state(
@del_custom_field,
params[:custom_field][:column_index]
)
render json: { status: :ok }
else
render json: { status: :unprocessable_entity }

View file

@ -2,6 +2,8 @@ class SampleGroupsController < ApplicationController
before_action :load_vars_nested
before_action :check_create_permissions
before_action :set_sample_group, except: [:create, :index]
before_action :set_project_my_module, only: :index
layout 'fluid'
def create
@sample_group = SampleGroup.new(sample_group_params)
@ -112,6 +114,15 @@ class SampleGroupsController < ApplicationController
private
def set_project_my_module
@project = Project.find_by_id(params[:project_id]) if params[:project_id]
@experiment = Experiment
.find_by_id(params[:experiment_id]) if params[:experiment_id]
@my_module = MyModule
.find_by_id(params[:my_module_id]) if params[:my_module_id]
render_403 unless @project || @my_module
end
def set_sample_group
@sample_group = SampleGroup.find_by_id(params[:id])
end

View file

@ -2,6 +2,8 @@ class SampleTypesController < ApplicationController
before_action :load_vars_nested
before_action :check_create_permissions
before_action :set_sample_type, except: [:create, :index]
before_action :set_project_my_module, only: :index
layout 'fluid'
def create
@sample_type = SampleType.new(sample_type_params)
@ -112,6 +114,15 @@ class SampleTypesController < ApplicationController
private
def set_project_my_module
@project = Project.find_by_id(params[:project_id]) if params[:project_id]
@experiment = Experiment
.find_by_id(params[:experiment_id]) if params[:experiment_id]
@my_module = MyModule
.find_by_id(params[:my_module_id]) if params[:my_module_id]
render_403 unless @project || @my_module
end
def load_vars_nested
@organization = Organization.find_by_id(params[:organization_id])

View file

@ -21,6 +21,7 @@ class UserSamplesController < ApplicationController
def load_samples_table_status
@samples_table_state = SamplesTable.find_status(current_user,
current_organization).first
respond_to do |format|
if @samples_table_state
format.json do

View file

@ -11,4 +11,45 @@ module ApplicationHelper
controller_name == 'projects' ||
(controller_name == 'reports' && action_name == 'index')
end
def display_tooltip(message, len = Constants::NAME_TRUNCATION_LENGTH)
if message.strip.length > Constants::NAME_TRUNCATION_LENGTH
"<div class='modal-tooltip'>#{truncate(message.strip, length: len)} \
<span class='modal-tooltiptext'>#{message.strip}</span></div>".html_safe
else
truncate(message.strip, length: len)
end
end
def sample_types_page_project?
controller_name == 'sample_types' &&
@my_module.nil? &&
@experiment.nil?
end
def sample_groups_page_project?
controller_name == 'sample_groups' &&
@my_module.nil? &&
@experiment.nil?
end
def sample_types_page_my_module?
controller_name == 'sample_types' && !@my_module.nil?
end
def sample_groups_page_my_module?
controller_name == 'sample_groups' && !@my_module.nil?
end
def sample_groups_page_experiment?
controller_name == 'sample_groups' &&
@my_module.nil? &&
!@experiment.nil?
end
def sample_types_page_expermient?
controller_name == 'sample_types' &&
@my_module.nil? &&
!@experiment.nil?
end
end

View file

@ -18,6 +18,6 @@ class CustomField < ActiveRecord::Base
after_create :update_samples_table_state
def update_samples_table_state
SamplesTable.update_samples_table_state(self)
SamplesTable.update_samples_table_state(self, nil)
end
end

View file

@ -5,16 +5,37 @@ class SamplesTable < ActiveRecord::Base
belongs_to :organization, inverse_of: :samples_tables
scope :find_status,
->(org, user) { where(user: user, organization: org).pluck(:status) }
->(user, org) { where(user: user, organization: org).pluck(:status) }
def self.update_samples_table_state(custom_field)
def self.update_samples_table_state(custom_field, column_index)
samples_table = SamplesTable.where(user: custom_field.user,
organization: custom_field.organization)
org_status = samples_table.first['status']
index = org_status['columns'].count
org_status['columns'][index] = SampleDatatable::
SAMPLES_TABLE_DEFAULT_STATE['columns'].first
org_status['ColReorder'] << index.to_s
if column_index
org_status['columns'].delete(column_index)
org_status['columns'].keys.each do |index|
p index
if index.to_i > column_index.to_i
org_status['columns'][(index.to_i - 1).to_s] =
org_status['columns'].delete(index)
else
index
end
end
org_status['ColReorder'].delete(column_index)
org_status['ColReorder'].map! do |index|
if index.to_i > column_index.to_i
(index.to_i - 1).to_s
else
index
end
end
else
index = org_status['columns'].count
org_status['columns'][index] = SampleDatatable::
SAMPLES_TABLE_DEFAULT_STATE['columns'].first
org_status['ColReorder'] << index.to_s
end
samples_table.first.update(status: org_status)
end

View file

@ -4,28 +4,23 @@
sample_group)%>"
data-color="<%= sample_group.color %>">
<div class="row">
<div class="col-xs-6">
<%= form_for [organization, sample_group], html: { class: 'form-inline' }, remote: true do |f| %>
<div class="form-group">
<%= f.text_field :name, value: sample_group.name , class: 'form-control' %>
<span class="edit-confirm glyphicon glyphicon-ok"></span>
<span class="abort glyphicon glyphicon-remove"
data-element="<%= organization_sample_group_sample_group_element_path(organization,
sample_group) %>"></span>
<div class="col-xs-8">
<div class="form-group">
<%= f.text_field :name, value: sample_group.name , class: 'form-control' %>
</div>
</div>
<div class="col-xs-4 text-right">
<button type="button"
class="edit-confirm btn btn-primary"><%= t('general.edit') %></button>
<button type="button"
class="abort btn btn-default"
data-element="<%=
organization_sample_group_sample_group_element_path(organization,
sample_group) %>">
<%= t('general.cancel') %></button>
</div>
<% end %>
</div>
<div class="col-xs-6 text-right">
<span class="pull-right sample-group-controls">
<span class="color-picker">
<%= bootstrap_form_for [organization, sample_group], remote: true do |f| %>
<%= f.color_picker_select :color,
Constants::TAG_COLORS,
class: 'edit-sample-group-color' %>
<% end %>
</span>
<span class="delete glyphicon glyphicon-trash"></span>
</span>
</div>
</div>
</li>

View file

@ -5,7 +5,7 @@
organization_sample_group_destroy_confirmation_path(organization,
sample_group) %>"
data-color="<%= sample_group.color %>">
<%= sample_group.name %>
<span class="sample-type-group-name"><%= sample_group.name %></span>
<span class="pull-right sample-group-controls">
<span class="color-picker">
<%= bootstrap_form_for [organization, sample_group], remote: true do |f| %>
@ -14,7 +14,7 @@
class: 'edit-sample-group-color' %>
<% end %>
</span>
<span class="edit glyphicon glyphicon-pencil"></span>
<span class="edit-sample-group glyphicon glyphicon-pencil"></span>
<span class="delete glyphicon glyphicon-trash"></span>
</span>
</li>

View file

@ -1,14 +1,22 @@
<% provide(:head_title, t('sample_groups.index.head_title')) %>
<%= render partial: "shared/sidebar" %>
<%= render partial: "shared/secondary_navigation" %>
<% if current_organization %>
<ul class="nav nav-tabs nav-settings" data-position="bottom">
<li role="presentation">
<%= link_to t('sample_types.index.sample_types'),
organization_sample_types_path(current_organization) %>
organization_sample_types_path(current_organization,
project_id: (@project.id if @project),
my_module_id: (@my_module.id if @my_module),
experiment_id: (@experiment.id if @experiment)) %>
</li>
<li role="presentation" class="active">
<%= link_to t('sample_types.index.sample_groups'),
organization_sample_groups_path(current_organization) %>
organization_sample_groups_path(current_organization,
project_id: (@project.id if @project),
my_module_id: (@my_module.id if @my_module),
experiment_id: (@experiment.id if @experiment)) %>
</li>
</ul>
<div class="tab-content">
@ -21,27 +29,25 @@
<ul class="list-unstyled sample_types_groups_list"
id="sample_groups_list">
<li class="new-resource-form">
<%= bootstrap_form_for SampleGroup.new,
remote: true,
html: { class: 'form-inline' },
url: organization_sample_groups_path(current_organization) do |f| %>
<%= f.text_field :name,
id: 'name-input',
class: 'form-control',
hide_label: true %>
<div class="sample-group-submit">
<span id="submit" class="glyphicon glyphicon-ok"></span>
</div>
<span class="pull-right sample-group-controls">
<span class="color-picker">
<%= f.color_picker_select :color,
Constants::TAG_COLORS,
class: 'new-sample-group-color' %>
</span>
<span id="remove" class="glyphicon glyphicon-trash"></span>
</span>
<% end %>
<div class="row">
<%= bootstrap_form_for SampleGroup.new,
remote: true,
html: { class: 'form-inline' },
url: organization_sample_groups_path(current_organization) do |f| %>
<div class="col-xs-8">
<%= f.text_field :name,
id: 'name-input',
class: 'form-control',
hide_label: true %>
</div>
<div class="col-xs-4 text-right">
<button id="submit"
class="btn btn-primary"><%= t('general.create') %></button>
<button id="remove"
class="btn btn-default"><%= t('general.cancel') %></button>
</div>
<% end %>
</div>
</li>
<% @sample_groups.sorted.each do |sample_group| %>
<%= render partial: 'sample_group',

View file

@ -3,20 +3,22 @@
organization_sample_type_destroy_confirmation_path(organization, sample_type)
%>">
<div class="row">
<div class="col-xs-6">
<%= form_for [organization, sample_type], html: { class: 'form-inline' }, remote: true do |f| %>
<div class="form-group">
<%= f.text_field :name, value: sample_type.name , class: 'form-control' %>
<span class="edit-confirm glyphicon glyphicon-ok"></span>
<span class="abort glyphicon glyphicon-remove"
data-element="<%=
organization_sample_type_sample_type_element_path(organization,
sample_type) %>"></span>
<div class="col-xs-8">
<div class="form-group">
<%= f.text_field :name, value: sample_type.name , class: 'form-control' %>
</div>
</div>
<div class="col-xs-4 text-right">
<button type="button"
class="edit-confirm btn btn-primary"><%= t('general.edit') %></button>
<button type="button"
class="abort btn btn-default"
data-element="<%=
organization_sample_type_sample_type_element_path(organization,
sample_type) %>">
<%= t('general.cancel') %></button>
</div>
<% end %>
</div>
<div class="col-xs-6 text-right">
<span class="delete glyphicon glyphicon-trash"></span>
</div>
</div>
</li>

View file

@ -6,9 +6,9 @@
data-delete="<%=
organization_sample_type_destroy_confirmation_path(organization, sample_type)
%>">
<%= sample_type.name %>
<span class="sample-type-group-name"><%= sample_type.name %></span>
<span class="pull-right">
<span class="edit glyphicon glyphicon-pencil"></span>
<span class="edit-sample-type glyphicon glyphicon-pencil"></span>
<span class="delete glyphicon glyphicon-trash"></span>
</span>
</li>

View file

@ -1,14 +1,22 @@
<% provide(:head_title, t('sample_types.index.head_title')) %>
<%= render partial: "shared/sidebar" %>
<%= render partial: "shared/secondary_navigation" %>
<% if current_organization %>
<ul class="nav nav-tabs nav-settings" data-position="bottom">
<li role="presentation" class="active">
<%= link_to t('sample_types.index.sample_types'),
organization_sample_types_path(current_organization) %>
organization_sample_types_path(current_organization,
project_id: (@project.id if @project),
my_module_id: (@my_module.id if @my_module),
experiment_id: (@experiment.id if @experiment)) %>
</li>
<li role="presentation">
<%= link_to t('sample_types.index.sample_groups'),
organization_sample_groups_path(current_organization) %>
organization_sample_groups_path(current_organization,
project_id: (@project.id if @project),
my_module_id: (@my_module.id if @my_module),
experiment_id: (@experiment.id if @experiment)) %>
</li>
</ul>
<div class="tab-content">
@ -20,18 +28,25 @@
<ul class="list-unstyled sample_types_groups_list"
id="sample_types_list">
<li class="new-resource-form">
<%= form_for SampleType.new,
remote: true,
html: { class: 'form-inline' },
url: organization_sample_types_path(current_organization) do |f| %>
<div class="form-group">
<%= f.text_field :name, id: 'name-input', class: 'form-control' %>
<span id="submit" class="glyphicon glyphicon-ok"></span>
</div>
<span class="pull-right">
<span id="remove" class="glyphicon glyphicon-trash"></span>
</span>
<% end %>
<div class="row">
<%= form_for SampleType.new,
remote: true,
html: { class: 'form-inline' },
url: organization_sample_types_path(current_organization) do |f| %>
<div class="col-xs-8">
<div class="form-group">
<%= f.text_field :name, id: 'name-input', class: 'form-control' %>
</div>
</div>
<div class="text-right col-md-4">
<button id="submit"
class="btn btn-primary"><%= t('general.create') %></button>
<button id="remove"
class="btn btn-default"><%= t('general.cancel') %></button>
</div>
<% end %>
</div>
</li>
<% @sample_types.sorted.each do |sample_type| %>
<%= render partial: 'sample_type',

View file

@ -1,20 +0,0 @@
<div class="modal fade" id="modal-create-sample-group" tabindex="-1" role="dialog" aria-labelledby="modal-create-sample-group-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">&times;</span></button>
<h4 class="modal-title"><%= t("samples.modal_add_new_sample_group.title_html", organization: @organization.name) %></h4>
</div>
<%= bootstrap_form_for SampleGroup.new, remote: true, url: organization_sample_groups_path(@organization) do |f| %>
<div class="modal-body">
<%= f.text_field :name, id: "name-input" %>
<%= f.color_picker_btn_group :color, Constants::TAG_COLORS, id: "color-input", class: "btn-group-sample-group-color", label: t("sample_groups.color_label")%>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><%= t("general.cancel")%></button>
<input type="submit" class="btn btn-primary" value="<%= t("samples.modal_add_new_sample_group.create")%>"</input>
</div>
<% end %>
</div>
</div>
</div>

View file

@ -1,4 +1,5 @@
<%= bootstrap_form_for @custom_field, url: organization_custom_field_path(@organization, @custom_field, format: :json), remote: :true, method: :delete, data: { role: "destroy-custom-field-form", id: @custom_field.id } do |f| %>
<%= f.hidden_field :column_index, value: column_index %>
<p><%= t("samples.modal_delete_custom_field.message", cf: @custom_field.name) %></p>
<div class="alert alert-danger" role="alert">
<span class="glyphicon glyphicon-exclamation-sign"></span>
@ -9,4 +10,4 @@
<li><%= t("samples.modal_delete_custom_field.alert_line_2") %></li>
</ul>
</div>
<% end %>
<% end %>

View file

@ -1,7 +1,7 @@
<%= render partial: "samples/import_samples_modal" %>
<%= render partial: "samples/delete_samples_modal" %>
<%= render partial: "samples/create_sample_group_modal" %>
<%= render partial: "samples/delete_custom_field_modal" %>
<!-- Modal for parsing sample sheets should be empty at first -->
<div class="modal fade" id="modal-parse-samples" tabindex="-1" role="dialog" aria-labelledby=="modal-parse-samples-label"></div>
@ -67,7 +67,10 @@
<% if can_add_sample_related_things_to_organization %>
<div class="dropdown pull-right" style="display: inline;">
<%= link_to(t('samples.types_and_groups'),
organization_sample_types_path(@organization),
organization_sample_types_path(@organization,
project_id: (@project.id if @project),
my_module_id: (@my_module.id if @my_module),
experiment_id: (@experiment.id if @experiment)),
class: 'btn btn-default' ) %>
</div>
<% end %>
@ -126,6 +129,14 @@
data-num-columns="<%= num_of_columns %>"
data-new-sample="<%= new_organization_sample_path(organization_id: @organization) %>"
data-create-sample="<%= organization_samples_path(organization_id: @organization) %>"
data-sample-types-link="<%= organization_sample_types_path(@organization,
project_id: (@project.id if @project),
my_module_id: (@my_module.id if @my_module),
experiment_id: (@experiment.id if @experiment)) %>"
data-sample-groups-link="<%= organization_sample_groups_path(current_organization,
project_id: (@project.id if @project),
my_module_id: (@my_module.id if @my_module),
experiment_id: (@experiment.id if @experiment)) %>"
>
<thead>
<tr>
@ -144,7 +155,7 @@
<%= "data-edit-url='#{organization_custom_field_path(@organization, cf)}'" %>
<%= "data-destroy-html-url='#{organization_custom_field_destroy_html_path(@organization, cf)}'" %>
>
<%= cf.name %>
<%= display_tooltip(cf.name) %>
</th>
<% end %>
</tr>

View file

@ -22,7 +22,9 @@
</a>
<% end %>
</li>
<% if project_page? %>
<% if project_page? ||
sample_types_page_project? ||
sample_groups_page_project? %>
<li class="active">
<span class="glyphicon glyphicon-blackboard"></span>
</li>
@ -37,7 +39,8 @@
<% end %>
</li>
<% end %>
<% if experiment_page? || module_page? %>
<% if experiment_page? ||
module_page? %>
<% if !module_page? %>
<li class="active">
<%= fa_icon 'fa-flask' %>
@ -67,7 +70,9 @@
<!-- True secondary navigation (buttons on the right side) -->
<ul class="nav navbar-nav navbar-right" style="vertical-align: bottom">
<% if project_page? %>
<% if project_page? ||
sample_types_page_project? ||
sample_groups_page_project? %>
<% if can_view_project(@project) then %>
<li id="canvas-nav-tab" class="<%= "active" if is_project_show? %>">
<a href="<%= project_url(@project) %>" title="<%=t "nav2.projects.show" %>">
@ -77,7 +82,9 @@
</li>
<% end %>
<% if can_view_project_samples(@project) then %>
<li id="project-samples-nav-tab" class="<%= "active" if is_project_samples? %>">
<li id="project-samples-nav-tab" class="<%= "active" if is_project_samples? ||
sample_types_page_project? ||
sample_groups_page_project? %>">
<a href="<%= samples_project_url(@project) %>" title="<%=t "nav2.projects.samples" %>">
<span class="hidden-sm hidden-md"><%=t "nav2.projects.samples" %></span>
<span class="hidden-xs hidden-lg glyphicon glyphicon-tint"></span>
@ -98,7 +105,9 @@
</li>
<% end %>
<% elsif experiment_page? %>
<% elsif experiment_page? ||
sample_groups_page_experiment? ||
sample_types_page_expermient? %>
<% if can_view_experiment(@experiment) then %>
<li id="canvas-nav-tab" class="<%= "active" if is_experiment_canvas? %>">
<a href="<%= canvas_experiment_url(@experiment) %>" title="<%=t "nav2.experiments.canvas" %>">
@ -108,7 +117,9 @@
</li>
<% end %>
<% if can_view_experiment_samples(@experiment) then %>
<li id="experiment-samples-nav-tab" class="<%= "active" if is_experiment_samples? %>">
<li id="experiment-samples-nav-tab" class="<%= "active" if is_experiment_samples? ||
sample_groups_page_experiment? ||
sample_types_page_expermient? %>">
<a href="<%= samples_experiment_url(@experiment) %>" title="<%=t "nav2.projects.samples" %>">
<span class="hidden-sm hidden-md"><%=t "nav2.projects.samples" %></span>
<span class="hidden-xs hidden-lg glyphicon glyphicon-tint"></span>
@ -129,7 +140,9 @@
</li>
<% end %>
<% elsif module_page? %>
<% elsif module_page? ||
sample_types_page_my_module? ||
sample_groups_page_my_module? %>
<% if can_view_module_protocols(@my_module) then %>
<li id="steps-nav-tab" class="<%= "active" if is_module_protocols? %>">
<a href="<%= protocols_my_module_url(@my_module) %>" title="<%=t "nav2.modules.steps" %>">
@ -155,7 +168,9 @@
</li>
<% end %>
<% if can_view_module_samples(@my_module) then %>
<li id="module-samples-nav-tab" class="<%= "active" if is_module_samples? %>">
<li id="module-samples-nav-tab" class="<%= "active" if is_module_samples? ||
sample_types_page_my_module? ||
sample_groups_page_my_module? %>">
<a href="<%= samples_my_module_url(@my_module) %>" title="<%=t "nav2.modules.samples" %>">
<span class="hidden-sm hidden-md"><%=t "nav2.modules.samples" %></span>
<span class="hidden-xs hidden-lg glyphicon glyphicon-tint"></span>
@ -209,8 +224,15 @@
<% end %>
</li>
<% end %>
<% if experiment_page? || module_page? %>
<% if !module_page? %>
<% if experiment_page? ||
module_page? ||
sample_types_page_my_module? ||
sample_groups_page_my_module? ||
sample_groups_page_experiment? ||
sample_types_page_expermient? %>
<% if !module_page? &&
!sample_types_page_my_module? &&
!sample_groups_page_my_module? %>
<li class="active">
<%= truncate(@experiment.name,
length: Constants::NAME_TRUNCATION_LENGTH) %>
@ -228,7 +250,9 @@
</li>
<% end %>
<% end %>
<% if module_page? %>
<% if module_page? ||
sample_types_page_my_module? ||
sample_groups_page_my_module? %>
<li class="active">
<%= truncate(@my_module.name,
length: Constants::NAME_TRUNCATION_LENGTH) %>

View file

@ -14,7 +14,9 @@
<div class="tree">
<ul>
<% if project_page? %>
<% if project_page? ||
sample_types_page_project? ||
sample_groups_page_project? %>
<li class="active">
<span class="tree-link line-wrap">
<i></i>

View file

@ -1,7 +1,9 @@
<ul>
<% if project.active_experiments.present? then %>
<% project.active_experiments.each do |experiment| %>
<% if experiment_page? && experiment == @experiment %>
<% if (experiment_page? ||
sample_groups_page_experiment? ||
sample_types_page_expermient?) && experiment == @experiment %>
<li class="active" data-parent="candidate">
<span class="tree-link line-wrap">
<i></i>

View file

@ -9,6 +9,8 @@ class Constants
NAME_MAX_LENGTH = 255
# Max characters for short text fields, after which they get truncated
NAME_TRUNCATION_LENGTH = 25
# Max characters for short text fields, in dropdownList
NAME_TRUNCATION_LENGTH_DROPDOWN = 20
# Max characters for long text fields
TEXT_MAX_LENGTH = 10000
# Max characters for rich text fields (in html format)

View file

@ -890,7 +890,7 @@ en:
head_title: 'Sample Types'
sample_types: 'Sample types'
sample_groups: 'Sample groups'
new: 'Create Sample type'
new: 'Create sample type'
destroy_modal_title: "Permanently delete the \"%{name}\" sample type?"
destroy_modal_body: 'This action is irreversible and makes the sample type inaccessible to all team members.'
destroy_modal_submit: 'Permanently delete sample type'
@ -1453,6 +1453,7 @@ en:
edit: "Edit"
cancel: "Cancel"
close: "Close"
create: 'Create'
check_all: "Check all"
no_comments: "No comments!"
more_comments: "More comments"