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
|
@ -1,3 +1,5 @@
|
|||
require 'additionals/version'
|
||||
|
||||
module Additionals
|
||||
MAX_CUSTOM_MENU_ITEMS = 5
|
||||
SELECT2_INIT_ENTRIES = 20
|
||||
|
@ -5,17 +7,15 @@ module Additionals
|
|||
GOTO_LIST = " \xc2\xbb".freeze
|
||||
LIST_SEPARATOR = "#{GOTO_LIST} ".freeze
|
||||
|
||||
RenderAsync.configuration.jquery = true
|
||||
|
||||
class << self
|
||||
def setup
|
||||
incompatible_plugins %w[redmine_issue_control_panel
|
||||
redmine_editauthor
|
||||
RenderAsync.configuration.jquery = true
|
||||
|
||||
incompatible_plugins %w[redmine_editauthor
|
||||
redmine_changeauthor
|
||||
redmine_auto_watch]
|
||||
|
||||
patch %w[AccountController
|
||||
ApplicationController
|
||||
patch %w[ApplicationController
|
||||
AutoCompletesController
|
||||
Issue
|
||||
IssuePriority
|
||||
|
@ -60,22 +60,7 @@ module Additionals
|
|||
require_dependency 'additionals/hooks'
|
||||
|
||||
# Macros
|
||||
load_macros %w[cryptocompare date fa gist gmap google_docs group_users iframe
|
||||
issue redmine_issue redmine_wiki
|
||||
last_updated_at last_updated_by meteoblue member new_issue project
|
||||
recently_updated reddit slideshare tradingview twitter user vimeo youtube asciinema]
|
||||
end
|
||||
|
||||
def settings_compatible(plugin_name)
|
||||
if Setting[plugin_name].class == Hash
|
||||
# convert Rails 4 data (this runs only once)
|
||||
new_settings = ActiveSupport::HashWithIndifferentAccess.new(Setting[plugin_name])
|
||||
Setting.send("#{plugin_name}=", new_settings)
|
||||
new_settings
|
||||
else
|
||||
# Rails 5 uses ActiveSupport::HashWithIndifferentAccess
|
||||
Setting[plugin_name]
|
||||
end
|
||||
load_macros
|
||||
end
|
||||
|
||||
# support with default setting as fall back
|
||||
|
@ -91,6 +76,15 @@ module Additionals
|
|||
true? setting(value)
|
||||
end
|
||||
|
||||
# required multiple times because of this bug: https://www.redmine.org/issues/33290
|
||||
def redmine_database_ready?(with_table = nil)
|
||||
ActiveRecord::Base.connection
|
||||
rescue ActiveRecord::NoDatabaseError
|
||||
false
|
||||
else
|
||||
with_table.nil? || ActiveRecord::Base.connection.table_exists?(with_table)
|
||||
end
|
||||
|
||||
def true?(value)
|
||||
return false if value.is_a? FalseClass
|
||||
return true if value.is_a?(TrueClass) || value.to_i == 1 || value.to_s.casecmp('true').zero?
|
||||
|
@ -98,6 +92,17 @@ module Additionals
|
|||
false
|
||||
end
|
||||
|
||||
def debug(message)
|
||||
return if Rails.env.production?
|
||||
|
||||
Rails.logger.debug "#{Time.current.strftime('%H:%M:%S')} DEBUG [#{caller_locations(1..1).first.label}]: #{message}"
|
||||
end
|
||||
|
||||
def class_prefix(klass)
|
||||
klass_name = klass.is_a?(String) ? klass : klass.name
|
||||
klass_name.underscore.tr '/', '_'
|
||||
end
|
||||
|
||||
def now_with_user_time_zone(user = User.current)
|
||||
if user.time_zone.nil?
|
||||
Time.zone.now
|
||||
|
@ -108,7 +113,7 @@ module Additionals
|
|||
|
||||
def incompatible_plugins(plugins = [], title = 'additionals')
|
||||
plugins.each do |plugin|
|
||||
raise "\n\033[31m#{title} plugin cannot be used with #{plugin} plugin'.\033[0m" if Redmine::Plugin.installed?(plugin)
|
||||
raise "\n\033[31m#{title} plugin cannot be used with #{plugin} plugin.\033[0m" if Redmine::Plugin.installed?(plugin)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -124,10 +129,19 @@ module Additionals
|
|||
end
|
||||
end
|
||||
|
||||
def load_macros(macros = [], plugin_id = 'additionals')
|
||||
macro_dir = Rails.root.join("plugins/#{plugin_id}/lib/#{plugin_id}/wiki_macros")
|
||||
macros.each do |macro|
|
||||
require_dependency "#{macro_dir}/#{macro.underscore}_macro"
|
||||
def load_macros(plugin_id = 'additionals')
|
||||
Dir[File.join(plugin_dir(plugin_id),
|
||||
'lib',
|
||||
plugin_id,
|
||||
'wiki_macros',
|
||||
'**/*_macro.rb')].sort.each { |f| require f }
|
||||
end
|
||||
|
||||
def plugin_dir(plugin_id = 'additionals')
|
||||
if Gem.loaded_specs[plugin_id].nil?
|
||||
File.join Redmine::Plugin.directory, plugin_id
|
||||
else
|
||||
Gem.loaded_specs[plugin_id].full_gem_path
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -135,7 +149,7 @@ module Additionals
|
|||
cached_settings_name = "@load_settings_#{plugin_id}"
|
||||
cached_settings = instance_variable_get cached_settings_name
|
||||
if cached_settings.nil?
|
||||
data = YAML.safe_load(ERB.new(IO.read(Rails.root.join("plugins/#{plugin_id}/config/settings.yml"))).result) || {}
|
||||
data = YAML.safe_load(ERB.new(IO.read(File.join(plugin_dir(plugin_id), '/config/settings.yml'))).result) || {}
|
||||
instance_variable_set cached_settings_name, data.symbolize_keys
|
||||
else
|
||||
cached_settings
|
||||
|
@ -156,7 +170,31 @@ module Additionals
|
|||
private
|
||||
|
||||
def settings
|
||||
settings_compatible :plugin_additionals
|
||||
Setting[:plugin_additionals]
|
||||
end
|
||||
end
|
||||
|
||||
# Run the classic redmine plugin initializer after rails boot
|
||||
class Plugin < ::Rails::Engine
|
||||
require 'deface'
|
||||
require 'emoji'
|
||||
require 'render_async'
|
||||
require 'rss'
|
||||
require 'slim'
|
||||
|
||||
config.after_initialize do
|
||||
# engine_name could be used (additionals_plugin), but can
|
||||
# create some side effencts
|
||||
plugin_id = 'additionals'
|
||||
|
||||
# if plugin is already in plugins directory, use this and leave here
|
||||
next if Redmine::Plugin.installed? plugin_id
|
||||
|
||||
# gem is used as redmine plugin
|
||||
require File.expand_path '../init', __dir__
|
||||
AdditionalTags.setup
|
||||
Additionals::Gemify.install_assets plugin_id
|
||||
Additionals::Gemify.create_plugin_hint plugin_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ module Additionals
|
|||
users = prj.assignable_users_and_groups.to_a
|
||||
users << author if author&.active?
|
||||
if assigned_to_id_was.present?
|
||||
assignee = Principal.find_by(id: assigned_to_id_was)
|
||||
assignee = Principal.find_by id: assigned_to_id_was
|
||||
users << assignee if assignee
|
||||
end
|
||||
|
||||
|
|
62
plugins/additionals/lib/additionals/gemify.rb
Normal file
62
plugins/additionals/lib/additionals/gemify.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
module Additionals
|
||||
class Gemify
|
||||
class << self
|
||||
# install assets from gem (without asset pipline)
|
||||
def install_assets(plugin_id = 'additionals')
|
||||
return unless Gem.loaded_specs[plugin_id]
|
||||
|
||||
source = File.join Gem.loaded_specs[plugin_id].full_gem_path, 'assets'
|
||||
destination = File.join Dir.pwd, 'public', 'plugin_assets', plugin_id
|
||||
return unless File.directory? source
|
||||
|
||||
source_files = Dir["#{source}/**/*"]
|
||||
source_dirs = source_files.select { |d| File.directory?(d) }
|
||||
source_files -= source_dirs
|
||||
|
||||
unless source_files.empty?
|
||||
base_target_dir = File.join(destination, File.dirname(source_files.first).gsub(source, ''))
|
||||
begin
|
||||
FileUtils.mkdir_p base_target_dir
|
||||
rescue StandardError => e
|
||||
raise "Could not create directory #{base_target_dir}: " + e.message
|
||||
end
|
||||
end
|
||||
|
||||
source_dirs.each do |dir|
|
||||
target_dir = File.join(destination, dir.gsub(source, ''))
|
||||
begin
|
||||
FileUtils.mkdir_p(target_dir)
|
||||
rescue StandardError => e
|
||||
raise "Could not create directory #{target_dir}: " + e.message
|
||||
end
|
||||
end
|
||||
|
||||
source_files.each do |file|
|
||||
begin
|
||||
target = File.join destination, file.gsub(source, '')
|
||||
FileUtils.cp(file, target) unless File.exist?(target) && FileUtils.identical?(file, target)
|
||||
rescue StandardError => e
|
||||
raise "Could not copy #{file} to #{target}: " + e.message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Create text file to Redmine's plugins directory.
|
||||
# The purpose is telling plugins directory to users.
|
||||
def create_plugin_hint(plugin_id = 'additionals')
|
||||
plugins_dir = File.join(Bundler.root, 'plugins')
|
||||
path = File.join plugins_dir, plugin_id
|
||||
return if File.exist? path
|
||||
|
||||
File.open(path, 'w') do |f|
|
||||
f.write(<<PLUGIN_HINT)
|
||||
This plugin was installed as gem wrote to Gemfile.local instead of putting Redmine's plugin directory.
|
||||
See #{plugin_id} gem installed directory.
|
||||
PLUGIN_HINT
|
||||
end
|
||||
rescue Errno::EACCES => e
|
||||
Rails.logger.warn "Could not create plugin hint file: #{e.message}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,5 +1,15 @@
|
|||
module Additionals
|
||||
module Helpers
|
||||
def link_to_external(name, link, options = {})
|
||||
options[:class] ||= 'external'
|
||||
options[:class] << ' external' if options[:class].exclude? 'external'
|
||||
|
||||
options[:rel] ||= 'noopener'
|
||||
options[:target] ||= '_blank'
|
||||
|
||||
link_to name, link, options
|
||||
end
|
||||
|
||||
def additionals_list_title(options)
|
||||
title = []
|
||||
if options[:issue]
|
||||
|
@ -116,16 +126,11 @@ module Additionals
|
|||
if uri.scheme.nil? && uri.path[0] != '/' && issue_id_parts.count == 2
|
||||
rc[:issue_id] = url
|
||||
else
|
||||
if request.nil?
|
||||
# this is used by mailer
|
||||
return rc if url.exclude?(Setting.host_name)
|
||||
elsif uri.host != URI.parse(request.original_url).host
|
||||
return rc
|
||||
end
|
||||
s_pos = uri.path.rindex '/issues/'
|
||||
return rc unless s_pos
|
||||
|
||||
s_pos = uri.path.rindex('/issues/')
|
||||
id_string = uri.path[s_pos + 8..-1]
|
||||
e_pos = id_string.index('/')
|
||||
e_pos = id_string.index '/'
|
||||
rc[:issue_id] = e_pos.nil? ? id_string : id_string[0..e_pos - 1]
|
||||
# check for comment_id
|
||||
rc[:comment_id] = uri.fragment[5..-1].to_i if comment_id.nil? && uri.fragment.present? && uri.fragment[0..4] == 'note-'
|
||||
|
@ -142,51 +147,6 @@ module Additionals
|
|||
safe_join s
|
||||
end
|
||||
|
||||
def system_uptime
|
||||
if windows_platform?
|
||||
`net stats srv | find "Statist"`
|
||||
elsif File.exist?('/proc/uptime')
|
||||
secs = `cat /proc/uptime`.to_i
|
||||
min = 0
|
||||
hours = 0
|
||||
days = 0
|
||||
if secs.positive?
|
||||
min = (secs / 60).round
|
||||
hours = (secs / 3_600).round
|
||||
days = (secs / 86_400).round
|
||||
end
|
||||
if days >= 1
|
||||
"#{days} #{l(:days, count: days)}"
|
||||
elsif hours >= 1
|
||||
"#{hours} #{l(:hours, count: hours)}"
|
||||
else
|
||||
"#{min} #{l(:minutes, count: min)}"
|
||||
end
|
||||
else
|
||||
# this should be mac os
|
||||
seconds = `sysctl -n kern.boottime | awk '{print $4}'`.tr(',', '')
|
||||
so = DateTime.strptime(seconds.strip, '%s')
|
||||
if so.present?
|
||||
time_tag(so)
|
||||
else
|
||||
days = `uptime | awk '{print $3}'`.to_i.round
|
||||
"#{days} #{l(:days, count: days)}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def system_info
|
||||
if windows_platform?
|
||||
'unknown'
|
||||
else
|
||||
`uname -a`
|
||||
end
|
||||
end
|
||||
|
||||
def windows_platform?
|
||||
true if /cygwin|mswin|mingw|bccwin|wince|emx/.match?(RUBY_PLATFORM)
|
||||
end
|
||||
|
||||
def autocomplete_select_entries(name, type, option_tags, options = {})
|
||||
unless option_tags.is_a?(String) || option_tags.blank?
|
||||
# if option_tags is not an array, it should be an object
|
||||
|
@ -212,18 +172,25 @@ module Additionals
|
|||
|
||||
def project_list_css_classes(project, level)
|
||||
classes = [cycle('odd', 'even')]
|
||||
classes += project.css_classes.split(' ')
|
||||
classes += project.css_classes.split
|
||||
if level.positive?
|
||||
classes << 'idnt'
|
||||
classes << "idnt-#{level}"
|
||||
end
|
||||
classes.join(' ')
|
||||
classes.join ' '
|
||||
end
|
||||
|
||||
def addtionals_textarea_cols(text, options = {})
|
||||
[[(options[:min].presence || 8), text.to_s.length / 50].max, (options[:max].presence || 20)].min
|
||||
end
|
||||
|
||||
def title_with_fontawesome(title, symbole, wrapper = 'span')
|
||||
tag.send(wrapper) do
|
||||
concat tag.i class: "#{symbole} for-fa-title", 'aria-hidden': 'true'
|
||||
concat title
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def additionals_already_loaded(scope, js_name)
|
||||
|
@ -261,10 +228,6 @@ module Additionals
|
|||
additionals_include_js 'clipboard.min'
|
||||
end
|
||||
|
||||
def additionals_load_observe_field
|
||||
additionals_include_js 'additionals_observe_field'
|
||||
end
|
||||
|
||||
def additionals_load_font_awesome
|
||||
additionals_include_css 'fontawesome-all.min'
|
||||
end
|
||||
|
@ -311,12 +274,10 @@ module Additionals
|
|||
return if user.nil?
|
||||
|
||||
if user.type == 'Group'
|
||||
if options[:no_link]
|
||||
if options[:no_link] || !Redmine::Plugin.installed?('redmine_hrm')
|
||||
user.name
|
||||
elsif Redmine::Plugin.installed? 'redmine_hrm'
|
||||
link_to_hrm_group user
|
||||
else
|
||||
user.name
|
||||
link_to_hrm_group user
|
||||
end
|
||||
else
|
||||
options[:size] = 14 if options[:size].nil?
|
||||
|
|
|
@ -17,7 +17,7 @@ module Additionals
|
|||
render_on :view_my_account_preferences, partial: 'users/autowatch_involved_issue'
|
||||
render_on :view_users_form_preferences, partial: 'users/autowatch_involved_issue'
|
||||
render_on :view_users_show_contextual, partial: 'users/additionals_contextual'
|
||||
render_on :view_wiki_show_sidebar_bottom, partial: 'additionals_sidebar'
|
||||
render_on :view_wiki_show_sidebar_bottom, partial: 'wiki/additionals_sidebar'
|
||||
|
||||
def helper_issues_show_detail_after_setting(context = {})
|
||||
detail = context[:detail]
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
module Additionals
|
||||
module Patches
|
||||
module AccountControllerPatch
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
include InstanceMethods
|
||||
invisible_captcha(only: [:register],
|
||||
on_timestamp_spam: :timestamp_spam_check,
|
||||
if: -> { Additionals.setting?(:invisible_captcha) })
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def timestamp_spam_check
|
||||
# redmine uses same action for _GET and _POST
|
||||
return unless request.post?
|
||||
|
||||
if respond_to?(:redirect_back)
|
||||
redirect_back(fallback_location: home_url, flash: { error: InvisibleCaptcha.timestamp_error_message })
|
||||
else
|
||||
redirect_to :back, flash: { error: InvisibleCaptcha.timestamp_error_message }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,15 +12,15 @@ module Additionals
|
|||
end
|
||||
end
|
||||
|
||||
def issue_assignee
|
||||
assignee_classes = ['User']
|
||||
assignee_classes << 'Group' if Setting.issue_group_assignment?
|
||||
def global_users
|
||||
scope = Principal.assignable
|
||||
@assignee = scope.like(params[:q]).sorted.limit(100).to_a
|
||||
render layout: false, partial: 'issue_assignee'
|
||||
end
|
||||
|
||||
scope = Principal.where(type: assignee_classes).limit(100)
|
||||
scope = scope.member_of(project) if @project.present?
|
||||
scope = scope.distinct
|
||||
@assignee = scope.active.visible.sorted.like(params[:q]).to_a
|
||||
@assignee = @assignee.sort! { |x, y| x.name <=> y.name }
|
||||
def issue_assignee
|
||||
scope = Principal.assignable_for_issues @project
|
||||
@assignee = scope.like(params[:q]).sorted.limit(100).to_a
|
||||
render layout: false, partial: 'issue_assignee'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -54,18 +54,19 @@ module Additionals
|
|||
!watcher.active? ||
|
||||
watched_by?(watcher)
|
||||
|
||||
add_watcher(watcher)
|
||||
add_watcher watcher
|
||||
end
|
||||
|
||||
def autowatch_involved
|
||||
return unless Additionals.setting?(:issue_autowatch_involved) &&
|
||||
User.current.pref.autowatch_involved_issue
|
||||
return if Redmine::Plugin.installed?('redmine_automation') && author_id == RedmineAutomation.bot_user_id
|
||||
|
||||
add_autowatcher(User.current)
|
||||
add_autowatcher User.current
|
||||
add_autowatcher(author) if (new_record? || author_id != author_id_was) && author != User.current
|
||||
|
||||
if !assigned_to_id.nil? && assigned_to_id != User.current.id && (new_record? || assigned_to_id != assigned_to_id_was)
|
||||
add_autowatcher(assigned_to)
|
||||
add_autowatcher assigned_to
|
||||
end
|
||||
|
||||
true
|
||||
|
@ -105,14 +106,10 @@ module Additionals
|
|||
end
|
||||
|
||||
def status_x_affected?(new_status_id)
|
||||
return false unless Additionals.setting?(:issue_current_user_status)
|
||||
return false unless Additionals.setting? :issue_current_user_status
|
||||
return false if Additionals.setting(:issue_assign_to_x).blank?
|
||||
|
||||
if Additionals.setting(:issue_assign_to_x).include?(new_status_id.to_s)
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
Additionals.setting(:issue_assign_to_x).include? new_status_id.to_s
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -4,6 +4,19 @@ module Additionals
|
|||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
scope :assignable, -> { active.visible.where(type: %w[User Group]) }
|
||||
|
||||
scope :assignable_for_issues, lambda { |*args|
|
||||
project = args.first
|
||||
users = assignable
|
||||
users = users.where.not(type: 'Group') unless Setting.issue_group_assignment?
|
||||
users = users.joins(members: :roles)
|
||||
.where(roles: { assignable: true })
|
||||
.distinct
|
||||
users = users.member_of project if project.present?
|
||||
users
|
||||
}
|
||||
|
||||
# TODO: find better solution, which not requires overwrite visible
|
||||
# to filter out hide role members
|
||||
scope :visible, lambda { |*args|
|
||||
|
|
|
@ -37,26 +37,20 @@ module Additionals
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def users_by_role_old
|
||||
roles_with_users = if Redmine::VERSION.to_s >= '4.2'
|
||||
principals_by_role
|
||||
else
|
||||
super
|
||||
end
|
||||
|
||||
roles_with_users.each do |role_with_users|
|
||||
role = role_with_users.first
|
||||
next unless role.hide
|
||||
|
||||
roles_with_users.delete(role) unless User.current.allowed_to?(:show_hidden_roles_in_memberbox, project)
|
||||
end
|
||||
|
||||
roles_with_users
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
# without hidden roles!
|
||||
def all_principals_by_role
|
||||
memberships.includes(:principal, :roles).each_with_object({}) do |m, h|
|
||||
m.roles.each do |r|
|
||||
h[r] ||= []
|
||||
h[r] << m.principal
|
||||
end
|
||||
h
|
||||
end
|
||||
end
|
||||
|
||||
def visible_principals
|
||||
query = ::Query.new(project: self, name: '_')
|
||||
query&.principals
|
||||
|
@ -70,10 +64,9 @@ module Additionals
|
|||
# assignable_users result depends on Setting.issue_group_assignment?
|
||||
# this result is not depending on issue settings
|
||||
def assignable_users_and_groups
|
||||
Principal.active
|
||||
Principal.assignable
|
||||
.joins(members: :roles)
|
||||
.where(type: %w[User Group],
|
||||
members: { project_id: id },
|
||||
.where(members: { project_id: id },
|
||||
roles: { assignable: true })
|
||||
.distinct
|
||||
.sorted
|
||||
|
|
3
plugins/additionals/lib/additionals/version.rb
Normal file
3
plugins/additionals/lib/additionals/version.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
module Additionals
|
||||
VERSION = '3.0.2-master'.freeze
|
||||
end
|
|
@ -48,7 +48,7 @@ module Additionals
|
|||
classes << "fa-#{values[0]}"
|
||||
end
|
||||
|
||||
classes += options[:class].split(' ') if options[:class].present?
|
||||
classes += options[:class].split if options[:class].present?
|
||||
classes << "fa-#{options[:size]}" if options[:size].present?
|
||||
|
||||
content_options = { class: classes.uniq.join(' ') }
|
||||
|
|
|
@ -43,7 +43,7 @@ module Additionals
|
|||
comment_id = info[:comment_id] if comment_id.nil?
|
||||
info[:issue_id])
|
||||
|
||||
issue = Issue.find_by(id: issue_id)
|
||||
issue = Issue.find_by id: issue_id
|
||||
return if issue.nil? || !issue.visible?
|
||||
|
||||
text = case options[:format]
|
||||
|
|
|
@ -23,7 +23,7 @@ module Additionals
|
|||
|
||||
macro :projects do |_obj, args|
|
||||
_args, options = extract_macro_options(args, :title, :with_create_issue)
|
||||
@projects = Additionals.load_projects
|
||||
@projects = User.current.projects.active.includes(:enabled_modules).sorted
|
||||
return if @projects.nil?
|
||||
|
||||
@html_options = { class: 'external' }
|
||||
|
@ -35,13 +35,4 @@ module Additionals
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.load_projects
|
||||
all_projects = Project.active.visible.sorted
|
||||
my_projects = []
|
||||
all_projects.each do |p|
|
||||
my_projects << p if User.current.member_of?(p)
|
||||
end
|
||||
my_projects
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,6 +33,8 @@ module Additionals
|
|||
.where("#{WikiContent.table_name}.updated_on > ?", User.current.today - days)
|
||||
.order("#{WikiContent.table_name}.updated_on desc")
|
||||
|
||||
pages = pages.visible(User.current, project: project) if pages.respond_to? :visible
|
||||
|
||||
s = []
|
||||
date = nil
|
||||
pages.each do |page_raw|
|
||||
|
|
|
@ -4,7 +4,7 @@ module Additionals
|
|||
Redmine::WikiFormatting::Macros.register do
|
||||
desc "Display link to user profile\n\n" \
|
||||
"Syntax:\n\n" \
|
||||
"{{user(USER_NAME [, format=USER_FORMAT, avatar=BOOL])}}\n\n" \
|
||||
"{{user(USER_NAME [, format=USER_FORMAT, text=BOOL], avatar=BOOL])}}\n\n" \
|
||||
"USER_NAME can be user id or user name (login name)\n" \
|
||||
"USER_FORMATS\n" \
|
||||
"- system (use system settings) (default)\n- " +
|
||||
|
@ -14,19 +14,26 @@ module Additionals
|
|||
"...Link to user with user id 1\n\n" \
|
||||
"{{user(1, avatar=true)}}\n" \
|
||||
"...Link to user with user id 1 with avatar\n\n" \
|
||||
"{{user(current_user, text=true)}}\n" \
|
||||
"...Show only user (without link) of the current user\n\n" \
|
||||
"{{user(admin)}}\n" \
|
||||
"...Link to user with username 'admin'\n\n" \
|
||||
"{{user(admin, format=firstname)}}\n" \
|
||||
"...Link to user with username 'admin' and show firstname as link text"
|
||||
|
||||
macro :user do |_obj, args|
|
||||
args, options = extract_macro_options(args, :format, :avatar)
|
||||
args, options = extract_macro_options(args, :format, :avatar, :text)
|
||||
raise 'The correct usage is {{user(<user_id or username>, format=USER_FORMAT)}}' if args.empty?
|
||||
|
||||
user_id = args[0]
|
||||
|
||||
user = User.find_by id: user_id
|
||||
user ||= User.find_by(login: user_id)
|
||||
user ||= if user_id == 'current_user'
|
||||
User.current
|
||||
else
|
||||
User.find_by login: user_id
|
||||
end
|
||||
|
||||
return if user.nil?
|
||||
|
||||
name = if options[:format].blank?
|
||||
|
@ -41,10 +48,12 @@ module Additionals
|
|||
s << ' '
|
||||
end
|
||||
|
||||
s << if user.active?
|
||||
link_to h(name), user_url(user, only_path: controller_path != 'mailer'), class: user.css_classes
|
||||
link_css = "macro #{user.css_classes}"
|
||||
|
||||
s << if user.active? && (options[:text].blank? || !options[:text])
|
||||
link_to h(name), user_url(user, only_path: controller_path != 'mailer'), class: link_css
|
||||
else
|
||||
h name
|
||||
tag.span h(name), class: link_css
|
||||
end
|
||||
safe_join s
|
||||
end
|
||||
|
|
|
@ -21,12 +21,7 @@ module Additionals
|
|||
|
||||
width = options[:width].presence || 640
|
||||
height = options[:height].presence || 360
|
||||
|
||||
autoplay = if !options[:autoplay].nil? && Additionals.true?(options[:autoplay])
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
autoplay = !options[:autoplay].nil? && Additionals.true?(options[:autoplay])
|
||||
|
||||
raise 'The correct usage is {{vimeo(<video key>[, width=x, height=y])}}' if args.empty?
|
||||
|
||||
|
|
|
@ -21,12 +21,7 @@ module Additionals
|
|||
|
||||
width = options[:width].presence || 640
|
||||
height = options[:height].presence || 360
|
||||
|
||||
autoplay = if !options[:autoplay].nil? && Additionals.true?(options[:autoplay])
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
autoplay = !options[:autoplay].nil? && Additionals.true?(options[:autoplay])
|
||||
|
||||
raise 'The correct usage is {{youtube(<video key>[, width=x, height=y])}}' if args.empty?
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue