#218 Recycle bin - bulk operations

This commit is contained in:
Karel Pičman 2014-06-13 10:19:27 +02:00
parent 8d3c66c097
commit 1db1e4bbd2
20 changed files with 175 additions and 145 deletions

View File

@ -132,10 +132,10 @@ class DmsfController < ApplicationController
def entries_operation
# Download/Email
selected_folders = params[:subfolders].present? ? params[:subfolders] : []
selected_files = params[:files].present? ? params[:files] : []
selected_dir_links = params[:dir_links]
selected_file_links = params[:file_links]
selected_folders = params[:subfolders] || []
selected_files = params[:files] || []
selected_dir_links = params[:dir_links] || []
selected_file_links = params[:file_links] || []
if selected_folders.blank? && selected_files.blank? &&
selected_dir_links.blank? && selected_file_links.blank?
@ -147,19 +147,28 @@ class DmsfController < ApplicationController
if selected_dir_links.present?
selected_dir_links.each do |id|
link = DmsfLink.find_by_id id
selected_folders << link.target_id if link
selected_folders << link.target_id if link && !selected_folders.include?(link.target_id.to_s)
end
end
if selected_file_links.present?
selected_file_links.each do |id|
link = DmsfLink.find_by_id id
selected_files << link.target_id if link
selected_files << link.target_id if link && !selected_files.include?(link.target_id.to_s)
end
end
if params[:email_entries].present?
email_entries(selected_folders, selected_files)
elsif params[:restore_entries].present?
restore_entries(selected_folders, selected_files, selected_dir_links, selected_file_links)
redirect_to :back
elsif params[:delete_entries].present?
delete_entries(selected_folders, selected_files, selected_dir_links, selected_file_links, false)
redirect_to :back
elsif params[:destroy_entries].present?
delete_entries(selected_folders, selected_files, selected_dir_links, selected_file_links, true)
redirect_to :back
else
download_entries(selected_folders, selected_files)
end
@ -201,94 +210,6 @@ class DmsfController < ApplicationController
redirect_to dmsf_folder_path(:id => @project, :folder_id => @folder)
end
def delete_entries
selected_folders = params[:subfolders]
selected_files = params[:files]
selected_dir_links = params[:dir_links]
selected_file_links = params[:file_links]
if selected_folders.blank? && selected_files.blank? &&
selected_dir_links.blank? && selected_file_links.blank?
flash[:warning] = l(:warning_no_entries_selected)
else
failed_entries = []
if User.current.allowed_to?(:folder_manipulation, @project)
# Folders
if selected_folders.present?
selected_folders.each do |subfolderid|
subfolder = DmsfFolder.visible.find_by_id subfolderid
next unless subfolder
if subfolder.project != @project || !subfolder.delete
failed_entries.push(subfolder)
end
end
end
# Folder links
if selected_dir_links.present?
selected_dir_links.each do |dir_link_id|
link_folder = DmsfLink.visible.find_by_id dir_link_id
next unless link_folder
if link_folder.project != @project || !link_folder.delete
failed_entries.push(link_folder)
end
end
end
else
flash[:error] = l(:error_user_has_not_right_delete_folder)
end
deleted_files = []
if User.current.allowed_to?(:file_manipulation, @project)
# Files
if selected_files.present?
selected_files.each do |fileid|
file = DmsfFile.visible.find_by_id fileid
next unless file
if file.project != @project || !file.delete
failed_entries.push(file)
else
deleted_files.push(file)
end
end
end
# File links
if selected_file_links.present?
selected_file_links.each do |file_link_id|
file_link = DmsfLink.visible.find_by_id file_link_id
next unless file_link
if file_link.project != @project || !file_link.delete
failed_entries.push(file_link)
end
end
end
else
flash[:error] = l(:error_user_has_not_right_delete_file)
end
unless deleted_files.empty?
deleted_files.each do |f|
log_activity(f, 'deleted')
end
begin
DmsfMailer.get_notify_users(User.current, deleted_files).each do |u|
DmsfMailer.files_deleted(u, @project, deleted_files).deliver
end
rescue Exception => e
Rails.logger.error "Could not send email notifications: #{e.message}"
end
end
if failed_entries.empty?
flash[:notice] = l(:notice_entries_deleted)
else
flash[:warning] = l(:warning_some_entries_were_not_deleted, :entries => failed_entries.map{|e| e.title}.join(', '))
end
end
redirect_to :back
end
# Folder manipulation
def new
@folder = DmsfFolder.new
@pathfolder = @parent
@ -345,6 +266,8 @@ class DmsfController < ApplicationController
def restore
if @folder.restore
flash[:notice] = l(:notice_dmsf_folder_restored)
else
flash[:error] = @folder.errors[:base][0]
end
redirect_to :back
end
@ -488,13 +411,17 @@ class DmsfController < ApplicationController
def zip_entries(zip, selected_folders, selected_files)
if selected_folders && selected_folders.is_a?(Array)
selected_folders.each do |selected_folder_id|
folder = DmsfFolder.visible.find(selected_folder_id)
zip.add_folder(folder, (@folder.dmsf_path_str if @folder)) if folder
folder = DmsfFolder.visible.find_by_id selected_folder_id
if folder
zip.add_folder(folder, (@folder.dmsf_path_str if @folder))
else
raise FileNotFound
end
end
end
if selected_files && selected_files.is_a?(Array)
selected_files.each do |selected_file_id|
file = DmsfFile.visible.find(selected_file_id)
file = DmsfFile.visible.find_by_id selected_file_id
if file && file.last_revision && File.exists?(file.last_revision.disk_file)
zip.add_file(file, (@folder.dmsf_path_str if @folder)) if file
else
@ -509,6 +436,95 @@ class DmsfController < ApplicationController
zip
end
def restore_entries(selected_folders, selected_files, selected_dir_links, selected_file_links)
# Folders
selected_folders.each do |id|
folder = DmsfFolder.find_by_id id
if folder
unless folder.restore
flash[:error] = folder.errors[:base][0]
end
else
raise FileNotFound
end
end
# Files
selected_files.each do |id|
file = DmsfFile.find_by_id id
if file
unless file.restore
flash[:error] = file.errors[:base][0]
end
else
raise FileNotFound
end
end
# Links
(selected_dir_links + selected_file_links).each do |id|
link = DmsfLink.find_by_id id
if link
unless link.restore
flash[:error] = link.errors[:base][0]
end
else
raise FileNotFound
end
end
end
def delete_entries(selected_folders, selected_files, selected_dir_links, selected_file_links, commit)
# Folders
selected_folders.each do |id|
folder = DmsfFolder.find_by_id id
if folder
unless folder.delete commit
flash[:error] = folder.errors[:base][0]
end
else
raise FileNotFound
end
end
# Files
deleted_files = []
not_deleted_files = []
selected_files.each do |id|
file = DmsfFile.find_by_id id
if file
if file.delete(commit)
deleted_files << file unless commit
else
not_deleted_files << file
end
else
raise FileNotFound
end
end
# Activities
if !deleted_files.empty?
deleted_files.each do |f|
log_activity(f, 'deleted')
end
begin
DmsfMailer.get_notify_users(User.current, deleted_files).each do |u|
DmsfMailer.files_deleted(u, @project, deleted_files).deliver
end
rescue Exception => e
Rails.logger.error "Could not send email notifications: #{e.message}"
end
end
unless not_deleted_files.empty?
flash[:warning] = l(:warning_some_entries_were_not_deleted, :entries => not_deleted_files.map{|e| e.title}.join(', '))
end
# Links
(selected_dir_links + selected_file_links).each do |id|
link = DmsfLink.find_by_id id
link.delete commit if link
end
if flash[:error].blank? && flash[:warning].blank?
flash[:notice] = l(:notice_entries_deleted)
end
end
def find_folder
@folder = DmsfFolder.find params[:folder_id] if params[:folder_id].present?
rescue DmsfAccessError

