blob: 6371079a013474d1a381adf63fe5b1768e6f140f [file] [log] [blame]
<!-- The <search-controls-sk> custom element declaration.
This is a general element to be used by all pages that
call a search endpoint on the backend.
It encapsulates the state of the query. When that state
is changed through some of the controls it updates the URL
and send an update to the host element to reload data based
on the new query state.
The state object contains these fields:
- pos: show positive (boolean).
- neg: show negative (boolean).
- unt: show untriaged (boolean).
- include: show ignored digests (boolean).
- head: only digests that are currently in HEAD.
- query: query string to select configuration.
Attributes:
state - The current query state.
disabled - Boolean to indicate whether to disable all the controls.
beta - Boolean to enable beta-level functions.
Events:
'state-change' - Fired when the state of the query changes and
it needs to be reloaded. The 'detail' field of the event contains
the new state represented by the controls.
Methods:
setState(state) - Set the state of the controls to 'state'.
setParamSet(params) - Sets the parameters of the enclosed query-dialog-sk element
and enables the controls accordingly.
setCommitInfo(commitinfo) - Where commitinfo is an array of objects of the form:
{
author: "foo@example.org"
commit_time: 1428574804
hash: "d9f8862ab6bed4195cbfe5dda48693e1062b01e2"
}
-->
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="bower_components/paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="bower_components/iron-icons/iron-icons.html">
<link rel="import" href="bower_components/iron-icons/image-icons.html">
<link rel="import" href="bower_components/paper-button/paper-button.html">
<link rel="import" href="query-dialog-sk.html">
<link rel="import" href="filter-dialog-sk.html">
<link rel="import" href="shared-styles.html">
<dom-module id="search-controls-sk">
<template>
<style include="iron-flex iron-flex-alignment"></style>
<style include="shared-styles">
.horizontalTopControl {
font-weight: bold;
}
.horizontalTopControl {
margin: 0 2em 0 0;
}
.horizontal.currSelection {
margin-left: 1em;
margin-right: 3em;
max-width: 20em;
}
.corpus_label {
font-weight: bold;
margin: auto 0;
}
</style>
<div class="vertical layout">
<div class="horizontal layout">
<paper-toggle-button class="horizontalTopControl" checked="{{state.pos}}" disabled={{disabled}}>Positive</paper-toggle-button>
<paper-toggle-button class="horizontalTopControl" checked="{{state.neg}}" disabled={{disabled}}>Negative</paper-toggle-button>
<paper-toggle-button class="horizontalTopControl" checked="{{state.unt}}" disabled={{disabled}}>Untriaged</paper-toggle-button>
<paper-toggle-button class="horizontalTopControl" checked="{{state.head}}" disabled={{disabled}}>Head</paper-toggle-button>
<paper-toggle-button class="horizontalTopControl" checked="{{state.include}}" disabled={{disabled}}>Ignored</paper-toggle-button>
<paper-button id="filterButton" class$="topControl" raised disabled="[[disabled]]"
title="Metrics Filter"><iron-icon icon="icons:filter-list"></iron-icon>
</paper-button>
</div>
<div class="horizontal layout">
<span class=corpus_label>Corpus:</span>
<corpus-selector-sk id="corpusSelector"></corpus-selector-sk>
</div>
<div class="horizontal layout">
<paper-button id="searchButton" class$="topControl" raised disabled="[[disabled]]"
title="Filter Traces"><iron-icon icon="image:tune"></iron-icon></paper-button>
<div class="horizontal currSelection">
[[_splitAmp(state.query)]]
</div>
</div>
</div>
<query-dialog-sk id="queryDialog" trigger="searchButton"></query-dialog-sk>
<filter-dialog-sk id="filterDialog" trigger="filterButton"></filter-dialog-sk>
</template>
<script>
Polymer({
is: "search-controls-sk",
properties: {
state: {
type: Object
},
disabled: {
type: Boolean,
value: false
},
beta: {
type: Boolean,
value: false
}
},
observers: [
'_fireStateChange(state.*)'
],
ready: function() {
this.listen(this.$.searchButton, 'tap', '_handleSearchButton');
this.listen(this.$.filterButton, 'tap', '_handleFilterButton');
this.listen(this.$.queryDialog, 'edit', '_handleQueryEdit');
this.listen(this.$.filterDialog, 'edit', '_handleFilterEdit');
this.listen(this.$.corpusSelector, 'corpus_selected', '_handleCorpusChange');
// If the corpus changes make sure we do cleanup work.
this.async(function() {
this._statusEle = $$$("gold-status-sk");
if (this._statusEle) {
this.listen(this._statusEle, 'corpus-change', '_handleCorpusChange');
}
});
},
setState: function(state, fireEvent) {
this._noFire = !fireEvent;
this.set('state', sk.object.shallowCopy(state));
this.$.filterDialog.setValue(this.state);
const query = sk.query.toParamSet(state.query);
const corporaSelected = query['source_type'];
if (corporaSelected && corporaSelected.length) {
this.$.corpusSelector.selectedCorpus = corporaSelected[0];
} else {
this.$.corpusSelector.selectedCorpus = sk.app_config.defaultCorpus;
}
},
setParamSet: function(params) {
this.$.queryDialog.queryEle.setParamSet(params);
this.$.filterDialog.setParamSet(params);
// TODO(kjlubick) in the lit-html version, this should reflect of digests as matched by
// the positive/negative/diff selector (i.e. the things above it).
const corpora = params['source_type'].map((name) => {
return {
name: name,
};
});
this.$.corpusSelector.corpora = corpora;
},
setCommitInfo: function(commits) {
this.$.filterDialog.setCommitInfo(commits);
},
_handleQueryEdit: function(ev) {
ev.stopPropagation();
this.set('state.query', ev.detail);
},
_handleFilterEdit: function(ev) {
ev.stopPropagation();
// merge filter into state
var newState = sk.object.applyDelta(ev.detail, this.state);
this.set('state', newState);
},
_handleSearchButton: function(ev) {
ev.stopPropagation();
this.$.queryDialog.open(this.state.query);
},
_handleFilterButton: function(ev) {
ev.stopPropagation();
this.$.filterDialog.open(this.state.filter);
},
_handleCorpusChange: function(ev) {
this.$.queryDialog.close();
// TODO(kjlubick) This is a dirty ugly hack, making the corpus change reload the entire
// page. However, the port to lit-html is coming soon, and I don't feel like making
// more changes to this Polymer code than is necessary.
const params = sk.query.toParamSet(this.state.query);
params.source_type = [ev.detail.corpus];
this.state.query = sk.query.fromParamSet(params);
window.location = window.location.pathname + gold.queryFromState(this.state);
},
_fireStateChange: function() {
if (this._noFire) {
this._noFire = false;
return;
}
var detail = sk.object.shallowCopy(this.state);
this.fire('state-change', detail);
},
_splitAmp: function(qStr) {
return sk.query.splitAmp(qStr, ', ');
}
});
</script>
</dom-module>