Merge branch 'redmine_notifications' into devel-2.4.12

This commit is contained in:
Karel.Picman 2022-02-01 12:46:56 +01:00
commit 5e4d47a88e
52 changed files with 1063 additions and 365 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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,

View File

@ -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 %>
</div>
@ -91,6 +93,24 @@
<% content_for :sidebar do %>
<%= render partial: 'dmsf/sidebar' %>
<% project_or_folder = @folder? @folder : @project %>
<% if project_or_folder&.watchers.present? %>
<div id="watchers">
<% if @folder %>
<%= render partial: 'watchers/watchers', locals: { watched: @folder } %>
<% else %>
<% if User.current.allowed_to?(:add_project_watchers, @project) %>
<div class="contextual">
<%= link_to l(:button_add), new_watchers_path(object_type: :project, object_id: @project.id), remote: true,
method: 'get' %>
</div>
<% end %>
<h3><%= l(:label_project_watchers) %> (<%= @project.watcher_users.size %>)</h3>
<%= watchers_list @project %>
<% end %>
</div>
<% end %>
<% end %>
<% if Redmine::Plugin.installed?(:easy_extensions) %>

View File

@ -27,7 +27,7 @@
<%= hidden_field_tag 'back_url', url_for(params: request.query_parameters), id: nil %>
<%= query_columns_hidden_tags(query) %>
<div class="autoscroll">
<table class="list dmsf odd-even <%= query.css_classes %> context_menu-container" data-hascontextmenu="true">
<table class="list dmsf odd-even <%= query.css_classes %> context-menu-container" data-hascontextmenu="true">
<thead>
<tr>
<% if defined?(EasyExtensions) %>

View File

@ -38,13 +38,13 @@
<% @idnt ||= 0 %>
<tr id="<%= id %>" class="<%= cycle('odd', 'even') %> <%= node.css_classes(query.deleted) %> <%= params[:classes] %> <%= @idnt > 0 ? "idnt idnt-#{@idnt}" : nil %>">
<td class="checkbox hide-when-print">
<%= 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 %>
</td>
<% query.inline_columns.each do |column| %>
<%= content_tag 'td', column_content(column, node), class: column.css_classes %>
<% end %>
<td class="buttons">
<% 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 %>

View File

@ -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 %>

View File

@ -25,7 +25,7 @@
<% html_title(l(:dmsf)) %>
<div class="contextual">
<% 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)),

View File

@ -46,15 +46,17 @@
class: 'icon icon-lock', disabled: !allowed %>
<% end %>
</li>
<li>
<% 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 %>
</li>
<% if notifications %>
<li>
<% 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 %>
</li>
<% end %>
<li>
<%= 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') %>
</li>
<% end %>
<li>
<%= render partial: 'dmsf_context_menus/watch', locals: { object: dmsf_file } %>
</li>
<li>
<%= 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,

View File

@ -49,17 +49,19 @@
<% end %>
</li>
<% end %>
<li>
<% 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 %>
</li>
<% if notifications %>
<li>
<% 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 %>
</li>
<% end %>
<% unless edit %>
<li>
<%= context_menu_link l(:button_download), entries_operations_dmsf_path(id: project, folder_id: folder,
@ -72,6 +74,9 @@
disabled: !email_allowed %>
</li>
<% end %>
<li>
<%= render partial: 'dmsf_context_menus/watch', locals: { object: dmsf_folder } %>
</li>
<li>
<%= context_menu_link l(:button_delete),
dmsf_link ? dmsf_link_path(id: dmsf_link, folder_id: folder, back_url: back_url) :

View File

@ -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 %>
<span class="icon icon-del">
<%= l(:link_trash_bin) %>
</span>
<%= l(:link_trash_bin) %>
</span>
<% end %>

View File

@ -0,0 +1,25 @@
<%
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011-22 Karel Pičman <karel.picman@kontron.com>
#
# 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.
%>
<li>
<%= render partial: 'dmsf_context_menus/watch', locals: { object: dmsf_project } %>
</li>

View File

@ -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 %>

View File

@ -0,0 +1,30 @@
<%
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011-22 Karel Pičman <karel.picman@kontron.com>
#
# 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? %>

View File

@ -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 } %>

