diff --git a/README.rdoc b/README.rdoc index 3411c10..c91955c 100644 --- a/README.rdoc +++ b/README.rdoc @@ -1,4 +1,4 @@ -= Redmine Watcher Groups += Redmine Watcher Groups for Redmine 3.x.x Plugin for Redmine that adds functionality to have Watcher Groups in addition to Watchers. diff --git a/app/controllers/watcher_groups_controller.rb b/app/controllers/watcher_groups_controller.rb index 6cf3695..6ebfe4b 100644 --- a/app/controllers/watcher_groups_controller.rb +++ b/app/controllers/watcher_groups_controller.rb @@ -19,13 +19,19 @@ def create @watched.set_watcher_group(group, true) find_watcher_users = find_watcher_users | group.users end - if find_watcher_users.any? and Redmine::Plugin.installed? :redmine_advanced_issue_history - notes = [] - find_watcher_users.each do |user| - notes.append("Watcher #{user.name} was added") - end - add_system_journal(notes, issue) - end + if find_watcher_users.any? + if Setting['plugin_redmine_watcher_groups']['redmine_watcher_groups_log_watchers_setting'] == 'yes' + if Redmine::Plugin.installed? :redmine_advanced_issue_history + notes = [] + find_watcher_users.each do |user| + notes.append("Watcher #{user.name} was added") + end + add_system_journal(notes, issue) + else + issue.add_watcher_journal(:label_watcher_group_add, group_ids.flatten.compact.uniq.collect { |group_id| Group.find(group_id).name }.join(", ")) + end + end + end end end respond_to do |format| @@ -49,12 +55,16 @@ def destroy issue = Issue.find(params[:object_id]) group_users = group.users if group_users.any? - if Redmine::Plugin.installed? :redmine_advanced_issue_history - notes = [] - group_users.each do |user| - notes.append("Watcher #{user.name} was removed") - end - add_system_journal(notes, issue) + if Setting['plugin_redmine_watcher_groups']['redmine_watcher_groups_log_watchers_setting'] == 'yes' + if Redmine::Plugin.installed? :redmine_advanced_issue_history + notes = [] + group_users.each do |user| + notes.append("Watcher #{user.name} was removed") + end + add_system_journal(notes, issue) + else + issue.add_watcher_journal(:label_watcher_group_remove, group.name) + end end end end @@ -66,7 +76,7 @@ def destroy end def autocomplete_for_group - @groups = Group.active.like(params[:q]).find(:all, :limit => 100) + @groups = Group.sorted.active.like(params[:q]).limit(100) if @watched @groups -= @watched.watcher_groups end diff --git a/app/views/issues/new.html.erb b/app/views/issues/new.html.erb index 8b640be..22f0bc2 100644 --- a/app/views/issues/new.html.erb +++ b/app/views/issues/new.html.erb @@ -1,8 +1,8 @@ -

<%=l(:label_issue_new)%>

+<%= title l(:label_issue_new) %> <%= call_hook(:view_issues_new_top, {:issue => @issue}) %> -<%= labelled_form_for @issue, :url => project_issues_path(@project), +<%= labelled_form_for @issue, :url => _project_issues_path(@project), :html => {:id => 'issue-form', :multipart => true} do |f| %> <%= error_messages_for 'issue' %> <%= hidden_field_tag 'copy_from', params[:copy_from] if params[:copy_from] %> @@ -11,6 +11,12 @@ <%= render :partial => 'issues/form', :locals => {:f => f} %> + <% if @copy_from && Setting.link_copied_issue == 'ask' %> +

+ + <%= check_box_tag 'link_copy', '1', @link_copy %> +

+ <% end %> <% if @copy_from && @copy_from.attachments.any? %>

@@ -26,10 +32,10 @@

<%= render :partial => 'attachments/form', :locals => {:container => @issue} %>

- <% if @issue.safe_attribute? 'watcher_user_ids' %> + <% if @issue.safe_attribute? 'watcher_user_ids' -%>

