From 8f6b06a3a5940b460ccb757113362a1d97531aa0 Mon Sep 17 00:00:00 2001 From: Roland Scheidel Date: Tue, 3 Dec 2019 09:45:33 +0100 Subject: [PATCH] add an option to the multiple files selected actions to add and remove tags from multiple files at once --- apps/files/css/files.scss | 12 +++++ apps/files/js/app.js | 5 ++ apps/files/js/filelist.js | 109 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+) diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss index 915c037431dd2..20add2b5719c8 100644 --- a/apps/files/css/files.scss +++ b/apps/files/css/files.scss @@ -1127,3 +1127,15 @@ table.dragshadow td.size { #gallery-button { display: none; } + +#tag_multiple_files_container { + overflow: hidden; + background-color: #fff; + border-radius: 3px; + position: relative; + + td { + padding: 0 0.5em 0 0.5em; + } +} + diff --git a/apps/files/js/app.js b/apps/files/js/app.js index 20da85f0f927b..d6b5f4756da91 100644 --- a/apps/files/js/app.js +++ b/apps/files/js/app.js @@ -102,6 +102,11 @@ displayName: t('files', 'Delete'), iconClass: 'icon-delete', }, + { name: 'tags', + displayName: 'Tags', + iconClass: 'icon-tag' + + } ], sorting: { mode: $('#defaultFileSorting').val(), diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index d2a23283f12bc..788cf0189a5bf 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -508,6 +508,9 @@ case 'restore': this._onClickRestoreSelected(ev); break; + case 'tags': + this._onClickTagSelected(ev); + break; } }, /** @@ -1063,6 +1066,112 @@ event.preventDefault(); }, + /** + * CUSTOM CODE + * Event handler for when clicking on "Tags" for the selected files + */ + _onClickTagSelected: function(event) { + var self = this; + event.preventDefault(); + var commonTags = []; + + var selectedFiles = _.pluck(this.getSelectedFiles(),'id') + var tagCollections=[]; + var fetchTagPromises = []; + + + selectedFiles.forEach(function(fileId) { + var deferred = new $.Deferred(); + var tagCollection = new OC.SystemTags.SystemTagsMappingCollection([], { + objectType: 'files', + objectId: fileId}); + tagCollections.push(tagCollection); + tagCollection.fetch({ + success: function(){ + deferred.resolve('success'); + }, + error: function() {deferred.resolve('failed');} + }) + fetchTagPromises.push(deferred); + }); + if (!self._inputView) { + self._inputView = new OC.SystemTags.SystemTagsInputField({ + multiple: true, + allowActions: true, + allowCreate: true, + isAdmin: OC.isUserAdmin(), + }); + self._inputView.on('select', self._onSelectTag, self); + self._inputView.on('deselect', self._onDeselectTag, self); + self._inputView.render(); + self.tagsContainer = $(''); + // console.log('inputView',self._inputView, self._inputView.$el,'tag container', self.tagsContainer); + self.tagsContainer.children()[0].append(self._inputView.$el.context); + $('#app-content-files>#filestable>thead').append(self.tagsContainer); + + } + self._inputView.$el.addClass('icon-loading'); + self.tagsContainer.show(); + Promise.all(fetchTagPromises).then(function() { + //find tags which are common to all selected files + commonTags =_.intersection.apply(null, tagCollections.map(function (tagCollection) {return tagCollection.getTagIds();})); + self._inputView.setValues(commonTags); + self._inputView.$el.removeClass('icon-loading'); + $(document).on('click',function(ev){ + self._onClickDocument(ev); + }); + }); + }, + + _onClickDocument: function(ev) { + if(!$(ev.target).closest('#editor_container').length) { + this._inputView.setValues([]); + this.tagsContainer.hide(); + $(document).unbind('click', this._onClickDocument); + } + + }, + + /** + * Custom code + * Set tag for all selected files + * @param tagModel + * @private + */ + _onSelectTag: function(tagModel) { + console.log('selected',tagModel.attributes); + var selectedFiles = _.pluck(this.getSelectedFiles(),'id') + if (!_.isArray(selectedFiles)) { + console.log('selected files - no array!', selectedFiles); + } + selectedFiles.forEach(function(fileId) { + $.ajax({ + url: OC.linkToRemote('dav') + '/systemtags-relations/files/' +fileId + '/'+ tagModel.attributes.id, + type: 'PUT', + }); + }); + + }, + /** + * remove tag from all selected files + * @param tagId + * @private + */ + _onDeselectTag: function(tagId) { + var selectedFiles = _.pluck(this.getSelectedFiles(),'id') + console.log('removing tag', tagId, 'for files', selectedFiles, this.getSelectedFiles()) + if (!_.isArray(selectedFiles)) { + console.log('selected files - no array!', selectedFiles); + } + selectedFiles.forEach(function(fileId) { + console.log('remove tag route',OC.linkToRemote('dav') + '/systemtags-relations/files/' +fileId + '/'+ tagId) + $.ajax({ + url: OC.linkToRemote('dav') + '/systemtags-relations/files/' +fileId + '/'+ tagId, + type: 'DELETE' + }); + }); + }, + /** * Event handler when clicking on a table header */