diff options
author | Vincent Petry <pvince81@owncloud.com> | 2016-02-08 11:43:42 +0100 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2016-02-09 10:59:29 +0100 |
commit | e378a757fffa3e43a798c0bce7d2d831912bcf75 (patch) | |
tree | f5af92a98e4cc048b169f06fba1b7be37318fee7 /core/js | |
parent | ae367c7e97b99885c7cb1feadae22aa1bb6cb729 (diff) | |
download | nextcloud-server-e378a757fffa3e43a798c0bce7d2d831912bcf75.tar.gz nextcloud-server-e378a757fffa3e43a798c0bce7d2d831912bcf75.zip |
Add system tags filter section for files app
Diffstat (limited to 'core/js')
-rw-r--r-- | core/js/files/client.js | 73 | ||||
-rw-r--r-- | core/js/systemtags/systemtagsinputfield.js | 4 | ||||
-rw-r--r-- | core/js/tests/specs/files/clientSpec.js | 154 |
3 files changed, 230 insertions, 1 deletions
diff --git a/core/js/files/client.js b/core/js/files/client.js index b736447d65e..55a8e2c485a 100644 --- a/core/js/files/client.js +++ b/core/js/files/client.js @@ -241,7 +241,7 @@ path = decodeURIComponent(path); - if (response.propStat.length === 1 && response.propStat[0].status !== 200) { + if (response.propStat.length === 0 || response.propStat[0].status !== 'HTTP/1.1 200 OK') { return null; } @@ -415,6 +415,77 @@ }, /** + * Fetches a flat list of files filtered by a given filter criteria. + * (currently only system tags is supported) + * + * @param {Object} filter filter criteria + * @param {Object} [filter.systemTagIds] list of system tag ids to filter by + * @param {Object} [options] options + * @param {Array} [options.properties] list of Webdav properties to retrieve + * + * @return {Promise} promise + */ + getFilteredFiles: function(filter, options) { + options = options || {}; + var self = this; + var deferred = $.Deferred(); + var promise = deferred.promise(); + var properties; + if (_.isUndefined(options.properties)) { + properties = this.getPropfindProperties(); + } else { + properties = options.properties; + } + + if (!filter || !filter.systemTagIds || !filter.systemTagIds.length) { + throw 'Missing filter argument'; + } + + var headers = _.extend({}, this._defaultHeaders); + // root element with namespaces + var body = '<oc:filter-files '; + var namespace; + for (namespace in this._client.xmlNamespaces) { + body += ' xmlns:' + this._client.xmlNamespaces[namespace] + '="' + namespace + '"'; + } + body += '>\n'; + + // properties query + body += ' <' + this._client.xmlNamespaces['DAV:'] + ':prop>\n'; + _.each(properties, function(prop) { + var property = self._client.parseClarkNotation(prop); + body += ' <' + self._client.xmlNamespaces[property.namespace] + ':' + property.name + ' />\n'; + }); + + body += ' </' + this._client.xmlNamespaces['DAV:'] + ':prop>\n'; + + // rules block + body += ' <oc:filter-rules>\n'; + _.each(filter.systemTagIds, function(systemTagIds) { + body += ' <oc:systemtag>' + escapeHTML(systemTagIds) + '</oc:systemtag>\n'; + }); + body += ' </oc:filter-rules>\n'; + + // end of root + body += '</oc:filter-files>\n'; + + this._client.request( + 'REPORT', + this._buildUrl(), + headers, + body + ).then(function(result) { + if (self._isSuccessStatus(result.status)) { + var results = self._parseResult(result.body); + deferred.resolve(result.status, results); + } else { + deferred.reject(result.status); + } + }); + return promise; + }, + + /** * Returns the file info of a given path. * * @param {String} path path diff --git a/core/js/systemtags/systemtagsinputfield.js b/core/js/systemtags/systemtagsinputfield.js index 48fc98c6188..a64e5386102 100644 --- a/core/js/systemtags/systemtagsinputfield.js +++ b/core/js/systemtags/systemtagsinputfield.js @@ -425,6 +425,10 @@ } }, + getValues: function() { + this.$tagsField.select2('val'); + }, + setValues: function(values) { this.$tagsField.select2('val', values); }, diff --git a/core/js/tests/specs/files/clientSpec.js b/core/js/tests/specs/files/clientSpec.js index b945e1bb4da..7673ec6e0fc 100644 --- a/core/js/tests/specs/files/clientSpec.js +++ b/core/js/tests/specs/files/clientSpec.js @@ -318,6 +318,160 @@ describe('OC.Files.Client tests', function() { }); }); + describe('file filtering', function() { + + // TODO: switch this to the already parsed structure + var folderContentsXml = dav.Client.prototype.parseMultiStatus( + '<?xml version="1.0" encoding="utf-8"?>' + + '<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns">' + + makeResponseBlock( + '/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/', + { + 'd:getlastmodified': 'Fri, 10 Jul 2015 10:00:05 GMT', + 'd:getetag': '"56cfcabd79abb"', + 'd:resourcetype': '<d:collection/>', + 'oc:id': '00000011oc2d13a6a068', + 'oc:fileid': '11', + 'oc:permissions': 'RDNVCK', + 'oc:size': '120' + }, + [ + 'd:getcontenttype', + 'd:getcontentlength' + ] + ) + + makeResponseBlock( + '/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/One.txt', + { + 'd:getlastmodified': 'Fri, 10 Jul 2015 13:38:05 GMT', + 'd:getetag': '"559fcabd79a38"', + 'd:getcontenttype': 'text/plain', + 'd:getcontentlength': 250, + 'd:resourcetype': '', + 'oc:id': '00000051oc2d13a6a068', + 'oc:fileid': '51', + 'oc:permissions': 'RDNVW' + }, + [ + 'oc:size', + ] + ) + + makeResponseBlock( + '/owncloud/remote.php/webdav/path/to%20space/%E6%96%87%E4%BB%B6%E5%A4%B9/sub', + { + 'd:getlastmodified': 'Fri, 10 Jul 2015 14:00:00 GMT', + 'd:getetag': '"66cfcabd79abb"', + 'd:resourcetype': '<d:collection/>', + 'oc:id': '00000015oc2d13a6a068', + 'oc:fileid': '15', + 'oc:permissions': 'RDNVCK', + 'oc:size': '100' + }, + [ + 'd:getcontenttype', + 'd:getcontentlength' + ] + ) + + '</d:multistatus>' + ); + + it('sends REPORT with filter information', function() { + client.getFilteredFiles({ + systemTagIds: ['123', '456'] + }); + + expect(requestStub.calledOnce).toEqual(true); + expect(requestStub.lastCall.args[0]).toEqual('REPORT'); + expect(requestStub.lastCall.args[1]).toEqual(baseUrl); + + var body = requestStub.lastCall.args[3]; + var doc = (new window.DOMParser()).parseFromString( + body, + 'application/xml' + ); + + var ns = 'http://owncloud.org/ns'; + expect(doc.documentElement.localName).toEqual('filter-files'); + expect(doc.documentElement.namespaceURI).toEqual(ns); + + var filterRoots = doc.getElementsByTagNameNS(ns, 'filter-rules'); + var rulesList = filterRoots[0] = doc.getElementsByTagNameNS(ns, 'systemtag'); + expect(rulesList.length).toEqual(2); + expect(rulesList[0].localName).toEqual('systemtag'); + expect(rulesList[0].namespaceURI).toEqual(ns); + expect(rulesList[0].textContent).toEqual('123'); + expect(rulesList[1].localName).toEqual('systemtag'); + expect(rulesList[1].namespaceURI).toEqual(ns); + expect(rulesList[1].textContent).toEqual('456'); + }); + it('sends REPORT with explicit properties to filter file list', function() { + client.getFilteredFiles({ + systemTagIds: ['123', '456'] + }); + + expect(requestStub.calledOnce).toEqual(true); + expect(requestStub.lastCall.args[0]).toEqual('REPORT'); + expect(requestStub.lastCall.args[1]).toEqual(baseUrl); + + var props = getRequestedProperties(requestStub.lastCall.args[3]); + expect(props).toContain('{DAV:}getlastmodified'); + expect(props).toContain('{DAV:}getcontentlength'); + expect(props).toContain('{DAV:}getcontenttype'); + expect(props).toContain('{DAV:}getetag'); + expect(props).toContain('{DAV:}resourcetype'); + expect(props).toContain('{http://owncloud.org/ns}fileid'); + expect(props).toContain('{http://owncloud.org/ns}size'); + expect(props).toContain('{http://owncloud.org/ns}permissions'); + }); + it('parses the result list into a FileInfo array', function() { + var promise = client.getFilteredFiles({ + systemTagIds: ['123', '456'] + }); + + expect(requestStub.calledOnce).toEqual(true); + + requestDeferred.resolve({ + status: 207, + body: folderContentsXml + }); + + promise.then(function(status, response) { + expect(status).toEqual(207); + expect(_.isArray(response)).toEqual(true); + + // returns all entries + expect(response.length).toEqual(3); + + // file entry + var info = response[0]; + expect(info instanceof OC.Files.FileInfo).toEqual(true); + expect(info.id).toEqual(11); + + // file entry + var info = response[1]; + expect(info instanceof OC.Files.FileInfo).toEqual(true); + expect(info.id).toEqual(51); + + // sub entry + info = response[2]; + expect(info instanceof OC.Files.FileInfo).toEqual(true); + expect(info.id).toEqual(15); + }); + }); + it('throws exception if arguments are missing', function() { + var thrown = null; + try { + client.getFilteredFiles({ + systemTagIds: [] + }); + } catch (e) { + thrown = true; + } + + expect(thrown).toEqual(true); + }); + }); + describe('file info', function() { var responseXml = dav.Client.prototype.parseMultiStatus( '<?xml version="1.0" encoding="utf-8"?>' + |