View File

@ -221,6 +221,8 @@ class DmsfFilesController < ApplicationController
if @file.restore
log_activity('restored')
flash[:notice] = l(:notice_dmsf_file_restored)
else
flash[:error] = @file.errors[:base][0]
end
redirect_to :back
end

View File

@ -125,6 +125,10 @@ class DmsfFile < ActiveRecord::Base
end
def restore
if self.dmsf_folder_id && (self.folder.nil? || self.folder.deleted)
errors[:base] << l(:error_parent_folder)
return false
end
self.revisions.each { |r| r.restore }
self.referenced_links.each { |l| l.restore }
self.deleted = false

View File

@ -104,6 +104,10 @@ class DmsfFolder < ActiveRecord::Base
end
def restore
if self.dmsf_folder_id && (self.folder.nil? || self.folder.deleted)
errors[:base] << l(:error_parent_folder)
return false
end
self.referenced_links.each { |l| l.restore }
self.deleted = false
self.deleted_by_user = nil

View File

@ -112,6 +112,10 @@ class DmsfLink < ActiveRecord::Base
end
def restore
if self.dmsf_folder_id && (self.folder.nil? || self.folder.deleted)
errors[:base] << l(:error_parent_folder)
return false
end
self.deleted = false
self.deleted_by_user = nil
save

