2019-05-21 21:19:44 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2016-02-12 23:52:43 +08:00
|
|
|
module ApplicationHelper
|
2017-01-13 18:34:10 +08:00
|
|
|
include ActionView::Helpers::AssetTagHelper
|
|
|
|
include ActionView::Helpers::UrlHelper
|
2017-05-25 22:28:06 +08:00
|
|
|
include InputSanitizeHelper
|
2017-01-13 18:34:10 +08:00
|
|
|
|
2016-07-29 21:47:41 +08:00
|
|
|
def module_page?
|
|
|
|
controller_name == 'my_modules'
|
2016-02-12 23:52:43 +08:00
|
|
|
end
|
|
|
|
|
2016-07-29 21:47:41 +08:00
|
|
|
def experiment_page?
|
|
|
|
controller_name == 'experiments'
|
2016-02-12 23:52:43 +08:00
|
|
|
end
|
|
|
|
|
2016-07-29 21:47:41 +08:00
|
|
|
def project_page?
|
2018-05-08 22:33:42 +08:00
|
|
|
controller_name == 'projects' &&
|
|
|
|
action_name.in?(%w(show experiment_archive))
|
|
|
|
end
|
|
|
|
|
|
|
|
def all_projects_page?
|
|
|
|
controller_name == 'projects' && action_name.in?(%w(index archive))
|
2016-02-12 23:52:43 +08:00
|
|
|
end
|
2016-12-14 20:36:10 +08:00
|
|
|
|
|
|
|
def display_tooltip(message, len = Constants::NAME_TRUNCATION_LENGTH)
|
2018-05-16 21:08:50 +08:00
|
|
|
return '' unless message
|
2019-05-21 21:19:44 +08:00
|
|
|
|
2017-06-19 21:30:38 +08:00
|
|
|
if message.strip.length > len
|
2017-01-03 05:27:12 +08:00
|
|
|
sanitize_input("<div class='modal-tooltip'> \
|
|
|
|
#{truncate(message.strip, length: len)} \
|
|
|
|
<span class='modal-tooltiptext'> \
|
|
|
|
#{message.strip}</span></div>")
|
2016-12-14 20:36:10 +08:00
|
|
|
else
|
|
|
|
truncate(message.strip, length: len)
|
|
|
|
end
|
|
|
|
end
|
2016-12-15 00:05:00 +08:00
|
|
|
|
2016-12-12 17:30:03 +08:00
|
|
|
def sample_types_page_project?
|
2016-12-14 17:35:48 +08:00
|
|
|
controller_name == 'sample_types' &&
|
|
|
|
@my_module.nil? &&
|
|
|
|
@experiment.nil?
|
2016-12-12 17:30:03 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def sample_groups_page_project?
|
2016-12-14 17:35:48 +08:00
|
|
|
controller_name == 'sample_groups' &&
|
|
|
|
@my_module.nil? &&
|
|
|
|
@experiment.nil?
|
2016-12-12 17:30:03 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def sample_types_page_my_module?
|
2016-12-14 17:35:48 +08:00
|
|
|
controller_name == 'sample_types' && !@my_module.nil?
|
2016-12-12 17:30:03 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def sample_groups_page_my_module?
|
2016-12-14 17:35:48 +08:00
|
|
|
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?
|
2016-12-12 17:30:03 +08:00
|
|
|
end
|
2017-01-10 00:16:39 +08:00
|
|
|
|
2017-05-18 20:21:00 +08:00
|
|
|
def module_repository_page?
|
|
|
|
controller_name == 'my_modules' && !@repository.nil?
|
|
|
|
end
|
|
|
|
|
2017-04-06 14:42:16 +08:00
|
|
|
def smart_annotation_notification(options = {})
|
|
|
|
title = options.fetch(:title) { :title_must_be_present }
|
|
|
|
message = options.fetch(:message) { :message_must_be_present }
|
|
|
|
new_text = options.fetch(:new_text) { :new_text_must_be_present }
|
|
|
|
old_text = options[:old_text] || ''
|
2017-04-04 15:19:43 +08:00
|
|
|
sa_user = /\[\@(.*?)~([0-9a-zA-Z]+)\]/
|
2017-04-10 17:21:28 +08:00
|
|
|
# fetch user ids from the previous text
|
2017-04-06 14:42:16 +08:00
|
|
|
old_user_ids = []
|
|
|
|
old_text.gsub(sa_user) do |el|
|
|
|
|
match = el.match(sa_user)
|
|
|
|
old_user_ids << match[2].base62_decode
|
|
|
|
end
|
2017-04-06 21:08:03 +08:00
|
|
|
# fetch user ids from the new text
|
2017-04-06 14:42:16 +08:00
|
|
|
new_user_ids = []
|
|
|
|
new_text.gsub(sa_user) do |el|
|
2017-04-04 15:19:43 +08:00
|
|
|
match = el.match(sa_user)
|
2017-04-06 14:42:16 +08:00
|
|
|
new_user_ids << match[2].base62_decode
|
2017-04-04 15:19:43 +08:00
|
|
|
end
|
2017-04-06 21:08:03 +08:00
|
|
|
# check if the user has been already mentioned
|
2017-04-06 14:42:16 +08:00
|
|
|
annotated_users = []
|
|
|
|
new_user_ids.each do |el|
|
|
|
|
annotated_users << el unless old_user_ids.include?(el)
|
|
|
|
end
|
2017-04-06 21:08:03 +08:00
|
|
|
# restrict the list of ids and generate notification
|
2017-04-04 15:19:43 +08:00
|
|
|
annotated_users.uniq.each do |user_id|
|
|
|
|
target_user = User.find_by_id(user_id)
|
|
|
|
next unless target_user
|
2019-05-21 21:19:44 +08:00
|
|
|
|
2017-04-04 15:19:43 +08:00
|
|
|
generate_annotation_notification(target_user, title, message)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def generate_annotation_notification(target_user, title, message)
|
|
|
|
notification = Notification.create(
|
|
|
|
type_of: :assignment,
|
2017-05-11 17:36:47 +08:00
|
|
|
title: sanitize_input(title),
|
|
|
|
message: sanitize_input(message)
|
2017-04-04 15:19:43 +08:00
|
|
|
)
|
2019-05-21 21:19:44 +08:00
|
|
|
UserNotification.create(notification: notification, user: target_user) if target_user.assignments_notification
|
2017-04-04 15:19:43 +08:00
|
|
|
end
|
|
|
|
|
2017-01-25 16:48:49 +08:00
|
|
|
def smart_annotation_parser(text, team = nil)
|
2017-05-03 21:30:08 +08:00
|
|
|
# sometimes happens that the "team" param gets wrong data: "{nil, []}"
|
|
|
|
# so we have to check if the "team" param is kind of Team object
|
2017-04-25 19:44:31 +08:00
|
|
|
team = nil unless team.is_a? Team
|
2019-03-20 19:58:22 +08:00
|
|
|
new_text = smart_annotation_filter_resources(text, team)
|
2017-01-25 16:48:49 +08:00
|
|
|
new_text = smart_annotation_filter_users(new_text, team)
|
2017-01-24 17:51:12 +08:00
|
|
|
new_text
|
|
|
|
end
|
|
|
|
|
|
|
|
# Check if text have smart annotations of resources
|
|
|
|
# and outputs a link to resource
|
2019-03-20 19:58:22 +08:00
|
|
|
def smart_annotation_filter_resources(text, team)
|
2019-07-01 16:14:16 +08:00
|
|
|
user = if !defined?(current_user) && @user
|
|
|
|
@user
|
|
|
|
else
|
|
|
|
current_user
|
|
|
|
end
|
|
|
|
SmartAnnotations::TagToHtml.new(user, team, text).html
|
2017-01-24 17:51:12 +08:00
|
|
|
end
|
2017-01-11 00:05:32 +08:00
|
|
|
|
2017-01-24 17:51:12 +08:00
|
|
|
# Check if text have smart annotations of users
|
|
|
|
# and outputs a popover with user information
|
2017-01-25 16:48:49 +08:00
|
|
|
def smart_annotation_filter_users(text, team)
|
2017-01-11 21:56:47 +08:00
|
|
|
sa_user = /\[\@(.*?)~([0-9a-zA-Z]+)\]/
|
2017-01-24 17:51:12 +08:00
|
|
|
new_text = text.gsub(sa_user) do |el|
|
2017-01-11 00:05:32 +08:00
|
|
|
match = el.match(sa_user)
|
2017-01-11 21:56:47 +08:00
|
|
|
user = User.find_by_id(match[2].base62_decode)
|
2017-05-27 00:09:29 +08:00
|
|
|
next unless user
|
2019-05-21 21:19:44 +08:00
|
|
|
|
2017-04-04 21:22:41 +08:00
|
|
|
popover_for_user_name(user, team)
|
2017-01-11 00:05:32 +08:00
|
|
|
end
|
|
|
|
new_text
|
2017-01-10 00:16:39 +08:00
|
|
|
end
|
2017-04-03 21:10:00 +08:00
|
|
|
|
2017-04-04 21:22:41 +08:00
|
|
|
# Generate smart annotation link for one user object
|
2019-02-27 23:02:53 +08:00
|
|
|
def popover_for_user_name(user,
|
|
|
|
team = nil,
|
|
|
|
skip_user_status = false,
|
|
|
|
skip_avatar = false)
|
2017-05-27 00:09:29 +08:00
|
|
|
user_still_in_team = user.teams.include?(team)
|
|
|
|
|
2017-04-03 21:10:00 +08:00
|
|
|
user_description = %(<div class='col-xs-4'>
|
2017-05-03 21:33:23 +08:00
|
|
|
<img src='#{user_avatar_absolute_url(user, :thumb)}'
|
2017-05-03 16:50:43 +08:00
|
|
|
alt='thumb'></div><div class='col-xs-8'>
|
2017-04-03 21:10:00 +08:00
|
|
|
<div class='row'><div class='col-xs-9 text-left'><h5>
|
|
|
|
#{user.full_name}</h5></div><div class='col-xs-3 text-right'>
|
2018-07-09 19:13:44 +08:00
|
|
|
<span class='fas fa-times' aria-hidden='true'></span>
|
2017-04-03 21:10:00 +08:00
|
|
|
</div></div><div class='row'><div class='col-xs-12'>
|
2017-04-04 21:22:41 +08:00
|
|
|
<p class='silver'>#{user.email}</p>)
|
2017-05-27 00:09:29 +08:00
|
|
|
if user_still_in_team
|
|
|
|
user_t = user.user_teams
|
|
|
|
.where('user_teams.team_id = ?', team)
|
|
|
|
.first
|
2017-04-04 21:22:41 +08:00
|
|
|
user_description += %(<p>
|
2017-05-27 00:09:29 +08:00
|
|
|
#{I18n.t('atwho.users.popover_html',
|
2017-04-04 21:22:41 +08:00
|
|
|
role: user_t.role.capitalize,
|
|
|
|
team: user_t.team.name,
|
2018-11-09 22:58:08 +08:00
|
|
|
time: I18n.l(user_t.created_at, format: :full_date))}
|
2017-04-04 21:22:41 +08:00
|
|
|
</p></div></div></div>)
|
|
|
|
else
|
|
|
|
user_description += %(<p></p></div></div></div>)
|
|
|
|
end
|
2017-05-09 20:55:23 +08:00
|
|
|
|
2017-05-27 00:09:29 +08:00
|
|
|
user_name = user.full_name
|
2018-10-22 20:32:10 +08:00
|
|
|
|
2019-02-27 23:02:53 +08:00
|
|
|
html = if skip_avatar
|
|
|
|
''
|
|
|
|
else
|
2019-05-21 21:19:44 +08:00
|
|
|
raw("<span class=\"global-avatar-container smart-annotation\"><img src='#{user_avatar_absolute_url(user, :icon_small)}'" \
|
2019-02-27 23:02:53 +08:00
|
|
|
"alt='avatar' class='atwho-user-img-popover'" \
|
2019-05-21 21:19:44 +08:00
|
|
|
" ref='#{'missing-img' if missing_avatar(user, :icon_small)}'></span>")
|
2019-02-27 23:02:53 +08:00
|
|
|
end
|
|
|
|
|
2018-11-26 22:17:18 +08:00
|
|
|
html =
|
2019-02-27 23:02:53 +08:00
|
|
|
raw(html) +
|
2017-05-27 00:09:29 +08:00
|
|
|
raw('<a onClick="$(this).popover(\'show\')" ' \
|
2018-11-26 22:17:18 +08:00
|
|
|
'class="atwho-user-popover" data-container="body" ' \
|
|
|
|
'data-html="true" tabindex="0" data-trigger="focus" ' \
|
|
|
|
'data-placement="top" data-toggle="popover" data-content="') +
|
2017-05-27 00:09:29 +08:00
|
|
|
raw(user_description) + raw('" >') + user_name + raw('</a>')
|
2018-11-26 22:17:18 +08:00
|
|
|
|
2019-05-21 21:19:44 +08:00
|
|
|
html << " #{I18n.t('atwho.res.removed')}" unless skip_user_status || user_still_in_team
|
|
|
|
html = '<span class="atwho-user-container">' + html + '</span>'
|
2018-11-26 22:17:18 +08:00
|
|
|
html
|
2017-04-03 21:10:00 +08:00
|
|
|
end
|
2017-05-03 16:50:43 +08:00
|
|
|
|
2019-05-21 21:19:44 +08:00
|
|
|
# No more dirty hack
|
2017-05-03 21:33:23 +08:00
|
|
|
def user_avatar_absolute_url(user, style)
|
2019-05-21 21:19:44 +08:00
|
|
|
begin
|
|
|
|
unless missing_avatar(user, style)
|
2019-07-05 22:56:05 +08:00
|
|
|
image = File.open(user.avatar_variant(style))
|
2019-05-21 21:19:44 +08:00
|
|
|
encoded_data = Base64.strict_encode64(image)
|
|
|
|
avatar_base64 = "data:#{user.avatar_content_type};base64,#{encoded_data}"
|
|
|
|
return avatar_base64
|
|
|
|
end
|
|
|
|
rescue StandardError => e
|
|
|
|
Rails.logger.error e.message
|
2017-05-03 16:50:43 +08:00
|
|
|
end
|
2019-05-21 21:19:44 +08:00
|
|
|
url_for("/images/#{style}/missing.png")
|
2017-05-03 16:50:43 +08:00
|
|
|
end
|
2017-06-27 17:26:32 +08:00
|
|
|
|
|
|
|
def missing_avatar(user, style)
|
2019-08-09 15:47:07 +08:00
|
|
|
user.avatar == '/images/icon_small/missing.png' ||
|
|
|
|
user.avatar == '/images/thumb/missing.png'
|
2017-06-27 17:26:32 +08:00
|
|
|
end
|
2019-05-10 22:25:18 +08:00
|
|
|
|
|
|
|
def wopi_enabled?
|
|
|
|
ENV['WOPI_ENABLED'] == 'true'
|
|
|
|
end
|
2016-02-12 23:52:43 +08:00
|
|
|
end
|