| <!-- 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(); |
| // TODO(kjlubick) ev.detail does not include the source_type because there was some |
| // special logic in gold.js to add it on when the state changed. This is very confusing |
| // and no longer works (because the corpus selector was moved into the page). Thus, |
| // we need to append the corpus ourselves. This will be not needed when we port this |
| // page to lit-html. |
| const existingCorpus = sk.query.toParamSet(this.state.query).source_type; |
| const newQuery = `source_type=${encodeURIComponent(existingCorpus)}&${ev.detail}`; |
| console.debug('updating search to ', newQuery); |
| this.set('state.query', newQuery); |
| }, |
| |
| _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> |