- <%= watchers_checkboxes(@issue, @available_watchers) %> + <%= watchers_checkboxes(@issue, users_for_new_issue_watchers(@issue)) %> <%= link_to l(:label_search_for_watchers), @@ -49,9 +55,9 @@ <%= submit_tag l(:button_create) %> <%= submit_tag l(:button_create_and_continue), :name => 'continue' %> - <%= preview_link preview_new_issue_path(:project_id => @project), 'issue-form' %> + <%= preview_link preview_new_issue_path(:project_id => @issue.project), 'issue-form' %> - <%= javascript_tag "$('#issue_subject').focus();" %> + <%#= javascript_tag "$('#issue_subject').focus();" %> <% end %>

diff --git a/app/views/settings/_redmine_watcher_groups_settings.html.erb b/app/views/settings/_redmine_watcher_groups_settings.html.erb new file mode 100644 index 0000000..38b9b6b --- /dev/null +++ b/app/views/settings/_redmine_watcher_groups_settings.html.erb @@ -0,0 +1,10 @@ +

+ <%= label_tag 'redmine_watcher_groups_log_watchers_setting', l(:label_watcher_change_setlog) %> + <%= + select_tag 'settings[redmine_watcher_groups_log_watchers_setting]', options_for_select([ + [l(:general_text_No), 'no'], + [l(:general_text_Yes), 'yes'], + ], @settings['redmine_watcher_groups_log_watchers_setting']) %> + <%=l(:label_watcher_change_setlog_description) %> +