View File

@ -109,11 +109,9 @@
:class => 'dmfs_entries', :id => 'entries_form') do %>
<%= hidden_field_tag('action') %>
<div class="controls" style="float: left">
<%= submit_tag(l(:submit_download), :title => l(:title_download_checked), :name => 'download_entries') %>
<%= submit_tag(l(:submit_email), :title => l(:title_send_checked_by_email), :name => 'email_entries') %>
<% if @file_manipulation_allowed && @folder_manipulation_allowed && !@locked_for_user %>
<button type="button" id="entries_delete_button" title="<%= l(:title_delete_checked) %>"><%= l(:button_delete) %></button>
<% end %>
<%= submit_tag(l(:button_download), :title => l(:title_download_checked), :name => 'download_entries') %>
<%= submit_tag(l(:field_mail), :title => l(:title_send_checked_by_email), :name => 'email_entries') %>
<%= submit_tag(l(:button_delete), :title => l(:title_delete_checked), :name => 'delete_entries') %>
</div>
<% values = @folder ? @folder.custom_field_values : @parent ? @parent.custom_field_values : DmsfFolder.new(:project => @project).custom_field_values %>
<% unless values.empty? %>

View File

@ -36,9 +36,11 @@
:class => 'dmfs_entries', :id => 'entries_form') do %>
<%= hidden_field_tag('action') %>
<div class="controls" style="float: left">
<%= submit_tag(l(:submit_download), :title => l(:title_download_checked), :name => 'download_entries') %>
<% if @file_manipulation_allowed && @folder_manipulation_allowed && !@locked_for_user %>
<button type="button" id="entries_delete_button" title="<%= l(:title_delete_checked) %>"><%= l(:button_delete) %></button>
<% if @file_manipulation_allowed && @folder_manipulation_allowed %>
<%= submit_tag(l(:title_restore), :title => l(:title_restore_checked), :name => 'restore_entries') %>
<% if @file_delete_allowed%>
<%= submit_tag(l(:button_delete), :title => l(:title_delete_checked), :name => 'destroy_entries') %>
<% end %>
<% end %>
</div>
<table class="display entries" id="browser">

View File

@ -74,10 +74,8 @@ cs:
title_waiting_for_approval: Čeká na schválení
title_approved: Schváleno
title_unlock_file: Odemknout a umožnit změny ostatním uživatelům
title_lock_file: Zamknout a zabránit změnám ostatních uživatelů
submit_download: Stáhnout
title_download_checked: Stáhnout vybrané jako Zip
submit_email: Email
title_lock_file: Zamknout a zabránit změnám ostatních uživatelů
title_download_checked: Stáhnout vybrané jako Zip
title_send_checked_by_email: Zaslat vybrané emailem
link_user_preferences: Vaše nastavení
heading_send_documents_by_email: Odeslat dokumenty emailem
@ -303,6 +301,8 @@ cs:
notice_dmsf_file_restored: Document byl úspěšně obnoven
notice_dmsf_folder_restored: Adresář byl úspěšně obnoven
notice_dmsf_link_restored: Odkaz byl úspěšně obnoven
title_restore_checked: Obnov vybrané
error_parent_folder: Nadřazený adresář neexistuje
my:
blocks:

View File

@ -74,10 +74,8 @@ de:
title_waiting_for_approval: Warte auf Zustimmung
title_approved: Zugestimmt
title_unlock_file: Hebe Sperre auf um Änderungen anderer Nutzer zu ermöglichen
title_lock_file: Sperre um Änderungen anderer Nutzer zu verhindern
submit_download: Download
title_download_checked: Download der ausgewählten Dateien in einem ZIP-Archiv
submit_email: Email
title_lock_file: Sperre um Änderungen anderer Nutzer zu verhindern
title_download_checked: Download der ausgewählten Dateien in einem ZIP-Archiv
title_send_checked_by_email: Sende gewählte Dateien per Email
link_user_preferences: Deine Einstellungen
heading_send_documents_by_email: Sende Dateien per Email
@ -303,6 +301,8 @@ de:
notice_dmsf_file_restored: The document has been successfully restored
notice_dmsf_folder_restored: The folder has been successfully restored
notice_dmsf_link_restored: The link has been successfully restored
title_restore_checked: Restore checked
error_parent_folder: "The parent folder doesn't exist"
my:
blocks:

