From 45db89f3e6b7b391db5f9c766f3b3ef8b4e0750a Mon Sep 17 00:00:00 2001 From: Abijeet Date: Sat, 2 Jun 2018 20:45:19 +0530 Subject: [PATCH] Added a new action menu in files and trash list. Uses the new file-multi-select-menu component. Towards #7647 Signed-off-by: Abijeet --- apps/files/css/files.scss | 13 +-- apps/files/css/mobile.scss | 14 +-- apps/files/js/app.js | 19 +++- apps/files/js/fileactions.js | 12 +-- apps/files/js/filelist.js | 91 ++++++++----------- ...electionmenu.js => filemultiselectmenu.js} | 80 +++++++++------- apps/files/js/merged-index.json | 2 +- apps/files/templates/recentlist.php | 10 +- apps/files/templates/simplelist.php | 13 +-- apps/files_trashbin/js/app.js | 14 ++- apps/files_trashbin/templates/index.php | 16 +--- 11 files changed, 152 insertions(+), 132 deletions(-) rename apps/files/js/{fileselectionmenu.js => filemultiselectmenu.js} (62%) diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss index bbc95d7cd6..b3ce4c0239 100644 --- a/apps/files/css/files.scss +++ b/apps/files/css/files.scss @@ -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 { diff --git a/apps/files/css/mobile.scss b/apps/files/css/mobile.scss index c5bb819392..42526a5c3f 100644 --- a/apps/files/css/mobile.scss +++ b/apps/files/css/mobile.scss @@ -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; } diff --git a/apps/files/js/app.js b/apps/files/js/app.js index 6e4e8c1b13..f8e59a71b9 100644 --- a/apps/files/js/app.js +++ b/apps/files/js/app.js @@ -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); diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index 4c0ccaf645..3623663ed6 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -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 = $(''); $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'); } }; diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index ec203043e4..c5929fbd21 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -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')); } } } diff --git a/apps/files/js/fileselectionmenu.js b/apps/files/js/filemultiselectmenu.js similarity index 62% rename from apps/files/js/fileselectionmenu.js rename to apps/files/js/filemultiselectmenu.js index 8cb10f08bb..767166b06c 100644 --- a/apps/files/js/fileselectionmenu.js +++ b/apps/files/js/filemultiselectmenu.js @@ -20,45 +20,15 @@ '' + '{{/if}}' + '{{displayName}}' + - '' + + '' + '{{/each}}' + ''; - 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 = $(''); + $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); \ No newline at end of file + OCA.Files.FileMultiSelectMenu = FileMultiSelectMenu; +})(OC, OCA); diff --git a/apps/files/js/merged-index.json b/apps/files/js/merged-index.json index 05b33139e9..cd7e72e1a5 100644 --- a/apps/files/js/merged-index.json +++ b/apps/files/js/merged-index.json @@ -6,7 +6,7 @@ "jquery-visibility.js", "fileinfomodel.js", "filesummary.js", - "fileselectionmenu.js", + "filemultiselectmenu.js", "breadcrumb.js", "filelist.js", "search.js", diff --git a/apps/files/templates/recentlist.php b/apps/files/templates/recentlist.php index 6c271a07f5..cfdb95c80a 100644 --- a/apps/files/templates/recentlist.php +++ b/apps/files/templates/recentlist.php @@ -28,10 +28,12 @@ t('Modified')); ?> - - t('Delete')) ?> - - + + + + t('Delete')) ?> + + diff --git a/apps/files/templates/simplelist.php b/apps/files/templates/simplelist.php index 1dc927c9b5..78adb21922 100644 --- a/apps/files/templates/simplelist.php +++ b/apps/files/templates/simplelist.php @@ -13,7 +13,6 @@

t('No entries found in this folder')); ?>

- @@ -27,11 +26,13 @@ diff --git a/apps/files_trashbin/js/app.js b/apps/files_trashbin/js/app.js index fd3d5db32f..002c01bf96 100644 --- a/apps/files_trashbin/js/app.js +++ b/apps/files_trashbin/js/app.js @@ -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', + } + ] } ); }, diff --git a/apps/files_trashbin/templates/index.php b/apps/files_trashbin/templates/index.php index a4459947d0..dd24abb5de 100644 --- a/apps/files_trashbin/templates/index.php +++ b/apps/files_trashbin/templates/index.php @@ -31,25 +31,15 @@