mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-20 14:45:56 +08:00
Merge branch 'master' into rails-5.1
Conflicts: app/models/repository.rb app/models/repository_row.rb app/views/projects/index.html.erb app/views/shared/_secondary_navigation.html.erb
This commit is contained in:
commit
9f60ece25f
|
@ -47,6 +47,7 @@
|
|||
|
||||
// Populate the errors container
|
||||
$('#import-errors-container').html(data.responseJSON.html);
|
||||
animateSpinner(null, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -148,6 +148,7 @@ function dataTableInit() {
|
|||
data = myData;
|
||||
}
|
||||
$.ajax({
|
||||
async: false,
|
||||
url: '/repositories/' + repositoryId + '/state_save',
|
||||
data: {state: data},
|
||||
dataType: 'json',
|
||||
|
|
|
@ -76,7 +76,14 @@
|
|||
Comments.initialize();
|
||||
initNewResultAsset();
|
||||
}).on('ajax:error', function(e, xhr) {
|
||||
$form.renderFormErrors('result', xhr.responseJSON, true, e);
|
||||
var errors = xhr.responseJSON.errors;
|
||||
var formInput = $form.find('#result_asset_attributes_file');
|
||||
$('[data-status="error"]').remove();
|
||||
$.each(errors, function(key, value) {
|
||||
var message = '<span data-status="error" style="color: #a94442">';
|
||||
message += value + '</span>';
|
||||
formInput.after(message);
|
||||
})
|
||||
animateSpinner(null, false);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -46,5 +46,6 @@ $('form#form-import')
|
|||
|
||||
// Populate the errors container
|
||||
$('#import-errors-container').html(data.responseJSON.html);
|
||||
animateSpinner(null, false);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -583,6 +583,19 @@ a[data-toggle="tooltip"] {
|
|||
background-color: $color-emperor;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.repositories-team {
|
||||
padding: 10px 15px;
|
||||
|
||||
&.active {
|
||||
color: $color-theme-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.repository-search {
|
||||
padding-left: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -226,18 +226,33 @@ class RepositoriesController < ApplicationController
|
|||
end
|
||||
|
||||
def import_records
|
||||
import_records = repostiory_import_actions
|
||||
status = import_records.import!
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
if status[:status] == :ok
|
||||
flash[:success] = t('repositories.import_records.success_flash',
|
||||
number_of_rows: status[:nr_of_added])
|
||||
render json: {}, status: :ok
|
||||
# Check if there exist mapping for repository record (it's mandatory)
|
||||
if params[:mappings].value?('-1')
|
||||
import_records = repostiory_import_actions
|
||||
status = import_records.import!
|
||||
|
||||
if status[:status] == :ok
|
||||
flash[:success] = t('repositories.import_records.success_flash',
|
||||
number_of_rows: status[:nr_of_added])
|
||||
render json: {}, status: :ok
|
||||
else
|
||||
flash[:alert] = t('repositories.import_records.error_flash',
|
||||
message: status[:errors])
|
||||
render json: {}, status: :unprocessable_entity
|
||||
end
|
||||
else
|
||||
flash[:alert] = t('repositories.import_records.error_flash',
|
||||
message: status[:errors])
|
||||
render json: {}, status: :unprocessable_entity
|
||||
render json: {
|
||||
html: render_to_string(
|
||||
partial: 'shared/flash_errors.html.erb',
|
||||
locals: { error_title: t('repositories.import_records'\
|
||||
'.error_message.errors_list_title'),
|
||||
error: t('repositories.import_records.error_message'\
|
||||
'.no_repository_name') }
|
||||
)
|
||||
},
|
||||
status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,6 +17,9 @@ class SearchController < ApplicationController
|
|||
search_steps if @search_category == :steps
|
||||
search_checklists if @search_category == :checklists
|
||||
search_samples if @search_category == :samples
|
||||
if @search_category == :repositories && params[:repository]
|
||||
search_repository
|
||||
end
|
||||
search_assets if @search_category == :assets
|
||||
search_tables if @search_category == :tables
|
||||
search_comments if @search_category == :comments
|
||||
|
@ -106,6 +109,39 @@ class SearchController < ApplicationController
|
|||
whole_phrase: @search_whole_phrase).size
|
||||
end
|
||||
|
||||
def count_by_repository
|
||||
count_total = 0
|
||||
search_results = Repository.search(current_user,
|
||||
true,
|
||||
@search_query,
|
||||
Constants::SEARCH_NO_LIMIT,
|
||||
nil,
|
||||
match_case: @search_case,
|
||||
whole_word: @search_whole_word,
|
||||
whole_phrase: @search_whole_phrase)
|
||||
@repository_search_count = {}
|
||||
current_user.teams.includes(:repositories).each do |team|
|
||||
team_results = {}
|
||||
team_results[:count] = 0
|
||||
team_results[:repositories] = {}
|
||||
team.repositories.each do |repository|
|
||||
repository_results = {}
|
||||
repository_results[:id] = repository.id
|
||||
repository_results[:count] = 0
|
||||
search_results.each do |result|
|
||||
if repository.id == result.id
|
||||
count_total += result.counter
|
||||
repository_results[:count] += result.counter
|
||||
end
|
||||
end
|
||||
team_results[:repositories][repository.name] = repository_results
|
||||
team_results[:count] += repository_results[:count]
|
||||
end
|
||||
@repository_search_count[team.name] = team_results
|
||||
end
|
||||
count_total
|
||||
end
|
||||
|
||||
def count_search_results
|
||||
@project_search_count = count_by_name Project
|
||||
@experiment_search_count = count_by_name Experiment
|
||||
|
@ -118,6 +154,7 @@ class SearchController < ApplicationController
|
|||
@step_search_count = count_by_name Step
|
||||
@checklist_search_count = count_by_name Checklist
|
||||
@sample_search_count = count_by_name Sample
|
||||
@repository_search_count_total = count_by_repository
|
||||
@asset_search_count = count_by_name Asset
|
||||
@table_search_count = count_by_name Table
|
||||
@comment_search_count = count_by_name Comment
|
||||
|
@ -133,6 +170,7 @@ class SearchController < ApplicationController
|
|||
@search_results_count += @step_search_count
|
||||
@search_results_count += @checklist_search_count
|
||||
@search_results_count += @sample_search_count
|
||||
@search_results_count += @repository_search_count_total
|
||||
@search_results_count += @asset_search_count
|
||||
@search_results_count += @table_search_count
|
||||
@search_results_count += @comment_search_count
|
||||
|
@ -210,6 +248,20 @@ class SearchController < ApplicationController
|
|||
@search_count = @sample_search_count
|
||||
end
|
||||
|
||||
def search_repository
|
||||
@repository = Repository.find_by_id(params[:repository])
|
||||
render_403 unless can_view_repository(@repository)
|
||||
@repository_results = []
|
||||
if @repository_search_count_total > 0
|
||||
@repository_results =
|
||||
RepositoryRow.search(@repository, @search_query, @search_page,
|
||||
match_case: @search_case,
|
||||
whole_word: @search_whole_word,
|
||||
whole_phrase: @search_whole_phrase)
|
||||
end
|
||||
@search_count = @repository_search_count_total
|
||||
end
|
||||
|
||||
def search_assets
|
||||
@asset_results = []
|
||||
@asset_results = search_by_name(Asset) if @asset_search_count > 0
|
||||
|
|
|
@ -225,7 +225,8 @@ module ApplicationHelper
|
|||
user_name << ' ' + I18n.t('atwho.res.removed') if !user_still_in_team
|
||||
|
||||
raw("<img src='#{user_avatar_absolute_url(user, :icon_small)}'" \
|
||||
"alt='avatar' class='atwho-user-img-popover'>") +
|
||||
"alt='avatar' class='atwho-user-img-popover'" \
|
||||
" ref='#{'missing-img' if missing_avatar(user, :icon_small)}'>") +
|
||||
raw('<a onClick="$(this).popover(\'show\')" ' \
|
||||
'class="atwho-user-popover" data-container="body" ' \
|
||||
'data-html="true" tabindex="0" data-trigger="focus" ' \
|
||||
|
@ -253,9 +254,14 @@ module ApplicationHelper
|
|||
end
|
||||
end
|
||||
|
||||
unless user.avatar(style) == '/images/icon_small/missing.png'
|
||||
unless missing_avatar(user, style)
|
||||
return user.avatar(style, timeout: Constants::URL_LONG_EXPIRE_TIME)
|
||||
end
|
||||
url_for(prefix + "/images/#{style}/missing.png")
|
||||
end
|
||||
|
||||
def missing_avatar(user, style)
|
||||
user.avatar(style) == '/images/icon_small/missing.png' ||
|
||||
user.avatar(style) == '/images/thumb/missing.png'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -100,11 +100,17 @@ module ReportsHelper
|
|||
"<span class=\"label label-#{style}\">#{text}</span>".html_safe
|
||||
end
|
||||
|
||||
def sanitize_report_pdf(text, tags = [], attributes = [])
|
||||
ActionController::Base.helpers.sanitize(
|
||||
text,
|
||||
tags: Constants::WHITELISTED_TAGS + tags,
|
||||
attributes: Constants::WHITELISTED_ATTRIBUTES + attributes
|
||||
)
|
||||
# Fixes issues with avatar images in reports
|
||||
def fix_smart_annotation_image(html)
|
||||
html_doc = Nokogiri::HTML(html)
|
||||
html_doc.search('.atwho-user-popover').each do |el|
|
||||
text = el.content
|
||||
el.replace("<a href='#' style='margin-left: 5px'>#{text}</a>")
|
||||
end
|
||||
html_doc.search('[ref="missing-img"]').each do |el|
|
||||
tag = wicked_pdf_image_tag('icon_small/missing.png')
|
||||
el.replace(tag)
|
||||
end
|
||||
html_doc.to_s
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
class Repository < ApplicationRecord
|
||||
include SearchableModel
|
||||
|
||||
belongs_to :team, optional: true
|
||||
belongs_to :created_by,
|
||||
foreign_key: :created_by_id,
|
||||
class_name: 'User',
|
||||
optional: true
|
||||
has_many :repository_columns
|
||||
has_many :repository_rows
|
||||
has_many :repository_table_states,
|
||||
inverse_of: :repository, dependent: :destroy
|
||||
|
@ -18,6 +19,47 @@ class Repository < ApplicationRecord
|
|||
validates :team, presence: true
|
||||
validates :created_by, presence: true
|
||||
|
||||
def self.search(
|
||||
user,
|
||||
_include_archived,
|
||||
query = nil,
|
||||
page = 1,
|
||||
current_team = nil,
|
||||
options = {}
|
||||
)
|
||||
team_ids =
|
||||
if current_team
|
||||
current_team.id
|
||||
else
|
||||
Team.joins(:user_teams)
|
||||
.where('user_teams.user_id = ?', user.id)
|
||||
.distinct
|
||||
.pluck(:id)
|
||||
end
|
||||
|
||||
row_ids = RepositoryRow
|
||||
.search(nil, query, Constants::SEARCH_NO_LIMIT, options)
|
||||
.select(:id)
|
||||
|
||||
new_query = Repository
|
||||
.select('repositories.*, COUNT(repository_rows.id) AS counter')
|
||||
.joins(:team)
|
||||
.joins('LEFT OUTER JOIN repository_rows ON ' \
|
||||
'repositories.id = repository_rows.repository_id')
|
||||
.where(team: team_ids)
|
||||
.where('repository_rows.id IN (?)', row_ids)
|
||||
.group('repositories.id')
|
||||
|
||||
# Show all results if needed
|
||||
if page == Constants::SEARCH_NO_LIMIT
|
||||
new_query
|
||||
else
|
||||
new_query
|
||||
.limit(Constants::SEARCH_LIMIT)
|
||||
.offset((page - 1) * Constants::SEARCH_LIMIT)
|
||||
end
|
||||
end
|
||||
|
||||
def open_spreadsheet(file)
|
||||
filename = file.original_filename
|
||||
file_path = file.path
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
class RepositoryRow < ApplicationRecord
|
||||
include SearchableModel
|
||||
|
||||
belongs_to :repository, optional: true
|
||||
belongs_to :created_by,
|
||||
foreign_key: :created_by_id,
|
||||
|
@ -19,4 +21,47 @@ class RepositoryRow < ApplicationRecord
|
|||
presence: true,
|
||||
length: { maximum: Constants::NAME_MAX_LENGTH }
|
||||
validates :created_by, presence: true
|
||||
|
||||
def self.search(repository, query, page = 1, options)
|
||||
new_query = distinct
|
||||
.joins(:created_by)
|
||||
.joins(
|
||||
"LEFT OUTER JOIN (
|
||||
SELECT repository_cells.repository_row_id,
|
||||
repository_text_values.data AS text_value,
|
||||
to_char(repository_date_values.data, 'DD.MM.YYYY HH24:MI')
|
||||
AS date_value
|
||||
FROM repository_cells
|
||||
INNER JOIN repository_text_values
|
||||
ON repository_text_values.id = repository_cells.value_id
|
||||
FULL OUTER JOIN repository_date_values
|
||||
ON repository_date_values.id = repository_cells.value_id
|
||||
) AS values
|
||||
ON values.repository_row_id = repository_rows.id"
|
||||
)
|
||||
.where_attributes_like(
|
||||
['repository_rows.name', 'users.full_name',
|
||||
'values.text_value', 'values.date_value'],
|
||||
query, options
|
||||
)
|
||||
|
||||
if repository
|
||||
new_query = new_query
|
||||
.preload(
|
||||
:repository_columns,
|
||||
:created_by,
|
||||
repository_cells: :value
|
||||
)
|
||||
.where(repository: repository)
|
||||
end
|
||||
|
||||
# Show all results if needed
|
||||
if page == Constants::SEARCH_NO_LIMIT
|
||||
new_query
|
||||
else
|
||||
new_query
|
||||
.limit(Constants::SEARCH_LIMIT)
|
||||
.offset((page - 1) * Constants::SEARCH_LIMIT)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -62,8 +62,8 @@ class UserTeam < ApplicationRecord
|
|||
end
|
||||
|
||||
# Also, make new owner author of all protocols that belong
|
||||
# to the departing user.
|
||||
p_ids = user.added_protocols.pluck(:id)
|
||||
# to the departing user and belong to this team.
|
||||
p_ids = user.added_protocols.where(team: team).pluck(:id)
|
||||
Protocol.find(p_ids).each do |protocol|
|
||||
protocol.record_timestamps = false
|
||||
protocol.added_by = new_owner
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<!-- project archive button -->
|
||||
<a class="btn btn-default pull-right" href="<%= url_for projects_archive_path %>" id="project-archive-btn" data-turbolinks="false" title="">
|
||||
<a class="btn btn-default pull-right" href="<%= url_for projects_archive_path %>" id="project-archive-btn" data-turbolinks="false" title="<%= t'projects.index.archive' %>">
|
||||
<span class="glyphicon glyphicon-briefcase" aria-hidden="true"></span>
|
||||
</a>
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
</li>
|
||||
<li role="presentation" class="<%= "active" if @type == :archive %>">
|
||||
<%= link_to protocols_path(team: @current_team, type: :archive) do %>
|
||||
<span class="glyphicon glyphicon-briefcase"></span>
|
||||
<span class="glyphicon glyphicon-briefcase" title="<%= t'protocols.index.navigation.archive' %>"></span>
|
||||
<% end %>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
<body class="print-report-body">
|
||||
<div class="print-report">
|
||||
<% # Also whitelist <img> and <input type="checkbox"> tags %>
|
||||
<%= sanitize_report_pdf(@html, ['img', 'input'], ['type', 'disabled', 'checked']) %>
|
||||
<%= sanitize_input(fix_smart_annotation_image(@html),
|
||||
['img', 'input'],
|
||||
['type', 'disabled', 'checked']) %>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<%= t("repositories.modal_delete_record.notice") %>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<%= t("repositories.modal_delete_record.other_samples") %>
|
||||
<%= t("repositories.modal_delete_record.other_records") %>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="onClickDeleteRecord();">
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-3 col-md-3" id="search-menu">
|
||||
<ul class="nav nav-pills nav-stacked nav-stacked-arrow">
|
||||
<ul class="nav nav-pills nav-stacked nav-stacked-arrow nav-search">
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :projects %>
|
||||
|
@ -187,6 +187,7 @@
|
|||
<%= t'Samples' %>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category.present? and @search_category == :assets %>
|
||||
|
@ -226,6 +227,28 @@
|
|||
<%= t'Comments' %>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<% @repository_search_count.each do |team, results| %>
|
||||
<li class="repositories-team <%= 'active' if results[:count] > 0 %>">
|
||||
<span class="fa fa-cubes"></span>
|
||||
<%= t('Repositories_team', team: team) %>
|
||||
</li>
|
||||
<% results[:repositories].each do |repository, values| %>
|
||||
<li role="presentation"
|
||||
class="
|
||||
<%= "active" if @search_category == :repositories && @repository.id == values[:id] %>
|
||||
<%= "disabled" if values[:count] == 0 %> repository-search"
|
||||
>
|
||||
<a href="?<%= {category: 'repositories',
|
||||
repository: values[:id], q: @search_query,
|
||||
whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
|
||||
match_case: @search_case, utf8: '✓'}.to_query %>">
|
||||
<span class="badge pull-right"><%= values[:count] %></span>
|
||||
<%= repository %>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
@ -272,6 +295,9 @@
|
|||
<% if @search_category == :samples and @sample_search_count > 0 %>
|
||||
<%= render 'search/results/samples', search_query: @search_query, results: @sample_results %>
|
||||
<% end %>
|
||||
<% if @search_category == :repositories and @repository_search_count_total > 0 %>
|
||||
<%= render 'search/results/repositories', search_query: @search_query, results: @repository_results, repository: @repository %>
|
||||
<% end %>
|
||||
<% if @search_category == :assets and @asset_search_count > 0 %>
|
||||
<%= render 'search/results/assets', search_query: @search_query, results: @asset_results %>
|
||||
<% end %>
|
||||
|
|
51
app/views/search/results/_repositories.html.erb
Normal file
51
app/views/search/results/_repositories.html.erb
Normal file
|
@ -0,0 +1,51 @@
|
|||
<% results.each do |repository_row| %>
|
||||
<h5>
|
||||
<span class="fa fa-cubes"></span>
|
||||
<%=t "search.index.repositories.repository_row" %>
|
||||
<%= highlight repository_row.name, search_query.strip.split(/\s+/) %>
|
||||
</h5>
|
||||
|
||||
<p>
|
||||
<% repository_row.repository_cells.each do |cell| %>
|
||||
<span>
|
||||
<%=t "search.index.repositories.custom_column", column: cell.repository_column.name %>
|
||||
<%= highlight cell.value.data, search_query.strip.split(/\s+/) %>
|
||||
</span>
|
||||
<br>
|
||||
<% end %>
|
||||
<span>
|
||||
<%=t "search.index.repositories.added_on" %>
|
||||
<%=l repository_row.created_at, format: :full %>
|
||||
</span>
|
||||
<br>
|
||||
<span>
|
||||
<%=t "search.index.repositories.added_by" %>
|
||||
<%= highlight repository_row.created_by.full_name, search_query.strip.split(/\s+/) %>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<span>
|
||||
<%=t "search.index.modules" %>
|
||||
<% if repository_row.my_modules.any? %>
|
||||
<% repository_row.my_modules.each_with_index do |mod, i| %>
|
||||
<%= render partial: "search/results/partials/my_module_text.html.erb",
|
||||
locals: { my_module: mod, link_to_page: :repositories, repository: repository } %>
|
||||
<% if i != repository_row.my_modules.count - 1 %>
|
||||
,
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<em><%=t "search.index.repositories.no_modules" %></em>
|
||||
<% end %>
|
||||
</span>
|
||||
<br>
|
||||
<span>
|
||||
<%=t "search.index.team" %>
|
||||
<%= render partial: "search/results/partials/team_text.html.erb",
|
||||
locals: { team: repository.team } %>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<% end %>
|
|
@ -18,6 +18,10 @@
|
|||
<%= route_to_other_team samples_my_module_path(my_module),
|
||||
my_module.experiment.project.team,
|
||||
text %>
|
||||
<% when :repositories %>
|
||||
<%= route_to_other_team repository_my_module_path(my_module, repository),
|
||||
my_module.experiment.project.team,
|
||||
text %>
|
||||
<% when :protocols %>
|
||||
<%= route_to_other_team protocols_my_module_path(my_module),
|
||||
my_module.experiment.project.team,
|
||||
|
|
7
app/views/shared/_flash_errors.html.erb
Normal file
7
app/views/shared/_flash_errors.html.erb
Normal file
|
@ -0,0 +1,7 @@
|
|||
<% if error.present? %>
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<div><%= error_title %></div>
|
||||
<br>
|
||||
<%= error %>
|
||||
</div>
|
||||
<% end %>
|
|
@ -9,7 +9,7 @@
|
|||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<%= link_to(root_path, class: 'navbar-brand') do %>
|
||||
<%= link_to(root_path, class: 'navbar-brand', title: t('nav.label.scinote')) do %>
|
||||
<%
|
||||
show_version = !Rails.env.production?
|
||||
if ENV['NAVBAR_SHOW_VERSION'].present?
|
||||
|
@ -32,33 +32,33 @@
|
|||
<!-- links -->
|
||||
<ul class="nav navbar-nav">
|
||||
<li>
|
||||
<a href="<%= projects_path %>">
|
||||
<a title="<%= t('nav.label.projects') %>" href="<%= projects_path %>">
|
||||
<span class="glyphicon glyphicon-home"></span>
|
||||
<span class="visible-xs-inline visible-sm-inline"><%= t('nav.label.projects') %></span>
|
||||
</a>
|
||||
</li>
|
||||
<% if current_team %>
|
||||
<li>
|
||||
<a id="protocol-link" href="<%= protocols_path %>">
|
||||
<a id="protocol-link" title="<%= t('nav.label.protocols') %>" href="<%= protocols_path %>">
|
||||
<span class="glyphicon glyphicon-list-alt"></span>
|
||||
<span class="visible-xs-inline visible-sm-inline"><%= t('nav.label.protocols') %></span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a id="repositories-link" href="<%= team_repositories_path(current_team) %>">
|
||||
<a id="repositories-link" title="<%= t('nav.label.repositories') %>" href="<%= team_repositories_path(current_team) %>">
|
||||
<i class="fa fa-cubes" aria-hidden="true"></i>
|
||||
<span class="visible-xs-inline visible-sm-inline"><%= t('nav.label.repositories') %></span>
|
||||
</a>
|
||||
</li>
|
||||
<% else %>
|
||||
<li class="disabled">
|
||||
<a id="protocol-link" href="#">
|
||||
<a id="protocol-link" title="<%= t('nav.label.protocols') %>" href="#">
|
||||
<span class="glyphicon glyphicon-list-alt"></span>
|
||||
<span class="visible-xs-inline visible-sm-inline"><%= t('nav.label.protocols') %></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="disabled">
|
||||
<a id="repositories-link" href="#">
|
||||
<a id="repositories-link" title="<%= t('nav.label.repositories') %>" href="#">
|
||||
<span class="fa fa-cubes"></span>
|
||||
<span class="visible-xs-inline visible-sm-inline"><%= t('nav.label.repositories') %></span>
|
||||
</a>
|
||||
|
@ -73,7 +73,7 @@
|
|||
</li>
|
||||
<% end %>
|
||||
<li>
|
||||
<a class="btn-activity" href="<%= activities_path(format: :json) %>" role="button" data-remote="true">
|
||||
<a class="btn-activity" title="<%= t('nav.label.activities') %>" href="<%= activities_path(format: :json) %>" role="button" data-remote="true">
|
||||
<span class="glyphicon glyphicon-equalizer"></span>
|
||||
<span class="visible-xs-inline visible-sm-inline"><%= t('nav.label.activities') %></span>
|
||||
</a>
|
||||
|
@ -88,6 +88,7 @@
|
|||
<li class="dropdown" id="team-switch">
|
||||
<a href="#"
|
||||
class="dropdown-toggle"
|
||||
title="<%= t('nav.label.teams') %>"
|
||||
data-toggle="dropdown"
|
||||
role="button"
|
||||
aria-haspopup="true"
|
||||
|
@ -135,11 +136,13 @@
|
|||
id="search-ico">
|
||||
<a href="#"
|
||||
class="dropdown-toggle"
|
||||
title="<%= t('nav.label.search') %>"
|
||||
data-toggle="dropdown"
|
||||
role="button"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<span class="glyphicon glyphicon-search"></span>
|
||||
<span class="visible-xs-inline visible-sm-inline"><%= t('nav.label.search') %></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu search-dropdown">
|
||||
<li>
|
||||
|
@ -174,12 +177,14 @@
|
|||
<a href="#"
|
||||
id="notifications-dropdown"
|
||||
class="dropdown-toggle"
|
||||
title="<%= t('nav.label.notifications') %>"
|
||||
data-toggle="dropdown"
|
||||
role="button"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
data-href="<%= recent_notifications_url(current_user) %>">
|
||||
<%= fa_icon 'bell'%>
|
||||
<span class="visible-xs-inline visible-sm-inline"><%= t('nav.label.notifications') %></span>
|
||||
<span id="count-notifications"
|
||||
data-href="<%= unseen_notification_url(current_user) %>">
|
||||
</span>
|
||||
|
@ -205,11 +210,13 @@
|
|||
<a href="#"
|
||||
id="help-link"
|
||||
class="dropdown-toggle"
|
||||
title="<%= t('nav.label.info') %>"
|
||||
data-toggle="dropdown"
|
||||
role="button"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<span class="glyphicon glyphicon-info-sign"></span>
|
||||
<span class="visible-xs-inline visible-sm-inline"><%= t('nav.label.info') %></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" data-hook="navigation-help-menu">
|
||||
<li><%= link_to t('nav.help.support'),
|
||||
|
@ -234,6 +241,7 @@
|
|||
<li class="dropdown">
|
||||
<a href="#"
|
||||
class="dropdown-toggle"
|
||||
title="<%= t('nav.label.account') %>"
|
||||
data-toggle="dropdown"
|
||||
role="button"
|
||||
aria-haspopup="true"
|
||||
|
|
|
@ -101,7 +101,9 @@
|
|||
<% end %>
|
||||
<% if can_view_project_archive(@project) then %>
|
||||
<li id="project-archive-nav-tab" data-turbolinks="false" class="<%= "active" if is_project_archive? %>">
|
||||
<a href="<%= experiment_archive_project_url(@project) %>"><span class="glyphicon glyphicon-briefcase"></span></a>
|
||||
<a href="<%= experiment_archive_project_url(@project) %>" title="<%=t "nav2.projects.archive" %>">
|
||||
<span class="glyphicon glyphicon-briefcase"></span>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
|
@ -136,7 +138,9 @@
|
|||
<% end %>
|
||||
<% if can_view_experiment_archive(@experiment) then %>
|
||||
<li id="project-archive-nav-tab" data-turbolinks="false" class="<%= "active" if is_experiment_archive? %>">
|
||||
<a href="<%= module_archive_experiment_url(@experiment) %>"><span class="glyphicon glyphicon-briefcase"></span></a>
|
||||
<a href="<%= module_archive_experiment_url(@experiment) %>" title="<%=t "nav2.projects.archive" %>">
|
||||
<span class="glyphicon glyphicon-briefcase"></span>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
<div class="center-block center-block-narrow">
|
||||
<h2>Sign up</h2>
|
||||
|
||||
<%= form_for(:user, as: resource_name, url: registration_path(resource_name)) do |f| %>
|
||||
<div data-hook="sign-up-form-hook">
|
||||
<%= form_for(:user, as: resource_name, url: registration_path(resource_name), html: { id: "sign-up-form" } ) do |f| %>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label :full_name %>
|
||||
|
@ -44,7 +44,7 @@
|
|||
<%= f.submit 'Sign up', class: 'btn btn-primary' %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
<%= render 'users/shared/links' %>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -197,7 +197,7 @@ class Constants
|
|||
#=============================================================================
|
||||
|
||||
# Application version
|
||||
APP_VERSION = '1.11.0'.freeze
|
||||
APP_VERSION = '1.12.1'.freeze
|
||||
|
||||
TEXT_EXTRACT_FILE_TYPES = [
|
||||
'application/pdf',
|
||||
|
|
|
@ -75,11 +75,17 @@ en:
|
|||
activities:
|
||||
none: "No activities!"
|
||||
label:
|
||||
projects: "Projects"
|
||||
scinote: "sciNote"
|
||||
projects: "Home"
|
||||
protocols: "Protocols"
|
||||
calendar: "Calendar"
|
||||
activities: "Activities"
|
||||
repositories: "Repositories"
|
||||
teams: "Teams"
|
||||
search: "Search"
|
||||
notifications: "Notifications"
|
||||
info: "Info"
|
||||
account: "Account"
|
||||
|
||||
sidebar:
|
||||
title: "Navigation"
|
||||
|
@ -91,6 +97,7 @@ en:
|
|||
samples: "Samples"
|
||||
activities: "Activity"
|
||||
reports: "Reports"
|
||||
archive: "Archive"
|
||||
experiments:
|
||||
canvas: "Overview"
|
||||
modules:
|
||||
|
@ -142,6 +149,12 @@ en:
|
|||
added_on: "Added on: "
|
||||
added_by: "Added by: "
|
||||
custom_field: "%{cf}: "
|
||||
repositories:
|
||||
repository_row: "Repository item: "
|
||||
added_on: "Added on: "
|
||||
added_by: "Added by: "
|
||||
custom_column: "%{column}: "
|
||||
no_modules: "not assigned to any task"
|
||||
comments:
|
||||
project: "Project comment"
|
||||
my_module: "Task comment"
|
||||
|
@ -159,6 +172,7 @@ en:
|
|||
projects:
|
||||
index:
|
||||
head_title: "Home"
|
||||
archive: "Archive"
|
||||
new: "New project"
|
||||
visibility_private: "Project is private. Only invited users can see it."
|
||||
visibility_public: "Project is public. Everybody from the team can see it."
|
||||
|
@ -891,7 +905,7 @@ en:
|
|||
add_new_record: "Add new item"
|
||||
import_records:
|
||||
import: 'Import'
|
||||
success_flash: "%{number_of_rows} new record(s) successfully imported."
|
||||
success_flash: "%{number_of_rows} new item(s) successfully imported."
|
||||
error_flash: "Something went wrong: %{message}"
|
||||
error_message:
|
||||
temp_file_not_found: "This file could not be found. Your session might expire."
|
||||
|
@ -899,6 +913,8 @@ en:
|
|||
no_data_to_parse: "There's nothing to be parsed."
|
||||
no_column_name: "Name column is required!"
|
||||
duplicated_values: "Two or more columns have the same mapping."
|
||||
errors_list_title: "Items were not imported because one or more errors were found:"
|
||||
no_repository_name: "Item name is required!"
|
||||
edit_record: "Edit"
|
||||
delete_record: "Delete"
|
||||
save_record: "Save"
|
||||
|
@ -913,41 +929,41 @@ en:
|
|||
view_all_records: "View all items"
|
||||
view_assigned_records: "View assigned items"
|
||||
modal_delete_record:
|
||||
title: "Delete record"
|
||||
notice: "Are you sure you want to delete the selected records?"
|
||||
other_samples: "Only records created by you will be deleted."
|
||||
delete: "Delete records"
|
||||
title: "Delete items"
|
||||
notice: "Are you sure you want to delete the selected item(s)?"
|
||||
other_records: "Only items created by you will be deleted."
|
||||
delete: "Delete item(s)"
|
||||
modal_delete_column:
|
||||
title: "Delete a column"
|
||||
message: "Are you sure you wish to permanently delete selected column %{column}? This action is irreversible."
|
||||
alert_heading: "Deleting a column has following consequences:"
|
||||
alert_line_1: "you will lose information in this column for %{nr} records;"
|
||||
alert_line_1: "you will lose information in this column for %{nr} item(s);"
|
||||
alert_line_2: "the column will be deleted for all team members."
|
||||
delete: "Delete column"
|
||||
modal_parse:
|
||||
title: 'Import records'
|
||||
title: 'Import items'
|
||||
modal_import:
|
||||
title: 'Import records'
|
||||
title: 'Import items'
|
||||
notice: 'You may upload .csv file (comma separated) or tab separated file (.txt or .tdv) or Excel file (.xls, .xlsx). First row should include header names, followed by rows with sample data.'
|
||||
upload: 'Upload file'
|
||||
js:
|
||||
permission_error: "You don't have permission to edit this record."
|
||||
not_found_error: "This repository record does not exist."
|
||||
permission_error: "You don't have permission to edit this item."
|
||||
not_found_error: "This repository item does not exist."
|
||||
column_added: "New column was sucessfully created."
|
||||
empty_column_name: "Please enter column name."
|
||||
create:
|
||||
success_flash: "Successfully added record <strong>%{record}</strong> to repository <strong>%{repository}</strong>"
|
||||
success_flash: "Successfully added item <strong>%{record}</strong> to repository <strong>%{repository}</strong>"
|
||||
update:
|
||||
success_flash: "Successfully updated record <strong>%{record}</strong> in repository <strong>%{repository}</strong>"
|
||||
success_flash: "Successfully updated item <strong>%{record}</strong> in repository <strong>%{repository}</strong>"
|
||||
destroy:
|
||||
success_flash: "%{records_number} record(s) successfully deleted."
|
||||
contains_other_records_flash: "%{records_number} record(s) successfully deleted. %{other_records_number} of the selected record(s) were created by other users and were not deleted."
|
||||
no_records_selected_flash: "There were no selected records."
|
||||
no_deleted_records_flash: "No records were deleted. %{other_records_number} of the selected records were created by other users and were not deleted."
|
||||
assigned_records_flash: "Successfully assigned record(s) <strong>%{records}</strong> to task"
|
||||
unassigned_records_flash: "Successfully unassigned record(s) <strong>%{records}</strong> from task"
|
||||
no_records_assigned_flash: "No records were assigned to task"
|
||||
no_records_unassigned_flash: "No records were unassigned from task"
|
||||
success_flash: "%{records_number} item(s) successfully deleted."
|
||||
contains_other_records_flash: "%{records_number} item(s) successfully deleted. %{other_records_number} of the selected item(s) were created by other users and were not deleted."
|
||||
no_records_selected_flash: "There were no selected items."
|
||||
no_deleted_records_flash: "No items were deleted. %{other_records_number} of the selected items were created by other users and were not deleted."
|
||||
assigned_records_flash: "Successfully assigned item(s) <strong>%{records}</strong> to task"
|
||||
unassigned_records_flash: "Successfully unassigned item(s) <strong>%{records}</strong> from task"
|
||||
no_records_assigned_flash: "No items were assigned to task"
|
||||
no_records_unassigned_flash: "No items were unassigned from task"
|
||||
default_column: 'Name'
|
||||
|
||||
samples:
|
||||
|
@ -1083,7 +1099,7 @@ en:
|
|||
empty_file: "You've selected empty file. There's not much to import."
|
||||
temp_file_failure: "We couldn't create temporary file. Please contact administrator."
|
||||
no_file_selected: "You didn't select any file."
|
||||
errors_list_title: "Samples were not imported because one or more errors was found:"
|
||||
errors_list_title: "Samples were not imported because one or more errors were found:"
|
||||
list_row: "Row %{row}"
|
||||
list_error: "%{key}: %{val}"
|
||||
import_samples:
|
||||
|
@ -1139,8 +1155,8 @@ en:
|
|||
uncomplete_module: "<i>%{user}</i> uncompleted task <strong>%{module}</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>"
|
||||
assign_repository_records: "<i>%{user}</i> assigned record(s) <strong>%{records}</strong> from <strong>%{repository}</strong> repository to task <strong>%{task}</strong>"
|
||||
unassign_repository_records: "<i>%{user}</i> unassigned record(s) <strong>%{records}</strong> from <strong>%{repository}</strong> repository from task <strong>%{task}</strong>"
|
||||
assign_repository_records: "<i>%{user}</i> assigned item(s) <strong>%{records}</strong> from <strong>%{repository}</strong> repository to task <strong>%{task}</strong>"
|
||||
unassign_repository_records: "<i>%{user}</i> unassigned item(s) <strong>%{records}</strong> from <strong>%{repository}</strong> repository from task <strong>%{task}</strong>"
|
||||
create_step: "<i>%{user}</i> created Step %{step} <strong>%{step_name}</strong>."
|
||||
destroy_step: "<i>%{user}</i> deleted Step %{step} <strong>%{step_name}</strong>."
|
||||
add_comment_to_step: "<i>%{user}</i> commented on Step %{step} <strong>%{step_name}</strong>."
|
||||
|
@ -1412,6 +1428,7 @@ en:
|
|||
navigation:
|
||||
public: "Public protocols"
|
||||
private: "Private protocols"
|
||||
archive: "Archive"
|
||||
public_description: "Public protocols are visible and can be used by everyone from the team."
|
||||
private_description: "Private protocols are only visible to you."
|
||||
create_new: "Create new"
|
||||
|
@ -1677,7 +1694,7 @@ en:
|
|||
sample_annotation_title: "%{user} mentioned you in Column: %{column} of Sample %{sample}"
|
||||
sample_annotation_message_html: "Sample: %{sample} | Column: %{column}"
|
||||
repository_annotation_title: "%{user} mentioned you in Column: %{column} of Record %{record} in Repository %{repository}"
|
||||
repository_annotation_message_html: "Record: %{record} | Column: %{column}"
|
||||
repository_annotation_message_html: "Item: %{record} | Column: %{column}"
|
||||
protocol_step_annotation_message_html: "Protocol: %{protocol}"
|
||||
email_title: "You've received a sciNote notification!"
|
||||
assign_user_to_team: "<i>%{assigned_user}</i> was added as %{role} to team <strong>%{team}</strong> by <i>%{assigned_by_user}</i>."
|
||||
|
@ -1780,6 +1797,7 @@ en:
|
|||
Tables: "Tables"
|
||||
Sample: "Sample"
|
||||
Samples: "Samples"
|
||||
Repositories_team: "Repositories - %{team}"
|
||||
Reports: "Reports"
|
||||
Comments: "Comments"
|
||||
Step: "Step"
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
require File.expand_path('app/helpers/database_helper')
|
||||
include DatabaseHelper
|
||||
|
||||
class AddSearchIndexesToRepositories < ActiveRecord::Migration[4.2]
|
||||
def up
|
||||
if db_adapter_is? 'PostgreSQL'
|
||||
if index_exists?(:repository_rows, :name)
|
||||
remove_index :repository_rows, :name
|
||||
end
|
||||
add_gin_index_without_tags :repository_rows, :name
|
||||
add_gin_index_without_tags :repository_text_values, :data
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
if db_adapter_is? 'PostgreSQL'
|
||||
remove_index :repository_rows, :name
|
||||
remove_index :repository_text_values, :data
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue