summaryrefslogtreecommitdiffstats
path: root/core/js
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2016-02-08 11:43:42 +0100
committerVincent Petry <pvince81@owncloud.com>2016-02-09 10:59:29 +0100
commite378a757fffa3e43a798c0bce7d2d831912bcf75 (patch)
treef5af92a98e4cc048b169f06fba1b7be37318fee7 /core/js
parentae367c7e97b99885c7cb1feadae22aa1bb6cb729 (diff)
downloadnextcloud-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.js73
-rw-r--r--core/js/systemtags/systemtagsinputfield.js4
-rw-r--r--core/js/tests/specs/files/clientSpec.js154
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"?>' +