Add multiple file/directory deletion in the filemanager (#544)
* Add deletion of multiple selected files * Adjust success/failure text to properly represent multiple files * Actually update the minimized versions with the new code * Use let instead of var and seperate items into seperate code tags * Deleting the selected items now supports the new endpoint * Replaced the select buttons with checkboxes * Selections is now handled by find all the selected checkboxes * Add a warning if no files/folders are selected when pressing delete * Add a select all files/folders checkbox * Move mass delete button into a mass actions dropdown * Move style to css file * Actually update the minimized files (again) * Mass actions button is now disabled by default * Clicking on a row selects the checkbox and enables the actions button * Fix clicking anything else but the row or checkbox triggering selection
This commit is contained in:
parent
0def41740a
commit
e64eb4901e
7 changed files with 203 additions and 13 deletions
|
@ -292,12 +292,17 @@ class ActionsClass {
|
|||
showLoaderOnConfirm: true
|
||||
}, () => {
|
||||
$.ajax({
|
||||
type: 'DELETE',
|
||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/server/file/f/${delPath}${delName}`,
|
||||
type: 'POST',
|
||||
headers: {
|
||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
||||
'X-Access-Server': Pterodactyl.server.uuid,
|
||||
}
|
||||
},
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/server/file/delete`,
|
||||
timeout: 10000,
|
||||
data: JSON.stringify({
|
||||
items: [`${delPath}${delName}`]
|
||||
}),
|
||||
}).done(data => {
|
||||
nameBlock.parent().addClass('warning').delay(200).fadeOut();
|
||||
swal({
|
||||
|
@ -316,6 +321,125 @@ class ActionsClass {
|
|||
});
|
||||
}
|
||||
|
||||
toggleMassActions() {
|
||||
if ($('#file_listing input[type="checkbox"]:checked').length) {
|
||||
$('#mass_actions').removeClass('disabled');
|
||||
} else {
|
||||
$('#mass_actions').addClass('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
toggleHighlight(event) {
|
||||
const parent = $(event.currentTarget);
|
||||
const item = $(event.currentTarget).find('input');
|
||||
|
||||
if($(item).is(':checked')) {
|
||||
$(item).prop('checked', false);
|
||||
parent.removeClass('warning').delay(200);
|
||||
} else {
|
||||
$(item).prop('checked', true);
|
||||
parent.addClass('warning').delay(200);
|
||||
}
|
||||
}
|
||||
|
||||
highlightAll(event) {
|
||||
let parent;
|
||||
const item = $(event.currentTarget).find('input');
|
||||
|
||||
if($(item).is(':checked')) {
|
||||
$('#file_listing input[type=checkbox]').prop('checked', false);
|
||||
$('#file_listing input[data-action="addSelection"]').each(function() {
|
||||
parent = $(this).closest('tr');
|
||||
parent.removeClass('warning').delay(200);
|
||||
});
|
||||
} else {
|
||||
$('#file_listing input[type=checkbox]').prop('checked', true);
|
||||
$('#file_listing input[data-action="addSelection"]').each(function() {
|
||||
parent = $(this).closest('tr');
|
||||
parent.addClass('warning').delay(200);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
deleteSelected() {
|
||||
let selectedItems = [];
|
||||
let selectedItemsElements = [];
|
||||
let parent;
|
||||
let nameBlock;
|
||||
let delLocation;
|
||||
|
||||
$('#file_listing input[data-action="addSelection"]:checked').each(function() {
|
||||
parent = $(this).closest('tr');
|
||||
nameBlock = $(parent).find('td[data-identifier="name"]');
|
||||
delLocation = decodeURIComponent(nameBlock.data('path')) + decodeURIComponent(nameBlock.data('name'));
|
||||
|
||||
selectedItems.push(delLocation);
|
||||
selectedItemsElements.push(parent);
|
||||
});
|
||||
|
||||
if (selectedItems.length != 0)
|
||||
{
|
||||
let formattedItems = "";
|
||||
$.each(selectedItems, function(key, value) {
|
||||
formattedItems += ("<code>" + value + "</code>, ");
|
||||
})
|
||||
|
||||
formattedItems = formattedItems.slice(0, -2);
|
||||
|
||||
swal({
|
||||
type: 'warning',
|
||||
title: '',
|
||||
text: 'Are you sure you want to delete:' + formattedItems + '? There is <strong>no</strong> reversing this action.',
|
||||
html: true,
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
closeOnConfirm: false,
|
||||
showLoaderOnConfirm: true
|
||||
}, () => {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
headers: {
|
||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
||||
'X-Access-Server': Pterodactyl.server.uuid,
|
||||
},
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/server/file/delete`,
|
||||
timeout: 10000,
|
||||
data: JSON.stringify({
|
||||
items: selectedItems
|
||||
}),
|
||||
}).done(data => {
|
||||
$('#file_listing input:checked').each(function() {
|
||||
$(this).prop('checked', false);
|
||||
});
|
||||
|
||||
$.each(selectedItemsElements, function() {
|
||||
$(this).addClass('warning').delay(200).fadeOut();
|
||||
})
|
||||
|
||||
swal({
|
||||
type: 'success',
|
||||
title: 'Files Deleted'
|
||||
});
|
||||
}).fail(jqXHR => {
|
||||
console.error(jqXHR);
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Whoops!',
|
||||
html: true,
|
||||
text: 'An error occured while attempting to delete these files. Please try again.',
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
swal({
|
||||
type: 'warning',
|
||||
title: '',
|
||||
text: 'Please select files/folders to delete.',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
decompress() {
|
||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
||||
const compPath = decodeURIComponent(nameBlock.data('path'));
|
||||
|
|
|
@ -45,6 +45,10 @@ class FileManager {
|
|||
ContextMenu.run();
|
||||
this.reloadFilesButton();
|
||||
this.addFolderButton();
|
||||
this.selectItem();
|
||||
this.selectAll();
|
||||
this.selectiveDeletion();
|
||||
this.selectRow();
|
||||
if (_.isFunction(next)) {
|
||||
return next();
|
||||
}
|
||||
|
@ -83,12 +87,42 @@ class FileManager {
|
|||
});
|
||||
}
|
||||
|
||||
selectItem() {
|
||||
$('[data-action="addSelection"]').on('click', event => {
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
selectAll() {
|
||||
$('[data-action="selectAll"]').on('click', event => {
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
selectiveDeletion() {
|
||||
$('[data-action="selective-deletion"]').on('mousedown', event => {
|
||||
new ActionsClass().deleteSelected();
|
||||
});
|
||||
}
|
||||
|
||||
addFolderButton() {
|
||||
$('[data-action="add-folder"]').unbind().on('click', () => {
|
||||
new ActionsClass().folder($('#file_listing').data('current-dir') || '/');
|
||||
})
|
||||
}
|
||||
|
||||
selectRow() {
|
||||
$('#file_listing tr').on('mousedown', event => {
|
||||
if($(event.target).is('th') || $(event.target).is('input[data-action="selectAll"]')) {
|
||||
new ActionsClass().highlightAll(event);
|
||||
} else if($(event.target).is('td') || $(event.target).is('input[data-action="addSelection"]')) {
|
||||
new ActionsClass().toggleHighlight(event);
|
||||
}
|
||||
|
||||
new ActionsClass().toggleMassActions();
|
||||
});
|
||||
}
|
||||
|
||||
decodeHash() {
|
||||
return decodeURIComponent(window.location.hash.substring(1));
|
||||
}
|
||||
|
|
Reference in a new issue