Actualiza el plugin Additionals a 3.0.2-master
This commit is contained in:
parent
3b6a41320c
commit
cfa0d58b18
164 changed files with 2027 additions and 58190 deletions
|
@ -6,7 +6,7 @@ module AdditionalsChartjsHelper
|
|||
end
|
||||
|
||||
def select_options_for_chartjs_colorscheme(selected)
|
||||
data = YAML.safe_load(ERB.new(IO.read(Rails.root.join('plugins/additionals/config/colorschemes.yml'))).result) || {}
|
||||
data = YAML.safe_load(ERB.new(IO.read(File.join(Additionals.plugin_dir, 'config', 'colorschemes.yml'))).result) || {}
|
||||
grouped_options_for_select(data, selected)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,20 +3,34 @@ module AdditionalsClipboardjsHelper
|
|||
render_clipboardjs_button(target, clipboard_text_from_button) + render_clipboardjs_javascript(target)
|
||||
end
|
||||
|
||||
def render_text_with_clipboardjs(text)
|
||||
return if text.blank?
|
||||
|
||||
tag.acronym text,
|
||||
class: 'clipboard-text',
|
||||
title: l(:label_copy_to_clipboard),
|
||||
data: clipboardjs_data(text: text)
|
||||
end
|
||||
|
||||
def clipboardjs_data(clipboard_data)
|
||||
data = { 'label-copied' => l(:label_copied_to_clipboard),
|
||||
'label-to-copy' => l(:label_copy_to_clipboard) }
|
||||
|
||||
clipboard_data.each do |key, value|
|
||||
data["clipboard-#{key}"] = value if value.present?
|
||||
end
|
||||
|
||||
data
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def render_clipboardjs_button(target, clipboard_text_from_button)
|
||||
data = { 'clipboard-target' => "##{target}",
|
||||
'label-copied' => l(:label_copied_to_clipboard),
|
||||
'label-to-copy' => l(:label_copy_to_clipboard) }
|
||||
|
||||
data['clipboard-text'] = clipboard_text_from_button if clipboard_text_from_button.present?
|
||||
|
||||
tag.button id: "zc_#{target}",
|
||||
class: 'clipboard_button far fa-copy',
|
||||
class: 'clipboard-button far fa-copy',
|
||||
type: 'button',
|
||||
title: l(:label_copy_to_clipboard),
|
||||
data: data
|
||||
data: clipboardjs_data(target: "##{target}", text: clipboard_text_from_button)
|
||||
end
|
||||
|
||||
def render_clipboardjs_javascript(target)
|
||||
|
|
|
@ -100,12 +100,9 @@ module AdditionalsMenuHelper
|
|||
def additionals_custom_top_menu_item(item, user_roles)
|
||||
show_entry = false
|
||||
item[:roles].each do |role|
|
||||
if user_roles.empty? && role.to_i == Role::BUILTIN_ANONYMOUS
|
||||
show_entry = true
|
||||
break
|
||||
elsif User.current.logged? && role.to_i == Role::BUILTIN_NON_MEMBER
|
||||
# if user is logged in and non_member is active in item,
|
||||
# always show it
|
||||
if user_roles.empty? && role.to_i == Role::BUILTIN_ANONYMOUS ||
|
||||
# if user is logged in and non_member is active in item, always show it
|
||||
User.current.logged? && role.to_i == Role::BUILTIN_NON_MEMBER
|
||||
show_entry = true
|
||||
break
|
||||
end
|
||||
|
|
|
@ -4,8 +4,8 @@ module AdditionalsQueriesHelper
|
|||
end
|
||||
|
||||
def additionals_retrieve_query(object_type, options = {})
|
||||
session_key = additionals_query_session_key(object_type)
|
||||
query_class = Object.const_get("#{object_type.camelcase}Query")
|
||||
session_key = additionals_query_session_key object_type
|
||||
query_class = Object.const_get "#{object_type.camelcase}Query"
|
||||
if params[:query_id].present?
|
||||
additionals_load_query_id(query_class, session_key, params[:query_id], options, object_type)
|
||||
elsif api_request? ||
|
||||
|
@ -28,7 +28,7 @@ module AdditionalsQueriesHelper
|
|||
else
|
||||
# retrieve from session
|
||||
@query = query_class.find_by(id: session[session_key][:id]) if session[session_key][:id]
|
||||
session_data = Rails.cache.read(additionals_query_cache_key(object_type))
|
||||
session_data = Rails.cache.read additionals_query_cache_key(object_type)
|
||||
@query ||= query_class.new(name: '_',
|
||||
filters: session_data.nil? ? nil : session_data[:filters],
|
||||
group_by: session_data.nil? ? nil : session_data[:group_by],
|
||||
|
@ -79,11 +79,11 @@ module AdditionalsQueriesHelper
|
|||
def additionals_select2_search_users(options = {})
|
||||
q = params[:q].to_s.strip
|
||||
exclude_id = params[:user_id].to_i
|
||||
scope = User.active.where(type: 'User')
|
||||
scope = User.active.where type: 'User'
|
||||
scope = scope.visible unless options[:all_visible]
|
||||
scope = scope.where.not(id: exclude_id) if exclude_id.positive?
|
||||
scope = scope.where(options[:where_filter], options[:where_params]) if options[:where_filter]
|
||||
q.split(' ').map { |search_string| scope = scope.like(search_string) } if q.present?
|
||||
q.split.map { |search_string| scope = scope.like(search_string) } if q.present?
|
||||
scope = scope.order(last_login_on: :desc)
|
||||
.limit(Additionals::SELECT2_INIT_ENTRIES)
|
||||
@users = scope.to_a.sort! { |x, y| x.name <=> y.name }
|
||||
|
@ -140,13 +140,13 @@ module AdditionalsQueriesHelper
|
|||
def xlsx_write_header_row(workbook, worksheet, columns)
|
||||
columns_width = []
|
||||
columns.each_with_index do |c, index|
|
||||
value = if c.class.name == 'String'
|
||||
value = if c.is_a? String
|
||||
c
|
||||
else
|
||||
c.caption.to_s
|
||||
end
|
||||
|
||||
worksheet.write(0, index, value, workbook.add_format(xlsx_cell_format(:header)))
|
||||
worksheet.write 0, index, value, workbook.add_format(xlsx_cell_format(:header))
|
||||
columns_width << xlsx_get_column_width(value)
|
||||
end
|
||||
columns_width
|
||||
|
@ -224,13 +224,11 @@ module AdditionalsQueriesHelper
|
|||
|
||||
def xlsx_hyperlink_cell?(token)
|
||||
# Match http, https or ftp URL
|
||||
if %r{\A[fh]tt?ps?://}.match?(token)
|
||||
true
|
||||
# Match mailto:
|
||||
elsif token.present? && token.start_with?('mailto:')
|
||||
true
|
||||
# Match internal or external sheet link
|
||||
elsif /\A(?:in|ex)ternal:/.match?(token)
|
||||
if %r{\A[fh]tt?ps?://}.match?(token) ||
|
||||
# Match mailto:
|
||||
token.present? && token.start_with?('mailto:') ||
|
||||
# Match internal or external sheet link
|
||||
/\A(?:in|ex)ternal:/.match?(token)
|
||||
true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
module AdditionalsSelect2Helper
|
||||
def additionals_select2_tag(name, option_tags = nil, options = {})
|
||||
s = select_tag(name, option_tags, options)
|
||||
id = options.delete(:id) || sanitize_to_id(name)
|
||||
s << hidden_field_tag("#{name}[]", '') if options[:multiple] && options.fetch(:include_hidden, true)
|
||||
|
||||
s + javascript_tag("select2Tag('#{sanitize_to_id name}', #{options.to_json});")
|
||||
s + javascript_tag("select2Tag('#{id}', #{options.to_json});")
|
||||
end
|
||||
|
||||
# Transforms select filters of +type+ fields into select2
|
||||
|
|
|
@ -4,7 +4,6 @@ module AdditionalsSettingsHelper
|
|||
{ name: 'wiki', partial: 'additionals/settings/wiki', label: :label_wiki },
|
||||
{ name: 'macros', partial: 'additionals/settings/macros', label: :label_macro_plural },
|
||||
{ name: 'rules', partial: 'additionals/settings/issues', label: :label_issue_plural },
|
||||
{ name: 'users', partial: 'additionals/settings/users', label: :label_user_plural },
|
||||
{ name: 'web', partial: 'additionals/settings/web_apis', label: :label_web_apis }]
|
||||
|
||||
unless Redmine::Plugin.installed? 'redmine_hrm'
|
||||
|
@ -46,6 +45,22 @@ module AdditionalsSettingsHelper
|
|||
text_field_tag("settings[#{name}]", value, options)]
|
||||
end
|
||||
|
||||
def additionals_settings_passwordfield(name, options = {})
|
||||
label_title = options.delete(:label).presence || l("label_#{name}")
|
||||
value = options.delete(:value).presence || @settings[name]
|
||||
|
||||
safe_join [label_tag("settings[#{name}]", label_title),
|
||||
password_field_tag("settings[#{name}]", value, options)]
|
||||
end
|
||||
|
||||
def additionals_settings_urlfield(name, options = {})
|
||||
label_title = options.delete(:label).presence || l("label_#{name}")
|
||||
value = options.delete(:value).presence || @settings[name]
|
||||
|
||||
safe_join [label_tag("settings[#{name}]", label_title),
|
||||
url_field_tag("settings[#{name}]", value, options)]
|
||||
end
|
||||
|
||||
def additionals_settings_textarea(name, options = {})
|
||||
label_title = options.delete(:label).presence || l("label_#{name}")
|
||||
value = options.delete(:value).presence || @settings[name]
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
require 'digest/md5'
|
||||
|
||||
module AdditionalsTagHelper
|
||||
def additionals_tag_cloud(tags, options = {})
|
||||
return if tags.blank?
|
||||
|
||||
options[:show_count] = true
|
||||
|
||||
# prevent ActsAsTaggableOn::TagsHelper from calling `all`
|
||||
# otherwise we will need sort tags after `tag_cloud`
|
||||
tags = tags.all if tags.respond_to?(:all)
|
||||
|
||||
s = []
|
||||
tags.each do |tag|
|
||||
s << additionals_tag_link(tag, options)
|
||||
end
|
||||
|
||||
sep = if options[:tags_without_color]
|
||||
', '
|
||||
else
|
||||
' '
|
||||
end
|
||||
|
||||
tag.div safe_join(s, sep), class: 'tags'
|
||||
end
|
||||
|
||||
# plain list of tags
|
||||
def render_additionals_tags(tags, sep = ' ')
|
||||
s = if tags.blank?
|
||||
['']
|
||||
else
|
||||
tags.map(&:name)
|
||||
end
|
||||
s.join(sep)
|
||||
end
|
||||
|
||||
def additionals_tag_links(tag_list, options = {})
|
||||
return unless tag_list
|
||||
|
||||
sep = if options[:tags_without_color]
|
||||
', '
|
||||
else
|
||||
' '
|
||||
end
|
||||
|
||||
safe_join(tag_list.map do |tag|
|
||||
additionals_tag_link tag, options
|
||||
end, sep)
|
||||
end
|
||||
|
||||
def additionals_tag_link(tag_object, options = {})
|
||||
tag_name = []
|
||||
tag_name << tag_object.name
|
||||
|
||||
unless options[:tags_without_color]
|
||||
tag_bg_color = additionals_tag_color tag_object.name
|
||||
tag_fg_color = additionals_tag_fg_color tag_bg_color
|
||||
tag_style = "background-color: #{tag_bg_color}; color: #{tag_fg_color}"
|
||||
end
|
||||
|
||||
tag_name << tag.span("(#{tag_object.count})", class: 'tag-count') if options[:show_count]
|
||||
|
||||
if options[:tags_without_color]
|
||||
tag.span link_to(safe_join(tag_name), additionals_tag_url(tag_object.name, options)),
|
||||
class: 'tag-label'
|
||||
else
|
||||
tag.span link_to(safe_join(tag_name),
|
||||
additionals_tag_url(tag_object.name, options),
|
||||
style: tag_style),
|
||||
class: 'additionals-tag-label-color',
|
||||
style: tag_style
|
||||
end
|
||||
end
|
||||
|
||||
def additionals_tag_url(tag_name, options = {})
|
||||
action = options[:tag_action].presence || (controller_name == 'hrm_user_resources' ? 'show' : 'index')
|
||||
|
||||
{ controller: options[:tag_controller].presence || controller_name,
|
||||
action: action,
|
||||
set_filter: 1,
|
||||
project_id: options[:project],
|
||||
fields: [:tags],
|
||||
values: { tags: [tag_name] },
|
||||
operators: { tags: '=' } }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def tag_cloud(tags, classes)
|
||||
return [] if tags.empty?
|
||||
|
||||
max_count = tags.max_by(&:count).count.to_f
|
||||
|
||||
tags.each do |tag|
|
||||
index = ((tag.count / max_count) * (classes.size - 1))
|
||||
yield tag, classes[index.nan? ? 0 : index.round]
|
||||
end
|
||||
end
|
||||
|
||||
def additionals_tag_color(tag_name)
|
||||
"##{Digest::MD5.hexdigest(tag_name)[0..5]}"
|
||||
end
|
||||
|
||||
def additionals_tag_fg_color(bg_color)
|
||||
# calculate contrast text color according to YIQ method
|
||||
# https://24ways.org/2010/calculating-color-contrast/
|
||||
# https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color
|
||||
r = bg_color[1..2].hex
|
||||
g = bg_color[3..4].hex
|
||||
b = bg_color[5..6].hex
|
||||
(r * 299 + g * 587 + b * 114) >= 128_000 ? 'black' : 'white'
|
||||
end
|
||||
end
|
|
@ -86,10 +86,10 @@ module DashboardsHelper
|
|||
tag.div class: 'active-dashboards' do
|
||||
out = [tag.h3(l(:label_active_dashboard)),
|
||||
tag.ul do
|
||||
concat tag.ul "#{l :field_name}: #{dashboard.name}"
|
||||
concat tag.ul safe_join([l(:field_author), link_to_user(dashboard.author)], ': ')
|
||||
concat tag.ul "#{l :field_created_on}: #{format_time dashboard.created_at}"
|
||||
concat tag.ul "#{l :field_updated_on}: #{format_time dashboard.updated_at}"
|
||||
concat tag.li "#{l :field_name}: #{dashboard.name}"
|
||||
concat tag.li safe_join([l(:field_author), link_to_user(dashboard.author)], ': ')
|
||||
concat tag.li "#{l :field_created_on}: #{format_time dashboard.created_at}"
|
||||
concat tag.li "#{l :field_updated_on}: #{format_time dashboard.updated_at}"
|
||||
end]
|
||||
|
||||
if dashboard.description.present?
|
||||
|
@ -105,7 +105,7 @@ module DashboardsHelper
|
|||
return '' unless dashboards.any?
|
||||
|
||||
tag.h3(title, class: 'dashboards') +
|
||||
tag.ul do
|
||||
tag.ul(class: 'dashboards') do
|
||||
dashboards.each do |dashboard|
|
||||
selected = dashboard.id == if params[:dashboard_id].present?
|
||||
params[:dashboard_id].to_i
|
||||
|
@ -115,19 +115,24 @@ module DashboardsHelper
|
|||
|
||||
css = 'dashboard'
|
||||
css << ' selected' if selected
|
||||
li_class = nil
|
||||
|
||||
link = [dashboard_link(dashboard, project, class: css)]
|
||||
if dashboard.system_default?
|
||||
link << if dashboard.project_id.nil?
|
||||
font_awesome_icon('fas_cube',
|
||||
li_class = 'global'
|
||||
font_awesome_icon 'fas_cube',
|
||||
title: l(:field_system_default),
|
||||
class: 'dashboard-system-default global')
|
||||
class: "dashboard-system-default #{li_class}"
|
||||
else
|
||||
font_awesome_icon('fas_cube',
|
||||
li_class = 'project'
|
||||
font_awesome_icon 'fas_cube',
|
||||
title: l(:field_project_system_default),
|
||||
class: 'dashboard-system-default project')
|
||||
class: "dashboard-system-default #{li_class}"
|
||||
end
|
||||
end
|
||||
concat tag.li safe_join(link)
|
||||
|
||||
concat tag.li safe_join(link), class: li_class
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -325,7 +330,7 @@ module DashboardsHelper
|
|||
max_entries = settings[:max_entries] || DashboardContent::DEFAULT_MAX_ENTRIES
|
||||
|
||||
news = if dashboard.content_project.nil?
|
||||
News.latest User.current
|
||||
News.latest User.current, max_entries
|
||||
else
|
||||
dashboard.content_project
|
||||
.news
|
||||
|
@ -378,7 +383,7 @@ module DashboardsHelper
|
|||
max_entries = max_entries.present? ? max_entries.to_i : 10
|
||||
|
||||
begin
|
||||
URI.open(url) do |rss_feed|
|
||||
URI.parse(url).open do |rss_feed|
|
||||
rss = RSS::Parser.parse(rss_feed)
|
||||
rss.items.each do |item|
|
||||
cnt += 1
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue