diff options
author | Roland Scheidel <mail@scheidel.at> | 2019-12-03 09:45:33 +0100 |
---|---|---|
committer | backportbot[bot] <backportbot[bot]@users.noreply.github.com> | 2021-07-23 16:28:23 +0000 |
commit | 377942d5ef0d5de06fcbd436032e90a4deadc064 (patch) | |
tree | 45028db15a68ac8c35b5652574c2c2151a98a2df | |
parent | f19f9e1927a76716448d78ce8d8bcfefa959a9cf (diff) | |
download | nextcloud-server-377942d5ef0d5de06fcbd436032e90a4deadc064.tar.gz nextcloud-server-377942d5ef0d5de06fcbd436032e90a4deadc064.zip |
add an option to the multiple files selected actions to add and remove tags from multiple files at once
Signed-off-by: Roland Scheidel <kontakt@scheidel.at>
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
-rw-r--r-- | apps/files/css/files.scss | 22 | ||||
-rw-r--r-- | apps/files/js/app.js | 5 | ||||
-rw-r--r-- | apps/files/js/filelist.js | 121 |
3 files changed, 148 insertions, 0 deletions
diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss index 596c931a25b..5aea86d064a 100644 --- a/apps/files/css/files.scss +++ b/apps/files/css/files.scss @@ -1215,3 +1215,25 @@ table.dragshadow td.size { #gallery-button { display: none; } + +#tag_multiple_files_container { + overflow: hidden; + background-color: #fff; + border-radius: 3px; + position: relative; + display: flex; + flex-wrap: wrap; + margin-bottom: 10px; + + h3 { + width: 100%; + padding: 0 18px; + } + + .systemTagsInputFieldContainer { + flex: 1 1 80%; + min-width: 0; + margin: 0 12px; + } +} + diff --git a/apps/files/js/app.js b/apps/files/js/app.js index 1a0d59eee0f..6971088bb47 100644 --- a/apps/files/js/app.js +++ b/apps/files/js/app.js @@ -113,6 +113,11 @@ iconClass: 'icon-delete', order: 99, }, + { + 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 3f4cae45cdc..38e8e66ccbe 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -555,6 +555,9 @@ case 'restore': this._onClickRestoreSelected(ev); break; + case 'tags': + this._onClickTagSelected(ev); + break; } }, /** @@ -1117,6 +1120,124 @@ }, /** + * 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(); + + // Build dom + self.tagsTitle = $('<h3>'+ t('files', 'Please select tag(s) to add to the selection') +'</h3>'); + self.tagsSubmit = $('<button>' + t('files', 'Apply tag(s) to selection') + '</button>'); + self.tagsContainer = $('<tr id="tag_multiple_files_container"></tr>'); + self.tagsTitle.appendTo(self.tagsContainer) + self.tagsContainer.append(self._inputView.el); + self.tagsSubmit.appendTo(self.tagsContainer) + + // Inject everything + self.$table.find('thead').append(self.tagsContainer); + + self.tagsSubmit.on('click', function(ev){ + self._onClickDocument(ev); + }); + } + + 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).off('click', this._onClickDocument); + } + + }, + + /** + * Custom code + * Set tag for all selected files + * @param tagModel + * @private + */ + _onSelectTag: function(tagModel) { + var selectedFiles = _.pluck(this.getSelectedFiles(),'id') + if (!_.isArray(selectedFiles)) { + return; + } + 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'); + if (!_.isArray(selectedFiles)) { + return; + } + selectedFiles.forEach(function(fileId) { + $.ajax({ + url: OC.linkToRemote('dav') + '/systemtags-relations/files/' +fileId + '/'+ tagId, + type: 'DELETE' + }); + }); + }, + + /** * Event handler when clicking on a table header */ _onClickHeader: function(e) { |