aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Scheidel <mail@scheidel.at>2019-12-03 09:45:33 +0100
committerbackportbot[bot] <backportbot[bot]@users.noreply.github.com>2021-07-23 16:28:23 +0000
commit377942d5ef0d5de06fcbd436032e90a4deadc064 (patch)
tree45028db15a68ac8c35b5652574c2c2151a98a2df
parentf19f9e1927a76716448d78ce8d8bcfefa959a9cf (diff)
downloadnextcloud-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.scss22
-rw-r--r--apps/files/js/app.js5
-rw-r--r--apps/files/js/filelist.js121
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) {