This is an automated email from the ASF dual-hosted git repository.
jihao 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 ca8545b [TE] frontend - abachuk/alert-details-ui-tweaks - formatting
alert header (#6210)
ca8545b is described below
commit ca8545b29218e79910a35cd592a547d17cb945d3
Author: Alex Bachuk <[email protected]>
AuthorDate: Thu Nov 5 16:40:50 2020 -0500
[TE] frontend - abachuk/alert-details-ui-tweaks - formatting alert header
(#6210)
* refactoring alert details breakdown to <dl>
* styling edit and share buttons
* adding html title tags, header layout change
* minor changes, cleanup
* configuring the linter with single quote formatting
* cleanup eslintrc
* fixing unclosed string
* removing single quote eslint rule to not break some unit tests until we
standardize the linters
* fixing indent issue before in the class name
authored-by: Alex Bachuk <[email protected]>
---
thirdeye/thirdeye-frontend/.eslintrc.js | 44 +++--
.../self-serve-alert-yaml-details/template.hbs | 148 +++++++--------
.../pods/components/timeseries-chart/component.js | 205 ++++++++++++++-------
.../app/pods/home/index/template.hbs | 127 ++++++-------
.../app/pods/manage/explore/template.hbs | 25 +--
.../app/styles/components/button.scss | 34 ++--
.../app/styles/shared/_styles.scss | 40 ++--
.../share-custom-template/component-test.js | 34 ++--
.../thirdeye-frontend/tests/utils/constants.js | 4 +-
9 files changed, 358 insertions(+), 303 deletions(-)
diff --git a/thirdeye/thirdeye-frontend/.eslintrc.js
b/thirdeye/thirdeye-frontend/.eslintrc.js
index 1c01456..d086263 100644
--- a/thirdeye/thirdeye-frontend/.eslintrc.js
+++ b/thirdeye/thirdeye-frontend/.eslintrc.js
@@ -1,36 +1,34 @@
module.exports = {
globals: {
- server: true,
+ server: true
},
root: true,
parserOptions: {
ecmaVersion: 2018,
- sourceType: 'module',
+ sourceType: 'module'
},
- plugins: [
- 'ember'
- ],
- extends: [
- 'eslint:recommended',
- 'plugin:ember/recommended'
- ],
+ plugins: ['ember'],
+ extends: ['eslint:recommended', 'plugin:ember/recommended'],
env: {
browser: true,
es6: true
},
rules: {
- "eol-last": ["warn", "always"],
- "indent": ["warn", 2, { "SwitchCase": 1 }],
- "space-in-parens": ["warn", "never"],
- "no-trailing-spaces": ["warn"],
- "comma-dangle": ["warn", "never"],
- "comma-spacing": ["warn", { "before": false, "after": true }],
- "semi": ["warn", "always"],
- "comma-style": ["warn", "last"],
- "no-unused-vars": ["warn", { "vars": "all", "args": "after-used",
"ignoreRestSiblings": false }],
- // TODO: fix all warnings and change rules back to "error"
- "ember/avoid-leaking-state-in-ember-objects": ["warn"],
- "ember/no-attrs-in-components": ["warn"]
+ 'eol-last': ['warn', 'always'],
+ indent: ['warn', 2, { SwitchCase: 1 }],
+ 'space-in-parens': ['warn', 'never'],
+ 'no-trailing-spaces': ['warn'],
+ 'comma-dangle': ['warn', 'never'],
+ 'comma-spacing': ['warn', { before: false, after: true }],
+ semi: ['warn', 'always'],
+ 'comma-style': ['warn', 'last'],
+ 'no-unused-vars': [
+ 'warn',
+ { vars: 'all', args: 'after-used', ignoreRestSiblings: false },
+ ],
+ // TODO: fix all warnings and change rules back to 'error'
+ 'ember/avoid-leaking-state-in-ember-objects': ['warn'],
+ 'ember/no-attrs-in-components': ['warn']
},
overrides: [
// node files
@@ -58,6 +56,6 @@ module.exports = {
env: {
embertest: true
}
- }
- ]
+ },
+ ],
};
diff --git
a/thirdeye/thirdeye-frontend/app/pods/components/self-serve-alert-yaml-details/template.hbs
b/thirdeye/thirdeye-frontend/app/pods/components/self-serve-alert-yaml-details/template.hbs
index 7a92159..9a62b22 100644
---
a/thirdeye/thirdeye-frontend/app/pods/components/self-serve-alert-yaml-details/template.hbs
+++
b/thirdeye/thirdeye-frontend/app/pods/components/self-serve-alert-yaml-details/template.hbs
@@ -1,103 +1,79 @@
-<div class="te-search-results__header">
- <div class="te-search-results__title-group">
+<div class="te-search-results__header row">
+ <div class="te-search-results__title-group col-md-10 col-xs-9">
<div class="te-search-results__title">
- <span
title={{alertData.detectionName}}>{{alertData.detectionName}}</span>
+ <h3 class="te-search-results__title-name"
title={{alertData.detectionName}}>{{alertData.detectionName}}</h3>
{{#if (eq displayMode "list")}}
- {{#link-to "manage.explore" alertData.id}}
- <div class="te-search-results__title-name"
title={{alertData.detectionName}}>{{alertData.detectionName}}</div>
- {{/link-to}}
+ {{#link-to "manage.explore" alertData.id}}
+ <div class="te-search-results__title-name"
title={{alertData.detectionName}}>{{alertData.detectionName}}</div>
+ {{/link-to}}
{{/if}}
- <h4 class="te-alert-page__subtitle">{{alertData.description}}</h4>
{{#if isLoadError}}
- <div class="te-search-results__tag {{if (eq displayMode "list")
"te-search-results__tag--list"}} {{if alertData.isActive
"te-search-results__tag--active"}}">
- Error
- </div>
+ <div
+ class="te-search-results__tag {{if (eq displayMode "list")
"te-search-results__tag--list"}} {{if alertData.isActive
"te-search-results__tag--active"}}">
+ Error
+ </div>
{{else}}
- <div class="te-search-results__tag {{if (eq displayMode "list")
"te-search-results__tag--list"}} {{if alertData.isActive
"te-search-results__tag--active"}}">
- {{if alertData.isActive "Active" "Inactive"}}
- </div>
- {{#x-toggle
+ <div
+ class="te-search-results__tag {{if (eq displayMode "list")
"te-search-results__tag--list"}} {{if alertData.isActive
"te-search-results__tag--active"}}">
+ {{if alertData.isActive "Active" "Inactive"}}
+ </div>
+ {{#x-toggle
value=alertData.isActive
classNames="te-toggle te-toggle--form te-toggle--left report-toggle
activation-toggle"
theme="ios"
id="active-toggle"
showLabels=false
name="activeToggle"
- onToggle=(action "toggleAlertActivation")
- as |toggle|}}
- {{toggle.switch theme='ios' onLabel='diff on' offLabel='diff off'}}
- {{/x-toggle}}
+ onToggle=(action "toggleAlertActivation")
+ as |toggle|}}
+ {{toggle.switch theme='ios' onLabel='diff on' offLabel='diff off'}}
+ {{/x-toggle}}
{{/if}}
</div>
</div>
- {{yield}}
+ <div class="col-md-2 col-xs-3">
+ <div class="pull-right">{{yield}}</div>
+ </div>
</div>
-
+<h4 class="te-alert-page__subtitle">{{alertData.description}}</h4>
{{#if (not isLoadError)}}
- <ul class="te-search-results__list te-search-results__list--details-block
row">
- <div class="col-xs-12 col-sm-5">
- <li class="te-search-results__row">
- <div class="te-search-results__option
te-search-results__option--{{modeSubClass}}
te-search-results__option--left">Metric</div>
- <div class="te-search-results__value{{valueClassSuffix}}"
title={{alertData.metric}}>{{alertData.metric}}</div>
- </li>
- <li class="te-search-results__row">
- <div class="te-search-results__option
te-search-results__option--{{modeSubClass}}
te-search-results__option--left">Dataset</div>
- <div class="te-search-results__value{{valueClassSuffix}}"
title={{alertData.dataset}}>
- <span class="{{unless alertData.dataset
'te-search-results__prop--missing' 'te-search-results__prop'}}">
- {{if alertData.dataset alertData.dataset 'N/A'}}
- </span>
- </div>
- </li>
- <li class="te-search-results__row">
- <div class="te-search-results__option
te-search-results__option--{{modeSubClass}}
te-search-results__option--left">Filtered By</div>
- <div class="te-search-results__value{{valueClassSuffix}}"
title={{alertData.filters}}>
- <span class="{{unless alertData.filters
'te-search-results__prop--missing' 'te-search-results__prop'}}">
- {{if alertData.filters alertData.filters 'N/A'}}
- </span>
- </div>
- </li>
- <li class="te-search-results__row">
- <div class="te-search-results__option
te-search-results__option--{{modeSubClass}}
te-search-results__option--left">Breakdown By</div>
- <div class="te-search-results__value{{valueClassSuffix}}"
title={{alertData.dimensionExploration}}>
- <span class="{{unless alertData.dimensionExploration
'te-search-results__prop--missing' 'te-search-results__prop'}}">
- {{if alertData.dimensionExploration alertData.dimensionExploration
'N/A'}}
- </span>
- </div>
- </li>
- </div>
- <div class="col-xs-12 col-sm-7">
- <li class="te-search-results__row">
- <div class="te-search-results__option
te-search-results__option--{{modeSubClass}}
te-search-results__option--left">Created By</div>
- <div class="te-search-results__value{{valueClassSuffix}}"
title={{alertData.createdBy}}>
- <span class="{{unless alertData.createdBy
'te-search-results__prop--missing' 'te-search-results__prop'}}">
- {{if alertData.createdBy alertData.createdBy 'N/A'}}
- </span>
- </div>
- </li>
- <li class="te-search-results__row">
- <div class="te-search-results__option
te-search-results__option--{{modeSubClass}}
te-search-results__option--left">Updated By</div>
- <div class="te-search-results__value{{valueClassSuffix}}"
title={{alertData.updatedBy}}>
- <span class="{{unless alertData.updatedBy
'te-search-results__prop--missing' 'te-search-results__prop'}}">
- {{if alertData.updatedBy alertData.updatedBy 'N/A'}}
- </span>
- </div>
- </li>
- <li class="te-search-results__row">
- <div class="te-search-results__option
te-search-results__option--{{modeSubClass}}
te-search-results__option--left">Last detection</div>
- <div class="te-search-results__value{{valueClassSuffix}}"
title={{alertData.lastDetectionTime}}>
- <span class="{{unless alertData.lastDetectionTime
'te-search-results__prop--missing' 'te-search-results__prop'}}">
- {{if alertData.lastDetectionTime alertData.lastDetectionTime
'N/A'}}
- </span>
- </div>
- </li>
- <li class="te-search-results__row">
- <div class="te-search-results__option
te-search-results__option--{{modeSubClass}}
te-search-results__option--left">Subscribed Groups</div>
- <div class="te-search-results__value{{valueClassSuffix}}"
title={{subscribedGroups}}>
- <span class="{{unless subscribedGroups
'te-search-results__prop--missing' 'te-search-results__prop'}}">
- {{if subscribedGroups subscribedGroups 'N/A'}}
- </span>
- </div>
- </li>
- </div>
- </ul>
+<div class="te-alert-detail-breakdown row">
+ <dl class="col-xs-12 col-sm-5 row">
+ <dt class="col-md-4">Metric</dt>
+ <dd class="col-md-8 te-search-results__value{{valueClassSuffix}}"
title={{alertData.metric}}>{{alertData.metric}}
+ </dd>
+
+ <dt class="col-md-4">Dataset</dt>
+ <dd class="col-md-8 te-search-results__value{{valueClassSuffix}}"
title={{alertData.dataset}}>
+ {{if alertData.dataset alertData.dataset 'N/A'}}
+ </dd>
+
+ <dt class="col-md-4">Filtered By</dt>
+ <dd class="col-md-8 te-search-results__value{{valueClassSuffix}}"
title={{alertData.filters}}>
+ {{if alertData.filters alertData.filters 'N/A'}}</dd>
+
+ <dt class="col-md-4">Breakdown By</dt>
+ <dd class="col-md-8 te-search-results__value{{valueClassSuffix}}"
title={{alertData.dimensionExploration}}>
+ {{if alertData.dimensionExploration alertData.dimensionExploration
'N/A'}}</dd>
+ </dl>
+
+ <dl class="col-xs-12 col-sm-5 row">
+ <dt class="col-md-4">Created By</dt>
+ <dd class="col-md-8 te-search-results__value{{valueClassSuffix}}"
title={{alertData.createdBy}}>
+ {{if alertData.createdBy alertData.createdBy 'N/A'}}</dd>
+
+ <dt class="col-md-4">Updated By</dt>
+ <dd class="col-md-8 te-search-results__value{{valueClassSuffix}}"
title={{alertData.updatedBy}}>
+ {{if alertData.updatedBy alertData.updatedBy 'N/A'}}</dd>
+
+ <dt class="col-md-4">Last detection</dt>
+ <dd class="col-md-8 te-search-results__value{{valueClassSuffix}}"
title={{alertData.lastDetectionTime}}>
+ {{if alertData.lastDetectionTime alertData.lastDetectionTime 'N/A'}}</dd>
+
+ <dt class="col-md-4">Subscribed Groups</dt>
+ <dd class="col-md-8 te-search-results__value{{valueClassSuffix}}"
title={{subscribedGroups}}>
+ {{if subscribedGroups subscribedGroups 'N/A'}}
+ </dd>
+ </dl>
+</div>
{{/if}}
diff --git
a/thirdeye/thirdeye-frontend/app/pods/components/timeseries-chart/component.js
b/thirdeye/thirdeye-frontend/app/pods/components/timeseries-chart/component.js
index 574f1a9..337a692 100644
---
a/thirdeye/thirdeye-frontend/app/pods/components/timeseries-chart/component.js
+++
b/thirdeye/thirdeye-frontend/app/pods/components/timeseries-chart/component.js
@@ -86,20 +86,24 @@ export default Component.extend({
pink: '#FF1B90'
},
- subchart: { // on init only
+ subchart: {
+ // on init only
show: true
},
- zoom: { // on init only
+ zoom: {
+ // on init only
enabled: true,
onzoom: null
},
- point: { // on init only
+ point: {
+ // on init only
show: true
},
- line: { // on init only
+ line: {
+ // on init only
connectNull: false
},
@@ -109,18 +113,27 @@ export default Component.extend({
const cache = this.get('_seriesCache') || {};
const series = this.get('series') || {};
const colorMapping = this.get('colorMapping');
- const { axis, legend, tooltip, focusedIds } = this.getProperties('axis',
'legend', 'tooltip', 'focusedIds');
+ const { axis, legend, tooltip, focusedIds } = this.getProperties(
+ 'axis',
+ 'legend',
+ 'tooltip',
+ 'focusedIds'
+ );
const seriesKeys = Object.keys(series).sort();
- const addedKeys = seriesKeys.filter(sid => !cache[sid]);
- const changedKeys = seriesKeys.filter(sid => cache[sid] &&
!_.isEqual(cache[sid], series[sid]));
- const deletedKeys = Object.keys(cache).filter(sid => !series[sid]);
- const regionKeys = seriesKeys.filter(sid => series[sid] &&
series[sid].type == 'region');
+ const addedKeys = seriesKeys.filter((sid) => !cache[sid]);
+ const changedKeys = seriesKeys.filter(
+ (sid) => cache[sid] && !_.isEqual(cache[sid], series[sid])
+ );
+ const deletedKeys = Object.keys(cache).filter((sid) => !series[sid]);
+ const regionKeys = seriesKeys.filter(
+ (sid) => series[sid] && series[sid].type == 'region'
+ );
// keys containing '-region' should not appear in the graph legend.
- const noLegendKeys = seriesKeys.filter(sid => (sid.includes('-region')));
+ const noLegendKeys = seriesKeys.filter((sid) => sid.includes('-region'));
- const regions = regionKeys.map(sid => {
+ const regions = regionKeys.map((sid) => {
const t = series[sid].timestamps;
let region = { start: t[0], end: t[t.length - 1] };
@@ -132,42 +145,72 @@ export default Component.extend({
});
const unloadKeys = deletedKeys.concat(noLegendKeys);
- const unload = unloadKeys.concat(unloadKeys.map(sid =>
`${sid}-timestamps`));
+ const unload = unloadKeys.concat(
+ unloadKeys.map((sid) => `${sid}-timestamps`)
+ );
- const loadKeys = addedKeys.concat(changedKeys).filter(sid =>
!noLegendKeys.includes(sid));
+ const loadKeys = addedKeys
+ .concat(changedKeys)
+ .filter((sid) => !noLegendKeys.includes(sid));
const xs = {};
- loadKeys.forEach(sid => xs[sid] = `${sid}-timestamps`);
+ loadKeys.forEach((sid) => (xs[sid] = `${sid}-timestamps`));
- const values = loadKeys.map(sid => [sid].concat(series[sid].values));
+ const values = loadKeys.map((sid) => [sid].concat(series[sid].values));
- const timestamps = loadKeys.map(sid =>
[`${sid}-timestamps`].concat(series[sid].timestamps));
+ const timestamps = loadKeys.map((sid) =>
+ [`${sid}-timestamps`].concat(series[sid].timestamps)
+ );
const columns = values.concat(timestamps);
const colors = {};
- loadKeys.filter(sid => series[sid].color).forEach(sid => colors[sid] =
colorMapping[series[sid].color]);
+ loadKeys
+ .filter((sid) => series[sid].color)
+ .forEach((sid) => (colors[sid] = colorMapping[series[sid].color]));
const types = {};
- loadKeys.filter(sid => series[sid].type).forEach(sid => types[sid] =
series[sid].type);
+ loadKeys
+ .filter((sid) => series[sid].type)
+ .forEach((sid) => (types[sid] = series[sid].type));
const axes = {};
- loadKeys.filter(sid => 'axis' in series[sid]).forEach(sid => axes[sid] =
series[sid].axis);
+ loadKeys
+ .filter((sid) => 'axis' in series[sid])
+ .forEach((sid) => (axes[sid] = series[sid].axis));
// keep the lower bound line in graph but remove in from the legend
legend.hide = ['lowerBound', 'old-anomaly-edges', 'new-anomaly-edges'];
- const config = { unload, xs, columns, types, regions, tooltip, focusedIds,
colors, axis, axes, legend };
+ const config = {
+ unload,
+ xs,
+ columns,
+ types,
+ regions,
+ tooltip,
+ focusedIds,
+ colors,
+ axis,
+ axes,
+ legend
+ };
return config;
},
_makeAxisRange(axis) {
const range = { min: {}, max: {} };
- Object.keys(axis).filter(key => 'min' in axis[key]).forEach(key =>
range['min'][key] = axis[key]['min']);
- Object.keys(axis).filter(key => 'max' in axis[key]).forEach(key =>
range['max'][key] = axis[key]['max']);
+ Object.keys(axis)
+ .filter((key) => 'min' in axis[key])
+ .forEach((key) => (range['min'][key] = axis[key]['min']));
+ Object.keys(axis)
+ .filter((key) => 'max' in axis[key])
+ .forEach((key) => (range['max'][key] = axis[key]['max']));
return range;
},
_updateCache() {
// debounce: do not trigger if chart object already destroyed
- if (this.isDestroyed) { return; }
+ if (this.isDestroyed) {
+ return;
+ }
const series = this.get('series') || {};
this.set('_seriesCache', _.cloneDeep(series));
@@ -176,7 +219,7 @@ export default Component.extend({
/**
* Updates the focused entity on the chart
*/
- _updateFocusedIds: function() {
+ _updateFocusedIds: function () {
const ids = this.get('focusedIds');
if (!_.isEmpty(ids)) {
@@ -213,69 +256,91 @@ export default Component.extend({
this._updateCache();
},
- _shadeBounds(){
+ _shadeBounds() {
const parentElement = this.api.internal.config.bindto;
- d3.select(parentElement).select(".confidence-bounds").remove();
- d3.select(parentElement).select(".sub-confidence-bounds").remove();
-
d3.select(parentElement).select('.timeseries-graph__slider-circle').remove();
-
d3.select(parentElement).selectAll('timeseries-graph__slider-line').remove();
+ d3.select(parentElement).select('.confidence-bounds').remove();
+ d3.select(parentElement).select('.sub-confidence-bounds').remove();
+ d3.select(parentElement)
+ .select('.timeseries-graph__slider-circle')
+ .remove();
+ d3.select(parentElement)
+ .selectAll('timeseries-graph__slider-line')
+ .remove();
const chart = this.api;
- if (chart && chart.legend && chart.internal && chart.internal.data &&
chart.internal.data.targets) {
+ if (
+ chart &&
+ chart.legend &&
+ chart.internal &&
+ chart.internal.data &&
+ chart.internal.data.targets
+ ) {
if (chart.internal.data.targets.length > 24) {
chart.legend.hide();
}
}
// key is 'Upper and lower bound' because we delete the lowerBound key for
the legend.
- if(chart && chart.internal && chart.internal.data &&
chart.internal.data.xs && Array.isArray(chart.internal.data.xs['Upper and lower
bound'])) {
- const indices = d3.range(chart.internal.data.xs['Upper and lower
bound'].length);
+ if (
+ chart &&
+ chart.internal &&
+ chart.internal.data &&
+ chart.internal.data.xs &&
+ Array.isArray(chart.internal.data.xs['Upper and lower bound'])
+ ) {
+ const indices = d3.range(
+ chart.internal.data.xs['Upper and lower bound'].length
+ );
const yscale = chart.internal.y;
const xscale = chart.internal.x;
const yscaleSub = chart.internal.subY;
const xscaleSub = chart.internal.subX;
const xVals = chart.internal.data.xs['Upper and lower bound'];
- let upperBoundVals = chart.internal.data.targets.find(target => {
+ let upperBoundVals = chart.internal.data.targets.find((target) => {
return target.id === 'Upper and lower bound';
});
- let lowerBoundVals = chart.internal.data.targets.find(target => {
+ let lowerBoundVals = chart.internal.data.targets.find((target) => {
return target.id === 'lowerBound';
});
if (upperBoundVals && lowerBoundVals) {
- upperBoundVals = upperBoundVals.values.map(e => e.value);
- lowerBoundVals = lowerBoundVals.values.map(e => e.value);
+ upperBoundVals = upperBoundVals.values.map((e) => e.value);
+ lowerBoundVals = lowerBoundVals.values.map((e) => e.value);
// If all upper bound vals are null, we assume that there is only a
lower bound
- if (upperBoundVals.every(val => val === null)) {
- let currentVals = chart.internal.data.targets.find(target => {
+ if (upperBoundVals.every((val) => val === null)) {
+ let currentVals = chart.internal.data.targets.find((target) => {
return target.id === 'Current';
});
if (currentVals) {
- currentVals = currentVals.values.map(e => e.value);
+ currentVals = currentVals.values.map((e) => e.value);
const currentMax = Math.max(...currentVals);
upperBoundVals = upperBoundVals.map(() => 2 * currentMax);
}
}
- const area_main = d3.area()
+ const area_main = d3
+ .area()
.curve(d3.curveLinear)
- .x(d => xscale(xVals[d]))
- .y0(d => yscale(lowerBoundVals[d]))
- .y1(d => yscale(upperBoundVals[d]));
+ .x((d) => xscale(xVals[d]))
+ .y0((d) => yscale(lowerBoundVals[d]))
+ .y1((d) => yscale(upperBoundVals[d]));
- const area_sub = d3.area()
+ const area_sub = d3
+ .area()
.curve(d3.curveLinear)
- .x(d => xscaleSub(xVals[d]))
- .y0(d => yscaleSub(lowerBoundVals[d]))
- .y1(d => yscaleSub(upperBoundVals[d]));
+ .x((d) => xscaleSub(xVals[d]))
+ .y0((d) => yscaleSub(lowerBoundVals[d]))
+ .y1((d) => yscaleSub(upperBoundVals[d]));
let i = 0;
const bothCharts =
d3.select(parentElement).selectAll('.c3-chart-bars');
- bothCharts.each(function() {
+ bothCharts.each(function () {
if (i === 0 && this) {
- d3.select(this).insert('path')
+ d3.select(this)
+ .insert('path')
.datum(indices)
.attr('class', 'confidence-bounds')
.attr('d', area_main);
} else if (i === 1 && this) {
- d3.select(this).insert('path')
+ d3.select(this)
+ .insert('path')
.datum(indices)
.attr('class', 'sub-confidence-bounds')
.attr('d', area_sub);
@@ -287,32 +352,36 @@ export default Component.extend({
// add resize buttons after shading bounds
const resizeButtons = d3.selectAll('.resize');
- resizeButtons.append('circle')
+ resizeButtons
+ .append('circle')
.attr('class', 'timeseries-graph__slider-circle')
.attr('cx', 0)
.attr('cy', 30)
.attr('r', 10)
.attr('fill', '#0091CA');
- resizeButtons.append('line')
+ resizeButtons
+ .append('line')
.attr('class', 'timeseries-graph__slider-line')
- .attr("x1", 0)
- .attr("y1", 27)
- .attr("x2", 0)
- .attr("y2", 33);
+ .attr('x1', 0)
+ .attr('y1', 27)
+ .attr('x2', 0)
+ .attr('y2', 33);
- resizeButtons.append('line')
+ resizeButtons
+ .append('line')
.attr('class', 'timeseries-graph__slider-line')
- .attr("x1", -5)
- .attr("y1", 27)
- .attr("x2", -5)
- .attr("y2", 33);
+ .attr('x1', -5)
+ .attr('y1', 27)
+ .attr('x2', -5)
+ .attr('y2', 33);
- resizeButtons.append('line')
+ resizeButtons
+ .append('line')
.attr('class', 'timeseries-graph__slider-line')
- .attr("x1", 5)
- .attr("y1", 27)
- .attr("x2", 5)
- .attr("y2", 33);
+ .attr('x1', 5)
+ .attr('y1', 27)
+ .attr('x2', 5)
+ .attr('y2', 33);
},
didUpdateAttrs() {
@@ -327,7 +396,7 @@ export default Component.extend({
}
},
- didRender(){
+ didRender() {
this._super(...arguments);
later(() => {
@@ -342,7 +411,7 @@ export default Component.extend({
*/
notifyPhantomJS() {
if (typeof window.callPhantom === 'function') {
- window.callPhantom({message: 'ready'});
+ window.callPhantom({ message: 'ready' });
}
},
diff --git a/thirdeye/thirdeye-frontend/app/pods/home/index/template.hbs
b/thirdeye/thirdeye-frontend/app/pods/home/index/template.hbs
index 7fa2f59..be4ea77 100644
--- a/thirdeye/thirdeye-frontend/app/pods/home/index/template.hbs
+++ b/thirdeye/thirdeye-frontend/app/pods/home/index/template.hbs
@@ -11,29 +11,29 @@
selectAction=(action "onRangeSelection")
}}
{{#if appOrSubGroup}}
- {{#link-to "home.share-dashboard" (query-params appName=appName
subGroup=subGroup duration=duration startDate=startDate endDate=endDate
feedbackType=feedbackType shareId=null) tagName="button" type="button"
class="pull-right te-button te-button--outline"}}
- Share
- {{/link-to}}
+ {{#link-to "home.share-dashboard" (query-params appName=appName
subGroup=subGroup duration=duration startDate=startDate endDate=endDate
feedbackType=feedbackType shareId=null) tagName="button" type="button"
class="btn pull-right te-button te-button--outline"}}
+ Share
+ {{/link-to}}
{{/if}}
</header>
<article class="dashboard-container__body">
<section class="dashboard-container__application-header">
<div class="dashboard-container__application-or-subgroup">
- <strong>Anomalies filter by: </strong>
+ <strong>Anomalies filter by: </strong>
{{#each anomaliesByOptions as |option|}}
- <div class="dashboard-container__radio-button-item">
- {{#radio-button value=option groupValue=anomaliesBySelected
changed=(action "onAnomaliesBy")}}
- <span class="te-radio__option">{{option}}</span>
- {{/radio-button}}
- </div>
+ <div class="dashboard-container__radio-button-item">
+ {{#radio-button value=option groupValue=anomaliesBySelected
changed=(action "onAnomaliesBy")}}
+ <span class="te-radio__option">{{option}}</span>
+ {{/radio-button}}
+ </div>
{{/each}}
</div>
{{#if byApplication}}
- <div class="dashboard-container__application-header-dropdown">
- <label class="te-label te-label--small">Application</label>
- {{#power-select
+ <div class="dashboard-container__application-header-dropdown">
+ <label class="te-label te-label--small">Application</label>
+ {{#power-select
options=sortedApplications
selected=appNameSelected
searchField="application"
@@ -41,13 +41,13 @@
placeholder="Please pick an application"
onchange=(action "selectApplication")
as |app|}}
- {{app.application}}
- {{/power-select}}
- </div>
+ {{app.application}}
+ {{/power-select}}
+ </div>
{{else}}
- <div class="dashboard-container__application-header-dropdown">
- <label class="te-label te-label--small">Subscription Group</label>
- {{#power-select
+ <div class="dashboard-container__application-header-dropdown">
+ <label class="te-label te-label--small">Subscription Group</label>
+ {{#power-select
options=sortedSubscriptionGroups
selected=subGroupSelected
searchField="name"
@@ -55,27 +55,27 @@
placeholder="Please pick a subscription group"
onchange=(action "selectSubscriptionGroup")
as |subGroup|}}
- {{subGroup.name}}
- {{/power-select}}
- </div>
+ {{subGroup.name}}
+ {{/power-select}}
+ </div>
{{/if}}
<div>
{{#if byApplication}}
- <h3 class="dashboard-container__title">{{appName}}</h3>
+ <h3 class="dashboard-container__title">{{appName}}</h3>
{{else}}
- <h3 class="dashboard-container__title">{{subGroup}}</h3>
+ <h3 class="dashboard-container__title">{{subGroup}}</h3>
{{/if}}
</div>
</section>
- {{#if isLoading}}
+ {{#if isLoading}}
<div class="dashboard-container__spinner-wrapper">
{{ember-spinner lines=30 radius=20 length=0 width=10 opacity=0 trail=75
color='blue'}}
</div>
- {{/if}}
+ {{/if}}
- {{#if areAnomaliesCurrent}}
+ {{#if areAnomaliesCurrent}}
<section>
{{stats-cards stats=stats}}
</section>
@@ -93,34 +93,36 @@
onchange=(action "onFilterBy" feedbackType)
as |feedbackType|
}}
- {{feedbackType}}
+ {{feedbackType}}
{{/power-select}}
<a class="pull-right thirdeye-link" {{action 'toggleAllAccordions'}}>
{{#if toggleCollapsed}}
- Expand all <i class="glyphicon glyphicon-menu-down"></i>
+ Expand all <i class="glyphicon glyphicon-menu-down"></i>
{{else}}
- Collapse all <i class="glyphicon glyphicon-menu-up"></i>
+ Collapse all <i class="glyphicon glyphicon-menu-up"></i>
{{/if}}
</a>
</div>
{{#bs-accordion as |accordion|}}
- {{#each-in filteredAnomalyMapping as |metric humanizedEntityList|}}
- {{#accordion.item value=metric as |aitem|}}
- {{#aitem.title}}
- <section class="dashboard-container__title">Metric:
- <span>{{metric}} ({{humanizedEntityList.length}} {{if (gt
humanizedEntityList.length 1) "anomalies" "anomaly"}})</span>
- <span><i class="glyphicon glyphicon-menu-{{if toggleCollapsed
"down" "up"}}"></i></span>
- </section>
- {{/aitem.title}}
- {{#aitem.body collapsed=toggleCollapsed}}
- {{#if isReportAnomalyEnabled}}
- <div class="pull-left">
- <i class="glyphicon glyphicon-edit
dashboard-container__icon"></i> Report missing anomaly in <span
class="anomalies-table__text anomalies-table__text--stronger">alert page</span>
for: </div>
- <div class="pull-left dashboard-container__alert-selector">
- {{#with (get model.alertsByMetric metric) as |alertList|}}
- {{#power-select
+ {{#each-in filteredAnomalyMapping as |metric humanizedEntityList|}}
+ {{#accordion.item value=metric as |aitem|}}
+ {{#aitem.title}}
+ <section class="dashboard-container__title">Metric:
+ <span>{{metric}} ({{humanizedEntityList.length}}
+ {{if (gt humanizedEntityList.length 1) "anomalies"
"anomaly"}})</span>
+ <span><i class="glyphicon glyphicon-menu-{{if toggleCollapsed "down"
"up"}}"></i></span>
+ </section>
+ {{/aitem.title}}
+ {{#aitem.body collapsed=toggleCollapsed}}
+ {{#if isReportAnomalyEnabled}}
+ <div class="pull-left">
+ <i class="glyphicon glyphicon-edit dashboard-container__icon"></i>
Report missing anomaly in <span
+ class="anomalies-table__text anomalies-table__text--stronger">alert
page</span> for: </div>
+ <div class="pull-left dashboard-container__alert-selector">
+ {{#with (get model.alertsByMetric metric) as |alertList|}}
+ {{#power-select
triggerId=metric
id=metric
triggerClass="te-form__select te-form__select--shortened"
@@ -131,15 +133,16 @@
onchange=(action "onSelectAlert" metric)
as |alertOption|
}}
- {{alertOption}}
- {{/power-select}}
- {{/with}}
- </div>
- <div class="te-button te-button--outline pull-left
dashboard-container__go-link">
- <a class="thirdeye-link thirdeye-link--terciary" href="#"
{{action "onClickReport" metric humanizedEntityList}}>GO</a>
- </div>
- {{/if}}
- {{models-table
+ {{alertOption}}
+ {{/power-select}}
+ {{/with}}
+ </div>
+ <div class="te-button te-button--outline pull-left
dashboard-container__go-link">
+ <a class="thirdeye-link thirdeye-link--terciary" href="#"
+ {{action "onClickReport" metric humanizedEntityList}}>GO</a>
+ </div>
+ {{/if}}
+ {{models-table
data=humanizedEntityList
columns=columns
customClasses=classes
@@ -150,23 +153,23 @@
pageSize=5
showComponentFooter=true
}}
- {{/aitem.body}}
- {{/accordion.item}}
- {{!-- TODO: leave to decide if after poc we need it - lohuynh
+ {{/aitem.body}}
+ {{/accordion.item}}
+ {{!-- TODO: leave to decide if after poc we need it - lohuynh
{{#if (gt humanizedEntityList.length 5)}}
<a href="{{get (get model.redirectLink metric) alert}}"
class="dashboard-container__redirect-link">
See More
</a>
{{/if}} --}}
- {{else}}
- {{partial 'partials/home'}}
- {{/each-in}}
+ {{else}}
+ {{partial 'partials/home'}}
+ {{/each-in}}
{{/bs-accordion}}
</section>
- {{else}}
+ {{else}}
{{partial 'partials/home'}}
- {{/if}}
+ {{/if}}
</article>
</div>
-{{outlet}}
+{{outlet}}
\ No newline at end of file
diff --git a/thirdeye/thirdeye-frontend/app/pods/manage/explore/template.hbs
b/thirdeye/thirdeye-frontend/app/pods/manage/explore/template.hbs
index 1938545..a0599f7 100644
--- a/thirdeye/thirdeye-frontend/app/pods/manage/explore/template.hbs
+++ b/thirdeye/thirdeye-frontend/app/pods/manage/explore/template.hbs
@@ -6,11 +6,11 @@
isLoadError=isLoadError
toggleActivation=(action "toggleActivation")
}}
- <div class="te-search-results__cta">
- {{#link-to "manage.yaml" model.alertId}}
- <button class="te-button te-button--outline">Edit</button>
- {{/link-to}}
- </div>
+ <div class="te-search-results__cta">
+ {{#link-to "manage.yaml" model.alertId}}
+ <button class="te-button te-button--outline btn">Edit</button>
+ {{/link-to}}
+ </div>
{{/self-serve-alert-yaml-details}}
</div>
</section>
@@ -18,13 +18,14 @@
<section class="te-page__bottom">
<div class="container">
{{#if isLoadError}}
- <div class="te-alert-page-pending">
- <img src="{{rootURL}}assets/images/te-alert-error.png"
class="te-alert-page-pending__image te-alert-page-pending__image--error"
alt="error">
- <h2 class="te-alert-page-pending__title">Oops, something went
wrong</h2>
- <p class="te-alert-page-pending__text">{{errorText}}</p>
- </div>
+ <div class="te-alert-page-pending">
+ <img src="{{rootURL}}assets/images/te-alert-error.png"
+ class="te-alert-page-pending__image
te-alert-page-pending__image--error" alt="error">
+ <h2 class="te-alert-page-pending__title">Oops, something went wrong</h2>
+ <p class="te-alert-page-pending__text">{{errorText}}</p>
+ </div>
{{else}}
- {{alert-details
+ {{alert-details
isPreviewMode=false
alertYaml=model.detectionYaml
showDetails=true
@@ -40,4 +41,4 @@
}}
{{/if}}
</div>
-</section>
+</section>
\ No newline at end of file
diff --git a/thirdeye/thirdeye-frontend/app/styles/components/button.scss
b/thirdeye/thirdeye-frontend/app/styles/components/button.scss
index 5a61682..d840dcc 100644
--- a/thirdeye/thirdeye-frontend/app/styles/components/button.scss
+++ b/thirdeye/thirdeye-frontend/app/styles/components/button.scss
@@ -2,11 +2,12 @@
.te-button {
border-radius: 2px;
- border: 1px solid #339BC7;
+ border: 1px solid #339bc7;
margin: 0 1px;
font-size: 17px;
line-height: 20px;
font-weight: 600;
+ transition: background-color 0.3s ease;
&--small {
height: 32px;
@@ -14,22 +15,22 @@
}
&--cancel {
- background-color: #FFF;
- color: #339BC7;
+ background-color: #fff;
+ color: #339bc7;
a {
- color: #339BC7;
+ color: #339bc7;
}
&:hover,
&:focus,
&:active,
a:hover {
- color: #339BC7;
+ color: #339bc7;
text-decoration: none;
}
}
&--muted {
- background-color: #FFF;
+ background-color: #fff;
border-color: app-shade(black, 0.55);
color: app-shade(black, 0.55);
a {
@@ -38,8 +39,8 @@
&:hover,
&:focus,
&:active,
- a:hover, {
- background-color: rgba(207,207,207,.25);
+ a:hover {
+ background-color: rgba(207, 207, 207, 0.25);
border-color: app-shade(black, 0.75);
color: app-shade(black, 0.75);
text-decoration: none;
@@ -49,20 +50,20 @@
&--submit {
margin-left: 4px;
background-color: $te-blue-7;
- color: #FFF;
+ color: #fff;
&:hover,
&:focus,
&:active,
a:hover {
- color: #FFF;
+ color: #fff;
text-decoration: none;
background-color: $te-blue-8;
}
}
&--link {
- border-color: #FFF;
+ border-color: #fff;
color: $te-blue;
cursor: pointer;
text-decoration: none;
@@ -88,14 +89,19 @@
}
&--link-white {
- border-color: #FFF;
- color: #FFF;
+ border-color: #fff;
+ color: #fff;
background-color: inherit;
text-decoration: none;
}
&--outline {
color: $te-blue;
+ background-color: transparent;
+ &:hover {
+ background-color: $te-blue;
+ color: #fff;
+ }
}
}
@@ -106,7 +112,7 @@
font-size: 17px;
line-height: 20px;
font-weight: 600;
- border-color: #FFF;
+ border-color: #fff;
color: $te-blue;
cursor: pointer;
text-decoration: none;
diff --git a/thirdeye/thirdeye-frontend/app/styles/shared/_styles.scss
b/thirdeye/thirdeye-frontend/app/styles/shared/_styles.scss
index 85a27a3..b3c34b4 100644
--- a/thirdeye/thirdeye-frontend/app/styles/shared/_styles.scss
+++ b/thirdeye/thirdeye-frontend/app/styles/shared/_styles.scss
@@ -54,7 +54,7 @@ body {
.te-table-global-filter {
display: inline-block;
padding-bottom: 5px;
- padding-right:5px;
+ padding-right: 5px;
}
.te-column-dropdown {
@@ -340,7 +340,7 @@ body {
background-color: rgba(0, 0, 0, 0.03);
}
- &:hover:not(:disabled){
+ &:hover:not(:disabled) {
border-color: app-shade(black, 0.55);
}
@@ -392,7 +392,7 @@ body {
font-size: $te-font-size-small;
color: $te-link-blue;
font-weight: 600;
- letter-spacing: .03em;
+ letter-spacing: 0.03em;
float: right;
margin: -15px 10px 0 0;
cursor: pointer;
@@ -448,17 +448,17 @@ body {
&__number {
color: black;
&--good {
- color: #4B9D27;
+ color: #4b9d27;
font-weight: normal;
}
&--average {
- color: #F5A623;
+ color: #f5a623;
font-weight: normal;
}
&--poor {
- color: #FF4B51;
+ color: #ff4b51;
font-weight: normal;
}
}
@@ -590,7 +590,6 @@ body {
}
&__val-glyph {
-
&--middle {
padding: 26px 10px 0 9px;
font-size: 19px;
@@ -722,7 +721,7 @@ body {
&__title {
font-size: 40px;
font-weight: 100;
- letter-spacing: .02em;
+ letter-spacing: 0.02em;
}
&__text {
@@ -751,9 +750,15 @@ body {
}
}
+.te-alert-page {
+ &__subtitle {
+ margin: 0 0 $te-content-container-margin 0;
+ }
+}
+
.glyphicon-spin {
- -webkit-animation: spin 1000ms infinite linear;
- animation: spin 1000ms infinite linear;
+ -webkit-animation: spin 1000ms infinite linear;
+ animation: spin 1000ms infinite linear;
}
.te-search-results {
@@ -780,10 +785,6 @@ body {
}
&__header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 14px;
}
&__row {
@@ -821,8 +822,6 @@ body {
&__value {
overflow: hidden;
text-overflow: ellipsis;
- color: black;
- max-height: 19px;
}
&__value-solo {
@@ -844,13 +843,16 @@ body {
&__title {
min-width: 95px;
+ display: flex;
}
&__title-name {
overflow: hidden;
text-overflow: ellipsis;
- max-width: 660px;
+ max-width: 80%;
display: inline-block;
+ font-weight: 600;
+ margin: 0 $te-spacing 0 0;
}
&__edit-button {
@@ -884,7 +886,7 @@ body {
background-color: app-shade(black, 3);
font-size: 13px;
text-transform: uppercase;
- letter-spacing: .08em;
+ letter-spacing: 0.08em;
line-height: 20px;
border-radius: 3px;
padding: 4px 8px;
@@ -894,6 +896,7 @@ body {
width: auto;
font-weight: bold;
border: 2px solid;
+ cursor: default;
&--list {
margin: 3px 10px 0 0;
@@ -940,7 +943,6 @@ body {
}
&__a-tag {
-
&--good {
text-decoration: none !important;
color: $te-good !important;
diff --git
a/thirdeye/thirdeye-frontend/tests/integration/pods/components/share-custom-template/component-test.js
b/thirdeye/thirdeye-frontend/tests/integration/pods/components/share-custom-template/component-test.js
index 93b104e..c079019 100644
---
a/thirdeye/thirdeye-frontend/tests/integration/pods/components/share-custom-template/component-test.js
+++
b/thirdeye/thirdeye-frontend/tests/integration/pods/components/share-custom-template/component-test.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
import { module, test } from 'qunit';
-import { run } from "@ember/runloop";
+import { run } from '@ember/runloop';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
@@ -18,23 +18,23 @@ module('Integration | Component | share custom template',
function(hooks) {
start: '1539626400000',
end: '1539626400000',
shareConfig: {
- groupName: 'someGroup',
- appName: 'someApp',
- chart: 'table',
- title: 'Title of metrics',
- entities: [
- [
- { type: 'label', value: 'Column name1', index: 0},
- { type: 'label', value: 'Column name2', index: 0},
- { type: 'label', value: 'Column name3', index: 0}
- ],
- [
- { type: 'label', value: 'Email', index: 1},
- { type: 'change', metrics: ['thirdeye:metric:11111'], offsets:
['current', 'wo1w'], summary: ['69.0M', '-2.03'], index: 1},
- { type: 'change', metrics: ['thirdeye:metric:22222'], offsets:
['current', 'wo1w'], summary: ['69.0M', '-2.03'], index: 1}
- ]
+ groupName: 'someGroup',
+ appName: 'someApp',
+ chart: 'table',
+ title: 'Title of metrics',
+ entities: [
+ [
+ { type: 'label', value: 'Column name1', index: 0},
+ { type: 'label', value: 'Column name2', index: 0},
+ { type: 'label', value: 'Column name3', index: 0}
+ ],
+ [
+ { type: 'label', value: 'Email', index: 1},
+ { type: 'change', metrics: ['thirdeye:metric:11111'], offsets:
['current', 'wo1w'], summary: ['69.0M', '-2.03'], index: 1},
+ { type: 'change', metrics: ['thirdeye:metric:22222'], offsets:
['current', 'wo1w'], summary: ['69.0M', '-2.03'], index: 1}
]
- }
+ ]
+ }
});
// Rendering the component
diff --git a/thirdeye/thirdeye-frontend/tests/utils/constants.js
b/thirdeye/thirdeye-frontend/tests/utils/constants.js
index d304868..2b51b14 100644
--- a/thirdeye/thirdeye-frontend/tests/utils/constants.js
+++ b/thirdeye/thirdeye-frontend/tests/utils/constants.js
@@ -1,4 +1,4 @@
-import { isPresent } from "@ember/utils";
+import { isPresent } from '@ember/utils';
/**
* General self-serve element selectors
@@ -69,7 +69,7 @@ export const selfServeConst = {
LINK_TUNE_ALERT: '.te-self-serve__side-link:contains("Customize
sensitivity")',
// Tuning Page Elements
- LINK_ALERT_PAGE: '.te-button:contains("Back to overview")',
+ LINK_ALERT_PAGE: '.te-button:contains("Back to overview")'
};
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]