+ diff --git a/app/views/watcher_groups/_new.html.erb b/app/views/watcher_groups/_new.html.erb index ccb92ca..5b53e22 100644 --- a/app/views/watcher_groups/_new.html.erb +++ b/app/views/watcher_groups/_new.html.erb @@ -17,7 +17,7 @@
<%= principals_check_box_tags 'watcher_group[group_ids][]', ( # watched ? watched.addable_watcher_groups : - Group.sorted.active.all(:limit => 100)) %> + Group.sorted.active.limit(100) ) %>

diff --git a/config/locales/bg.yml b/config/locales/bg.yml new file mode 100644 index 0000000..3f3bd53 --- /dev/null +++ b/config/locales/bg.yml @@ -0,0 +1,3 @@ +bg: + label_watcher_change_setlog: "Запис в историята на задачата? " + label_watcher_change_setlog_description: "Промяната ще бъде записана в историята на задачата" diff --git a/config/locales/cs.yml b/config/locales/cs.yml new file mode 100644 index 0000000..2dc9837 --- /dev/null +++ b/config/locales/cs.yml @@ -0,0 +1,4 @@ +# Czech strings go here for Rails i18n +cs: + label_issue_watcher_groups: "Sledováno skupinami" + label_group_search: "Vyhledání skupiny:" diff --git a/config/locales/de.yml b/config/locales/de.yml new file mode 100644 index 0000000..3803266 --- /dev/null +++ b/config/locales/de.yml @@ -0,0 +1,7 @@ +# German strings go here for Rails i18n +de: + my_label: "Meine Kennung" + label_issue_watcher_groups: "Beobachtergruppen" + label_group_search: "Suche nach Gruppe:" + label_watcher_change_setlog: "Änderung in Issue-History loggen? " + label_watcher_change_setlog_description: "Alle Änderungen werden in der Bearbeitungshistorie des Tickets nachvollziehbar geloggt" diff --git a/config/locales/en.yml b/config/locales/en.yml index 9f1c058..aca8ff3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,5 +1,10 @@ # English strings go here for Rails i18n en: - my_label: "My label" label_issue_watcher_groups: "Watcher Groups" label_group_search: "Search for group:" + label_watcher_user_add: "'%{name}' added user(s) '%{target_name}' to watchers" + label_watcher_user_remove: "'%{name}' removed user(s) '%{target_name}' from watchers" + label_watcher_group_add: "'%{name}' added group(s) '%{target_name}' to watchers" + label_watcher_group_remove: "'%{name}' removed group(s) '%{target_name}' from watchers" + label_watcher_change_setlog: "Log in issue history? " + label_watcher_change_setlog_description: "Changes will be logged in history of that issue" diff --git a/config/locales/es.yml b/config/locales/es.yml new file mode 100644 index 0000000..35cf350 --- /dev/null +++ b/config/locales/es.yml @@ -0,0 +1,3 @@ +es: + label_watcher_change_setlog: "¿Registrar en el historial de la petición? " + label_watcher_change_setlog_description: "Los cambios serán registrados en el historial de la petición" diff --git a/config/locales/it.yml b/config/locales/it.yml index 99aa0b6..40f0ca6 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -1,4 +1,3 @@ it: - my_label: "Etichetta" label_issue_watcher_groups: "Gruppi osservatori" label_group_search: "Cerca un gruppo:" diff --git a/config/locales/ja.yml b/config/locales/ja.yml new file mode 100644 index 0000000..51b9d00 --- /dev/null +++ b/config/locales/ja.yml @@ -0,0 +1,10 @@ +# Japanese strings go here for Rails i18n +ja: + label_issue_watcher_groups: "ウォッチャーグループ" + label_group_search: "グループの検索:" + label_watcher_user_add: "「%{name}」がユーザ「%{target_name}」をウォッチャーに追加しました" + label_watcher_user_remove: "「%{name}」がユーザ「%{target_name}」をウォッチャーから外しました" + label_watcher_group_add: "「%{name}」がグループ「%{target_name}」をウォッチャーに追加しました" + label_watcher_group_remove: "「%{name}」がグループ「%{target_name}」をウォッチャーから外しました" + label_watcher_change_setlog: "チケット履歴に記録しますか? " + label_watcher_change_setlog_description: "変更はそのチケット履歴に記録されます" diff --git a/config/locales/nl.yml b/config/locales/nl.yml new file mode 100644 index 0000000..90128e9 --- /dev/null +++ b/config/locales/nl.yml @@ -0,0 +1,3 @@ +nl: + label_watcher_change_setlog: "Wijzigingen tonen in de geschiedenis? " + label_watcher_change_setlog_description: "Veranderingen zullen worden weergegeven in de geschiedenis van de ticket" diff --git a/config/locales/ru.yml b/config/locales/ru.yml new file mode 100644 index 0000000..ec53c9b --- /dev/null +++ b/config/locales/ru.yml @@ -0,0 +1,3 @@ +ru: + label_watcher_change_setlog: "Делать запись в журнал? " + label_watcher_change_setlog_description: "Измнение будет внесено в журнал данного документа" diff --git a/config/locales/tr.yml b/config/locales/tr.yml new file mode 100644 index 0000000..ee863b4 --- /dev/null +++ b/config/locales/tr.yml @@ -0,0 +1,3 @@ +tr: + label_watcher_change_setlog: "Tarihçeye kayıt? " + label_watcher_change_setlog_description: "Evet seçilirse bu değişikliğin kimin tarafından ne zaman yapıldığı işin tarihçesine eklenir." diff --git a/config/locales/zh.yml b/config/locales/zh.yml new file mode 100644 index 0000000..26bc9e6 --- /dev/null +++ b/config/locales/zh.yml @@ -0,0 +1,3 @@ +zh: + label_watcher_change_setlog: "记录到问题历史? " + label_watcher_change_setlog_description: "更改将会记录到该问题历史里" diff --git a/init.rb b/init.rb index efc3452..5b16843 100644 --- a/init.rb +++ b/init.rb @@ -16,13 +16,19 @@ IssuesController.send(:include, WatcherGroupsIssuesControllerPatch) end + unless WatchersController.included_modules.include?(WatcherGroupsWatchersControllerPatch) + WatchersController.send(:include, WatcherGroupsWatchersControllerPatch) + end + end Redmine::Plugin.register :redmine_watcher_groups do name 'Redmine Watcher Groups plugin' - author 'Kamen Ferdinandov, Massimo Rossello' + author 'Kamen Ferdinandov, Massimo Rossello, Stephane Lapie' description 'This is a plugin for Redmine to add watcher groups functionality' version '1.0.0' url 'http://github.com/maxrossello/redmine_watcher_groups' author_url 'http://github.com/maxrossello' + + settings :default => {"redmine_watcher_groups_log_watchers_setting" => 'no'}, :partial => 'settings/redmine_watcher_groups_settings' end diff --git a/lib/watcher_groups_helper.rb b/lib/watcher_groups_helper.rb index d23c37c..8529b6f 100644 --- a/lib/watcher_groups_helper.rb +++ b/lib/watcher_groups_helper.rb @@ -50,6 +50,7 @@ def watcher_groups_checkboxes(object, groups, checked=nil) :class => "floating" end.join.html_safe end + def watchers_list(object) remove_allowed = User.current.allowed_to?("delete_#{object.class.name.underscore}_watchers".to_sym, object.project) content = ''.html_safe diff --git a/lib/watcher_groups_issue_hook.rb b/lib/watcher_groups_issue_hook.rb index 1b80833..80c8abc 100644 --- a/lib/watcher_groups_issue_hook.rb +++ b/lib/watcher_groups_issue_hook.rb @@ -12,17 +12,21 @@ def controller_issues_new_after_save(context={}) context[:issue].save context[:issue].reload - notes = [] - group_ids = context[:params][:issue]["watcher_group_ids"] - group_ids.each do |group_id| - group_users = Group.find(group_id.to_i).users.uniq - group_users.each do |user| - notes.append("Watcher #{user.name} was added") - end - end - - if notes.any? and Redmine::Plugin.installed? :redmine_advanced_issue_history - add_system_journal(notes, context[:issue]) + if Setting['plugin_redmine_watcher_groups']['redmine_watcher_groups_log_watchers_setting'] == 'yes' + group_ids = context[:params][:issue]["watcher_group_ids"] + if Redmine::Plugin.installed? :redmine_advanced_issue_history + notes = [] + group_ids.each do |group_id| + group_users = Group.find(group_id.to_i).users.uniq + group_users.each do |user| + notes.append("Watcher #{user.name} was added") + end + end + add_system_journal(notes, context[:issue]) if notes.any? + else + watcher_name = group_ids.collect { |group_id| Group.find(group_id).name }.join(", ") + context[:issue].add_watcher_journal(:label_watcher_group_add, watcher_name) + end end end diff --git a/lib/watcher_groups_issue_patch.rb b/lib/watcher_groups_issue_patch.rb index 11cc1fe..94d957c 100644 --- a/lib/watcher_groups_issue_patch.rb +++ b/lib/watcher_groups_issue_patch.rb @@ -7,6 +7,7 @@ def self.included(base) # :nodoc: alias_method_chain :notified_watchers , :groups alias_method_chain :watched_by? , :groups alias_method_chain :watcher_users, :users + alias_method_chain :set_watcher, :journal end end @@ -19,10 +20,18 @@ def self.included(base) # :nodoc: joins(:watchers).where("#{Watcher.table_name}.user_id IN (#{user.id} #{g.empty? ? "" : ","} #{g.map(&:id).join(',')})") } + def add_watcher_journal(action, watcher_name) + if Setting['plugin_redmine_watcher_groups']['redmine_watcher_groups_log_watchers_setting'] == 'yes' + journal = self.init_journal(User.current, l(action, :name => User.current.name, :target_name => watcher_name).html_safe) + journal.save + end + end + def watcher_groups if self.id - groups = Watcher.find(:all, :conditions => "watchable_type='#{self.class}' and watchable_id = #{self.id}") - Group.find_all_by_id(groups.map(&:user_id)) + groups = Watcher.where("watchable_type='#{self.class}' and watchable_id = #{self.id}") + return [] if groups.empty? + Group.where(id: groups.map(&:user_id)) end end @@ -51,9 +60,7 @@ def addable_watcher_groups # Adds group as a watcher def add_watcher_group(group) - if Watcher.find(:all, - :conditions => "watchable_type='#{self.class}' and watchable_id = #{self.id} and user_id = '#{group.id}'", - :limit => 1).blank? + if Watcher.where("watchable_type='#{self.class}' and watchable_id = #{self.id} and user_id = '#{group.id}'").limit(1).blank? # insert directly into table to avoid user type checking Watcher.connection.execute("INSERT INTO #{Watcher.table_name} (user_id, watchable_id, watchable_type) VALUES (#{group.id}, #{self.id}, '#{self.class.name}')") end @@ -80,24 +87,24 @@ def watched_by_group?(group) module InstanceMethods def notified_watchers_with_groups notified = [] - - w = Watcher.find(:all, :conditions => "watchable_type='#{self.class}' and watchable_id = #{self.id}") - groups = Group.find_all_by_id(w.map(&:user_id)) + w = Watcher.where("watchable_type='#{self.class}' and watchable_id = #{self.id}") + groups = Group.where(id: w.map(&:user_id)) groups.each do |p| - group_users = p.users + group_users = p.users.to_a group_users.reject! {|user| user.mail.blank? || user.mail_notification == 'none'} if respond_to?(:visible?) group_users.reject! {|user| !visible?(user)} end - notified += group_users + notified |= group_users end - notified += watcher_users + + notified |= watcher_users.to_a notified.reject! {|user| user.mail.blank? || user.mail_notification == 'none'} if respond_to?(:visible?) notified.reject! {|user| !visible?(user)} end - notified.uniq + notified end def watched_by_with_groups?(user) @@ -109,10 +116,18 @@ def watched_by_with_groups?(user) def watcher_users_with_users users = watcher_users_without_users + old_object = users watcher_groups.each do |g| - users += g.users + users |= g.users end if self.id? - users.uniq + users.define_singleton_method(:reset) do old_object.reset end if old_object.class != users.class + users + end + + def set_watcher_with_journal(user, watching=true) + result = set_watcher_without_journal(user, watching) + self.add_watcher_journal((watching ? :label_watcher_user_add : :label_watcher_user_remove), user.name) + result end end end diff --git a/lib/watcher_groups_issues_controller_patch.rb b/lib/watcher_groups_issues_controller_patch.rb index 78738c5..7b31000 100644 --- a/lib/watcher_groups_issues_controller_patch.rb +++ b/lib/watcher_groups_issues_controller_patch.rb @@ -6,6 +6,18 @@ def self.included(base) # :nodoc: base.class_eval do helper :watcher_groups include WatcherGroupsHelper + + def new + respond_to do |format| + format.html { + render :action => 'new', :layout => !request.xhr? + } + format.js { + #this is needed for proper rendering /projects/:project/issues/new.js + render :action => 'new', formats: [:js], :layout => false + } + end + end end end diff --git a/lib/watcher_groups_watchers_controller_patch.rb b/lib/watcher_groups_watchers_controller_patch.rb new file mode 100644 index 0000000..c4da8cf --- /dev/null +++ b/lib/watcher_groups_watchers_controller_patch.rb @@ -0,0 +1,26 @@ +module WatcherGroupsWatchersControllerPatch + def self.included(base) # :nodoc: + base.send(:include, InstanceMethods) + base.class_eval do + alias_method_chain :create, :journal + end + end + + WatchersController.class_eval do + module InstanceMethods + def create_with_journal + create_without_journal + user_ids = [] + if params[:watcher].is_a?(Hash) + user_ids << (params[:watcher][:user_ids] || params[:watcher][:user_id]) + else + user_ids << params[:user_id] + end + @watchables.each do |watched| + watched.add_watcher_journal(:label_watcher_user_add, user_ids.flatten.compact.uniq.collect { |user_id| User.find(user_id).name }.join(", ")) + end + end + end + end +end +