View File

@ -74,10 +74,8 @@ en:
title_waiting_for_approval: Waiting for Approval
title_approved: Approved
title_unlock_file: Unlock to allow changes for other members
title_lock_file: Lock to prevent changes for other members
submit_download: Download
title_download_checked: Download checked in Zip archive
submit_email: Email
title_lock_file: Lock to prevent changes for other members
title_download_checked: Download checked in Zip archive
title_send_checked_by_email: Send checked by email
link_user_preferences: Your DMSF project preferences
heading_send_documents_by_email: Send documents by email
@ -303,6 +301,8 @@ en:
notice_dmsf_file_restored: The document has been successfully restored
notice_dmsf_folder_restored: The folder has been successfully restored
notice_dmsf_link_restored: The link has been successfully restored
title_restore_checked: Restore checked
error_parent_folder: "The parent folder doesn't exist"
my:
blocks:

View File

@ -74,10 +74,8 @@ es:
title_waiting_for_approval: Waiting for Approval
title_approved: Approved
title_unlock_file: Unlock to allow changes for other members
title_lock_file: Lock to prevent changes for other members
submit_download: Download
title_download_checked: Download checked in Zip archive
submit_email: Email
title_lock_file: Lock to prevent changes for other members
title_download_checked: Download checked in Zip archive
title_send_checked_by_email: Send checked by email
link_user_preferences: Your DMSF project preferences
heading_send_documents_by_email: Send documents by email
@ -303,6 +301,8 @@ es:
notice_dmsf_file_restored: The document has been successfully restored
notice_dmsf_folder_restored: The folder has been successfully restored
notice_dmsf_link_restored: The link has been successfully restored
title_restore_checked: Restore checked
error_parent_folder: "The parent folder doesn't exist"
my:
blocks:

View File

@ -74,10 +74,8 @@ fr:
title_waiting_for_approval: Attente de validation
title_approved: Validé
title_unlock_file: Déverrouiller afin de permettre la modification par les membres du projet
title_lock_file: "Verrouiller afin d'empêcher les modifications du document"
submit_download: Télécharger
title_download_checked: Télécharger les fichiers sélectionnés au format zip
submit_email: Email
title_lock_file: "Verrouiller afin d'empêcher les modifications du document"
title_download_checked: Télécharger les fichiers sélectionnés au format zip
title_send_checked_by_email: Transmettre les fichiers sélectionnés par mail
link_user_preferences: Préférences personnelles du module DMSF
heading_send_documents_by_email: Transmettre les documents par mail
@ -303,6 +301,8 @@ fr:
notice_dmsf_file_restored: The document has been successfully restored
notice_dmsf_folder_restored: The folder has been successfully restored
notice_dmsf_link_restored: The link has been successfully restored
title_restore_checked: Restore checked
error_parent_folder: "The parent folder doesn't exist"
my:
blocks:

View File

@ -74,10 +74,8 @@ ja:
title_waiting_for_approval: 承認待ち
title_approved: 承認済み
title_unlock_file: ロック解除して他のメンバーの変更を許可します
title_lock_file: ロックして他のメンバーの変更を禁止します
submit_download: ダウンロード
title_download_checked: チェックしたものを Zip アーカイブでダウンロードします
submit_email: 電子メール
title_lock_file: ロックして他のメンバーの変更を禁止します
title_download_checked: チェックしたものを Zip アーカイブでダウンロードします
title_send_checked_by_email: チェックしたものを電子メールで送信します
link_user_preferences: あなたの DMSF プロジェクト設定
heading_send_documents_by_email: 電子メールによる文書の送信
@ -303,6 +301,8 @@ ja:
notice_dmsf_file_restored: The document has been successfully restored
notice_dmsf_folder_restored: The folder has been successfully restored
notice_dmsf_link_restored: The link has been successfully restored
title_restore_checked: Restore checked
error_parent_folder: "The parent folder doesn't exist"
my:
blocks:

View File

@ -74,10 +74,8 @@ ru:
title_waiting_for_approval: Ожидается на утверждение
title_approved: Утверждено
title_unlock_file: Разблокируйте файл, чтобы разрешить изменение его другими участниками
title_lock_file: Заблокируйте файл, чтобы запретить его изменение другими участниками
submit_download: Скачать
title_download_checked: Скачать выбранные файлы
submit_email: Отправить письмо
title_lock_file: Заблокируйте файл, чтобы запретить его изменение другими участниками
title_download_checked: Скачать выбранные файлы
title_send_checked_by_email: Отправить выбранные файлы по электронной почте
link_user_preferences: Ваши настройки DMSF проекта
heading_send_documents_by_email: Отправить документы по электронной почте
@ -303,6 +301,8 @@ ru:
notice_dmsf_file_restored: The document has been successfully restored
notice_dmsf_folder_restored: The folder has been successfully restored
notice_dmsf_link_restored: The link has been successfully restored
title_restore_checked: Restore checked
error_parent_folder: "The parent folder doesn't exist"
my:
blocks:

