You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by ji...@apache.org on 2019/05/28 20:46:34 UTC

[incubator-pinot] branch master updated: [TE] frontend - harleyjj/edit-alert - use new yaml components in edit-alert (#4237)

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

jihao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new 447f7fc  [TE] frontend - harleyjj/edit-alert - use new yaml components in edit-alert (#4237)
447f7fc is described below

commit 447f7fc29019432a39fe790e2bd0daf470737e48
Author: Harley Jackson <hj...@linkedin.com>
AuthorDate: Tue May 28 13:46:28 2019 -0700

    [TE] frontend - harleyjj/edit-alert - use new yaml components in edit-alert (#4237)
    
    This commit helps prepare the manage/yaml route (edit alert) for full-ui. The PR:
    
    Implements edit-alert using new separate yaml components
    Migrates shared props to the controller
    Fixes bug where preview button doesn't show unless user types
    Fixes bug where template yaml text is shoved into editor when copy-pasting content
    Makes all subscription groups available in dropdown on Edit Alert, since subscription group editing has been separated on Edit Alert anyway
---
 .../app/pods/components/alert-details/template.hbs | 575 +++++++++++----------
 .../pods/components/detection-yaml/component.js    |  24 +-
 .../pods/components/detection-yaml/template.hbs    |   2 +-
 .../pods/components/subscription-yaml/component.js | 205 +-------
 .../pods/components/subscription-yaml/template.hbs |  15 +-
 .../app/pods/manage/yaml/controller.js             | 158 +++++-
 .../app/pods/manage/yaml/route.js                  |  51 +-
 .../app/pods/manage/yaml/template.hbs              |  66 ++-
 .../app/pods/self-serve/create-alert/controller.js |  12 +
 .../app/pods/self-serve/create-alert/route.js      |  52 +-
 .../app/pods/self-serve/create-alert/template.hbs  |   4 +
 11 files changed, 653 insertions(+), 511 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 431e077..4da1538 100644
--- a/thirdeye/thirdeye-frontend/app/pods/components/alert-details/template.hbs
+++ b/thirdeye/thirdeye-frontend/app/pods/components/alert-details/template.hbs
@@ -2,16 +2,27 @@
 
   <div class="pull-right">
     {{#if isPreviewMode}}
-      {{#unless dataIsCurrent}}
+      {{#if showDetails}}
+        {{#unless dataIsCurrent}}
+          {{bs-button
+            defaultText=(if showDetails "Rerun Preview" "Preview Alert")
+            disabled=disablePreviewButton
+            type="outline-primary"
+            buttonType="refresh"
+            onClick=(action "getPreview")
+            class="te-button te-button--cancel"
+          }}
+        {{/unless}}
+      {{else}}
         {{bs-button
-          defaultText=(if showDetails "Rerun Preview" "Preview Alert")
+          defaultText="Preview Alert"
           disabled=disablePreviewButton
           type="outline-primary"
           buttonType="refresh"
           onClick=(action "getPreview")
           class="te-button te-button--cancel"
         }}
-      {{/unless}}
+      {{/if}}
     {{/if}}
   </div>
   {{#unless errorAnomalies}}
@@ -33,80 +44,99 @@
           </div>
         {{/if}}
         {{#if dataIsCurrent}}
-        {{range-pill-selectors
-          title="Showing"
-          uiDateFormat=pill.uiDateFormat
-          activeRangeEnd=pill.activeRangeEnd
-          activeRangeStart=pill.activeRangeStart
-          timeRangeOptions=pill.timeRangeOptions
-          timePickerIncrement=pill.timePickerIncrement
-          predefinedRanges=pill.predefinedRanges
-          selectAction=(action "onRangeSelection")
-        }}
-        <div class="te-horizontal-cards te-content-block">
-          <h4 class="te-self-serve__block-title">
-            <label for="select-dimension" class="control-label te-label">
-              Alert Performance
-              <span>
-                <i class="glyphicon glyphicon-question-sign"></i>
-                {{#tooltip-on-element class="te-tooltip"}}
-                  All estimated performance numbers are based on reviewed anomalies.
-                {{/tooltip-on-element}}
-              </span>
-            </label>
-          </h4>
-          {{!-- Alert anomaly stats cards --}}
-          {{stats-cards stats=stats}}
-
-          {{#if repRunStatus}}
-            <p class="te-self-serve__block-subtext te-self-serve__block-subtext--normal">Replay in progress. Please check back later...</p>
-          {{/if}}
-        </div>
-
-        {{#if isReportSuccess}}
-          {{#bs-alert type="success" class="te-form__banner te-form__banner--success"}}
-            <strong>Success:</strong> Anomaly reported for dates <strong>{{reportedRange}}</strong>. Refresh page to see new anomalies...
-          {{/bs-alert}}
-        {{/if}}
+          {{range-pill-selectors
+            title="Showing"
+            uiDateFormat=pill.uiDateFormat
+            activeRangeEnd=pill.activeRangeEnd
+            activeRangeStart=pill.activeRangeStart
+            timeRangeOptions=pill.timeRangeOptions
+            timePickerIncrement=pill.timePickerIncrement
+            predefinedRanges=pill.predefinedRanges
+            selectAction=(action "onRangeSelection")
+          }}
+          <div class="te-horizontal-cards te-content-block">
+            <h4 class="te-self-serve__block-title">
+              <label for="select-dimension" class="control-label te-label">
+                Alert Performance
+                <span>
+                  <i class="glyphicon glyphicon-question-sign"></i>
+                  {{#tooltip-on-element class="te-tooltip"}}
+                    All estimated performance numbers are based on reviewed anomalies.
+                  {{/tooltip-on-element}}
+                </span>
+              </label>
+            </h4>
+            {{!-- Alert anomaly stats cards --}}
+            {{stats-cards stats=stats}}
 
-        {{#if isReportFailure}}
-          {{#bs-alert type="danger" class="te-form__banner te-form__banner--failure"}}
-            <strong>Error:</strong> Failed to save reported anomaly.
-          {{/bs-alert}}
-        {{/if}}
+            {{#if repRunStatus}}
+              <p class="te-self-serve__block-subtext te-self-serve__block-subtext--normal">Replay in progress. Please check back later...</p>
+            {{/if}}
+          </div>
 
-        <div class="te-content-block">
-          {{#if isPreviewMode}}
-            <h4 class="te-self-serve__block-title">{{selectedRule}} {{#if alertHasDimensions}}/ {{selectedDimension}}{{/if}} anomalies over time ({{numCurrentAnomalies}})</h4>
-          {{else}}
-            <h4 class="te-self-serve__block-title">{{#if alertHasDimensions}}{{selectedDimension}} a{{else}}A{{/if}}nomalies over time ({{numCurrentAnomalies}})</h4>
+          {{#if isReportSuccess}}
+            {{#bs-alert type="success" class="te-form__banner te-form__banner--success"}}
+              <strong>Success:</strong> Anomaly reported for dates <strong>{{reportedRange}}</strong>. Refresh page to see new anomalies...
+            {{/bs-alert}}
           {{/if}}
 
-          {{#unless isPreviewMode}}
-            <a class="te-self-serve__side-link te-self-serve__side-link--high" {{action "onClickReportAnomaly" this}}>Report missing anomaly</a>
-          {{/unless}}
+          {{#if isReportFailure}}
+            {{#bs-alert type="danger" class="te-form__banner te-form__banner--failure"}}
+              <strong>Error:</strong> Failed to save reported anomaly.
+            {{/bs-alert}}
+          {{/if}}
 
-          <div class="te-form__select te-form__select--same-line col-md-3">
-            {{!-- Rule selector --}}
+          <div class="te-content-block">
             {{#if isPreviewMode}}
-              {{#power-select
-                triggerId="select-rule"
-                triggerClass="te-form__select"
-                options=ruleOptions
-                searchEnabled=true
-                searchPlaceholder="Type to filter..."
-                matchTriggerWidth=false
-                matchContentWidth=true
-                selected=selectedRule
-                onchange=(action "onSelectRule")
-                as |rule|
-              }}
-                {{rule}}
-              {{/power-select}}
+              <h4 class="te-self-serve__block-title">{{selectedRule}} {{#if alertHasDimensions}}/ {{selectedDimension}}{{/if}} anomalies over time ({{numCurrentAnomalies}})</h4>
+            {{else}}
+              <h4 class="te-self-serve__block-title">{{#if alertHasDimensions}}{{selectedDimension}} a{{else}}A{{/if}}nomalies over time ({{numCurrentAnomalies}})</h4>
+            {{/if}}
 
-              {{!-- Dimension selector --}}
-              {{#if alertHasDimensions}}
-                <div class="te-form__select te-form__select--margin-left">
+            {{#unless isPreviewMode}}
+              <a class="te-self-serve__side-link te-self-serve__side-link--high" {{action "onClickReportAnomaly" this}}>Report missing anomaly</a>
+            {{/unless}}
+
+            <div class="te-form__select te-form__select--same-line col-md-3">
+              {{!-- Rule selector --}}
+              {{#if isPreviewMode}}
+                {{#power-select
+                  triggerId="select-rule"
+                  triggerClass="te-form__select"
+                  options=ruleOptions
+                  searchEnabled=true
+                  searchPlaceholder="Type to filter..."
+                  matchTriggerWidth=false
+                  matchContentWidth=true
+                  selected=selectedRule
+                  onchange=(action "onSelectRule")
+                  as |rule|
+                }}
+                  {{rule}}
+                {{/power-select}}
+
+                {{!-- Dimension selector --}}
+                {{#if alertHasDimensions}}
+                  <div class="te-form__select te-form__select--margin-left">
+                    {{#power-select
+                      triggerId="select-dimension"
+                      triggerClass="te-form__select"
+                      options=dimensionOptions
+                      searchEnabled=true
+                      searchPlaceholder="Type to filter..."
+                      matchTriggerWidth=false
+                      matchContentWidth=true
+                      selected=selectedDimension
+                      onchange=(action "onSelectDimension")
+                      as |dimension|
+                    }}
+                      {{dimension}}
+                    {{/power-select}}
+                  </div>
+                {{/if}}
+              {{else}}
+                {{!-- Dimension selector --}}
+                {{#if alertHasDimensions}}
                   {{#power-select
                     triggerId="select-dimension"
                     triggerClass="te-form__select"
@@ -121,244 +151,225 @@
                   }}
                     {{dimension}}
                   {{/power-select}}
-                </div>
+                {{/if}}
               {{/if}}
-            {{else}}
-              {{!-- Dimension selector --}}
-              {{#if alertHasDimensions}}
-                {{#power-select
-                  triggerId="select-dimension"
-                  triggerClass="te-form__select"
-                  options=dimensionOptions
-                  searchEnabled=true
-                  searchPlaceholder="Type to filter..."
-                  matchTriggerWidth=false
-                  matchContentWidth=true
-                  selected=selectedDimension
-                  onchange=(action "onSelectDimension")
-                  as |dimension|
+            </div>
+
+            {{!-- Missing anomaly modal --}}
+            {{#te-modal
+              cancelButtonText="Cancel"
+              submitButtonText="Report"
+              submitAction=(action "onSave")
+              cancelAction=(action "onCancel")
+              isShowingModal=openReportModal
+              headerText="Report Undetected Anomaly"
+            }}
+              {{#if renderModalContent}}
+                {{alert-report-modal
+                  series=series
+                  colorMapping=colorMapping
+                  axis=axis
+                  zoom=zoom
+                  legend=legend
+                  metricName=alertData.metric
+                  alertName=alertData.detectionName
+                  predefinedRanges=predefinedRanges
+                  dimensionOptions=dimensionOptions
+                  selectedDimension=selectedDimension
+                  alertHasDimensions=alertHasDimensions
+                  isMetricDataLoading=isMetricDataLoading
+                  isMetricDataInvalid=isMetricDataInvalid
+                  inputAction=(action "onInputMissingAnomaly")
                 }}
-                  {{dimension}}
-                {{/power-select}}
+              {{else}}
+                {{ember-spinner}}
               {{/if}}
-            {{/if}}
-          </div>
+            {{/te-modal}}
 
-          {{!-- Missing anomaly modal --}}
-          {{#te-modal
-            cancelButtonText="Cancel"
-            submitButtonText="Report"
-            submitAction=(action "onSave")
-            cancelAction=(action "onCancel")
-            isShowingModal=openReportModal
-            headerText="Report Undetected Anomaly"
-          }}
-            {{#if renderModalContent}}
-              {{alert-report-modal
+            <div class="col-xs-12 te-graph-container">
+              {{#if isLoadingTimeSeries}}
+                <div class="spinner-wrapper spinner-wrapper--card">
+                  {{ember-spinner}}
+                </div>
+              {{/if}}
+              {{timeseries-chart
                 series=series
                 colorMapping=colorMapping
                 axis=axis
                 zoom=zoom
                 legend=legend
-                metricName=alertData.metric
-                alertName=alertData.detectionName
-                predefinedRanges=predefinedRanges
-                dimensionOptions=dimensionOptions
-                selectedDimension=selectedDimension
-                alertHasDimensions=alertHasDimensions
-                isMetricDataLoading=isMetricDataLoading
-                isMetricDataInvalid=isMetricDataInvalid
-                inputAction=(action "onInputMissingAnomaly")
+                point=point
               }}
-            {{else}}
-              {{ember-spinner}}
-            {{/if}}
-          {{/te-modal}}
-
-          <div class="col-xs-12 te-graph-container">
-            {{#if isLoadingTimeSeries}}
-              <div class="spinner-wrapper spinner-wrapper--card">
-                {{ember-spinner}}
-              </div>
-            {{/if}}
-            {{timeseries-chart
-              series=series
-              colorMapping=colorMapping
-              axis=axis
-              zoom=zoom
-              legend=legend
-              point=point
-            }}
-            {{#unless isPreviewMode}}
-              <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>
-            {{/unless}}
-        </div>
-        {{!-- Baseline type selector --}}
-        {{range-pill-selectors
-          title="Baseline"
-          timeRangeOptions=baselineOptions
-          selectAction=(action "onBaselineOptionClick")
-        }}
-          {{#if anomalies}}
+              {{#unless isPreviewMode}}
+                <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>
+              {{/unless}}
+          </div>
+          {{!-- Baseline type selector --}}
+          {{range-pill-selectors
+            title="Baseline"
+            timeRangeOptions=baselineOptions
+            selectAction=(action "onBaselineOptionClick")
+          }}
+            {{#if anomalies}}
 
-            {{!-- Alert anomaly table --}}
-            <div class="te-block-container">
-              <table class="te-anomaly-table">
-                {{#if anomalies}}
-                  <thead>
-                    <tr class="te-anomaly-table__row te-anomaly-table__head">
-                      <th class="te-anomaly-table__cell-head te-anomaly-table__cell-head--left">
-                        <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "start"}}>
-                          Start/Duration (PDT)
-                          <i class="te-anomaly-table__icon glyphicon {{if sortColumnStartUp "glyphicon-menu-up" "glyphicon-menu-down"}}"></i>
-                        </a>
-                      </th>
-                      {{#if alertHasDimensions}}
-                        <th class="te-anomaly-table__cell-head te-anomaly-table__cell-head--fixed">Dimensions</th>
-                      {{/if}}
-                      <th class="te-anomaly-table__cell-head">
-                        <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "change"}}>
-                          Current / Predicted
-                          <i class="te-anomaly-table__icon glyphicon {{if sortColumnChangeUp "glyphicon-menu-up" "glyphicon-menu-down"}}"></i>
-                        </a>
-                      </th>
-                      {{#unless isPreviewMode}}
+              {{!-- Alert anomaly table --}}
+              <div class="te-block-container">
+                <table class="te-anomaly-table">
+                  {{#if anomalies}}
+                    <thead>
+                      <tr class="te-anomaly-table__row te-anomaly-table__head">
+                        <th class="te-anomaly-table__cell-head te-anomaly-table__cell-head--left">
+                          <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "start"}}>
+                            Start/Duration (PDT)
+                            <i class="te-anomaly-table__icon glyphicon {{if sortColumnStartUp "glyphicon-menu-up" "glyphicon-menu-down"}}"></i>
+                          </a>
+                        </th>
+                        {{#if alertHasDimensions}}
+                          <th class="te-anomaly-table__cell-head te-anomaly-table__cell-head--fixed">Dimensions</th>
+                        {{/if}}
                         <th class="te-anomaly-table__cell-head">
-                          <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "feedback"}}>
-                            Feedback
-                            <i class="te-anomaly-table__icon glyphicon {{if sortColumnFeedbackUp "glyphicon-menu-up" "glyphicon-menu-down"}}"></i>
+                          <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "change"}}>
+                            Current / Predicted
+                            <i class="te-anomaly-table__icon glyphicon {{if sortColumnChangeUp "glyphicon-menu-up" "glyphicon-menu-down"}}"></i>
                           </a>
                         </th>
-                        <th class="te-anomaly-table__cell-head"></th>
-                      {{/unless}}
-                    </tr>
-                  </thead>
-                {{/if}}
-                <tbody>
-                  {{#each paginatedFilteredAnomalies as |anomaly|}}
-                    <tr class="te-anomaly-table__row">
-                       <td class="te-anomaly-table__cell">
-                        <ul class="te-anomaly-table__list te-anomaly-table__list--left">
-                          <li class="te-anomaly-table__list-item te-anomaly-table__list-item--stronger">
-                            {{#if isPreviewMode}}
-                              {{anomaly.startDateStr}}
-                            {{else}}
-                              <a target="_blank" class="te-anomaly-table__link" href="/app/#/rootcause?anomalyId={{anomaly.anomalyId}}">
-                                {{anomaly.startDateStr}}
-                              </a>
-                            {{/if}}
-                          </li>
-                          <li class="te-anomaly-table__list-item te-anomaly-table__list-item--lighter">{{anomaly.durationStr}}</li>
-                        </ul>
-                       </td>
-                       {{#if alertHasDimensions}}
+                        {{#unless isPreviewMode}}
+                          <th class="te-anomaly-table__cell-head">
+                            <a class="te-anomaly-table__cell-link" {{action "toggleSortDirection" "feedback"}}>
+                              Feedback
+                              <i class="te-anomaly-table__icon glyphicon {{if sortColumnFeedbackUp "glyphicon-menu-up" "glyphicon-menu-down"}}"></i>
+                            </a>
+                          </th>
+                          <th class="te-anomaly-table__cell-head"></th>
+                        {{/unless}}
+                      </tr>
+                    </thead>
+                  {{/if}}
+                  <tbody>
+                    {{#each paginatedFilteredAnomalies as |anomaly|}}
+                      <tr class="te-anomaly-table__row">
                          <td class="te-anomaly-table__cell">
-                          <ul class="te-anomaly-table__list">
-                           {{#each anomaly.dimensionList as |dimension|}}
-                              <li class="te-anomaly-table__list-item te-anomaly-table__list-item--smaller" title="{{dimension.dimensionVal}}">
-                                {{dimension}}: <span class="stronger">{{get anomaly.dimensions dimension}}</span>
-                              </li>
-                           {{else}}
-                              -
-                           {{/each}}
+                          <ul class="te-anomaly-table__list te-anomaly-table__list--left">
+                            <li class="te-anomaly-table__list-item te-anomaly-table__list-item--stronger">
+                              {{#if isPreviewMode}}
+                                {{anomaly.startDateStr}}
+                              {{else}}
+                                <a target="_blank" class="te-anomaly-table__link" href="/app/#/rootcause?anomalyId={{anomaly.anomalyId}}">
+                                  {{anomaly.startDateStr}}
+                                </a>
+                              {{/if}}
+                            </li>
+                            <li class="te-anomaly-table__list-item te-anomaly-table__list-item--lighter">{{anomaly.durationStr}}</li>
                           </ul>
                          </td>
-                       {{/if}}
-                       <td class="te-anomaly-table__cell">
-                        <ul class="te-anomaly-table__list">
-                          <li>{{anomaly.shownCurrent}} / {{anomaly.shownBaseline}}</li>
-                          <li class="te-anomaly-table__value-label te-anomaly-table__value-label--{{calculate-direction anomaly.shownChangeRate}}">
-                            {{#if (not anomaly.isNullChangeRate)}}
-                              ({{anomaly.shownChangeRate}}%)
-                            {{else}}
-                              (N/A)
-                            {{/if}}
-                          </li>
-                        </ul>
-                       </td>
-                       {{#unless isPreviewMode}}
+                         {{#if alertHasDimensions}}
+                           <td class="te-anomaly-table__cell">
+                            <ul class="te-anomaly-table__list">
+                             {{#each anomaly.dimensionList as |dimension|}}
+                                <li class="te-anomaly-table__list-item te-anomaly-table__list-item--smaller" title="{{dimension.dimensionVal}}">
+                                  {{dimension}}: <span class="stronger">{{get anomaly.dimensions dimension}}</span>
+                                </li>
+                             {{else}}
+                                -
+                             {{/each}}
+                            </ul>
+                           </td>
+                         {{/if}}
                          <td class="te-anomaly-table__cell">
-                            {{#if renderStatusIcon}}
-                              {{#if anomaly.showResponseSaved}}
-                                <i class="te-anomaly-table__icon--status glyphicon glyphicon-ok-circle"></i>
+                          <ul class="te-anomaly-table__list">
+                            <li>{{anomaly.shownCurrent}} / {{anomaly.shownBaseline}}</li>
+                            <li class="te-anomaly-table__value-label te-anomaly-table__value-label--{{calculate-direction anomaly.shownChangeRate}}">
+                              {{#if (not anomaly.isNullChangeRate)}}
+                                ({{anomaly.shownChangeRate}}%)
+                              {{else}}
+                                (N/A)
                               {{/if}}
-                              {{#if anomaly.showResponseFailed}}
-                                <i class="te-anomaly-table__icon--status te-anomaly-table__icon--error glyphicon glyphicon-remove-circle"></i>
+                            </li>
+                          </ul>
+                         </td>
+                         {{#unless isPreviewMode}}
+                           <td class="te-anomaly-table__cell">
+                              {{#if renderStatusIcon}}
+                                {{#if anomaly.showResponseSaved}}
+                                  <i class="te-anomaly-table__icon--status glyphicon glyphicon-ok-circle"></i>
+                                {{/if}}
+                                {{#if anomaly.showResponseFailed}}
+                                  <i class="te-anomaly-table__icon--status te-anomaly-table__icon--error glyphicon glyphicon-remove-circle"></i>
+                                {{/if}}
                               {{/if}}
-                            {{/if}}
 
-                            {{#if anomaly.isUserReported}}
-                              <div class="te-anomaly-table__text te-anomaly-table__text--explore">User Reported</div>
-                              <div class="te-anomaly-table__comment">
-                                <i class="glyphicon glyphicon-th-list"></i>
-                                {{#tooltip-on-element class="te-anomaly-table__tooltip"}}
-                                  {{anomaly.anomalyFeedbackComments}}
-                                {{/tooltip-on-element}}
+                              {{#if anomaly.isUserReported}}
+                                <div class="te-anomaly-table__text te-anomaly-table__text--explore">User Reported</div>
+                                <div class="te-anomaly-table__comment">
+                                  <i class="glyphicon glyphicon-th-list"></i>
+                                  {{#tooltip-on-element class="te-anomaly-table__tooltip"}}
+                                    {{anomaly.anomalyFeedbackComments}}
+                                  {{/tooltip-on-element}}
+                                </div>
+                              {{else}}
+                                {{#power-select
+                                  triggerId=anomaly.anomalyId
+                                  triggerClass="te-anomaly-table__select"
+                                  options=feedbackOptions
+                                  searchEnabled=false
+                                  selected=(get labelMap anomaly.anomalyFeedback)
+                                  onchange=(action "onChangeAnomalyFeedback" anomaly)
+                                  as |response|
+                                }}
+                                  {{response}}
+                                {{/power-select}}
+                              {{/if}}
+                           </td>
+                           <td class="te-anomaly-table__cell te-anomaly-table__cell--feedback">
+                              <div class="te-anomaly-table__link-wrapper">
+                                {{#link-to 'rootcause' (query-params anomalyId=anomaly.anomalyId) target="_blank" class="te-anomaly-table__link"}}
+                                  Investigate
+                                {{/link-to}}
                               </div>
-                            {{else}}
-                              {{#power-select
-                                triggerId=anomaly.anomalyId
-                                triggerClass="te-anomaly-table__select"
-                                options=feedbackOptions
-                                searchEnabled=false
-                                selected=(get labelMap anomaly.anomalyFeedback)
-                                onchange=(action "onChangeAnomalyFeedback" anomaly)
-                                as |response|
-                              }}
-                                {{response}}
-                              {{/power-select}}
-                            {{/if}}
-                         </td>
-                         <td class="te-anomaly-table__cell te-anomaly-table__cell--feedback">
-                            <div class="te-anomaly-table__link-wrapper">
-                              {{#link-to 'rootcause' (query-params anomalyId=anomaly.anomalyId) target="_blank" class="te-anomaly-table__link"}}
-                                Investigate
-                              {{/link-to}}
-                            </div>
-                         </td>
-                       {{/unless}}
-                    </tr>
-                  {{/each}}
-                </tbody>
-              </table>
-            </div>
+                           </td>
+                         {{/unless}}
+                      </tr>
+                    {{/each}}
+                  </tbody>
+                </table>
+              </div>
 
-            {{!--pagination--}}
-            {{#if (gt pagesNum 1)}}
-              <nav class="text-center" aria-label="Page navigation">
-                <ul class="pagination">
-                  <li class={{if (eq currentPage 1) 'active disabled'}} >
-                    <a href="#" {{action "onPaginationClick" 1}} aria-label="First">
-                      <span aria-hidden="true">First</span>
-                    </a>
-                  </li>
-                  <li class={{if (eq currentPage 1) 'active disabled'}}>
-                    <a href="#" {{action "onPaginationClick" "previous"}} aria-label="Previous">
-                      <span aria-hidden="true">Previous</span>
-                    </a>
-                  </li>
-                  {{#each viewPages as |page|}}
-                    <li class={{if (eq page currentPage) 'active'}}><a href="#" {{action "onPaginationClick" page}}>{{page}}</a></li>
-                  {{/each}}
-                  <li class={{if (eq currentPage pagesNum) 'disabled'}} >
-                    <a href="#" {{action "onPaginationClick" "next"}} aria-label="Next">
-                      <span aria-hidden="true">Next</span>
-                    </a>
-                  </li>
-                  <li class={{if (eq currentPage pagesNum) 'disabled'}} >
-                    <a href="#" {{action "onPaginationClick" pagesNum}} aria-label="Last">
-                      <span aria-hidden="true">Last</span>
-                    </a>
-                  </li>
-                </ul>
-              </nav>
+              {{!--pagination--}}
+              {{#if (gt pagesNum 1)}}
+                <nav class="text-center" aria-label="Page navigation">
+                  <ul class="pagination">
+                    <li class={{if (eq currentPage 1) 'active disabled'}} >
+                      <a href="#" {{action "onPaginationClick" 1}} aria-label="First">
+                        <span aria-hidden="true">First</span>
+                      </a>
+                    </li>
+                    <li class={{if (eq currentPage 1) 'active disabled'}}>
+                      <a href="#" {{action "onPaginationClick" "previous"}} aria-label="Previous">
+                        <span aria-hidden="true">Previous</span>
+                      </a>
+                    </li>
+                    {{#each viewPages as |page|}}
+                      <li class={{if (eq page currentPage) 'active'}}><a href="#" {{action "onPaginationClick" page}}>{{page}}</a></li>
+                    {{/each}}
+                    <li class={{if (eq currentPage pagesNum) 'disabled'}} >
+                      <a href="#" {{action "onPaginationClick" "next"}} aria-label="Next">
+                        <span aria-hidden="true">Next</span>
+                      </a>
+                    </li>
+                    <li class={{if (eq currentPage pagesNum) 'disabled'}} >
+                      <a href="#" {{action "onPaginationClick" pagesNum}} aria-label="Last">
+                        <span aria-hidden="true">Last</span>
+                      </a>
+                    </li>
+                  </ul>
+                </nav>
+              {{/if}}
             {{/if}}
-          {{/if}}
 
 
-              </div>
+                </div>
         {{else}}
         <div class="yaml-editor-msg">Alert configuration has changed.</div>
         {{/if}}
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/detection-yaml/component.js b/thirdeye/thirdeye-frontend/app/pods/components/detection-yaml/component.js
index bf60125..9121641 100644
--- a/thirdeye/thirdeye-frontend/app/pods/components/detection-yaml/component.js
+++ b/thirdeye/thirdeye-frontend/app/pods/components/detection-yaml/component.js
@@ -47,19 +47,6 @@ export default Component.extend({
 
 
 
-  /**
-   * sets Yaml value displayed to contents of detectionYaml or currentYamlAlertOriginal
-   * @method currentYamlAlert
-   * @return {String}
-   */
-  currentYamlAlert: computed(
-    'detectionYaml',
-    function() {
-      const inputYaml = get(this, 'detectionYaml');
-      return inputYaml || get(this, 'currentYamlAlertOriginal');
-    }
-  ),
-
   isDetectionMsg: computed(
     'detectionMsg',
     function() {
@@ -68,6 +55,17 @@ export default Component.extend({
     }
   ),
 
+  init() {
+    this._super(...arguments);
+    const {
+      detectionYaml,
+      currentYamlAlertOriginal
+    } = this.getProperties('detectionYaml', 'currentYamlAlertOriginal');
+    if (!detectionYaml) {
+      set(this, 'detectionYaml', currentYamlAlertOriginal);
+    }
+  },
+
   /**
    * Calls api's for specific metric's autocomplete
    * @method _loadAutocompleteById
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/detection-yaml/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/detection-yaml/template.hbs
index 742375f..108bb5c 100644
--- a/thirdeye/thirdeye-frontend/app/pods/components/detection-yaml/template.hbs
+++ b/thirdeye/thirdeye-frontend/app/pods/components/detection-yaml/template.hbs
@@ -29,7 +29,7 @@
 <div class="col-xs-12 {{if isEditMode "bottom-margin"}}">
   {{ember-ace
     lines=35
-    value=currentYamlAlert
+    value=detectionYaml
     suggestCompletions=(action 'yamlSuggestions')
     enableLiveAutocompletion=true
     update=(action "onEditingDetectionYamlAction")
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/subscription-yaml/component.js b/thirdeye/thirdeye-frontend/app/pods/components/subscription-yaml/component.js
index ba50299..ed49a1f 100644
--- a/thirdeye/thirdeye-frontend/app/pods/components/subscription-yaml/component.js
+++ b/thirdeye/thirdeye-frontend/app/pods/components/subscription-yaml/component.js
@@ -8,25 +8,24 @@
  * @property {function} updateSubscriptionYaml - bubble up the subscription group yaml to parent
  * @example
    {{subscription-yaml
-     subscriptionGroupId=model.subscriptionGroupId
      isEditMode=true
-     subscriptionGroupNames=model.subscriptionGroupNames
      subscriptionYaml=model.subscriptionYaml
-     setSubscriptionYaml=updateSubscriptionYaml
+     setSubscriptionYaml=(action "updateSubscriptionYaml")
+     subscriptionMsg={string} //Optional error message to surface
+     selectSubscriptionGroup=(action "changeSubscriptionGroup")
+     subscriptionGroupNamesDisplay=subscriptionGroupNamesDisplay
+     groupName=groupName
+     createGroup=createGroup // default group for reset
    }}
  * @authors lohuynh and hjackson
  */
 
 import Component from '@ember/component';
-import {computed, set, get, getProperties} from '@ember/object';
-import {yamlAlertSettings, toastOptions} from 'thirdeye-frontend/utils/constants';
-import fetch from 'fetch';
+import {computed, get, set} from '@ember/object';
+import {yamlAlertSettings} from 'thirdeye-frontend/utils/constants';
 import {inject as service} from '@ember/service';
-import {task} from 'ember-concurrency';
 import config from 'thirdeye-frontend/config/environment';
 
-const CREATE_GROUP_TEXT = 'Create a new subscription group';
-
 export default Component.extend({
   classNames: ['yaml-editor'],
   notifications: service('toast'),
@@ -45,94 +44,10 @@ export default Component.extend({
   showAnomalyModal: false,
   showNotificationModal: false,
   setSubscriptionYaml: null, // function passed in from parent
+  createGroup: null,
 
 
 
-  init() {
-    this._super(...arguments);
-    const subscriptionGroupNamesDisplay = get(this, 'subscriptionGroupNamesDisplay');
-    // Checks to make sure there is a subscription group array with at least one subscription group
-    if (subscriptionGroupNamesDisplay && Array.isArray(subscriptionGroupNamesDisplay) && subscriptionGroupNamesDisplay.length > 0) {
-      const firstGroup = subscriptionGroupNamesDisplay[0];
-      const setSubscriptionYaml = get(this, 'setSubscriptionYaml');
-      setSubscriptionYaml(firstGroup.yaml);
-      set(this, 'groupName', firstGroup);
-      set(this, 'subscriptionGroupId', firstGroup.id);
-    }
-  },
-
-  /**
-   * populates subscription group dropdown with options from fetch or model
-   * @method subscriptionGroupNamesDisplay
-   * @return {Object}
-   */
-  subscriptionGroupNamesDisplay: computed(
-    'subscriptionGroupNames',
-    async function() {
-      const {
-        isEditMode,
-        subscriptionGroupNames
-      } = this.getProperties('isEditMode', 'subscriptionGroupNames');
-      const createGroup = {
-        name: CREATE_GROUP_TEXT,
-        id: 'n/a',
-        yaml: yamlAlertSettings
-      };
-      const moddedArray = [createGroup];
-      if (isEditMode) {
-        return [...moddedArray, ...subscriptionGroupNames];
-      }
-      const subscriptionGroups = await get(this, '_fetchSubscriptionGroups').perform();
-      return [...moddedArray, ...subscriptionGroups];
-    }
-  ),
-
-  /**
-   * Flag to trigger special case of no existing subscription groups for an alert
-   * @method noExistingSubscriptionGroup
-   * @return {Boolean}
-   */
-  noExistingSubscriptionGroup: computed(
-    'subscriptionGroupNames',
-    function() {
-      const subscriptionGroupNames = get(this, 'subscriptionGroupNames');
-      if (subscriptionGroupNames && Array.isArray(subscriptionGroupNames) && subscriptionGroupNames.length > 0) {
-        return false;
-      }
-      return true;
-    }
-  ),
-
-  /**
-   * Change subscription group button text depending on whether creating or updating
-   * @method subGroupButtonText
-   * @return {String}
-   */
-  subGroupButtonText: computed(
-    'noExistingSubscriptionGroup',
-    'groupName',
-    function() {
-      const {
-        noExistingSubscriptionGroup,
-        groupName
-      } = this.getProperties('noExistingSubscriptionGroup', 'groupName');
-      return (noExistingSubscriptionGroup || !groupName || groupName.name === CREATE_GROUP_TEXT) ? "Create Group" : "Update Group";
-    }
-  ),
-
-  /**
-   * sets Yaml value displayed to contents of subscriptionYaml or currentYamlSettingsOriginal
-   * @method currentSubscriptionYaml
-   * @return {String}
-   */
-  currentSubscriptionYaml: computed(
-    'subscriptionYaml',
-    function() {
-      const subscriptionYaml = get(this, 'subscriptionYaml');
-      return subscriptionYaml || get(this, 'currentYamlSettingsOriginal');
-    }
-  ),
-
   isSubscriptionMsg: computed(
     'subscriptionMsg',
     function() {
@@ -141,72 +56,14 @@ export default Component.extend({
     }
   ),
 
-  _fetchSubscriptionGroups: task(function* () {
-    //dropdown of subscription groups
-    const url2 = `/detection/subscription-groups`;
-    const postProps2 = {
-      method: 'get',
-      headers: { 'content-type': 'application/json' }
-    };
-    const notifications = get(this, 'notifications');
-
-    try {
-      const response = yield fetch(url2, postProps2);
-      const json = yield response.json();
-      return json.filterBy('yaml');
-    } catch (error) {
-      notifications.error('Failed to retrieve subscription groups.', 'Error', toastOptions);
-    }
-  }).drop(),
-
-  // Method for handling subscription group, whether there are any or not
-  async _handleSubscriptionGroup(subscriptionYaml, notifications, subscriptionGroupId) {
+  init() {
+    this._super(...arguments);
     const {
-      noExistingSubscriptionGroup,
-      groupName
-    } = this.getProperties('noExistingSubscriptionGroup', 'groupName');
-    if (noExistingSubscriptionGroup || !groupName || groupName.name === CREATE_GROUP_TEXT) {
-      //POST settings
-      const setting_url = '/yaml/subscription';
-      const settingsPostProps = {
-        method: 'POST',
-        body: subscriptionYaml,
-        headers: { 'content-type': 'text/plain' }
-      };
-      try {
-        const settings_result = await fetch(setting_url, settingsPostProps);
-        const settings_status  = get(settings_result, 'status');
-        const settings_json = await settings_result.json();
-        if (settings_status !== 200) {
-          set(this, 'errorMsg', get(settings_json, 'message'));
-          notifications.error(`Failed to save the subscription configuration due to: ${settings_json.message}.`, 'Error', toastOptions);
-        } else {
-          notifications.success('Subscription configuration saved successfully', 'Done', toastOptions);
-        }
-      } catch (error) {
-        notifications.error('Error while saving subscription config.', error, toastOptions);
-      }
-    } else {
-      //PUT settings
-      const setting_url = `/yaml/subscription/${subscriptionGroupId}`;
-      const settingsPostProps = {
-        method: 'PUT',
-        body: subscriptionYaml,
-        headers: { 'content-type': 'text/plain' }
-      };
-      try {
-        const settings_result = await fetch(setting_url, settingsPostProps);
-        const settings_status  = get(settings_result, 'status');
-        const settings_json = await settings_result.json();
-        if (settings_status !== 200) {
-          set(this, 'errorMsg', get(settings_json, 'message'));
-          notifications.error(`Failed to save the subscription configuration due to: ${settings_json.message}.`, 'Error', toastOptions);
-        } else {
-          notifications.success('Subscription configuration saved successfully', 'Done', toastOptions);
-        }
-      } catch (error) {
-        notifications.error('Error while saving subscription config.', error, toastOptions);
-      }
+      subscriptionYaml,
+      currentYamlSettingsOriginal
+    } = this.getProperties('subscriptionYaml', 'currentYamlSettingsOriginal');
+    if (!subscriptionYaml) {
+      set(this, 'subscriptionYaml', currentYamlSettingsOriginal);
     }
   },
 
@@ -215,8 +72,13 @@ export default Component.extend({
      * resets given yaml field to default value for creation mode and server value for edit mode
      */
     resetYAML() {
-      const setSubscriptionYaml = get(this, 'setSubscriptionYaml');
-      setSubscriptionYaml(get(this, 'currentYamlSettingsOriginal'));
+      const {
+        selectSubscriptionGroup,
+        createGroup,
+        subscriptionGroupNamesDisplay,
+        isEditMode
+      } = this.getProperties('selectSubscriptionGroup', 'createGroup', 'subscriptionGroupNamesDisplay', 'isEditMode');
+      isEditMode ? selectSubscriptionGroup(createGroup) : selectSubscriptionGroup(subscriptionGroupNamesDisplay[0]);
     },
 
     /**
@@ -232,7 +94,6 @@ export default Component.extend({
     onEditingSubscriptionYamlAction(value) {
       const setSubscriptionYaml = get(this, 'setSubscriptionYaml');
       setSubscriptionYaml(value);
-      set(this, 'disableSubGroupSave', false);
     },
 
     /**
@@ -240,25 +101,9 @@ export default Component.extend({
      */
     onSubscriptionGroupSelectionAction(value) {
       if(value.yaml) {
-        const setSubscriptionYaml = get(this, 'setSubscriptionYaml');
-        setSubscriptionYaml(value.yaml);
-        set(this, 'groupName', value);
-        set(this, 'subscriptionGroupId', value.id);
+        const selectSubscriptionGroup = get(this, 'selectSubscriptionGroup');
+        selectSubscriptionGroup(value);
       }
-    },
-
-    /**
-     * Fired by subscription group button in YAML UI in edit mode
-     * Grabs subscription group yaml and posts or puts it to the backend.
-     */
-    async submitSubscriptionGroup() {
-      const {
-        subscriptionYaml,
-        notifications,
-        subscriptionGroupId
-      } = getProperties(this, 'subscriptionYaml', 'notifications', 'subscriptionGroupId');
-      // If there is no existing subscription group, this method will handle it
-      this._handleSubscriptionGroup(subscriptionYaml, notifications, subscriptionGroupId);
     }
   }
 });
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/subscription-yaml/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/subscription-yaml/template.hbs
index f3e9979..732bb5a 100644
--- a/thirdeye/thirdeye-frontend/app/pods/components/subscription-yaml/template.hbs
+++ b/thirdeye/thirdeye-frontend/app/pods/components/subscription-yaml/template.hbs
@@ -25,7 +25,7 @@
       defaultText="Reset"
       type="outline-primary"
       buttonType="reset"
-      onClick=(action "resetYAML" "subscription")
+      onClick=(action "resetYAML")
       class="te-button te-button--link"
     }}
     {{bs-button
@@ -41,7 +41,7 @@
   {{!-- subscription settings editor --}}
   {{ember-ace
     lines=25
-    value=currentSubscriptionYaml
+    value=subscriptionYaml
     update=(action "onEditingSubscriptionYamlAction")
     mode="ace/mode/yaml"
   }}
@@ -54,14 +54,3 @@
     </div>
   {{/if}}
 </div>
-
-{{#if isEditMode}}
-  {{bs-button
-      defaultText=subGroupButtonText
-      type="primary"
-      buttonType="submit"
-      disabled=disableSubGroupSave
-      onClick=(action "submitSubscriptionGroup")
-      class="te-button te-button--submit"
-    }}
-{{/if}}
diff --git a/thirdeye/thirdeye-frontend/app/pods/manage/yaml/controller.js b/thirdeye/thirdeye-frontend/app/pods/manage/yaml/controller.js
index 96ef85f..ba3e890 100644
--- a/thirdeye/thirdeye-frontend/app/pods/manage/yaml/controller.js
+++ b/thirdeye/thirdeye-frontend/app/pods/manage/yaml/controller.js
@@ -1,9 +1,161 @@
 /**
- * Controller for Alert Landing and Details Page
- * @module manage/alert
- * @exports manage/alert
+ * Controller for Edit Alert page
+ * @module manage/yaml/{alertId}
+ * @exports manage/yaml/{alertId}
  */
 import Controller from '@ember/controller';
+import {computed, set, get, getProperties} from '@ember/object';
+import {toastOptions} from 'thirdeye-frontend/utils/constants';
+import {inject as service} from '@ember/service';
+
+const CREATE_GROUP_TEXT = 'Create a new subscription group';
 
 export default Controller.extend({
+  notifications: service('toast'),
+  alertDataIsCurrent: true,
+  disableYamlSave: true,
+  toggleCollapsed: true,              // flag for the accordion that hides/shows preview
+  disableSubGroupSave: true,
+
+  /**
+   * Flag to trigger special case of no existing subscription groups for an alert
+   * @method noExistingSubscriptionGroup
+   * @return {Boolean}
+   */
+  noExistingSubscriptionGroup: computed(
+    'subscriptionGroupNames',
+    function() {
+      const subscriptionGroupNames = get(this, 'subscriptionGroupNames');
+      if (subscriptionGroupNames && Array.isArray(subscriptionGroupNames) && subscriptionGroupNames.length > 0) {
+        return false;
+      }
+      return true;
+    }
+  ),
+
+  /**
+   * Change subscription group button text depending on whether creating or updating
+   * @method subGroupButtonText
+   * @return {String}
+   */
+  subGroupButtonText: computed(
+    'noExistingSubscriptionGroup',
+    'groupName',
+    function() {
+      const {
+        noExistingSubscriptionGroup,
+        groupName
+      } = this.getProperties('noExistingSubscriptionGroup', 'groupName');
+      return (noExistingSubscriptionGroup || !groupName || groupName.name === CREATE_GROUP_TEXT) ? "Create Group" : "Update Group";
+    }
+  ),
+
+  // Method for handling subscription group, whether there are any or not
+  async _handleSubscriptionGroup(subscriptionYaml, notifications, subscriptionGroupId) {
+    const {
+      noExistingSubscriptionGroup,
+      groupName
+    } = this.getProperties('noExistingSubscriptionGroup', 'groupName');
+    if (noExistingSubscriptionGroup || !groupName || groupName.name === CREATE_GROUP_TEXT) {
+      //POST settings
+      const setting_url = '/yaml/subscription';
+      const settingsPostProps = {
+        method: 'POST',
+        body: subscriptionYaml,
+        headers: { 'content-type': 'text/plain' }
+      };
+      try {
+        const settings_result = await fetch(setting_url, settingsPostProps);
+        const settings_status  = get(settings_result, 'status');
+        const settings_json = await settings_result.json();
+        if (settings_status !== 200) {
+          set(this, 'errorMsg', get(settings_json, 'message'));
+          notifications.error(`Failed to save the subscription configuration due to: ${settings_json.message}.`, 'Error', toastOptions);
+        } else {
+          notifications.success('Subscription configuration saved successfully', 'Done', toastOptions);
+        }
+      } catch (error) {
+        notifications.error('Error while saving subscription config.', error, toastOptions);
+      }
+    } else {
+      //PUT settings
+      const setting_url = `/yaml/subscription/${subscriptionGroupId}`;
+      const settingsPostProps = {
+        method: 'PUT',
+        body: subscriptionYaml,
+        headers: { 'content-type': 'text/plain' }
+      };
+      try {
+        const settings_result = await fetch(setting_url, settingsPostProps);
+        const settings_status  = get(settings_result, 'status');
+        const settings_json = await settings_result.json();
+        if (settings_status !== 200) {
+          set(this, 'errorMsg', get(settings_json, 'message'));
+          notifications.error(`Failed to save the subscription configuration due to: ${settings_json.message}.`, 'Error', toastOptions);
+        } else {
+          notifications.success('Subscription configuration saved successfully', 'Done', toastOptions);
+        }
+      } catch (error) {
+        notifications.error('Error while saving subscription config.', error, toastOptions);
+      }
+    }
+  },
+
+  actions: {
+    changeAccordion() {
+      set(this, 'toggleCollapsed', !get(this, 'toggleCollapsed'));
+    },
+
+    /**
+     * update the detection yaml string
+     * @method updateDetectionYaml
+     * @return {undefined}
+     */
+    updateDetectionYaml(updatedYaml) {
+      this.setProperties({
+        detectionYaml: updatedYaml,
+        alertDataIsCurrent: false,
+        disableYamlSave: false
+      });
+    },
+
+    /**
+     * update the subscription yaml string  and activates 'create group' button
+     * @method updateSubscriptionYaml
+     * @return {undefined}
+     */
+    updateSubscriptionYaml(updatedYaml) {
+      this.setProperties({
+        disableSubGroupSave: false,
+        subscriptionYaml: updatedYaml
+      });
+    },
+
+    /**
+     * update the subscription group object for dropdown
+     * @method updateSubscriptionGroup
+     * @return {undefined}
+     */
+    changeSubscriptionGroup(group) {
+      this.setProperties({
+        subscriptionYaml: group.yaml,
+        groupName: group,
+        subscriptionGroupId: group.id
+      });
+    },
+
+    /**
+     * Fired by subscription group button in YAML UI in edit mode
+     * Grabs subscription group yaml and posts or puts it to the backend.
+     */
+    async submitSubscriptionGroup() {
+      const {
+        subscriptionYaml,
+        notifications,
+        subscriptionGroupId
+      } = getProperties(this, 'subscriptionYaml', 'notifications', 'subscriptionGroupId');
+      // If there is no existing subscription group, this method will handle it
+      this._handleSubscriptionGroup(subscriptionYaml, notifications, subscriptionGroupId);
+    }
+  }
 });
diff --git a/thirdeye/thirdeye-frontend/app/pods/manage/yaml/route.js b/thirdeye/thirdeye-frontend/app/pods/manage/yaml/route.js
index 301f823..dd99e62 100644
--- a/thirdeye/thirdeye-frontend/app/pods/manage/yaml/route.js
+++ b/thirdeye/thirdeye-frontend/app/pods/manage/yaml/route.js
@@ -9,10 +9,13 @@ import { set, get } from '@ember/object';
 import { inject as service } from '@ember/service';
 import yamljs from 'yamljs';
 import moment from 'moment';
-import { toastOptions } from 'thirdeye-frontend/utils/constants';
+import { yamlAlertSettings, toastOptions } from 'thirdeye-frontend/utils/constants';
 import { formatYamlFilter } from 'thirdeye-frontend/utils/utils';
 
+const CREATE_GROUP_TEXT = 'Create a new subscription group';
+
 export default Route.extend({
+  anomaliesApiService: service('services/api/anomalies'),
   notifications: service('toast'),
 
   async model(params) {
@@ -86,14 +89,58 @@ export default Route.extend({
       }
     }
 
+    const subscriptionGroupNames = await this.get('anomaliesApiService').querySubscriptionGroups(); // Get all subscription groups available
+
     return RSVP.hash({
       alertId,
       alertData: get(this, 'detectionInfo'),
       detectionYaml: get (this, 'rawDetectionYaml'),
       subscriptionGroups: get(this, 'subscriptionGroups'),
-      subscribedGroups
+      subscribedGroups,
+      subscriptionGroupNames // all subscription groups as Ember data
     });
   },
 
+  setupController(controller, model) {
+    const createGroup = {
+      name: CREATE_GROUP_TEXT,
+      id: 'n/a',
+      yaml: yamlAlertSettings
+    };
+    const moddedArray = [createGroup];
+    const subscriptionGroups = this.get('store')
+      .peekAll('subscription-groups')
+      .sortBy('name')
+      .filter(group => (group.get('active') && group.get('yaml')))
+      .map(group => {
+        return {
+          name: group.get('name'),
+          id: group.get('id'),
+          yaml: group.get('yaml')
+        };
+      });
+    const subscriptionGroupNamesDisplay = [
+      { groupName: 'Create Group', options: moddedArray },
+      { groupName: 'Subscribed Groups', options: model.subscriptionGroups },
+      { groupName: 'Other Groups', options: subscriptionGroups}
+    ];
+
+    let subscriptionYaml = yamlAlertSettings;
+    let groupName = createGroup;
+    let subscriptionGroupId = createGroup.id;
+
+    controller.setProperties({
+      alertId: model.alertId,
+      subscriptionGroupNames: model.subscriptionGroups,
+      subscriptionGroupNamesDisplay,
+      detectionYaml: model.detectionYaml,
+      groupName,
+      subscriptionGroupId,
+      subscriptionYaml,
+      model,
+      createGroup
+    });
+  }
+
 
 });
diff --git a/thirdeye/thirdeye-frontend/app/pods/manage/yaml/template.hbs b/thirdeye/thirdeye-frontend/app/pods/manage/yaml/template.hbs
index 22ce453..72ecccc 100644
--- a/thirdeye/thirdeye-frontend/app/pods/manage/yaml/template.hbs
+++ b/thirdeye/thirdeye-frontend/app/pods/manage/yaml/template.hbs
@@ -23,13 +23,65 @@
         <p class="te-alert-page-pending__text">{{errorText}}</p>
       </div>
     {{else}}
-      {{yaml-editor
-        alertId=model.alertId
-        isEditMode=true
-        showSettings=true
-        subscriptionGroupNames=model.subscriptionGroups
-        detectionYaml=model.detectionYaml
-      }}
+      <fieldset class="te-form__section te-form__section--first row">
+
+        {{#detection-yaml
+          isEditMode=true
+          alertId=model.alertId
+          detectionYaml=detectionYaml
+          setDetectionYaml=(action "updateDetectionYaml")
+          disableYamlSave=disableYamlSave
+        }}
+        {{/detection-yaml}}
+
+        <div class="col-xs-12">
+          {{#bs-accordion onChange=(action "changeAccordion") as |acc|}}
+            {{#acc.item value=preview as |aitem|}}
+              {{#aitem.title}}
+                <section class="dashboard-container__title thirdeye-link-secondary">Preview alert [Beta] {{if toggleCollapsed "/ Enter YAML configuration to preview alert." ""}}
+                  <span class="pull-right"><i class="glyphicon glyphicon-menu-{{if toggleCollapsed "down" "up"}}"></i></span>
+                </section>
+              {{/aitem.title}}
+              {{#aitem.body}}
+                {{#alert-details
+                  isPreviewMode=true
+                  alertYaml=detectionYaml
+                  dataIsCurrent=alertDataIsCurrent
+                }}
+                  {{yield}}
+                {{/alert-details}}
+              {{/aitem.body}}
+            {{/acc.item}}
+          {{/bs-accordion}}
+        </div>
+
+        <div class="col-xs-12">
+          <hr/>
+        </div>
+
+        {{#subscription-yaml
+          isEditMode=true
+          subscriptionYaml=subscriptionYaml
+          setSubscriptionYaml=(action "updateSubscriptionYaml")
+          subscriptionMsg=""
+          selectSubscriptionGroup=(action "changeSubscriptionGroup")
+          subscriptionGroupNamesDisplay=subscriptionGroupNamesDisplay
+          groupName=groupName
+          createGroup=createGroup
+        }}
+        {{/subscription-yaml}}
+
+      </fieldset>
+      <fieldset class="te-form__section-submit">
+        {{bs-button
+            defaultText=subGroupButtonText
+            type="primary"
+            buttonType="submit"
+            disabled=disableSubGroupSave
+            onClick=(action "submitSubscriptionGroup")
+            class="te-button te-button--submit"
+          }}
+      </fieldset>
     {{/if}}
   </div>
 </section>
diff --git a/thirdeye/thirdeye-frontend/app/pods/self-serve/create-alert/controller.js b/thirdeye/thirdeye-frontend/app/pods/self-serve/create-alert/controller.js
index 3a90c0a..6024fce 100644
--- a/thirdeye/thirdeye-frontend/app/pods/self-serve/create-alert/controller.js
+++ b/thirdeye/thirdeye-frontend/app/pods/self-serve/create-alert/controller.js
@@ -1076,6 +1076,18 @@ export default Controller.extend({
     },
 
     /**
+     * update the subscription group object for dropdown
+     * @method updateSubscriptionGroup
+     * @return {undefined}
+     */
+    changeSubscriptionGroup(group) {
+      this.setProperties({
+        subscriptionYaml: group.yaml,
+        groupName: group
+      });
+    },
+
+    /**
      * Fired by create button in YAML UI
      * Grabs YAML content and sends it
      */
diff --git a/thirdeye/thirdeye-frontend/app/pods/self-serve/create-alert/route.js b/thirdeye/thirdeye-frontend/app/pods/self-serve/create-alert/route.js
index e0e7339..24d3a02 100644
--- a/thirdeye/thirdeye-frontend/app/pods/self-serve/create-alert/route.js
+++ b/thirdeye/thirdeye-frontend/app/pods/self-serve/create-alert/route.js
@@ -5,22 +5,18 @@
  */
 import fetch from 'fetch';
 import { hash } from 'rsvp';
-import moment from 'moment';
 import Route from '@ember/routing/route';
-import { task, timeout } from 'ember-concurrency';
-import {
-  selfServeApiCommon,
-  selfServeApiOnboard
-} from 'thirdeye-frontend/utils/api/self-serve';
+import { selfServeApiOnboard } from 'thirdeye-frontend/utils/api/self-serve';
 import { postProps, checkStatus } from 'thirdeye-frontend/utils/utils';
 import { inject as service } from '@ember/service';
-import { get } from '@ember/object';
+import { yamlAlertSettings } from 'thirdeye-frontend/utils/constants';
 
-let onboardStartTime = {};
+const CREATE_GROUP_TEXT = 'Create a new subscription group';
 
 export default Route.extend({
   anomaliesApiService: service('services/api/anomalies'),
   session: service(),
+  store: service('store'),
 
   /**
    * Model hook for the create alert route.
@@ -39,6 +35,42 @@ export default Route.extend({
     });
   },
 
+  setupController(controller, model) {
+    const createGroup = {
+      name: CREATE_GROUP_TEXT,
+      id: 'n/a',
+      yaml: yamlAlertSettings
+    };
+    const moddedArray = [createGroup];
+    const subscriptionGroups = this.get('store')
+      .peekAll('subscription-groups')
+      .sortBy('name')
+      .filter(group => (group.get('active') && group.get('yaml')))
+      .map(group => {
+        return {
+          name: group.get('name'),
+          id: group.get('id'),
+          yaml: group.get('yaml')
+        };
+      });
+    const subscriptionGroupNamesDisplay = [...moddedArray, ...subscriptionGroups];
+    let subscriptionYaml = yamlAlertSettings;
+    let groupName = createGroup;
+    if (subscriptionGroupNamesDisplay && Array.isArray(subscriptionGroupNamesDisplay) && subscriptionGroupNamesDisplay.length > 0) {
+      const firstGroup = subscriptionGroupNamesDisplay[0];
+      subscriptionYaml = firstGroup.yaml;
+      groupName = firstGroup;
+    }
+
+    controller.setProperties({
+      subscriptionGroupNames: model.subscriptionGroups,
+      subscriptionGroupNamesDisplay,
+      groupName,
+      subscriptionYaml,
+      model
+    });
+  },
+
   /**
    * Model hook for the create alert route.
    * @method resetController
@@ -114,7 +146,7 @@ export default Route.extend({
     * @method triggerReplaySequence
     */
     triggerOnboardingJob(data) {
-      const { ignore, payload } = data;
+      const { payload } = data;
       const jobName = payload.functionName;
 
       fetch(selfServeApiOnboard.updateAlert(jobName), postProps(payload))
@@ -128,7 +160,7 @@ export default Route.extend({
             this.jumpToAlertPage(result.jobId, null);
           }
         })
-        .catch((err) => {
+        .catch(() => {
           // Error state will be handled on alert page
           this.jumpToAlertPage(-1, jobName);
         });
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 504c5e5..98b8072 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
@@ -464,6 +464,10 @@
         isEditMode=false
         subscriptionYaml=subscriptionYaml
         setSubscriptionYaml=(action "updateSubscriptionYaml")
+        subscriptionMsg=""
+        selectSubscriptionGroup=(action "changeSubscriptionGroup")
+        subscriptionGroupNamesDisplay=subscriptionGroupNamesDisplay
+        groupName=groupName
       }}
       {{/subscription-yaml}}
 


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