diff --git a/after_init.rb b/after_init.rb index fb79f6a1..29dd305d 100644 --- a/after_init.rb +++ b/after_init.rb @@ -91,6 +91,16 @@ def dmsf_init :reorder_steps, :update, :update_step, :delete_step, :edit] } pmap.permission :display_system_folders, read: true + # Watchers + pmap.permission :view_dmsf_file_watchers, {}, read: true + pmap.permission :add_dmsf_file_watchers, { watchers: [:new, :create, :append, :autocomplete_for_user]} + pmap.permission :delete_dmsf_file_watchers, { watchers: :destroy} + pmap.permission :view_dmsf_folder_watchers, {}, read: true + pmap.permission :add_dmsf_folder_watchers, { watchers: [:new, :create, :append, :autocomplete_for_user]} + pmap.permission :delete_dmsf_folder_watchers, { watchers: :destroy} + pmap.permission :view_project_watchers, {}, read: true + pmap.permission :add_project_watchers, { watchers: [:new, :create, :append, :autocomplete_for_user]} + pmap.permission :delete_project_watchers, { watchers: :destroy} end end end diff --git a/app/controllers/dmsf_context_menus_controller.rb b/app/controllers/dmsf_context_menus_controller.rb index e97c7e7c..aad0e539 100644 --- a/app/controllers/dmsf_context_menus_controller.rb +++ b/app/controllers/dmsf_context_menus_controller.rb @@ -22,10 +22,12 @@ class DmsfContextMenusController < ApplicationController helper :context_menus + helper :watchers before_action :find_folder before_action :find_dmsf_file before_action :find_dmsf_folder + before_action :find_dmsf_project def dmsf if @dmsf_file @@ -48,6 +50,12 @@ class DmsfContextMenusController < ApplicationController @project = @dmsf_link.project @allowed = User.current.allowed_to? :file_manipulation, @project @email_allowed = false + elsif @dmsf_project # project + @locked = false + @unlockable = false + @project = @dmsf_project + @allowed = User.current.allowed_to? :view_project_watchers, @project + @email_allowed = false else # multiple selection @project = get_project @locked = false @@ -56,7 +64,12 @@ class DmsfContextMenusController < ApplicationController User.current.allowed_to?(:folder_manipulation, @project) @email_allowed = User.current.allowed_to?(:email_documents, @project) end - @back_url = dmsf_folder_path(id: @project, folder_id: @folder) + if params['back_url'].present? + @back_url = params['back_url'] + else + @back_url = dmsf_folder_path(id: @project, folder_id: @folder) + end + @notifications = Setting.notified_events.include?('dmsf_legacy_notifications') render layout: false rescue ActiveRecord::RecordNotFound render_404 @@ -138,4 +151,12 @@ class DmsfContextMenusController < ApplicationController end end + def find_dmsf_project + if (params[:ids].present? && (params[:ids].size == 1)) && (!@dmsf_project) + if params[:ids][0] =~ /project-(\d+)/ + @dmsf_project = Project.find_by(id: $1) + end + end + end + end \ No newline at end of file diff --git a/app/controllers/dmsf_controller.rb b/app/controllers/dmsf_controller.rb index eaee48c8..53a3bf3d 100644 --- a/app/controllers/dmsf_controller.rb +++ b/app/controllers/dmsf_controller.rb @@ -45,6 +45,7 @@ class DmsfController < ApplicationController helper :dmsf_queries include DmsfQueriesHelper helper :context_menus + helper :watchers def permissions if !DmsfFolder.permissions?(@folder, false) @@ -79,6 +80,7 @@ class DmsfController < ApplicationController @folder_manipulation_allowed = User.current.allowed_to?(:folder_manipulation, @project) @file_manipulation_allowed = User.current.allowed_to?(:file_manipulation, @project) @trash_enabled = @folder_manipulation_allowed && @file_manipulation_allowed + @notifications = Setting.notified_events.include?('dmsf_legacy_notifications') @query.dmsf_folder_id = @folder ? @folder.id : nil @query.deleted = false @query.sub_projects |= Setting.plugin_redmine_dmsf['dmsf_projects_as_subfolders'].present? @@ -236,6 +238,11 @@ class DmsfController < ApplicationController @pathfolder = copy_folder(@folder) @force_file_unlock_allowed = User.current.allowed_to?(:force_file_unlock, @project) @redirect_to_folder_id = params[:redirect_to_folder_id] + @notifications = Setting.notified_events.include?('dmsf_legacy_notifications') + end + + def edit_root + @notifications = Setting.notified_events.include?('dmsf_legacy_notifications') end def create diff --git a/app/controllers/dmsf_files_controller.rb b/app/controllers/dmsf_files_controller.rb index f186ca57..85a57131 100644 --- a/app/controllers/dmsf_files_controller.rb +++ b/app/controllers/dmsf_files_controller.rb @@ -36,6 +36,8 @@ class DmsfFilesController < ApplicationController helper :dmsf_workflows helper :dmsf helper :queries + helper :watchers + helper :context_menus include QueriesHelper @@ -83,6 +85,7 @@ class DmsfFilesController < ApplicationController @file_manipulation_allowed = User.current.allowed_to?(:file_manipulation, @project) @revision_count = @file.dmsf_file_revisions.visible.all.size @revision_pages = Paginator.new @revision_count, params['per_page'] ? params['per_page'].to_i : 25, params['page'] + @notifications = Setting.notified_events.include?('dmsf_legacy_notifications') respond_to do |format| format.html { diff --git a/app/controllers/dmsf_workflows_controller.rb b/app/controllers/dmsf_workflows_controller.rb index 50839db2..673c3912 100644 --- a/app/controllers/dmsf_workflows_controller.rb +++ b/app/controllers/dmsf_workflows_controller.rb @@ -74,99 +74,110 @@ class DmsfWorkflowsController < ApplicationController end if revision.workflow == DmsfWorkflow::STATE_APPROVED # Just approved - recipients = DmsfMailer.get_notify_users(@project, [revision.dmsf_file], true) - DmsfMailer.deliver_workflow_notification( - recipients, - @dmsf_workflow, - revision, - :text_email_subject_approved, - :text_email_finished_approved, - :text_email_to_see_history) - if Setting.plugin_redmine_dmsf['dmsf_display_notified_recipients'] - unless recipients.blank? - to = recipients.collect{ |r| r.name }.first(DMSF_MAX_NOTIFICATION_RECEIVERS_INFO).join(', ') - to << ((recipients.count > DMSF_MAX_NOTIFICATION_RECEIVERS_INFO) ? ',...' : '.') - flash[:warning] = l(:warning_email_notifications, to: to) + if Setting.notified_events.include?('dmsf_workflow_action') + recipients = DmsfMailer.get_notify_users(@project, revision.dmsf_file, true) + DmsfMailer.deliver_workflow_notification( + recipients, + @dmsf_workflow, + revision, + :text_email_subject_approved, + :text_email_finished_approved, + :text_email_to_see_history) + if Setting.plugin_redmine_dmsf['dmsf_display_notified_recipients'] + unless recipients.blank? + to = recipients.collect{ |r| r.name }.first(DMSF_MAX_NOTIFICATION_RECEIVERS_INFO).join(', ') + to << ((recipients.count > DMSF_MAX_NOTIFICATION_RECEIVERS_INFO) ? ',...' : '.') + flash[:warning] = l(:warning_email_notifications, to: to) + end end end else # Just rejected - recipients = @dmsf_workflow.participiants - recipients.push revision.dmsf_workflow_assigned_by_user - recipients.uniq! - recipients = recipients & DmsfMailer.get_notify_users(@project, [revision.dmsf_file], true) - DmsfMailer.deliver_workflow_notification( - recipients, - @dmsf_workflow, - revision, - :text_email_subject_rejected, - :text_email_finished_rejected, - :text_email_to_see_history, - action.note) - if Setting.plugin_redmine_dmsf['dmsf_display_notified_recipients'] - unless recipients.blank? - to = recipients.collect{ |r| r.name }.first(DMSF_MAX_NOTIFICATION_RECEIVERS_INFO).join(', ') - to << ((recipients.count > DMSF_MAX_NOTIFICATION_RECEIVERS_INFO) ? ',...' : '.') - flash[:warning] = l(:warning_email_notifications, to: to) + if Setting.notified_events.include?('dmsf_workflow_action') + recipients = @dmsf_workflow.participiants + recipients.push revision.dmsf_workflow_assigned_by_user + recipients.uniq! + recipients = recipients & DmsfMailer.get_notify_users(@project, revision.dmsf_file, true) + DmsfMailer.deliver_workflow_notification( + recipients, + @dmsf_workflow, + revision, + :text_email_subject_rejected, + :text_email_finished_rejected, + :text_email_to_see_history, + action.note) + if Setting.plugin_redmine_dmsf['dmsf_display_notified_recipients'] + unless recipients.blank? + to = recipients.collect{ |r| r.name }.first(DMSF_MAX_NOTIFICATION_RECEIVERS_INFO).join(', ') + to << ((recipients.count > DMSF_MAX_NOTIFICATION_RECEIVERS_INFO) ? ',...' : '.') + flash[:warning] = l(:warning_email_notifications, to: to) + end end end end else if action.action == DmsfWorkflowStepAction::ACTION_DELEGATE # Delegation - delegate = User.active.find_by(id: params[:step_action].to_i / 10) - if DmsfMailer.get_notify_users(@project, [revision.dmsf_file], true).include?(delegate) - DmsfMailer.deliver_workflow_notification( - [delegate], - @dmsf_workflow, - revision, - :text_email_subject_delegated, - :text_email_finished_delegated, - :text_email_to_proceed, - action.note, - action.dmsf_workflow_step_assignment.dmsf_workflow_step) - if Setting.plugin_redmine_dmsf['dmsf_display_notified_recipients'] - flash[:warning] = l(:warning_email_notifications, to: delegate.name) + if Setting.notified_events.include?('dmsf_workflow_action') + delegate = User.active.find_by(id: params[:step_action].to_i / 10) + if DmsfMailer.get_notify_users(@project, revision.dmsf_file, true).include?(delegate) + DmsfMailer.deliver_workflow_notification( + [delegate], + @dmsf_workflow, + revision, + :text_email_subject_delegated, + :text_email_finished_delegated, + :text_email_to_proceed, + action.note, + action.dmsf_workflow_step_assignment.dmsf_workflow_step) + if Setting.plugin_redmine_dmsf['dmsf_display_notified_recipients'] + flash[:warning] = l(:warning_email_notifications, to: delegate.name) + end end end else # Next step assignments = @dmsf_workflow.next_assignments revision.id unless assignments.empty? - if assignments.first.dmsf_workflow_step.step != action.dmsf_workflow_step_assignment.dmsf_workflow_step.step - # Next step - assignments.each do |assignment| - if assignment.user && DmsfMailer.get_notify_users(@project, [revision.dmsf_file], true).include?(assignment.user) + if Setting.notified_events.include?('dmsf_workflow_action') + if assignments.first.dmsf_workflow_step.step != action.dmsf_workflow_step_assignment.dmsf_workflow_step.step + # Next step + assignments.each do |assignment| + if assignment.user && DmsfMailer.get_notify_users(@project, revision.dmsf_file, + true).include?(assignment.user) + DmsfMailer.deliver_workflow_notification( + [assignment.user], + @dmsf_workflow, + revision, + :text_email_subject_requires_approval, + :text_email_finished_step, + :text_email_to_proceed, + nil, + assignment.dmsf_workflow_step) + end + end + to = revision.dmsf_workflow_assigned_by_user + if to && DmsfMailer.get_notify_users(@project, revision.dmsf_file, + true).include?(to) DmsfMailer.deliver_workflow_notification( - [assignment.user], + [to], @dmsf_workflow, revision, - :text_email_subject_requires_approval, - :text_email_finished_step, - :text_email_to_proceed, - nil, - assignment.dmsf_workflow_step) + :text_email_subject_updated, + :text_email_finished_step_short, + :text_email_to_see_status) end - end - to = revision.dmsf_workflow_assigned_by_user - if to && DmsfMailer.get_notify_users(@project, [revision.dmsf_file], true).include?(to) - DmsfMailer.deliver_workflow_notification( - [to], - @dmsf_workflow, - revision, - :text_email_subject_updated, - :text_email_finished_step_short, - :text_email_to_see_status) - end - if Setting.plugin_redmine_dmsf['dmsf_display_notified_recipients'] - recipients = assignments.collect{ |a| a.user } - recipients << to if to - recipients.uniq! - recipients = recipients & DmsfMailer.get_notify_users(@project, [revision.dmsf_file], true) - unless recipients.empty? - to = recipients.collect{ |r| r.name }.first(DMSF_MAX_NOTIFICATION_RECEIVERS_INFO).join(', ') - to << ((recipients.count > DMSF_MAX_NOTIFICATION_RECEIVERS_INFO) ? ',...' : '.') - flash[:warning] = l(:warning_email_notifications, to: to) + if Setting.plugin_redmine_dmsf['dmsf_display_notified_recipients'] + recipients = assignments.collect{ |a| a.user } + recipients << to if to + recipients.uniq! + recipients = recipients & DmsfMailer.get_notify_users(@project, revision.dmsf_file, + true) + unless recipients.empty? + to = recipients.collect{ |r| r.name }.first(DMSF_MAX_NOTIFICATION_RECEIVERS_INFO).join(', ') + to << ((recipients.count > DMSF_MAX_NOTIFICATION_RECEIVERS_INFO) ? ',...' : '.') + flash[:warning] = l(:warning_email_notifications, to: to) + end end end end @@ -411,7 +422,9 @@ class DmsfWorkflowsController < ApplicationController if revision revision.set_workflow(@dmsf_workflow.id, params[:action]) if revision.save - @dmsf_workflow.notify_users(@project, revision, self) + if Setting.notified_events.include?('dmsf_workflow_action') + @dmsf_workflow.notify_users(@project, revision, self) + end flash[:notice] = l(:notice_workflow_started) else flash[:error] = l(:notice_cannot_start_workflow) diff --git a/app/helpers/dmsf_upload_helper.rb b/app/helpers/dmsf_upload_helper.rb index a244e974..74401e75 100644 --- a/app/helpers/dmsf_upload_helper.rb +++ b/app/helpers/dmsf_upload_helper.rb @@ -147,19 +147,17 @@ module DmsfUploadHelper end end # Notifications - if (folder && folder.notification?) || (!folder && project.dmsf_notification?) - begin - recipients = DmsfMailer.deliver_files_updated(project, files) - if Setting.plugin_redmine_dmsf['dmsf_display_notified_recipients'] - unless recipients.empty? - to = recipients.collect{ |r| r.name }.first(DMSF_MAX_NOTIFICATION_RECEIVERS_INFO).join(', ') - to << ((recipients.count > DMSF_MAX_NOTIFICATION_RECEIVERS_INFO) ? ',...' : '.') - controller.flash[:warning] = l(:warning_email_notifications, to: to) if controller - end + begin + recipients = DmsfMailer.deliver_files_updated(project, files) + if Setting.plugin_redmine_dmsf['dmsf_display_notified_recipients'] + unless recipients.empty? + to = recipients.collect{ |r| r.name }.first(DMSF_MAX_NOTIFICATION_RECEIVERS_INFO).join(', ') + to << ((recipients.count > DMSF_MAX_NOTIFICATION_RECEIVERS_INFO) ? ',...' : '.') + controller.flash[:warning] = l(:warning_email_notifications, to: to) if controller end - rescue => e - Rails.logger.error "Could not send email notifications: #{e.message}" end + rescue => e + Rails.logger.error "Could not send email notifications: #{e.message}" end end if failed_uploads.present? && controller diff --git a/app/models/dmsf_file.rb b/app/models/dmsf_file.rb index 3a65a14d..a7c69ec6 100644 --- a/app/models/dmsf_file.rb +++ b/app/models/dmsf_file.rb @@ -73,7 +73,7 @@ class DmsfFile < ActiveRecord::Base url: Proc.new { |o| { controller: 'dmsf_files', action: 'view', id: o } }, datetime: Proc.new { |o| o.updated_at }, author: Proc.new { |o| o.last_revision.user } - + acts_as_watchable acts_as_searchable columns: ["#{table_name}.name", "#{DmsfFileRevision.table_name}.title", "#{DmsfFileRevision.table_name}.description", "#{DmsfFileRevision.table_name}.comment"], project_key: 'project_id', date_column: "#{table_name}.updated_at" @@ -88,6 +88,9 @@ class DmsfFile < ActiveRecord::Base def initialize(*args) @project = nil + if new_record? + self.watcher_user_ids = [] + end super end @@ -212,10 +215,16 @@ class DmsfFile < ActiveRecord::Base end def notify? - return true if notification - return true if dmsf_folder && dmsf_folder.notify? - return true if !dmsf_folder && project.dmsf_notification - false + notification || dmsf_folder&.notify? || (!dmsf_folder && project.dmsf_notification) + end + + def get_all_watchers(watchers) + watchers.concat notified_watchers + if dmsf_folder + watchers.concat dmsf_folder.notified_watchers + else + watchers.concat project.notified_watchers + end end def notify_deactivate diff --git a/app/models/dmsf_folder.rb b/app/models/dmsf_folder.rb index 49efd769..3622a85e 100644 --- a/app/models/dmsf_folder.rb +++ b/app/models/dmsf_folder.rb @@ -78,13 +78,12 @@ class DmsfFolder < ActiveRecord::Base scope :notsystem, -> { where(system: false) } acts_as_customizable - acts_as_searchable columns: ["#{table_name}.title", "#{table_name}.description"], project_key: 'project_id', date_column: 'updated_at', permission: :view_dmsf_files, scope: Proc.new { DmsfFolder.visible } - + acts_as_watchable acts_as_event title: Proc.new { |o| o.title }, description: Proc.new { |o| o.description }, url: Proc.new { |o| { controller: 'dmsf', action: 'show', id: o.project, folder_id: o } }, @@ -122,6 +121,13 @@ class DmsfFolder < ActiveRecord::Base DmsfFolder.permissions?(folder.dmsf_folder, allow_system) end + def initialize(*args) + if new_record? + self.watcher_user_ids = [] + end + super + end + def default_values if Setting.plugin_redmine_dmsf['dmsf_default_notifications'].present? && !system self.notification = true @@ -197,10 +203,16 @@ class DmsfFolder < ActiveRecord::Base end def notify? - return true if notification - return true if dmsf_folder&.notify? - return true if !dmsf_folder && project.dmsf_notification - false + notification || dmsf_folder&.notify? || (!dmsf_folder && project.dmsf_notification) + end + + def get_all_watchers(watchers) + watchers << notified_watchers + if dmsf_folder + watchers << dmsf_folder.notified_watchers + else + watchers << project.notified_watchers + end end def notify_deactivate @@ -577,8 +589,8 @@ class DmsfFolder < ActiveRecord::Base if title =~ /^\./ classes << 'dmsf-system' else + classes << 'hascontextmenu' if (type != 'project') - classes << 'hascontextmenu' classes << 'dmsf-draggable' end if %(project folder).include?(type) diff --git a/app/models/dmsf_mailer.rb b/app/models/dmsf_mailer.rb index bff6eee4..f9273204 100644 --- a/app/models/dmsf_mailer.rb +++ b/app/models/dmsf_mailer.rb @@ -26,8 +26,7 @@ class DmsfMailer < Mailer layout 'mailer' def self.deliver_files_updated(project, files) - users = get_notify_users(project, files) - files = files.select { |file| file.notify? } + users = get_notify_users(project, files.first) users.each do |user| files_updated(user, project, files).deliver_later end @@ -48,8 +47,7 @@ class DmsfMailer < Mailer end def self.deliver_files_deleted(project, files) - users = get_notify_users(project, files) - files = files.select { |file| file.notify? } + users = get_notify_users(project, files.first) users.each do |user| files_deleted(user, project, files).deliver_later end @@ -137,60 +135,46 @@ class DmsfMailer < Mailer end end - def self.get_notify_users(project, files = [], force_notification = false) + # force_notification = true => approval workflow's notifications + def self.get_notify_users(project, file, force_notification = false) return [] unless project.active? - if !force_notification && files.present? - notify_files = files.select { |file| file.notify? } - return [] if notify_files.empty? - end - notify_members = project.members.active.select do |notify_member| - notify_user = notify_member.user - if notify_user == User.current && notify_user.pref.no_self_notified - false - else - if notify_member.dmsf_mail_notification.nil? - case notify_user.mail_notification - when 'all' - true - when 'selected' - notify_member.mail_notification? - when 'only_my_events' - author = false - files.each do |file| - if file.involved?(notify_user) || file.assigned?(notify_user) - author = true - break - end - end - author - when 'only_owner' - owner = false - files.each do |file| - if file.owner?(notify_user) - owner = true - break - end - end - owner - when 'only_assigned' - assignee = false - files.each do |file| - if file.assigned?(notify_user) - assignee = true - break - end - end - assignee - else - false - end + # Notifications + if (force_notification && Setting.notified_events.include?('dmsf_workflow_plural')) || + (Setting.notified_events.include?('dmsf_legacy_notifications') && file&.notify?) + notify_members = project.members.active.select do |notify_member| + notify_user = notify_member.user + if notify_user == User.current && notify_user.pref.no_self_notified + false else - notify_member.dmsf_mail_notification + if notify_member.dmsf_mail_notification.nil? + case notify_user.mail_notification + when 'all' + true + when 'selected' + notify_member.mail_notification? + when 'only_my_events' + file.involved?(notify_user) || file.assigned?(notify_user) + when 'only_owner' + file.owner? notify_user + when 'only_assigned' + file.assigned? notify_user + else + false + end + else + notify_member.dmsf_mail_notification + end end end + users = notify_members.collect { |m| m.user } + else + users = [] end - - notify_members.collect { |m| m.user }.uniq + # Watchers + watchers = [] + file.get_all_watchers(watchers) + users.concat watchers + users.uniq end end diff --git a/app/models/dmsf_workflow.rb b/app/models/dmsf_workflow.rb index aa1d64cc..9ffff5b2 100644 --- a/app/models/dmsf_workflow.rb +++ b/app/models/dmsf_workflow.rb @@ -211,7 +211,7 @@ class DmsfWorkflow < ActiveRecord::Base assignments = next_assignments(revision.id) recipients = assignments.collect{ |a| a.user } recipients.uniq! - recipients = recipients & DmsfMailer.get_notify_users(project, [revision.dmsf_file], true) + recipients = recipients & DmsfMailer.get_notify_users(project, revision.dmsf_file, true) DmsfMailer.deliver_workflow_notification( recipients, self, diff --git a/app/views/dmsf/_main.html.erb b/app/views/dmsf/_main.html.erb index 35f07259..33b78283 100644 --- a/app/views/dmsf/_main.html.erb +++ b/app/views/dmsf/_main.html.erb @@ -42,7 +42,8 @@ project: @project, locked_for_user: @locked_for_user, file_manipulation_allowed: @file_manipulation_allowed, - trash_enabled: @trash_enabled } %> + trash_enabled: @trash_enabled, + notifications: @notifications } %> <% else %> <%= actions_dropdown do %> <%= render partial: 'dmsf_context_menus/main', locals: { @@ -52,7 +53,8 @@ project: @project, locked_for_user: @locked_for_user, file_manipulation_allowed: @file_manipulation_allowed, - trash_enabled: @trash_enabled } %> + trash_enabled: @trash_enabled, + notifications: @notifications} %> <% end %> <% end %> @@ -91,6 +93,24 @@ <% content_for :sidebar do %> <%= render partial: 'dmsf/sidebar' %> + + <% project_or_folder = @folder? @folder : @project %> + <% if project_or_folder&.watchers.present? %> +
+ <% if @folder %> + <%= render partial: 'watchers/watchers', locals: { watched: @folder } %> + <% else %> + <% if User.current.allowed_to?(:add_project_watchers, @project) %> +
+ <%= link_to l(:button_add), new_watchers_path(object_type: :project, object_id: @project.id), remote: true, + method: 'get' %> +
+ <% end %> +

