This is an automated email from the ASF dual-hosted git repository. apucher pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-pinot.git
The following commit(s) were added to refs/heads/master by this push: new 9dfb949 [TE] rootcause - rich metric selector (#3567) 9dfb949 is described below commit 9dfb949df93ea0b3bc8fc74cf4a2b03a8b6fde87 Author: Alexander Pucher <apuc...@linkedin.com> AuthorDate: Thu Nov 29 16:31:22 2018 -0800 [TE] rootcause - rich metric selector (#3567) Improve visualization of metrics selector on root cause page. Displays metric names similar to metrics table, with dataset subscript and dimension values. Also enables quick-selection of metrics with pre-existing dimensions. --- .../app/mirage/endpoints/rootcause.js | 3 +- .../app/pods/components/filter-select/component.js | 14 +++---- .../rootcause-select-metric-dimension/component.js | 9 +++-- .../rootcause-select-metric-dimension/template.hbs | 2 +- .../rootcause-select-metric/component.js | 46 +++++++++++++++------- .../rootcause-select-metric/template.hbs | 6 +-- .../pods/custom/metrics-table-metric/template.hbs | 2 +- .../rootcause/select-metric-label/template.hbs | 6 +++ .../styles/components/rootcause-select-metric.scss | 28 +++++++++++-- .../tests/acceptance/rootcause-test.js | 7 +--- 10 files changed, 82 insertions(+), 41 deletions(-) diff --git a/thirdeye/thirdeye-frontend/app/mirage/endpoints/rootcause.js b/thirdeye/thirdeye-frontend/app/mirage/endpoints/rootcause.js index 9a158e7..2041a10 100644 --- a/thirdeye/thirdeye-frontend/app/mirage/endpoints/rootcause.js +++ b/thirdeye/thirdeye-frontend/app/mirage/endpoints/rootcause.js @@ -185,7 +185,8 @@ export default function(server) { server.get('/rootcause/metric/aggregate', () => {}); server.get('/rootcause/metric/aggregate/cache', () => {}); server.get('/rootcause/metric/breakdown', () => {}); - server.get('rootcause/metric/aggregate/batch', () => {}); + server.get('/rootcause/metric/aggregate/batch', () => {}); + server.get('/rootcause/metric/aggregate/chunk', () => {}); server.get('/rootcause/metric/timeseries', () => { return { timestamp: [moment().valueOf()], diff --git a/thirdeye/thirdeye-frontend/app/pods/components/filter-select/component.js b/thirdeye/thirdeye-frontend/app/pods/components/filter-select/component.js index cf91bf8..2fb0114 100644 --- a/thirdeye/thirdeye-frontend/app/pods/components/filter-select/component.js +++ b/thirdeye/thirdeye-frontend/app/pods/components/filter-select/component.js @@ -152,15 +152,13 @@ export default Component.extend({ // Selected Filters Serializer selectedFilters: computed('selected', { get() { - const filters = JSON.parse(this.get('selected')); + const selected = this.get('selected') || '{}'; + const filters = JSON.parse(selected); return convertHashToFilters(filters); }, set(key, value) { - const filters = convertFiltersToHash(value); - this.set('selected', filters); - - return value; + this.set('selected', value); } }), @@ -201,10 +199,12 @@ export default Component.extend({ // Action handler for filter Selection/Deselection onFilterChange(filters) { const onChangeHandler = this.get('onChange'); - this.set('selectedFilters', filters); + + const newSelected = convertFiltersToHash(filters); + this.set('selected', newSelected); if (onChangeHandler) { - onChangeHandler(this.get('selected')); + onChangeHandler(newSelected); } } } diff --git a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric-dimension/component.js b/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric-dimension/component.js index 412c8f7..6b855b8 100644 --- a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric-dimension/component.js +++ b/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric-dimension/component.js @@ -208,11 +208,14 @@ export default Component.extend({ const baseUrn = metricUrns[0]; const { selectedUrn, baseUrnCache } = getProperties(this, 'selectedUrn', 'baseUrnCache'); - const filterMap = toFilterMap(toFilters(selectedUrn)); - if (!_.isEqual(baseUrn, baseUrnCache)) { + const previousFilterMap = toFilterMap(toFilters(selectedUrn)); + const incomingFilterMap = toFilterMap(toFilters(baseUrn)); + const newFilterMap = _.isEmpty(incomingFilterMap) ? previousFilterMap : incomingFilterMap; + + if (!_.isEqual(baseUrn, baseUrnCache) || !_.isEqual(previousFilterMap, newFilterMap)) { setProperties(this, { baseUrn, baseUrnCache: baseUrn }); - this._fetchFilters(baseUrn, filterMap); + this._fetchFilters(baseUrn, newFilterMap); } }, diff --git a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric-dimension/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric-dimension/template.hbs index c155cce..61716d5 100644 --- a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric-dimension/template.hbs +++ b/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric-dimension/template.hbs @@ -1,7 +1,7 @@ <div class="row"> <div class="col-xs-6"> <label class="te-label te-label--small" for="select-metric"> - Metrics to Investigate + Metric under Investigation <span> <i class="glyphicon glyphicon-question-sign"></i> {{#tooltip-on-element class="te-tooltip"}} diff --git a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric/component.js b/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric/component.js index d5c78af..b8a087b 100644 --- a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric/component.js +++ b/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric/component.js @@ -1,6 +1,6 @@ import Component from '@ember/component'; import fetch from 'fetch'; -import { toBaselineUrn, toCurrentUrn, filterPrefix } from 'thirdeye-frontend/utils/rca-utils'; +import { toBaselineUrn, toCurrentUrn, filterPrefix, toMetricLabel } from 'thirdeye-frontend/utils/rca-utils'; import { selfServeApiCommon } from 'thirdeye-frontend/utils/api/self-serve'; import { task, timeout } from 'ember-concurrency'; import _ from 'lodash'; @@ -40,24 +40,40 @@ export default Component.extend({ 'entities', 'selectedUrns', function() { const { selectedUrns, entities } = this.getProperties('selectedUrns', 'entities'); + + // NOTE: all of this is very hacky as it merges data from two different sources - entities and the autocomplete + const selectedMetrics = filterPrefix(selectedUrns, 'thirdeye:metric:') .filter(urn => urn in entities) .map((urn) => { const entity = entities[urn]; - const agg = { alias: entity.label, id: entity.urn.split(':')[2] }; - return agg; + const labelParts = entity.label.split('::'); + return { + alias: entity.label, + urn: entity.urn, + name: toMetricLabel(urn, entities), + dataset: labelParts[0], + isSelected: true + }; }); + const relatedMetrics = filterPrefix(Object.keys(entities), 'thirdeye:metric:') - .filter(urn => urn in entities) - .map((urn) => { - const entity = entities[urn]; - const agg = { alias: entity.label, id: entity.urn.split(':')[2] }; - return agg; - }); + .filter(urn => urn in entities && !selectedUrns.has(urn)) + .map((urn) => { + const entity = entities[urn]; + const labelParts = entity.label.split('::'); + return { + alias: entity.label, + urn: entity.urn, + name: toMetricLabel(urn, entities), + dataset: labelParts[0], + isSelected: false + }; + }); return [ - { groupName: 'Selected Metrics', options: _.sortBy(selectedMetrics, (row) => row.alias) || [] }, - { groupName: 'Related Metrics', options: _.sortBy(relatedMetrics, (row) => row.alias) || [] } + { groupName: 'Selected Metrics', options: _.sortBy(selectedMetrics || [], (row) => row.alias) }, + { groupName: 'Related Metrics', options: _.sortBy(relatedMetrics || [], (row) => row.alias) } ]; } ), @@ -103,6 +119,7 @@ export default Component.extend({ recommendedMetricsAction(metric) { this.send('onChange', metric); }, + /** * Action handler for metric search changes * @param {Object} metric @@ -111,10 +128,11 @@ export default Component.extend({ const { onSelection } = this.getProperties('onSelection'); if (!onSelection) { return; } - const { id } = metric; - if (!id) { return; } + const { urn, id } = metric; + if (!urn && !id) { return; } + + const metricUrn = urn ? urn : `thirdeye:metric:${id}`; - const metricUrn = `thirdeye:metric:${id}`; const updates = { [metricUrn]: true, [toBaselineUrn(metricUrn)]: true, [toCurrentUrn(metricUrn)]: true }; onSelection(updates); diff --git a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric/template.hbs index 6d4d1ea..a495ac1 100644 --- a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric/template.hbs +++ b/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-metric/template.hbs @@ -10,9 +10,5 @@ matchTriggerWidth=false as |metric| }} -{{#if (eq selectedMetric.alias metric.alias)}} - <span class="bluelink">{{metric.alias}}</span> -{{else}} - {{metric.alias}} -{{/if}} + {{partial 'partials/rootcause/select-metric-label'}} {{/power-select}} diff --git a/thirdeye/thirdeye-frontend/app/pods/custom/metrics-table-metric/template.hbs b/thirdeye/thirdeye-frontend/app/pods/custom/metrics-table-metric/template.hbs index 3a90a3e..948efb0 100644 --- a/thirdeye/thirdeye-frontend/app/pods/custom/metrics-table-metric/template.hbs +++ b/thirdeye/thirdeye-frontend/app/pods/custom/metrics-table-metric/template.hbs @@ -5,5 +5,5 @@ {{/if}} </p> <p class="metrics-table__value--small"> - ({{get record 'dataset'}}) + {{get record 'dataset'}} </p> diff --git a/thirdeye/thirdeye-frontend/app/pods/partials/rootcause/select-metric-label/template.hbs b/thirdeye/thirdeye-frontend/app/pods/partials/rootcause/select-metric-label/template.hbs new file mode 100644 index 0000000..8e43434 --- /dev/null +++ b/thirdeye/thirdeye-frontend/app/pods/partials/rootcause/select-metric-label/template.hbs @@ -0,0 +1,6 @@ +<p class="rootcause-select-metric__value {{if (get-safe metric "isSelected") "rootcause-select-metric__value--bluelink"}}"> + {{get-safe metric "name"}} +</p> +<p class="rootcause-select-metric__value--small"> + {{get-safe metric "dataset"}} +</p> diff --git a/thirdeye/thirdeye-frontend/app/styles/components/rootcause-select-metric.scss b/thirdeye/thirdeye-frontend/app/styles/components/rootcause-select-metric.scss index bf6bef3..c8695bd 100644 --- a/thirdeye/thirdeye-frontend/app/styles/components/rootcause-select-metric.scss +++ b/thirdeye/thirdeye-frontend/app/styles/components/rootcause-select-metric.scss @@ -3,8 +3,30 @@ } .ember-power-select-option { - .bluelink { - font-weight: bold; - color: $te-blue; + +} + +#select-metric .ember-power-select-selected-item { + margin-left: 0; +} + +.rootcause-select-metric { + &__value { + margin: 0; + padding: 0; + height: 21px; + + &--small { + margin: 0; + padding: 0; + height: 18px; + font-size: 10px; + color: app-shade(black, 0.60); + } + + &--bluelink { + font-weight: bold; + color: $te-blue; + } } } diff --git a/thirdeye/thirdeye-frontend/tests/acceptance/rootcause-test.js b/thirdeye/thirdeye-frontend/tests/acceptance/rootcause-test.js index d429204..d646111 100644 --- a/thirdeye/thirdeye-frontend/tests/acceptance/rootcause-test.js +++ b/thirdeye/thirdeye-frontend/tests/acceptance/rootcause-test.js @@ -17,7 +17,7 @@ module('Acceptance | rootcause', async function(hooks) { test(`visiting /rootcause on anomalyId shows correct header title`, async assert => { await visit('/rootcause?anomalyId=1'); - + assert.ok( $('.rootcause-header__major').get(0).value.includes('Investigation on pageViews'), 'title is correct'); @@ -53,11 +53,6 @@ module('Acceptance | rootcause', async function(hooks) { 'pageViews', 'metric label is correct' ); - assert.equal( - $(rcEl.SELECTED_METRIC).get(0).innerText.trim(), - 'pageViews', - 'selected metric is correct' - ); }); test('visiting rootcause page and making changes to the title and comment should create a session with saved changes', --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org For additional commands, e-mail: commits-h...@pinot.apache.org