Repository: ambari Updated Branches: refs/heads/trunk e148fca5a -> 00f7a6a61
AMBARI-8631. Provide assigning Alert Groups for Alert Notifications in Alert Notifications popup. (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/00f7a6a6 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/00f7a6a6 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/00f7a6a6 Branch: refs/heads/trunk Commit: 00f7a6a61cdffb9e6bc0b3055332aa40e84c3a57 Parents: e148fca Author: Oleg Nechiporenko <onechipore...@apache.org> Authored: Wed Dec 10 14:37:46 2014 +0200 Committer: Oleg Nechiporenko <onechipore...@apache.org> Committed: Wed Dec 10 16:17:20 2014 +0200 ---------------------------------------------------------------------- .../manage_alert_notifications_controller.js | 48 +++--- ambari-web/app/mappers/alert_groups_mapper.js | 6 +- ambari-web/app/messages.js | 1 + ambari-web/app/styles/alerts.less | 11 ++ .../main/alerts/create_alert_notification.hbs | 40 +++-- .../alerts/manage_alert_notifications_view.js | 2 +- ...anage_alert_notifications_controller_test.js | 154 ++++++++++++------- .../test/mappers/alert_groups_mapper_test.js | 12 +- 8 files changed, 185 insertions(+), 89 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/00f7a6a6/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js b/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js index d53b816..5984421 100644 --- a/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js +++ b/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js @@ -172,16 +172,18 @@ App.ManageAlertNotificationsController = Em.Controller.extend({ /** * Load all Alert Notifications from server - * Don't do anything if controller not isLoaded - * @returns {$.ajax|null} + * @method loadAlertNotifications */ loadAlertNotifications: function () { + var self = this; this.set('isLoaded', false); - return App.ajax.send({ - name: 'alerts.notifications', - sender: this, - success: 'getAlertNotificationsSuccessCallback', - error: 'getAlertNotificationsErrorCallback' + App.router.get('updateController').updateAlertGroups(function () { + App.ajax.send({ + name: 'alerts.notifications', + sender: self, + success: 'getAlertNotificationsSuccessCallback', + error: 'getAlertNotificationsErrorCallback' + }); }); }, @@ -278,7 +280,15 @@ App.ManageAlertNotificationsController = Em.Controller.extend({ controller: this, templateName: require('templates/main/alerts/create_alert_notification'), + /** + * @type {string} + */ + tooltipForGlobalCheckbox: function () { + return isEdit ? '' : Em.I18n.t('alerts.actions.manage_alert_notifications_popup.global.tooltip'); + }.property(), + didInsertElement: function () { + App.tooltip($('.checkbox-tooltip')); this.nameValidation(); }, @@ -291,6 +301,7 @@ App.ManageAlertNotificationsController = Em.Controller.extend({ }.observes('controller.inputFields.name.value'), groupsSelectView: Em.Select.extend({ + attributeBindings: ['disabled'], init: function () { this._super(); this.set('parentView.groupSelect', this); @@ -300,11 +311,15 @@ App.ManageAlertNotificationsController = Em.Controller.extend({ groupSelect: null, selectAllGroups: function () { - this.set('groupSelect.selection', this.get('groupSelect.content').slice()); + if (!this.get('controller.inputFields.global.value')) { + this.set('groupSelect.selection', this.get('groupSelect.content').slice()); + } }, clearAllGroups: function () { - this.set('groupSelect.selection', []); + if (!this.get('controller.inputFields.global.value')) { + this.set('groupSelect.selection', []); + } }, severitySelectView: Em.Select.extend({ @@ -357,7 +372,6 @@ App.ManageAlertNotificationsController = Em.Controller.extend({ formatNotificationAPIObject: function () { var inputFields = this.get('inputFields'); var properties = {}; - var clusterId = App.Cluster.find().objectAt(0).get('id'); if (inputFields.get('method.value') === 'EMAIL') { properties['ambari.dispatch.recipients'] = inputFields.get('email.value').replace(/\s/g, '').split(','); properties['mail.smtp.host'] = inputFields.get('SMTPServer.value'); @@ -372,24 +386,20 @@ App.ManageAlertNotificationsController = Em.Controller.extend({ inputFields.get('customProperties').forEach(function (customProperty) { properties[customProperty.name] = customProperty.value; }); - return { + var apiObject = { AlertTarget: { name: inputFields.get('name.value'), description: inputFields.get('description.value'), global: inputFields.get('global.value'), - groups: inputFields.get('groups.value').map(function (group) { - return { - name: group.get('name'), - id: group.get('id'), - default: group.get('default'), - cluster_id: clusterId - }; - }), notification_type: inputFields.get('method.value'), alert_states: inputFields.get('severityFilter.value'), properties: properties } }; + if (!inputFields.get('global.value')) { + apiObject.AlertTarget.groups = inputFields.get('groups.value').mapProperty('id'); + } + return apiObject; }, /** http://git-wip-us.apache.org/repos/asf/ambari/blob/00f7a6a6/ambari-web/app/mappers/alert_groups_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/alert_groups_mapper.js b/ambari-web/app/mappers/alert_groups_mapper.js index ff44e21..0060a15 100644 --- a/ambari-web/app/mappers/alert_groups_mapper.js +++ b/ambari-web/app/mappers/alert_groups_mapper.js @@ -31,7 +31,11 @@ App.alertGroupsMapper = App.QuickDataMapper.create({ id: 'AlertGroup.id', name: 'AlertGroup.name', default: 'AlertGroup.default', - targets: 'AlertGroup.targets' + targets_key: 'AlertGroup.targets', + targets_type: 'array', + targets: { + item: 'id' + } }, /** http://git-wip-us.apache.org/repos/asf/ambari/blob/00f7a6a6/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index 1d074e7..e16ab9c 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -1902,6 +1902,7 @@ Em.I18n.translations = { 'alerts.actions.manage_alert_notifications_popup.community':'Community', 'alerts.actions.manage_alert_notifications_popup.port':'Port', 'alerts.actions.manage_alert_notifications_popup.global':'Global', + 'alerts.actions.manage_alert_notifications_popup.global.tooltip':'Check this checkbox to make the notification apply globally to all groups defined in Ambari', 'alerts.actions.manage_alert_notifications_popup.severityFilter':'Severity Filter', 'alerts.actions.manage_alert_notifications_popup.clearAll':'Clear All', 'alerts.actions.manage_alert_notifications_popup.selectAll':'Select All', http://git-wip-us.apache.org/repos/asf/ambari/blob/00f7a6a6/ambari-web/app/styles/alerts.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/alerts.less b/ambari-web/app/styles/alerts.less index cf813d1..6c026e7 100644 --- a/ambari-web/app/styles/alerts.less +++ b/ambari-web/app/styles/alerts.less @@ -416,6 +416,17 @@ .add-custom-property { margin-left: 140px; } + + a { + &.disabled { + cursor: default; + color: gray; + &:hover { + text-decoration: none; + } + } + } + } .create-edit-alert-notification-popup { http://git-wip-us.apache.org/repos/asf/ambari/blob/00f7a6a6/ambari-web/app/templates/main/alerts/create_alert_notification.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/alerts/create_alert_notification.hbs b/ambari-web/app/templates/main/alerts/create_alert_notification.hbs index 5c264ca..a7e3f1a 100644 --- a/ambari-web/app/templates/main/alerts/create_alert_notification.hbs +++ b/ambari-web/app/templates/main/alerts/create_alert_notification.hbs @@ -20,6 +20,8 @@ <form class="form-horizontal"> + + {{! alert-notification name }} <div class="control-group"> <label class="control-label" for="inputName">{{controller.inputFields.name.label}}</label> @@ -27,29 +29,38 @@ {{view Em.TextField valueBinding="controller.inputFields.name.value" id="inputName" class="input-xlarge"}} </div> </div> + {{! alert-notification name end }} + {{! alert-notification is global }} <div class="control-group"> - <label class="control-label" for="inputGroups">{{controller.inputFields.groups.label}}</label> + <label class="control-label" for="inputGlobal">{{controller.inputFields.global.label}}</label> <div class="controls"> - {{view view.groupsSelectView multiple="true" id="inputGroups" class="input-large" - selectionBinding="controller.inputFields.groups.value" - contentBinding="controller.allAlertGroups" - optionLabelPath="content.displayName" - }} - <a href="#" {{action selectAllGroups target="view"}}>{{t alerts.actions.manage_alert_notifications_popup.selectAll}}</a> | - <a href="#" {{action clearAllGroups target="view"}}>{{t alerts.actions.manage_alert_notifications_popup.clearAll}}</a> + <span class="checkbox-tooltip" {{bindAttr data-original-title="view.tooltipForGlobalCheckbox"}}> + {{view Em.Checkbox checkedBinding="controller.inputFields.global.value" disabledBinding="controller.inputFields.global.disabled" id="inputGlobal" class="input-xlarge"}} + </span> </div> </div> + {{! alert-notification is global end }} + {{! alert-notification groups }} <div class="control-group"> - <label class="control-label" for="inputGlobal">{{controller.inputFields.global.label}}</label> + <label class="control-label" for="inputGroups">{{controller.inputFields.groups.label}}</label> <div class="controls"> - {{view Em.Checkbox checkedBinding="controller.inputFields.global.value" disabledBinding="controller.inputFields.global.disabled" id="inputGlobal" class="input-xlarge"}} + {{view view.groupsSelectView multiple="true" id="inputGroups" class="input-large" + disabledBinding="controller.inputFields.global.value" + selectionBinding="controller.inputFields.groups.value" + contentBinding="controller.allAlertGroups" + optionLabelPath="content.displayName" + }} + <a href="#" {{action selectAllGroups target="view"}} {{bindAttr class="controller.inputFields.global.value:disabled"}}>{{t alerts.actions.manage_alert_notifications_popup.selectAll}}</a> | + <a href="#" {{action clearAllGroups target="view"}} {{bindAttr class="controller.inputFields.global.value:disabled"}}>{{t alerts.actions.manage_alert_notifications_popup.clearAll}}</a> </div> </div> + {{! alert-notification groups end }} + {{! alert-notification severity }} <div class="control-group"> <label class="control-label">{{controller.inputFields.severityFilter.label}}</label> @@ -62,7 +73,9 @@ <a href="#" {{action clearAllSeverity target="view"}}>{{t alerts.actions.manage_alert_notifications_popup.clearAll}}</a> </div> </div> + {{! alert-notification severity end }} + {{! alert-notification description }} <div class="control-group"> <label class="control-label" for="inputDescription">{{controller.inputFields.description.label}}</label> @@ -70,7 +83,9 @@ {{view Em.TextArea valueBinding="controller.inputFields.description.value" id="inputDescription" rows="4" class="input-xlarge"}} </div> </div> + {{! alert-notification description end }} + {{! alert-notification method }} <div class="control-group"> <label class="control-label" for="inputMethod">{{controller.inputFields.method.label}}</label> @@ -78,7 +93,9 @@ {{view Em.Select contentBinding="controller.methods" selectionBinding="controller.inputFields.method.value" id="inputMethod" class="input-xlarge"}} </div> </div> + {{! alert-notification method end }} + {{! alert-notification email }} {{#if view.isEmailMethodSelected}} <div class="control-group"> <label class="control-label" for="inputEmail">{{controller.inputFields.email.label}}</label> @@ -138,7 +155,9 @@ </div> </div> {{/if}} + {{! alert-notification email end }} + {{! alert-notification custom properties }} {{#each customProperty in controller.inputFields.customProperties}} <div class="control-group"> <label class="control-label" for="inputGroups">{{customProperty.name}}</label> @@ -149,6 +168,7 @@ </div> </div> {{/each}} + {{! alert-notification custom properties end }} <a href="#" class="add-custom-property" {{action addCustomPropertyHandler target="controller"}}>{{t installer.step7.config.addProperty}} ...</a> http://git-wip-us.apache.org/repos/asf/ambari/blob/00f7a6a6/ambari-web/app/views/main/alerts/manage_alert_notifications_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/alerts/manage_alert_notifications_view.js b/ambari-web/app/views/main/alerts/manage_alert_notifications_view.js index 51dee4a..cb88925 100644 --- a/ambari-web/app/views/main/alerts/manage_alert_notifications_view.js +++ b/ambari-web/app/views/main/alerts/manage_alert_notifications_view.js @@ -29,7 +29,7 @@ App.ManageAlertNotificationsView = Em.View.extend({ selectedAlertNotificationGroups: function () { return this.get('controller.selectedAlertNotification.groups').toArray().mapProperty('displayName').join(', '); - }.property('controller.selectedAlertNotification'), + }.property('controller.selectedAlertNotification', 'controller.selectedAlertNotification.groups.@each', 'controller.isLoaded'), isEditButtonDisabled: true, http://git-wip-us.apache.org/repos/asf/ambari/blob/00f7a6a6/ambari-web/test/controllers/main/alerts/manage_alert_notifications_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/alerts/manage_alert_notifications_controller_test.js b/ambari-web/test/controllers/main/alerts/manage_alert_notifications_controller_test.js index e36c417..f40f515 100644 --- a/ambari-web/test/controllers/main/alerts/manage_alert_notifications_controller_test.js +++ b/ambari-web/test/controllers/main/alerts/manage_alert_notifications_controller_test.js @@ -64,7 +64,6 @@ describe('App.ManageAlertNotificationsController', function () { controller.set('isLoaded', true); controller.loadAlertNotifications(); expect(controller.get('isLoaded')).to.be.false; - expect(App.ajax.send.calledOnce).to.be.true; }); }); @@ -277,75 +276,113 @@ describe('App.ManageAlertNotificationsController', function () { describe("#showCreateEditPopup()", function () { - before(function () { - sinon.stub(App.ModalPopup, 'show', function () { - return 'popup'; - }); + beforeEach(function () { + sinon.spy(App.ModalPopup, 'show'); }); - after(function () { + afterEach(function () { App.ModalPopup.show.restore(); }); it("should open popup and set popup object to createEditPopup", function () { - controller.set('createEditPopup', null); - controller.showCreateEditPopup(); - expect(App.ModalPopup.show.calledOnce).to.be.true; - expect(controller.get('createEditPopup')).to.equal('popup'); + }); - }); + describe('#bodyClass', function () { - describe("#formatNotificationAPIObject()", function () { + var view; + + beforeEach(function () { + + view = controller.showCreateEditPopup().get('bodyClass').create({ + controller: Em.Object.create({ + inputFields: { + global: {} + } + }), + groupSelect: Em.Object.create({ + selection: [], + content: [{}, {}] + }) + }); + + }); + + describe('#selectAllGroups', function () { + + it('should check inputFields.global.value', function () { + + view.set('controller.inputFields.global.value', true); + view.selectAllGroups(); + expect(view.get('groupSelect.selection')).to.eql([]); + + view.set('controller.inputFields.global.value', false); + view.selectAllGroups(); + expect(view.get('groupSelect.selection')).to.eql([{}, {}]); + + }); + + }); + + describe('#clearAllGroups', function () { + + it('should check inputFields.global.value', function () { + + view.set('controller.inputFields.global.value', false); + view.selectAllGroups(); + + view.set('controller.inputFields.global.value', true); + view.clearAllGroups(); + expect(view.get('groupSelect.selection')).to.eql([{}, {}]); + + view.set('controller.inputFields.global.value', false); + view.clearAllGroups(); + expect(view.get('groupSelect.selection')).to.eql([]); + + }); - beforeEach(function(){ - sinon.stub(App.Cluster, 'find', function () { - return { - objectAt: function () { - return Em.Object.create({ - id: 1 - }) - } - } }); + }); - afterEach(function() { - App.Cluster.find.restore(); + }); + + describe("#formatNotificationAPIObject()", function () { + + var inputFields = Em.Object.create({ + name: { + value: 'test_name' + }, + groups: { + value: [{id: 1}, {id: 2}, {id: 3}] + }, + global: { + value: false + }, + method: { + value: 'EMAIL' + }, + email: { + value: 'te...@test.test, te...@test.test,te...@test.test , te...@test.test' + }, + severityFilter: { + value: ['OK', 'CRITICAL'] + }, + description: { + value: 'test_description' + }, + customProperties: [ + {name: 'n1', value: 'v1'}, + {name: 'n2', value: 'v2'} + ] }); it("should create object with properties from inputFields values", function () { - controller.set('inputFields', Em.Object.create({ - name: { - value: 'test_name' - }, - groups: { - value: [] - }, - global: { - value: false - }, - method: { - value: 'EMAIL' - }, - email: { - value: 'te...@test.test, te...@test.test,te...@test.test , te...@test.test' - }, - severityFilter: { - value: ['OK', 'CRITICAL'] - }, - description: { - value: 'test_description' - }, - customProperties: [ - {name: 'n1', value: 'v1'}, - {name: 'n2', value: 'v2'} - ] - })); + controller.set('inputFields', inputFields); var result = controller.formatNotificationAPIObject(); @@ -354,7 +391,6 @@ describe('App.ManageAlertNotificationsController', function () { name: 'test_name', description: 'test_description', global: false, - groups: [], notification_type: 'EMAIL', alert_states: ['OK', 'CRITICAL'], properties: { @@ -366,11 +402,22 @@ describe('App.ManageAlertNotificationsController', function () { ], 'n1': 'v1', 'n2': 'v2' - } + }, + groups: [1,2,3] } })); }); + it('should ignore groups if global is true', function () { + + controller.set('inputFields', inputFields); + controller.set('inputFields.global.value', true); + + var result = controller.formatNotificationAPIObject(); + expect(Em.keys(result.AlertTarget)).to.not.contain('groups'); + + }); + }); describe('#createAlertNotification()', function () { @@ -608,5 +655,4 @@ describe('App.ManageAlertNotificationsController', function () { }); -}); - +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/00f7a6a6/ambari-web/test/mappers/alert_groups_mapper_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/mappers/alert_groups_mapper_test.js b/ambari-web/test/mappers/alert_groups_mapper_test.js index 09b169f..f21f694 100644 --- a/ambari-web/test/mappers/alert_groups_mapper_test.js +++ b/ambari-web/test/mappers/alert_groups_mapper_test.js @@ -40,7 +40,8 @@ describe('App.alertGroupsMapper', function () { } ], "id" : 3, - "name" : "ZOOKEEPER" + "name" : "ZOOKEEPER", + "targets": [{id: 1}, {id: 2}] } }, { @@ -77,7 +78,8 @@ describe('App.alertGroupsMapper', function () { } ], "id" : 2, - "name" : "YARN" + "name" : "YARN", + "targets": [{id: 2}, {id: 3}] } } ] @@ -115,7 +117,8 @@ describe('App.alertGroupsMapper', function () { metrics_alert_definitions: [], web_alert_definitions: [], aggregate_alert_definitions: [9], - script_alert_definitions: [] + script_alert_definitions: [], + targets: [1, 2] }, { id: 2, @@ -125,7 +128,8 @@ describe('App.alertGroupsMapper', function () { metrics_alert_definitions: [1, 5], web_alert_definitions: [2, 3, 7], aggregate_alert_definitions: [4], - script_alert_definitions: [6] + script_alert_definitions: [6], + targets: [2, 3] } ];