You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by xh...@apache.org on 2020/05/29 20:36:18 UTC

[incubator-pinot] branch master updated: [TE] frontend - harleyjj/components - remove dead components (#5466)

This is an automated email from the ASF dual-hosted git repository.

xhsun 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 2807584  [TE] frontend - harleyjj/components - remove dead components (#5466)
2807584 is described below

commit 2807584edfefc710d7c084747a0a509526205587
Author: Harley Jackson <hj...@linkedin.com>
AuthorDate: Fri May 29 13:36:04 2020 -0700

    [TE] frontend - harleyjj/components - remove dead components (#5466)
---
 .../app/pods/components/alert-details/template.hbs |   1 +
 .../components/alert-report-modal/template.hbs     |   6 +
 .../app/pods/components/anomaly-graph/component.js | 764 ---------------------
 .../app/pods/components/anomaly-graph/template.hbs | 120 ----
 .../app/pods/components/anomaly-id/component.js    |  37 -
 .../app/pods/components/anomaly-id/template.hbs    |  15 -
 .../components/anomaly-stats-block/component.js    |  21 -
 .../components/anomaly-stats-block/template.hbs    |  53 --
 .../pods/components/dimension-heatmap/component.js | 199 ------
 .../pods/components/dimension-heatmap/template.hbs |  16 -
 .../pods/components/dimension-summary/component.js |   5 -
 .../pods/components/dimension-summary/template.hbs |  16 -
 .../app/pods/components/events-header/component.js |  86 ---
 .../app/pods/components/events-header/template.hbs |  26 -
 .../app/pods/components/events-table/component.js  | 134 ----
 .../app/pods/components/events-table/template.hbs  |  16 -
 .../modals/manage-groups-modal/component.js        | 716 -------------------
 .../modals/manage-groups-modal/template.hbs        | 239 -------
 .../components/performance-tooltip/component.js    |   5 -
 .../components/performance-tooltip/template.hbs    |  17 -
 .../self-serve-alert-yaml-details/component.js     |   2 +-
 .../pods/components/self-serve-graph/component.js  | 114 ---
 .../pods/components/self-serve-graph/template.hbs  |  38 -
 .../pods/components/thirdeye-chart/component.js    |   8 -
 .../pods/components/thirdeye-chart/template.hbs    |   1 -
 .../pods/custom/anomalies-table/rule/template.hbs  |   2 +-
 .../app/pods/example/controller.js                 |  10 -
 .../thirdeye-frontend/app/pods/example/route.js    |  32 -
 .../app/pods/example/template.hbs                  |  23 -
 .../pods/manage/alerts/performance/controller.js   | 101 ---
 .../app/pods/manage/alerts/performance/route.js    | 348 ----------
 .../pods/manage/alerts/performance/template.hbs    | 140 ----
 .../app/pods/self-serve/create-alert/template.hbs  |  15 -
 thirdeye/thirdeye-frontend/app/router.js           |   2 +-
 thirdeye/thirdeye-frontend/app/styles/app.scss     |   4 -
 .../app/styles/components/anomaly-graph.scss       | 151 ----
 .../app/styles/components/anomaly-id.scss          |  32 -
 .../app/styles/components/dimension-heatmap.scss   |  69 --
 .../app/styles/components/dimension-summary.scss   |  30 -
 .../app/styles/pods/manage/alerts-performance.scss |  20 -
 .../components/anomaly-graph/component-test.js     |  23 -
 .../pods/components/anomaly-id/component-test.js   |  55 --
 .../components/thirdeye-chart/component-test.js    |  26 -
 43 files changed, 10 insertions(+), 3728 deletions(-)

diff --git a/thirdeye/thirdeye-frontend/app/pods/components/alert-details/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/alert-details/template.hbs
index b622e43..9760ad6 100644
--- a/thirdeye/thirdeye-frontend/app/pods/components/alert-details/template.hbs
+++ b/thirdeye/thirdeye-frontend/app/pods/components/alert-details/template.hbs
@@ -247,6 +247,7 @@
                   isMetricDataLoading=isMetricDataLoading
                   isMetricDataInvalid=isMetricDataInvalid
                   inputAction=(action "onInputMissingAnomaly")
+                  isReportFailure=isReportFailure
                 }}
               {{else}}
                 {{ember-spinner}}
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/alert-report-modal/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/alert-report-modal/template.hbs
index 8bb3444..08e85fb 100644
--- a/thirdeye/thirdeye-frontend/app/pods/components/alert-report-modal/template.hbs
+++ b/thirdeye/thirdeye-frontend/app/pods/components/alert-report-modal/template.hbs
@@ -47,6 +47,12 @@
     {{/if}}
   </fieldset>
 
+  {{#if isReportFailure}}
+    {{#bs-alert type="danger" class="te-form__banner te-form__banner--failure"}}
+      <strong>Error:</strong> Failed to save reported anomaly. Did you select dates and times?
+    {{/bs-alert}}
+  {{/if}}
+
   <fieldset class="te-form__section row">
     <div class="form-group col-xs-6">
       <legend class="te-report-title">Mark the Anomaly Region</legend>
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/anomaly-graph/component.js b/thirdeye/thirdeye-frontend/app/pods/components/anomaly-graph/component.js
deleted file mode 100644
index 3ac6d93..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/anomaly-graph/component.js
+++ /dev/null
@@ -1,764 +0,0 @@
-import $ from 'jquery';
-import { set, computed } from '@ember/object';
-import { later } from '@ember/runloop';
-import Component from '@ember/component';
-import moment from 'moment';
-import d3 from 'd3';
-import { humanizeFloat } from 'thirdeye-frontend/utils/utils';
-
-const COLOR_MAPPING = {
-  blue: '#33AADA',
-  orange: '#EF7E37',
-  teal: '#17AFB8',
-  purple: '#9896F2',
-  red: '#FF6C70',
-  green: '#6BAF49',
-  pink: '#FF61b6',
-  light_blue: '#65C3E8',
-  light_orange: '#F6A16C',
-  light_teal: '#68C5CD',
-  light_purple: '#B2B0FA',
-  light_red: '#FF999A',
-  light_green: '#91C475',
-  light_pink: '#FF91CF'
-};
-
-export default Component.extend({
-  init() {
-    this._super(...arguments);
-    const subChartStart = this.get('subChartStart');
-    const subChartEnd = this.get('subChartEnd');
-    this.setProperties({
-      _subchartStart: Number(this.get('subchartStart')),
-      _subchartEnd: Number(this.get('subchartEnd'))
-    });
-  },
-
-  // Helper function that builds the subchart region buttons
-  buildSliderButton() {
-    const componentId = this.get('componentId');
-    const resizeButtons = d3.select(`#${componentId}.c3-chart-component`).selectAll('.resize');
-
-    resizeButtons.append('circle')
-      .attr('cx', 0)
-      .attr('cy', 30)
-      .attr('r', 10)
-      .attr('fill', '#0091CA');
-    resizeButtons.append('line')
-      .attr('class', 'anomaly-graph__slider-line')
-      .attr("x1", 0)
-      .attr("y1", 27)
-      .attr("x2", 0)
-      .attr("y2", 33);
-
-    resizeButtons.append('line')
-      .attr('class', 'anomaly-graph__slider-line')
-      .attr("x1", -5)
-      .attr("y1", 27)
-      .attr("x2", -5)
-      .attr("y2", 33);
-
-    resizeButtons.append('line')
-      .attr('class', 'anomaly-graph__slider-line')
-      .attr("x1", 5)
-      .attr("y1", 27)
-      .attr("x2", 5)
-      .attr("y2", 33);
-  },
-
-  // Builds the Current/Expected legend for the graph
-  buildCustomLegend() {
-    const componentId = this.get('componentId');
-    const chart = d3.select(`#${componentId}.c3-chart-component`);
-    const legendText = this.get('legendText');
-
-    const {
-      solid = { text: 'current', color: 'blue' }
-    }  = legendText;
-
-    chart.insert('div', '.chart').attr('class', 'anomaly-graph__legend').selectAll('span')
-      .data([solid])
-      .enter().append('svg')
-      .attr('class', 'anomaly-graph__legend-item')
-      .attr('width', 80)
-      .attr('height', 20)
-      .attr('data-id', function (el) { return el.text; })
-      .each(function (el) {
-        const element = d3.select(this);
-
-        element.append('text')
-          .attr('x', 35)
-          .attr('y', 12)
-          .text(el.text);
-
-        element.append('line')
-          .attr('class', function(el) {
-            return `anomaly-graph__legend-line anomaly-graph__legend-line--${el.color}`;
-          })
-          .attr('x1', 0)
-          .attr('y1', 10)
-          .attr('x2', 30)
-          .attr('y2', 10)
-          .attr('stroke-dasharray', () => {
-            const dasharrayNum = 'none';
-            return dasharrayNum;
-          });
-      });
-    // Necessary so that it is 'thenable'
-    return Promise.resolve();
-  },
-
-  willDestroyElement() {
-    this._super(...arguments);
-
-    const subchartStart = this.get('_subchartStart');
-    const subchartEnd = this.get('_subchartEnd');
-
-
-    this.setProperties({
-      subchartStart,
-      subchartEnd
-    });
-  },
-
-  didRender(){
-    this._super(...arguments);
-
-    later(() => {
-      this.buildSliderButton();
-      this.buildCustomLegend().then(() => {
-        this.notifyPhantomJS();
-      });
-    });
-  },
-
-  /**
-   * Checks if the page is being viewed from phantomJS
-   * and notifies it that the page is rendered and ready
-   * for a screenshot
-   */
-  notifyPhantomJS() {
-    if (typeof window.callPhantom === 'function') {
-      window.callPhantom({message: 'ready'});
-    }
-  },
-
-  /**
-   * Maps each metric and event to a color / class
-   */
-  didReceiveAttrs() {
-    this._super(...arguments);
-
-    const colors = {};
-    const primaryMetric = this.get('primaryMetric');
-    const relatedMetric = this.get('relatedMetrics') || [];
-    const selectedMetrics = this.get('selectedMetrics') || [];
-    const selectedDimensions = this.get('selectedDimensions') || [];
-    const events = this.get('holidayEvents') || [];
-
-    // This check is necessary so that it is only set once
-    if (primaryMetric.isSelected === undefined) {
-      set(primaryMetric, 'isSelected', true);
-    }
-
-    const data = [
-      primaryMetric,
-      ...relatedMetric,
-      ...selectedMetrics,
-      ...selectedDimensions
-    ];
-
-    data.forEach((datum) => {
-      const name = datum.metricName || datum.name;
-      const { color } = datum;
-      colors[`${name}-current`] = COLOR_MAPPING[color || 'blue'];
-      colors[`${name}-expected`] = COLOR_MAPPING[color || 'orange'];
-    });
-
-    events.forEach((event) => {
-      const { displayColor = 'blue'} = event;
-      colors[event.displayLabel] = COLOR_MAPPING[displayColor];
-    });
-
-    this.set('colors', colors);
-  },
-
-  tagName: 'div',
-  classNames: ['anomaly-graph'],
-  primaryMetric: {},
-  relatedMetrics: [],
-  selectedMetrics: [],
-  dimensions: [],
-  selectedDimensions: [],
-
-  showGraphLegend: false,
-  colors: {},
-  showSubChart: false,
-  subchartStart: null,
-  subchartEnd: null,
-
-  _subchartStart: 0,
-  _subchartEnd: 0,
-
-  analysisStart: 0,
-  analysisEnd: 0,
-
-  showLegend: false,
-  // contains copy for the legend
-  // currently supports 'dotted' and 'solid'
-  legendText: {},
-
-  showTitle: false,
-  height: 0,
-  componentId: 'main-graph',
-
-  initStart: null,
-  initEnd: null,
-  anomalyRegionStart: 0,
-  anomalyRegionEnd: 0,
-  regionStart: 0,
-  regionEnd: 0,
-
-  showEvents: false,
-  showDimensions: false,
-  showMetrics: false,
-  events: [],
-
-  enableZoom: false,
-
-  // padding for the anomaly graph (optional)
-  padding: null,
-
-  // dd for primary metric
-  primaryMetricId: computed('componentId', function() {
-    return this.get('componentId') + '-primary-metric-';
-  }),
-
-  // id for related metrics
-  relatedMetricId: computed('componentId', function() {
-    return this.get('componentId') + '-related-metric-';
-  }),
-
-  // id for dimension
-  dimensionId:  computed('componentId', function() {
-    return this.get('componentId') + '-dimension-';
-  }),
-
-  // filtered events for graph
-  holidayEvents: computed('events', function() {
-    return this.get('events');
-    // const events = this.get('events');
-    // const hiddenEvents = [];
-    // return events.filter((event) => {
-    //   return !hiddenEvents.includes(event.eventType);
-    // });
-  }),
-
-  holidayEventsColumn: computed(
-    'holidayEvents',
-    function() {
-      const events = this.get('holidayEvents');
-
-      return events.map((event) => {
-        const {
-          // start,
-          // end,
-          displayScore,
-          displayLabel
-        } = event;
-
-        // const scores = (!end || start === end)
-        //   ? [score, score]
-        //   : [score];
-        return [displayLabel, displayScore];
-      });
-    }
-  ),
-
-  holidayEventsDatesColumn: computed(
-    'holidayEvents',
-    function() {
-      const holidays = this.get('holidayEvents');
-
-      return holidays.map((holiday) => {
-        const { displayStart, displayEnd } = holiday;
-
-        const start = displayStart;
-        const end = displayEnd;
-
-        const date = !end ? [end] : [start];
-
-        return [`${holiday.displayLabel}-date`, date];
-      });
-    }
-  ),
-
-  /**
-   * Graph Legend config
-   */
-  legend: computed('showGraphLegend', function() {
-    return {
-      position: 'inset',
-      show: false
-    };
-  }),
-
-  /**
-   * Graph Zoom config
-   */
-  zoom: computed(
-    'onSubchartChange',
-    'enableZoom',
-    function() {
-      const onSubchartBrush = this.get('onSubchartChange');
-      return {
-        enabled: this.get('enableZoom'),
-        onzoomend: onSubchartBrush,
-        rescale: true
-      };
-    }
-  ),
-
-  /**
-   * Graph Point Config
-   */
-  point: computed(
-    'showGraphLegend',
-    function() {
-      return {
-        show: true,
-        r: function(data) {
-          const { id } = data;
-          if (id.includes('current') || id.includes('expected')) {
-            return 0;
-          }
-
-          return 5;
-        }
-      };
-    }
-  ),
-
-  /**
-   * Graph axis config
-   */
-  axis: computed(
-    'chartDates',
-    'primaryMetric',
-    'subchartStart',
-    'subchartEnd',
-    'showEvents',
-    'minDate',
-    'maxDate',
-    function() {
-      const [ _, ...dates ] = this.get('chartDates');
-      const subchartStart = this.get('_subchartStart')
-        || this.get('subchartStart');
-      const subchartEnd = this.get('_subchartEnd')
-        || this.get('subchartEnd');
-      const min = dates.get('firstObject');
-      const max = dates.get('lastObject');
-      const extentStart = Math.max(min, moment(subchartStart).valueOf());
-      const extentEnd = Math.min(max, moment(subchartEnd).valueOf());
-
-      const extentRange = (subchartStart && subchartEnd)
-        ? [extentStart, extentEnd]
-        : null;
-
-      return {
-        y: {
-          show: true,
-          // min: 0,
-          tick: {
-            format: function(d){return humanizeFloat(d);}
-          }
-        },
-        y2: {
-          show: false,
-          label: 'events score',
-          min: 0,
-          max: 1,
-          padding: {
-            bottom: 0
-          },
-          tick: {
-            values: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
-          }
-        },
-        x: {
-          type: 'timeseries',
-          show: true,
-          padding: 0,
-          min: this.get('minDate') || min,
-          max: this.get('maxDate') || max,
-          tick: {
-            fit: false
-            // format: function (x) { return new Date(x).toString(); }
-          },
-          extent: extentRange
-        }
-      };
-    }
-  ),
-
-  /**
-   * Graph Subchart Config
-   */
-  subchart: computed(
-    'showLegend',
-    'showSubchart',
-    'showGraphLegend',
-    function() {
-      const showSubchart = this.get('showGraphLegend') || this.get('showSubchart');
-      return {
-        show: showSubchart,
-        onbrush: this.get('onbrush').bind(this)
-      };
-    }
-  ),
-
-  /**
-   * Callback that handles the anomaly brush event
-   */
-  onbrush: function(dates) {
-    const [ start, end ] = dates;
-    const onSubchartBrush = this.get('onSubchartChange');
-    const [ , ...graphDates ] = this.get('chartDates');
-    const min = graphDates.get('firstObject');
-    const max = graphDates.get('lastObject');
-
-    if ((moment(start).valueOf() == min) && (moment(end).valueOf() == max)) {
-      this.setProperties({
-        _subchartStart: 0,
-        _subchartEnd: 0
-      });
-    } else {
-      this.setProperties({
-        _subchartStart: moment(start).valueOf(),
-        _subchartEnd: moment(end).valueOf()
-      });
-
-      onSubchartBrush && onSubchartBrush(dates);
-    }
-
-  },
-
-  /**
-   * Graph Height Config
-   */
-  size: computed(
-    'showLegend',
-    'height',
-    function() {
-      const height = this.get('height') || 400;
-      return {
-        height
-      };
-    }
-  ),
-
-  /**
-   * Data massages primary Metric into a Column
-   */
-  primaryMetricColumn: computed(
-    'primaryMetric',
-    'primaryMetric.isSelected',
-    function() {
-      const primaryMetric = this.get('primaryMetric');
-
-      // Return data only when it's selected
-      if (primaryMetric.isSelected) {
-        const { currentValues } = primaryMetric.subDimensionContributionMap['All'];
-        return [
-          [`${primaryMetric.metricName}-current`, ...currentValues]
-        ];
-      }
-      return [
-        [`${primaryMetric.metricName}-current`]
-      ];
-    }
-  ),
-
-  /**
-   * Data massages relatedMetrics into Columns
-   */
-  selectedMetricsColumn: computed(
-    'selectedMetrics',
-    'selectedMetrics.@each',
-    function() {
-      const columns = [];
-      const selectedMetrics = this.get('selectedMetrics') || [];
-
-      selectedMetrics.forEach((metric)  => {
-        if (!metric) { return; }
-
-        const { currentValues } = metric.subDimensionContributionMap['All'];
-        columns.push([`${metric.metricName}-current`, ...currentValues]);
-      });
-      return columns;
-    }
-  ),
-
-  /**
-   * Data massages dimensions into Columns
-   */
-  selectedDimensionsColumn: computed(
-    'selectedDimensions',
-    function() {
-      const columns = [];
-      const selectedDimensions = this.get('selectedDimensions') || [];
-
-      selectedDimensions.forEach((dimension) => {
-        const { currentValues } = dimension;
-        columns.push([`${dimension.name}-current`, ...currentValues]);
-      });
-      return columns;
-    }
-  ),
-  /**
-   * Derives x axis from the primary metric
-   */
-  chartDates: computed(
-    'primaryMetric.timeBucketsCurrent',
-    function() {
-      return ['date', ...this.get('primaryMetric.timeBucketsCurrent')];
-    }
-  ),
-
-  /**
-   * Aggregates data for chart
-   */
-  data: computed(
-    'primaryMetricColumn',
-    'selectedMetricsColumn',
-    'selectedDimensionsColumn',
-    'holidayEventsColumn',
-    'holidayEventsDatesColumn',
-    'chartDates',
-    'colors',
-    'onEventClick',
-    function() {
-      const {
-        primaryMetricColumn = [],
-        selectedMetricsColumn = [],
-        selectedDimensionsColumn = [],
-        holidayEventsColumn = [],
-        holidayEventsDatesColumn = []
-      } = this.getProperties(
-        'primaryMetricColumn',
-        'selectedMetricsColumn',
-        'selectedDimensionsColumn',
-        'holidayEventsDatesColumn',
-        'holidayEventsColumn');
-
-      const columns = [
-        ...primaryMetricColumn,
-        ...selectedMetricsColumn,
-        ...selectedDimensionsColumn
-      ];
-
-      const holidayAxis = holidayEventsColumn
-        .map(column => column[0])
-        .reduce((hash, columnName) => {
-          hash[columnName] = `${columnName}-date`;
-
-          return hash;
-        }, {});
-
-      const holidayAxes = holidayEventsColumn
-        .map(column => column[0])
-        .reduce((hash, columnName) => {
-          hash[columnName] = 'y2';
-
-          return hash;
-        }, {});
-
-      const xAxis = columns
-        .map(column => column[0])
-        .reduce((hash, columnName) => {
-          hash[columnName] = 'date';
-
-          return hash;
-        }, {});
-
-      return {
-        xs: Object.assign({}, xAxis, holidayAxis),
-        axes: Object.assign({ y2: 'y2'}, holidayAxes),
-        columns: [
-          this.get('chartDates'),
-          ...columns,
-          ...holidayEventsColumn,
-          ...holidayEventsDatesColumn
-        ],
-        type: 'line',
-        xFormat: '%Y-%m-%d %H:%M',
-        colors: this.get('colors'),
-        onclick: this.get('onEventClick')
-      };
-    }
-  ),
-
-  /**
-   * Data massages Primary Metric's region
-   * and assigns color class
-   */
-  primaryRegions: computed('primaryMetric', function() {
-    const primaryMetric = this.get('primaryMetric') || {};
-    const {
-      regions,
-      color = 'orange'
-    } = primaryMetric;
-
-    if (!regions) { return []; }
-
-    return regions.map((region) => {
-      return {
-        axis: 'x',
-        start: region.start,
-        end: region.end,
-        tick: {
-          format: '%m %d %Y'
-        },
-        class: `c3-region--${color}`
-      };
-
-    });
-  }),
-
-  /**
-   * Data massages the main anomaly region
-   */
-  anomalyRegion: computed(
-    'analysisStart',
-    'analysisEnd',
-    function() {
-      const start = this.get('analysisStart');
-      const end = this.get('analysisEnd');
-
-      if (!(start && end)) { return []; }
-
-      const region = {
-        axis: 'x',
-        start: Number(start),
-        end: Number(end),
-        tick: {
-          format: '%m %d %Y'
-        },
-        class: `c3-region--dark-orange`
-      };
-
-      return [region];
-    }
-  ),
-
-  /**
-   * Data massages Primary Metric's region
-   * and assigns color class
-   */
-  relatedRegions: computed(
-    'selectedMetrics',
-    'selectedMetrics.@each',
-    function() {
-      const selectedMetrics = this.get('selectedMetrics') || [];
-      const regions = [];
-      selectedMetrics.forEach((metric)=> {
-
-        if (!metric.regions) { return; }
-
-        const metricRegions = metric.regions.map((region) => {
-          return {
-            axis: 'x',
-            start: region.start,
-            end: region.end,
-            tick: {
-              format: '%m %d %Y'
-            },
-            class: `c3-region--${metric.color}`
-          };
-        });
-        regions.push(...metricRegions);
-      });
-
-      return regions;
-    }
-  ),
-
-  /**
-   * Config for tooltip
-   */
-  tooltip: {
-    format: {
-      title: function(d) {
-        return moment(d).format('MM/DD hh:mm a');
-      },
-      value: function(val, ratio, id) {
-        const isMetric = ['current', 'expected'].some((category) => {
-          return id.includes(category);
-        });
-
-        if (isMetric) {
-          return d3.format('.3s')(val);
-        } else {
-          // do not return values if data point is an event
-
-          // NOTE: eventWeightMapping code removed on rca v1 deprecation
-
-          return '';
-        }
-      }
-    }
-  },
-
-
-  /**
-   * Aggregates chart regions
-   */
-  regions: computed(
-    'primaryRegions',
-    'relatedRegions',
-    'anomalyRegion',
-    function() {
-      return [
-        ...this.get('primaryRegions'),
-        ...this.get('relatedRegions'),
-        ...this.get('anomalyRegion')
-      ];
-    }
-  ),
-
-  actions: {
-    /**
-     * Shows/Hides the primary metric
-     */
-    onPrimaryMetricToggle() {
-      if (!this.attrs.onPrimaryClick) {
-        this.toggleProperty('primaryMetric.isSelected');
-      } else {
-        this.attrs.onPrimaryClick(...arguments);
-      }
-    },
-
-    /**
-     * Handles graph item selection
-     */
-    onSelection() {
-      this.attrs.onSelection(...arguments);
-    },
-
-    /**
-     * Shows/Hides the graph legend
-     */
-    onToggle() {
-      this.toggleProperty('showGraphLegend');
-    },
-
-    /**
-     * Scrolls to the appropriate tab on click
-     */
-    scrollToSection() {
-      later(() => {
-        $('#root-cause-analysis').get(0).scrollIntoView();
-      });
-    }
-  }
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/anomaly-graph/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/anomaly-graph/template.hbs
deleted file mode 100644
index ee68870..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/anomaly-graph/template.hbs
+++ /dev/null
@@ -1,120 +0,0 @@
-{{#if showLegend}}
-  <section class="anomaly-graph__left-panel">
-    <div class="anomaly_graph__filters">
-      <h5 class="legend-title">Primary Metric</h5>
-      <ul class="anomaly-graph__filter-group">
-        <li class="anomaly-graph__filter-item">
-          {{input
-            type="checkbox"
-            id=(concat primaryMetricId primaryMetric.metricId)
-            change=(action "onPrimaryMetricToggle")
-            checked=primaryMetric.isSelected}}
-          <label class="anomaly-graph__filter-label anomaly-graph__filter-label--{{primaryMetric.color}}" for="{{concat primaryMetricId primaryMetric.metricId}}" title={{primaryMetric.metricName}}> {{primaryMetric.metricName}} </label>
-        </li>
-      </ul>
-
-      {{#if showEvents}}
-        <h5 class="legend-title">Related Events ({{holidayEvents.length}})
-          <a class="pull-right legend-cta" {{action (toggle "isEventsHidden" this)}}>
-            <i class="glyphicon {{if isEventsHidden "glyphicon-chevron-down" "glyphicon-chevron-up"}}"></i>
-          </a>
-        </h5>
-        <ul class="anomaly-graph__filter-group {{if isEventsHidden "anomaly-graph__filter-group--hidden"}}">
-
-          {{#each holidayEvents as |event|}}
-            <li class="anomaly-graph__filter-item">
-              {{input
-                type="checkbox"
-                change=(action "onSelection" event.urn)
-                id=(concat relatedMetricId event.urn)
-                checked=event.isSelected}}
-              <label class="anomaly-graph__filter-label anomaly-graph__filter-label--{{event.color}}" for="{{concat relatedMetricId event.urn}}" title={{event.label}}> {{event.label}} </label>
-            </li>
-          {{else}}
-            No Related Events.
-            {{#if (eq componentId "main-graph")}}
-              {{#link-to 'rca.details.events' class="thirdeye-link"}} <a {{action "scrollToSection" bubbles=true}}> (Find an event) </a>{{/link-to}}
-            {{/if}}
-          {{/each}}
-
-        </ul>
-      {{/if}}
-
-      {{#if showDimensions}}
-        <h5 class="legend-title">Dimensions ({{dimensions.length}})
-          <a class="pull-right legend-cta" {{action (toggle "isDimensionsHidden" this)}}>
-            <i class="glyphicon {{if isDimensionsHidden "glyphicon-chevron-down" "glyphicon-chevron-up"}}"></i>
-          </a>
-        </h5>
-        <ul class="anomaly-graph__filter-group {{if isDimensionsHidden "anomaly-graph__filter-group--hidden"}}">
-          {{#each dimensions as |subdimension index|}}
-            <li class="anomaly-graph__filter-item">
-              {{input
-                type="checkbox"
-                id=(concat dimensionId index)
-                change=(action "onSelection" subdimension)
-                checked=subdimension.isSelected}}
-              <label class="anomaly-graph__filter-label anomaly-graph__filter-label--{{subdimension.color}}" for="{{concat dimensionId index}}" title={{subdimension.name}}> {{subdimension.name}} </label>
-            </li>
-          {{else}}
-            No Dimensions.
-            {{#if (eq componentId "main-graph")}}
-              {{#link-to 'rca.details.dimensions' class="thirdeye-link"}} <a {{action "scrollToSection" bubbles=true}}> (Find a dimension) </a>{{/link-to}}
-            {{/if}}
-          {{/each}}
-        </ul>
-      {{/if}}
-
-      {{#if showMetrics}}
-        <h5 class="legend-title">Related Metrics ({{relatedMetrics.length}})
-          <a class="pull-right legend-cta" {{action (toggle "isMetricsHidden" this)}}>
-            <i class="glyphicon {{if isMetricsHidden "glyphicon-chevron-down" "glyphicon-chevron-up"}}"></i>
-          </a>
-        </h5>
-        <ul class="anomaly-graph__filter-group {{if isMetricsHidden "anomaly-graph__filter-group--hidden"}}">
-        {{#each relatedMetrics as |metric index|}}
-          <li class="anomaly-graph__filter-item">
-            {{input
-              type="checkbox"
-              change=(action "onSelection" metric checked)
-              id=(concat relatedMetricId index)
-              checked=metric.isSelected
-              }}
-            <label class="anomaly-graph__filter-label anomaly-graph__filter-label--{{metric.color}}" for="{{concat relatedMetricId index}}" title={{metric.metricName}}> {{metric.metricName}} </label>
-          </li>
-        {{else}}
-          No Related Metrics.
-          {{#if (eq componentId "main-graph")}}
-            {{#link-to 'rca.details.metrics' class="thirdeye-link"}} <a {{action "scrollToSection" bubbles=true}}> (Find a metric) </a>{{/link-to}}
-          {{/if}}
-        {{/each}}
-        </ul>
-      {{/if}}
-
-
-    </div>
-  </section>
-{{/if}}
-
-<section class="anomaly-graph__right-panel">
-  {{#if showTitle}}
-    <h3 class="anomaly-graph__title">{{primaryMetric.metricName}}</h3>
-  {{/if}}
-  {{#if isLoading}}
-    {{ember-spinner}}
-  {{/if}}
-  {{thirdeye-chart
-    data=data
-    axis=axis
-    legend=legend
-    regions=regions
-    size=size
-    color=color
-    zoom=zoom
-    point=point
-    id=componentId
-    subchart=subchart
-    tooltip=tooltip
-    padding=padding
-  }}
-</section>
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/anomaly-id/component.js b/thirdeye/thirdeye-frontend/app/pods/components/anomaly-id/component.js
deleted file mode 100644
index a78babd..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/anomaly-id/component.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Handles display of anomaly ID and associated metadata
- * @module components/anomaly-id
- * @exports anomaly-id
- */
-import { computed } from '@ember/object';
-import Component from '@ember/component';
-import floatToPercent from 'thirdeye-frontend/utils/float-to-percent';
-
-export default Component.extend({
-  /**
-   * Component's tag name
-   */
-  tagName: 'ul',
-
-  /**
-   * List of associated classes
-   */
-  classNames: ['anomaly-id'],
-
-  /**
-   * Calculate the difference between the start value and end value for the currently loaded anomaly.
-   * Note: data frequency is 5min, hourly, or daily
-   * @method anomalyChangeRate
-   * @return {Number} - total % change from baseline
-   */
-  anomalyChangeRate: computed('anomaly.{current,baseline}', function() {
-    const currentValue = this.get('anomaly.current') || 0;
-    const baselineValue = this.get('anomaly.baseline') || 0;
-
-    if (baselineValue !== 0) {
-      return floatToPercent((currentValue - baselineValue) / baselineValue);
-    } else {
-      return 0;
-    }
-  })
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/anomaly-id/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/anomaly-id/template.hbs
deleted file mode 100644
index b6bb853..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/anomaly-id/template.hbs
+++ /dev/null
@@ -1,15 +0,0 @@
-<div class="container">
-  <li class="anomaly-id__item anomaly-id__item--title">
-    <span class="anomaly-id__title">Anomaly ID #</span>
-    <span class="anomaly-id__id">{{anomaly.anomalyIds}}</span>
-  </li>
-  <li class="anomaly-id__item">
-    <span class="anomaly-id__subtitle">Metric:</span>
-    <span class="anomaly-id__name">{{anomaly.anomalyFunctionName}}</span>
-  </li>
-  <li class="anomaly-id__item anomaly-id__item--value">
-    <span class="anomaly-id__total">{{anomaly.current}}</span>
-    <span class="anomaly-id__percent">({{anomalyChangeRate}}%)</span>
-    <span class="anomaly-id__text">WoW</span>
-  </li>
-</div>
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/anomaly-stats-block/component.js b/thirdeye/thirdeye-frontend/app/pods/components/anomaly-stats-block/component.js
deleted file mode 100644
index a37be11..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/anomaly-stats-block/component.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Anomaly-Stats-Block Component
- * Displays a row of cards, each of which contains stats, depending on the anomalyStats that are passed to the component
- * @module components/anomaly-stats-block
- * @property {boolean} isTunePreviewActive  - [optional] flag for whether tuning preview is active
- * @property {string} displayMode           - [optional] mode of display (i.e. "explore")
- * @property {object[]} anomalyStats        - [required] array of stats object that specify what to display on each card
- *
- * @example
- * {{anomaly-stats-block
- *   isTunePreviewActive=isTunePreviewActive
- *   displayMode="explore"
- *   anomalyStats=anomalyStats}}
- *
- * @exports anomaly-stats-block
- */
-import Component from '@ember/component';
-
-export default Component.extend({
-  classNames: ['te-horizontal-cards__container']
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/anomaly-stats-block/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/anomaly-stats-block/template.hbs
deleted file mode 100644
index ea9208f..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/anomaly-stats-block/template.hbs
+++ /dev/null
@@ -1,53 +0,0 @@
-{{#each anomalyStats as |card|}}
-  <ul class="te-horizontal-cards__card">
-
-    <li class="te-horizontal-cards">
-      <div class="te-horizontal-cards__card-title">{{card.title}}</div>
-      {{#if card.tooltip}}
-        <div class="te-horizontal-cards__card-tooltip">
-          <span>
-            <i class="glyphicon glyphicon-question-sign"></i>
-            {{#tooltip-on-element}}{{card.text}}{{/tooltip-on-element}}
-          </span>
-        </div>
-      {{else}}
-        <div class="te-horizontal-cards__card-text">{{card.text}}</div>
-      {{/if}}
-    </li>
-
-    <li class="te-horizontal-cards__card-value">
-      <div class="te-horizontal-cards__val-group">
-        {{#if isTunePreviewActive}}
-          <div class="te-horizontal-cards__card-subt">Current</div>
-        {{/if}}
-        <div class="te-horizontal-cards__card-number">
-          {{card.value}}
-          {{#if card.valueUnits}}
-            <span class="te-horizontal-cards__card-units">{{card.valueUnits}}</span>
-          {{/if}}
-        </div>
-        {{#if card.showProjected}}
-          <div class="te-horizontal-cards__card-subt {{if card.hideProjected "te-horizontal-cards--hidden"}}">Estimated: <span class="te-horizontal-cards__card-subt--stronger">{{card.projected}}{{if card.projectedUnits card.projectedUnits}}</span></div>
-        {{/if}}
-      </div>
-      {{#if isTunePreviewActive}}
-        <div class="te-horizontal-cards__val-group">
-          <i class="te-horizontal-cards__val-glyph--middle glyphicon glyphicon-menu-right"></i>
-        </div>
-        <div class="te-horizontal-cards__val-group">
-          <div class="te-horizontal-cards__card-subt">New</div>
-          <div class="te-horizontal-cards__card-number">
-            {{#if card.showDirectionIcon}}
-              <i class="te-horizontal-cards__val-glyph--right glyphicon glyphicon-triangle-{{card.direction}}"></i>
-            {{/if}}
-            {{card.projected}}
-            {{#if card.projectedUnits}}
-              <span class="te-horizontal-cards__card-units">{{card.projectedUnits}}</span>
-            {{/if}}
-          </div>
-        </div>
-      {{/if}}
-    </li>
-
-  </ul>
-{{/each}}
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/dimension-heatmap/component.js b/thirdeye/thirdeye-frontend/app/pods/components/dimension-heatmap/component.js
deleted file mode 100644
index 510689c..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/dimension-heatmap/component.js
+++ /dev/null
@@ -1,199 +0,0 @@
-import $ from 'jquery';
-import { computed } from '@ember/object';
-import { alias } from '@ember/object/computed';
-import Component from '@ember/component';
-import d3 from 'd3';
-
-export default Component.extend({
-  heatMapData: {},
-  dimensions: alias('heatMapData.dimensions'),
-  metricName: alias('heatMapData.metrics.firstObject'),
-  inverseMetric:alias('heatMapData.inverseMetric'),
-  classNames: ['dimension-heatmap'],
-  heatmapMode: 'Change in Contribution',
-
-  // Copy pasted code from all Thirdeye UI
-  treeMapData: computed(
-    'dimensions',
-    'dimensions.@each',
-    'heatMapData',
-    'metricName',
-    function() {
-      const dimensions = this.get('dimensions');
-      const heatMapData = this.get('heatMapData');
-      const metricName= this.get('metricName');
-      const treeMapData = [];
-      for (var i in dimensions) {
-        var dimension = dimensions[i];
-        var dataKey = `${metricName}.${dimension}`;
-        var row = {"t": "0", "children": []};
-        if (heatMapData.data && heatMapData.data[dataKey]) {
-          const {
-            dimensionValue: dimensionValueIndex,
-            percentageChange: percentageChangeIndex,
-            currentValue: currentValueIndex,
-            baselineValue: baselineValueIndex,
-            baselineContribution: baselineContributionIndex,
-            contributionToOverallChange: contributionToOverallChangeIndex,
-            currentContribution: currentContributionIndex,
-            contributionDifference: contributionChangeIndex
-          } = heatMapData.data[dataKey].schema.columnsToIndexMapping;
-
-          for (var j in heatMapData.data[dataKey].responseData) {
-            var record = heatMapData.data[dataKey].responseData[j];
-            var item = {
-              t: record[dimensionValueIndex],
-              value: record[currentValueIndex],
-              baselineValue: record[baselineValueIndex],
-              currentContribution: record[currentContributionIndex],
-              baselineContribution: record[baselineContributionIndex],
-              contributionChange: record[contributionChangeIndex],
-              percentageChange: record[percentageChangeIndex],
-              contributionToOverallChange: record[contributionToOverallChangeIndex]
-            };
-            if (item.t) {
-              row.children.push(item);
-            }
-          }
-        }
-        treeMapData.push(row);
-      }
-      return treeMapData;
-    }
-  ),
-
-  didUpdateAttrs() {
-    this._super(...arguments);
-
-    d3.select('.dimension-heatmap').selectAll('svg').remove();
-  },
-
-  willRender() {
-    this._super(...arguments);
-
-    d3.select('.dimension-heatmap').selectAll('svg').remove();
-  },
-
-  didRender() {
-    this._super(...arguments);
-
-    // Copy pasted code from all Thirdeye UI
-    const heatmapMode = this.get('heatmapMode');
-    const inverseMetric = this.get('inverseMetric');
-
-    var getChangeFactor = function (dataRow) {
-      var factor = dataRow.percentageChange;
-      if (heatmapMode === 'Change in Contribution') {
-        factor = dataRow.contributionChange;
-      }
-      if (heatmapMode === 'Contribution to Overall Change') {
-        factor = dataRow.contributionToOverallChange;
-      }
-      return factor;
-    };
-
-    var getBackgroundColor = function (factor) {
-      var opacity = Math.abs(factor / 25);
-      if((factor > 0 && !inverseMetric) || (factor < 0 && inverseMetric)){
-        return "rgba(0,0,234," + opacity + ")";
-      } else{
-        return "rgba(234,0,0,"  + opacity + ")" ;
-      }
-    };
-
-    var getTextColor = function (factor) {
-      var opacity = Math.abs(factor / 25);
-      if(opacity < 0.5){
-        return "#000000";
-      } else{
-        return "#ffffff" ;
-      }
-    };
-
-    const dimensions = this.get('dimensions');
-    const treeMapData = this.get('treeMapData');
-
-    if (!dimensions) { return; }
-
-    for (var i = 0; i < dimensions.length; i++) {
-      var data = treeMapData[i];
-      var dimension = dimensions[i];
-      var dimensionPlaceHolderId = '#' + dimension + '-heatmap-placeholder';
-      var height = $(dimensionPlaceHolderId).height();
-      var width = $(dimensionPlaceHolderId).width();
-      var treeMap = d3.layout.treemap().size([ width, height ]).sort(function(a, b) {
-        return a.value - b.value;
-      });
-
-      var div = d3.select(dimensionPlaceHolderId).attr("class", "heatmap")
-        .append("svg:svg").attr("width", width).attr("height", height).append("svg:g").attr("transform", "translate(.5,.5)");
-
-      var nodes = treeMap.nodes(data).filter(function(d) {
-        return !d.children;
-      });
-      var cell = div.selectAll("g").data(nodes).enter().append("svg:g").attr("class", "cell").attr("transform", function(d) {
-        return "translate(" + d.x + "," + d.y + ")";
-      // }).on("click", function(d) {
-        // return zoom(node == d.parent ? root : d.parent);
-      }).on("mousemove", function(d) {
-
-        if (!d.percentageChange) { return; }
-        const tooltipWidth = 200;
-        const xPosition = d3.event.pageX - (tooltipWidth + 20);
-        const yPosition = d3.event.pageY + 5;
-        d3.select("#tooltip")
-          .style("left", xPosition + "px")
-          .style("top", yPosition + "px");
-        d3.select("#tooltip #heading")
-          .text(d.t);
-        d3.select("#tooltip #percentageChange")
-          .text(`${d.percentageChange}%`);
-        d3.select("#tooltip #currentValue")
-          .text(d.value);
-        d3.select("#tooltip #contributionChange")
-          .text(`${d.contributionChange}%`);
-        d3.select("#tooltip #currentContribution")
-          .text(d.currentContribution);
-        d3.select("#tooltip #baselineContribution")
-          .text(d.baselineContribution);
-        d3.select("#tooltip #baselineValue")
-          .text(d.baselineValue);
-        d3.select("#tooltip").classed("hidden", false);
-      }).on("mouseout", function() {
-        d3.select("#tooltip").classed("hidden", true);
-      });
-
-      cell.append("svg:rect").attr("width", function(d) {
-        return Math.max(d.dx - 1, 0);
-      }).attr("height", function(d) {
-        return Math.max(d.dy - 1, 0);
-      }).style("fill", function(d) {
-        var factor = getChangeFactor(d);
-        return getBackgroundColor(factor);
-      });
-
-      cell.append('svg:text').attr("x", function(d) {
-        return d.dx / 2;
-      }).attr("y", function(d) {
-        return d.dy / 2;
-      }).attr("dy", ".35em").attr("text-anchor", "middle").text(function(d) {
-        var factor = getChangeFactor(d);
-        var text = d.t + '(' + factor + ')';
-
-        //each character takes up 7 pixels on an average
-        var estimatedTextLength = text.length * 7;
-        if(estimatedTextLength > d.dx) {
-          return text.substring(0, d.dx/7) + "..";
-        } else {
-          return text;
-        }
-      }).style('opacity', function(d) {
-        d.w = this.getComputedTextLength();
-        return d.dx > d.w ? 1 : 0;
-      }).style('fill', function(d){
-        var factor = getChangeFactor(d);
-        return getTextColor(factor);
-      });
-    }
-  }
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/dimension-heatmap/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/dimension-heatmap/template.hbs
deleted file mode 100644
index ce3235e..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/dimension-heatmap/template.hbs
+++ /dev/null
@@ -1,16 +0,0 @@
-<div class="row">
-  <div class="col-xs-12">
-    <table class="table table-borderless dimension-heatmap__table">
-      <tbody>
-        {{#each dimensions as |dimension|}}
-        <tr>
-          <td class="col-xs-1" style="vertical-align: middle" class="label-medium-light">{{dimension}}</td>
-          <td class="col-xs-11">
-            <div id="{{dimension}}-heatmap-placeholder" style="height: 50px; width: 100%"></div>
-          </td>
-        </tr>
-        {{/each}}
-      </tbody>
-    </table>
-  </div>
-</div>
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/dimension-summary/component.js b/thirdeye/thirdeye-frontend/app/pods/components/dimension-summary/component.js
deleted file mode 100644
index 507e904..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/dimension-summary/component.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Component from '@ember/component';
-
-export default Component.extend({
-  classNames: ['dimension-summary card-container card-container--padded']
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/dimension-summary/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/dimension-summary/template.hbs
deleted file mode 100644
index ec89715..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/dimension-summary/template.hbs
+++ /dev/null
@@ -1,16 +0,0 @@
-    <div class="dimension-summary__item">
-      <label class="dimension-summary__label">Current Total</label>
-      <span class="dimension-summary__data">{{format-number data.currentTotal}}</span>
-    </div>
-    <div class="dimension-summary__item">
-      <label class="dimension-summary__label">Baseline Total</label>
-      <span class="dimension-summary__data">{{format-number data.baselineTotal}}</span>
-    </div>
-    <div class="dimension-summary__item">
-      <label class="dimension-summary__label">Change Value</label>
-      <span class="dimension-summary__data dimension-summary__data--{{color-delta data.deltaChange}}">{{format-number data.deltaChange}}</span>
-    </div>
-    <div class="dimension-summary__item">
-      <label class="dimension-summary__label">% Change</label>
-      <span class="dimension-summary__data dimension-summary__data--{{color-delta data.deltaPercentage}}">{{data.deltaPercentage}} %</span>
-    </div>
\ No newline at end of file
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/events-header/component.js b/thirdeye/thirdeye-frontend/app/pods/components/events-header/component.js
deleted file mode 100644
index 3fa7afa..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/events-header/component.js
+++ /dev/null
@@ -1,86 +0,0 @@
-import { alias } from '@ember/object/computed';
-import { computed } from '@ember/object';
-import Component from '@ember/component';
-
-export default Component.extend({
-  events: [],
-  onTabChange: null,
-
-  // default active tab
-  activeTab: 'all',
-
-
-  /**
-   * Holiday Events
-   */
-  holidays: computed(
-    'events.@each',
-    function() {
-      return this.get('events')
-        .filter(event => event.eventType === 'holiday');
-    }
-  ),
-
-  /**
-   * GCN events
-   */
-  gcn: computed(
-    'events.@each',
-    function() {
-      return this.get('events')
-        .filter(event => event.eventType === 'gcn');
-    }
-  ),
-
-  /**
-   * anomaly events
-   */
-  anomaly: computed(
-    'events.@each',
-    function() {
-      return this.get('events')
-        .filter(event => event.eventType === 'anomaly');
-    }
-  ),
-
-
-  /**
-   * Informed events
-   */
-  informed: computed(
-    'events.@each',
-    function() {
-      return this.get('events')
-        .filter(event => event.eventType === 'informed');
-    }
-  ),
-
-
-  /**
-   * Lix events
-   */
-  lix: computed(
-    'events.@each',
-    function() {
-      return this.get('events')
-        .filter(event => event.eventType === 'lix');
-    }
-  ),
-
-  /**
-   * Count of events
-   */
-  allCount: alias('events.length'),
-  holidayCount: alias('holidays.length'),
-  gcnCount: alias('gcn.length'),
-  informedCount: alias('informed.length'),
-  lixCount: alias('lix.length'),
-  anomalyCount: alias('anomaly.length'),
-
-  actions: {
-    // Handles tab change on click
-    onTabClick(tab) {
-      this.attrs.onTabChange(tab);
-    }
-  }
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/events-header/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/events-header/template.hbs
deleted file mode 100644
index 9f77c9e..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/events-header/template.hbs
+++ /dev/null
@@ -1,26 +0,0 @@
-<div class="events-summary">
-  <div class="events-summary__item {{if (eq activeTab 'all') 'events-summary__item--active'}}" {{action "onTabClick" "all"}}>
-    <span class="events-summary__number">{{allCount}}</span>
-    <span>All</span>
-  </div>
-  <div class="events-summary__item events-summary__item--green {{if (eq activeTab 'holiday') 'events-summary__item--active'}}" {{action "onTabClick" "holiday"}}>
-    <span class="events-summary__number">{{holidayCount}}</span>
-    <span>Holiday</span>
-  </div>
-  <div class="events-summary__item events-summary__item--teal {{if (eq activeTab 'anomaly') 'events-summary__item--active'}}" {{action "onTabClick" "anomaly"}}>
-    <span class="events-summary__number">{{anomalyCount}}</span>
-    <span>Past Anomaly</span>
-  </div>
-  <div class="events-summary__item events-summary__item--orange {{if (eq activeTab 'gcn') 'events-summary__item--active'}}" {{action "onTabClick" "gcn"}}>
-    <span class="events-summary__number">{{gcnCount}}</span>
-    <span>GCN</span>
-  </div>
-  <div class="events-summary__item events-summary__item--purple {{if (eq activeTab 'lix') 'events-summary__item--active'}}" {{action "onTabClick" "lix"}}>
-    <span class="events-summary__number">{{lixCount}}</span>
-    <span>Lix</span>
-  </div>
-  <div class="events-summary__item events-summary__item--red {{if (eq activeTab 'informed') 'events-summary__item--active'}}" {{action "onTabClick" "informed"}}>
-    <span class="events-summary__number">{{informedCount}}</span>
-    <span>Deployment</span>
-  </div>
-</div>
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/events-table/component.js b/thirdeye/thirdeye-frontend/app/pods/components/events-table/component.js
deleted file mode 100644
index 5813c34..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/events-table/component.js
+++ /dev/null
@@ -1,134 +0,0 @@
-import { later } from '@ember/runloop';
-import { computed } from '@ember/object';
-import Component from '@ember/component';
-
-export default Component.extend({
-  events: [],
-  selectedTab: 'all',
-
-  start: null,
-  end: null,
-
-  /**
-   * Returns event based on the selected tab
-   */
-  filteredEvents: computed(
-    'eventsInRange.@each.type',
-    'selectedTab',
-    function() {
-      const events = this.get('eventsInRange');
-      const selectedTab = this.get('selectedTab');
-
-      if (selectedTab === 'all') { return events; }
-      return events
-        .filter(event => (event.eventType === selectedTab))
-        .sortBy('score')
-        .reverse();
-    }
-  ),
-
-  /**
-   * Returns events in a range
-   */
-  eventsInRange: computed(
-    'events',
-    'start',
-    'end',
-    function() {
-      const events = this.get('events');
-      const start = this.get('start');
-      const end = this.get('end');
-
-      if (!(start && end)) { return events; }
-
-      return events.filter((event) => {
-        const {
-          displayStart,
-          displayEnd } = event;
-
-        return (displayStart <= end) && (displayEnd >= start);
-      });
-    }
-  ),
-
-  // Require to display a loader for long rendering
-  didUpdateAttrs() {
-    later(() => {
-      this._super(...arguments);
-    });
-  },
-
-  init() {
-    this._super(...arguments);
-
-    /**
-     * Columns required by ember-models-table
-     */
-    const columns = [
-      {
-        template: 'custom/checkbox',
-        useFilter: false,
-        mayBeHidden: false,
-        className: 'events-table__column--checkbox'
-      },
-      {
-        propertyName: 'displayLabel',
-        template: 'custom/eventLabel',
-        title: 'Event Name',
-        className: 'events-table__column'
-      },
-      {
-        propertyName: 'eventType',
-        title: 'Type',
-        filterWithSelect: true,
-        sortFilterOptions: true,
-        className: 'events-table__column--compact'
-      },
-      {
-        propertyName: 'humanRelStart',
-        title: 'Start',
-        className: 'events-table__column--compact',
-        sortedBy: 'relStart',
-        disableFiltering: true
-      },
-      {
-        propertyName: 'humanDuration',
-        title: 'Duration',
-        className: 'events-table__column--compact',
-        sortedBy: 'duration',
-        disableFiltering: true
-      }
-    // {
-    //   propertyName: 'score',
-    //   title: 'Score',
-    //   disableFiltering: true,
-    //   className: 'events-table__column--compact',
-    //   sortDirection: 'desc'
-    // }
-    ];
-    this.set('columns', columns);
-  },
-
-  actions: {
-    /**
-     * Handles tab selection
-     * @param {String} tab String of the new selected tab
-     */
-    onTabChange(tab) {
-      const currentTab = this.get('selectedTab');
-
-      if (currentTab !== tab) {
-        this.set('selectedTab', tab);
-      }
-    },
-
-    /**
-     * Handles event selectiion
-     * @param {Object} event The new event Object
-     */
-    onSelection(event) {
-      this.attrs.onSelection(event.urn);
-    }
-  }
-});
-
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/events-table/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/events-table/template.hbs
deleted file mode 100644
index ed52290..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/events-table/template.hbs
+++ /dev/null
@@ -1,16 +0,0 @@
-{{events-header
-  events=eventsInRange
-  onTabChange=(action "onTabChange")
-  activeTab=selectedTab
-}}
-
-{{models-table
-  data=filteredEvents
-  columns=columns
-  showColumnsDropdown=false
-  showGlobalFilter=false
-  filteringIgnoreCase=true
-  multipleExpand=true
-  expandedRowTemplate='custom/expanded-row'
-  onSelection='onSelection'
-}}
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/modals/manage-groups-modal/component.js b/thirdeye/thirdeye-frontend/app/pods/components/modals/manage-groups-modal/component.js
deleted file mode 100644
index 6a3e196..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/modals/manage-groups-modal/component.js
+++ /dev/null
@@ -1,716 +0,0 @@
-/**
- * Component for selecting and managing subscription groups in a modal
- *
- * Supports
- * - search groups via application and name,
- * - search anomaly functions from db
- * - group creation, copying and editing
- * - transactional cancel or save
- *
- * @module components/modals/manage-groups-modal
- * @property {Function} onSubmit          - closure action saving group changes
- * @property {Function} onCancel          - closure action cancelling the modal
- * @property {int} preselectedGroupId     - preselected group id (optional)
- * @property {int} preselectedFunctionId  - preselected group id (optional)
- * @example
- {{modals/manage-groups-modal
-   showManageGroupsModal
- }}
- * @exports manage-groups-modal
- * @author apucher
- */
-
-import Component from '@ember/component';
-import { computed, get, set, getProperties, setProperties } from '@ember/object';
-import { checkStatus } from 'thirdeye-frontend/utils/utils';
-import fetch from 'fetch';
-import _ from 'lodash';
-import RSVP from 'rsvp';
-
-export default Component.extend({
-
-  /**
-   * Custom classes to be applied
-   */
-  classes: Object.freeze({
-    theadCell: "te-modal__table-header"
-  }),
-
-  /**
-   * display flag for modal
-   * @type {boolean}
-   */
-  showManageGroupsModal: false,
-
-  /**
-   * id of preselected group
-   * @type {int}
-   */
-  preselectedGroupId: null,
-
-  /**
-   * id of preselected function
-   * @type {int}
-   */
-  preselectedFunctionId: null,
-
-  /**
-   * Action for save/confirm. Passes selected group as argument
-   * @type {Function}
-   */
-  onSave: null,
-
-  /**
-   * Action for cancellation.
-   * @type {Function}
-   */
-  onExit: null,
-
-  /**
-   * Cache for current group
-   * @type {object}
-   */
-  changeCacheCurrent: null,
-
-  /**
-   * Cache for all changed groups
-   * @type {Set}
-   */
-  changeCache: null,
-
-  /**
-   * Cache for existing group names
-   * @type {Set}
-   */
-  groupNameCache: computed('groupOptionsRaw', function () {
-    const groupOptionsRaw = get(this, 'groupOptionsRaw');
-    return new Set(groupOptionsRaw.map(opt => opt.name));
-  }),
-
-  /**
-   * Handle init of properties
-   */
-  didReceiveAttrs() {
-    this._super(...arguments);
-
-    // TODO use ember data API for applications
-    fetch('/thirdeye/entity/APPLICATION')
-      .then(checkStatus)
-      .then(res => this._makeApplicationOptions(res))
-      .then(options => set(this, 'applicationOptions', options));
-
-    // TODO use ember data API for alert configs
-    // TODO support incremental backend search
-    fetch('/thirdeye/entity/ALERT_CONFIG')
-      .then(checkStatus)
-      .then(res => this._makeGroupOptions(res))
-      .then(options => {
-        this._handlePreselection(options, get(this, 'preselectedGroupId'));
-        return options;
-      })
-      .then(options => set(this, 'groupOptionsRaw', options));
-
-    // TODO use ember data API for anomaly functions
-    // TODO support incremental backend search
-    fetch('/thirdeye/entity/ANOMALY_FUNCTION')
-      .then(checkStatus)
-      .then(res => this._makeFunctionOptions(res))
-      .then(options => set(this, 'functionOptions', options));
-
-    // TODO optimize reverse lookup of options via dict if necessary
-
-    set(this, 'changeCache', new Set());
-  },
-
-  /**
-   * Non-editable flag for components dependent on application selection
-   * @type {boolean}
-   */
-  cannotSelect: computed('application', function () {
-    return _.isEmpty(get(this, 'application'));
-  }),
-
-  /**
-   * Non-editable flag for components dependent on group selection
-   * @type {boolean}
-   */
-  cannotEdit: computed('group', function () {
-    return _.isEmpty(get(this, 'group'));
-  }),
-
-  /**
-   * Preselected function name, resolved via functionOptions
-   * @type {string}
-   */
-  functionName: computed('functionOptions', 'preselectedFunctionId', function () {
-    const { functionOptions, preselectedFunctionId } =
-      getProperties(this, 'functionOptions', 'preselectedFunctionId');
-
-    if (!_.isNumber(preselectedFunctionId)) { return; }
-
-    const opt = functionOptions.find(opt => opt.id === preselectedFunctionId);
-
-    if (_.isEmpty(opt)) { return; }
-
-    return opt.name;
-  }),
-
-  /**
-   * Flag for preselected function
-   * @type {boolean}
-   */
-  hasFunction: computed('functionName', function () {
-    return _.isNumber(get(this, 'preselectedFunctionId'));
-  }),
-
-  /**
-   * Flag for add function shortcut
-   * @type {boolean}
-   */
-  hasFunctionShortcut: computed('preselectedFunctionId', 'group', function () {
-    const { preselectedFunctionId, group } =
-      getProperties(this, 'preselectedFunctionId', 'group');
-
-    if (_.isEmpty(group) || !_.isNumber(preselectedFunctionId)) { return false; }
-
-    if (group.emailConfig.functionIds.includes(preselectedFunctionId)) {
-      return false;
-    }
-
-    return true;
-  }),
-
-  /**
-   * Footer text tracking change cache
-   * @type {string}
-   */
-  footerText: computed('changeCache', function () {
-    const changeCache = get(this, 'changeCache');
-    if (_.isEmpty(changeCache)) {
-      return '';
-    }
-    if (changeCache.size === 1) {
-      return '(1 group will be modified)';
-    }
-    return `(${changeCache.size} groups will be modified)`;
-  }),
-
-  /**
-   * Error message container for group name
-   * @type {string}
-   */
-  groupNameMessage: null,
-
-  /**
-   * Error message container for to-recipients
-   * @type {string}
-   */
-  toAddrWarning: null,
-
-  /**
-   * Temp storage for recipients(to) from text input
-   * @type {String}
-   */
-  toAddresses: null,
-
-  /**
-   * Temp storage for recipients(cc) from text input
-   * @type {String}
-   */
-  ccAddresses: null,
-
-  /**
-   * Temp storage for recipients(bcc) from text input
-   * @type {String}
-   */
-  BccAddresses: null,
-
-  /**
-   * Group options available in database
-   * @type {Array}
-   */
-  groupOptionsRaw: [],
-
-  /**
-   * Group options available for selection (and search)
-   * @type {Array}
-   */
-  groupOptions: computed('application', 'groupOptionsRaw', function () {
-    const { application, groupOptionsRaw } = getProperties(this, 'application', 'groupOptionsRaw');
-    const options = groupOptionsRaw.filter(opt => opt.application === null || opt.application === application || opt.id === null);
-    options[0].application = application; // set application for "new" template
-    return options;
-  }),
-
-  /**
-   * Shortcut header for groups an alert is already part of
-   * @type {Array}
-   */
-  groupShortcuts: computed('preselectedFunctionId', 'groupOptionsRaw', function () {
-    const { preselectedFunctionId, groupOptionsRaw } =
-      getProperties(this, 'preselectedFunctionId', 'groupOptionsRaw');
-
-    return groupOptionsRaw.filter((group) => {
-      if (group.emailConfig && group.emailConfig.functionIds) {
-        return group.emailConfig.functionIds.includes(preselectedFunctionId);
-      }
-    });
-  }),
-
-  /**
-   * Currently selected group
-   * @type {object}
-   */
-  group: null,
-
-  /**
-   * Currently selected application
-   * @type {object}
-   */
-  application: null,
-
-  /**
-   * Application options available for selection (and search)
-   * @type {Array}
-   */
-  applicationOptions: [],
-
-  /**
-   * Currently selected application option
-   * @type {object}
-   */
-  applicationOptionSelected: computed('application', function () {
-    const { applicationOptions, application } = getProperties(this, 'applicationOptions', 'application');
-    if (_.isEmpty(application)) { return; }
-    return applicationOptions.find(opt => opt.application === application);
-  }).readOnly(),
-
-  /**
-   * Cron options available for selection
-   * @type {Array}
-   */
-  cronOptionsRaw: [
-    { name: 'immediately', cron: '0 0/5 * * * ? *' },
-    { name: 'every 15 min', cron: '0 0/15 * * * ? *' },
-    { name: 'every hour', cron: '0 0 * * * ? *' },
-    { name: 'every 3 hours', cron: '0 0 0/3 * * ? *' },
-    { name: 'every 6 hours', cron: '0 0 0/6 * * ? *' },
-    { name: 'daily', cron: '0 0 0 * * ? *' },
-    { name: 'weekly', cron: '0 0 0 * * SUN *' }
-  ],
-
-  /**
-   * Cron options including an optional custom, pre-existing option
-   * @type {Array}
-   */
-  cronOptions: computed('group', 'cronOptionsRaw', function () {
-    const { group, cronOptionsRaw } = getProperties(this, 'group', 'cronOptionsRaw');
-
-    if (_.isEmpty(group)) { return cronOptionsRaw; }
-
-    if (_.isEmpty(cronOptionsRaw.find(opt => opt.cron === group.cronExpression))) {
-      return [...cronOptionsRaw].concat([{ name: `custom setting ("${group.cronExpression}")`, cron: group.cronExpression  }]);
-    }
-
-    return cronOptionsRaw;
-  }),
-
-  /**
-   * Currently selected cron option
-   * @type {object}
-   */
-  cronOptionSelected: computed('group.cronExpression', function () {
-    const { cronOptions, group } = getProperties(this, 'cronOptions', 'group');
-    if (_.isEmpty(group)) { return; }
-    return cronOptions.find(opt => opt.cron === group.cronExpression);
-  }).readOnly(),
-
-  /**
-   * SubjectType options available for selection
-   * @type {Array}
-   */
-  subjectTypeOptions: [
-    { name: 'group name only', subjectType: 'ALERT' },
-    { name: 'with metric name', subjectType: 'METRICS' },
-    { name: 'with dataset name', subjectType: 'DATASETS' }
-  ],
-
-  /**
-   * Currently selected subjectType option
-   * @type {object}
-   */
-  subjectTypeOptionSelected: computed('group.subjectType', function () {
-    const { subjectTypeOptions, group } = getProperties(this, 'subjectTypeOptions', 'group');
-    if (_.isEmpty(group)) { return; }
-    return subjectTypeOptions.find(opt => opt.subjectType === group.subjectType);
-  }).readOnly(),
-
-  /**
-   * Function options available for selection (and search)
-   * @type {Array}
-   */
-  functionOptions: [],
-
-  /**
-   * Cached functionIds parsed from currently selected group
-   * @type {Set}
-   */
-  functionOptionsSelectedIds: computed('group.emailConfig.functionIds', function () {
-    const functionIds = get(this, 'group.emailConfig.functionIds');
-    if (_.isEmpty(functionIds)) { return []; }
-    return new Set(functionIds);
-  }),
-
-  /**
-   * Currently selected function ids
-   * @type {Array}
-   */
-  functionOptionsSelected: computed('functionOptionsSelectedIds', function () {
-    const { functionOptions, functionOptionsSelectedIds } = getProperties(this, 'functionOptions', 'functionOptionsSelectedIds');
-    if (_.isEmpty(functionOptionsSelectedIds)) { return []; }
-    return functionOptions.filter(opt => functionOptionsSelectedIds.has(opt.id));
-  }).readOnly(),
-
-  /**
-   * Parses application entities into power-select options
-   *
-   * @param res {Array} APPLICATION entities
-   * @returns {Array} application options
-   * @private
-   */
-  _makeApplicationOptions (res) {
-    return res.map(r => Object.assign({}, { name: r.application, application: r.application })).sortBy('name');
-  },
-
-  /**
-   * Parses alert group entities into power-select options
-   *
-   * @param res {Array} ALERT_CONFIG entities
-   * @returns {Array} groups
-   * @private
-   */
-  _makeGroupOptions (res) {
-    return [{
-      id: null,
-      name: '(new group)',
-      active: true,
-      application: null,
-      cronExpression: get(this, 'cronOptions')[0].cron,
-      subjectType: get(this, 'subjectTypeOptions')[0].subjectType,
-      emailConfig: {
-        functionIds: []
-      }
-    }].concat(res.sortBy('name'));
-  },
-
-  /**
-   * Parses anomaly function entities into power-select options
-   *
-   * @param res {Array} ANOMALY_FUNCTION entities
-   * @returns {Array} function options
-   * @private
-   */
-  _makeFunctionOptions (res) {
-    return res.map(f => Object.assign({}, { name: f.functionName, id: f.id })).sortBy('name');
-  },
-
-  /**
-   * Selects the group with given id
-   *
-   * @param groupOptions {Array} available groups
-   * @param groupId {int} preselected group id
-   * @private
-   */
-  _handlePreselection(groupOptions, groupId) {
-    if (_.isEmpty(groupId)) { return; }
-
-    const group = groupOptions.find(opt => opt.id === groupId);
-    if (_.isEmpty(group)) { return; }
-
-    setProperties(this, { group, application: group.application });
-  },
-
-  /**
-   * Stage a newly selected group for caching if not already tracked in change cache
-   *
-   * @param group {object} group
-   * @private
-   */
-  _makeChangeCacheCurrent(group) {
-    const changeCache = get(this, 'changeCache');
-
-    if (_.isEmpty(group)) { return; }
-
-    if (changeCache.has(group)) {
-      set(this, 'changeCacheCurrent', group);
-      return;
-    }
-
-    set(this, 'changeCacheCurrent', _.cloneDeep(group));
-  },
-
-  /**
-   * Checks for changes of the selected group and adds it to the change cache if verified
-   * // TODO trigger this (debounced) on every edit?
-   *
-   * @private
-   */
-  _updateChangeCache() {
-    const { changeCacheCurrent, changeCache, group } =
-      getProperties(this, 'changeCacheCurrent', 'changeCache', 'group');
-
-    if (_.isEmpty(group)) { return; }
-
-    if (!changeCache.has(group) && !_.isEqual(changeCacheCurrent, group)) {
-      const newChangeCache = new Set([...changeCache].concat([group]));
-      set(this, 'changeCache', newChangeCache);
-    }
-  },
-
-  /**
-   * Validate the group name for validity and uniqueness and display warning if necessary.
-   *
-   * @param group {object} group
-   * @private
-   */
-  _validateGroupName(group) {
-    const { groupNameCache, changeCacheCurrent } =
-      getProperties(this, 'groupNameCache', 'changeCacheCurrent');
-
-    if (_.isEmpty(group)) { return; }
-    if (_.isEmpty(groupNameCache)) { return; }
-
-    const inUse = new Set(groupNameCache);
-    if (!_.isEmpty(changeCacheCurrent)) {
-      inUse.delete(changeCacheCurrent.name);
-    }
-
-    if (_.isEmpty(group.name) || group.name.startsWith('(') || inUse.has(group.name)) {
-      set(this, 'groupNameMessage', 'group name invalid or already in use');
-    } else {
-      set(this, 'groupNameMessage', null);
-    }
-  },
-
-  /**
-   * Check for at least one recipient
-   *
-   * @param toAddr {String} comma separated email addresses
-   * @private
-   */
-  _validateRecipient(toAddr) {
-    if (!_.isEmpty(toAddr)) {
-      var emailArray = toAddr.split(',');
-      for (var index = 0; index < emailArray.length; index++) {
-        if (this._validateEmail(emailArray[index].trim())) {
-          set(this, 'toAddrWarning', null);
-          return;
-        }
-      }
-    }
-
-    set(this, 'toAddrWarning', 'Please enter at least one valid recipient');
-  },
-
-  /**
-   * Verify if string is a valid email address
-   *
-   * @param email {String} email address
-   * @private
-   */
-  _validateEmail(email) {
-    var re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
-    return re.test(String(email).toLowerCase());
-  },
-
-  actions: {
-    /**
-     * Handles recipient updates
-     */
-    onToAddresses () {
-      const toAddresses = get(this, 'toAddresses');
-      this._validateRecipient(toAddresses);
-
-      set(this, 'group.receiverAddresses.to', toAddresses.replace(/[^!-~]+/g, '').replace(/,+/g, ',').split(','));
-    },
-    onCcAddresses () {
-      const ccAddresses = get(this, 'ccAddresses');
-      set(this, 'group.receiverAddresses.cc', ccAddresses.replace(/[^!-~]+/g, '').replace(/,+/g, ',').split(','));
-    },
-    onBccAddresses () {
-      const bccAddresses = get(this, 'bccAddresses');
-      set(this, 'group.receiverAddresses.bcc', bccAddresses.replace(/[^!-~]+/g, '').replace(/,+/g, ',').split(','));
-    },
-
-    /**
-     * Handles functionIds selection
-     * @param functionOptions {Array} function options
-     */
-    onFunctionIds (functionOptions) {
-      const prevFunctionIds = get(this, 'group.emailConfig.functionIds');
-      const fid = get(this, 'preselectedFunctionId');
-
-      const functionIds = functionOptions.map(opt => opt.id);
-      set(this, 'group.emailConfig.functionIds', functionIds);
-
-      // trigger group shortcut compute (instead of deep nested listener)
-      if (_.isNumber(fid) && (prevFunctionIds.includes(fid) || functionIds.includes(fid))) {
-        this.notifyPropertyChange('preselectedFunctionId');
-      }
-    },
-
-    /**
-     * Handles adding preselected function id to selected function ids
-     */
-    onFunctionShortcut () {
-      const { preselectedFunctionId, group } =
-        getProperties(this, 'preselectedFunctionId', 'group');
-
-      if (!_.isNumber(preselectedFunctionId)) { return; }
-      if (_.isEmpty(group)) { return; }
-
-      const functionIds = new Set(group.emailConfig.functionIds);
-      functionIds.add(preselectedFunctionId);
-
-      set(this, 'group.emailConfig.functionIds', [...functionIds]);
-
-      // trigger group shortcut compute (instead of deep nested listener)
-      this.notifyPropertyChange('preselectedFunctionId');
-    },
-
-    /**
-     * Handles the close event
-     */
-    onCancel () {
-      const onExit = get(this, 'onExit');
-
-      setProperties(this, {
-        application: null,
-        group: null,
-        toAddresses: null,
-        ccAddresses: null,
-        bccAddresses: null,
-        showManageGroupsModal: false,
-        changeCache: new Set(),
-        groupNameMessage: null,
-        toAddrWarning: null
-      });
-
-      if (onExit) { onExit(); }
-    },
-
-    /**
-     * Handles save event
-     */
-    onSubmit () {
-      this._updateChangeCache();
-
-      const { group, onSave, changeCache } = getProperties(this, 'group', 'onSave', 'changeCache');
-
-      const promises = [...changeCache].map(group => {
-        fetch('/thirdeye/entity?entityType=ALERT_CONFIG', {method: 'POST', body: JSON.stringify(group)})
-          .then(checkStatus);
-      });
-
-      // TODO use ember data API for alert configs
-      RSVP.allSettled(promises)
-        .then(res => setProperties(this, {
-          application: null,
-          group: null,
-          toAddresses: null,
-          ccAddresses: null,
-          bccAddresses: null,
-          showManageGroupsModal: false,
-          changeCache: new Set(),
-          groupNameMessage: null,
-          toAddrWarning: null
-        }))
-        .then(res => {
-          if (onSave) { onSave(group); }
-        })
-        .catch(err => set(this, 'message', err));
-    },
-
-    /**
-     * Handles group selection
-     * @param group
-     */
-    onGroup (group) {
-      this._updateChangeCache();
-      this._makeChangeCacheCurrent(group);
-
-      setProperties(this, {
-        application: group.application, // in case not set
-        group,
-        groupFunctionIds: (group.emailConfig.functionIds || []).join(', '),
-        toAddresses: (group.receiverAddresses.to || []).join(', '),
-        ccAddresses: (group.receiverAddresses.cc || []).join(', '),
-        bccAddresses: (group.receiverAddresses.bcc || []).join(', ')
-      });
-
-      this._validateGroupName(group);
-    },
-
-    /**
-     * Handles copy button
-     */
-    onCopy () {
-      const { group, groupOptions, groupOptionsRaw } = getProperties(this, 'group', 'groupOptions', 'groupOptionsRaw');
-
-      if (_.isEmpty(group) || group.id === null) { return; }
-
-      const newGroup = Object.assign(_.cloneDeep(group), {
-        id: null,
-        name: `Copy of ${group.name}`
-      });
-
-      // push options directly rather than triggering re-compute
-      groupOptionsRaw.pushObject(newGroup);
-      groupOptions.pushObject(newGroup);
-
-      setProperties(this, { group: newGroup, changeCacheCurrent: group });
-      this._validateGroupName(newGroup);
-    },
-
-    /**
-     * Handles cron selection
-     * @param cronOption {object} cron option
-     */
-    onCron (cronOption) {
-      set(this, 'group.cronExpression', cronOption.cron);
-    },
-
-    /**
-     * Handles subjectType selection
-     * @param subjectOption {object} subjectType option
-     */
-    onSubjectType (subjectOption) {
-      set(this, 'group.subjectType', subjectOption.subjectType);
-    },
-
-    /**
-     * Handles application selection
-     * @param applicationOption {object} application option
-     */
-    onApplication (applicationOption) {
-      this._updateChangeCache();
-      setProperties(this, {
-        application: applicationOption.application,
-        group: null,
-        toAddresses: null,
-        ccAddresses: null,
-        bccAddresses: null,
-        groupNameMessage: null,
-        toAddrWarning: null
-      });
-    },
-
-    /**
-     * Handle group name edit
-     */
-    onName () {
-      const group = get(this, 'group');
-      this._validateGroupName(group);
-    }
-  }
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/modals/manage-groups-modal/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/modals/manage-groups-modal/template.hbs
deleted file mode 100644
index eab485e..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/modals/manage-groups-modal/template.hbs
+++ /dev/null
@@ -1,239 +0,0 @@
-{{#te-modal
-  headerText="Manage Subscription Groups"
-  footerText=footerText
-  isShowingModal=showManageGroupsModal
-  isInvalid=isInvalid
-  cancelAction=(action "onCancel")
-  submitAction=(action "onSubmit")
-  hasFooter=true
-}}
-
-  {{#if hasFunction}}
-    <div class="row te-modal__settings">
-      <div class="col-md-2">
-        <span class="te-label te-label--bold te-label--dark">Group shortcuts</span>
-      </div>
-      <div class="col-md-10">
-        {{#each groupShortcuts as |group index| }}
-          {{#if index}}, {{/if}}
-          <a {{action "onGroup" group}}>{{group.name}}</a>
-        {{/each}}
-      </div>
-    </div>
-
-    <hr/>
-  {{/if}}
-
-  <div class="row te-modal__settings">
-    <div class="col-md-2">
-      <span class="te-label te-label--bold te-label--dark">Find Group</span>
-    </div>
-    <div class="col-md-3">
-      {{#power-select
-        class="te-modal__input"
-        triggerClass="te-modal__filter-select te-modal__filter-select--flushed"
-        selected=applicationOptionSelected
-        options=applicationOptions
-        renderInPlace=true
-        searchField="name"
-        triggerId="application-selection"
-        placeholder="Select application"
-        onchange=(action "onApplication")
-      as |option|
-      }}
-        {{option.name}}
-      {{/power-select}}
-    </div>
-
-    <div class="col-md-5">
-      {{#power-select
-        triggerClass="te-modal__filter-select te-modal__filter-select--flushed"
-        selected=group
-        options=groupOptions
-        searchField="name"
-        renderInPlace=true
-        triggerId="group-selection"
-        placeholder="Search subscription group"
-        disabled=cannotSelect
-        onchange=(action "onGroup")
-      as |group|
-      }}
-        {{group.name}}
-      {{/power-select}}
-    </div>
-    <div class="col-md-2">
-      <button id="button-new" onclick={{action "onCopy"}} disabled={{cannotEdit}}>Create copy</button>
-    </div>
-  </div>
-
-  <hr/>
-
-  <div class="row te-modal__settings">
-    <div class="col-md-2">
-      <span class="te-label te-label--bold te-label--dark">Group name</span>
-    </div>
-    <div class="col-md-10">
-      {{input
-        type="text"
-        id="name"
-        value=group.name
-        class="te-modal__input te-modal__input--fullwidth"
-        disabled=cannotEdit
-        key-up=(action "onName")
-     }}
-      {{#if groupNameMessage}}
-        ({{groupNameMessage}})
-      {{/if}}
-    </div>
-  </div>
-
-  <div class="row te-modal__settings">
-    <div class="col-md-2">
-      <span class="te-label te-label--bold te-label--dark">Alerts</span>
-    </div>
-    <div class="col-md-10">
-      {{#power-select-multiple
-        triggerClass="te-modal__filter-select te-modal__filter-select--flushed"
-        selected=functionOptionsSelected
-        options=functionOptions
-        renderInPlace=true
-        searchField="name"
-        triggerId="function-selection"
-        disabled=cannotEdit
-        onchange=(action "onFunctionIds")
-      as |option|
-      }}
-        {{option.name}}
-      {{/power-select-multiple}}
-      {{#if hasFunctionShortcut}}
-        (add <a {{action "onFunctionShortcut"}}>{{functionName}}</a> to alerts)
-      {{/if}}
-    </div>
-  </div>
-
-  <div class="row te-modal__settings">
-    <div class="col-md-2">
-      <span class="te-label te-label--bold te-label--dark">Schedule</span>
-    </div>
-    <div class="col-md-8">
-      {{#power-select
-        triggerClass="te-modal__filter-select te-modal__filter-select--flushed"
-        selected=cronOptionSelected
-        options=cronOptions
-        renderInPlace=true
-        searchEnabled=false
-        triggerId="cron-selection"
-        disabled=cannotEdit
-        onchange=(action "onCron")
-      as |option|
-      }}
-        {{option.name}}
-      {{/power-select}}
-    </div>
-    <div class="col-md-2">
-      <input
-        type="checkbox"
-        id="active"
-        checked={{group.active}}
-          disabled={{cannotEdit}}
-      />
-      <label for="active">Enabled</label>
-    </div>
-  </div>
-
-  <div class="row te-modal__settings">
-    <div class="col-md-2">
-      <span class="te-label te-label--bold te-label--dark">Email subject</span>
-    </div>
-    <div class="col-md-10">
-      {{#power-select
-        triggerClass="te-modal__filter-select te-modal__filter-select--flushed"
-        selected=subjectTypeOptionSelected
-        options=subjectTypeOptions
-        renderInPlace=true
-        searchEnabled=false
-        triggerId="subject-type-selection"
-        disabled=cannotEdit
-        onchange=(action "onSubjectType")
-      as |option|
-      }}
-        {{option.name}}
-      {{/power-select}}
-    </div>
-  </div>
-
-  <div class="row te-modal__settings">
-    <div class="col-md-2">
-      <span class="te-label te-label--bold te-label--dark">Sender</span>
-    </div>
-    <div class="col-md-10">
-      {{input
-        type="text"
-        id="from-address"
-        value=group.fromAddress
-        class="te-modal__input te-modal__input--fullwidth"
-        disabled=cannotEdit
-      }}
-    </div>
-  </div>
-
-  <div class="row te-modal__settings">
-    <div class="col-md-2">
-      <span class="te-label te-label--bold te-label--dark">To</span>
-    </div>
-    <div class="col-md-10">
-      {{textarea-autosize
-        cols=80
-        rows=3
-        placeholder="Enter recipients (comma separated). E.g., user1@linkedin.com, user2@linkedin.com"
-        type="text"
-        id="to-addresses"
-        value=toAddresses
-        class="te-modal__input te-modal__input--fullwidth"
-        disabled=cannotEdit
-        key-up=(action "onToAddresses")
-      }}
-      {{#if toAddrWarning}}
-        ({{toAddrWarning}})
-      {{/if}}
-    </div>
-  </div>
-
-  <div class="row te-modal__settings">
-    <div class="col-md-2">
-      <span class="te-label te-label--bold te-label--dark">Cc</span>
-    </div>
-    <div class="col-md-10">
-      {{textarea-autosize
-        cols=80
-        rows=1
-        placeholder="Enter recipients (comma separated). E.g., user1@linkedin.com, user2@linkedin.com"
-        type="text"
-        id="cc-addresses"
-        value=ccAddresses
-        class="te-modal__input te-modal__input--fullwidth"
-        disabled=cannotEdit
-        change=(action "onCcAddresses")
-      }}
-    </div>
-  </div>
-
-  <div class="row te-modal__settings">
-    <div class="col-md-2">
-      <span class="te-label te-label--bold te-label--dark">Bcc</span>
-    </div>
-    <div class="col-md-10">
-      {{textarea-autosize
-        cols=80
-        rows=1
-        placeholder="Enter recipients (comma separated). E.g., user1@linkedin.com, user2@linkedin.com"
-        type="text"
-        id="bcc-addresses"
-        value=bccAddresses
-        class="te-modal__input te-modal__input--fullwidth"
-        disabled=cannotEdit
-        change=(action "onBccAddresses")
-      }}
-    </div>
-  </div>
-{{/te-modal}}
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/performance-tooltip/component.js b/thirdeye/thirdeye-frontend/app/pods/components/performance-tooltip/component.js
deleted file mode 100644
index 692740d..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/performance-tooltip/component.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Component from '@ember/component';
-
-export default Component.extend({
-  classNames: ['te-performance-tooltip']
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/performance-tooltip/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/performance-tooltip/template.hbs
deleted file mode 100644
index dbd65d3..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/performance-tooltip/template.hbs
+++ /dev/null
@@ -1,17 +0,0 @@
-{{#if (not-eq data.tot 0)}}
-  <a class="te-anomaly-table__link" href="#">
-    {{if viewTotals data.tot data.avg}}
-      {{#tooltip-on-element}}
-        {{category}} for <span class="te-performance-tooltip__title">{{data.name}}</span><br>
-        <ul class="te-performance-tooltip__list">
-          <li class="te-performance-tooltip__item"><span class="te-performance-tooltip__category">Total: </span>{{data.tot}}</li>
-          <li class="te-performance-tooltip__item"><span class="te-performance-tooltip__category">Avg: </span>{{data.avg}}</li>
-          <li class="te-performance-tooltip__item"><span class="te-performance-tooltip__category">Min: </span>{{data.min}}</li>
-          <li class="te-performance-tooltip__item"><span class="te-performance-tooltip__category">Max: </span>{{data.max}}</li>
-          <li class="te-performance-tooltip__item"><span class="te-performance-tooltip__category">Standard deviation: </span>{{data.std}}</li>
-        </ul>
-      {{/tooltip-on-element}}
-  </a>
-{{else}}
-  {{if viewTotals data.tot data.avg}}
-{{/if}}
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/self-serve-alert-yaml-details/component.js b/thirdeye/thirdeye-frontend/app/pods/components/self-serve-alert-yaml-details/component.js
index 95e8a09..8b5aebb 100644
--- a/thirdeye/thirdeye-frontend/app/pods/components/self-serve-alert-yaml-details/component.js
+++ b/thirdeye/thirdeye-frontend/app/pods/components/self-serve-alert-yaml-details/component.js
@@ -2,7 +2,7 @@
  * This component displays an alert summary section for users to see alert properties at a glance.
  * Initially used for consistency in both alert index page and single alert details page.
  * We use slightly different sub class names for positioning based on use case.
- * @module components/self-serve-alert-details
+ * @module components/self-serve-alert-yaml-details
  * @property {Object} alertData    - alert properties
  * @property {Boolean} isLoadError - was there an error loading the data
  * @property {String} displayMode  - is the use case part of a list or standalone? 'list' || 'single'
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/self-serve-graph/component.js b/thirdeye/thirdeye-frontend/app/pods/components/self-serve-graph/component.js
deleted file mode 100644
index da87a9b..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/self-serve-graph/component.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * Wrapper component for the anomaly-graph component as used in the self-serve flow.
- * It handles presentation of the graph under various loading and error conditions.
- * @module components/self-serve-graph
- * @property {Boolean} isMetricDataLoading    - is primary metric data still loading
- * @property {Boolean} isMetricDataInvalid    - has the metric data been found to be not graphable
- * @property {Boolean} isDimensionFetchDone   - are we done preparing dimension data
- * @property {Boolean} isSecondaryDataLoading - loads spinner if peripheral data load is made
- * @property {Boolean} removeGraphMargin      - render with or without extra margins
- * @property {Object} metricData              - primary metric data
- * @property {Array} topDimensions            - top x dimensions to load aside from primary metric
- * @property {String} componentId             - id for the graph wrapper element
- * @example
-    {{self-serve-graph
-      isMetricDataLoading=false
-      isMetricDataInvalid=false
-      isDimensionFetchDone=false
-      metricData=metricData
-      topDimensions=topDimensions
-      componentId='create-alert'
-    }}
- * @exports self-serve-graph
- * @author smcclung
- */
-
-import Component from '@ember/component';
-import { computed, set } from '@ember/object';
-
-export default Component.extend({
-  classNames: ['col-xs-12', 'te-graph-container'],
-  classNameBindings: ['removeGraphMargin:te-graph-container--marginless'],
-  isMetricDataLoading: true,
-  isMetricDataInvalid: false,
-  isDimensionFetchDone: false,
-  isSecondaryDataLoading: false,
-  metricData: {},
-  topDimensions: [],
-  componentId: '',
-
-  /**
-   * Standard legend settings for graph
-   */
-  legendText: {
-    dotted: {
-      text: 'WoW'
-    },
-    solid: {
-      text: 'Observed'
-    }
-  },
-
-  /**
-   * All selected dimensions to be loaded into graph
-   * @returns {Array}
-   */
-  selectedDimensions: computed(
-    'topDimensions',
-    'topDimensions.@each.isSelected',
-    function() {
-      const topDimensions = this.get('topDimensions');
-      return topDimensions ? this.get('topDimensions').filterBy('isSelected') : [];
-    }
-  ),
-
-  /**
-   * Determines pending state of graph
-   * @returns {Boolean}
-   */
-  isMetricDataPending: computed(
-    'isMetricSelected',
-    'isMetricDataLoading',
-    'isMetricDataInvalid',
-    function() {
-      const {
-        isMetricSelected,
-        isMetricDataLoading
-      } = this.getProperties('isMetricSelected', 'isMetricDataLoading');
-      return !this.get('isMetricSelected') || this.get('isMetricDataLoading') || this.get('isMetricDataInvalid');
-    }
-  ),
-
-  /**
-   * Determines whether peripheral data for the graph is loading
-   * @returns {Boolean}
-   */
-  isAnythingLoading: computed.or('isMetricDataLoading', 'isSecondaryDataLoading'),
-
-  /**
-   * Sets the message text over the graph placeholder before data is loaded
-   * @method graphMessageText
-   * @return {String} the appropriate graph placeholder text
-   */
-  graphMessageText: computed(
-    'isMetricDataInvalid',
-    function() {
-      const defaultMsg = 'Graph will appear here when data is loaded...';
-      const invalidMsg = 'Sorry, I\'m not able to load data for this metric';
-      return this.get('isMetricDataInvalid') ? invalidMsg : defaultMsg;
-    }
-  ),
-
-  actions: {
-    /**
-     * Enable reaction to dimension toggling in graph legend component
-     * @method onSelection
-     * @return {undefined}
-     */
-    onSelection(selectedDimension) {
-      const { isSelected } = selectedDimension;
-      set(selectedDimension, 'isSelected', !isSelected);
-    }
-  }
-
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/self-serve-graph/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/self-serve-graph/template.hbs
deleted file mode 100644
index 05146d6..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/self-serve-graph/template.hbs
+++ /dev/null
@@ -1,38 +0,0 @@
-<div class="te-graph-alert {{if isMetricDataPending 'te-graph-alert--pending'}}">
-  {{#if (and (or isFetchingDimensions isDimensionFetchDone) isTopDimensionsAllowed)}}
-    {{#if isDimensionError}}
-      <div class="te-form__super-label">... error loading subDimensions for <span class="stronger">{{selectedDimension}}</span></div>
-    {{else}}
-      <div class="te-form__super-label">...{{if isDimensionFetchDone 'Displaying' 'Loading'}} top {{topDimensions.length}} contributing subDimensions for <span class="stronger">{{selectedDimension}}</span></div>
-    {{/if}}
-  {{/if}}
-  {{#if isAnythingLoading}} <div class="spinner-wrapper-self-serve">{{ember-spinner}}</div> {{/if}}
-  {{#if (or isMetricDataPending isMetricDataInvalid)}}
-    <div class="te-graph-alert__content">
-      <div class="glyphicon glyphicon-{{if isMetricDataInvalid 'alert' 'equalizer'}} te-graph-alert__icon{{if isMetricDataInvalid '--warning'}}"></div>
-      <p class="te-graph-alert__pre-text">{{graphMessageText}}</p>
-    </div>
-  {{else}}
-    {{#if (not isMetricDataInvalid)}}
-      {{anomaly-graph
-        primaryMetric=metricData
-        selectedDimensions=selectedDimensions
-        dimensions=topDimensions
-        showDimensions=false
-        isLoading=loading
-        showSubchart=true
-        showLegend=false
-        enableZoom=true
-        legendText=legendText
-        componentId=componentId
-        showGraphLegend=false
-        onSelection=(action "onSelection")
-      }}
-    {{/if}}
-  {{/if}}
-</div>
-{{#if (or isMetricDataInvalid isMetricSelected)}}
-  <div class="te-form__note">
-    NOTE: If you find the metric shown above is inconsistent, please email <a class="thirdeye-link-secondary" target="_blank" href="{{graphMailtoLink}}">ask_thirdeye</a>.
-  </div>
-{{/if}}
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/thirdeye-chart/component.js b/thirdeye/thirdeye-frontend/app/pods/components/thirdeye-chart/component.js
deleted file mode 100644
index de8e728..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/thirdeye-chart/component.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import chartComponent from 'ember-c3/components/c3-chart';
-
-/**
- * Extended the c3-chart component so that we will have access to
- * the chart and its internal API
- */
-export default chartComponent.extend({
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/thirdeye-chart/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/thirdeye-chart/template.hbs
deleted file mode 100644
index 889d9ee..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/thirdeye-chart/template.hbs
+++ /dev/null
@@ -1 +0,0 @@
-{{yield}}
diff --git a/thirdeye/thirdeye-frontend/app/pods/custom/anomalies-table/rule/template.hbs b/thirdeye/thirdeye-frontend/app/pods/custom/anomalies-table/rule/template.hbs
index 82a260b..4329fa8 100644
--- a/thirdeye/thirdeye-frontend/app/pods/custom/anomalies-table/rule/template.hbs
+++ b/thirdeye/thirdeye-frontend/app/pods/custom/anomalies-table/rule/template.hbs
@@ -9,7 +9,7 @@
 }}
   {{#if isDeleteSuccess}}
     {{#bs-alert type="success" class="te-form__banner te-form__banner--success"}}
-      <strong>Success:</strong> Anomaly reported.  Refresh page to see new anomalies...
+      <strong>Success:</strong> Anomaly deleted.  Refresh page to see new anomalies...
     {{/bs-alert}}
   {{/if}}
 
diff --git a/thirdeye/thirdeye-frontend/app/pods/example/controller.js b/thirdeye/thirdeye-frontend/app/pods/example/controller.js
deleted file mode 100644
index 095d5d6..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/example/controller.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import Controller from '@ember/controller';
-
-export default Controller.extend({
-  splitView: false,
-  actions: {
-    onToggleSplitView() {
-      this.toggleProperty('splitView');
-    }
-  }
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/example/route.js b/thirdeye/thirdeye-frontend/app/pods/example/route.js
deleted file mode 100644
index 803e0d4..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/example/route.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import { inject as service } from '@ember/service';
-import Route from '@ember/routing/route';
-import { Actions as AnomalyActions } from 'thirdeye-frontend/actions/anomaly';
-
-export default Route.extend({
-  redux: service(),
-  session: service(),
-
-  model(params) {
-    const { id } = params;
-    const redux = this.get('redux');
-
-    redux.dispatch(AnomalyActions.fetchData(id));
-    return {};
-  },
-
-  actions: {
-    /**
-     * save session url for transition on login
-     * @method willTransition
-     */
-    willTransition(transition) {
-      //saving session url - TODO: add a util or service - lohuynh
-      if (transition.intent.name && transition.intent.name !== 'logout') {
-        this.set('session.store.fromUrl', {lastIntentTransition: transition});
-      }
-    },
-    error() {
-      return true;
-    }
-  }
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/example/template.hbs b/thirdeye/thirdeye-frontend/app/pods/example/template.hbs
deleted file mode 100644
index 996120c..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/example/template.hbs
+++ /dev/null
@@ -1,23 +0,0 @@
-{{#containers/anomaly-container as |anomalyList actions|}}
-  {{#if anomalyList.loading}}
-    Loading...
-  {{/if}}
-
-  {{#if anomalyList.failed}}
-    Oops, something went wrong...
-  {{/if}}
-
-  {{#if anomalyList.loaded}}
-    {{#if anomalyList.anomaly}}
-        <section class="anomaly-title-bar">
-          {{anomaly-id anomaly=anomalyList.anomaly}}
-        </section>
-        <main class="anomaly-content container">
-          <h1>Example</h1>
-          <p>This is a placeholder example page for the new ember app utilizing ember-redux and connecting to the back end at localhost:1426</p>
-        </main>
-    {{else}}
-      No anomalies found.
-    {{/if}}
-  {{/if}}
-{{/containers/anomaly-container}}
diff --git a/thirdeye/thirdeye-frontend/app/pods/manage/alerts/performance/controller.js b/thirdeye/thirdeye-frontend/app/pods/manage/alerts/performance/controller.js
deleted file mode 100644
index 0f268a2..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/manage/alerts/performance/controller.js
+++ /dev/null
@@ -1,101 +0,0 @@
-import _ from 'lodash';
-import moment from 'moment';
-import { computed, set } from '@ember/object';
-import Controller from '@ember/controller';
-import { inject as service } from '@ember/service';
-
-export default Controller.extend({
-
-  /**
-   * Make duration service accessible
-   */
-  durationCache: service('services/duration'),
-
-  /**
-   * Active class appendage of 'view totals' link
-   * @type {String}
-   */
-  viewTotalsState: computed('viewTotals', function() {
-    return this.get('viewTotals') ? 'active' : 'inactive';
-  }),
-
-  /**
-   * Active class appendage of 'view average' link
-   * @type {String}
-   */
-  viewAvgState: computed('viewTotals', function() {
-    return !this.get('viewTotals') ? 'active' : 'inactive';
-  }),
-
-  /**
-   * List of applications to render as rows, with filtering applied
-   * @type {Array}
-   */
-  applications: computed(
-    'perfDataByApplication',
-    'selectedSortMode',
-    'viewTotals',
-    'sortMap',
-    function() {
-      const sortMap = this.get('sortMap');
-      const selectedSortMode = this.get('selectedSortMode');
-      const sortMapChild = this.get('viewTotals') ? '.tot' : '.avg';
-      const keysWithChildren = ['anomaly', 'user', 'responses'];
-      let allApps = this.get('perfDataByApplication');
-      let fullSortKey = '';
-      let applySortType = true;
-
-      if (selectedSortMode) {
-        let [ sortKey, sortDir ] = selectedSortMode.split(':');
-        applySortType = keysWithChildren.includes(sortKey);
-        fullSortKey = applySortType ? sortMap[sortKey] + sortMapChild : sortMap[sortKey];
-
-        if (sortDir === 'up') {
-          allApps = _.sortBy(allApps, fullSortKey);
-        } else {
-          allApps = _.sortBy(allApps, fullSortKey).reverse();
-        }
-      }
-
-      return allApps;
-    }
-  ),
-
-  actions: {
-
-    /**
-     * Sets the new custom date range for anomaly coverage
-     * @method onRangeSelection
-     * @param {Object} rangeOption - the user-selected time range to load
-     */
-    onRangeSelection(rangeOption) {
-      const {
-        start,
-        end,
-        value: duration
-      } = rangeOption;
-      const durationObj = {
-        duration,
-        startDate: moment(start).valueOf(),
-        endDate: moment(end).valueOf()
-      };
-      // Cache the new time range and update page with it
-      this.get('durationCache').setDuration(durationObj);
-      this.transitionToRoute({ queryParams: durationObj });
-    },
-
-    /**
-     * Handle sorting for each sortable table column
-     * @param {String} sortKey  - stringified start date
-     */
-    toggleSortDirection(sortKey) {
-      const sortMenu = this.get('sortMenuGlyph');
-      const propName = 'sortColumn' + sortKey.capitalize() + 'Up' || '';
-      let direction = '';
-      this.toggleProperty(propName);
-      direction  = this.get(propName) ? 'up' : 'down';
-      set(sortMenu, sortKey, direction);
-      this.set('selectedSortMode', `${sortKey}:${direction}`);
-    }
-  }
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/manage/alerts/performance/route.js b/thirdeye/thirdeye-frontend/app/pods/manage/alerts/performance/route.js
deleted file mode 100644
index 548b23b..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/manage/alerts/performance/route.js
+++ /dev/null
@@ -1,348 +0,0 @@
-/**
- * Handles the 'create alert' route nested in the 'manage' route.
- * @module self-serve/create/route
- * @exports alert create model
- */
-
-import fetch from 'fetch';
-import moment from 'moment';
-import Route from '@ember/routing/route';
-import {
-  hash,
-  allSettled
-} from 'rsvp';
-import { getWithDefault } from '@ember/object';
-import {
-  checkStatus,
-  buildDateEod
-} from 'thirdeye-frontend/utils/utils';
-import { isPresent } from '@ember/utils';
-import { setUpTimeRangeOptions } from 'thirdeye-frontend/utils/manage-alert-utils';
-import { inject as service } from '@ember/service';
-
-/**
- * If true, this reduces the list of alerts per app to 2 for a quick demo.
- */
-const isDemoMode = false;
-
-/**
- * Mapping anomaly table column names to corresponding prop keys
- */
-const sortMap = {
-  name: 'name',
-  alert: 'alerts',
-  anomaly: 'data.totalAlerts',
-  user: 'data.userReportAnomaly',
-  responses: 'data.totalResponses',
-  resrate: 'data.responseRate',
-  precision: 'data.precision'
-};
-
-/**
- * Time range-related constants
- */
-const displayDateFormat = 'YYYY-MM-DD HH:mm';
-const durationMap = { m:'month', d:'day', w:'week' };
-const defaultDurationObj = {
-  duration: '3m',
-  startDate: buildDateEod(3, 'month').valueOf(),
-  endDate: moment()
-};
-
-/**
- * Fetches all anomaly data for found anomalies - downloads all 'pages' of data from server
- * in order to handle sorting/filtering on the entire set locally. Start/end date are not used here.
- * @param {Array} anomalyIds - list of all found anomaly ids
- * @return {Ember.RSVP promise}
- */
-const fetchAppAnomalies = (alertList, startDate, endDate) => {
-  const alertPromises = [];
-  const filteredStartDate = moment(Number(startDate)).toISOString();
-  const filteredEndDate = moment(Number(endDate)).toISOString();
-  const tuneParams = `start=${filteredStartDate}&end=${filteredEndDate}`;
-
-  alertList.forEach((alert) => {
-    let { name, id } = alert;
-    let getAlertPerfHash = {
-      id,
-      name,
-      data: fetch(`/detection-job/eval/filter/${alert.id}?${tuneParams}`).then(checkStatus)
-    };
-    alertPromises.push(hash(getAlertPerfHash));
-  });
-
-  return allSettled(alertPromises);
-};
-
-/**
- * Associate each anomaly with an application name. This is done by:
- * 1) For each existing application, find all alert groups associated with it
- * 2) Add the app name to each of the group's function Ids (making sure we don't duplicate an Id)
- * @param {Array} allApps - list of all applications
- * @param {Array} validGroups - all alert groups that are active
- * @returns {Array} appBucket
- */
-const fillAppBuckets = (allApps, validGroups) => {
-  let appBucket = [];
-
-  allApps.forEach((app) => {
-    let associatedGroups = validGroups.filter(group => group.application.includes(app.application));
-    if (associatedGroups.length) {
-      let uniqueIds = Array.from(new Set([].concat(...associatedGroups.map(group => group.emailConfig.functionIds))));
-      if (isDemoMode) {
-        uniqueIds = uniqueIds.slice(0, 1);
-      }
-      if (uniqueIds.length) {
-        uniqueIds.forEach((id) => {
-          appBucket.push({ name: app.application, id });
-        });
-      }
-    }
-  });
-
-  return appBucket;
-};
-
-/**
- * Simply average the given array of numbers
- * @param {Array} values - all values to average
- * @returns {Number} average value
- */
-const average = (values) => {
-  return (values.reduce((total, amount) => amount += total))/values.length;
-};
-
-/**
- * Check whether there are any fetch promise failures
- * @param {Array} data - all settled RSVP promises
- * @returns {Boolean} true if a failure was found
- */
-const isPromiseRejected = (data) => {
-  return data.map(obj => obj.state).some(state => state === 'rejected');
-};
-
-/**
- * Calculate the standard deviation, or variance in the given array
- * @param {Array} values - all values to average
- * @returns {Number} standard deviation
- */
-const standardDeviation = (values) => {
-  let avg = average(values);
-
-  let squareDiffs = values.map((value) => {
-    let diff = value - avg;
-    let sqrDiff = diff * diff;
-    return sqrDiff;
-  });
-
-  let avgSquareDiff = average(squareDiffs);
-  let stdDev = Math.sqrt(avgSquareDiff);
-  return stdDev;
-};
-
-/**
- * Derive the response or precision rate for a set of anomalies
- * @param {Array} anomalies - all anomalies in a given application
- * @param {Number} subset - the target subset (true anomalies, false, etc)
- * @returns {Number} a percentage
- */
-const calculateRate = (anomalies, subset) => {
-  let percentage = 0;
-  if (anomalies && subset) {
-    percentage = (subset * 100) / anomalies;
-  }
-  return Number(percentage.toFixed());
-};
-
-/**
- * Setup for query param behavior
- */
-const queryParamsConfig = {
-  refreshModel: true,
-  replace: true
-};
-
-export default Route.extend({
-  session: service(),
-  queryParams: {
-    duration: queryParamsConfig,
-    startDate: queryParamsConfig,
-    endDate: queryParamsConfig
-  },
-
-  beforeModel(transition) {
-    const { duration, startDate } = transition.queryParams;
-    // Default to 1 month of anomalies to show if no dates present in query params
-    if (!duration || !startDate) {
-      this.transitionTo({ queryParams: defaultDurationObj });
-    }
-  },
-
-  /**
-   * Model hook for the create alert route.
-   * @method model
-   * @return {Object}
-   */
-  model(transition) {
-    // Get duration data
-    const {
-      duration,
-      startDate,
-      endDate
-    } = transition;
-
-    return hash({
-      // Fetch all alert group configurations
-      configGroups: fetch('/thirdeye/entity/ALERT_CONFIG').then(checkStatus),
-      applications: fetch('/thirdeye/entity/APPLICATION').then(checkStatus),
-      duration,
-      startDate,
-      endDate
-    });
-  },
-
-  afterModel(model) {
-    this._super(model);
-
-    const activeGroups = model.configGroups.filterBy('active');
-    const groupsWithAppName = activeGroups.filter(group => isPresent(group.application));
-    const groupsWithAlertId = groupsWithAppName.filter(group => group.emailConfig.functionIds.length > 0);
-    const filteredGroups = isDemoMode ? groupsWithAlertId.slice(0, 3) : groupsWithAlertId;
-    const idsByApplication = fillAppBuckets(model.applications, filteredGroups);
-    Object.assign(model, { idsByApplication });
-  },
-
-  setupController(controller, model) {
-    this._super(controller, model);
-
-    const {
-      idsByApplication,
-      startDate,
-      endDate,
-      duration
-    } = model;
-
-    // Display loading banner
-    controller.setProperties({
-      timeRangeOptions: setUpTimeRangeOptions(['1m', '3m'], duration),
-      activeRangeStart: moment(Number(startDate)).format(displayDateFormat),
-      activeRangeEnd: moment(Number(endDate)).format(displayDateFormat),
-      uiDateFormat: "MMM D, YYYY hh:mm a",
-      timePickerIncrement: 5,
-      isDataLoading: true
-    });
-
-    // Get perf data for each alert and assign it to the model
-    fetchAppAnomalies(idsByApplication, startDate, endDate)
-      .then((richFunctionObjects) => {
-        const newFunctionObjects = richFunctionObjects.filter(obj => obj.state === 'fulfilled').map(obj => obj.value);
-        const availableGroups = Array.from(new Set(newFunctionObjects.map(alertObj => alertObj.name)));
-        const roundable = ['totalAlerts', 'totalResponses', 'falseAlarm', 'newTrend', 'trueAnomalies', 'userReportAnomaly'];
-        let sortMenuGlyph = {};
-        let newGroupArr = [];
-        let count = 0;
-
-        // Filter down to functions belonging to our active application groups
-        availableGroups.forEach((group) => {
-          let avgData = {};
-          let keyData = {};
-          let groupData = newFunctionObjects.filter((alert) => {
-            return alert.name === group;
-          });
-
-          // Get array of keys from first record
-          let metricKeys = Object.keys(groupData[0].data);
-          let getTotalValue = (key) => getWithDefault(avgData, key, 0);
-          count++;
-
-          // Look at each anomaly's perf object keys. For our "roundable" fields, get derived data
-          metricKeys.forEach((key) => {
-            let isRawValue = roundable.includes(key);
-            let allValues = groupData.map(group => group.data[key]);
-            let allNumeric = allValues.every(val => !Number.isNaN(Number(val)));
-            let total = allValues.reduce((total, amount) => amount += total);
-            avgData[key] = {};
-
-            if (allNumeric && isRawValue) {
-              let avg = total/allValues.length;
-              avgData[key].avg = Math.round(avg);
-              avgData[key].tot = total;
-              avgData[key].max = Math.max(...allValues);
-              avgData[key].min = Math.min(...allValues);
-              avgData[key].std = standardDeviation(allValues).toFixed(2);
-              avgData[key].name = group;
-            } else {
-              let avg = total/(allValues.filter(Number)).length;
-              avgData[key].avg = !Number.isNaN(Number(avg)) ? `${(avg * 100).toFixed(1)}` : 'N/A';
-              avgData[key].tot = 'N/A';
-            }
-            avgData[key].values = allValues;
-          });
-
-          // Gather totals and make custom calculations
-          let pTrue = getTotalValue('trueAnomalies.tot');
-          let pNew = getTotalValue('newTrend.tot');
-          let pFalse = getTotalValue('falseAlarm.tot');
-          let rResponses = getTotalValue('totalResponses.tot');
-          let rTotal = getTotalValue('totalAlerts.tot');
-          let precisionTotal = pTrue + pNew + pFalse;
-          avgData['responseRate'] = avgData['responseRate'] ? calculateRate(rTotal, rResponses) : 'N/A';
-          avgData['precision'] = avgData['precision'] ? calculateRate(precisionTotal, pTrue + pNew) : 'N/A';
-
-          // Add perf data to application groups array
-          newGroupArr.push({
-            name: isDemoMode ? `group ${count}` : group,
-            data: avgData,
-            alerts: groupData.length
-          });
-        });
-
-        // Initialize glyph icons for each table column
-        for (var key in sortMap) {
-          sortMenuGlyph[key] = 'down';
-        }
-
-        // Pass perf data and state to controller
-        controller.setProperties({
-          sortMap,
-          sortMenuGlyph,
-          viewTotals: true,
-          isDataLoading: false,
-          isDataLoadingError: false,
-          perfDataByApplication: newGroupArr
-        });
-
-      })
-      .catch((errMsg) => {
-        controller.setProperties({
-          isDataLoadingError: true,
-          errMsg
-        });
-      });
-  },
-
-  actions: {
-    /**
-     * save session url for transition on login
-     * @method willTransition
-     */
-    willTransition(transition) {
-      //saving session url - TODO: add a util or service - lohuynh
-      if (transition.intent.name && transition.intent.name !== 'logout') {
-        this.set('session.store.fromUrl', {lastIntentTransition: transition});
-      }
-    },
-    error() {
-      return true;
-    },
-
-    /**
-    * Refresh route's model.
-    * @method refreshModel
-    * @return {undefined}
-    */
-    refreshModel() {
-      this.refresh();
-    }
-  }
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/manage/alerts/performance/template.hbs b/thirdeye/thirdeye-frontend/app/pods/manage/alerts/performance/template.hbs
deleted file mode 100644
index 9a00a55..0000000
--- a/thirdeye/thirdeye-frontend/app/pods/manage/alerts/performance/template.hbs
+++ /dev/null
@@ -1,140 +0,0 @@
-{{#if isDataLoading}}
-  <div class="te-alert-page-pending">
-    <img src="{{rootURL}}assets/images/te-alert-{{if isDataLoadingError "error" "pending"}}.png" class="te-alert-page-pending__image {{if isDataLoadingError "te-alert-page-pending__image--error"}}" alt="alertData.Setup is Processing">
-    <h2 class="te-alert-page-pending__title">{{if isDataLoadingError "Oops, something went wrong." "Aggregating anomaly performance data..."}}</h2>
-    {{#if (not isDataLoadingError)}}<div class="te-alert-page-pending__loader"></div>{{/if}}
-    <p class="te-alert-page-pending__text">
-      {{#if isDataLoadingError}}
-        The performance data cannot be retrieved.<br/>{{errMsg}}
-      {{else}}
-        Fetching all app-related anomaly data for all alerts may take up to a minute. <br/>Hang in there!
-      {{/if}}
-    </p>
-  </div>
-{{else}}
-  <div class="manage-alert-tune">
-
-    {{!-- Date range selector --}}
-    {{range-pill-selectors
-      title="Select Time Range"
-      uiDateFormat=uiDateFormat
-      activeRangeEnd=activeRangeEnd
-      activeRangeStart=activeRangeStart
-      timeRangeOptions=timeRangeOptions
-      timePickerIncrement=timePickerIncrement
-      selectAction=(action "onRangeSelection")
-    }}
-
-    <div class="te-content-block">
-      <h4 class="te-alert-page__subtitle">Alert Performance by Application Group</h4>
-      <a class="te-self-serve__side-link te-self-serve__side-link--{{viewTotalsState}}" {{action (toggle "viewTotals" this)}}>View total values</a>
-      <a class="te-self-serve__side-link te-self-serve__side-link--{{viewAvgState}}" {{action (toggle "viewTotals" this)}}>View average values</a>
-      {{!-- Alert anomaly table --}}
-      <table class="te-anomaly-table te-anomaly-table--performance">
-        <thead>
-          <tr class="te-anomaly-table__row te-anomaly-table__head">
-           <th class="te-anomaly-table__cell-head">
-              <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "name"}}>
-                Appp
-                <i class="te-anomaly-table__icon te-anomaly-table__icon--small glyphicon glyphicon-menu-{{sortMenuGlyph.name}}"></i>
-              </a>
-             </th>
-             <th class="te-anomaly-table__cell-head">
-              <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "alert"}}>
-                Alerts
-                <i class="te-anomaly-table__icon te-anomaly-table__icon--small glyphicon glyphicon-menu-{{sortMenuGlyph.alert}}"></i>
-              </a>
-             </th>
-             <th class="te-anomaly-table__cell-head">
-              <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "anomaly"}}>
-                Anomalies
-                <i class="te-anomaly-table__icon te-anomaly-table__icon--small glyphicon glyphicon-menu-{{sortMenuGlyph.anomaly}}"></i>
-              </a>
-             </th>
-             <th class="te-anomaly-table__cell-head">
-              <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "user"}}>
-                User-rep
-                <i class="te-anomaly-table__icon te-anomaly-table__icon--small glyphicon glyphicon-menu-{{sortMenuGlyph.user}}"></i>
-              </a>
-            </th>
-             <th class="te-anomaly-table__cell-head">
-              <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "responses"}}>
-                Responses
-                <i class="te-anomaly-table__icon te-anomaly-table__icon--small glyphicon glyphicon-menu-{{sortMenuGlyph.responses}}"></i>
-              </a>
-             </th>
-             <th class="te-anomaly-table__cell-head">
-              <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "resrate"}}>
-                Response rate
-                <i class="te-anomaly-table__icon te-anomaly-table__icon--small glyphicon glyphicon-menu-{{sortMenuGlyph.resrate}}"></i>
-              </a>
-            </th>
-             <th class="te-anomaly-table__cell-head">
-              <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "precision"}}>
-                Precision
-                <i class="te-anomaly-table__icon te-anomaly-table__icon--small glyphicon glyphicon-menu-{{sortMenuGlyph.precision}}"></i>
-              </a>
-            </th>
-          </tr>
-        </thead>
-
-        <tbody>
-          {{#each applications as |app|}}
-            <tr class="te-anomaly-table__row">
-              <td class="te-anomaly-table__cell te-anomaly-table__list-item te-anomaly-table__list-item--stronger">{{app.name}}</td>
-              <td class="te-anomaly-table__cell">{{app.alerts}}</td>
-              <td class="te-anomaly-table__cell">
-                {{performance-tooltip
-                  data=app.data.totalAlerts
-                  category="Anomalies"
-                  viewTotals=viewTotals
-                }}
-              </td>
-              <td class="te-anomaly-table__cell">
-                {{performance-tooltip
-                  data=app.data.userReportAnomaly
-                  category="User reported anomalies"
-                  viewTotals=viewTotals
-                }}
-              </td>
-              <td class="te-anomaly-table__cell">
-                <div class="te-performance-metric">
-                  {{performance-tooltip
-                   data=app.data.totalResponses
-                   category="Total Responses"
-                   viewTotals=viewTotals
-                  }}
-                </div>
-                <div class="te-performance-metric__subset">
-                  ( T: {{performance-tooltip
-                         data=app.data.trueAnomalies
-                         category="True anomalies"
-                         viewTotals=viewTotals
-                       }} |
-                  F: {{performance-tooltip
-                       data=app.data.falseAlarm
-                       category="False anomalies"
-                       viewTotals=viewTotals
-                     }} |
-                  N: {{performance-tooltip
-                       data=app.data.newTrend
-                       category="New trend anomalies"
-                       viewTotals=viewTotals
-                     }} )
-              </div>
-              </td>
-              <td class="te-anomaly-table__cell">
-                {{app.data.responseRate}}
-                <span class="te-anomaly-table__list-item te-anomaly-table__list-item--smaller">%</span>
-              </td>
-              <td class="te-anomaly-table__cell">
-                {{app.data.precision}}
-                <span class="te-anomaly-table__list-item te-anomaly-table__list-item--smaller">%</span>
-              </td>
-            </tr>
-          {{/each}}
-        </tbody>
-      </table>
-    </div>
-  </div>
-{{/if}}
diff --git a/thirdeye/thirdeye-frontend/app/pods/self-serve/create-alert/template.hbs b/thirdeye/thirdeye-frontend/app/pods/self-serve/create-alert/template.hbs
index 2d7165f..f5320d9 100644
--- a/thirdeye/thirdeye-frontend/app/pods/self-serve/create-alert/template.hbs
+++ b/thirdeye/thirdeye-frontend/app/pods/self-serve/create-alert/template.hbs
@@ -120,21 +120,6 @@
       </div>
 
       {{!-- Render metric graph --}}
-      {{self-serve-graph
-        removeGraphMargin=true
-        metricData=selectedMetric
-        componentId='create-alert'
-        topDimensions=topDimensions
-        isTopDimensionsAllowed=false
-        graphMailtoLink=graphMailtoLink
-        selectedDimension=selectedDimension
-        selectedDimensions=selectedDimensions
-        isMetricSelected=isMetricSelected
-        isMetricDataLoading=isMetricDataLoading
-        isMetricDataInvalid=isMetricDataInvalid
-        isSecondaryDataLoading=isSecondaryDataLoading
-        isDimensionFetchDone=isDimensionFetchDone
-      }}
 
     </fieldset>
 
diff --git a/thirdeye/thirdeye-frontend/app/router.js b/thirdeye/thirdeye-frontend/app/router.js
index a9d895b..945a302 100644
--- a/thirdeye/thirdeye-frontend/app/router.js
+++ b/thirdeye/thirdeye-frontend/app/router.js
@@ -24,7 +24,7 @@ Router.map(function() {
 
   this.route('manage', function() {
     this.route('alerts', function() {
-      this.route('performance');
+      this.route('index', { path: '/' });
     });
     this.route('explore', { path: 'explore/:alert_id'});
     this.route('yaml', { path: 'yaml/:alert_id' });
diff --git a/thirdeye/thirdeye-frontend/app/styles/app.scss b/thirdeye/thirdeye-frontend/app/styles/app.scss
index 1c470dd..cca77e1 100644
--- a/thirdeye/thirdeye-frontend/app/styles/app.scss
+++ b/thirdeye/thirdeye-frontend/app/styles/app.scss
@@ -32,14 +32,10 @@ body {
 
 // Components
 @import 'components/alert-details';
-@import 'components/anomaly-id';
-@import 'components/anomaly-graph';
 @import 'components/te-navbar';
 @import 'components/button';
 @import 'components/links';
 @import 'components/filter-select';
-@import 'components/dimension-heatmap';
-@import 'components/dimension-summary';
 @import 'components/heatmap-chart';
 @import 'components/login-form';
 @import 'components/entity-filter';
diff --git a/thirdeye/thirdeye-frontend/app/styles/components/anomaly-graph.scss b/thirdeye/thirdeye-frontend/app/styles/components/anomaly-graph.scss
deleted file mode 100644
index 93983f6..0000000
--- a/thirdeye/thirdeye-frontend/app/styles/components/anomaly-graph.scss
+++ /dev/null
@@ -1,151 +0,0 @@
-// Overriding default c3
-
-.anomaly-graph {
-  box-sizing: border-box;
-  display: flex;
-  border: 1px solid $te-grey--border;
-
-  &:not(:first-child) {
-      margin-top: 14px;
-  }
-
-  &--no-border {
-    border: 0;
-  }
-
-  .c3-brush .extent {
-    fill: #4682b4;
-    fill-opacity: .125;
-    stroke: #CCC;
-  }
-
-  .c3-line {
-    stroke-width: 2px;
-  }
-
-  .c3-chart-line:nth-child(even) > .c3-lines {
-    stroke-dasharray: 1%;
-  }
-
-  .anomaly-graph__slider-line {
-    stroke: white;
-    stroke-width: 3;
-  }
-
-  .anomaly-graph__region-slider .extent{
-    stroke: #fff;
-    fill-opacity: .2;
-    fill: $te-orange;
-  }
-
-  &__legend {
-    position: absolute;
-    top: 0;
-    right: 0;
-  }
-
-  &__legend-item {
-    display: block;
-  }
-
-  &__legend-line {
-    stroke: $te-blue !important;
-    stroke-width: 3;
-
-    &--orange {
-      stroke: $te-orange !important;
-    }
-  }
-}
-
-.anomaly-graph__filter-item {
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  overflow: hidden;
-}
-.anomaly-graph__filter-label {
-  cursor: pointer;
-  color: #0091CA;
-  font-weight: normal;
-}
-
-.anomaly-graph__filter-group {
-  padding-left: 14px;
-  margin: 14px 0;
-  list-style: none;
-  &--hidden {
-    height: 0;
-    overflow: hidden;
-    margin: 0;
-  }
-}
-
-.anomaly-graph__title {
-  @include margin-reset;
-  @include padding-reset;
-  font-size: initial;
-  font-weight: normal;
-  margin-bottom: 14px;
-}
-
-.legend-title {
-  padding: 14px;
-  color: rgba(0,0,0, 0.55);
-  margin: 0;
-  background-color: #F3F6F8;
-  font-size: 14px;
-  font-weight: 600;
-  position: sticky;
-  top: 0;
-}
-
-.legend-cta {
-  color: rgba(0, 0, 0, 0.30);
-}
-
-.anomaly-graph__left-panel {
-  min-width: 250px;
-  flex-grow: 1;
-  overflow: scroll;
-  position: relative;
-  border-right: 1px solid $te-grey--border;
-}
-
-.anomaly-graph__right-panel {
-  position: relative;
-  flex-basis: 75%;
-  flex-grow: 1;
-  width: 75%;
-  padding: 14px;
-}
-
-.anomaly_graph__filters {
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  right: 0;
-  left: 0;
-}
-
-
-$colors:
-  "blue" $te-blue,
-  "orange" $te-orange,
-  "teal" $te-teal,
-  "purple" $te-purple,
-  "red" $te-red,
-  "green" $te-green,
-  "pink" $te-pink,
-  "grey" $te-grey,
-  "dark-orange" #B74700;
-
-// creates .c3-region-"color" classes
-@each $i in $colors{
-  .c3-region--#{nth($i, 1)} {
-    fill: nth($i, 2);
-  }
-
-  .anomaly-graph__filter-label--#{nth($i, 1)} {
-  color: lighten(nth($i, 2), 10%);
-  }
-};
diff --git a/thirdeye/thirdeye-frontend/app/styles/components/anomaly-id.scss b/thirdeye/thirdeye-frontend/app/styles/components/anomaly-id.scss
deleted file mode 100644
index b98f61f..0000000
--- a/thirdeye/thirdeye-frontend/app/styles/components/anomaly-id.scss
+++ /dev/null
@@ -1,32 +0,0 @@
-.anomaly-id {
-  list-style: none;
-  font-size: $te-font-size-medium;
-  font-weight: 300;
-  width: 100%;
-  padding: 20px 0;
-
-  &__item {
-    line-height: $te-list-line-height;
-
-    &--title {
-      font-size: $te-font-size-component-title;
-    }
-
-    &--value {
-      font-size: $te-font-size-medium;
-      font-weight: normal;
-    }
-  }
-
-  &__subtitle {
-    font-weight: normal;
-  }
-
-  &__total {
-    font-weight: bold;
-  }
-
-  &__percent {
-    color: $anomaly-id-percent-change;
-  }
-}
diff --git a/thirdeye/thirdeye-frontend/app/styles/components/dimension-heatmap.scss b/thirdeye/thirdeye-frontend/app/styles/components/dimension-heatmap.scss
deleted file mode 100644
index 71ef52f..0000000
--- a/thirdeye/thirdeye-frontend/app/styles/components/dimension-heatmap.scss
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copy paste from the old Thirdeye UI
-.dimension-heatmap {
-  margin-top: 24px;
-}
-
-.dimension-heatmap__table {
-  margin-bottom: 0;
-}
-
-.heatmap {
-  background-color: #f5f5f5;
-}
-
-.analysis-tooltip {
-  font-size: 14px;
-}
-
-.analysis-tooltip__header {
-  font-weight: bold;
-}
-
-.analysis-tooltip__column {
-  text-align: right;
-}
-
-.analysis-tooltip__column-header {
-  text-align: left;
-}
-
-.analysis-tooltip__container {
-  width: 400px;
-}
-
-.analysis-tooltip__list {
-  list-style: none;
-  margin-bottom: 0;
-  padding-left: 0;
-}
-
-.analysis-tooltip__list-item {
-  display: flex;
-  justify-content: space-between;
-}
-
-#tooltip,
-#heatmap-tooltip {
-  position: absolute;
-  min-width: 300px;
-  height: auto;
-  padding: 10px;
-  background-color: white;
-  -webkit-border-radius: 10px;
-  -moz-border-radius: 10px;
-  border-radius: 10px;
-  -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
-  -moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
-  box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
-  pointer-events: none;
-
-  &.hidden {
-    display: none;
-  }
-
-  & p {
-    margin: 0;
-    font-size: 13px;
-  }
-}
-
diff --git a/thirdeye/thirdeye-frontend/app/styles/components/dimension-summary.scss b/thirdeye/thirdeye-frontend/app/styles/components/dimension-summary.scss
deleted file mode 100644
index fb105fc..0000000
--- a/thirdeye/thirdeye-frontend/app/styles/components/dimension-summary.scss
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copy paste from old Thirdeye UI
-.dimension-summary {
-  display: flex;
-  justify-content: space-between;
-}
-.dimension-summary__label {
-  text-transform: uppercase;
-  color: rgba(0,0,0,.55);
-  font-weight: normal;
-}
-
-.dimension-summary__item {
-  display: flex;
-  flex-direction: column;
-  justify-content: space-between;
-}
-
-.dimension-summary__data {
-  font-size: 18px;
-  color: rgba(0,0,0,.70);
-  margin-top: 0;
-
-  &--positive {
-  color: #398b18;
-  }
-
-  &--negative {
-  color: #ee1620;
-  }
-}
diff --git a/thirdeye/thirdeye-frontend/app/styles/pods/manage/alerts-performance.scss b/thirdeye/thirdeye-frontend/app/styles/pods/manage/alerts-performance.scss
index 8566192..e62be78 100644
--- a/thirdeye/thirdeye-frontend/app/styles/pods/manage/alerts-performance.scss
+++ b/thirdeye/thirdeye-frontend/app/styles/pods/manage/alerts-performance.scss
@@ -1,23 +1,3 @@
-.te-performance-tooltip {
-  display: inline-block;
-
-  &__title {
-    text-transform: uppercase;
-  }
-  &__list {
-    padding-left: 0;
-    margin-top: 5px;
-    max-width: 400px;
-  }
-  &__item {
-    list-style: none;
-  }
-  &__category {
-    color: app-shade(white, 5);
-    padding-right: 7px;
-  }
-}
-
 .te-performance-metric {
   width: 20px;
   text-align: right;
diff --git a/thirdeye/thirdeye-frontend/tests/integration/pods/components/anomaly-graph/component-test.js b/thirdeye/thirdeye-frontend/tests/integration/pods/components/anomaly-graph/component-test.js
deleted file mode 100644
index 3d881cb..0000000
--- a/thirdeye/thirdeye-frontend/tests/integration/pods/components/anomaly-graph/component-test.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// TODO: [THIRDEYE-1796] Fix failing tests
-// import { moduleForComponent, test } from 'ember-qunit';
-// import hbs from 'htmlbars-inline-precompile';
-
-// moduleForComponent('anomaly-graph', 'Integration | Component | anomaly graph', {
-//   integration: true
-// });
-
-// test('it renders', function(assert) {
-//   const selector = '.anomaly-graph';
-//   const anomaly = {
-//     dates: ['2017-01-01 10:00', '2017-01-02 10:00', '2017-01-03 10:00'], 
-//     currentValues: [1,2,3],
-//     baselineValues: [4,5,6],
-//     anomalyRegionStart: '2017-01-01 10:00',
-//     anomalyRegionEnd: '2017-01-03 10:00',
-//     metricName: 'test_metric'
-//   };
-//   this.set('anomaly', anomaly);
-//   this.render(hbs`{{anomaly-graph anomaly=anomaly}}`);
-
-//   assert.ok(this.$(selector).length, 'anomaly graph renders correctly');
-// });
diff --git a/thirdeye/thirdeye-frontend/tests/integration/pods/components/anomaly-id/component-test.js b/thirdeye/thirdeye-frontend/tests/integration/pods/components/anomaly-id/component-test.js
deleted file mode 100644
index 2916e7e..0000000
--- a/thirdeye/thirdeye-frontend/tests/integration/pods/components/anomaly-id/component-test.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import { module, test } from 'qunit';
-import { setupRenderingTest } from 'ember-qunit';
-import { render } from '@ember/test-helpers';
-import hbs from 'htmlbars-inline-precompile';
-import floatToPercent from 'thirdeye-frontend/utils/float-to-percent';
-
-module('Integration | Component | anomaly id', function(hooks) {
-  setupRenderingTest(hooks);
-
-  const idSelector = '.anomaly-id__id';
-  const nameSelector = '.anomaly-id__name';
-  const currentValueSelector = '.anomaly-id__total';
-  const changeRateSelector = '.anomaly-id__percent';
-  const anomalyId = 20475;
-  const anomalyCurrentValue = 10;
-  const anomalyBaselineValue = 2;
-  const anomaly = {
-    anomalyIds: anomalyId,
-    current: anomalyCurrentValue,
-    baseline: anomalyBaselineValue,
-    anomalyFunctionName: 'some-function-name'
-  };
-  const calculateChangeRate = (current, baseline) => {
-    return (baseline === 0) ? 0 : floatToPercent((current - baseline) / baseline);
-  };
-
-  // Test for proper rendering of all Anomaly ID Block data
-  test('Anomaly ID block: all meta properties render', async function(assert) {
-    let changeRate = calculateChangeRate(anomaly.current, anomaly.baseline);
-
-    // this.set('anomaly', anomaly);
-    // this.set('anomalyChangeRate', changeRate);
-    this.setProperties({ 'anomaly': anomaly, 'anomalyChangeRate': changeRate });
-    await render(hbs`{{anomaly-id anomaly=anomaly}}`);
-
-    assert.equal(this.$(idSelector).text().trim(), anomalyId, 'The anomaly id is correct and renders');
-    assert.equal(this.$(nameSelector).text().trim(), anomaly.anomalyFunctionName, 'The anomaly name is correct and renders');
-    assert.equal(this.$(currentValueSelector).text().trim(), anomaly.current, 'The current value is correct and renders');
-    assert.equal(this.$(changeRateSelector).text().trim(), '(' + changeRate + '%)', 'The change rate is correct and renders');
-  });
-
-  // Now test for proper handling of a zero-value for baseline. In this case, percent change
-  // cannot be calculated - we should return and display '0'
-  test('Anomaly ID block: render correct change rate for zero baseline', async function(assert) {
-    anomaly.baseline = 0;
-    let changeRate = calculateChangeRate(anomaly.current, anomaly.baseline);
-
-    // this.set('anomaly', anomaly);
-    // this.set('anomalyChangeRate', changeRate);
-    this.setProperties({ 'anomaly': anomaly, 'anomalyChangeRate': changeRate });
-    await render(hbs`{{anomaly-id anomaly=anomaly}}`);
-
-    assert.equal(this.$(changeRateSelector).text().trim(), '(' + changeRate + '%)', 'The change rate handles a zero baseline correctly');
-  });
-});
diff --git a/thirdeye/thirdeye-frontend/tests/integration/pods/components/thirdeye-chart/component-test.js b/thirdeye/thirdeye-frontend/tests/integration/pods/components/thirdeye-chart/component-test.js
deleted file mode 100644
index e729d2f..0000000
--- a/thirdeye/thirdeye-frontend/tests/integration/pods/components/thirdeye-chart/component-test.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// TODO: [THIRDEYE-1796] Fix failing tests
-// import { moduleForComponent, test } from 'ember-qunit';
-// import hbs from 'htmlbars-inline-precompile';
-
-// moduleForComponent('thirdeye-chart', 'Integration | Component | thirdeye chart', {
-//   integration: true
-// });
-
-// test('it renders', function(assert) {
-
-//   // Set any properties with this.set('myProperty', 'value');
-//   // Handle any actions with this.on('myAction', function(val) { ... });
-
-//   this.render(hbs`{{thirdeye-chart}}`);
-
-//   assert.equal(this.$().text().trim(), '');
-
-//   // Template block usage:
-//   this.render(hbs`
-//     {{#thirdeye-chart}}
-//       template block text
-//     {{/thirdeye-chart}}
-//   `);
-
-//   assert.equal(this.$().text().trim(), 'template block text');
-// });


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org