<!-- The <triage-page-sk> custom element declaration.

  Allows triaging clusters.

  Attributes:
    None.

  Events:
    None.

  Methods:
    None.

-->
<link rel="import" href="/res/imp/bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="/res/imp/bower_components/paper-spinner/paper-spinner.html">
<link rel="import" href="/res/imp/bower_components/iron-selector/iron-selector.html">

<link rel="import" href="/res/common/imp/query-summary-sk.html" />
<link rel="import" href="/res/common/imp/details-summary.html" />

<link rel="import" href="/res/imp/triage-status.html" />
<link rel="import" href="/res/imp/commit-detail.html" />

<dom-module id="triage-page-sk">
  <style include="iron-flex iron-flex-alignment iron-positioning">
    details-sk {
      margin-top: 0.5em;
    }

    day-range-sk {
      display: block;
    }

    .fixed {
      font-family: 'Roboto Mono', monospace;
    }

    .cluster {
      text-align: center;
    }

    triage-status-sk {
      text-align: left;
    }

    tr:nth-child(even) {
      background-color: #eee;
    }

    table {
      border-collapse: collapse;
      border-spacing: 0;
    }

    #table.hidden {
      display: none;
    }

    .dot {
      text-decoration: none;
      color: black;
    }

    .iron-selected {
      background: #eee;
    }

    iron-selector div {
      width: 10em;
      margin: 0.3em 1em;
      padding: 0.2em;
    }

    summary-sk h2 {
      display: inline;
    }
  </style>
  <template>
    <details-sk open>
      <summary-sk>
        <h2 id="filter">Filter</h2>
      </summary-sk>
      <iron-selector
        attr-for-selected="value"
        selected="{{state.subset}}"
        fallback-selection="untriaged"
        on-selected-item-changed="_updateRange"
        >
        <div value=all title="Show results for all commits in the time range.">All</div>
        <div value=flagged title="Show only the commits with alerts in the given time range.">Flagged</div>
        <div value=untriaged title="Show all the untriaged alerts regardless of the time range.">Untriaged</div>
      </iron-selector>
    </details-sk>
    <details-sk>
      <summary-sk>
        <h2 id="range">Range</h2>
      </summary-sk>
      <day-range-sk id=range on-day-range-change="_rangeChange"></day-range-sk>
    </details-sk>
    <paper-spinner id=spinner></paper-spinner>
    <table on-open-keys=_openKeys on-triaged=_triaged id=table>
      <tr>
        <th>Commit</th>
        <template is="dom-repeat" items="[[_reg.header]]">
          <th colspan=2><query-summary-sk selection="[[item]]"></query-summary-sk></th>
        </template>
      </tr>
      <tr>
        <th></th>
        <template is="dom-repeat" items="[[_reg.header]]">
          <th>Low</th>
          <th>High</th>
        </template>
      </tr>
      <template is="dom-repeat" items="[[_reg.table]]" index-as="tableIndex">
        <tr>
          <td class=fixed>
            <commit-detail-sk cid="[[item.cid]]"></commit-detail-sk>
          </td>
          <template is="dom-repeat" items="[[item.columns]]">
            <td class=cluster>
              <template is="dom-if" if="[[item.low]]">
                <triage-status-sk query="[[_queryFrom(index)]]" cluster_type=low full_summary="[[_full_summary(item.frame, item.low)]]" triage="[[item.low_status]]"></triage-status-sk>
              </template>
              <template is="dom-if" if="[[_not(item.low)]]">
                <a class=dot title="No clusters found." href="/g/c/[[_hashFrom(tableIndex)]]?query=[[_encQueryFrom(index)]]">[[_display(tableIndex,state.end)]]</a>
              </template>
            </td>
            <td class=cluster>
              <template is="dom-if" if="[[item.high]]">
                <triage-status-sk query="[[_queryFrom(index)]]" cluster_type=high full_summary="[[_full_summary(item.frame, item.high)]]" triage="[[item.high_status]]"></triage-status-sk>
              </template>
              <template is="dom-if" if="[[_not(item.high)]]">
                <a class=dot title="No clusters found." href="/g/c/[[_hashFrom(tableIndex)]]?query=[[_encQueryFrom(index)]]">[[_display(tableIndex,state.end)]]</a>
              </template>
            </td>
          </template>
        </tr>
      </template>
    </table>
  </template>
</dom-module>

<script>
  (function () {
    var now = Math.floor(Date.now()/1000);

    Polymer({
      is: "triage-page-sk",

      properties: {
        state: {
          type: Object,
          value: function() {
            return {
              begin: now - 4*24*60*60,
              end: now,
              subset: "untriaged",
            };
          },
        },
        _reg: {
          type: Object,
          value: function() { return {}; },
        },
        _triageInProgress: {
          type: Boolean,
          value: false,
        }
      },

      ready: function() {
        sk.stateReflector(this, this._updateRange.bind(this));
      },

      _openKeys: function(e) {
        var state = {
          keys: e.detail.keys,
        };
        sk.post('/_/keys/', JSON.stringify(state)).then(JSON.parse).then(function (json) {
          var query = {
            keys:       json.id,
            begin:      e.detail.begin,
            end:        e.detail.end,
            xbaroffset: e.detail.xbar.offset
          };
          window.open('/e/?' + sk.query.fromObject(query), '_blank');
        }.bind(this));
      },

      _rangeChange: function(e) {
        this.set('state.begin', e.detail.begin);
        this.set('state.end', e.detail.end);
        this._updateRange();
      },

      _updateRange: function() {
        this.set('_reg',  {});
        this.$.range.begin = this.state.begin;
        this.$.range.end = this.state.end;
        var body = {
          begin: this.state.begin,
          end: this.state.end,
          subset: this.state.subset,
        };
        this.$.spinner.active = true;
        this.$.table.classList.toggle("hidden", true);
        sk.post("/_/reg/", JSON.stringify(body), "application/json").then(JSON.parse).then(function(json) {
          this.$.spinner.active = false;
          this.$.table.classList.toggle("hidden", false);
          this.set('_reg', json);
        }.bind(this)).catch(function(msg) {
          if (msg) {
            sk.errorMessage(msg, 10000);
          }
          this.$.spinner.active = false;
        }.bind(this));
      },

      _triaged: function(e) {
        this.$.spinner.active = true;
        if (this._triageInProgress === true) {
          sk.errorMessage("A triage request is in progress.");
          return
        }
        this._triageInProgress = true;
        sk.post("/_/triage/", JSON.stringify(e.detail), "application/json").then(JSON.parse).then(function(json) {
          this.$.spinner.active = false;
          this._triageInProgress = false;
          if (json.bug) {
            // Open the bug reporting page in a new window.
            window.open(json.bug, '_blank');
          }
        }.bind(this)).catch(function(msg) {
          if (msg) {
            sk.errorMessage(msg, 10000);
          }
          this.$.spinner.active = false;
          this._triageInProgress = false;
        }.bind(this));
      },

      _queryFrom: function(index) {
        return this._reg.header[index];
      },

      _encQueryFrom: function(index) {
        return encodeURIComponent(this._reg.header[index]);
      },

      _hashFrom: function(index) {
        return this._reg.table[index].cid.hash;
      },

      _full_summary: function(frame, summary) {
        return {
          frame: frame,
          summary: summary,
        }
      },

      _not: function(x) {
        return !x;
      },

      _display: function(index) {
        if (this.state.end == now && index < sk.perf.radius && this.state.subset == "all") {
          return "";
        } else {
          return "∅";
        }
      },

    });
  })();
</script>
