AMBARI-18912. Implement Create Alerts: step 1 select alert type.(XIWANG)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/31ce5f7d Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/31ce5f7d Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/31ce5f7d Branch: refs/heads/branch-feature-AMBARI-18634 Commit: 31ce5f7d3d087af5d0f03f295fe5d680a6ee453d Parents: e73e783 Author: Xi Wang <xiw...@apache.org> Authored: Wed Nov 16 18:31:35 2016 -0800 Committer: Xi Wang <xiw...@apache.org> Committed: Tue Nov 22 14:21:01 2016 -0800 ---------------------------------------------------------------------- .../add_alert_definition/step1_controller.js | 41 ++++++------- .../alerts/definition_configs_controller.js | 40 ++++++------- ambari-web/app/messages.js | 17 ++++-- .../app/models/alerts/alert_definition.js | 54 ++++++++++++++++++ ambari-web/app/styles/alerts.less | 60 ++++++++++++++++++++ .../main/alerts/add_alert_definition/step1.hbs | 30 +++++----- .../alerts/add_alert_definition/step1_view.js | 3 + .../step1_controller_test.js | 24 +------- 8 files changed, 186 insertions(+), 83 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/31ce5f7d/ambari-web/app/controllers/main/alerts/add_alert_definition/step1_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/alerts/add_alert_definition/step1_controller.js b/ambari-web/app/controllers/main/alerts/add_alert_definition/step1_controller.js index 2d4f338..c758fc0 100644 --- a/ambari-web/app/controllers/main/alerts/add_alert_definition/step1_controller.js +++ b/ambari-web/app/controllers/main/alerts/add_alert_definition/step1_controller.js @@ -24,34 +24,25 @@ App.AddAlertDefinitionStep1Controller = Em.Controller.extend({ /** * List of available alert definition types - * @type {{value: string, isActive: boolean}[]} + * @type {{name: string, isActive: boolean}[]} */ - alertDefinitionsTypes: [ - Em.Object.create({value: 'PORT', isActive: false, icon: 'glyphicon glyphicon-signal'}), - Em.Object.create({value: 'METRIC', isActive: false, icon: 'icon-bolt'}), - Em.Object.create({value: 'WEB', isActive: false, icon: 'glyphicon glyphicon-globe'}), - Em.Object.create({value: 'AGGREGATE', isActive: false, icon: 'glyphicon glyphicon-plus-sign-alt'}), - Em.Object.create({value: 'SCRIPT', isActive: false, icon: 'glyphicon glyphicon-code'}), - Em.Object.create({value: 'SERVER', isActive: false, icon: 'glyphicon glyphicon-desktop'}), - Em.Object.create({value: 'RECOVERY', isActive: false, icon: 'glyphicon glyphicon-desktop'}) - ], - - /** - * "Next"-button is disabled if user doesn't select any alert definition type - * @type {boolean} - */ - isSubmitDisabled: Em.computed.everyBy('alertDefinitionsTypes', 'isActive', false), + alertDefinitionsTypes: function () { + return App.AlertType.find().map(function(option) { + return Em.Object.create({ + name: option.get('name'), + displayName: option.get('displayName'), + icon: option.get('iconPath'), + description: option.get('description') + }); + }); + }.property(), /** * Set selectedType if it exists in the wizard controller * @method loadStep */ loadStep: function() { - this.get('alertDefinitionsTypes').setEach('isActive', false); - var selectedType = this.get('content.selectedType'); - if(selectedType) { - this.selectType({context: {value: selectedType}}); - } + this.set('content.selectedType', ''); }, /** @@ -61,10 +52,10 @@ App.AddAlertDefinitionStep1Controller = Em.Controller.extend({ */ selectType: function(e) { var type = e.context, - types = this.get('alertDefinitionsTypes'); - types.setEach('isActive', false); - types.findProperty('value', type.value).set('isActive', true); - this.set('content.selectedType', type.value); + types = this.get('alertDefinitionsTypes'); + this.set('content.selectedType', type.name); + $("[rel='selectable-tooltip']").trigger('mouseleave'); + App.router.send('next'); } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/31ce5f7d/ambari-web/app/controllers/main/alerts/definition_configs_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/alerts/definition_configs_controller.js b/ambari-web/app/controllers/main/alerts/definition_configs_controller.js index 4c82556..138aaa4 100644 --- a/ambari-web/app/controllers/main/alerts/definition_configs_controller.js +++ b/ambari-web/app/controllers/main/alerts/definition_configs_controller.js @@ -225,7 +225,7 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({ var result = []; var alertDefinition = this.get('content'); var isWizard = this.get('isWizard'); - var units = this.get('content.reporting').findProperty('type','units') ? + var units = this.get('content.reporting') && this.get('content.reporting').findProperty('type','units') ? this.get('content.reporting').findProperty('type','units').get('text'): null; if (this.get('isWizard')) { @@ -256,7 +256,7 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({ value: isWizard ? '' : this.getThresholdsProperty('critical', 'value') }), App.AlertConfigProperties.Parameter.create({ - value: alertDefinition.get('uri.connectionTimeout'), + value: isWizard ? '': alertDefinition.get('uri.connectionTimeout'), threshold: "CRITICAL", name: 'connection_timeout', label: 'Connection Timeout', @@ -311,7 +311,7 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({ value: isWizard ? '' : this.getThresholdsProperty('critical', 'value') }), App.AlertConfigProperties.Parameter.create({ - value: alertDefinition.get('uri.connectionTimeout'), + value: isWizard ? '': alertDefinition.get('uri.connectionTimeout'), threshold: "CRITICAL", name: 'connection_timeout', label: 'Connection Timeout', @@ -404,7 +404,7 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({ valueMetric: units }), App.AlertConfigProperties.Parameter.create({ - value: alertDefinition.get('uri.connectionTimeout'), + value: isWizard ? '': alertDefinition.get('uri.connectionTimeout'), name: 'connection_timeout', label: 'Connection Timeout', displayType: 'parameter', @@ -447,20 +447,22 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({ NUMERIC: App.AlertConfigProperties.Parameters.NumericMixin, PERCENT: App.AlertConfigProperties.Parameters.PercentageMixin }; - alertDefinition.get('parameters').forEach(function (parameter) { - var mixin = mixins[parameter.get('type')] || {}; // validation depends on parameter-type - result.push(App.AlertConfigProperties.Parameter.create(mixin, { - value: isWizard ? '' : parameter.get('value'), - apiProperty: parameter.get('name'), - description: parameter.get('description'), - label: isWizard ? '' : parameter.get('displayName'), - threshold: isWizard ? '' : parameter.get('threshold'), - units: isWizard ? '' : parameter.get('units'), - type: isWizard ? '' : parameter.get('type'), - hidden: parameter.get('visibility') === "HIDDEN", - readonly: parameter.get('visibility') === "READ_ONLY" - })); - }); + if (alertDefinition) { + alertDefinition.get('parameters').forEach(function (parameter) { + var mixin = mixins[parameter.get('type')] || {}; // validation depends on parameter-type + result.push(App.AlertConfigProperties.Parameter.create(mixin, { + value: isWizard ? '' : parameter.get('value'), + apiProperty: parameter.get('name'), + description: parameter.get('description'), + label: isWizard ? '' : parameter.get('displayName'), + threshold: isWizard ? '' : parameter.get('threshold'), + units: isWizard ? '' : parameter.get('units'), + type: isWizard ? '' : parameter.get('type'), + hidden: parameter.get('visibility') === "HIDDEN", + readonly: parameter.get('visibility') === "READ_ONLY" + })); + }); + } return result; }, @@ -473,7 +475,7 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({ renderAggregateConfigs: function () { var isWizard = this.get('isWizard'); var alertDefinition = this.get('content'); - var units = this.get('content.reporting').findProperty('type','units') ? + var units = this.get('content.reporting') && this.get('content.reporting').findProperty('type','units') ? this.get('content.reporting').findProperty('type','units').get('text'): null; return [ App.AlertConfigProperties.Description.create({ http://git-wip-us.apache.org/repos/asf/ambari/blob/31ce5f7d/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index 7ba19db..aa4e2aa 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -1073,12 +1073,21 @@ Em.I18n.translations = { 'form.validator.alertNotificationName':'Invalid Alert Notification Name. Only alphanumerics, hyphens, spaces and underscores are allowed.', 'form.validator.configKey.specific':'"{0}" is invalid Key. Only alphanumerics, hyphens, underscores, asterisks and periods are allowed.', - 'alerts.add.header': 'Create Alert Definition', - 'alerts.add.step1.header': 'Choose Type', - 'alerts.add.step2.header': 'Configure', - 'alerts.add.step3.header': 'Review', + 'alerts.add.header': 'Create Alert', + 'alerts.add.step1.header': 'Choose Alert Type', + 'alerts.add.step1.header.description': 'Select the type of alert you want to create', + 'alerts.add.step2.header': 'Define Alert', + 'alerts.add.step3.header': 'Specify Threshold', 'alerts.add.step3.selectedType': 'Selected Type', + 'alerts.add.wizard.step1.body.choose.tooltip': 'Click to select', + 'alerts.add.wizard.step1.body.port.description':'Check TCP connectivity to a remote endpoint', + 'alerts.add.wizard.step1.body.web.description':'Check for TCP connectivity and verify that a proper HTTP response code was returned', + 'alerts.add.wizard.step1.body.metric.description':'Define JMX/AMS endpoints that can be queried for values', + 'alerts.add.wizard.step1.body.script.description':'Defer all functionality to a Python script accessible to the Ambari agents from a specified relative or absolute path', + 'alerts.add.wizard.step1.body.aggregate.description':'Combine the results of another alert definition from different nodes', + 'alerts.add.wizard.step1.body.raw.description':'User can upload alert parameter using a JSON script', + 'alerts.fastAccess.popup.header': '{0} Critical or Warning Alerts', 'alerts.fastAccess.popup.body.name': 'Alert Definition Name', 'alerts.fastAccess.popup.body.showmore': 'Go to Alerts Definitions', http://git-wip-us.apache.org/repos/asf/ambari/blob/31ce5f7d/ambari-web/app/models/alerts/alert_definition.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/alerts/alert_definition.js b/ambari-web/app/models/alerts/alert_definition.js index a3c8850..5d61112 100644 --- a/ambari-web/app/models/alerts/alert_definition.js +++ b/ambari-web/app/models/alerts/alert_definition.js @@ -325,3 +325,57 @@ App.AlertMetricsSourceDefinition.FIXTURES = []; App.AlertMetricsUriDefinition.FIXTURES = []; App.AlertMetricsAmsDefinition.FIXTURES = []; App.AlertDefinitionParameter.FIXTURES = []; + + +App.AlertType = DS.Model.extend({ + name: DS.attr('string'), + displayName: DS.attr('string'), + iconPath: DS.attr('string'), + description: DS.attr('string'), + properties: DS.attr('array') +}); + +App.AlertType.FIXTURES = [ + { + id: 'PORT', + name: 'PORT', + icon_path: 'glyphicon glyphicon-log-in', + display_name: 'Port', + description: Em.I18n.t('alerts.add.wizard.step1.body.port.description') + }, + { + id: 'WEB', + name: 'WEB', + icon_path: 'glyphicon glyphicon-globe', + display_name: 'Web', + description: Em.I18n.t('alerts.add.wizard.step1.body.web.description') + }, + { + id: 'METRIC', + name: 'METRIC', + display_name: 'Metric', + icon_path: 'glyphicon glyphicon-flash', + description: Em.I18n.t('alerts.add.wizard.step1.body.metric.description') + }, + { + id: 'SCRIPT', + name: 'SCRIPT', + icon_path: 'glyphicon glyphicon-file', + display_name: 'Script', + description: Em.I18n.t('alerts.add.wizard.step1.body.script.description') + }, + { + id: 'AGGREGATE', + name: 'AGGREGATE', + icon_path: 'glyphicon glyphicon-plus', + display_name: 'Aggregate', + description: Em.I18n.t('alerts.add.wizard.step1.body.aggregate.description') + }, + { + id: 'RAW', + name: 'RAW', + icon_path: 'glyphicon glyphicon-align-justify', + display_name: 'Raw', + description: Em.I18n.t('alerts.add.wizard.step1.body.raw.description') + } +]; http://git-wip-us.apache.org/repos/asf/ambari/blob/31ce5f7d/ambari-web/app/styles/alerts.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/alerts.less b/ambari-web/app/styles/alerts.less index f12393d..bf3eaf3 100644 --- a/ambari-web/app/styles/alerts.less +++ b/ambari-web/app/styles/alerts.less @@ -581,3 +581,63 @@ margin: 7px; } } + +/***** Start styles for alert create wizard *****/ +#create-alert-wizard-step1 { + .alert-types-container { + padding: 10px 15px; + .alert-type { + height: 150px; + width: 32%; + margin: 5px; + padding: 10px; + background: white; + } + .alert-type:hover { + cursor: pointer; + } + .icon { + .glyphicon { + font-size: 35px; + line-height: 3.5; + } + } + .icon.PORT { + color: #F6D955; + } + .icon.WEB { + color: #9ADCD4; + } + .icon.METRIC { + color: #F69F79; + } + .icon.SCRIPT { + color: #F2C2AA; + } + .icon.AGGREGATE { + color: #8AD4C7; + } + .icon.RAW { + color: #C9A6B2; + } + .label-description { + padding-top: 10px; + .label-text { + font-size: 14px; + font-weight: bold; + margin-bottom: 5px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + .description-text { + font-size: 12px; + overflow: hidden; + text-overflow: ellipsis; + } + } + } +} + +/***** End styles for alert create wizard *****/ + http://git-wip-us.apache.org/repos/asf/ambari/blob/31ce5f7d/ambari-web/app/templates/main/alerts/add_alert_definition/step1.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/alerts/add_alert_definition/step1.hbs b/ambari-web/app/templates/main/alerts/add_alert_definition/step1.hbs index ee61648..6617164 100644 --- a/ambari-web/app/templates/main/alerts/add_alert_definition/step1.hbs +++ b/ambari-web/app/templates/main/alerts/add_alert_definition/step1.hbs @@ -16,20 +16,22 @@ * limitations under the License. }} -<div class="wizard-content col-md-9"> +<div id="create-alert-wizard-step1" class="wizard-content col-md-9"> <h4 class="step-title">{{t alerts.add.step1.header}}</h4> - <div class="panel panel-default"> - <div class="panel-body"> - {{#each type in controller.alertDefinitionsTypes}} - <a href="#" {{bindAttr class=":btn type.isActive:active"}} {{action selectType type target="controller"}}> - <span {{bindAttr class="type.icon"}}></span> {{type.value}} - </a> - {{/each}} + <p class="step-description">{{t alerts.add.step1.header.description}}</p> + <div class="alert-types-container row"> + {{#each type in controller.alertDefinitionsTypes}} + <div class="col-md-4 row alert-type" rel="selectable-tooltip" + {{translateAttr data-original-title="alerts.add.wizard.step1.body.choose.tooltip"}} + {{action "selectType" type target="controller"}}> + <div {{bindAttr class="type.name :icon :col-md-3"}}> + <span {{bindAttr class="type.icon"}}></span> + </div> + <div class="label-description col-md-9"> + <p class="label-text">{{type.displayName}}</p> + <p class="description-text">{{type.description}}</p> + </div> + </div> + {{/each}} </div> - </div> -</div> -<div class="wizard-footer col-md-12"> - <div class="btn-area"> - <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action next}}>{{t common.next}} →</a> - </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/31ce5f7d/ambari-web/app/views/main/alerts/add_alert_definition/step1_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/alerts/add_alert_definition/step1_view.js b/ambari-web/app/views/main/alerts/add_alert_definition/step1_view.js index d55d20f..398d721 100644 --- a/ambari-web/app/views/main/alerts/add_alert_definition/step1_view.js +++ b/ambari-web/app/views/main/alerts/add_alert_definition/step1_view.js @@ -24,6 +24,9 @@ App.AddAlertDefinitionStep1View = Em.View.extend({ didInsertElement: function() { this.get('controller').loadStep(); + Em.run.later(this, function () { + App.tooltip($("[rel='selectable-tooltip']")); + }, 300); } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/31ce5f7d/ambari-web/test/controllers/main/alerts/add_alert_definition/step1_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/alerts/add_alert_definition/step1_controller_test.js b/ambari-web/test/controllers/main/alerts/add_alert_definition/step1_controller_test.js index 322c08a..7d19239 100644 --- a/ambari-web/test/controllers/main/alerts/add_alert_definition/step1_controller_test.js +++ b/ambari-web/test/controllers/main/alerts/add_alert_definition/step1_controller_test.js @@ -30,13 +30,13 @@ describe('App.AddAlertDefinitionStep1Controller', function () { describe('#selectType', function() { beforeEach(function () { - controller.get('alertDefinitionsTypes').setEach('isActive', false); + controller.get('content').set('selectedType', ''); }); it('should set isActive for selected type', function () { var e = {context: {value: 'PORT'}}; controller.selectType(e); - expect(controller.get('alertDefinitionsTypes').findProperty('value', 'PORT').get('isActive')).to.be.true; + expect(controller.get('content.selectedType')).to.equal('PORT'); }); }); @@ -45,30 +45,12 @@ describe('App.AddAlertDefinitionStep1Controller', function () { beforeEach(function () { controller.set('content.selectedType', 'PORT'); - }); it('should set predefined type', function () { controller.loadStep(); - expect(controller.get('alertDefinitionsTypes').findProperty('value', 'PORT').get('isActive')).to.be.true; - }); - - }); - - describe('#isSubmitDisabled', function () { - - beforeEach(function () { - controller.get('alertDefinitionsTypes').setEach('isActive', false); - }); - - it('should be based on isActive', function () { - - expect(controller.get('isSubmitDisabled')).to.be.true; - controller.get('alertDefinitionsTypes').objectAt(0).set('isActive', true); - expect(controller.get('isSubmitDisabled')).to.be.false; - + expect(controller.get('content.selectedType').to.equal('')); }); }); - }); \ No newline at end of file