Chromium Code Reviews| Index: appengine/swarming/elements/res/imp/taskpage/task-page.html |
| diff --git a/appengine/swarming/elements/res/imp/taskpage/task-page.html b/appengine/swarming/elements/res/imp/taskpage/task-page.html |
| index d5cee63f12742ff6a2f36f64712003cd86dc91be..a54be57d6efc153de6f94972dc101930230c9f97 100644 |
| --- a/appengine/swarming/elements/res/imp/taskpage/task-page.html |
| +++ b/appengine/swarming/elements/res/imp/taskpage/task-page.html |
| @@ -33,6 +33,8 @@ |
| <link rel="import" href="/res/imp/bower_components/polymer/polymer.html"> |
| <link rel="import" href="/res/imp/common/common-behavior.html"> |
| +<link rel="import" href="/res/imp/common/error-toast.html"> |
| +<link rel="import" href="/res/imp/common/interval-timer.html"> |
| <link rel="import" href="/res/imp/common/single-page-style.html"> |
| <link rel="import" href="/res/imp/common/swarming-app.html"> |
| <link rel="import" href="/res/imp/common/task-behavior.html"> |
| @@ -95,13 +97,15 @@ |
| value="{{_show_raw}}"> |
| </url-param> |
| <url-param name="refresh" |
| - value="{{_refresh}}" |
| + value="{{_refresh_interval}}" |
| default_value="10"> |
| </url-param> |
| <swarming-app |
| client_id="[[client_id]]" |
| auth_headers="{{_auth_headers}}" |
| + permissions="{{_permissions}}" |
| + profile="{{_profile}}" |
| signed_in="{{_signed_in}}" |
| busy="[[_busy]]" |
| @@ -112,7 +116,9 @@ |
| <div hidden$="[[_not(_signed_in)]]"> |
| <task-page-data |
| + id="data" |
| auth_headers="[[_auth_headers]]" |
| + refresh_interval="[[_refresh_interval]]" |
| task_id="[[task_id]]" |
| busy="{{_busy}}" |
| @@ -128,8 +134,10 @@ |
| <button on-click="_refresh"> |
| <iron-icon class="refresh" icon="icons:refresh"></iron-icon> |
| </button> |
| - <button on-click="_retry"><span>Retry</span></button> |
| - <button on-click="_cancel">Cancel</button> |
| + <button on-click="_promptRetry">Retry</button> |
| + <template is="dom-if" if="[[_canCancelTask(_result,_permissions)]]"> |
| + <button on-click="_promptCancel">Cancel</button> |
| + </template> |
| </div> |
| <table> |
| <tr> |
| @@ -142,12 +150,12 @@ |
| </tr> |
| <tr> |
| <td>Created</td> |
| - <td>[[_request.human_created_ts]]</td> |
| + <td title$="[[_request.created_ts]]">[[_request.human_created_ts]]</td> |
| </tr> |
| <template is="dom-if" if="[[_wasPickedUp(_result)]]"> |
| <tr> |
| <td>Started</td> |
| - <td>[[_result.human_started_ts]]</td> |
| + <td title$="[[_result.started_ts]]">[[_result.human_started_ts]]</td> |
| </tr> |
| </template> |
| <template is="dom-if" if="[[_wasNotPickedUp(_result)]]"> |
| @@ -159,18 +167,18 @@ |
| <template is="dom-if" if="[[_result.human_completed_ts]]"> |
| <tr> |
| <td>Completed</td> |
| - <td>[[_result.human_completed_ts]]</td> |
| + <td title$="[[_result.completed_ts]]">[[_result.human_completed_ts]]</td> |
| </tr> |
| </template> |
| <template is="dom-if" if="[[_result.human_abandoned_ts]]"> |
| <tr> |
| <td>Abandoned</td> |
| - <td>[[_result.human_abandoned_ts]]</td> |
| + <td title$="[[_result.abandoned_ts]]">[[_result.human_abandoned_ts]]</td> |
| </tr> |
| </template> |
| <tr> |
| <td>Last Updated</td> |
| - <td>[[_result.human_modified_ts]]</td> |
| + <td title$="[[_result.modified_ts]]">[[_result.human_modified_ts]]</td> |
| </tr> |
| <template is="dom-if" if="[[_result.deduped_from]]"> |
| <tr> |
| @@ -223,11 +231,17 @@ |
| </tr> |
| </template> |
| <tr> |
| - <td rowspan$="[[_rowspan(_request.properties.dimensions)]]">Requested Dimensions</td> |
| + <td rowspan$="[[_rowspan(_request.properties.dimensions)]]"> |
| + <a |
| + title="The list of bots that matches the list of dimensions" |
| + href$="[[_botListLink(_request.properties.dimensions)]]"> |
| + Requested Dimensions |
| + </a> |
| + </td> |
| </tr> |
| <template is="dom-repeat" items="{{_request.properties.dimensions}}" as="dimension"> |
| <tr> |
| - <td><b>[[dimension.key]]:</b> [[dimension.value]]</td> |
| + <td><b>[[dimension.key]]:</b> [[_alias(dimension)]]</td> |
| </tr> |
| </template> |
| <tr> |
| @@ -329,11 +343,13 @@ |
| <td><a href$="[[_botLink(_result.bot_id)]]">[[_result.bot_id]]</td> |
| </tr> |
| <tr> |
| - <td rowspan$="[[_rowspan(_result.bot_dimensions)]]">Bot Dimensions</td> |
| + <td rowspan$="[[_rowspan(_result.bot_dimensions)]]"> |
| + <a>Bot Dimensions</a> |
| + </td> |
| </tr> |
| <template is="dom-repeat" items="[[_result.bot_dimensions]]" as="dimension"> |
| <tr> |
| - <td><b>[[dimension.key]]:</b> [[_join(dimension.value," | ")]]</td> |
| + <td><b>[[dimension.key]]:</b> [[_alias(dimension)]]</td> |
| </tr> |
| </template> |
| @@ -411,7 +427,7 @@ |
| <paper-input |
| class="refresh_input" |
| label="Refresh Interval (seconds)" |
| - value="{{_refresh}}" |
| + value="{{_refresh_interval}}" |
| auto-validate |
| min="1" |
| max="1000" |
| @@ -428,9 +444,22 @@ |
| </div> |
| </div> |
| </div> |
| - |
| </swarming-app> |
| + <paper-dialog id="prompt" modal on-iron-overlay-closed="_promptClosed"> |
| + <h2>Are you sure?</h2> |
| + <div>Are you sure you want to [[_dialogPrompt]]?</div> |
| + <div class="buttons"> |
| + <paper-button dialog-dismiss autofocus>No</paper-button> |
| + <paper-button dialog-confirm>Yes</paper-button> |
| + </div> |
| + </paper-dialog> |
| + |
| + <error-toast></error-toast> |
| + |
| + <interval-timer period="[[_refresh_interval]]" on-trigger="_refreshOutput"> |
| + </interval-timer> |
| + |
| </template> |
| <script> |
| (function(){ |
| @@ -453,19 +482,56 @@ |
| type: String, |
| }, |
| + |
| + _dialogPrompt: { |
| + type: String, |
| + value: "", |
| + }, |
| + _refresh_interval: { |
| + type: Number, |
| + }, |
| _request: { |
| type: Object, |
| observer: "_requestUpdated" |
| }, |
| _request_detail: { |
| type: Boolean, |
| + }, |
| + _result: { |
| + type: Object, |
| + }, |
| + _stdout: { |
| + type: String, |
| } |
| }, |
| + _alias: function(dim) { |
| + var values = dim.value; |
| + if (!Array.isArray(values)) { |
| + values = [values]; |
| + } |
| + if (swarming.alias.has(dim.key)) { |
| + |
|
jcgregorio
2016/09/21 14:22:03
No blank line.
kjlubick
2016/09/21 14:51:38
Done.
|
| + values.forEach(function(v, i){ |
| + values[i] = swarming.alias.apply(v, dim.key); |
| + }); |
| + } |
| + return values.join(" | "); |
| + }, |
| + |
| _bytes: function(sizeInBytes) { |
| return sk.human.bytes(sizeInBytes); |
| }, |
| + _canCancelTask: function(result, permissions) { |
| + return result && result.state === "PENDING" && permissions.cancel_task; |
| + }, |
| + |
| + _cancelTask: function() { |
| + var url = "/_ah/api/swarming/v1/task/" + this.task_id +"/cancel"; |
| + swarming.postWithToast(url, "Canceling task " + this.task_id, this._auth_headers); |
| + }, |
| + |
| _cipdRowspan: function(request, result) { |
| if (!request || !request.properties || !request.properties.cipd_input) { |
| return 0; |
| @@ -546,11 +612,6 @@ |
| "&hash=" + ref.isolated; |
| }, |
| - _join: function(arr, s) { |
| - arr = arr || []; |
| - return arr.join(s); |
| - }, |
| - |
| _noMilo: function(result) { |
| return !this._tag(result, "allow_milo"); |
| }, |
| @@ -567,12 +628,68 @@ |
| return this._timeDiffExact(result.created_ts, end); |
| }, |
| + _promptClosed: function(e) { |
| + if (e.detail.confirmed) { |
| + if (this._dialogPrompt.startsWith("cancel")) { |
| + this._cancelTask(); |
| + } else { |
| + this._retryTask(); |
| + } |
| + } |
| + }, |
| + |
| + _promptCancel: function() { |
| + this.set("_dialogPrompt", "cancel task "+this.task_id); |
| + this.$.prompt.open(); |
| + }, |
| + |
| + _promptRetry: function() { |
| + this.set("_dialogPrompt", "retry task "+this.task_id); |
| + this.$.prompt.open(); |
| + }, |
| + |
| + _refresh: function() { |
| + this.$.data.reload(); |
| + }, |
| + |
| + _refreshOutput: function() { |
| + this.$.data.reloadStdout(); |
| + var miloFrame = this.$$("iframe") |
| + if (miloFrame) { |
| + miloFrame.src = this._getMiloLink(this.milo_prefix,this.task_id); |
| + } |
| + }, |
| + |
| _requestUpdated: function(request) { |
| if (this._noMilo(request)) { |
| this.set("_show_raw", 1); |
| } |
| }, |
| + _retryTask: function() { |
| + if (!this._request) { |
| + sk.errorMessage("Task not yet loaded", 3000); |
| + return; |
| + } |
| + var newTask = { |
| + expiration_secs: this._request.expiration_secs, |
| + name: this._request.name +" (retry)", |
| + parent_task_id: this._request.parent_task_id, |
| + priority: this._request.priority, |
| + properties:this._request.properties, |
| + tags: this._request.tags, |
| + user: this._profile.email, |
| + service_account: this._request.service_account, |
| + } |
| + swarming.postWithToast("/_ah/api/swarming/v1/tasks/new", "Retrying task " + this.task_id, |
| + this._auth_headers, newTask).then(function(response) { |
|
jcgregorio
2016/09/21 14:22:03
The value of 'response' will the error message ret
kjlubick
2016/09/21 14:51:38
Fixed.
|
| + response = JSON.parse(response); |
| + if (response && response.task_id) { |
| + this.set("task_id", response.task_id); |
| + } |
| + }.bind(this)); |
| + }, |
| + |
| _rowspan: function(dims) { |
| dims = dims || []; |
| return dims.length + 1; |