Chromium Code Reviews| Index: appengine/swarming/elements/res/imp/common/pageable-data.html |
| diff --git a/appengine/swarming/elements/res/imp/common/pageable-data.html b/appengine/swarming/elements/res/imp/common/pageable-data.html |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1eac76daf765518a263ee9f481760e7fd47182ff |
| --- /dev/null |
| +++ b/appengine/swarming/elements/res/imp/common/pageable-data.html |
| @@ -0,0 +1,161 @@ |
| +<!-- |
| + This in an HTML Import-able file that contains the definition |
| + of the following elements: |
| + |
| + <pageable-data> |
| + |
| + The pageable-data element allows for easy paging of data from the swarming |
| + server. It displays a button to the user to go fetch more data, which will |
| + be appended to the output, rather than replaced, which is typical in |
| + elements like iron-ajax. |
| + |
| + Typical usage is |
| + |
| + this.$.page.clear(); |
| + this.$.page.load("/api/frobulator?alpha=beta", this.auth_headers, 20); |
| + |
| + which initializes the url to query and goes to fetch the first 20 records |
| + from the api. The user can then click the button to get the next page of |
| + data. This can be done programatically with page(). |
| + |
| + Properties: |
| + // input |
| + label: String, what to label the button to page for more data. |
| + parse: Function, This function takes the JSON object from the server and |
| + returns an array of objects. Preprocessing should be done in this |
| + function, if necessary. |
| + |
| + // output |
| + busy: Boolean, if a request is in flight. Calls to page() while busy will |
| + be ignored. |
| + output: Array<Object> the accumulated values from the server. |
| + |
| + Methods: |
| + clear(): Reset the element, emptying output. page() will not work until |
| + a call to load() has been made. |
| + load(url, headers, pageSize): Initialize the element and make a call to |
|
stephana
2016/09/28 13:25:23
empty line between the method descriptions and pro
kjlubick
2016/09/28 13:50:36
Done.
|
| + the server for the first batch of data. |
| + page(): Must be called after a call to load(). Fetch the next batch of |
| + data from the server. |
| + |
| + Events: |
| + None. |
| +--> |
| + |
| +<link rel="import" href="/res/imp/common/swarming-app.html"> |
| + |
| +<dom-module id="pageable-data"> |
| + <template> |
| + <style include="swarming-app-style"> |
| + </style> |
| + |
| + <button |
| + on-tap="page" |
| + disabled$="[[_noMore(_cursor)]]"> |
| + [[label]] |
| + </button> |
| + |
| + </template> |
| + <script> |
| + (function(){ |
| + var END = "END"; |
| + Polymer({ |
| + is: 'pageable-data', |
| + |
| + properties: { |
| + // input |
| + label: { |
| + type: String, |
| + value: "Show More", |
| + }, |
| + parse: { |
| + type: Function, |
| + value: function(){ |
| + return function(a){ |
| + return a; |
| + }; |
| + }, |
| + }, |
| + |
| + // output |
| + busy: { |
| + type: Boolean, |
| + value: false, |
| + notify: true, |
| + }, |
| + output: { |
| + type: Array, |
| + notify: true, |
| + }, |
| + |
| + _cursor: { |
| + type: String, |
| + }, |
| + _url: { |
| + type: String, |
| + }, |
| + _headers: { |
| + type: Object, |
| + }, |
| + _page_size: { |
| + type: Number, |
| + } |
| + }, |
| + |
| + clear: function() { |
| + this.set("output", []); |
| + this._cursor = undefined; |
|
stephana
2016/09/28 13:25:23
I would either delete the _cursor member or set it
kjlubick
2016/09/28 13:50:36
Done.
|
| + }, |
| + |
| + load: function(url, headers, pageSize) { |
| + if (!url) { |
| + console.log("url can't be blank"); |
|
stephana
2016/09/28 13:25:23
Same as below. Assume that the client of this elem
kjlubick
2016/09/28 13:50:37
Done.
|
| + return; |
| + } |
| + if (url.indexOf("?") === -1) { |
| + url += "?"; |
| + } |
| + this._url = url; |
| + this._headers = headers; |
| + this._page_size = pageSize || 50; |
| + this.page(); |
| + }, |
| + |
| + page: function() { |
| + if (this.busy || this._cursor === END) { |
| + // ignore pages while we are loading or are at the end of the data. |
| + return; |
| + } |
| + if (!this._url) { |
| + console.log("You must first call load() before calling page()"); |
|
stephana
2016/09/28 13:25:23
console.log IMO is mostly for debugging purposes a
kjlubick
2016/09/28 13:50:36
Done. I made it a throw just to be safe.
|
| + return; |
| + } |
| + this.set("busy", true); |
| + |
| + var url = this._url + "&limit=" + this._page_size; |
| + if (this._cursor !== undefined) { |
|
stephana
2016/09/28 13:25:23
I would make _cursor well defined in the sense, th
kjlubick
2016/09/28 13:50:37
Done.
|
| + url += "&cursor=" + this._cursor; |
| + } |
| + |
| + sk.request("GET", url, "", this._headers).then(JSON.parse).then(function(json){ |
| + var vals = this.parse(json); |
| + if (!this.output) { |
| + this.set("output", vals); |
| + } else { |
| + this.push("output", ...vals); |
| + } |
| + this.set("_cursor", json.cursor || END); |
| + this.set("busy", false); |
| + }.bind(this)).catch(function(reason){ |
| + console.log("Reason for failure of request to " + this._url, reason); |
| + this.set("busy", false); |
|
stephana
2016/09/28 13:25:23
There should be a notification of failure shown to
kjlubick
2016/09/28 13:50:37
Done.
|
| + }.bind(this)); |
| + }, |
| + |
| + _noMore: function(cursor) { |
| + return cursor === END; |
| + } |
| + }); |
| + })(); |
| + </script> |
| +</dom-module> |