| 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, msg, auth_headers) { |
| 8153 // Keep toast displayed until we hear back from the request. |
| 8154 sk.errorMessage(msg, 0); |
| 8155 |
| 8156 sk.request("POST", url, undefined, auth_headers).then(function(response)
{ |
| 8157 sk.errorMessage("Request sent. Response: "+response, 3000); |
| 8158 }.bind(this)).catch(function(reason) { |
| 8159 console.log("Request failed", reason); |
| 8160 sk.errorMessage("Request failed. Reason: "+reason, 5000); |
| 8161 }.bind(this)); |
| 8162 } |
| 8149 }; | 8163 }; |
| 8150 })(); | 8164 })(); |
| 8151 </script> | 8165 </script> |
| 8152 <script> | 8166 <script> |
| 8153 Polymer.AppLayout = Polymer.AppLayout || {}; | 8167 Polymer.AppLayout = Polymer.AppLayout || {}; |
| 8154 | 8168 |
| 8155 Polymer.AppLayout._scrollEffects = Polymer.AppLayout._scrollEffects || {}; | 8169 Polymer.AppLayout._scrollEffects = Polymer.AppLayout._scrollEffects || {}; |
| 8156 | 8170 |
| 8157 Polymer.AppLayout.scrollTimingFunction = function easeOutQuad(t, b, c, d) { | 8171 Polymer.AppLayout.scrollTimingFunction = function easeOutQuad(t, b, c, d) { |
| 8158 t /= d; | 8172 t /= d; |
| (...skipping 15800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 23959 Fired when the animation finishes. | 23973 Fired when the animation finishes. |
| 23960 This is useful if you want to wait until | 23974 This is useful if you want to wait until |
| 23961 the ripple animation finishes to perform some action. | 23975 the ripple animation finishes to perform some action. |
| 23962 | 23976 |
| 23963 @event transitionend | 23977 @event transitionend |
| 23964 Event param: {{node: Object}} detail Contains the animated node. | 23978 Event param: {{node: Object}} detail Contains the animated node. |
| 23965 */ | 23979 */ |
| 23966 }); | 23980 }); |
| 23967 </script> | 23981 </script> |
| 23968 </dom-module> | 23982 </dom-module> |
| 23983 <dom-module id="error-toast" assetpath="/res/imp/common/"> |
| 23984 <template> |
| 23985 <paper-toast id="toast"></paper-toast> |
| 23986 </template> |
| 23987 </dom-module> |
| 23988 |
| 23989 <script> |
| 23990 Polymer({ |
| 23991 is: "error-toast", |
| 23992 ready: function() { |
| 23993 document.addEventListener('error-sk', function(e) { |
| 23994 this.$.toast.close(); |
| 23995 if (e.detail.message) { |
| 23996 this.$.toast.text = e.detail.message; |
| 23997 var duration = 10000; |
| 23998 // duration = 0 is a valid input for "keep open indefinitely". |
| 23999 if (e.detail.duration !== undefined) { |
| 24000 duration = e.detail.duration; |
| 24001 } |
| 24002 this.$.toast.duration = duration; |
| 24003 this.$.toast.show(); |
| 24004 } else { |
| 24005 console.log("Empty message?", e); |
| 24006 } |
| 24007 }.bind(this)); |
| 24008 }, |
| 24009 }); |
| 24010 </script> |
| 23969 <dom-module id="task-filters" assetpath="/res/imp/tasklist/"> | 24011 <dom-module id="task-filters" assetpath="/res/imp/tasklist/"> |
| 23970 <template> | 24012 <template> |
| 23971 <style is="custom-style" include="iron-flex iron-flex-alignment iron-positio
ning query-column-filter-style"> | 24013 <style is="custom-style" include="iron-flex iron-flex-alignment iron-positio
ning query-column-filter-style"> |
| 23972 .item.wide { | 24014 .item.wide { |
| 23973 max-width: 400px; | 24015 max-width: 400px; |
| 23974 } | 24016 } |
| 23975 .selector.wide { | 24017 .selector.wide { |
| 23976 min-width: 275px; | 24018 min-width: 275px; |
| 23977 } | 24019 } |
| 23978 | 24020 |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 24395 </url-param> | 24437 </url-param> |
| 24396 | 24438 |
| 24397 <swarming-app client_id="[[client_id]]" auth_headers="{{_auth_headers}}" per
missions="{{_permissions}}" signed_in="{{_signed_in}}" busy="[[_busy]]" name="Sw
arming Task List"> | 24439 <swarming-app client_id="[[client_id]]" auth_headers="{{_auth_headers}}" per
missions="{{_permissions}}" signed_in="{{_signed_in}}" busy="[[_busy]]" name="Sw
arming Task List"> |
| 24398 | 24440 |
| 24399 <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2> | 24441 <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2> |
| 24400 | 24442 |
| 24401 <div hidden$="[[_not(_signed_in)]]"> | 24443 <div hidden$="[[_not(_signed_in)]]"> |
| 24402 <task-list-data auth_headers="[[_auth_headers]]" query_params="[[_query_
params]]" tasks="{{_items}}" busy="{{_busy}}" primary_map="{{_primary_map}}" pri
mary_arr="{{_primary_arr}}"> | 24444 <task-list-data auth_headers="[[_auth_headers]]" query_params="[[_query_
params]]" tasks="{{_items}}" busy="{{_busy}}" primary_map="{{_primary_map}}" pri
mary_arr="{{_primary_arr}}"> |
| 24403 </task-list-data> | 24445 </task-list-data> |
| 24404 | 24446 |
| 24405 <paper-toast id="toast"></paper-toast> | 24447 <error-toast></error-toast> |
| 24406 | 24448 |
| 24407 <div class="horizontal layout"> | 24449 <div class="horizontal layout"> |
| 24408 | 24450 |
| 24409 <task-filters primary_map="[[_primary_map]]" primary_arr="[[_primary_a
rr]]" columns="{{_columns}}" query_params="{{_query_params}}" filter="{{_filter}
}"> | 24451 <task-filters primary_map="[[_primary_map]]" primary_arr="[[_primary_a
rr]]" columns="{{_columns}}" query_params="{{_query_params}}" filter="{{_filter}
}"> |
| 24410 </task-filters> | 24452 </task-filters> |
| 24411 | 24453 |
| 24412 </div> | 24454 </div> |
| 24413 | 24455 |
| 24414 <table class="task-list"> | 24456 <table class="task-list"> |
| 24415 <thead on-sort_change="_sortChange"> | 24457 <thead on-sort_change="_sortChange"> |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 24595 }, | 24637 }, |
| 24596 | 24638 |
| 24597 _cancelTask: function(e) { | 24639 _cancelTask: function(e) { |
| 24598 var task = e.model.task; | 24640 var task = e.model.task; |
| 24599 if (!task || !task.task_id) { | 24641 if (!task || !task.task_id) { |
| 24600 console.log("Missing task info", task); | 24642 console.log("Missing task info", task); |
| 24601 return | 24643 return |
| 24602 } | 24644 } |
| 24603 var id = task.task_id | 24645 var id = task.task_id |
| 24604 | 24646 |
| 24605 // Keep toast displayed until we hear back from the cancel. | |
| 24606 this.$.toast.duration = 0; | |
| 24607 this.$.toast.text="Canceling task " + id; | |
| 24608 this.$.toast.open(); | |
| 24609 var url = "/_ah/api/swarming/v1/task/" + id +"/cancel"; | 24647 var url = "/_ah/api/swarming/v1/task/" + id +"/cancel"; |
| 24610 sk.request("POST", url, undefined, this._auth_headers).then(function(res
ponse) { | 24648 this._postWithToast(url, "Canceling task " + id, 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 }, | 24649 }, |
| 24625 | 24650 |
| 24626 _tag: function(task, col) { | 24651 _tag: function(task, col) { |
| 24627 if (!task || !task.tagMap) { | 24652 if (!task || !task.tagMap) { |
| 24628 return undefined; | 24653 return undefined; |
| 24629 } | 24654 } |
| 24630 return task.tagMap[col]; | 24655 return task.tagMap[col]; |
| 24631 }, | 24656 }, |
| 24632 | 24657 |
| 24633 _taskLink: function(taskId) { | 24658 _taskLink: function(taskId) { |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 24889 _calcSize: function() { | 24914 _calcSize: function() { |
| 24890 return this.getBoundingClientRect()[this.dimension] + 'px'; | 24915 return this.getBoundingClientRect()[this.dimension] + 'px'; |
| 24891 } | 24916 } |
| 24892 | 24917 |
| 24893 }); | 24918 }); |
| 24894 | 24919 |
| 24895 </script> | 24920 </script> |
| 24896 <script> | 24921 <script> |
| 24897 | 24922 |
| 24898 /** | 24923 /** |
| 24924 * `Polymer.NeonAnimatableBehavior` is implemented by elements containing anim
ations for use with |
| 24925 * elements implementing `Polymer.NeonAnimationRunnerBehavior`. |
| 24926 * @polymerBehavior |
| 24927 */ |
| 24928 Polymer.NeonAnimatableBehavior = { |
| 24929 |
| 24930 properties: { |
| 24931 |
| 24932 /** |
| 24933 * Animation configuration. See README for more info. |
| 24934 */ |
| 24935 animationConfig: { |
| 24936 type: Object |
| 24937 }, |
| 24938 |
| 24939 /** |
| 24940 * Convenience property for setting an 'entry' animation. Do not set `anim
ationConfig.entry` |
| 24941 * manually if using this. The animated node is set to `this` if using thi
s property. |
| 24942 */ |
| 24943 entryAnimation: { |
| 24944 observer: '_entryAnimationChanged', |
| 24945 type: String |
| 24946 }, |
| 24947 |
| 24948 /** |
| 24949 * Convenience property for setting an 'exit' animation. Do not set `anima
tionConfig.exit` |
| 24950 * manually if using this. The animated node is set to `this` if using thi
s property. |
| 24951 */ |
| 24952 exitAnimation: { |
| 24953 observer: '_exitAnimationChanged', |
| 24954 type: String |
| 24955 } |
| 24956 |
| 24957 }, |
| 24958 |
| 24959 _entryAnimationChanged: function() { |
| 24960 this.animationConfig = this.animationConfig || {}; |
| 24961 this.animationConfig['entry'] = [{ |
| 24962 name: this.entryAnimation, |
| 24963 node: this |
| 24964 }]; |
| 24965 }, |
| 24966 |
| 24967 _exitAnimationChanged: function() { |
| 24968 this.animationConfig = this.animationConfig || {}; |
| 24969 this.animationConfig['exit'] = [{ |
| 24970 name: this.exitAnimation, |
| 24971 node: this |
| 24972 }]; |
| 24973 }, |
| 24974 |
| 24975 _copyProperties: function(config1, config2) { |
| 24976 // shallowly copy properties from config2 to config1 |
| 24977 for (var property in config2) { |
| 24978 config1[property] = config2[property]; |
| 24979 } |
| 24980 }, |
| 24981 |
| 24982 _cloneConfig: function(config) { |
| 24983 var clone = { |
| 24984 isClone: true |
| 24985 }; |
| 24986 this._copyProperties(clone, config); |
| 24987 return clone; |
| 24988 }, |
| 24989 |
| 24990 _getAnimationConfigRecursive: function(type, map, allConfigs) { |
| 24991 if (!this.animationConfig) { |
| 24992 return; |
| 24993 } |
| 24994 |
| 24995 if(this.animationConfig.value && typeof this.animationConfig.value === 'fu
nction') { |
| 24996 this._warn(this._logf('playAnimation', "Please put 'animationConfig' ins
ide of your components 'properties' object instead of outside of it.")); |
| 24997 return; |
| 24998 } |
| 24999 |
| 25000 // type is optional |
| 25001 var thisConfig; |
| 25002 if (type) { |
| 25003 thisConfig = this.animationConfig[type]; |
| 25004 } else { |
| 25005 thisConfig = this.animationConfig; |
| 25006 } |
| 25007 |
| 25008 if (!Array.isArray(thisConfig)) { |
| 25009 thisConfig = [thisConfig]; |
| 25010 } |
| 25011 |
| 25012 // iterate animations and recurse to process configurations from child nod
es |
| 25013 if (thisConfig) { |
| 25014 for (var config, index = 0; config = thisConfig[index]; index++) { |
| 25015 if (config.animatable) { |
| 25016 config.animatable._getAnimationConfigRecursive(config.type || type,
map, allConfigs); |
| 25017 } else { |
| 25018 if (config.id) { |
| 25019 var cachedConfig = map[config.id]; |
| 25020 if (cachedConfig) { |
| 25021 // merge configurations with the same id, making a clone lazily |
| 25022 if (!cachedConfig.isClone) { |
| 25023 map[config.id] = this._cloneConfig(cachedConfig) |
| 25024 cachedConfig = map[config.id]; |
| 25025 } |
| 25026 this._copyProperties(cachedConfig, config); |
| 25027 } else { |
| 25028 // put any configs with an id into a map |
| 25029 map[config.id] = config; |
| 25030 } |
| 25031 } else { |
| 25032 allConfigs.push(config); |
| 25033 } |
| 25034 } |
| 25035 } |
| 25036 } |
| 25037 }, |
| 25038 |
| 25039 /** |
| 25040 * An element implementing `Polymer.NeonAnimationRunnerBehavior` calls this
method to configure |
| 25041 * an animation with an optional type. Elements implementing `Polymer.NeonAn
imatableBehavior` |
| 25042 * should define the property `animationConfig`, which is either a configura
tion object |
| 25043 * or a map of animation type to array of configuration objects. |
| 25044 */ |
| 25045 getAnimationConfig: function(type) { |
| 25046 var map = {}; |
| 25047 var allConfigs = []; |
| 25048 this._getAnimationConfigRecursive(type, map, allConfigs); |
| 25049 // append the configurations saved in the map to the array |
| 25050 for (var key in map) { |
| 25051 allConfigs.push(map[key]); |
| 25052 } |
| 25053 return allConfigs; |
| 25054 } |
| 25055 |
| 25056 }; |
| 25057 |
| 25058 </script> |
| 25059 <script> |
| 25060 |
| 25061 /** |
| 25062 * `Polymer.NeonAnimationRunnerBehavior` adds a method to run animations. |
| 25063 * |
| 25064 * @polymerBehavior Polymer.NeonAnimationRunnerBehavior |
| 25065 */ |
| 25066 Polymer.NeonAnimationRunnerBehaviorImpl = { |
| 25067 |
| 25068 _configureAnimations: function(configs) { |
| 25069 var results = []; |
| 25070 if (configs.length > 0) { |
| 25071 for (var config, index = 0; config = configs[index]; index++) { |
| 25072 var neonAnimation = document.createElement(config.name); |
| 25073 // is this element actually a neon animation? |
| 25074 if (neonAnimation.isNeonAnimation) { |
| 25075 var result = null; |
| 25076 // configuration or play could fail if polyfills aren't loaded |
| 25077 try { |
| 25078 result = neonAnimation.configure(config); |
| 25079 // Check if we have an Effect rather than an Animation |
| 25080 if (typeof result.cancel != 'function') { |
| 25081 result = document.timeline.play(result); |
| 25082 } |
| 25083 } catch (e) { |
| 25084 result = null; |
| 25085 console.warn('Couldnt play', '(', config.name, ').', e); |
| 25086 } |
| 25087 if (result) { |
| 25088 results.push({ |
| 25089 neonAnimation: neonAnimation, |
| 25090 config: config, |
| 25091 animation: result, |
| 25092 }); |
| 25093 } |
| 25094 } else { |
| 25095 console.warn(this.is + ':', config.name, 'not found!'); |
| 25096 } |
| 25097 } |
| 25098 } |
| 25099 return results; |
| 25100 }, |
| 25101 |
| 25102 _shouldComplete: function(activeEntries) { |
| 25103 var finished = true; |
| 25104 for (var i = 0; i < activeEntries.length; i++) { |
| 25105 if (activeEntries[i].animation.playState != 'finished') { |
| 25106 finished = false; |
| 25107 break; |
| 25108 } |
| 25109 } |
| 25110 return finished; |
| 25111 }, |
| 25112 |
| 25113 _complete: function(activeEntries) { |
| 25114 for (var i = 0; i < activeEntries.length; i++) { |
| 25115 activeEntries[i].neonAnimation.complete(activeEntries[i].config); |
| 25116 } |
| 25117 for (var i = 0; i < activeEntries.length; i++) { |
| 25118 activeEntries[i].animation.cancel(); |
| 25119 } |
| 25120 }, |
| 25121 |
| 25122 /** |
| 25123 * Plays an animation with an optional `type`. |
| 25124 * @param {string=} type |
| 25125 * @param {!Object=} cookie |
| 25126 */ |
| 25127 playAnimation: function(type, cookie) { |
| 25128 var configs = this.getAnimationConfig(type); |
| 25129 if (!configs) { |
| 25130 return; |
| 25131 } |
| 25132 this._active = this._active || {}; |
| 25133 if (this._active[type]) { |
| 25134 this._complete(this._active[type]); |
| 25135 delete this._active[type]; |
| 25136 } |
| 25137 |
| 25138 var activeEntries = this._configureAnimations(configs); |
| 25139 |
| 25140 if (activeEntries.length == 0) { |
| 25141 this.fire('neon-animation-finish', cookie, {bubbles: false}); |
| 25142 return; |
| 25143 } |
| 25144 |
| 25145 this._active[type] = activeEntries; |
| 25146 |
| 25147 for (var i = 0; i < activeEntries.length; i++) { |
| 25148 activeEntries[i].animation.onfinish = function() { |
| 25149 if (this._shouldComplete(activeEntries)) { |
| 25150 this._complete(activeEntries); |
| 25151 delete this._active[type]; |
| 25152 this.fire('neon-animation-finish', cookie, {bubbles: false}); |
| 25153 } |
| 25154 }.bind(this); |
| 25155 } |
| 25156 }, |
| 25157 |
| 25158 /** |
| 25159 * Cancels the currently running animations. |
| 25160 */ |
| 25161 cancelAnimation: function() { |
| 25162 for (var k in this._animations) { |
| 25163 this._animations[k].cancel(); |
| 25164 } |
| 25165 this._animations = {}; |
| 25166 } |
| 25167 }; |
| 25168 |
| 25169 /** @polymerBehavior Polymer.NeonAnimationRunnerBehavior */ |
| 25170 Polymer.NeonAnimationRunnerBehavior = [ |
| 25171 Polymer.NeonAnimatableBehavior, |
| 25172 Polymer.NeonAnimationRunnerBehaviorImpl |
| 25173 ]; |
| 25174 </script> |
| 25175 <script> |
| 25176 |
| 25177 /** |
| 25178 Use `Polymer.PaperDialogBehavior` and `paper-dialog-shared-styles.html` to imple
ment a Material Design |
| 25179 dialog. |
| 25180 |
| 25181 For example, if `<paper-dialog-impl>` implements this behavior: |
| 25182 |
| 25183 <paper-dialog-impl> |
| 25184 <h2>Header</h2> |
| 25185 <div>Dialog body</div> |
| 25186 <div class="buttons"> |
| 25187 <paper-button dialog-dismiss>Cancel</paper-button> |
| 25188 <paper-button dialog-confirm>Accept</paper-button> |
| 25189 </div> |
| 25190 </paper-dialog-impl> |
| 25191 |
| 25192 `paper-dialog-shared-styles.html` provide styles for a header, content area, and
an action area for buttons. |
| 25193 Use the `<h2>` tag for the header and the `buttons` class for the action area. Y
ou can use the |
| 25194 `paper-dialog-scrollable` element (in its own repository) if you need a scrollin
g content area. |
| 25195 |
| 25196 Use the `dialog-dismiss` and `dialog-confirm` attributes on interactive controls
to close the |
| 25197 dialog. If the user dismisses the dialog with `dialog-confirm`, the `closingReas
on` will update |
| 25198 to include `confirmed: true`. |
| 25199 |
| 25200 ### Accessibility |
| 25201 |
| 25202 This element has `role="dialog"` by default. Depending on the context, it may be
more appropriate |
| 25203 to override this attribute with `role="alertdialog"`. |
| 25204 |
| 25205 If `modal` is set, the element will prevent the focus from exiting the element. |
| 25206 It will also ensure that focus remains in the dialog. |
| 25207 |
| 25208 @hero hero.svg |
| 25209 @demo demo/index.html |
| 25210 @polymerBehavior Polymer.PaperDialogBehavior |
| 25211 */ |
| 25212 |
| 25213 Polymer.PaperDialogBehaviorImpl = { |
| 25214 |
| 25215 hostAttributes: { |
| 25216 'role': 'dialog', |
| 25217 'tabindex': '-1' |
| 25218 }, |
| 25219 |
| 25220 properties: { |
| 25221 |
| 25222 /** |
| 25223 * If `modal` is true, this implies `no-cancel-on-outside-click`, `no-canc
el-on-esc-key` and `with-backdrop`. |
| 25224 */ |
| 25225 modal: { |
| 25226 type: Boolean, |
| 25227 value: false |
| 25228 } |
| 25229 |
| 25230 }, |
| 25231 |
| 25232 observers: [ |
| 25233 '_modalChanged(modal, _readied)' |
| 25234 ], |
| 25235 |
| 25236 listeners: { |
| 25237 'tap': '_onDialogClick' |
| 25238 }, |
| 25239 |
| 25240 ready: function () { |
| 25241 // Only now these properties can be read. |
| 25242 this.__prevNoCancelOnOutsideClick = this.noCancelOnOutsideClick; |
| 25243 this.__prevNoCancelOnEscKey = this.noCancelOnEscKey; |
| 25244 this.__prevWithBackdrop = this.withBackdrop; |
| 25245 }, |
| 25246 |
| 25247 _modalChanged: function(modal, readied) { |
| 25248 // modal implies noCancelOnOutsideClick, noCancelOnEscKey and withBackdrop
. |
| 25249 // We need to wait for the element to be ready before we can read the |
| 25250 // properties values. |
| 25251 if (!readied) { |
| 25252 return; |
| 25253 } |
| 25254 |
| 25255 if (modal) { |
| 25256 this.__prevNoCancelOnOutsideClick = this.noCancelOnOutsideClick; |
| 25257 this.__prevNoCancelOnEscKey = this.noCancelOnEscKey; |
| 25258 this.__prevWithBackdrop = this.withBackdrop; |
| 25259 this.noCancelOnOutsideClick = true; |
| 25260 this.noCancelOnEscKey = true; |
| 25261 this.withBackdrop = true; |
| 25262 } else { |
| 25263 // If the value was changed to false, let it false. |
| 25264 this.noCancelOnOutsideClick = this.noCancelOnOutsideClick && |
| 25265 this.__prevNoCancelOnOutsideClick; |
| 25266 this.noCancelOnEscKey = this.noCancelOnEscKey && |
| 25267 this.__prevNoCancelOnEscKey; |
| 25268 this.withBackdrop = this.withBackdrop && this.__prevWithBackdrop; |
| 25269 } |
| 25270 }, |
| 25271 |
| 25272 _updateClosingReasonConfirmed: function(confirmed) { |
| 25273 this.closingReason = this.closingReason || {}; |
| 25274 this.closingReason.confirmed = confirmed; |
| 25275 }, |
| 25276 |
| 25277 /** |
| 25278 * Will dismiss the dialog if user clicked on an element with dialog-dismiss |
| 25279 * or dialog-confirm attribute. |
| 25280 */ |
| 25281 _onDialogClick: function(event) { |
| 25282 // Search for the element with dialog-confirm or dialog-dismiss, |
| 25283 // from the root target until this (excluded). |
| 25284 var path = Polymer.dom(event).path; |
| 25285 for (var i = 0; i < path.indexOf(this); i++) { |
| 25286 var target = path[i]; |
| 25287 if (target.hasAttribute && (target.hasAttribute('dialog-dismiss') || tar
get.hasAttribute('dialog-confirm'))) { |
| 25288 this._updateClosingReasonConfirmed(target.hasAttribute('dialog-confirm
')); |
| 25289 this.close(); |
| 25290 event.stopPropagation(); |
| 25291 break; |
| 25292 } |
| 25293 } |
| 25294 } |
| 25295 |
| 25296 }; |
| 25297 |
| 25298 /** @polymerBehavior */ |
| 25299 Polymer.PaperDialogBehavior = [Polymer.IronOverlayBehavior, Polymer.PaperDialo
gBehaviorImpl]; |
| 25300 |
| 25301 </script> |
| 25302 |
| 25303 |
| 25304 <dom-module id="paper-dialog-shared-styles" assetpath="/res/imp/bower_components
/paper-dialog-behavior/"> |
| 25305 <template> |
| 25306 <style> |
| 25307 :host { |
| 25308 display: block; |
| 25309 margin: 24px 40px; |
| 25310 |
| 25311 background: var(--paper-dialog-background-color, --primary-background-co
lor); |
| 25312 color: var(--paper-dialog-color, --primary-text-color); |
| 25313 |
| 25314 @apply(--paper-font-body1); |
| 25315 @apply(--shadow-elevation-16dp); |
| 25316 @apply(--paper-dialog); |
| 25317 } |
| 25318 |
| 25319 :host > ::content > * { |
| 25320 margin-top: 20px; |
| 25321 padding: 0 24px; |
| 25322 } |
| 25323 |
| 25324 :host > ::content > .no-padding { |
| 25325 padding: 0; |
| 25326 } |
| 25327 |
| 25328 :host > ::content > *:first-child { |
| 25329 margin-top: 24px; |
| 25330 } |
| 25331 |
| 25332 :host > ::content > *:last-child { |
| 25333 margin-bottom: 24px; |
| 25334 } |
| 25335 |
| 25336 :host > ::content h2 { |
| 25337 position: relative; |
| 25338 margin: 0; |
| 25339 @apply(--paper-font-title); |
| 25340 |
| 25341 @apply(--paper-dialog-title); |
| 25342 } |
| 25343 |
| 25344 :host > ::content .buttons { |
| 25345 position: relative; |
| 25346 padding: 8px 8px 8px 24px; |
| 25347 margin: 0; |
| 25348 |
| 25349 color: var(--paper-dialog-button-color, --primary-color); |
| 25350 |
| 25351 @apply(--layout-horizontal); |
| 25352 @apply(--layout-end-justified); |
| 25353 } |
| 25354 </style> |
| 25355 </template> |
| 25356 </dom-module> |
| 25357 |
| 25358 |
| 25359 <dom-module id="paper-dialog" assetpath="/res/imp/bower_components/paper-dialog/
"> |
| 25360 <template> |
| 25361 <style include="paper-dialog-shared-styles"></style> |
| 25362 <content></content> |
| 25363 </template> |
| 25364 </dom-module> |
| 25365 |
| 25366 <script> |
| 25367 |
| 25368 (function() { |
| 25369 |
| 25370 Polymer({ |
| 25371 |
| 25372 is: 'paper-dialog', |
| 25373 |
| 25374 behaviors: [ |
| 25375 Polymer.PaperDialogBehavior, |
| 25376 Polymer.NeonAnimationRunnerBehavior |
| 25377 ], |
| 25378 |
| 25379 listeners: { |
| 25380 'neon-animation-finish': '_onNeonAnimationFinish' |
| 25381 }, |
| 25382 |
| 25383 _renderOpened: function() { |
| 25384 this.cancelAnimation(); |
| 25385 this.playAnimation('entry'); |
| 25386 }, |
| 25387 |
| 25388 _renderClosed: function() { |
| 25389 this.cancelAnimation(); |
| 25390 this.playAnimation('exit'); |
| 25391 }, |
| 25392 |
| 25393 _onNeonAnimationFinish: function() { |
| 25394 if (this.opened) { |
| 25395 this._finishRenderOpened(); |
| 25396 } else { |
| 25397 this._finishRenderClosed(); |
| 25398 } |
| 25399 } |
| 25400 |
| 25401 }); |
| 25402 |
| 25403 })(); |
| 25404 |
| 25405 </script> |
| 25406 <script> |
| 25407 |
| 25408 /** |
| 24899 * `Polymer.IronMenuBehavior` implements accessible menu behavior. | 25409 * `Polymer.IronMenuBehavior` implements accessible menu behavior. |
| 24900 * | 25410 * |
| 24901 * @demo demo/index.html | 25411 * @demo demo/index.html |
| 24902 * @polymerBehavior Polymer.IronMenuBehavior | 25412 * @polymerBehavior Polymer.IronMenuBehavior |
| 24903 */ | 25413 */ |
| 24904 Polymer.IronMenuBehaviorImpl = { | 25414 Polymer.IronMenuBehaviorImpl = { |
| 24905 | 25415 |
| 24906 properties: { | 25416 properties: { |
| 24907 | 25417 |
| 24908 /** | 25418 /** |
| (...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 26263 margin-bottom: 5px; | 26773 margin-bottom: 5px; |
| 26264 } | 26774 } |
| 26265 td, th { | 26775 td, th { |
| 26266 border: 1px solid #BBB; | 26776 border: 1px solid #BBB; |
| 26267 padding: 5px; | 26777 padding: 5px; |
| 26268 } | 26778 } |
| 26269 | 26779 |
| 26270 .quarantined, .failed_task { | 26780 .quarantined, .failed_task { |
| 26271 background-color: #ffdddd; | 26781 background-color: #ffdddd; |
| 26272 } | 26782 } |
| 26273 .dead { | 26783 .dead, .bot_died { |
| 26274 background-color: #cccccc; | 26784 background-color: #cccccc; |
| 26275 } | 26785 } |
| 26276 | 26786 |
| 26277 .message { | 26787 .message { |
| 26278 white-space: pre-line; | 26788 white-space: pre-line; |
| 26279 font-family: monospace; | 26789 font-family: monospace; |
| 26280 } | 26790 } |
| 26281 | 26791 |
| 26282 .bot_state { | 26792 .bot_state { |
| 26283 white-space: pre; | 26793 white-space: pre; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 26306 } | 26816 } |
| 26307 | 26817 |
| 26308 paper-tab.iron-selected { | 26818 paper-tab.iron-selected { |
| 26309 background-color: #A6CEE3; | 26819 background-color: #A6CEE3; |
| 26310 border: 3px solid #1F78B4; | 26820 border: 3px solid #1F78B4; |
| 26311 color: #000; | 26821 color: #000; |
| 26312 font-weight: bold; | 26822 font-weight: bold; |
| 26313 text-decoration: underline; | 26823 text-decoration: underline; |
| 26314 } | 26824 } |
| 26315 | 26825 |
| 26826 paper-dialog { |
| 26827 border-radius: 6px; |
| 26828 } |
| 26829 |
| 26316 </style> | 26830 </style> |
| 26317 | 26831 |
| 26318 <url-param name="id" value="{{bot_id}}"> | 26832 <url-param name="id" value="{{bot_id}}"> |
| 26319 </url-param> | 26833 </url-param> |
| 26320 <url-param name="show_all_events" value="{{_show_all}}"> | 26834 <url-param name="show_all_events" value="{{_show_all}}"> |
| 26321 </url-param> | 26835 </url-param> |
| 26322 <url-param name="selected" value="{{_selected}}"> | 26836 <url-param name="selected" value="{{_selected}}"> |
| 26323 </url-param> | 26837 </url-param> |
| 26324 <url-param name="show_state" value="{{_show_state}}"> | 26838 <url-param name="show_state" value="{{_show_state}}"> |
| 26325 </url-param> | 26839 </url-param> |
| 26326 | 26840 |
| 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"> | 26841 <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 | 26842 |
| 26329 <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2> | 26843 <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2> |
| 26330 | 26844 |
| 26331 <div hidden$="[[_not(_signed_in)]]"> | 26845 <div hidden$="[[_not(_signed_in)]]"> |
| 26332 | 26846 |
| 26333 <bot-page-data auth_headers="[[_auth_headers]]" bot_id="[[bot_id]]" bot=
"{{_bot}}" busy="{{_busy}}" events="{{_events}}" tasks="{{_tasks}}"> | 26847 <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> | 26848 </bot-page-data> |
| 26335 | 26849 |
| 26336 <div class="header horizontal layout"> | 26850 <div class="header horizontal layout"> |
| 26337 <paper-input class="id_input" label="Bot id" value="{{bot_id}}"></pape
r-input> | 26851 <paper-input class="id_input" label="Bot id" value="{{bot_id}}"></pape
r-input> |
| 26338 <button> | 26852 <button on-click="_refresh"> |
| 26339 <iron-icon class="refresh" icon="icons:refresh"></iron-icon> | 26853 <iron-icon class="refresh" icon="icons:refresh"></iron-icon> |
| 26340 </button> | 26854 </button> |
| 26341 </div> | 26855 </div> |
| 26342 | 26856 |
| 26343 <div> | 26857 <div> |
| 26344 <table> | 26858 <table> |
| 26345 <tbody><tr class$="[[_isDead(_bot)]]"> | 26859 <tbody><tr class$="[[_isDead(_bot)]]"> |
| 26346 <td>Last Seen</td> | 26860 <td>Last Seen</td> |
| 26347 <td title="[[_bot.human_last_seen_ts]]"> | 26861 <td title="[[_bot.human_last_seen_ts]]"> |
| 26348 [[_timeDiffExact(_bot.last_seen_ts)]] ago</td> | 26862 [[_timeDiffExact(_bot.last_seen_ts)]] ago</td> |
| 26349 <td> | 26863 <td> |
| 26350 | 26864 |
| 26351 <template is="dom-if" if="[[_canShutdown(_bot,_permissions)]]"> | 26865 <template is="dom-if" if="[[_canShutdown(_bot,_permissions)]]"> |
| 26352 <button class="raised"> | 26866 <button class="raised" on-click="_promptShutdown"> |
| 26353 Shut Down Gracefully | 26867 Shut Down Gracefully |
| 26354 </button> | 26868 </button> |
| 26355 </template> | 26869 </template> |
| 26356 <template is="dom-if" if="[[_canDelete(_bot,_permissions)]]"> | 26870 <template is="dom-if" if="[[_canDelete(_bot,_permissions)]]"> |
| 26357 <button class="raised"> | 26871 <button class="raised" on-click="_promptDelete"> |
| 26358 Delete | 26872 Delete |
| 26359 </button> | 26873 </button> |
| 26360 </template> | 26874 </template> |
| 26361 </td> | 26875 </td> |
| 26362 </tr> | 26876 </tr> |
| 26363 <template is="dom-if" if="[[_bot.quarantined]]"> | 26877 <template is="dom-if" if="[[_bot.quarantined]]"> |
| 26364 <tr class="quarantined"> | 26878 <tr class="quarantined"> |
| 26365 <td>Quarantined</td> | 26879 <td>Quarantined</td> |
| 26366 <td colspan="2">[[_quarantineMessage(_bot)]]</td> | 26880 <td colspan="2">[[_quarantineMessage(_bot)]]</td> |
| 26367 </tr> | 26881 </tr> |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 26450 <thead> | 26964 <thead> |
| 26451 <tr> | 26965 <tr> |
| 26452 <th>Task</th> | 26966 <th>Task</th> |
| 26453 <th>Started</th> | 26967 <th>Started</th> |
| 26454 <th>Duration</th> | 26968 <th>Duration</th> |
| 26455 <th>Result</th> | 26969 <th>Result</th> |
| 26456 </tr> | 26970 </tr> |
| 26457 </thead> | 26971 </thead> |
| 26458 <tbody> | 26972 <tbody> |
| 26459 <template is="dom-repeat" items="{{_tasks}}" as="task"> | 26973 <template is="dom-repeat" items="{{_tasks}}" as="task"> |
| 26460 <tr> | 26974 <tr class$="[[_taskClass(task)]]"> |
| 26461 <td><a target="_blank" href$="[[_taskLink(task.task_id)]]">[[t
ask.name]]</a></td> | 26975 <td><a target="_blank" href$="[[_taskLink(task.task_id)]]">[[t
ask.name]]</a></td> |
| 26462 <td>[[task.human_started_ts]]</td> | 26976 <td>[[task.human_started_ts]]</td> |
| 26463 <td title="[[task.human_completed_ts]]">[[task.human_duration]
]</td> | 26977 <td title="[[task.human_completed_ts]]">[[task.human_duration]
]</td> |
| 26464 <td>[[task.state]]</td> | 26978 <td>[[task.state]]</td> |
| 26465 </tr> | 26979 </tr> |
| 26466 </template> | 26980 </template> |
| 26467 </tbody> | 26981 </tbody> |
| 26468 </table> | 26982 </table> |
| 26469 </template> | 26983 </template> |
| 26470 | 26984 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 26489 <td> | 27003 <td> |
| 26490 <a target="_blank" href$="[[_luciLink(_bot.version)]]">[[_sh
orten(_bot.version,'8')]]</a> | 27004 <a target="_blank" href$="[[_luciLink(_bot.version)]]">[[_sh
orten(_bot.version,'8')]]</a> |
| 26491 </td> | 27005 </td> |
| 26492 </tr> | 27006 </tr> |
| 26493 </template> | 27007 </template> |
| 26494 </tbody> | 27008 </tbody> |
| 26495 </table> | 27009 </table> |
| 26496 </template> | 27010 </template> |
| 26497 </div> | 27011 </div> |
| 26498 | 27012 |
| 27013 </swarming-app> |
| 26499 | 27014 |
| 26500 </swarming-app> | 27015 <paper-dialog id="prompt" modal="" on-iron-overlay-closed="_promptClosed"> |
| 27016 <h2>Are you sure?</h2> |
| 27017 <div>Are you sure you want to [[_dialogPrompt]]?</div> |
| 27018 <div class="buttons"> |
| 27019 <paper-button dialog-dismiss="" autofocus="">No</paper-button> |
| 27020 <paper-button dialog-confirm="">Yes</paper-button> |
| 27021 </div> |
| 27022 </paper-dialog> |
| 27023 |
| 27024 <error-toast></error-toast> |
| 26501 | 27025 |
| 26502 </template> | 27026 </template> |
| 26503 <script> | 27027 <script> |
| 26504 (function(){ | 27028 (function(){ |
| 26505 | 27029 |
| 26506 | 27030 |
| 26507 Polymer({ | 27031 Polymer({ |
| 26508 is: 'bot-page', | 27032 is: 'bot-page', |
| 26509 | 27033 |
| 26510 behaviors: [ | 27034 behaviors: [ |
| 26511 SwarmingBehaviors.BotPageBehavior, | 27035 SwarmingBehaviors.BotPageBehavior, |
| 26512 ], | 27036 ], |
| 26513 | 27037 |
| 26514 properties: { | 27038 properties: { |
| 26515 bot_id: { | 27039 bot_id: { |
| 26516 type: String, | 27040 type: String, |
| 26517 }, | 27041 }, |
| 26518 client_id: { | 27042 client_id: { |
| 26519 type: String, | 27043 type: String, |
| 26520 }, | 27044 }, |
| 26521 | 27045 |
| 27046 _auth_headers: { |
| 27047 type: Object, |
| 27048 }, |
| 26522 _bot: { | 27049 _bot: { |
| 26523 type: Object, | 27050 type: Object, |
| 26524 }, | 27051 }, |
| 27052 _dialogPrompt: { |
| 27053 type: String, |
| 27054 value: "", |
| 27055 }, |
| 26525 _selected: { | 27056 _selected: { |
| 26526 type: Number, | 27057 type: Number, |
| 26527 }, | 27058 }, |
| 26528 _show_all: { | 27059 _show_all: { |
| 26529 type: Boolean, | 27060 type: Boolean, |
| 26530 }, | 27061 }, |
| 26531 _show_state: { | 27062 _show_state: { |
| 26532 type: Boolean, | 27063 type: Boolean, |
| 26533 } | 27064 } |
| 26534 }, | 27065 }, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 26545 return bot && !bot.is_dead && permissions.terminate_bot; | 27076 return bot && !bot.is_dead && permissions.terminate_bot; |
| 26546 }, | 27077 }, |
| 26547 | 27078 |
| 26548 _concat: function(arr) { | 27079 _concat: function(arr) { |
| 26549 if (!arr) { | 27080 if (!arr) { |
| 26550 return ""; | 27081 return ""; |
| 26551 } | 27082 } |
| 26552 return arr.join(" | "); | 27083 return arr.join(" | "); |
| 26553 }, | 27084 }, |
| 26554 | 27085 |
| 27086 _deleteBot: function() { |
| 27087 this._postWithToast("/_ah/api/swarming/v1/bot/"+this.bot_id+"/delete", |
| 27088 "Deleting "+this.bot_id, this._auth_headers); |
| 27089 }, |
| 27090 |
| 26555 _eventList(events, showAll) { | 27091 _eventList(events, showAll) { |
| 26556 if (!events) { | 27092 if (!events) { |
| 26557 return []; | 27093 return []; |
| 26558 } | 27094 } |
| 26559 return events.filter(function(e){ | 27095 return events.filter(function(e){ |
| 26560 return showAll || e.message; | 27096 return showAll || e.message; |
| 26561 }); | 27097 }); |
| 26562 }, | 27098 }, |
| 26563 | 27099 |
| 26564 _isDead(bot){ | 27100 _isDead(bot){ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 26581 return 1; | 27117 return 1; |
| 26582 } | 27118 } |
| 26583 return 1 + arr.length; | 27119 return 1 + arr.length; |
| 26584 }, | 27120 }, |
| 26585 | 27121 |
| 26586 _prettyPrint: function(obj) { | 27122 _prettyPrint: function(obj) { |
| 26587 obj = obj || {}; | 27123 obj = obj || {}; |
| 26588 return JSON.stringify(obj, null, 2); | 27124 return JSON.stringify(obj, null, 2); |
| 26589 }, | 27125 }, |
| 26590 | 27126 |
| 27127 _promptClosed: function(e) { |
| 27128 if (e.detail.confirmed) { |
| 27129 if (this._dialogPrompt.startsWith("shut down")) { |
| 27130 this._shutdownBot(); |
| 27131 } else { |
| 27132 this._deleteBot(); |
| 27133 } |
| 27134 } |
| 27135 }, |
| 27136 |
| 27137 _promptDelete: function() { |
| 27138 this.set("_dialogPrompt", "delete "+this.bot_id); |
| 27139 this.$.prompt.open(); |
| 27140 }, |
| 27141 |
| 27142 _promptShutdown: function() { |
| 27143 this.set("_dialogPrompt", "shut down "+this.bot_id); |
| 27144 this.$.prompt.open(); |
| 27145 }, |
| 27146 |
| 26591 _quarantineMessage: function(bot) { | 27147 _quarantineMessage: function(bot) { |
| 26592 if (bot && bot.quarantined) { | 27148 if (bot && bot.quarantined) { |
| 26593 var msg = bot.state.quarantined; | 27149 var msg = bot.state.quarantined; |
| 26594 // Sometimes, the quarantined message is actually in "error". This | 27150 // Sometimes, the quarantined message is actually in "error". This |
| 26595 // happens when the bot code has thrown an exception. | 27151 // happens when the bot code has thrown an exception. |
| 26596 if (msg === undefined || msg === "true" || msg === true) { | 27152 if (msg === undefined || msg === "true" || msg === true) { |
| 26597 msg = this._attribute(bot, "error"); | 27153 msg = this._attribute(bot, "error"); |
| 26598 } | 27154 } |
| 26599 return msg || "True"; | 27155 return msg || "True"; |
| 26600 } | 27156 } |
| 26601 return ""; | 27157 return ""; |
| 26602 }, | 27158 }, |
| 26603 | 27159 |
| 27160 _refresh: function() { |
| 27161 this.$.data.request(); |
| 27162 }, |
| 27163 |
| 26604 _shorten: function(str, length) { | 27164 _shorten: function(str, length) { |
| 26605 if (!str || ! length) { | 27165 if (!str || ! length) { |
| 26606 return ""; | 27166 return ""; |
| 26607 } | 27167 } |
| 26608 return str.substring(0, length); | 27168 return str.substring(0, length); |
| 26609 }, | 27169 }, |
| 26610 | 27170 |
| 27171 _shutdownBot: function() { |
| 27172 this._postWithToast("/_ah/api/swarming/v1/bot/"+this.bot_id+"/terminate"
, |
| 27173 "Shutting down "+this.bot_id, this._auth_headers); |
| 27174 }, |
| 27175 |
| 26611 _task: function(bot) { | 27176 _task: function(bot) { |
| 26612 return (bot && bot.task_id) || "idle"; | 27177 return (bot && bot.task_id) || "idle"; |
| 26613 }, | 27178 }, |
| 26614 | 27179 |
| 27180 _taskClass: function(task) { |
| 27181 if (task && task.internal_failure) { |
| 27182 return "bot_died"; |
| 27183 } |
| 27184 if (task && task.failure) { |
| 27185 return "failed_task"; |
| 27186 } |
| 27187 return ""; |
| 27188 }, |
| 27189 |
| 26615 _taskLink: function(task_id) { | 27190 _taskLink: function(task_id) { |
| 26616 // TODO(kjlubick): Migrate this to /newui/ when ready | 27191 // TODO(kjlubick): Migrate this to /newui/ when ready |
| 26617 if (task_id) { | 27192 if (task_id) { |
| 26618 return "/user/task/" + task_id; | 27193 return "/user/task/" + task_id; |
| 26619 } | 27194 } |
| 26620 return undefined; | 27195 return undefined; |
| 26621 }, | 27196 }, |
| 26622 | 27197 |
| 26623 _toggleState: function() { | 27198 _toggleState: function() { |
| 26624 this.set("_show_state", !this._show_state); | 27199 this.set("_show_state", !this._show_state); |
| 26625 } | 27200 } |
| 26626 | 27201 |
| 26627 }); | 27202 }); |
| 26628 })(); | 27203 })(); |
| 26629 </script> | 27204 </script> |
| 26630 </dom-module></div></body></html> | 27205 </dom-module></div></body></html> |
| OLD | NEW |