| <!-- 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 fiels: |
| - 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. |
| |
| orientation - Orientation of the controls. Values: 'horizontal', 'vertical' |
| 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, .verticalTopControl { |
| font-weight: bold; |
| } |
| |
| .verticalTopControl { |
| margin: 0 0 1em 0; |
| } |
| |
| .horizontalTopControl { |
| margin: 0 2em 0 0; |
| } |
| |
| .buttonContainer { |
| width: 8em; |
| } |
| |
| .buttonContainer.verticalTopControl { |
| margin-top: 2em; |
| } |
| |
| .horizontal.currSelection { |
| margin-left: 1em; |
| margin-right: 3em; |
| max-width: 20em; |
| } |
| |
| .vertical.currSelection { |
| padding-top: 1em; |
| max-width: 10em; |
| } |
| </style> |
| <div class$="[[orientation]] layout"> |
| <paper-toggle-button class$="{{_tcClass(orientation)}}" checked="{{state.pos}}" disabled={{disabled}}>Positive</paper-toggle-button> |
| <paper-toggle-button class$="{{_tcClass(orientation)}}" checked="{{state.neg}}" disabled={{disabled}}>Negative</paper-toggle-button> |
| <paper-toggle-button class$="{{_tcClass(orientation)}}" checked="{{state.unt}}" disabled={{disabled}}>Untriaged</paper-toggle-button> |
| <paper-toggle-button class$="{{_tcClass(orientation)}}" checked="{{state.head}}" disabled={{disabled}}>Head</paper-toggle-button> |
| <paper-toggle-button class$="{{_tcClass(orientation)}}" checked="{{state.include}}" disabled={{disabled}}>Ignored</paper-toggle-button> |
| |
| <div class="buttonContainer"> |
| <paper-button id="searchButton" class$="topControl" raised disabled="[[disabled]]" |
| title="Filter Traces"><iron-icon icon="image:tune"></iron-icon></paper-button> |
| </div> |
| <!-- TODO(stephana): Enable filter button when backend is ready --> |
| <div class$="{{_tcClass(orientation)}} buttonContainer"> |
| <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$="[[orientation]] currSelection"> |
| [[_splitAmp(state.query, orientation)]] |
| </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 |
| }, |
| |
| orientation: { |
| type: String, |
| value: "horizontal" |
| }, |
| |
| 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'); |
| |
| // 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); |
| }, |
| |
| setParamSet: function(params) { |
| this.$.queryDialog.queryEle.setParamSet(params); |
| this.$.filterDialog.setParamSet(params); |
| }, |
| |
| 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(); |
| }, |
| |
| _fireStateChange: function() { |
| if (this._noFire) { |
| this._noFire = false; |
| return; |
| } |
| |
| var detail = sk.object.shallowCopy(this.state); |
| this.fire('state-change', detail); |
| }, |
| |
| _tcClass: function(orientation) { |
| return (orientation==='horizontal') ? "horizontalTopControl" : "verticalTopControl"; |
| }, |
| |
| _splitAmp: function(qStr, orientation) { |
| return sk.query.splitAmp(qStr, (orientation === 'horizontal') ? ', ':' \n'); |
| } |
| |
| }); |
| </script> |
| </dom-module> |