View File

@ -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 %>
<span class="pagination"><%= pagination_links_full @revision_pages, @revision_count %></span>
<% if @file.watchers.present? %>
<% content_for :sidebar do %>
<div id="watchers">
<%= render partial: 'watchers/watchers', locals: { watched: @file } %>
</div>
<% end %>
<% end %>
<%= late_javascript_tag do %>
$('a.delete-revision').click(function(event) {
if(!window.confirm('<%= l(:text_are_you_sure) %>')) {

View File

@ -23,13 +23,15 @@
<% if member %>
<fieldset class="box tabular">
<legend><%= l(:link_user_preferences) %></legend>
<p>
<%= 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) %>
</p>
<% if Setting.notified_events.include?('dmsf_legacy_notifications') %>
<p>
<%= 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) %>
</p>
<% end %>
<p>
<%= content_tag :label, l(:label_title_format) %>
<%= text_field_tag 'title_format', member.dmsf_title_format, size: 10 %>

View File

@ -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) %>
<h3><%= l(:locked_documents)%> (<%= folders.count %>/<%= files.count %>)</h3>
<% end %>
0, @user&.id, Time.current]) %>
<h3><%= l(:locked_documents)%> (<%= folders.all.size %>/<%= files.all.size %>)</h3>
<% if folders.any? || files.any?%>
<%= form_tag({}) do %>
<table class="list">
<%= form_tag({}, data: { cm_url: dmsf_context_menu_path(back_url: my_page_path) }) do %>
<table class="list context-menu-container" data-hascontextmenu="true">
<thead>
<tr>
<th class="checkbox hide-when-print">
<%= check_box_tag 'check_all', '', false, class: 'toggle-selection',
title: "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
</th>
<th><%= l(:field_project) %></th>
<th><%= l(:label_document) %>/<%= l(:field_folder) %></th>
<th><%= l(:field_folder) %></th>
<th></th>
</tr>
</thead>
<tbody>
<% folders.each do |folder| %>
<tr id="folder-<%= folder.id %>">
<tr id="folder-<%= folder.id %>" class="hascontextmenu">
<td class="checkbox hide-when-print">
<%= check_box_tag 'ids[]', "folder-#{folder.id}", false, id: nil %>
</td>
<td class="project">
<%= link_to_project(folder.project) %>
<%= link_to_project folder.project %>
</td>
<td class="title">
<%= 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' %>
</td>
<td class="title">
<% 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 %>
</td>
<td>
<%= link_to_context_menu %>
</td>
</tr>
<% end %>
<% files.each do |file| %>
<tr id="file-<%= file.id %>">
<tr id="file-<%= file.id %>" class="hascontextmenu">
<td class="checkbox hide-when-print">
<%= check_box_tag 'ids[]', "file-#{file.id}", false, id: nil %>
</td>
<td class="project">
<%= link_to_project(file.project) if file.project %>
<%= link_to_project file.project %>
</td>
<td class="title">
<%= 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)}" %>
</td>
<td class="title">
<% 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 %>
</td>
<td>
<%= link_to_context_menu %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
<%= context_menu %>
<% else %>
<p class="nodata"><%= l(:label_no_data) %></p>
<% end %>

View File