<%= l(:label_project_watchers) %> (<%= @project.watcher_users.size %>)

+ <%= watchers_list @project %> + <% end %> +
+ <% end %> <% end %> <% if Redmine::Plugin.installed?(:easy_extensions) %> diff --git a/app/views/dmsf/_query_list.html.erb b/app/views/dmsf/_query_list.html.erb index ac0d72b0..4eacedc9 100644 --- a/app/views/dmsf/_query_list.html.erb +++ b/app/views/dmsf/_query_list.html.erb @@ -27,7 +27,7 @@ <%= hidden_field_tag 'back_url', url_for(params: request.query_parameters), id: nil %> <%= query_columns_hidden_tags(query) %>
- +
<% if defined?(EasyExtensions) %> diff --git a/app/views/dmsf/_query_rows.erb b/app/views/dmsf/_query_rows.erb index 094b63c4..8bc58aca 100644 --- a/app/views/dmsf/_query_rows.erb +++ b/app/views/dmsf/_query_rows.erb @@ -38,13 +38,13 @@ <% @idnt ||= 0 %> "> <% query.inline_columns.each do |column| %> <%= content_tag 'td', column_content(column, node), class: column.css_classes %> <% end %>
- <%= check_box_tag('ids[]', "#{node.type}-#{node.id}", false, id: nil) unless (system || (node.type == 'project')) %> + <%= check_box_tag('ids[]', "#{node.type}-#{node.id}", false, id: nil) unless system %> - <% unless (system || (node.type == 'project')) %> + <% unless system %> <% if defined?(EasyExtensions) %> <%= link_to '', '#', title: l(:button_actions), class: 'icon-only icon-actions js-contextmenu icon-more-horiz' %> <% else %> diff --git a/app/views/dmsf/edit.html.erb b/app/views/dmsf/edit.html.erb index 34796a47..2ae10ebd 100644 --- a/app/views/dmsf/edit.html.erb +++ b/app/views/dmsf/edit.html.erb @@ -46,6 +46,7 @@ edit: true, unlockable: @folder.unlockable? && (!@folder.locked_for_user? || User.current.allowed_to?(:force_file_unlock, @project)), email_allowed: User.current.allowed_to?(:email_documents, @project), + notifications: @notifications, back_url: edit_dmsf_url(id: @project, folder_id: @folder) } %> <% else %> @@ -60,6 +61,7 @@ edit: true, unlockable: @folder.unlockable? && (!@folder.locked_for_user? || User.current.allowed_to?(:force_file_unlock, @project)), email_allowed: User.current.allowed_to?(:email_documents, @project), + notifications: @notifications, back_url: edit_dmsf_url(id: @project, folder_id: @folder) } %> <% end %> diff --git a/app/views/dmsf/edit_root.html.erb b/app/views/dmsf/edit_root.html.erb index 9ef5f72f..c6cd495c 100644 --- a/app/views/dmsf/edit_root.html.erb +++ b/app/views/dmsf/edit_root.html.erb @@ -25,7 +25,7 @@ <% html_title(l(:dmsf)) %>
- <% if User.current.allowed_to?(:folder_manipulation, @project) %> + <% if @notifications && User.current.allowed_to?(:folder_manipulation, @project) %> <% if @project.dmsf_notification %> <%= link_to l(:label_notifications_off), notify_deactivate_dmsf_path(id: @project, back_url: edit_root_dmsf_path(id: @project)), diff --git a/app/views/dmsf_context_menus/_file.html.erb b/app/views/dmsf_context_menus/_file.html.erb index 9cc02f58..46e55a86 100644 --- a/app/views/dmsf_context_menus/_file.html.erb +++ b/app/views/dmsf_context_menus/_file.html.erb @@ -46,15 +46,17 @@ class: 'icon icon-lock', disabled: !allowed %> <% end %> -
  • - <% if dmsf_file.notification %> - <%= context_menu_link l(:label_notifications_off), notify_deactivate_dmsf_files_path(id: dmsf_file, - back_url: back_url), class: 'icon icon-email', disabled: !allowed || locked %> - <% else %> - <%= context_menu_link l(:label_notifications_on), notify_activate_dmsf_files_path(id: dmsf_file, - back_url: back_url), class: 'icon icon-email-add', disabled: !allowed || locked %> - <% end %> -
  • +<% if notifications %> +
  • + <% if dmsf_file.notification %> + <%= context_menu_link l(:label_notifications_off), notify_deactivate_dmsf_files_path(id: dmsf_file, + back_url: back_url), class: 'icon icon-email', disabled: !allowed || locked %> + <% else %> + <%= context_menu_link l(:label_notifications_on), notify_activate_dmsf_files_path(id: dmsf_file, + back_url: back_url), class: 'icon icon-email-add', disabled: !allowed || locked %> + <% end %> +
  • +<% end %>
  • <%= render partial: 'approval_workflow', locals: { dmsf_file: dmsf_file, project: project, locked: locked, back_url: back_url } %> @@ -82,6 +84,9 @@ (Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] != 'WEBDAV_READ_WRITE') %>
  • <% end %> +
  • + <%= render partial: 'dmsf_context_menus/watch', locals: { object: dmsf_file } %> +
  • <%= context_menu_link l(:button_delete), dmsf_link ? dmsf_link_path(id: dmsf_link, folder_id: folder, back_url: back_url) : dmsf_file_path(id: dmsf_file, diff --git a/app/views/dmsf_context_menus/_folder.html.erb b/app/views/dmsf_context_menus/_folder.html.erb index 29af3882..43873cbc 100644 --- a/app/views/dmsf_context_menus/_folder.html.erb +++ b/app/views/dmsf_context_menus/_folder.html.erb @@ -49,17 +49,19 @@ <% end %>
  • <% end %> -
  • - <% if dmsf_folder.notification %> - <%= context_menu_link l(:label_notifications_off), notify_deactivate_dmsf_path(id: dmsf_folder.project, - folder_id: dmsf_folder, back_url: back_url), class: 'icon icon-email', - disabled: !allowed || locked || !dmsf_folder.notification? %> - <% else %> - <%= context_menu_link l(:label_notifications_on), notify_activate_dmsf_path(id: dmsf_folder.project, - folder_id: dmsf_folder, back_url: back_url), class: 'icon icon-email-add', - disabled: !allowed || locked || dmsf_folder.notification? %> - <% end %> -
  • +<% if notifications %> +
  • + <% if dmsf_folder.notification %> + <%= context_menu_link l(:label_notifications_off), notify_deactivate_dmsf_path(id: dmsf_folder.project, + folder_id: dmsf_folder, back_url: back_url), class: 'icon icon-email', + disabled: !allowed || locked || !dmsf_folder.notification? %> + <% else %> + <%= context_menu_link l(:label_notifications_on), notify_activate_dmsf_path(id: dmsf_folder.project, + folder_id: dmsf_folder, back_url: back_url), class: 'icon icon-email-add', + disabled: !allowed || locked || dmsf_folder.notification? %> + <% end %> +
  • +<% end %> <% unless edit %>
  • <%= context_menu_link l(:button_download), entries_operations_dmsf_path(id: project, folder_id: folder, @@ -72,6 +74,9 @@ disabled: !email_allowed %>
  • <% end %> +
  • + <%= render partial: 'dmsf_context_menus/watch', locals: { object: dmsf_folder } %> +
  • <%= context_menu_link l(:button_delete), dmsf_link ? dmsf_link_path(id: dmsf_link, folder_id: folder, back_url: back_url) : diff --git a/app/views/dmsf_context_menus/_main.html.erb b/app/views/dmsf_context_menus/_main.html.erb index 89b81000..376ee294 100644 --- a/app/views/dmsf_context_menus/_main.html.erb +++ b/app/views/dmsf_context_menus/_main.html.erb @@ -42,16 +42,18 @@ title: l(:title_lock_folder), class: 'icon icon-lock') %> <% end %> <% end %> - <% if !locked_for_user && ((folder && folder.notification) || (!folder && project.dmsf_notification)) %> - <%= link_to l(:label_notifications_off), - notify_deactivate_dmsf_path(id: project, folder_id: folder), - title: l(:title_notifications_active_deactivate), - class: 'icon icon-email' %> - <% else %> - <%= link_to l(:label_notifications_on), - notify_activate_dmsf_path(id: project, folder_id: folder), - title: l(:title_notifications_not_active_activate), - class: 'icon icon-email-add' %> + <% if notifications %> + <% if !locked_for_user && ((folder && folder.notification) || (!folder && project.dmsf_notification)) %> + <%= link_to l(:label_notifications_off), + notify_deactivate_dmsf_path(id: project, folder_id: folder), + title: l(:title_notifications_active_deactivate), + class: 'icon icon-email' %> + <% else %> + <%= link_to l(:label_notifications_on), + notify_activate_dmsf_path(id: project, folder_id: folder), + title: l(:title_notifications_not_active_activate), + class: 'icon icon-email-add' %> + <% end %> <% end %> <% if file_manipulation_allowed && !locked_for_user %> <%= link_to l(:label_link_from), @@ -60,10 +62,11 @@ class: 'icon dmsf-icon-link' %> <% end %> <% end %> +<%= render partial: 'dmsf_context_menus/watch', locals: { object: folder ? folder : project } %> <% if trash_enabled %> <%= link_to l(:link_trash_bin), trash_dmsf_path(project), title: l(:link_trash_bin), class: 'icon icon-del' %> <% else %> - <%= l(:link_trash_bin) %> - + <%= l(:link_trash_bin) %> + <% end %> diff --git a/app/views/dmsf_context_menus/_project.html.erb b/app/views/dmsf_context_menus/_project.html.erb new file mode 100644 index 00000000..98e10f09 --- /dev/null +++ b/app/views/dmsf_context_menus/_project.html.erb @@ -0,0 +1,25 @@ +<% + # encoding: utf-8 + # + # Redmine plugin for Document Management System "Features" + # + # Copyright © 2011-22 Karel Pičman + # + # This program is free software; you can redistribute it and/or + # modify it under the terms of the GNU General Public License + # as published by the Free Software Foundation; either version 2 + # of the License, or (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program; if not, write to the Free Software + # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +%> + +
  • + <%= render partial: 'dmsf_context_menus/watch', locals: { object: dmsf_project } %> +
  • diff --git a/app/views/dmsf_context_menus/_revisions.html.erb b/app/views/dmsf_context_menus/_revisions.html.erb index 59a9729a..e14043d4 100644 --- a/app/views/dmsf_context_menus/_revisions.html.erb +++ b/app/views/dmsf_context_menus/_revisions.html.erb @@ -20,16 +20,18 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. %> -<% if file.notification %> - <%= link_to l(:label_notifications_off), - notify_deactivate_dmsf_files_path(id: file, back_url: back_url), - title: l(:title_notifications_active_deactivate), - class: 'icon icon-email' %> -<% else %> - <%= link_to l(:label_notifications_on), - notify_activate_dmsf_files_path(id: file, back_url: back_url), - title: l(:title_notifications_not_active_activate), - class: 'icon icon-email-add' %> +<% if notifications %> + <% if file.notification %> + <%= link_to l(:label_notifications_off), + notify_deactivate_dmsf_files_path(id: file, back_url: back_url), + title: l(:title_notifications_active_deactivate), + class: 'icon icon-email' %> + <% else %> + <%= link_to l(:label_notifications_on), + notify_activate_dmsf_files_path(id: file, back_url: back_url), + title: l(:title_notifications_not_active_activate), + class: 'icon icon-email-add' %> + <% end %> <% end %> <%= link_to l(:label_link_to), new_dmsf_link_path(project_id: project.id, dmsf_folder_id: file.dmsf_folder ? file.dmsf_folder.id : nil, @@ -39,5 +41,6 @@ <%= link_to "#{l(:button_copy)}/#{l(:button_move)}", copy_file_path(id: file, back_url: back_url), title: l(:title_copy), class: 'icon icon-copy' %> <%= link_to l(:button_download), view_dmsf_file_path(file, disposition: 'attachment'), class: 'icon icon-download' %> +<%= render partial: 'dmsf_context_menus/watch', locals: { object: file } %> <%= delete_link(dmsf_file_path(id: file, details: true), back_url: dmsf_folder_path(id: file.project, folder_id: file.dmsf_folder)) if file_delete_allowed %> diff --git a/app/views/dmsf_context_menus/_watch.html.erb b/app/views/dmsf_context_menus/_watch.html.erb new file mode 100644 index 00000000..b91b246c --- /dev/null +++ b/app/views/dmsf_context_menus/_watch.html.erb @@ -0,0 +1,30 @@ +<% + # encoding: utf-8 + # + # Redmine plugin for Document Management System "Features" + # + # Copyright © 2011-22 Karel Pičman + # + # This program is free software; you can redistribute it and/or + # modify it under the terms of the GNU General Public License + # as published by the Free Software Foundation; either version 2 + # of the License, or (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program; if not, write to the Free Software + # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + # + # Watch/unwatch menu's item +%> + +<% watched = Watcher.any_watched?([object], User.current) %> +<% css = [watcher_css([object]), watched ? 'icon icon-fav' : 'icon icon-fav-off'].join(' ') %> +<% text = watched ? l(:button_unwatch) : l(:button_watch) %> +<% url = watch_path(object_type: object.class.to_s.underscore, object_id: object.id) %> +<% method = watched ? 'delete' : 'post' %> +<%= context_menu_link text, url, method: method, class: css, disabled: !User.current.logged? %> diff --git a/app/views/dmsf_context_menus/dmsf.html.erb b/app/views/dmsf_context_menus/dmsf.html.erb index b1e92f3d..dff79742 100644 --- a/app/views/dmsf_context_menus/dmsf.html.erb +++ b/app/views/dmsf_context_menus/dmsf.html.erb @@ -24,14 +24,17 @@ <% if @dmsf_file %> <%= render partial: 'file', locals: { project: @project, folder: @folder, dmsf_file: @dmsf_file, dmsf_link: @dmsf_link, locked: @locked, unlockable: @unlockable, - allowed: @allowed, email_allowed: @email_allowed, back_url: @back_url } %> + allowed: @allowed, email_allowed: @email_allowed, + notifications: @notifications, back_url: @back_url } %> <% elsif @dmsf_folder %> <%= render partial: 'folder', locals: { project: @project, folder: @folder, dmsf_folder: @dmsf_folder, dmsf_link: @dmsf_link, locked: @locked, unlockable: @unlockable, allowed: @allowed, email_allowed: @email_allowed, edit: false, - back_url: @back_url } %> + notifications: @notifications, back_url: @back_url } %> <% elsif @dmsf_link %> <%= render partial: 'url', locals: { dmsf_link: @dmsf_link, allowed: @allowed, back_url: @back_url } %> + <% elsif @dmsf_project %> + <%= render partial: 'project', locals: { dmsf_project: @dmsf_project, allowed: @allowed, back_url: @back_url } %> <% else %> <%= render partial: 'multiple', locals: { project: @project, folder: @folder, allowed: @allowed, email_allowed: @email_allowed, back_url: @back_url } %> diff --git a/app/views/dmsf_files/show.html.erb b/app/views/dmsf_files/show.html.erb index 9fd7442f..c6609b00 100644 --- a/app/views/dmsf_files/show.html.erb +++ b/app/views/dmsf_files/show.html.erb @@ -44,12 +44,12 @@ <% if defined?(EasyExtensions) %> <%= render partial: 'dmsf_context_menus/revisions', locals: { project: @project, file: @file, file_delete_allowed: @file_delete_allowed, - back_url: dmsf_file_path(id: @file)} %> + notifications: @notifications, back_url: dmsf_file_path(id: @file)} %> <% else %> <%= actions_dropdown do %> <%= render partial: 'dmsf_context_menus/revisions', locals: { project: @project, file: @file, file_delete_allowed: @file_delete_allowed, - back_url: dmsf_file_path(id: @file) } %> + notifications: @notifications, back_url: dmsf_file_path(id: @file) } %> <% end %> <% end %> <% end %> @@ -171,6 +171,14 @@ <% end %> <%= pagination_links_full @revision_pages, @revision_count %> +<% if @file.watchers.present? %> + <% content_for :sidebar do %> +
    + <%= render partial: 'watchers/watchers', locals: { watched: @file } %> +
    + <% end %> +<% end %> + <%= late_javascript_tag do %> $('a.delete-revision').click(function(event) { if(!window.confirm('<%= l(:text_are_you_sure) %>')) { diff --git a/app/views/dmsf_state/_user_pref.html.erb b/app/views/dmsf_state/_user_pref.html.erb index 51ad1133..41f41a1a 100644 --- a/app/views/dmsf_state/_user_pref.html.erb +++ b/app/views/dmsf_state/_user_pref.html.erb @@ -23,13 +23,15 @@ <% if member %>
    <%= l(:link_user_preferences) %> -

    - <%= content_tag :label, l(:label_notifications) %> - <%= select_tag 'email_notify', - options_for_select([[l(:select_option_default), nil], - [l(:select_option_activated), true], [l(:select_option_deactivated), false]], - selected: member.dmsf_mail_notification) %> -

    + <% if Setting.notified_events.include?('dmsf_legacy_notifications') %> +

    + <%= content_tag :label, l(:label_notifications) %> + <%= select_tag 'email_notify', + options_for_select([[l(:select_option_default), nil], + [l(:select_option_activated), true], [l(:select_option_deactivated), false]], + selected: member.dmsf_mail_notification) %> +

    + <% end %>

    <%= content_tag :label, l(:label_title_format) %> <%= text_field_tag 'title_format', member.dmsf_title_format, size: 10 %> diff --git a/app/views/my/blocks/_locked_documents.html.erb b/app/views/my/blocks/_locked_documents.html.erb index c396d7a5..c1a8982a 100644 --- a/app/views/my/blocks/_locked_documents.html.erb +++ b/app/views/my/blocks/_locked_documents.html.erb @@ -20,72 +20,84 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. %> -<% folders = [] %> -<% files = [] %> <% folders = DmsfFolder.visible.joins( 'JOIN dmsf_locks ON dmsf_folders.id = dmsf_locks.entity_id').where( ['dmsf_locks.entity_type = ? AND dmsf_locks.user_id = ? AND (dmsf_locks.expires_at IS NULL OR dmsf_locks.expires_at > ?)', - 1, @user.id, Time.current]).all if @user %> + 1, @user&.id, Time.current]) %> <% files = DmsfFile.visible.joins( 'JOIN dmsf_locks ON dmsf_files.id = dmsf_locks.entity_id').where( ['dmsf_locks.entity_type = ? AND dmsf_locks.user_id = ? AND (dmsf_locks.expires_at IS NULL OR dmsf_locks.expires_at > ?)', - 0, @user.id, Time.current]).all if @user %> -<% unless defined?(EasyExtensions) %> -

    <%= l(:locked_documents)%> (<%= folders.count %>/<%= files.count %>)

    -<% end %> + 0, @user&.id, Time.current]) %> +

    <%= l(:locked_documents)%> (<%= folders.all.size %>/<%= files.all.size %>)

    <% if folders.any? || files.any?%> - <%= form_tag({}) do %> - + <%= form_tag({}, data: { cm_url: dmsf_context_menu_path(back_url: my_page_path) }) do %> +
    + + <% folders.each do |folder| %> - + + + <% end %> <% files.each do |file| %> - + + + <% end %>
    + <%= check_box_tag 'check_all', '', false, class: 'toggle-selection', + title: "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %> + <%= l(:field_project) %> <%= l(:label_document) %>/<%= l(:field_folder) %> <%= l(:field_folder) %>
    + <%= check_box_tag 'ids[]', "folder-#{folder.id}", false, id: nil %> + - <%= link_to_project(folder.project) %> + <%= link_to_project folder.project %> - <%= link_to h(folder.title), { controller: 'dmsf', action: 'show', id: folder.project, folder_id: folder}, + <%= link_to h(folder.title), dmsf_folder_path(id: folder.project, folder_id: folder), class: 'icon icon-folder' %> <% if folder.dmsf_folder %> <%= link_to h(folder.dmsf_folder.title), - { controller: 'dmsf', action: 'show', id: folder.project, folder_id: folder.dmsf_folder } %> + dmsf_folder_path(id: folder.project, folder_id: folder.dmsf_folder) %> <% else %> - <%= link_to l(:link_documents), { controller: 'dmsf', action: 'show', id: folder.project } %> + <%= link_to l(:link_documents), dmsf_folder_path(id: folder.project) %> <% end %> + <%= link_to_context_menu %> +
    + <%= check_box_tag 'ids[]', "file-#{file.id}", false, id: nil %> + - <%= link_to_project(file.project) if file.project %> + <%= link_to_project file.project %> - <%= link_to h(file.title), { controller: 'dmsf_files', action: :show, id: file }, + <%= link_to h(file.title), dmsf_file_path(id: file), class: "icon icon-file #{DmsfHelper.filetype_css(file.name)}" %> <% if file.dmsf_folder %> - <%= link_to h(file.dmsf_folder.title), - { controller: 'dmsf', action: 'show', id: file.project, folder_id: file.dmsf_folder } %> + <%= link_to h(file.dmsf_folder.title), dmsf_folder_path(id: file.project, folder_id: file.dmsf_folder) %> <% else %> - <%= link_to_if file.project, l(:link_documents), - { controller: 'dmsf', action: 'show', id: file.project } %> + <%= link_to_if file.project, l(:link_documents), dmsf_folder_path(id: file.project) %> <% end %> + <%= link_to_context_menu %> +
    <% end %> + <%= context_menu %> <% else %>

    <%= l(:label_no_data) %>

    <% end %> diff --git a/app/views/my/blocks/_open_approvals.html.erb b/app/views/my/blocks/_open_approvals.html.erb index 2a37e573..de20aa2a 100644 --- a/app/views/my/blocks/_open_approvals.html.erb +++ b/app/views/my/blocks/_open_approvals.html.erb @@ -20,28 +20,27 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. %> -<% assignments = Array.new %> -<% if @user %> - <% all_assignments = DmsfWorkflowStepAssignment. +<% all_assignments = DmsfWorkflowStepAssignment. left_outer_joins(:dmsf_workflow_step_actions). joins(:dmsf_workflow_step). joins(:dmsf_file_revision). where(dmsf_file_revisions: { deleted: DmsfFileRevision::STATUS_ACTIVE, workflow: DmsfWorkflow::STATE_WAITING_FOR_APPROVAL }). - where(dmsf_workflow_step_assignments: { user_id: @user.id }). + where(dmsf_workflow_step_assignments: { user_id: @user&.id }). where(['dmsf_workflow_step_actions.id IS NULL OR dmsf_workflow_step_actions.action = ?', - DmsfWorkflowStepAction::ACTION_DELEGATE]). + DmsfWorkflowStepAction::ACTION_DELEGATE]). order('dmsf_workflow_step_assignments.dmsf_file_revision_id, dmsf_workflow_steps.step').to_a %> - <% assignments = all_assignments.delete_if { |a| (a.dmsf_file_revision != a.dmsf_file_revision.dmsf_file.last_revision) } %> - <% assignments.uniq! { |a| a.dmsf_file_revision } %> -<% end %> -<% unless defined?(EasyExtensions) %> -

    <%= l(:open_approvals)%> (<%= assignments.size %>)

    -<% end %> +<% assignments = all_assignments.delete_if { |a| (a.dmsf_file_revision != a.dmsf_file_revision.dmsf_file.last_revision) } %> +<% assignments.uniq! { |a| a.dmsf_file_revision } %> +

    <%= l(:open_approvals)%> (<%= assignments.size %>)

    <% if assignments.any? %> - <%= form_tag do %> + <%= form_tag({}, data: { cm_url: dmsf_context_menu_path(back_url: my_page_path) }) do %> + @@ -52,16 +51,19 @@ <% assignments.each do |assignment| %> - + + - <% end %>
    + <%= check_box_tag 'check_all', '', false, class: 'toggle-selection', + title: "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %> + <%= l(:field_project) %> <%= l(:field_label_dmsf_workflow) %> <%= l(:field_status) %>
    + <%= check_box_tag 'ids[]', "file-#{assignment.dmsf_file_revision.dmsf_file.id}", false, id: nil %> + <% if assignment.dmsf_file_revision.dmsf_file.project %> - <%= link_to_project(assignment.dmsf_file_revision.dmsf_file.project) %> + <%= link_to_project assignment.dmsf_file_revision.dmsf_file.project %> <% end %> <% if assignment.dmsf_workflow_step && assignment.dmsf_workflow_step.dmsf_workflow %> - <%= link_to(h(assignment.dmsf_workflow_step.dmsf_workflow.name), - edit_dmsf_workflow_path(assignment.dmsf_workflow_step.dmsf_workflow)) %> + <%= link_to h(assignment.dmsf_workflow_step.dmsf_workflow.name), + edit_dmsf_workflow_path(assignment.dmsf_workflow_step.dmsf_workflow) %> <% end %> @@ -80,36 +82,29 @@ <% if assignment.dmsf_file_revision && assignment.dmsf_file_revision.dmsf_file %> <%= link_to h(assignment.dmsf_file_revision.title), - { controller: 'dmsf_files', action: :show, id: assignment.dmsf_file_revision.dmsf_file } %> + dmsf_file_path(id: assignment.dmsf_file_revision.dmsf_file) %> <% end %> <% if assignment.dmsf_file_revision %> <% if assignment.dmsf_file_revision.dmsf_file.dmsf_folder %> <%= link_to h(assignment.dmsf_file_revision.dmsf_file.dmsf_folder.title), - { controller: 'dmsf', action: 'show', id: assignment.dmsf_file_revision.dmsf_file.project, - folder_id: assignment.dmsf_file_revision.dmsf_file.dmsf_folder} %> + dmsf_folder_path(id: assignment.dmsf_file_revision.dmsf_file.project, + folder_id: assignment.dmsf_file_revision.dmsf_file.dmsf_folder) %> <% elsif assignment.dmsf_file_revision.dmsf_file.project %> - <%= link_to l(:link_documents), - { controller: 'dmsf', action: 'show', id: assignment.dmsf_file_revision.dmsf_file.project } %> + <%= link_to l(:link_documents), dmsf_folder_path(id: assignment.dmsf_file_revision.dmsf_file.project) %> <% end %> <% end %> - <%= render partial: 'dmsf_workflows/approval_workflow_button', - locals: { file: assignment.dmsf_file_revision.dmsf_file, - file_approval_allowed: User.current.allowed_to?(:file_approval, - assignment.dmsf_file_revision.dmsf_file.project), - workflows_available: nil, - project: assignment.dmsf_file_revision.dmsf_file.project, - wf: assignment.dmsf_workflow_step.dmsf_workflow, dmsf_link_id: nil, - back_url: my_page_path } %> + + <%= link_to_context_menu %>
    <% end %> + <%= context_menu %> <% else %>

    <%= l(:label_no_data) %>

    <% end %> diff --git a/app/views/my/blocks/_watched_documents.html.erb b/app/views/my/blocks/_watched_documents.html.erb new file mode 100644 index 00000000..c65b28fe --- /dev/null +++ b/app/views/my/blocks/_watched_documents.html.erb @@ -0,0 +1,118 @@ +<% +# encoding: utf-8 +# +# Redmine plugin for Document Management System "Features" +# +# Copyright © 2011-22 Karel Pičman +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +%> + +<% projects = Project.visible.has_module(:dmsf).joins(:watchers).where( + :watchers => { watchable_type: 'Project', user_id: @user&.id }) %> +<% folders = DmsfFolder.visible(:dmsf).joins(:watchers).where( + :watchers => { watchable_type: 'DmsfFolder', user_id: @user&.id }) %> +<% files = DmsfFile.visible.joins(:watchers).where( + :watchers => { watchable_type: 'DmsfFile', user_id: @user&.id }) %> +

    <%= l(:label_dmsf_watched)%> (<%= projects.all.size + folders.all.size %>/<%= files.all.size %>)

    +<% if projects.any? || folders.any? || files.any? %> + <%= form_tag({}, data: { cm_url: dmsf_context_menu_path(back_url: my_page_path) }) do %> + + + + + + + + + + + + <% projects.each do |project| %> + + + + + + + + <% end %> + <% folders.each do |folder| %> + + + + + + + + <% end %> + <% files.each do |file| %> + + + + + + + + <% end %> + +
    + <%= check_box_tag 'check_all', '', false, class: 'toggle-selection', + title: "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %> + <%= l(:field_project) %><%= l(:label_document) %>/<%= l(:field_folder) %><%= l(:field_folder) %>
    + <%= check_box_tag 'ids[]', "project-#{project.id}", false, id: nil %> + + <%= link_to_project project %> + + <%= link_to_project project, jump: 'dmsf', class: 'project' %> + + <%= link_to_context_menu %> +
    + <%= check_box_tag 'ids[]', "folder-#{folder.id}", false, id: nil %> + + <%= link_to_project folder.project %> + + <%= link_to h(folder.title), dmsf_folder_path(id: folder.project, folder_id: folder), + class: 'icon icon-folder' %> + + <% if folder.dmsf_folder %> + <%= link_to h(folder.dmsf_folder.title), dmsf_folder_path(id: folder.project, folder_id: + folder.dmsf_folder) %> + <% else %> + <%= link_to l(:link_documents), dmsf_folder_path(id: folder.project) %> + <% end %> + + <%= link_to_context_menu %> +
    + <%= check_box_tag 'ids[]', "file-#{file.id}", false, id: nil %> + + <%= link_to_project(file.project) if file.project %> + + <%= link_to h(file.title), dmsf_file_path(id: file), + class: "icon icon-file #{DmsfHelper.filetype_css(file.name)}" %> + + <% if file.dmsf_folder %> + <%= link_to h(file.dmsf_folder.title), dmsf_folder_path(id: file.project, folder_id: file.dmsf_folder) %> + <% else %> + <%= link_to l(:link_documents), dmsf_folder_path(id: file.project) %> + <% end %> + + <%= link_to_context_menu %> +
    + <% end %> + <%= context_menu %> +<% else %> +

    <%= l(:label_no_data) %>

    +<% end %> diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 0abea358..d80414cb 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -425,6 +425,21 @@ cs: title_start_minor: Zahájení není dovoleno, podružná verze musí být nula title_approval_minor: Schválení není dovoleno, podružná verze musí být nula + label_project_watchers: Sledující uživatelé + label_dmsf_folder_watchers: Sledující uživatelé + label_dmsf_file_watchers: Sledující uživatelé + label_dmsf_watched: Sledované dokumenty + dmsf_legacy_notifications: Původní DMS notifikace + permission_view_dmsf_folder_watchers: Zobrazit sledující složky + permission_add_dmsf_folder_watchers: Přidat sledujícího složky + permission_delete_dmsf_folder_watchers: Smazat sledující složky + permission_view_dmsf_file_watchers: Zobrazit sledující dokumentu + permission_add_dmsf_file_watchers: Přidat sledujícího dokumentu + permission_delete_dmsf_file_watchers: Smazat sledující dokumentu + permission_view_project_watchers: Zobrazit sledující projektu + permission_add_project_watchers: Přidat sledujícího projektu + permission_delete_project_watchers: Smazat sledující projektu + easy_pages: modules: dmsf_locked_documents: My locked documents diff --git a/config/locales/de.yml b/config/locales/de.yml index 2796578f..953c9b9e 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -421,6 +421,21 @@ de: title_start_minor: Start nicht erlaubt, Unterversion muss Null lauten title_approval_minor: Genehmigung nicht erlaubt, Unterversion muss Null lauten + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: Von mir gesperrte Dokumente diff --git a/config/locales/en.yml b/config/locales/en.yml index ae85d74f..976e0bef 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -425,6 +425,21 @@ en: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: My locked documents diff --git a/config/locales/es.yml b/config/locales/es.yml index 3bc59bf7..5db31a20 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -425,6 +425,21 @@ es: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: My locked documents diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 39bdf8ac..2bdb22d5 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -425,6 +425,21 @@ fr: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: My locked documents diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 163f3d1d..9b6bb6e6 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -424,6 +424,21 @@ hu: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: My locked documents diff --git a/config/locales/it.yml b/config/locales/it.yml index 416e2521..e00290cf 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -425,6 +425,21 @@ it: # Italian strings thx 2 Matteo Arceci! title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: My locked documents diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 0e9fcf13..c08d418e 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -426,6 +426,21 @@ ja: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: 自分がロック中の文書 diff --git a/config/locales/ko.yml b/config/locales/ko.yml index a04a17c0..5ca274ff 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -425,6 +425,21 @@ ko: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: 내 잠긴 파일 diff --git a/config/locales/nl.yml b/config/locales/nl.yml index d08d18d3..a418cc3e 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -425,6 +425,21 @@ nl: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: My locked documents diff --git a/config/locales/pl.yml b/config/locales/pl.yml index d168def0..0cd212ce 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -425,6 +425,21 @@ pl: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: My locked documents diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 33e6e9ec..8cebada6 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -425,6 +425,21 @@ pt-BR: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: My locked documents diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 8c178241..d923dcec 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -425,6 +425,21 @@ ru: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: Мои заблокированные документы diff --git a/config/locales/sl.yml b/config/locales/sl.yml index d479e44a..044401e8 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -425,6 +425,21 @@ sl: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: My locked documents diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index b3cacf94..17e25207 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -424,6 +424,21 @@ zh-TW: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: My locked documents diff --git a/config/locales/zh.yml b/config/locales/zh.yml index ed6d7c25..4597b03a 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -425,6 +425,21 @@ zh: title_start_minor: Start not allowed, minor must be zero title_approval_minor: Approval not allowed, minor must be zero + label_project_watchers: Watchers + label_dmsf_folder_watchers: Watchers + label_dmsf_file_watchers: Watchers + label_dmsf_watched: Watched documents + dmsf_legacy_notifications: Legacy DMS notifications + permission_view_dmsf_folder_watchers: View folder's watchers + permission_add_dmsf_folder_watchers: Add folder's watchers + permission_delete_dmsf_folder_watchers: Delete folder's watchers + permission_view_dmsf_file_watchers: View document's watchers + permission_add_dmsf_file_watchers: Add document's watchers + permission_delete_dmsf_file_watchers: Delete document's watchers + permission_view_project_watchers: View project's watchers + permission_add_project_watchers: Add project's watchers + permission_delete_project_watchers: Delete project's watchers + easy_pages: modules: dmsf_locked_documents: My locked documents diff --git a/lib/redmine_dmsf.rb b/lib/redmine_dmsf.rb index bbf67cc1..821e5de9 100644 --- a/lib/redmine_dmsf.rb +++ b/lib/redmine_dmsf.rb @@ -40,6 +40,7 @@ require 'redmine_dmsf/patches/user_patch' require 'redmine_dmsf/patches/issue_patch' require 'redmine_dmsf/patches/role_patch' require 'redmine_dmsf/patches/queries_controller_patch' +require 'redmine_dmsf/patches/notifiable_patch' if defined?(EasyExtensions) require 'redmine_dmsf/patches/easy_crm_case_patch' diff --git a/lib/redmine_dmsf/patches/notifiable_patch.rb b/lib/redmine_dmsf/patches/notifiable_patch.rb new file mode 100644 index 00000000..2e3d69cb --- /dev/null +++ b/lib/redmine_dmsf/patches/notifiable_patch.rb @@ -0,0 +1,53 @@ +# encoding: utf-8 +# frozen_string_literal: true +# +# Redmine plugin for Document Management System "Features" +# +# Copyright © 2011-22 Karel Pičman +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +module RedmineDmsf + module Patches + module NotifiablePatch + + def self.prepended(base) + + class << base + prepend ClassMethods + end + + end + + module ClassMethods + + ################################################################################################################ + # Overriden methods + # + def all + notifications = super + notifications << Redmine::Notifiable.new('dmsf_workflow_plural') + notifications << Redmine::Notifiable.new('dmsf_legacy_notifications') + notifications + end + + end + + end + end +end + +RedmineExtensions::PatchManager.register_patch_to_be_first 'Redmine::Notifiable', + 'RedmineDmsf::Patches::NotifiablePatch', prepend: true, first: true \ No newline at end of file diff --git a/lib/redmine_dmsf/patches/project_patch.rb b/lib/redmine_dmsf/patches/project_patch.rb index cb1a7101..f757f2aa 100644 --- a/lib/redmine_dmsf/patches/project_patch.rb +++ b/lib/redmine_dmsf/patches/project_patch.rb @@ -29,6 +29,11 @@ module RedmineDmsf ################################################################################################################## # Overridden methods + def initialize(attributes=nil, *args) + self.watcher_user_ids = [] + super + end + def copy(project, options={}) super(project, options) project = project.is_a?(Project) ? project : Project.find(project) @@ -62,6 +67,8 @@ module RedmineDmsf has_many :dmsf_links, -> { where dmsf_folder_id: nil }, class_name: 'DmsfLink', foreign_key: 'project_id', dependent: :destroy + acts_as_watchable + before_save :set_default_dmsf_notification validates_length_of :dmsf_description, maximum: 65535 diff --git a/test/functional/dmsf_context_menus_controller_test.rb b/test/functional/dmsf_context_menus_controller_test.rb index 5a110709..0ced5362 100644 --- a/test/functional/dmsf_context_menus_controller_test.rb +++ b/test/functional/dmsf_context_menus_controller_test.rb @@ -37,26 +37,30 @@ class DmsfContextMenusControllerTest < RedmineDmsf::Test::TestCase end def test_dmsf_file - get :dmsf, params: { id: @file1.project.id, ids: ["file-#{@file1.id}"] } - assert_response :success - assert_select 'a.icon-edit', text: l(:button_edit) - assert_select 'a.icon-lock', text: l(:button_lock) - assert_select 'a.icon-email-add', text: l(:label_notifications_on) - assert_select 'a.icon-del', text: l(:button_delete) - assert_select 'a.icon-download', text: l(:button_download) - assert_select 'a.icon-email', text: l(:field_mail) - assert_select 'a.icon-file', text: l(:button_edit_content) + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { id: @file1.project.id, ids: ["file-#{@file1.id}"] } + assert_response :success + assert_select 'a.icon-edit', text: l(:button_edit) + assert_select 'a.icon-lock', text: l(:button_lock) + assert_select 'a.icon-email-add', text: l(:label_notifications_on) + assert_select 'a.icon-del', text: l(:button_delete) + assert_select 'a.icon-download', text: l(:button_download) + assert_select 'a.icon-email', text: l(:field_mail) + assert_select 'a.icon-file', text: l(:button_edit_content) + end end def test_dmsf_file_locked - get :dmsf, params: { id: @file2.project.id, ids: ["file-#{@file2.id}"] } - assert_response :success - assert_select 'a.icon-edit.disabled', text: l(:button_edit) - assert_select 'a.icon-unlock', text: l(:button_unlock) - assert_select 'a.icon-lock', text: l(:button_lock), count: 0 - assert_select 'a.icon-email-add.disabled', text: l(:label_notifications_on) - assert_select 'a.icon-del.disabled', text: l(:button_delete) - assert_select 'a.icon-file.disabled', text: l(:button_edit_content) + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { id: @file2.project.id, ids: ["file-#{@file2.id}"] } + assert_response :success + assert_select 'a.icon-edit.disabled', text: l(:button_edit) + assert_select 'a.icon-unlock', text: l(:button_unlock) + assert_select 'a.icon-lock', text: l(:button_lock), count: 0 + assert_select 'a.icon-email-add.disabled', text: l(:label_notifications_on) + assert_select 'a.icon-del.disabled', text: l(:button_delete) + assert_select 'a.icon-file.disabled', text: l(:button_edit_content) + end end def test_dmsf_edit_file_locked_by_myself @@ -87,29 +91,35 @@ class DmsfContextMenusControllerTest < RedmineDmsf::Test::TestCase def test_dmsf_file_notification_on @file1.notify_activate - get :dmsf, params: { id: @file1.project.id, ids: ["file-#{@file1.id}"] } - assert_response :success - assert_select 'a.icon-email', text: l(:label_notifications_off) - assert_select 'a.icon-email-add', text: l(:label_notifications_on), count: 0 + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { id: @file1.project.id, ids: ["file-#{@file1.id}"] } + assert_response :success + assert_select 'a.icon-email', text: l(:label_notifications_off) + assert_select 'a.icon-email-add', text: l(:label_notifications_on), count: 0 + end end def test_dmsf_file_manipulation_permission_off @role_manager.remove_permission! :file_manipulation - get :dmsf, params: { id: @file1.project.id, ids: ["file-#{@file1.id}"] } - assert_response :success - assert_select 'a.icon-edit.disabled', text: l(:button_edit) - assert_select 'a.icon-lock.disabled', text: l(:button_lock) - assert_select 'a.icon-email-add.disabled', text: l(:label_notifications_on) - assert_select 'a.icon-del.disabled', text: l(:button_delete) + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { id: @file1.project.id, ids: ["file-#{@file1.id}"] } + assert_response :success + assert_select 'a.icon-edit.disabled', text: l(:button_edit) + assert_select 'a.icon-lock.disabled', text: l(:button_lock) + assert_select 'a.icon-email-add.disabled', text: l(:label_notifications_on) + assert_select 'a.icon-del.disabled', text: l(:button_delete) + end end def test_dmsf_file_manipulation_permission_on - get :dmsf, params: { id: @file1.project.id, ids: ["file-#{@file1.id}"] } - assert_response :success - assert_select 'a:not(icon-edit.disabled)', text: l(:button_edit) - assert_select 'a:not(icon-lock.disabled)', text: l(:button_lock) - assert_select 'a:not(icon-email-add.disabled)', text: l(:label_notifications_on) - assert_select 'a:not(icon-del.disabled)', text: l(:button_delete) + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { id: @file1.project.id, ids: ["file-#{@file1.id}"] } + assert_response :success + assert_select 'a:not(icon-edit.disabled)', text: l(:button_edit) + assert_select 'a:not(icon-lock.disabled)', text: l(:button_lock) + assert_select 'a:not(icon-email-add.disabled)', text: l(:label_notifications_on) + assert_select 'a:not(icon-del.disabled)', text: l(:button_delete) + end end def test_dmsf_file_email_permission_off @@ -162,29 +172,46 @@ class DmsfContextMenusControllerTest < RedmineDmsf::Test::TestCase end end - def test_dmsf_file_link - get :dmsf, params: { - id: @file_link6.project.id, folder_id: @file_link6.dmsf_folder, ids: ["file-link-#{@file_link6.id}"] } + def test_dmsf_file_watch + get :dmsf, params: { id: @file1.project, ids: ["file-#{@file1.id}"] } assert_response :success - assert_select 'a.icon-edit', text: l(:button_edit) - assert_select 'a.icon-lock', text: l(:button_lock) - assert_select 'a.icon-email-add', text: l(:label_notifications_on) - assert_select 'a.icon-del', text: l(:button_delete) - assert_select 'a.icon-download', text: l(:button_download) - assert_select 'a.icon-email', text: l(:field_mail) - assert_select 'a.icon-file', text: l(:button_edit_content) + assert_select 'a.icon-fav-off', text: l(:button_watch) + end + + def test_dmsf_file_unwatch + @file1.add_watcher @jsmith + get :dmsf, params: { id: @file1.project, ids: ["file-#{@file1.id}"] } + assert_response :success + assert_select 'a.icon-fav', text: l(:button_unwatch) + end + + def test_dmsf_file_link + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { + id: @file_link6.project.id, folder_id: @file_link6.dmsf_folder, ids: ["file-link-#{@file_link6.id}"] } + assert_response :success + assert_select 'a.icon-edit', text: l(:button_edit) + assert_select 'a.icon-lock', text: l(:button_lock) + assert_select 'a.icon-email-add', text: l(:label_notifications_on) + assert_select 'a.icon-del', text: l(:button_delete) + assert_select 'a.icon-download', text: l(:button_download) + assert_select 'a.icon-email', text: l(:field_mail) + assert_select 'a.icon-file', text: l(:button_edit_content) + end end def test_dmsf_file_link_locked assert @file_link2.target_file.locked? - get :dmsf, params: { - id: @file_link2.project.id, folder_id: @file_link2.dmsf_folder.id, ids: ["file-link-#{@file_link2.id}"] } - assert_response :success - assert_select 'a.icon-edit.disabled', text: l(:button_edit) - assert_select 'a.icon-unlock', text: l(:button_unlock) - assert_select 'a.icon-lock', text: l(:button_lock), count: 0 - assert_select 'a.icon-email-add.disabled', text: l(:label_notifications_on) - assert_select 'a.icon-del', text: l(:button_delete) + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { + id: @file_link2.project.id, folder_id: @file_link2.dmsf_folder.id, ids: ["file-link-#{@file_link2.id}"] } + assert_response :success + assert_select 'a.icon-edit.disabled', text: l(:button_edit) + assert_select 'a.icon-unlock', text: l(:button_unlock) + assert_select 'a.icon-lock', text: l(:button_lock), count: 0 + assert_select 'a.icon-email-add.disabled', text: l(:label_notifications_on) + assert_select 'a.icon-del', text: l(:button_delete) + end end def test_dmsf_url_link @@ -194,26 +221,30 @@ class DmsfContextMenusControllerTest < RedmineDmsf::Test::TestCase end def test_dmsf_folder - get :dmsf, params: { id: @folder1.project.id, ids: ["folder-#{@folder1.id}"] } - assert_response :success - assert_select 'a.icon-edit', text: l(:button_edit) - assert_select 'a.icon-lock', text: l(:button_lock) - assert_select 'a.icon-email-add', text: l(:label_notifications_on) - assert_select 'a.icon-del', text: l(:button_delete) - assert_select 'a:not(icon-del.disabled)', text: l(:button_delete) - assert_select 'a.icon-download', text: l(:button_download) - assert_select 'a.icon-email', text: l(:field_mail) + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { id: @folder1.project.id, ids: ["folder-#{@folder1.id}"] } + assert_response :success + assert_select 'a.icon-edit', text: l(:button_edit) + assert_select 'a.icon-lock', text: l(:button_lock) + assert_select 'a.icon-email-add', text: l(:label_notifications_on) + assert_select 'a.icon-del', text: l(:button_delete) + assert_select 'a:not(icon-del.disabled)', text: l(:button_delete) + assert_select 'a.icon-download', text: l(:button_download) + assert_select 'a.icon-email', text: l(:field_mail) + end end def test_dmsf_folder_locked assert @folder5.locked? - get :dmsf, params: { id: @folder5.project.id, ids: ["folder-#{@folder5.id}"] } - assert_response :success - assert_select 'a.icon-edit.disabled', text: l(:button_edit) - assert_select 'a.icon-unlock', text: l(:button_unlock) - assert_select 'a.icon-lock', text: l(:button_lock), count: 0 - assert_select 'a.icon-email-add.disabled', text: l(:label_notifications_on) - assert_select 'a.icon-del.disabled', text: l(:button_delete) + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { id: @folder5.project.id, ids: ["folder-#{@folder5.id}"] } + assert_response :success + assert_select 'a.icon-edit.disabled', text: l(:button_edit) + assert_select 'a.icon-unlock', text: l(:button_unlock) + assert_select 'a.icon-lock', text: l(:button_lock), count: 0 + assert_select 'a.icon-email-add.disabled', text: l(:label_notifications_on) + assert_select 'a.icon-del.disabled', text: l(:button_delete) + end end def test_dmsf_folder_locked_force_unlock_permission_off @@ -235,29 +266,35 @@ class DmsfContextMenusControllerTest < RedmineDmsf::Test::TestCase def test_dmsf_folder_notification_on @folder5.notify_activate - get :dmsf, params: { id: @folder5.project.id, ids: ["folder-#{@folder5.id}"] } - assert_response :success - assert_select 'a.icon-email', text: l(:label_notifications_off) - assert_select 'a.icon-email-add', text: l(:label_notifications_on), count: 0 + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { id: @folder5.project.id, ids: ["folder-#{@folder5.id}"] } + assert_response :success + assert_select 'a.icon-email', text: l(:label_notifications_off) + assert_select 'a.icon-email-add', text: l(:label_notifications_on), count: 0 + end end def test_dmsf_folder_manipulation_permmissions_off @role_manager.remove_permission! :folder_manipulation - get :dmsf, params: { id: @folder1.project.id, ids: ["folder-#{@folder1.id}"] } - assert_response :success - assert_select 'a.icon-edit.disabled', text: l(:button_edit) - assert_select 'a.icon-lock.disabled', text: l(:button_lock) - assert_select 'a.icon-email-add.disabled', text: l(:label_notifications_on) - assert_select 'a.icon-del.disabled', text: l(:button_delete) + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { id: @folder1.project.id, ids: ["folder-#{@folder1.id}"] } + assert_response :success + assert_select 'a.icon-edit.disabled', text: l(:button_edit) + assert_select 'a.icon-lock.disabled', text: l(:button_lock) + assert_select 'a.icon-email-add.disabled', text: l(:label_notifications_on) + assert_select 'a.icon-del.disabled', text: l(:button_delete) + end end def test_dmsf_folder_manipulation_permmissions_on - get :dmsf, params: { id: @folder1.project.id, ids: ["folder-#{@folder1.id}"] } - assert_response :success - assert_select 'a:not(icon-edit.disabled)', text: l(:button_edit) - assert_select 'a:not(icon-lock.disabled)', text: l(:button_lock) - assert_select 'a:not(icon-email-add.disabled)', text: l(:label_notifications_on) - assert_select 'a:not(icon-del.disabled)', text: l(:button_delete) + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { id: @folder1.project.id, ids: ["folder-#{@folder1.id}"] } + assert_response :success + assert_select 'a:not(icon-edit.disabled)', text: l(:button_edit) + assert_select 'a:not(icon-lock.disabled)', text: l(:button_lock) + assert_select 'a:not(icon-email-add.disabled)', text: l(:label_notifications_on) + assert_select 'a:not(icon-del.disabled)', text: l(:button_delete) + end end def test_dmsf_folder_email_permmissions_off @@ -273,26 +310,43 @@ class DmsfContextMenusControllerTest < RedmineDmsf::Test::TestCase assert_select 'a:not(icon-email.disabled)', text: l(:field_mail) end - def test_dmsf_folder_link - get :dmsf, params: { id: @folder_link1.project.id, ids: ["folder-#{@folder_link1.id}"] } + def test_dmsf_folder_watch + get :dmsf, params: { id: @folder1.project, ids: ["folder-#{@folder1.id}"] } assert_response :success - assert_select 'a.icon-edit', text: l(:button_edit) - assert_select 'a.icon-lock', text: l(:button_lock) - assert_select 'a.icon-email-add', text: l(:label_notifications_on) - assert_select 'a.icon-del', text: l(:button_delete) - assert_select 'a.icon-download', text: l(:button_download) - assert_select 'a.icon-email', text: l(:field_mail) + assert_select 'a.icon-fav-off', text: l(:button_watch) + end + + def test_dmsf_folder_unwatch + @folder1.add_watcher @jsmith + get :dmsf, params: { id: @folder1.project, ids: ["folder-#{@folder1.id}"] } + assert_response :success + assert_select 'a.icon-fav', text: l(:button_unwatch) + end + + def test_dmsf_folder_link + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { id: @folder_link1.project.id, ids: ["folder-#{@folder_link1.id}"] } + assert_response :success + assert_select 'a.icon-edit', text: l(:button_edit) + assert_select 'a.icon-lock', text: l(:button_lock) + assert_select 'a.icon-email-add', text: l(:label_notifications_on) + assert_select 'a.icon-del', text: l(:button_delete) + assert_select 'a.icon-download', text: l(:button_download) + assert_select 'a.icon-email', text: l(:field_mail) + end end def test_dmsf_folder_link_locked @folder_link1.target_folder.lock! - get :dmsf, params: { id: @folder_link1.project.id, ids: ["folder-#{@folder_link1.id}"] } - assert_response :success - assert_select 'a.icon-edit.disabled', text: l(:button_edit) - assert_select 'a.icon-unlock', text: l(:button_unlock) - assert_select 'a.icon-lock', text: l(:button_lock), count: 0 - assert_select 'a.icon-email-add.disabled', text: l(:label_notifications_on) - assert_select 'a.icon-del.disabled', text: l(:button_delete) + with_settings :notified_events => ['dmsf_legacy_notifications'] do + get :dmsf, params: { id: @folder_link1.project.id, ids: ["folder-#{@folder_link1.id}"] } + assert_response :success + assert_select 'a.icon-edit.disabled', text: l(:button_edit) + assert_select 'a.icon-unlock', text: l(:button_unlock) + assert_select 'a.icon-lock', text: l(:button_lock), count: 0 + assert_select 'a.icon-email-add.disabled', text: l(:label_notifications_on) + assert_select 'a.icon-del.disabled', text: l(:button_delete) + end end def test_dmsf_multiple @@ -308,6 +362,19 @@ class DmsfContextMenusControllerTest < RedmineDmsf::Test::TestCase assert_select 'a.icon-email', text: l(:field_mail) end + def test_dmsf_project_watch + get :dmsf, params: { ids: ["project-#{@project1.id}"] } + assert_response :success + assert_select 'a.icon-fav-off', text: l(:button_watch) + end + + def test_dmsf_project_unwatch + @project1.add_watcher @jsmith + get :dmsf, params: { ids: ["project-#{@project1.id}"] } + assert_response :success + assert_select 'a.icon-fav', text: l(:button_unwatch) + end + def test_trash_file get :trash, params: { id: @file1.project.id, ids: ["file-#{@file1.id}"] } assert_response :success diff --git a/test/functional/my_controller_test.rb b/test/functional/my_controller_test.rb index 44c4deac..ff1bf418 100644 --- a/test/functional/my_controller_test.rb +++ b/test/functional/my_controller_test.rb @@ -57,7 +57,7 @@ class MyControllerTest < RedmineDmsf::Test::TestCase end end end - + def test_page_with_open_locked_documents @request.session[:user_id] = @admin.id @admin.pref[:my_page_layout] = { 'top' => ['locked_documents'] } @@ -71,4 +71,17 @@ class MyControllerTest < RedmineDmsf::Test::TestCase end end + def test_page_with_open_watched_documents + @jsmith.pref[:my_page_layout] = { 'top' => ['watched_documents'] } + @jsmith.pref.save! + @file1.add_watcher @jsmith + @folder1.add_watcher @jsmith + @project1.add_watcher @jsmith + get :page + assert_response :success + assert_select 'div#list-top' do + assert_select 'h3', { text: "#{l(:label_dmsf_watched)} (2/1)" } + end + end + end \ No newline at end of file diff --git a/test/unit/dmsf_file_test.rb b/test/unit/dmsf_file_test.rb index 0faa084e..3719e61e 100644 --- a/test/unit/dmsf_file_test.rb +++ b/test/unit/dmsf_file_test.rb @@ -275,4 +275,9 @@ class DmsfFileTest < RedmineDmsf::Test::UnitTest assert_equal '', @file1.locked_by end + def test_watchable + @file1.add_watcher @jsmith + assert @file1.watched_by?(@jsmith) + end + end \ No newline at end of file diff --git a/test/unit/dmsf_folder_test.rb b/test/unit/dmsf_folder_test.rb index 416c3961..2b62c644 100644 --- a/test/unit/dmsf_folder_test.rb +++ b/test/unit/dmsf_folder_test.rb @@ -258,4 +258,9 @@ class DmsfFolderTest < RedmineDmsf::Test::UnitTest assert @folder6.empty? end + def test_watchable + @folder1.add_watcher @jsmith + assert @folder1.watched_by?(@jsmith) + end + end \ No newline at end of file diff --git a/test/unit/dmsf_mailer_test.rb b/test/unit/dmsf_mailer_test.rb index 19da7abc..9ae20e08 100644 --- a/test/unit/dmsf_mailer_test.rb +++ b/test/unit/dmsf_mailer_test.rb @@ -94,20 +94,34 @@ class DmsfMailerTest < RedmineDmsf::Test::UnitTest end def test_get_notify_users - users = DmsfMailer.get_notify_users(@project1, [@file1]) - assert users.present? + with_settings :notified_events => ['dmsf_legacy_notifications'] do + users = DmsfMailer.get_notify_users(@project1, @file1) + assert users.present? + end + with_settings :notified_events => [] do + users = DmsfMailer.get_notify_users(@project1, @file1) + assert users.empty? + end end def test_get_notify_users_notification_switched_off @file1.notify_deactivate - users = DmsfMailer.get_notify_users(@project1, [@file1]) + users = DmsfMailer.get_notify_users(@project1, @file1) assert users.blank? end def test_get_notify_users_on_inactive_projects @project1.status = Project::STATUS_CLOSED - users = DmsfMailer.get_notify_users(@project1, [@file1]) + users = DmsfMailer.get_notify_users(@project1, @file1) assert users.blank? end + def test_get_notify_users_with_watchers + @file1.add_watcher @jsmith + with_settings :notified_events => [] do + users = DmsfMailer.get_notify_users(@project1, @file1) + assert users.present? + end + end + end \ No newline at end of file diff --git a/test/unit/project_patch_test.rb b/test/unit/project_patch_test.rb index 50429859..433fdb10 100644 --- a/test/unit/project_patch_test.rb +++ b/test/unit/project_patch_test.rb @@ -103,4 +103,9 @@ class ProjectPatchTest < RedmineDmsf::Test::UnitTest assert !@project3.dmsf_available? end + def test_watchable + @project1.add_watcher @jsmith + assert @project1.watched_by?(@jsmith) + end + end \ No newline at end of file