Added a new action menu in files and trash list.
Uses the new file-multi-select-menu component. Towards #7647 Signed-off-by: Abijeet <abijeetpatro@gmail.com>
This commit is contained in:
parent
174ba1f012
commit
45db89f3e6
|
@ -169,13 +169,16 @@ table.multiselect th a {
|
|||
color: #000;
|
||||
}
|
||||
table th .columntitle {
|
||||
display: inline-block;
|
||||
display: block;
|
||||
padding: 15px;
|
||||
height: 50px;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
}
|
||||
table.multiselect th .columntitle {
|
||||
display: inline-block;
|
||||
}
|
||||
table th .columntitle.name {
|
||||
padding-left: 5px;
|
||||
margin-left: 50px;
|
||||
|
@ -482,9 +485,7 @@ a.action > img {
|
|||
line-height: 50px;
|
||||
padding: 18px 5px;
|
||||
}
|
||||
.selectedActions a.delete-selected {
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
.selectedActions a.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
@ -493,10 +494,6 @@ a.action > img {
|
|||
vertical-align: text-bottom;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
/* hide the delete icon in name column normal resolutions */
|
||||
table th#headerName .selectedActions .delete-selected {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#fileList td a {
|
||||
a.action {
|
||||
|
|
|
@ -28,7 +28,7 @@ table td {
|
|||
table.multiselect thead {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
|
||||
#fileList a.action.action-menu img {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
@ -41,10 +41,6 @@ table.multiselect thead {
|
|||
display: none !important;
|
||||
}
|
||||
|
||||
/* show the delete icon in name column in lower resolutions */
|
||||
table th#headerName .selectedActions .delete-selected {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/* proper notification area for multi line messages */
|
||||
#notification-container {
|
||||
|
@ -70,8 +66,14 @@ table.dragshadow {
|
|||
|
||||
}
|
||||
@media only screen and (max-width: 480px) {
|
||||
table thead {
|
||||
width: 100% !important;
|
||||
}
|
||||
/* Only show icons */
|
||||
table th .selectedActions a span:not(.icon) {
|
||||
table th .selectedActions {
|
||||
float: right;
|
||||
}
|
||||
table th .selectedActions > a span:not(.icon) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,23 @@
|
|||
allowLegacyActions: true,
|
||||
scrollTo: urlParams.scrollto,
|
||||
filesClient: OC.Files.getClient(),
|
||||
multiSelectMenu: [
|
||||
{
|
||||
name: 'moveCopy',
|
||||
displayName: t('files', 'Move or copy'),
|
||||
iconClass: 'icon-external',
|
||||
},
|
||||
{
|
||||
name: 'download',
|
||||
displayName: t('files', 'Download'),
|
||||
iconClass: 'icon-download',
|
||||
},
|
||||
{
|
||||
name: 'delete',
|
||||
displayName: t('files', 'Delete'),
|
||||
iconClass: 'icon-delete',
|
||||
}
|
||||
],
|
||||
sorting: {
|
||||
mode: $('#defaultFileSorting').val(),
|
||||
direction: $('#defaultFileSortingDirection').val()
|
||||
|
@ -130,7 +147,7 @@
|
|||
window.FileActions.off('registerAction.app-files', this._onActionsUpdated);
|
||||
},
|
||||
|
||||
_onActionsUpdated: function(ev, newAction) {
|
||||
_onActionsUpdated: function(ev) {
|
||||
// forward new action to the file list
|
||||
if (ev.action) {
|
||||
this.fileList.fileActions.registerAction(ev.action);
|
||||
|
|
|
@ -692,21 +692,21 @@
|
|||
OCA.Files.FileActions = FileActions;
|
||||
|
||||
/**
|
||||
* Replaces the download icon with a loading spinner and vice versa
|
||||
* Replaces the button icon with a loading spinner and vice versa
|
||||
* - also adds the class disabled to the passed in element
|
||||
*
|
||||
* @param {jQuery} $downloadButtonElement download fileaction
|
||||
* @param {jQuery} $buttonElement The button element
|
||||
* @param {boolean} showIt whether to show the spinner(true) or to hide it(false)
|
||||
*/
|
||||
OCA.Files.FileActions.updateFileActionSpinner = function($downloadButtonElement, showIt) {
|
||||
var $icon = $downloadButtonElement.find('.icon');
|
||||
OCA.Files.FileActions.updateFileActionSpinner = function($buttonElement, showIt) {
|
||||
var $icon = $buttonElement.find('.icon');
|
||||
if (showIt) {
|
||||
var $loadingIcon = $('<span class="icon icon-loading-small"></span>');
|
||||
$icon.after($loadingIcon);
|
||||
$icon.addClass('hidden');
|
||||
} else {
|
||||
$downloadButtonElement.find('.icon-loading-small').remove();
|
||||
$downloadButtonElement.find('.icon').removeClass('hidden');
|
||||
$buttonElement.find('.icon-loading-small').remove();
|
||||
$buttonElement.find('.icon').removeClass('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@
|
|||
* File selection menu, defaults to OCA.Files.FileSelectionMenu
|
||||
* @type OCA.Files.FileSelectionMenu
|
||||
*/
|
||||
fileSelectionMenu: null,
|
||||
fileMultiSelectMenu: null,
|
||||
/**
|
||||
* Whether selection is allowed, checkboxes and selection overlay will
|
||||
* be rendered
|
||||
|
@ -293,27 +293,10 @@
|
|||
|
||||
this.fileSummary = this._createSummary();
|
||||
|
||||
this.fileSelectionMenu = new OCA.Files.FileSelectionMenu([
|
||||
{
|
||||
name: 'moveCopy',
|
||||
displayName: t('files', 'Move or copy'),
|
||||
iconClass: 'icon-external',
|
||||
method: _.bind(this._onClickCopyMoveSelected, this)
|
||||
},
|
||||
{
|
||||
name: 'download',
|
||||
displayName: t('files', 'Download'),
|
||||
iconClass: 'icon-download',
|
||||
method: _.bind(this._onClickDownloadSelected, this)
|
||||
},
|
||||
{
|
||||
name: 'delete',
|
||||
displayName: t('files', 'Delete'),
|
||||
iconClass: 'icon-delete',
|
||||
method: _.bind(this._onClickDeleteSelected, this)
|
||||
}
|
||||
]);
|
||||
this.$el.find('#selectedActionsList').append(this.fileSelectionMenu.$el);
|
||||
if (options.multiSelectMenu) {
|
||||
this.fileMultiSelectMenu = new OCA.Files.FileMultiSelectMenu(options.multiSelectMenu);
|
||||
this.$el.find('#selectedActionsList').append(this.fileMultiSelectMenu.$el);
|
||||
}
|
||||
|
||||
if (options.sorting) {
|
||||
this.setSort(options.sorting.mode, options.sorting.direction, false, false);
|
||||
|
@ -363,16 +346,11 @@
|
|||
this.$el.on('show', _.bind(this._onShow, this));
|
||||
this.$el.on('urlChanged', _.bind(this._onUrlChanged, this));
|
||||
this.$el.find('.select-all').click(_.bind(this._onClickSelectAll, this));
|
||||
this.$el.find('.download').click(_.bind(this._onClickDownloadSelected, this));
|
||||
this.$el.find('.copy-move').click(_.bind(this._onClickCopyMoveSelected, this));
|
||||
this.$el.find('.delete-selected').click(_.bind(this._onClickDeleteSelected, this));
|
||||
this.$el.find('.actions-selected').click(function () {
|
||||
self.fileSelectionMenu.show(self);
|
||||
self.fileMultiSelectMenu.show(self);
|
||||
return false;
|
||||
});
|
||||
|
||||
this.$el.find('.selectedActions a').tooltip({placement:'top'});
|
||||
|
||||
this.$container.on('scroll', _.bind(this._onScroll, this));
|
||||
|
||||
if (options.scrollTo) {
|
||||
|
@ -420,6 +398,22 @@
|
|||
$('#app-content').off('appresized', this._onResize);
|
||||
},
|
||||
|
||||
multiSelectMenuClick: function (ev, action) {
|
||||
switch (action) {
|
||||
case 'delete':
|
||||
this._onClickDeleteSelected(ev)
|
||||
break;
|
||||
case 'download':
|
||||
this._onClickDownloadSelected(ev);
|
||||
break;
|
||||
case 'moveCopy':
|
||||
this._onClickCopyMoveSelected(ev);
|
||||
break;
|
||||
case 'restore':
|
||||
this._onClickRestoreSelected(ev);
|
||||
break;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Initializes the file actions, set up listeners.
|
||||
*
|
||||
|
@ -775,9 +769,11 @@
|
|||
/**
|
||||
* Event handler for when clicking on "Download" for the selected files
|
||||
*/
|
||||
_onClickDownloadSelected: function(event) {
|
||||
_onClickDownloadSelected: function() {
|
||||
var files;
|
||||
var self = this;
|
||||
var dir = this.getCurrentDirectory();
|
||||
|
||||
if (this.isAllSelected() && this.getSelectedFiles().length > 1) {
|
||||
files = OC.basename(dir);
|
||||
dir = OC.dirname(dir) || '/';
|
||||
|
@ -786,20 +782,16 @@
|
|||
files = _.pluck(this.getSelectedFiles(), 'name');
|
||||
}
|
||||
|
||||
// TODO: Update
|
||||
var downloadFileaction = $('#selectedActionsList').find('.download');
|
||||
|
||||
// don't allow a second click on the download action
|
||||
if(downloadFileaction.hasClass('disabled')) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
if(this.fileMultiSelectMenu.isDisabled('download')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.fileMultiSelectMenu.toggleLoading('download', true);
|
||||
var disableLoadingState = function(){
|
||||
OCA.Files.FileActions.updateFileActionSpinner(downloadFileaction, false);
|
||||
self.fileMultiSelectMenu.toggleLoading('download', false);
|
||||
};
|
||||
|
||||
OCA.Files.FileActions.updateFileActionSpinner(downloadFileaction, true);
|
||||
if(this.getSelectedFiles().length > 1) {
|
||||
OCA.Files.Files.handleDownload(this.getDownloadUrl(files, dir, true), disableLoadingState);
|
||||
}
|
||||
|
@ -813,23 +805,20 @@
|
|||
/**
|
||||
* Event handler for when clicking on "Move" for the selected files
|
||||
*/
|
||||
_onClickCopyMoveSelected: function(event) {
|
||||
_onClickCopyMoveSelected: function() {
|
||||
var files;
|
||||
var self = this;
|
||||
|
||||
files = _.pluck(this.getSelectedFiles(), 'name');
|
||||
|
||||
// TODO: Update
|
||||
var moveFileAction = $('#selectedActionsList').find('.move');
|
||||
|
||||
// don't allow a second click on the download action
|
||||
if(moveFileAction.hasClass('disabled')) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
if(this.fileMultiSelectMenu.isDisabled('moveCopy')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.fileMultiSelectMenu.toggleLoading('moveCopy', true);
|
||||
var disableLoadingState = function(){
|
||||
OCA.Files.FileActions.updateFileActionSpinner(moveFileAction, false);
|
||||
self.fileMultiSelectMenu.toggleLoading('moveCopy', false);
|
||||
};
|
||||
|
||||
var actions = this.isSelectedMovable() ? OC.dialogs.FILEPICKER_TYPE_COPY_MOVE : OC.dialogs.FILEPICKER_TYPE_COPY;
|
||||
|
@ -847,7 +836,7 @@
|
|||
/**
|
||||
* Event handler for when clicking on "Delete" for the selected files
|
||||
*/
|
||||
_onClickDeleteSelected: function(event) {
|
||||
_onClickDeleteSelected: function() {
|
||||
var files = null;
|
||||
if (!this.isAllSelected()) {
|
||||
files = _.pluck(this.getSelectedFiles(), 'name');
|
||||
|
@ -2922,14 +2911,14 @@
|
|||
this.$el.find('table').addClass('multiselect');
|
||||
|
||||
|
||||
this.fileSelectionMenu.toggleItemVisibility('download', !this.isSelectedDownloadable());
|
||||
this.fileSelectionMenu.toggleItemVisibility('delete', !this.isSelectedDeletable());
|
||||
this.fileSelectionMenu.toggleItemVisibility('moveCopy', !this.isSelectedCopiable());
|
||||
this.fileMultiSelectMenu.toggleItemVisibility('download', !this.isSelectedDownloadable());
|
||||
this.fileMultiSelectMenu.toggleItemVisibility('delete', !this.isSelectedDeletable());
|
||||
this.fileMultiSelectMenu.toggleItemVisibility('moveCopy', !this.isSelectedCopiable());
|
||||
if (this.isSelectedCopiable()) {
|
||||
if (this.isSelectedMovable()) {
|
||||
this.fileSelectionMenu.updateItemText('moveCopy', t('files', 'Move or copy'));
|
||||
this.fileMultiSelectMenu.updateItemText('moveCopy', t('files', 'Move or copy'));
|
||||
} else {
|
||||
this.fileSelectionMenu.updateItemText('moveCopy', t('files', 'Copy'));
|
||||
this.fileMultiSelectMenu.updateItemText('moveCopy', t('files', 'Copy'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,45 +20,15 @@
|
|||
'<span class="no-icon"></span>' +
|
||||
'{{/if}}' +
|
||||
'<span class="label">{{displayName}}</span>' +
|
||||
'</li>' +
|
||||
'</a></li>' +
|
||||
'{{/each}}' +
|
||||
'</ul>';
|
||||
|
||||
var FileSelectionMenu = OC.Backbone.View.extend({
|
||||
var FileMultiSelectMenu = OC.Backbone.View.extend({
|
||||
tagName: 'div',
|
||||
className: 'filesSelectMenu popovermenu bubble menu-center',
|
||||
_scopes: null,
|
||||
/**
|
||||
* Event handler whenever an action has been clicked within the menu
|
||||
*
|
||||
* @param {Object} event event object
|
||||
*/
|
||||
_onClickAction: function(event) {
|
||||
var $target = $(event.currentTarget);
|
||||
if (!$target.hasClass('menuitem')) {
|
||||
$target = $target.closest('.menuitem');
|
||||
}
|
||||
|
||||
OC.hideMenus();
|
||||
|
||||
var action = $target.data('action');
|
||||
if (!action) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i !== this._scopes.length; ++i) {
|
||||
var name = this._scopes[i].name;
|
||||
var method = this._scopes[i].method;
|
||||
if (name === action) {
|
||||
method(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
initialize: function(menuItems) {
|
||||
console.log('init-fileseleectionmenu');
|
||||
console.log(menuItems);
|
||||
this._scopes = menuItems;
|
||||
},
|
||||
events: {
|
||||
|
@ -84,7 +54,11 @@
|
|||
|
||||
this.render();
|
||||
this.$el.removeClass('hidden');
|
||||
|
||||
if (window.innerWidth < 480) {
|
||||
this.$el.removeClass('menu-center').addClass('menu-right');
|
||||
} else {
|
||||
this.$el.removeClass('menu-right').addClass('menu-center');
|
||||
}
|
||||
OC.showMenu(null, this.$el);
|
||||
return false;
|
||||
},
|
||||
|
@ -93,8 +67,44 @@
|
|||
},
|
||||
updateItemText: function (itemName, translation) {
|
||||
this.$el.find('.item-' + itemName).find('label').text(translation);
|
||||
},
|
||||
toggleLoading: function (itemName, showLoading) {
|
||||
var $actionElement = this.$el.find('.item-' + itemName);
|
||||
if ($actionElement.length === 0) {
|
||||
return;
|
||||
}
|
||||
var $icon = $actionElement.find('.icon');
|
||||
if (showLoading) {
|
||||
var $loadingIcon = $('<span class="icon icon-loading-small"></span>');
|
||||
$icon.after($loadingIcon);
|
||||
$icon.addClass('hidden');
|
||||
$actionElement.addClass('disabled');
|
||||
} else {
|
||||
$actionElement.find('.icon-loading-small').remove();
|
||||
$actionElement.find('.icon').removeClass('hidden');
|
||||
$actionElement.removeClass('disabled');
|
||||
}
|
||||
},
|
||||
isDisabled: function (itemName) {
|
||||
var $actionElement = this.$el.find('.item-' + itemName);
|
||||
return $actionElement.hasClass('disabled');
|
||||
},
|
||||
/**
|
||||
* Event handler whenever an action has been clicked within the menu
|
||||
*
|
||||
* @param {Object} event event object
|
||||
*/
|
||||
_onClickAction: function (event) {
|
||||
var $target = $(event.currentTarget);
|
||||
if (!$target.hasClass('menuitem')) {
|
||||
$target = $target.closest('.menuitem');
|
||||
}
|
||||
|
||||
OC.hideMenus();
|
||||
this._context.multiSelectMenuClick(event, $target.data('action'));
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
OCA.Files.FileSelectionMenu = FileSelectionMenu;
|
||||
})(OC, OCA);
|
||||
OCA.Files.FileMultiSelectMenu = FileMultiSelectMenu;
|
||||
})(OC, OCA);
|
|
@ -6,7 +6,7 @@
|
|||
"jquery-visibility.js",
|
||||
"fileinfomodel.js",
|
||||
"filesummary.js",
|
||||
"fileselectionmenu.js",
|
||||
"filemultiselectmenu.js",
|
||||
"breadcrumb.js",
|
||||
"filelist.js",
|
||||
"search.js",
|
||||
|
|
|
@ -28,10 +28,12 @@
|
|||
<a id="modified" class="columntitle"
|
||||
data-sort="mtime"><span><?php p($l->t('Modified')); ?></span><span
|
||||
class="sort-indicator"></span></a>
|
||||
<span class="selectedActions"><a href="" class="delete-selected">
|
||||
<span><?php p($l->t('Delete')) ?></span>
|
||||
<span class="icon icon-delete"></span>
|
||||
</a></span>
|
||||
<span class="selectedActions">
|
||||
<a href="" class="delete-selected">
|
||||
<span class="icon icon-delete"></span>
|
||||
<span><?php p($l->t('Delete')) ?></span>
|
||||
</a>
|
||||
</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
<h2><?php p($l->t('No entries found in this folder')); ?></h2>
|
||||
<p></p>
|
||||
</div>
|
||||
|
||||
<table id="filestable">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -27,11 +26,13 @@
|
|||
</th>
|
||||
<th id="headerDate" class="hidden column-mtime">
|
||||
<a id="modified" class="columntitle" data-sort="mtime"><span><?php p($l->t( 'Modified' )); ?></span><span class="sort-indicator"></span></a>
|
||||
<span class="selectedActions"><a href="" class="delete-selected">
|
||||
<?php p($l->t('Delete'))?>
|
||||
<img class="svg" alt=""
|
||||
src="<?php print_unescaped(OCP\Template::image_path("core", "actions/delete.svg")); ?>" />
|
||||
</a></span>
|
||||
<span class="selectedActions">
|
||||
<a href="" class="delete-selected">
|
||||
<img class="svg" alt=""
|
||||
src="<?php print_unescaped(OCP\Template::image_path("core", "actions/delete.svg")); ?>" />
|
||||
<?php p($l->t('Delete'))?>
|
||||
</a>
|
||||
</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
|
@ -30,7 +30,19 @@ OCA.Trashbin.App = {
|
|||
fileActions: this._createFileActions(),
|
||||
detailsViewEnabled: false,
|
||||
scrollTo: urlParams.scrollto,
|
||||
config: OCA.Files.App.getFilesConfig()
|
||||
config: OCA.Files.App.getFilesConfig(),
|
||||
multiSelectMenu: [
|
||||
{
|
||||
name: 'restore',
|
||||
displayName: t('files', 'Restore'),
|
||||
iconClass: 'icon-history',
|
||||
},
|
||||
{
|
||||
name: 'delete',
|
||||
displayName: t('files', 'Delete'),
|
||||
iconClass: 'icon-delete',
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
},
|
||||
|
|
|
@ -31,25 +31,15 @@
|
|||
<div id="headerName-container">
|
||||
<a class="name sort columntitle" data-sort="name"><span><?php p($l->t( 'Name' )); ?></span><span class="sort-indicator"></span></a>
|
||||
<span id="selectedActionsList" class='selectedActions'>
|
||||
<a href="" class="undelete">
|
||||
<span class="icon icon-history"></span>
|
||||
<span><?php p($l->t('Restore'))?></span>
|
||||
</a>
|
||||
<a href="" class="delete-selected">
|
||||
<span class="icon icon-delete"></span>
|
||||
<span><?php p($l->t('Delete'))?></span>
|
||||
<a href="" class="actions-selected">
|
||||
<span class="icon icon-more"></span>
|
||||
<span><?php p($l->t('Actions'))?></span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</th>
|
||||
<th id="headerDate" class="hidden column-mtime">
|
||||
<a id="modified" class="columntitle" data-sort="mtime"><span><?php p($l->t( 'Deleted' )); ?></span><span class="sort-indicator"></span></a>
|
||||
<span class="selectedActions">
|
||||
<a href="" class="delete-selected">
|
||||
<span><?php p($l->t('Delete'))?></span>
|
||||
<span class="icon icon-delete"></span>
|
||||
</a>
|
||||
</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
Loading…
Reference in New Issue