gr-ajax cleanup (gr-dashboard-view)

Also adds support for array param values passed to fetchJSON and
cleans up some unused code there as well.

Bug: Issue 3988
Change-Id: Ieabc015aebf1bf454e22d639334979f2b8831ee3
This commit is contained in:
Andrew Bonventre
2016-05-03 22:24:25 -04:00
parent 61bcdbc3db
commit 0c76ebbb1d
4 changed files with 63 additions and 60 deletions

View File

@@ -15,7 +15,7 @@ limitations under the License.
-->
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/rest-client-behavior.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<dom-module id="gr-dashboard-view">
<template>
@@ -37,12 +37,6 @@ limitations under the License.
}
}
</style>
<gr-ajax
auto
url="/changes/"
params="[[_computeQueryParams()]]"
last-response="{{_results}}"
loading="{{_loading}}"></gr-ajax>
<div class="loading" hidden$="[[!_loading]]">Loading...</div>
<div hidden$="[[_loading]]" hidden>
<gr-change-list
@@ -53,6 +47,7 @@ limitations under the License.
groups="{{_results}}"
group-titles="[[_groupTitles]]"></gr-change-list>
</div>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template>
<script src="gr-dashboard-view.js"></script>
</dom-module>

View File

@@ -49,28 +49,21 @@
},
},
behaviors: [
Gerrit.RESTClientBehavior,
],
attached: function() {
this.fire('title-change', {title: 'My Reviews'});
this._loading = true;
this._getDashboardChanges().then(function(results) {
this._results = results;
this._loading = false;
}.bind(this)).catch(function(err) {
this._loading = false;
console.error(err.message);
}.bind(this));
},
_computeQueryParams: function() {
var options = this.listChangesOptionsToHex(
this.ListChangesOption.LABELS,
this.ListChangesOption.DETAILED_ACCOUNTS,
this.ListChangesOption.REVIEWED
);
return {
O: options,
q: [
'is:open owner:self',
'is:open reviewer:self -owner:self',
'is:closed (owner:self OR reviewer:self) -age:4w limit:10',
],
};
_getDashboardChanges: function() {
return this.$.restAPI.getDashboardChanges();
},
});
})();

View File

@@ -84,27 +84,11 @@
opt_opts = opt_opts || {};
var fetchOptions = {
credentials: (opt_opts.noCredentials ? undefined : 'same-origin'),
credentials: 'same-origin',
headers: opt_opts.headers,
};
var urlWithParams = url;
if (opt_params) {
var params = [];
for (var p in opt_params) {
if (opt_params[p] == null) {
params.push(encodeURIComponent(p));
continue;
}
params.push(
encodeURIComponent(p) + '=' +
encodeURIComponent(opt_params[p]));
}
// Sorting the params leaves the order deterministic which is easier
// to test.
urlWithParams += '?' + params.sort().join('&');
}
var urlWithParams = this._urlWithParams(url, opt_params);
return fetch(urlWithParams, fetchOptions).then(function(response) {
if (opt_cancelCondition && opt_cancelCondition()) {
response.body.cancel();
@@ -117,14 +101,29 @@
}
return this.getResponseObject(response);
}.bind(this)).catch(function(err) {
if (opt_opts.noCredentials) {
throw err;
} else {
// This could be because of a 302 auth redirect. Retry the request.
return this.fetchJSON(url, opt_errFn, opt_cancelCondition, opt_params,
Object.assign(opt_opts, {noCredentials: true}));
throw err;
});
},
_urlWithParams: function(url, opt_params) {
if (!opt_params) { return url; }
var params = [];
for (var p in opt_params) {
if (opt_params[p] == null) {
params.push(encodeURIComponent(p));
continue;
}
}.bind(this));
var values = [].concat(opt_params[p]);
for (var i = 0; i < values.length; i++) {
params.push(
encodeURIComponent(p) + '=' +
encodeURIComponent(values[i]));
}
}
// Sorting the params leaves the order deterministic which is easier
// to test.
return url + '?' + params.sort().join('&');
},
getResponseObject: function(response) {
@@ -243,6 +242,23 @@
return this.fetchJSON('/changes/', null, null, params);
},
getDashboardChanges: function() {
var options = this._listChangesOptionsToHex(
ListChangesOption.LABELS,
ListChangesOption.DETAILED_ACCOUNTS,
ListChangesOption.REVIEWED
);
var params = {
O: options,
q: [
'is:open owner:self',
'is:open reviewer:self -owner:self',
'is:closed (owner:self OR reviewer:self) -age:4w limit:10',
],
};
return this.fetchJSON('/changes/', null, null, params);
},
getChangeActionURL: function(changeNum, opt_patchNum, endpoint) {
return this._changeBaseURL(changeNum, opt_patchNum) + endpoint;
},

View File

@@ -83,19 +83,18 @@ limitations under the License.
});
test('params are properly encoded', function() {
var fetchStub = sinon.stub(window, 'fetch', function() {
return Promise.resolve({text: function() {
return Promise.resolve(')]}\'\n{}');
}});
});
var params = {
var url = element._urlWithParams('/path/', {
sp: 'hola',
gr: 'guten tag',
noval: null,
};
element.fetchJSON('/path/', null, null, params);
assert.equal(fetchStub.args[0][0], '/path/?gr=guten%20tag&noval&sp=hola');
fetchStub.restore();
});
assert.equal(url, '/path/?gr=guten%20tag&noval&sp=hola');
url = element._urlWithParams('/path/', {
sp: 'hola',
en: ['hey', 'hi'],
});
assert.equal(url, '/path/?en=hey&en=hi&sp=hola');
});
test('request callbacks can be canceled', function(done) {