mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-01-27 01:59:28 +08:00
Merge pull request #3113 from mlorb/ml-sci-5311
Implement the option of deleting empty folders [SCI-5311]
This commit is contained in:
commit
20dc9967f5
11 changed files with 136 additions and 4 deletions
|
@ -7,10 +7,10 @@
|
|||
// - refresh project users tab after manage user modal is closed
|
||||
// - refactor view handling using library, ex. backbone.js
|
||||
|
||||
/* global animateSpinner HelperModule dropdownSelector Sidebar Turbolinks filterDropdown */
|
||||
/* global HelperModule dropdownSelector Sidebar Turbolinks filterDropdown */
|
||||
|
||||
(function() {
|
||||
const PERMISSIONS = ['editable', 'archivable', 'restorable', 'moveable'];
|
||||
const PERMISSIONS = ['editable', 'archivable', 'restorable', 'moveable', 'deletable'];
|
||||
var projectsWrapper = '#projectsWrapper';
|
||||
var toolbarWrapper = '#toolbarWrapper';
|
||||
var cardsWrapper = '#cardsWrapper';
|
||||
|
@ -97,6 +97,42 @@
|
|||
});
|
||||
}
|
||||
|
||||
// init delete project folders
|
||||
function initDeleteFoldersToolbarButton() {
|
||||
$(projectsWrapper)
|
||||
.on('ajax:before', '.delete-folders-btn', function() {
|
||||
let buttonForm = $(this);
|
||||
buttonForm.find('input[name="project_folders_ids[]"]').remove();
|
||||
selectedProjectFolders.forEach(function(id) {
|
||||
$('<input>').attr({
|
||||
type: 'hidden',
|
||||
name: 'project_folders_ids[]',
|
||||
value: id
|
||||
}).appendTo(buttonForm);
|
||||
});
|
||||
})
|
||||
.on('ajax:success', '.delete-folders-btn', function(ev, data) {
|
||||
// Add and show modal
|
||||
let deleteModal = $(data.html);
|
||||
$(projectsWrapper).append(deleteModal);
|
||||
deleteModal.modal('show');
|
||||
// Remove modal when it gets closed
|
||||
deleteModal.on('hidden.bs.modal', function() {
|
||||
$(this).remove();
|
||||
});
|
||||
});
|
||||
|
||||
$(projectsWrapper)
|
||||
.on('ajax:success', '.delete-folders-form', function(ev, data) {
|
||||
$('.modal-project-folder-delete').modal('hide');
|
||||
HelperModule.flashAlertMsg(data.message, 'success');
|
||||
refreshCurrentView();
|
||||
})
|
||||
.on('ajax:error', '.delete-folders-form', function(ev, data) {
|
||||
HelperModule.flashAlertMsg(data.responseJSON.message, 'danger');
|
||||
});
|
||||
}
|
||||
|
||||
// init project toolbar archive/restore functions
|
||||
function initArchiveRestoreToolbarButtons() {
|
||||
$(projectsWrapper)
|
||||
|
@ -322,6 +358,8 @@
|
|||
projectsToolbar.find('.single-object-action, .multiple-object-action').removeClass('hidden');
|
||||
if (selectedProjectFolders.length === 1) {
|
||||
projectsToolbar.find('.project-only-action').addClass('hidden');
|
||||
} else {
|
||||
projectsToolbar.find('.folders-only-action').addClass('hidden');
|
||||
}
|
||||
} else {
|
||||
projectsToolbar.find('.single-object-action').addClass('hidden');
|
||||
|
@ -329,6 +367,9 @@
|
|||
if (selectedProjectFolders.length > 0) {
|
||||
projectsToolbar.find('.project-only-action').addClass('hidden');
|
||||
}
|
||||
if (selectedProjects.length > 0) {
|
||||
projectsToolbar.find('.folder-only-action').addClass('hidden');
|
||||
}
|
||||
}
|
||||
PERMISSIONS.forEach((permission) => {
|
||||
if (!checkActionPermission(permission)) {
|
||||
|
@ -637,6 +678,7 @@
|
|||
initManageUsersModal();
|
||||
initExportProjectsModal();
|
||||
initExportProjects();
|
||||
initDeleteFoldersToolbarButton();
|
||||
initArchiveRestoreToolbarButtons();
|
||||
initViewProjectUsersLink();
|
||||
initManageProjectUsersLink();
|
||||
|
|
|
@ -475,6 +475,11 @@ li.module-hover {
|
|||
}
|
||||
}
|
||||
|
||||
.delete-folders-form,
|
||||
.delete-folders-btn {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.filter-container {
|
||||
.projects-filters {
|
||||
.select-block {
|
||||
|
|
|
@ -96,6 +96,35 @@ class ProjectFoldersController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def destroy_modal
|
||||
render json: {
|
||||
html: render_to_string(partial: 'projects/index/modals/project_folder_delete.html.erb',
|
||||
locals: { project_folders_ids: params[:project_folders_ids] })
|
||||
}
|
||||
end
|
||||
|
||||
def destroy
|
||||
project_folders = current_team.project_folders.where(id: params[:project_folders_ids])
|
||||
counter = 0
|
||||
project_folders.each do |folder|
|
||||
next if folder.projects.exists? || folder.project_folders.exists? || !can_update_team?(current_team)
|
||||
|
||||
folder.transaction do
|
||||
log_activity(:delete_project_folder, folder, project_folder: folder.id)
|
||||
folder.destroy!
|
||||
counter += 1
|
||||
rescue StandardError => e
|
||||
Rails.logger.error e.message
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
if counter.positive?
|
||||
render json: { message: t('projects.delete_folders.success_flash', number: counter) }
|
||||
else
|
||||
render json: { message: t('projects.delete_folders.error_flash') }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_project_folder
|
||||
|
|
|
@ -97,3 +97,10 @@ Canaid::Permissions.register_for(ProjectComment) do
|
|||
user.is_owner_of_project?(project_comment.project))
|
||||
end
|
||||
end
|
||||
|
||||
Canaid::Permissions.register_for(ProjectFolder) do
|
||||
# ProjectFolder: delete
|
||||
can :delete_project_folder do |_, project_folder|
|
||||
!project_folder.projects.exists? && !project_folder.project_folders.exists?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
data-editable="<%= can_update_team?(current_team) %>"
|
||||
data-moveable="<%= can_update_team?(current_team) %>"
|
||||
data-archivable="false"
|
||||
data-restorable="false">
|
||||
data-restorable="false"
|
||||
data-deletable="<%= can_delete_project_folder?(folder) && can_update_team?(current_team) %>">
|
||||
<div class="checkbox-cell table-cell">
|
||||
<div class="sci-checkbox-container">
|
||||
<input value="1" type="checkbox" class="sci-checkbox folder-card-selector">
|
||||
|
|
|
@ -46,6 +46,15 @@
|
|||
<span class="fas fa-undo" aria-hidden="true"></span>
|
||||
<span class="hidden-xs"><%= t('projects.index.restore_button') %></span>
|
||||
<% end %>
|
||||
<%= button_to destroy_modal_project_folders_url,
|
||||
class: 'btn btn-light multiple-object-action folders-only-action hidden',
|
||||
form_class: 'delete-folders-btn',
|
||||
data: { for: :deletable },
|
||||
remote: true,
|
||||
method: :post do %>
|
||||
<span class="fas fa-trash" aria-hidden="true"></span>
|
||||
<span class="hidden-xs"><%= t('projects.index.delete_button') %></span>
|
||||
<% end %>
|
||||
<!-- export projects button -->
|
||||
<a href="#" class="btn btn-light export-projects-btn multiple-object-action hidden"
|
||||
data-export-projects-modal-url="<%= export_projects_modal_team_path(current_team) %>">
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<div class="modal modal-project-folder-delete" role="dialog" aria-hidden="true" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h2 class="modal-title"><%= t('projects.index.modal_delete_folders.title') %></h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p><%= t('projects.index.modal_delete_folders.description_1_html', number: project_folders_ids.size) %></p>
|
||||
<p><%= t('projects.index.modal_delete_folders.description_2') %></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type='button' class='btn btn-default' data-dismiss='modal'><%= t('general.cancel')%></button>
|
||||
<%= button_to t('projects.index.modal_delete_folders.confirm_button'),
|
||||
destroy_project_folders_path,
|
||||
class: 'btn btn-danger',
|
||||
form_class: 'delete-folders-form',
|
||||
params: { project_folders_ids: project_folders_ids },
|
||||
remote: true %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -380,7 +380,8 @@ class Extends
|
|||
move_project: 158,
|
||||
create_project_folder: 159,
|
||||
move_project_folder: 160,
|
||||
rename_project_folder: 161
|
||||
rename_project_folder: 161,
|
||||
delete_project_folder: 162
|
||||
}
|
||||
|
||||
ACTIVITY_GROUPS = {
|
||||
|
|
|
@ -369,6 +369,7 @@ en:
|
|||
move_button: "Move"
|
||||
archive_button: "Archive"
|
||||
restore_button: "Restore"
|
||||
delete_button: "Delete"
|
||||
edit_option: "Edit"
|
||||
archive_option: "Archive"
|
||||
archive_confirm: "Are you sure you want to archive this project?"
|
||||
|
@ -417,6 +418,11 @@ en:
|
|||
projects: 'projects'
|
||||
folders: 'folders'
|
||||
projects_and_folders: 'projects & folders'
|
||||
modal_delete_folders:
|
||||
title: "Delete project folder(s)"
|
||||
description_1_html: "You are about to delete <strong>%{number}</strong> selected project folder(s)"
|
||||
description_2: "Are you sure you want to continue?"
|
||||
confirm_button: "Delete folder(s)"
|
||||
modal_manage_users:
|
||||
modal_title: "Manage users for %{name}"
|
||||
no_users: "No users!"
|
||||
|
@ -472,6 +478,9 @@ en:
|
|||
restore:
|
||||
success_flash: "Project <strong>%{name}</strong> successfully restored."
|
||||
error_flash: "Project <strong>%{name}</strong> not restored."
|
||||
delete_folders:
|
||||
success_flash: "<strong>%{number}</strong> project folder(s) successfully deleted."
|
||||
error_flash: "Failed to delete project folder(s)."
|
||||
show:
|
||||
head_title: "%{project}"
|
||||
reports:
|
||||
|
|
|
@ -180,6 +180,7 @@ en:
|
|||
|
||||
create_project_folder_html: "%{user} created project folder %{project_folder}."
|
||||
rename_project_folder_html: "%{user} renamed project folder %{project_folder}."
|
||||
delete_project_folder_html: "%{user} deleted project folder %{project_folder}."
|
||||
move_project_folder_html: "%{user} moved folder %{project_folder} from folder %{project_folder_from}</strong> to folder %{project_folder_to}."
|
||||
|
||||
activity_name:
|
||||
|
@ -325,6 +326,7 @@ en:
|
|||
move_project: "Project moved"
|
||||
create_project_folder: "Project folder created"
|
||||
rename_project_folder: "Project folder renamed"
|
||||
delete_project_folder: "Project folder deleted"
|
||||
move_project_folder: "Project folder moved"
|
||||
|
||||
activity_group:
|
||||
|
|
|
@ -310,6 +310,8 @@ Rails.application.routes.draw do
|
|||
collection do
|
||||
post 'move_to', to: 'project_folders#move_to', defaults: { format: 'json' }
|
||||
get 'move_to_modal', to: 'project_folders#move_to_modal', defaults: { format: 'json' }
|
||||
post 'destroy', to: 'project_folders#destroy', as: 'destroy', defaults: { format: 'json' }
|
||||
post 'destroy_modal', to: 'project_folders#destroy_modal', defaults: { format: 'json' }
|
||||
end
|
||||
end
|
||||
get 'project_folders/:project_folder_id', to: 'projects#index', as: :project_folder_projects
|
||||
|
|
Loading…
Reference in a new issue