Home | History | Annotate | Download | only in ui
      1 <!--
      2 Copyright 2014 The Chromium Authors. All rights reserved.
      3 Use of this source code is governed by a BSD-style license that can be
      4 found in the LICENSE file.
      5 -->
      6 
      7 <link rel="import" href="../lib/sugar.html">
      8 <script src="../scripts/results.js"></script>
      9 
     10 <link rel="import" href="../bower_components/core-animated-pages/core-animated-pages.html">
     11 <link rel="import" href="../bower_components/core-animated-pages/transitions/slide-from-right.html">
     12 <link rel="import" href="../lib/ct-scheduled-updater.html">
     13 <link rel="import" href="../model/ct-commit-log.html">
     14 <link rel="import" href="../model/ct-failures.html">
     15 <link rel="import" href="../model/ct-tree-list.html">
     16 <link rel="import" href="ct-results-panel.html">
     17 <link rel="import" href="ct-tree-select.html">
     18 <link rel="import" href="ct-unexpected-failures.html">
     19 
     20 <polymer-element name="ct-sheriff-o-matic">
     21   <template>
     22     <style>
     23       :host {
     24         display: flex;
     25         flex-direction: column;
     26         height: 100%;
     27       }
     28       header {
     29         -webkit-user-select: none;
     30         align-items: center;
     31         background-color: #212121;
     32         color: white;
     33         cursor: default;
     34         display: flex;
     35         flex-wrap: wrap;
     36         justify-content: space-between;
     37         font-size: 1.1em;
     38         padding: 0 5px;
     39         white-space: nowrap;
     40       }
     41       header a, header span {
     42         color: white;
     43         display: inline-block;
     44         padding: 0.25em 4px;
     45         text-decoration: none;
     46       }
     47       #right-toolbar {
     48         display: flex;
     49         flex-wrap: wrap;
     50         align-items: center;
     51       }
     52       ct-last-updated {
     53         margin: 0 5px;
     54       }
     55       core-animated-pages {
     56         flex: 1;
     57       }
     58       core-animated-pages > * {
     59         overflow: auto;
     60       }
     61     </style>
     62 
     63     <header>
     64       <div>
     65         <template if="{{ selected == 0 }}">
     66           <img src="../favicon.ico"> <span>Sheriff-o-matic</span>
     67         </template>
     68         <template if="{{ selected == 1 }}">
     69           <a on-click="{{ onBack }}" href="">
     70             &lt;&lt; Go back
     71           </a>
     72         </template>
     73       </div>
     74       <div id="right-toolbar">
     75         <ct-last-updated date="{{ failures.lastUpdateDate }}"></ct-last-updated>
     76         <ct-tree-select tree="{{ tree }}" treeList="{{ treeList }}"></ct-tree-select>
     77       </div>
     78     </header>
     79 
     80     <core-animated-pages selected="{{ selected }}" transitions="slide-from-right">
     81       <ct-unexpected-failures id="unexpected" tree="{{ tree }}" commitLog="{{ commitLog }}" failures="{{ failures }}" on-ct-examine-failures="{{ onExamine }}"></ct-unexpected-failures>
     82       <ct-results-panel group="{{ examinedFailureGroup }}"></ct-results-panel>
     83     </core-animated-pages>
     84   </template>
     85   <script>
     86     var kUpdateFrequency = 1000 * 30;
     87 
     88     Polymer({
     89       tree: '',
     90       treeList: null,
     91       selected: 0,
     92       examinedFailureGroup: null,
     93       _pendingFailureGroupKey: '',
     94 
     95       updateFromHistoryState: function(state) {
     96         this._pendingFailureGroupKey = state.examinedFailureGroupKey;
     97         if ('selected' in state)
     98           this.selected = state.selected;
     99       },
    100 
    101       onPopState: function(e) {
    102         this.updateFromHistoryState(e.state);
    103       },
    104 
    105       onBack: function(event) {
    106         if (event.button == 0) {
    107           window.history.back();
    108           event.preventDefault();
    109         }
    110       },
    111 
    112       onExamine: function(event) {
    113         window.history.pushState({
    114           examinedFailureGroupKey: event.detail.key,
    115           selected: 1,
    116         });
    117 
    118 
    119         this.examinedFailureGroup = event.detail;
    120         this.selected = 1;
    121       },
    122 
    123       created: function() {
    124         this.treeList = new CTTreeList();
    125         this.tree = this.treeList.defaultValue();
    126         this.commitLog = new CTCommitLog();
    127         this.failures = new CTFailures(this.commitLog);
    128         this._updater = new CTScheduledUpdater(this.update.bind(this), kUpdateFrequency);
    129 
    130         // History API handling:
    131         // If we have a current state, we should make sure the view is shown
    132         // accordingly.
    133         // Otherwise, we should inject a state using replaceState() so we can
    134         // handle history navigation cleanly.
    135         // Either way, the object will react to popstate events.
    136         if (window.history.state) {
    137           // Will be a no-op if the current state is already being used.
    138           this.updateFromHistoryState(window.history.state);
    139         } else {
    140           window.history.replaceState({
    141             selected: 0,
    142           });
    143         }
    144 
    145         window.addEventListener('popstate', this.onPopState.bind(this));
    146       },
    147 
    148       ready: function() {
    149         this.update();
    150       },
    151 
    152       update: function() {
    153         if (this._promise)
    154           return;
    155         this._promise = Promise.all(
    156           [this.commitLog.update(),
    157            this.failures.update()]).then(this._updateCompleted.bind(this));
    158       },
    159 
    160       _updateCompleted: function() {
    161         this._promise = null;
    162         this.$.unexpected.update();
    163         if (!this.failures.failures)
    164           return;
    165         if (!this._pendingFailureGroupKey)
    166           return;
    167         this.examinedFailureGroup = this.failures.failures[this.tree].find(function(group) {
    168           return group.key == this._pendingFailureGroupKey;
    169         }.bind(this));
    170         this._pendingFailureGroupKey = '';
    171       },
    172 
    173     });
    174   </script>
    175 </polymer-element>
    176