| OLD | NEW |
| 1 <!DOCTYPE html><html><head><!-- | 1 <!DOCTYPE html><html><head><!-- |
| 2 @license | 2 @license |
| 3 Copyright (c) 2016 The Polymer Project Authors. All rights reserved. | 3 Copyright (c) 2016 The Polymer Project Authors. All rights reserved. |
| 4 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt | 4 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt |
| 5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | 5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt |
| 6 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt | 6 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt |
| 7 Code distributed by Google as part of the polymer project is also | 7 Code distributed by Google as part of the polymer project is also |
| 8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt | 8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt |
| 9 --><!-- | 9 --><!-- |
| 10 @license | 10 @license |
| (...skipping 8128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8139 }, | 8139 }, |
| 8140 | 8140 |
| 8141 _or: function() { | 8141 _or: function() { |
| 8142 var result = false; | 8142 var result = false; |
| 8143 // can't use .foreach, as arguments isn't really an Array. | 8143 // can't use .foreach, as arguments isn't really an Array. |
| 8144 for (var i = 0; i < arguments.length; i++) { | 8144 for (var i = 0; i < arguments.length; i++) { |
| 8145 result = result || arguments[i]; | 8145 result = result || arguments[i]; |
| 8146 } | 8146 } |
| 8147 return result; | 8147 return result; |
| 8148 }, | 8148 }, |
| 8149 |
| 8150 // _postWithToast makes a post request and updates the provided paper-toas
t |
| 8151 // element with the response, regardless of failure. |
| 8152 _postWithToast: function(url, toast, auth_headers) { |
| 8153 // Keep toast displayed until we hear back from the request. |
| 8154 toast.duration = 0; |
| 8155 toast.open(); |
| 8156 sk.request("POST", url, undefined, auth_headers).then(function(response)
{ |
| 8157 toast.close(); |
| 8158 toast.show({ |
| 8159 text: "Request sent. Response: "+response, |
| 8160 duration: 3000, |
| 8161 }); |
| 8162 }.bind(this)).catch(function(reason) { |
| 8163 console.log("Request failed", reason); |
| 8164 toast.close(); |
| 8165 toast.show({ |
| 8166 text: "Request failed. Reason: "+reason, |
| 8167 duration: 3000, |
| 8168 }); |
| 8169 }.bind(this)); |
| 8170 } |
| 8149 }; | 8171 }; |
| 8150 })(); | 8172 })(); |
| 8151 </script> | 8173 </script> |
| 8152 <script> | 8174 <script> |
| 8153 Polymer.AppLayout = Polymer.AppLayout || {}; | 8175 Polymer.AppLayout = Polymer.AppLayout || {}; |
| 8154 | 8176 |
| 8155 Polymer.AppLayout._scrollEffects = Polymer.AppLayout._scrollEffects || {}; | 8177 Polymer.AppLayout._scrollEffects = Polymer.AppLayout._scrollEffects || {}; |
| 8156 | 8178 |
| 8157 Polymer.AppLayout.scrollTimingFunction = function easeOutQuad(t, b, c, d) { | 8179 Polymer.AppLayout.scrollTimingFunction = function easeOutQuad(t, b, c, d) { |
| 8158 t /= d; | 8180 t /= d; |
| (...skipping 16436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 24595 }, | 24617 }, |
| 24596 | 24618 |
| 24597 _cancelTask: function(e) { | 24619 _cancelTask: function(e) { |
| 24598 var task = e.model.task; | 24620 var task = e.model.task; |
| 24599 if (!task || !task.task_id) { | 24621 if (!task || !task.task_id) { |
| 24600 console.log("Missing task info", task); | 24622 console.log("Missing task info", task); |
| 24601 return | 24623 return |
| 24602 } | 24624 } |
| 24603 var id = task.task_id | 24625 var id = task.task_id |
| 24604 | 24626 |
| 24605 // Keep toast displayed until we hear back from the cancel. | |
| 24606 this.$.toast.duration = 0; | |
| 24607 this.$.toast.text="Canceling task " + id; | 24627 this.$.toast.text="Canceling task " + id; |
| 24608 this.$.toast.open(); | |
| 24609 var url = "/_ah/api/swarming/v1/task/" + id +"/cancel"; | 24628 var url = "/_ah/api/swarming/v1/task/" + id +"/cancel"; |
| 24610 sk.request("POST", url, undefined, this._auth_headers).then(function(res
ponse) { | 24629 this._postWithToast(url, this.$.toast, this._auth_headers); |
| 24611 this.$.toast.close(); | |
| 24612 this.$.toast.show({ | |
| 24613 text: "Request sent. Response: "+response, | |
| 24614 duration: 3000, | |
| 24615 }); | |
| 24616 }.bind(this)).catch(function(reason) { | |
| 24617 console.log("Cancellation failed", reason); | |
| 24618 this.$.toast.close(); | |
| 24619 this.$.toast.show({ | |
| 24620 text: "Request failed. Reason: "+reason, | |
| 24621 duration: 3000, | |
| 24622 }); | |
| 24623 }.bind(this)); | |
| 24624 }, | 24630 }, |
| 24625 | 24631 |
| 24626 _tag: function(task, col) { | 24632 _tag: function(task, col) { |
| 24627 if (!task || !task.tagMap) { | 24633 if (!task || !task.tagMap) { |
| 24628 return undefined; | 24634 return undefined; |
| 24629 } | 24635 } |
| 24630 return task.tagMap[col]; | 24636 return task.tagMap[col]; |
| 24631 }, | 24637 }, |
| 24632 | 24638 |
| 24633 _taskLink: function(taskId) { | 24639 _taskLink: function(taskId) { |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 24889 _calcSize: function() { | 24895 _calcSize: function() { |
| 24890 return this.getBoundingClientRect()[this.dimension] + 'px'; | 24896 return this.getBoundingClientRect()[this.dimension] + 'px'; |
| 24891 } | 24897 } |
| 24892 | 24898 |
| 24893 }); | 24899 }); |
| 24894 | 24900 |
| 24895 </script> | 24901 </script> |
| 24896 <script> | 24902 <script> |
| 24897 | 24903 |
| 24898 /** | 24904 /** |
| 24905 * `Polymer.NeonAnimatableBehavior` is implemented by elements containing anim
ations for use with |
| 24906 * elements implementing `Polymer.NeonAnimationRunnerBehavior`. |
| 24907 * @polymerBehavior |
| 24908 */ |
| 24909 Polymer.NeonAnimatableBehavior = { |
| 24910 |
| 24911 properties: { |
| 24912 |
| 24913 /** |
| 24914 * Animation configuration. See README for more info. |
| 24915 */ |
| 24916 animationConfig: { |
| 24917 type: Object |
| 24918 }, |
| 24919 |
| 24920 /** |
| 24921 * Convenience property for setting an 'entry' animation. Do not set `anim
ationConfig.entry` |
| 24922 * manually if using this. The animated node is set to `this` if using thi
s property. |
| 24923 */ |
| 24924 entryAnimation: { |
| 24925 observer: '_entryAnimationChanged', |
| 24926 type: String |
| 24927 }, |
| 24928 |
| 24929 /** |
| 24930 * Convenience property for setting an 'exit' animation. Do not set `anima
tionConfig.exit` |
| 24931 * manually if using this. The animated node is set to `this` if using thi
s property. |
| 24932 */ |
| 24933 exitAnimation: { |
| 24934 observer: '_exitAnimationChanged', |
| 24935 type: String |
| 24936 } |
| 24937 |
| 24938 }, |
| 24939 |
| 24940 _entryAnimationChanged: function() { |
| 24941 this.animationConfig = this.animationConfig || {}; |
| 24942 this.animationConfig['entry'] = [{ |
| 24943 name: this.entryAnimation, |
| 24944 node: this |
| 24945 }]; |
| 24946 }, |
| 24947 |
| 24948 _exitAnimationChanged: function() { |
| 24949 this.animationConfig = this.animationConfig || {}; |
| 24950 this.animationConfig['exit'] = [{ |
| 24951 name: this.exitAnimation, |
| 24952 node: this |
| 24953 }]; |
| 24954 }, |
| 24955 |
| 24956 _copyProperties: function(config1, config2) { |
| 24957 // shallowly copy properties from config2 to config1 |
| 24958 for (var property in config2) { |
| 24959 config1[property] = config2[property]; |
| 24960 } |
| 24961 }, |
| 24962 |
| 24963 _cloneConfig: function(config) { |
| 24964 var clone = { |
| 24965 isClone: true |
| 24966 }; |
| 24967 this._copyProperties(clone, config); |
| 24968 return clone; |
| 24969 }, |
| 24970 |
| 24971 _getAnimationConfigRecursive: function(type, map, allConfigs) { |
| 24972 if (!this.animationConfig) { |
| 24973 return; |
| 24974 } |
| 24975 |
| 24976 if(this.animationConfig.value && typeof this.animationConfig.value === 'fu
nction') { |
| 24977 this._warn(this._logf('playAnimation', "Please put 'animationConfig' ins
ide of your components 'properties' object instead of outside of it.")); |
| 24978 return; |
| 24979 } |
| 24980 |
| 24981 // type is optional |
| 24982 var thisConfig; |
| 24983 if (type) { |
| 24984 thisConfig = this.animationConfig[type]; |
| 24985 } else { |
| 24986 thisConfig = this.animationConfig; |
| 24987 } |
| 24988 |
| 24989 if (!Array.isArray(thisConfig)) { |
| 24990 thisConfig = [thisConfig]; |
| 24991 } |
| 24992 |
| 24993 // iterate animations and recurse to process configurations from child nod
es |
| 24994 if (thisConfig) { |
| 24995 for (var config, index = 0; config = thisConfig[index]; index++) { |
| 24996 if (config.animatable) { |
| 24997 config.animatable._getAnimationConfigRecursive(config.type || type,
map, allConfigs); |
| 24998 } else { |
| 24999 if (config.id) { |
| 25000 var cachedConfig = map[config.id]; |
| 25001 if (cachedConfig) { |
| 25002 // merge configurations with the same id, making a clone lazily |
| 25003 if (!cachedConfig.isClone) { |
| 25004 map[config.id] = this._cloneConfig(cachedConfig) |
| 25005 cachedConfig = map[config.id]; |
| 25006 } |
| 25007 this._copyProperties(cachedConfig, config); |
| 25008 } else { |
| 25009 // put any configs with an id into a map |
| 25010 map[config.id] = config; |
| 25011 } |
| 25012 } else { |
| 25013 allConfigs.push(config); |
| 25014 } |
| 25015 } |
| 25016 } |
| 25017 } |
| 25018 }, |
| 25019 |
| 25020 /** |
| 25021 * An element implementing `Polymer.NeonAnimationRunnerBehavior` calls this
method to configure |
| 25022 * an animation with an optional type. Elements implementing `Polymer.NeonAn
imatableBehavior` |
| 25023 * should define the property `animationConfig`, which is either a configura
tion object |
| 25024 * or a map of animation type to array of configuration objects. |
| 25025 */ |
| 25026 getAnimationConfig: function(type) { |
| 25027 var map = {}; |
| 25028 var allConfigs = []; |
| 25029 this._getAnimationConfigRecursive(type, map, allConfigs); |
| 25030 // append the configurations saved in the map to the array |
| 25031 for (var key in map) { |
| 25032 allConfigs.push(map[key]); |
| 25033 } |
| 25034 return allConfigs; |
| 25035 } |
| 25036 |
| 25037 }; |
| 25038 |
| 25039 </script> |
| 25040 <script> |
| 25041 |
| 25042 /** |
| 25043 * `Polymer.NeonAnimationRunnerBehavior` adds a method to run animations. |
| 25044 * |
| 25045 * @polymerBehavior Polymer.NeonAnimationRunnerBehavior |
| 25046 */ |
| 25047 Polymer.NeonAnimationRunnerBehaviorImpl = { |
| 25048 |
| 25049 _configureAnimations: function(configs) { |
| 25050 var results = []; |
| 25051 if (configs.length > 0) { |
| 25052 for (var config, index = 0; config = configs[index]; index++) { |
| 25053 var neonAnimation = document.createElement(config.name); |
| 25054 // is this element actually a neon animation? |
| 25055 if (neonAnimation.isNeonAnimation) { |
| 25056 var result = null; |
| 25057 // configuration or play could fail if polyfills aren't loaded |
| 25058 try { |
| 25059 result = neonAnimation.configure(config); |
| 25060 // Check if we have an Effect rather than an Animation |
| 25061 if (typeof result.cancel != 'function') { |
| 25062 result = document.timeline.play(result); |
| 25063 } |
| 25064 } catch (e) { |
| 25065 result = null; |
| 25066 console.warn('Couldnt play', '(', config.name, ').', e); |
| 25067 } |
| 25068 if (result) { |
| 25069 results.push({ |
| 25070 neonAnimation: neonAnimation, |
| 25071 config: config, |
| 25072 animation: result, |
| 25073 }); |
| 25074 } |
| 25075 } else { |
| 25076 console.warn(this.is + ':', config.name, 'not found!'); |
| 25077 } |
| 25078 } |
| 25079 } |
| 25080 return results; |
| 25081 }, |
| 25082 |
| 25083 _shouldComplete: function(activeEntries) { |
| 25084 var finished = true; |
| 25085 for (var i = 0; i < activeEntries.length; i++) { |
| 25086 if (activeEntries[i].animation.playState != 'finished') { |
| 25087 finished = false; |
| 25088 break; |
| 25089 } |
| 25090 } |
| 25091 return finished; |
| 25092 }, |
| 25093 |
| 25094 _complete: function(activeEntries) { |
| 25095 for (var i = 0; i < activeEntries.length; i++) { |
| 25096 activeEntries[i].neonAnimation.complete(activeEntries[i].config); |
| 25097 } |
| 25098 for (var i = 0; i < activeEntries.length; i++) { |
| 25099 activeEntries[i].animation.cancel(); |
| 25100 } |
| 25101 }, |
| 25102 |
| 25103 /** |
| 25104 * Plays an animation with an optional `type`. |
| 25105 * @param {string=} type |
| 25106 * @param {!Object=} cookie |
| 25107 */ |
| 25108 playAnimation: function(type, cookie) { |
| 25109 var configs = this.getAnimationConfig(type); |
| 25110 if (!configs) { |
| 25111 return; |
| 25112 } |
| 25113 this._active = this._active || {}; |
| 25114 if (this._active[type]) { |
| 25115 this._complete(this._active[type]); |
| 25116 delete this._active[type]; |
| 25117 } |
| 25118 |
| 25119 var activeEntries = this._configureAnimations(configs); |
| 25120 |
| 25121 if (activeEntries.length == 0) { |
| 25122 this.fire('neon-animation-finish', cookie, {bubbles: false}); |
| 25123 return; |
| 25124 } |
| 25125 |
| 25126 this._active[type] = activeEntries; |
| 25127 |
| 25128 for (var i = 0; i < activeEntries.length; i++) { |
| 25129 activeEntries[i].animation.onfinish = function() { |
| 25130 if (this._shouldComplete(activeEntries)) { |
| 25131 this._complete(activeEntries); |
| 25132 delete this._active[type]; |
| 25133 this.fire('neon-animation-finish', cookie, {bubbles: false}); |
| 25134 } |
| 25135 }.bind(this); |
| 25136 } |
| 25137 }, |
| 25138 |
| 25139 /** |
| 25140 * Cancels the currently running animations. |
| 25141 */ |
| 25142 cancelAnimation: function() { |
| 25143 for (var k in this._animations) { |
| 25144 this._animations[k].cancel(); |
| 25145 } |
| 25146 this._animations = {}; |
| 25147 } |
| 25148 }; |
| 25149 |
| 25150 /** @polymerBehavior Polymer.NeonAnimationRunnerBehavior */ |
| 25151 Polymer.NeonAnimationRunnerBehavior = [ |
| 25152 Polymer.NeonAnimatableBehavior, |
| 25153 Polymer.NeonAnimationRunnerBehaviorImpl |
| 25154 ]; |
| 25155 </script> |
| 25156 <script> |
| 25157 |
| 25158 /** |
| 25159 Use `Polymer.PaperDialogBehavior` and `paper-dialog-shared-styles.html` to imple
ment a Material Design |
| 25160 dialog. |
| 25161 |
| 25162 For example, if `<paper-dialog-impl>` implements this behavior: |
| 25163 |
| 25164 <paper-dialog-impl> |
| 25165 <h2>Header</h2> |
| 25166 <div>Dialog body</div> |
| 25167 <div class="buttons"> |
| 25168 <paper-button dialog-dismiss>Cancel</paper-button> |
| 25169 <paper-button dialog-confirm>Accept</paper-button> |
| 25170 </div> |
| 25171 </paper-dialog-impl> |
| 25172 |
| 25173 `paper-dialog-shared-styles.html` provide styles for a header, content area, and
an action area for buttons. |
| 25174 Use the `<h2>` tag for the header and the `buttons` class for the action area. Y
ou can use the |
| 25175 `paper-dialog-scrollable` element (in its own repository) if you need a scrollin
g content area. |
| 25176 |
| 25177 Use the `dialog-dismiss` and `dialog-confirm` attributes on interactive controls
to close the |
| 25178 dialog. If the user dismisses the dialog with `dialog-confirm`, the `closingReas
on` will update |
| 25179 to include `confirmed: true`. |
| 25180 |
| 25181 ### Accessibility |
| 25182 |
| 25183 This element has `role="dialog"` by default. Depending on the context, it may be
more appropriate |
| 25184 to override this attribute with `role="alertdialog"`. |
| 25185 |
| 25186 If `modal` is set, the element will prevent the focus from exiting the element. |
| 25187 It will also ensure that focus remains in the dialog. |
| 25188 |
| 25189 @hero hero.svg |
| 25190 @demo demo/index.html |
| 25191 @polymerBehavior Polymer.PaperDialogBehavior |
| 25192 */ |
| 25193 |
| 25194 Polymer.PaperDialogBehaviorImpl = { |
| 25195 |
| 25196 hostAttributes: { |
| 25197 'role': 'dialog', |
| 25198 'tabindex': '-1' |
| 25199 }, |
| 25200 |
| 25201 properties: { |
| 25202 |
| 25203 /** |
| 25204 * If `modal` is true, this implies `no-cancel-on-outside-click`, `no-canc
el-on-esc-key` and `with-backdrop`. |
| 25205 */ |
| 25206 modal: { |
| 25207 type: Boolean, |
| 25208 value: false |
| 25209 } |
| 25210 |
| 25211 }, |
| 25212 |
| 25213 observers: [ |
| 25214 '_modalChanged(modal, _readied)' |
| 25215 ], |
| 25216 |
| 25217 listeners: { |
| 25218 'tap': '_onDialogClick' |
| 25219 }, |
| 25220 |
| 25221 ready: function () { |
| 25222 // Only now these properties can be read. |
| 25223 this.__prevNoCancelOnOutsideClick = this.noCancelOnOutsideClick; |
| 25224 this.__prevNoCancelOnEscKey = this.noCancelOnEscKey; |
| 25225 this.__prevWithBackdrop = this.withBackdrop; |
| 25226 }, |
| 25227 |
| 25228 _modalChanged: function(modal, readied) { |
| 25229 // modal implies noCancelOnOutsideClick, noCancelOnEscKey and withBackdrop
. |
| 25230 // We need to wait for the element to be ready before we can read the |
| 25231 // properties values. |
| 25232 if (!readied) { |
| 25233 return; |
| 25234 } |
| 25235 |
| 25236 if (modal) { |
| 25237 this.__prevNoCancelOnOutsideClick = this.noCancelOnOutsideClick; |
| 25238 this.__prevNoCancelOnEscKey = this.noCancelOnEscKey; |
| 25239 this.__prevWithBackdrop = this.withBackdrop; |
| 25240 this.noCancelOnOutsideClick = true; |
| 25241 this.noCancelOnEscKey = true; |
| 25242 this.withBackdrop = true; |
| 25243 } else { |
| 25244 // If the value was changed to false, let it false. |
| 25245 this.noCancelOnOutsideClick = this.noCancelOnOutsideClick && |
| 25246 this.__prevNoCancelOnOutsideClick; |
| 25247 this.noCancelOnEscKey = this.noCancelOnEscKey && |
| 25248 this.__prevNoCancelOnEscKey; |
| 25249 this.withBackdrop = this.withBackdrop && this.__prevWithBackdrop; |
| 25250 } |
| 25251 }, |
| 25252 |
| 25253 _updateClosingReasonConfirmed: function(confirmed) { |
| 25254 this.closingReason = this.closingReason || {}; |
| 25255 this.closingReason.confirmed = confirmed; |
| 25256 }, |
| 25257 |
| 25258 /** |
| 25259 * Will dismiss the dialog if user clicked on an element with dialog-dismiss |
| 25260 * or dialog-confirm attribute. |
| 25261 */ |
| 25262 _onDialogClick: function(event) { |
| 25263 // Search for the element with dialog-confirm or dialog-dismiss, |
| 25264 // from the root target until this (excluded). |
| 25265 var path = Polymer.dom(event).path; |
| 25266 for (var i = 0; i < path.indexOf(this); i++) { |
| 25267 var target = path[i]; |
| 25268 if (target.hasAttribute && (target.hasAttribute('dialog-dismiss') || tar
get.hasAttribute('dialog-confirm'))) { |
| 25269 this._updateClosingReasonConfirmed(target.hasAttribute('dialog-confirm
')); |
| 25270 this.close(); |
| 25271 event.stopPropagation(); |
| 25272 break; |
| 25273 } |
| 25274 } |
| 25275 } |
| 25276 |
| 25277 }; |
| 25278 |
| 25279 /** @polymerBehavior */ |
| 25280 Polymer.PaperDialogBehavior = [Polymer.IronOverlayBehavior, Polymer.PaperDialo
gBehaviorImpl]; |
| 25281 |
| 25282 </script> |
| 25283 |
| 25284 |
| 25285 <dom-module id="paper-dialog-shared-styles" assetpath="/res/imp/bower_components
/paper-dialog-behavior/"> |
| 25286 <template> |
| 25287 <style> |
| 25288 :host { |
| 25289 display: block; |
| 25290 margin: 24px 40px; |
| 25291 |
| 25292 background: var(--paper-dialog-background-color, --primary-background-co
lor); |
| 25293 color: var(--paper-dialog-color, --primary-text-color); |
| 25294 |
| 25295 @apply(--paper-font-body1); |
| 25296 @apply(--shadow-elevation-16dp); |
| 25297 @apply(--paper-dialog); |
| 25298 } |
| 25299 |
| 25300 :host > ::content > * { |
| 25301 margin-top: 20px; |
| 25302 padding: 0 24px; |
| 25303 } |
| 25304 |
| 25305 :host > ::content > .no-padding { |
| 25306 padding: 0; |
| 25307 } |
| 25308 |
| 25309 :host > ::content > *:first-child { |
| 25310 margin-top: 24px; |
| 25311 } |
| 25312 |
| 25313 :host > ::content > *:last-child { |
| 25314 margin-bottom: 24px; |
| 25315 } |
| 25316 |
| 25317 :host > ::content h2 { |
| 25318 position: relative; |
| 25319 margin: 0; |
| 25320 @apply(--paper-font-title); |
| 25321 |
| 25322 @apply(--paper-dialog-title); |
| 25323 } |
| 25324 |
| 25325 :host > ::content .buttons { |
| 25326 position: relative; |
| 25327 padding: 8px 8px 8px 24px; |
| 25328 margin: 0; |
| 25329 |
| 25330 color: var(--paper-dialog-button-color, --primary-color); |
| 25331 |
| 25332 @apply(--layout-horizontal); |
| 25333 @apply(--layout-end-justified); |
| 25334 } |
| 25335 </style> |
| 25336 </template> |
| 25337 </dom-module> |
| 25338 |
| 25339 |
| 25340 <dom-module id="paper-dialog" assetpath="/res/imp/bower_components/paper-dialog/
"> |
| 25341 <template> |
| 25342 <style include="paper-dialog-shared-styles"></style> |
| 25343 <content></content> |
| 25344 </template> |
| 25345 </dom-module> |
| 25346 |
| 25347 <script> |
| 25348 |
| 25349 (function() { |
| 25350 |
| 25351 Polymer({ |
| 25352 |
| 25353 is: 'paper-dialog', |
| 25354 |
| 25355 behaviors: [ |
| 25356 Polymer.PaperDialogBehavior, |
| 25357 Polymer.NeonAnimationRunnerBehavior |
| 25358 ], |
| 25359 |
| 25360 listeners: { |
| 25361 'neon-animation-finish': '_onNeonAnimationFinish' |
| 25362 }, |
| 25363 |
| 25364 _renderOpened: function() { |
| 25365 this.cancelAnimation(); |
| 25366 this.playAnimation('entry'); |
| 25367 }, |
| 25368 |
| 25369 _renderClosed: function() { |
| 25370 this.cancelAnimation(); |
| 25371 this.playAnimation('exit'); |
| 25372 }, |
| 25373 |
| 25374 _onNeonAnimationFinish: function() { |
| 25375 if (this.opened) { |
| 25376 this._finishRenderOpened(); |
| 25377 } else { |
| 25378 this._finishRenderClosed(); |
| 25379 } |
| 25380 } |
| 25381 |
| 25382 }); |
| 25383 |
| 25384 })(); |
| 25385 |
| 25386 </script> |
| 25387 <script> |
| 25388 |
| 25389 /** |
| 24899 * `Polymer.IronMenuBehavior` implements accessible menu behavior. | 25390 * `Polymer.IronMenuBehavior` implements accessible menu behavior. |
| 24900 * | 25391 * |
| 24901 * @demo demo/index.html | 25392 * @demo demo/index.html |
| 24902 * @polymerBehavior Polymer.IronMenuBehavior | 25393 * @polymerBehavior Polymer.IronMenuBehavior |
| 24903 */ | 25394 */ |
| 24904 Polymer.IronMenuBehaviorImpl = { | 25395 Polymer.IronMenuBehaviorImpl = { |
| 24905 | 25396 |
| 24906 properties: { | 25397 properties: { |
| 24907 | 25398 |
| 24908 /** | 25399 /** |
| (...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 26263 margin-bottom: 5px; | 26754 margin-bottom: 5px; |
| 26264 } | 26755 } |
| 26265 td, th { | 26756 td, th { |
| 26266 border: 1px solid #BBB; | 26757 border: 1px solid #BBB; |
| 26267 padding: 5px; | 26758 padding: 5px; |
| 26268 } | 26759 } |
| 26269 | 26760 |
| 26270 .quarantined, .failed_task { | 26761 .quarantined, .failed_task { |
| 26271 background-color: #ffdddd; | 26762 background-color: #ffdddd; |
| 26272 } | 26763 } |
| 26273 .dead { | 26764 .dead, .bot_died { |
| 26274 background-color: #cccccc; | 26765 background-color: #cccccc; |
| 26275 } | 26766 } |
| 26276 | 26767 |
| 26277 .message { | 26768 .message { |
| 26278 white-space: pre-line; | 26769 white-space: pre-line; |
| 26279 font-family: monospace; | 26770 font-family: monospace; |
| 26280 } | 26771 } |
| 26281 | 26772 |
| 26282 .bot_state { | 26773 .bot_state { |
| 26283 white-space: pre; | 26774 white-space: pre; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 26306 } | 26797 } |
| 26307 | 26798 |
| 26308 paper-tab.iron-selected { | 26799 paper-tab.iron-selected { |
| 26309 background-color: #A6CEE3; | 26800 background-color: #A6CEE3; |
| 26310 border: 3px solid #1F78B4; | 26801 border: 3px solid #1F78B4; |
| 26311 color: #000; | 26802 color: #000; |
| 26312 font-weight: bold; | 26803 font-weight: bold; |
| 26313 text-decoration: underline; | 26804 text-decoration: underline; |
| 26314 } | 26805 } |
| 26315 | 26806 |
| 26807 paper-dialog { |
| 26808 border-radius: 6px; |
| 26809 } |
| 26810 |
| 26316 </style> | 26811 </style> |
| 26317 | 26812 |
| 26318 <url-param name="id" value="{{bot_id}}"> | 26813 <url-param name="id" value="{{bot_id}}"> |
| 26319 </url-param> | 26814 </url-param> |
| 26320 <url-param name="show_all_events" value="{{_show_all}}"> | 26815 <url-param name="show_all_events" value="{{_show_all}}"> |
| 26321 </url-param> | 26816 </url-param> |
| 26322 <url-param name="selected" value="{{_selected}}"> | 26817 <url-param name="selected" value="{{_selected}}"> |
| 26323 </url-param> | 26818 </url-param> |
| 26324 <url-param name="show_state" value="{{_show_state}}"> | 26819 <url-param name="show_state" value="{{_show_state}}"> |
| 26325 </url-param> | 26820 </url-param> |
| 26326 | 26821 |
| 26327 <swarming-app client_id="[[client_id]]" auth_headers="{{_auth_headers}}" per
missions="{{_permissions}}" signed_in="{{_signed_in}}" busy="[[_busy]]" name="Sw
arming Bot Page"> | 26822 <swarming-app client_id="[[client_id]]" auth_headers="{{_auth_headers}}" per
missions="{{_permissions}}" signed_in="{{_signed_in}}" busy="[[_busy]]" name="Sw
arming Bot Page"> |
| 26328 | 26823 |
| 26329 <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2> | 26824 <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2> |
| 26330 | 26825 |
| 26331 <div hidden$="[[_not(_signed_in)]]"> | 26826 <div hidden$="[[_not(_signed_in)]]"> |
| 26332 | 26827 |
| 26333 <bot-page-data auth_headers="[[_auth_headers]]" bot_id="[[bot_id]]" bot=
"{{_bot}}" busy="{{_busy}}" events="{{_events}}" tasks="{{_tasks}}"> | 26828 <bot-page-data id="data" auth_headers="[[_auth_headers]]" bot_id="[[bot_
id]]" bot="{{_bot}}" busy="{{_busy}}" events="{{_events}}" tasks="{{_tasks}}"> |
| 26334 </bot-page-data> | 26829 </bot-page-data> |
| 26335 | 26830 |
| 26336 <div class="header horizontal layout"> | 26831 <div class="header horizontal layout"> |
| 26337 <paper-input class="id_input" label="Bot id" value="{{bot_id}}"></pape
r-input> | 26832 <paper-input class="id_input" label="Bot id" value="{{bot_id}}"></pape
r-input> |
| 26338 <button> | 26833 <button on-click="_refresh"> |
| 26339 <iron-icon class="refresh" icon="icons:refresh"></iron-icon> | 26834 <iron-icon class="refresh" icon="icons:refresh"></iron-icon> |
| 26340 </button> | 26835 </button> |
| 26341 </div> | 26836 </div> |
| 26342 | 26837 |
| 26343 <div> | 26838 <div> |
| 26344 <table> | 26839 <table> |
| 26345 <tbody><tr class$="[[_isDead(_bot)]]"> | 26840 <tbody><tr class$="[[_isDead(_bot)]]"> |
| 26346 <td>Last Seen</td> | 26841 <td>Last Seen</td> |
| 26347 <td title="[[_bot.human_last_seen_ts]]"> | 26842 <td title="[[_bot.human_last_seen_ts]]"> |
| 26348 [[_timeDiffExact(_bot.last_seen_ts)]] ago</td> | 26843 [[_timeDiffExact(_bot.last_seen_ts)]] ago</td> |
| 26349 <td> | 26844 <td> |
| 26350 | 26845 |
| 26351 <template is="dom-if" if="[[_canShutdown(_bot,_permissions)]]"> | 26846 <template is="dom-if" if="[[_canShutdown(_bot,_permissions)]]"> |
| 26352 <button class="raised"> | 26847 <button class="raised" on-click="_promptShutdown"> |
| 26353 Shut Down Gracefully | 26848 Shut Down Gracefully |
| 26354 </button> | 26849 </button> |
| 26355 </template> | 26850 </template> |
| 26356 <template is="dom-if" if="[[_canDelete(_bot,_permissions)]]"> | 26851 <template is="dom-if" if="[[_canDelete(_bot,_permissions)]]"> |
| 26357 <button class="raised"> | 26852 <button class="raised" on-click="_promptDelete"> |
| 26358 Delete | 26853 Delete |
| 26359 </button> | 26854 </button> |
| 26360 </template> | 26855 </template> |
| 26361 </td> | 26856 </td> |
| 26362 </tr> | 26857 </tr> |
| 26363 <template is="dom-if" if="[[_bot.quarantined]]"> | 26858 <template is="dom-if" if="[[_bot.quarantined]]"> |
| 26364 <tr class="quarantined"> | 26859 <tr class="quarantined"> |
| 26365 <td>Quarantined</td> | 26860 <td>Quarantined</td> |
| 26366 <td colspan="2">[[_quarantineMessage(_bot)]]</td> | 26861 <td colspan="2">[[_quarantineMessage(_bot)]]</td> |
| 26367 </tr> | 26862 </tr> |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 26450 <thead> | 26945 <thead> |
| 26451 <tr> | 26946 <tr> |
| 26452 <th>Task</th> | 26947 <th>Task</th> |
| 26453 <th>Started</th> | 26948 <th>Started</th> |
| 26454 <th>Duration</th> | 26949 <th>Duration</th> |
| 26455 <th>Result</th> | 26950 <th>Result</th> |
| 26456 </tr> | 26951 </tr> |
| 26457 </thead> | 26952 </thead> |
| 26458 <tbody> | 26953 <tbody> |
| 26459 <template is="dom-repeat" items="{{_tasks}}" as="task"> | 26954 <template is="dom-repeat" items="{{_tasks}}" as="task"> |
| 26460 <tr> | 26955 <tr class$="[[_taskClass(task)]]"> |
| 26461 <td><a target="_blank" href$="[[_taskLink(task.task_id)]]">[[t
ask.name]]</a></td> | 26956 <td><a target="_blank" href$="[[_taskLink(task.task_id)]]">[[t
ask.name]]</a></td> |
| 26462 <td>[[task.human_started_ts]]</td> | 26957 <td>[[task.human_started_ts]]</td> |
| 26463 <td title="[[task.human_completed_ts]]">[[task.human_duration]
]</td> | 26958 <td title="[[task.human_completed_ts]]">[[task.human_duration]
]</td> |
| 26464 <td>[[task.state]]</td> | 26959 <td>[[task.state]]</td> |
| 26465 </tr> | 26960 </tr> |
| 26466 </template> | 26961 </template> |
| 26467 </tbody> | 26962 </tbody> |
| 26468 </table> | 26963 </table> |
| 26469 </template> | 26964 </template> |
| 26470 | 26965 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 26489 <td> | 26984 <td> |
| 26490 <a target="_blank" href$="[[_luciLink(_bot.version)]]">[[_sh
orten(_bot.version,'8')]]</a> | 26985 <a target="_blank" href$="[[_luciLink(_bot.version)]]">[[_sh
orten(_bot.version,'8')]]</a> |
| 26491 </td> | 26986 </td> |
| 26492 </tr> | 26987 </tr> |
| 26493 </template> | 26988 </template> |
| 26494 </tbody> | 26989 </tbody> |
| 26495 </table> | 26990 </table> |
| 26496 </template> | 26991 </template> |
| 26497 </div> | 26992 </div> |
| 26498 | 26993 |
| 26994 </swarming-app> |
| 26499 | 26995 |
| 26500 </swarming-app> | 26996 <paper-dialog id="prompt" modal="" on-iron-overlay-closed="_promptClosed"> |
| 26997 <h2>Are you sure?</h2> |
| 26998 <div>Are you sure you want to [[_dialogPrompt]]?</div> |
| 26999 <div class="buttons"> |
| 27000 <paper-button dialog-dismiss="" autofocus="">No</paper-button> |
| 27001 <paper-button dialog-confirm="">Yes</paper-button> |
| 27002 </div> |
| 27003 </paper-dialog> |
| 27004 |
| 27005 <paper-toast id="toast"></paper-toast> |
| 26501 | 27006 |
| 26502 </template> | 27007 </template> |
| 26503 <script> | 27008 <script> |
| 26504 (function(){ | 27009 (function(){ |
| 26505 | 27010 |
| 26506 | 27011 |
| 26507 Polymer({ | 27012 Polymer({ |
| 26508 is: 'bot-page', | 27013 is: 'bot-page', |
| 26509 | 27014 |
| 26510 behaviors: [ | 27015 behaviors: [ |
| 26511 SwarmingBehaviors.BotPageBehavior, | 27016 SwarmingBehaviors.BotPageBehavior, |
| 26512 ], | 27017 ], |
| 26513 | 27018 |
| 26514 properties: { | 27019 properties: { |
| 26515 bot_id: { | 27020 bot_id: { |
| 26516 type: String, | 27021 type: String, |
| 26517 }, | 27022 }, |
| 26518 client_id: { | 27023 client_id: { |
| 26519 type: String, | 27024 type: String, |
| 26520 }, | 27025 }, |
| 26521 | 27026 |
| 27027 _auth_headers: { |
| 27028 type: Object, |
| 27029 }, |
| 26522 _bot: { | 27030 _bot: { |
| 26523 type: Object, | 27031 type: Object, |
| 26524 }, | 27032 }, |
| 27033 _dialogPrompt: { |
| 27034 type: String, |
| 27035 value: "", |
| 27036 }, |
| 26525 _selected: { | 27037 _selected: { |
| 26526 type: Number, | 27038 type: Number, |
| 26527 }, | 27039 }, |
| 26528 _show_all: { | 27040 _show_all: { |
| 26529 type: Boolean, | 27041 type: Boolean, |
| 26530 }, | 27042 }, |
| 26531 _show_state: { | 27043 _show_state: { |
| 26532 type: Boolean, | 27044 type: Boolean, |
| 26533 } | 27045 } |
| 26534 }, | 27046 }, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 26545 return bot && !bot.is_dead && permissions.terminate_bot; | 27057 return bot && !bot.is_dead && permissions.terminate_bot; |
| 26546 }, | 27058 }, |
| 26547 | 27059 |
| 26548 _concat: function(arr) { | 27060 _concat: function(arr) { |
| 26549 if (!arr) { | 27061 if (!arr) { |
| 26550 return ""; | 27062 return ""; |
| 26551 } | 27063 } |
| 26552 return arr.join(" | "); | 27064 return arr.join(" | "); |
| 26553 }, | 27065 }, |
| 26554 | 27066 |
| 27067 _deleteBot: function() { |
| 27068 this.$.toast.text="Deleting "+this.bot_id; |
| 27069 this._postWithToast("/_ah/api/swarming/v1/bot/"+this.bot_id+"/delete", |
| 27070 this.$.toast, this._auth_headers); |
| 27071 }, |
| 27072 |
| 26555 _eventList(events, showAll) { | 27073 _eventList(events, showAll) { |
| 26556 if (!events) { | 27074 if (!events) { |
| 26557 return []; | 27075 return []; |
| 26558 } | 27076 } |
| 26559 return events.filter(function(e){ | 27077 return events.filter(function(e){ |
| 26560 return showAll || e.message; | 27078 return showAll || e.message; |
| 26561 }); | 27079 }); |
| 26562 }, | 27080 }, |
| 26563 | 27081 |
| 26564 _isDead(bot){ | 27082 _isDead(bot){ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 26581 return 1; | 27099 return 1; |
| 26582 } | 27100 } |
| 26583 return 1 + arr.length; | 27101 return 1 + arr.length; |
| 26584 }, | 27102 }, |
| 26585 | 27103 |
| 26586 _prettyPrint: function(obj) { | 27104 _prettyPrint: function(obj) { |
| 26587 obj = obj || {}; | 27105 obj = obj || {}; |
| 26588 return JSON.stringify(obj, null, 2); | 27106 return JSON.stringify(obj, null, 2); |
| 26589 }, | 27107 }, |
| 26590 | 27108 |
| 27109 _promptClosed: function(e) { |
| 27110 if (e.detail.confirmed) { |
| 27111 if (this._dialogPrompt.startsWith("shut down")) { |
| 27112 this._shutdownBot(); |
| 27113 } else { |
| 27114 this._deleteBot(); |
| 27115 } |
| 27116 } |
| 27117 }, |
| 27118 |
| 27119 _promptDelete: function() { |
| 27120 this.set("_dialogPrompt", "delete "+this.bot_id); |
| 27121 this.$.prompt.open(); |
| 27122 }, |
| 27123 |
| 27124 _promptShutdown: function() { |
| 27125 this.set("_dialogPrompt", "shut down "+this.bot_id); |
| 27126 this.$.prompt.open(); |
| 27127 }, |
| 27128 |
| 26591 _quarantineMessage: function(bot) { | 27129 _quarantineMessage: function(bot) { |
| 26592 if (bot && bot.quarantined) { | 27130 if (bot && bot.quarantined) { |
| 26593 var msg = bot.state.quarantined; | 27131 var msg = bot.state.quarantined; |
| 26594 // Sometimes, the quarantined message is actually in "error". This | 27132 // Sometimes, the quarantined message is actually in "error". This |
| 26595 // happens when the bot code has thrown an exception. | 27133 // happens when the bot code has thrown an exception. |
| 26596 if (msg === undefined || msg === "true" || msg === true) { | 27134 if (msg === undefined || msg === "true" || msg === true) { |
| 26597 msg = this._attribute(bot, "error"); | 27135 msg = this._attribute(bot, "error"); |
| 26598 } | 27136 } |
| 26599 return msg || "True"; | 27137 return msg || "True"; |
| 26600 } | 27138 } |
| 26601 return ""; | 27139 return ""; |
| 26602 }, | 27140 }, |
| 26603 | 27141 |
| 27142 _refresh: function() { |
| 27143 this.$.data.request(); |
| 27144 }, |
| 27145 |
| 26604 _shorten: function(str, length) { | 27146 _shorten: function(str, length) { |
| 26605 if (!str || ! length) { | 27147 if (!str || ! length) { |
| 26606 return ""; | 27148 return ""; |
| 26607 } | 27149 } |
| 26608 return str.substring(0, length); | 27150 return str.substring(0, length); |
| 26609 }, | 27151 }, |
| 26610 | 27152 |
| 27153 _shutdownBot: function() { |
| 27154 this.$.toast.text="Shutting down "+this.bot_id; |
| 27155 this._postWithToast("/_ah/api/swarming/v1/bot/"+this.bot_id+"/terminate"
, |
| 27156 this.$.toast, this._auth_headers); |
| 27157 }, |
| 27158 |
| 26611 _task: function(bot) { | 27159 _task: function(bot) { |
| 26612 return (bot && bot.task_id) || "idle"; | 27160 return (bot && bot.task_id) || "idle"; |
| 26613 }, | 27161 }, |
| 26614 | 27162 |
| 27163 _taskClass: function(task) { |
| 27164 if (task && task.internal_failure) { |
| 27165 return "bot_died"; |
| 27166 } |
| 27167 if (task && task.failure) { |
| 27168 return "failed_task"; |
| 27169 } |
| 27170 return ""; |
| 27171 }, |
| 27172 |
| 26615 _taskLink: function(task_id) { | 27173 _taskLink: function(task_id) { |
| 26616 // TODO(kjlubick): Migrate this to /newui/ when ready | 27174 // TODO(kjlubick): Migrate this to /newui/ when ready |
| 26617 if (task_id) { | 27175 if (task_id) { |
| 26618 return "/user/task/" + task_id; | 27176 return "/user/task/" + task_id; |
| 26619 } | 27177 } |
| 26620 return undefined; | 27178 return undefined; |
| 26621 }, | 27179 }, |
| 26622 | 27180 |
| 26623 _toggleState: function() { | 27181 _toggleState: function() { |
| 26624 this.set("_show_state", !this._show_state); | 27182 this.set("_show_state", !this._show_state); |
| 26625 } | 27183 } |
| 26626 | 27184 |
| 26627 }); | 27185 }); |
| 26628 })(); | 27186 })(); |
| 26629 </script> | 27187 </script> |
| 26630 </dom-module></div></body></html> | 27188 </dom-module></div></body></html> |
| OLD | NEW |