@ -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) %>
<h3><%= l(:open_approvals)%> (<%= assignments.size %>)</h3>
<% 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 } %>
<h3><%= l(:open_approvals)%> (<%= assignments.size %>)</h3>
<% if assignments.any? %>
<%= form_tag do %>
<%= form_tag({}, data: { cm_url: dmsf_context_menu_path(back_url: my_page_path) }) do %>
<table class="list">
<thead>
<tr>
<th class="checkbox hide-when-print">
<%= check_box_tag 'check_all', '', false, class: 'toggle-selection',
title: "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
</th>
<th><%= l(:field_project) %></th>
<th><%= l(:field_label_dmsf_workflow) %></th>
<th><%= l(:field_status) %></th>
@ -52,16 +51,19 @@
</thead>
<tbody>
<% assignments.each do |assignment| %>
<tr id="assignment-<%= assignment.id %>">
<tr id="file-<%= assignment.dmsf_file_revision.dmsf_file.id %>" class="hascontextmenu">
<td class="checkbox hide-when-print">
<%= check_box_tag 'ids[]', "file-#{assignment.dmsf_file_revision.dmsf_file.id}", false, id: nil %>
</td>
<td class="project">
<% 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 %>
</td>
<td>
<% 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 %>
</td>
<td class="dmsf_workflow">
@ -80,36 +82,29 @@
<td class="title">
<% 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 %>
</td>
<td class="title">
<% 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 %>
</td>
<td class="dmsf-buttons">
<%= 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 } %>
<td>
<%= link_to_context_menu %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
<%= context_menu %>
<% else %>
<p class="nodata"><%= l(:label_no_data) %></p>
<% end %>

View File

@ -0,0 +1,118 @@
<%
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011-22 Karel Pičman <karel.picman@kontron.com>
#
# 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 }) %>
<h3><%= l(:label_dmsf_watched)%> (<%= projects.all.size + folders.all.size %>/<%= files.all.size %>)</h3>
<% if projects.any? || folders.any? || files.any? %>
<%= form_tag({}, data: { cm_url: dmsf_context_menu_path(back_url: my_page_path) }) do %>
<table class="list context-menu-container" data-hascontextmenu="true">
<thead>
<tr>
<th class="checkbox hide-when-print">
<%= check_box_tag 'check_all', '', false, class: 'toggle-selection',
title: "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
</th>
<th><%= l(:field_project) %></th>
<th><%= l(:label_document) %>/<%= l(:field_folder) %></th>
<th><%= l(:field_folder) %></th>
<th></th>
</tr>
</thead>
<tbody>
<% projects.each do |project| %>
<tr id="project-<%= project.id %>" class="hascontextmenu">
<td class="checkbox hide-when-print">
<%= check_box_tag 'ids[]', "project-#{project.id}", false, id: nil %>
</td>
<td class="project">
<%= link_to_project project %>
</td>
<td class="title">
<%= link_to_project project, jump: 'dmsf', class: 'project' %>
</td>
<td class="title"></td>
<td>
<%= link_to_context_menu %>
</td>
</tr>
<% end %>
<% folders.each do |folder| %>
<tr id="folder-<%= folder.id %>" class="hascontextmenu">
<td class="checkbox hide-when-print">
<%= check_box_tag 'ids[]', "folder-#{folder.id}", false, id: nil %>
</td>
<td class="project">
<%= link_to_project folder.project %>
</td>
<td class="title">
<%= link_to h(folder.title), dmsf_folder_path(id: folder.project, folder_id: folder),
class: 'icon icon-folder' %>
</td>
<td class="title">
<% 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 %>
</td>
<td>
<%= link_to_context_menu %>
</td>
</tr>
<% end %>
<% files.each do |file| %>
<tr id="file-<%= file.id %>" class="hascontextmenu">
<td class="checkbox hide-when-print">
<%= check_box_tag 'ids[]', "file-#{file.id}", false, id: nil %>
</td>
<td class="project">
<%= link_to_project(file.project) if file.project %>
</td>
<td class="title">
<%= link_to h(file.title), dmsf_file_path(id: file),
class: "icon icon-file #{DmsfHelper.filetype_css(file.name)}" %>
</td>
<td class="title">
<% 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 %>
</td>
<td>
<%= link_to_context_menu %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
<%= context_menu %>
<% else %>
<p class="nodata"><%= l(:label_no_data) %></p>
<% end %>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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: 自分がロック中の文書

View File

@ -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: 내 잠긴 파일

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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: Мои заблокированные документы

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -0,0 +1,53 @@
# encoding: utf-8
# frozen_string_literal: true
#
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011-22 Karel Pičman <karel.picman@kontron.com>
#
# 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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