View File

@ -74,10 +74,8 @@ sl:
title_waiting_for_approval: V postopku odobritve
title_approved: Odobreno
title_unlock_file: Odkleni drugim članom za posodabljanje
title_lock_file: Zakleni za posodabljanje
submit_download: Prenesi dol
title_download_checked: Prenesi izbrano v Zip formatu
submit_email: Pripni v email
title_lock_file: Zakleni za posodabljanje
title_download_checked: Prenesi izbrano v Zip formatu
title_send_checked_by_email: Pošlji izbrano po elektronski pošti
link_user_preferences: Vaše Arhivske nastavitve za projekt
heading_send_documents_by_email: Pošlji dokumente po elektronski pošti
@ -303,6 +301,8 @@ sl:
notice_dmsf_file_restored: The document has been successfully restored
notice_dmsf_folder_restored: The folder has been successfully restored
notice_dmsf_link_restored: The link has been successfully restored
title_restore_checked: Restore checked
error_parent_folder: "The parent folder doesn't exist"
my:
blocks:

View File

@ -74,10 +74,8 @@ zh:
title_waiting_for_approval: 待批准
title_approved: 已批准
title_unlock_file: 解除锁定允许其他成员修改
title_lock_file: 锁定以防其他成员修改
submit_download: 下载
title_download_checked: zip归档下载所选
submit_email: 电子邮件
title_lock_file: 锁定以防其他成员修改
title_download_checked: zip归档下载所选
title_send_checked_by_email: 电子邮件发送所选
link_user_preferences: 您的文档管理系统项目偏好设定
heading_send_documents_by_email: 电子邮件发送文档
@ -303,6 +301,8 @@ zh:
notice_dmsf_file_restored: The document has been successfully restored
notice_dmsf_folder_restored: The folder has been successfully restored
notice_dmsf_link_restored: The link has been successfully restored
title_restore_checked: Restore checked
error_parent_folder: "The parent folder doesn't exist"
my:
blocks:

View File

@ -33,7 +33,7 @@ class DmsfFileRevisionTest < RedmineDmsf::Test::UnitTest
def test_delete_restore
@revision5.delete false
assert_nil DmsfFileRevision.visible.where(:id => @revision5.id).first
assert_nil DmsfFileRevision.visible.where(:id => @revision5.id).first, @revision5.errors[:base][0]
assert DmsfFileRevision.deleted.where(:id => @revision5.id).first
@revision5.restore
assert_nil DmsfFileRevision.deleted.where(:id => @revision5.id).first

View File

@ -89,7 +89,7 @@ class DmsfFileTest < RedmineDmsf::Test::UnitTest
# Delete
@file4.delete false
assert_nil DmsfFile.visible.where(:id => @file4.id).first
assert_nil DmsfFile.visible.where(:id => @file4.id).first, @file4.errors[:base][0]
assert DmsfFile.deleted.where(:id => @file4.id).first
assert_equal 0, @file4.revisions.visible.count
assert_equal 0, @file4.referenced_links.visible.count

View File

@ -34,7 +34,7 @@ class DmsfFolderTest < RedmineDmsf::Test::UnitTest
def test_delete_restore
assert_equal 1, @folder4.referenced_links.visible.count
@folder4.delete false
assert_nil DmsfFolder.visible.where(:id => @folder4.id).first
assert_nil DmsfFolder.visible.where(:id => @folder4.id).first, @folder4.errors[:base][0]
assert DmsfFolder.deleted.where(:id => @folder4.id).first
assert_equal 0, @folder4.referenced_links.visible.count
@folder4.restore

View File

@ -167,7 +167,7 @@ class DmsfLinksTest < RedmineDmsf::Test::UnitTest
def test_delete_restore
# File link
@file_link.delete false
assert_nil DmsfLink.visible.where(:id => @file_link.id).first
assert_nil DmsfLink.visible.where(:id => @file_link.id).first, @file_link.errors[:base][0]
assert DmsfLink.deleted.where(:id => @file_link.id).first
@file_link.restore
assert_nil DmsfLink.deleted.where(:id => @file_link.id).first