Return-Path: X-Original-To: apmail-ambari-commits-archive@www.apache.org Delivered-To: apmail-ambari-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 741C7C43F for ; Tue, 23 Dec 2014 14:45:20 +0000 (UTC) Received: (qmail 75289 invoked by uid 500); 23 Dec 2014 14:45:20 -0000 Delivered-To: apmail-ambari-commits-archive@ambari.apache.org Received: (qmail 75259 invoked by uid 500); 23 Dec 2014 14:45:20 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 75250 invoked by uid 99); 23 Dec 2014 14:45:20 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 23 Dec 2014 14:45:20 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id F0598A3540C; Tue, 23 Dec 2014 14:45:19 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: onechiporenko@apache.org To: commits@ambari.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: ambari git commit: AMBARI-8881. Create Alert Group popup should be modal (onechiporenko) Date: Tue, 23 Dec 2014 14:45:19 +0000 (UTC) Repository: ambari Updated Branches: refs/heads/trunk 5704491c2 -> 8cf3fa11b AMBARI-8881. Create Alert Group popup should be modal (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/8cf3fa11 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/8cf3fa11 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/8cf3fa11 Branch: refs/heads/trunk Commit: 8cf3fa11b8e325fb1fe323f210136591724119ce Parents: 5704491 Author: Oleg Nechiporenko Authored: Tue Dec 23 16:45:06 2014 +0200 Committer: Oleg Nechiporenko Committed: Tue Dec 23 16:45:06 2014 +0200 ---------------------------------------------------------------------- .../alerts/manage_alert_groups_controller.js | 460 ++++++++++--------- ambari-web/app/views.js | 1 + .../select_definitions_popup_body_view.js | 133 ++++++ .../manage_alert_groups_controller_test.js | 64 +-- 4 files changed, 417 insertions(+), 241 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/8cf3fa11/ambari-web/app/controllers/main/alerts/manage_alert_groups_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/alerts/manage_alert_groups_controller.js b/ambari-web/app/controllers/main/alerts/manage_alert_groups_controller.js index 6d273cf..373569c 100644 --- a/ambari-web/app/controllers/main/alerts/manage_alert_groups_controller.js +++ b/ambari-web/app/controllers/main/alerts/manage_alert_groups_controller.js @@ -16,22 +16,38 @@ * limitations under the License. */ - var App = require('app'); + var validator = require('utils/validator'); var numberUtils = require('utils/number_utils'); App.ManageAlertGroupsController = Em.Controller.extend({ + name: 'manageAlertGroupsController', + /** + * @type {boolean} + */ isLoaded: false, + /** + * @type {App.AlertGroup[]} + */ alertGroups: [], + /** + * @type {App.AlertGroup[]} + */ originalAlertGroups: [], + /** + * @type {App.AlertGroup} + */ selectedAlertGroup: null, + /** + * @type {App.AlertDefinition[]} + */ selectedDefinitions: [], /** @@ -39,8 +55,8 @@ App.ManageAlertGroupsController = Em.Controller.extend({ * @type {App.AlertNotification[]} */ alertNotifications: function () { - return this.get('isLoaded') ? App.AlertNotification.find().map (function (target) { - return Em.Object.create ({ + return this.get('isLoaded') ? App.AlertNotification.find().map(function (target) { + return Em.Object.create({ name: target.get('name'), id: target.get('id'), description: target.get('description'), @@ -59,8 +75,86 @@ App.ManageAlertGroupsController = Em.Controller.extend({ }.property('alertNotifications'), /** + * @type {boolean} + */ + isRemoveButtonDisabled: true, + + /** + * @type {boolean} + */ + isRenameButtonDisabled: true, + + /** + * @type {boolean} + */ + isDuplicateButtonDisabled: true, + + /** + * @type {boolean} + */ + isDeleteDefinitionsDisabled: function () { + var selectedGroup = this.get('selectedAlertGroup'); + return selectedGroup ? (selectedGroup.default || this.get('selectedDefinitions').length === 0) : true; + }.property('selectedAlertGroup', 'selectedAlertGroup.definitions.length', 'selectedDefinitions.length'), + + /** + * observes if any group changed including: group name, newly created group, deleted group, group with definitions/notifications changed + * @type {{toDelete: App.AlertGroup[], toSet: App.AlertGroup[], toCreate: App.AlertGroup[]}} + */ + defsModifiedAlertGroups: function () { + if (!this.get('isLoaded')) { + return false; + } + var groupsToDelete = []; + var groupsToSet = []; + var groupsToCreate = []; + var groups = this.get('alertGroups'); //current alert groups + var originalGroups = this.get('originalAlertGroups'); // original alert groups + var originalGroupsIds = originalGroups.mapProperty('id'); + groups.forEach(function (group) { + var originalGroup = originalGroups.findProperty('id', group.get('id')); + if (originalGroup) { + // should update definitions or notifications + if (!(JSON.stringify(group.get('definitions').slice().sort()) === JSON.stringify(originalGroup.get('definitions').slice().sort())) + || !(JSON.stringify(group.get('notifications').slice().sort()) === JSON.stringify(originalGroup.get('notifications').slice().sort()))) { + groupsToSet.push(group.set('id', originalGroup.get('id'))); + } else if (group.get('name') !== originalGroup.get('name')) { + // should update name + groupsToSet.push(group.set('id', originalGroup.get('id'))); + } + originalGroupsIds = originalGroupsIds.without(group.get('id')); + } else { + // should add new group + groupsToCreate.push(group); + } + }); + // should delete groups + originalGroupsIds.forEach(function (id) { + groupsToDelete.push(originalGroups.findProperty('id', id)); + }, this); + return { + toDelete: groupsToDelete, + toSet: groupsToSet, + toCreate: groupsToCreate + }; + }.property('selectedAlertGroup.definitions.@each', 'selectedAlertGroup.definitions.length', 'selectedAlertGroup.notifications.@each', 'selectedAlertGroup.notifications.length', 'alertGroups', 'isLoaded'), + + /** + * Determines if some group was edited/created/deleted + * @type {boolean} + */ + isDefsModified: function () { + var modifiedGroups = this.get('defsModifiedAlertGroups'); + if (!this.get('isLoaded')) { + return false; + } + return !!(modifiedGroups.toSet.length || modifiedGroups.toCreate.length || modifiedGroups.toDelete.length); + }.property('defsModifiedAlertGroups'), + + /** * Load all Alert Notifications from server - * @returns {$.ajax|null} + * @returns {$.ajax} + * @method loadAlertNotifications */ loadAlertNotifications: function () { this.set('isLoaded', false); @@ -98,11 +192,12 @@ App.ManageAlertGroupsController = Em.Controller.extend({ /** * Load all alert groups from alert group model + * @method loadAlertGroups */ loadAlertGroups: function () { var alertGroups = App.AlertGroup.find().map(function (group) { - var definitions = group.get('definitions').map (function (def) { - return Em.Object.create ({ + var definitions = group.get('definitions').map(function (def) { + return Em.Object.create({ name: def.get('name'), serviceName: def.get('serviceName'), componentName: def.get('componentName'), @@ -113,8 +208,8 @@ App.ManageAlertGroupsController = Em.Controller.extend({ }); }); - var targets = group.get('targets').map (function (target) { - return Em.Object.create ({ + var targets = group.get('targets').map(function (target) { + return Em.Object.create({ name: target.get('name'), id: target.get('id'), description: target.get('description'), @@ -150,21 +245,6 @@ App.ManageAlertGroupsController = Em.Controller.extend({ }, /** - * @type {boolean} - */ - isRemoveButtonDisabled: true, - - /** - * @type {boolean} - */ - isRenameButtonDisabled: true, - - /** - * @type {boolean} - */ - isDuplicateButtonDisabled: true, - - /** * Enable/disable "Remove"/"Rename"/"Duplicate" buttons basing on controller.selectedAlertGroup * @method buttonObserver */ @@ -176,13 +256,16 @@ App.ManageAlertGroupsController = Em.Controller.extend({ this.set('isDuplicateButtonDisabled', false); }.observes('selectedAlertGroup'), - resortAlertGroup: function() { - var alertGroups = Ember.copy(this.get('alertGroups')); - if(alertGroups.length < 2){ + /** + * @method resortAlertGroup + */ + resortAlertGroup: function () { + var alertGroups = Em.copy(this.get('alertGroups')); + if (alertGroups.length < 2) { return; } var defaultGroups = alertGroups.filterProperty('default'); - defaultGroups.forEach( function(defaultGroup) { + defaultGroups.forEach(function (defaultGroup) { alertGroups.removeObject(defaultGroup); }); var sorted = defaultGroups.sortProperty('name').concat(alertGroups.sortProperty('name')); @@ -194,6 +277,7 @@ App.ManageAlertGroupsController = Em.Controller.extend({ /** * remove definitions from group + * @method deleteDefinitions */ deleteDefinitions: function () { if (this.get('isDeleteDefinitionsDisabled')) { @@ -206,17 +290,12 @@ App.ManageAlertGroupsController = Em.Controller.extend({ this.set('selectedDefinitions', []); }, - isDeleteDefinitionsDisabled: function () { - var selectedGroup = this.get('selectedAlertGroup'); - if (selectedGroup) { - return selectedGroup.default || this.get('selectedDefinitions').length === 0; - } - return true; - }.property('selectedAlertGroup', 'selectedAlertGroup.definitions.length', 'selectedDefinitions.length'), - /** * Provides alert definitions which are available for inclusion in * non-default alert groups. + * @param {App.AlertGroup} selectedAlertGroup + * @method getAvailableDefinitions + * @return {{name: string, serviceName: string, componentName: string, serviceNameDisplay: string, componentNameDisplay: string, label: string, id: number}[]} */ getAvailableDefinitions: function (selectedAlertGroup) { if (selectedAlertGroup.get('default')) return []; @@ -232,8 +311,8 @@ App.ManageAlertGroupsController = Em.Controller.extend({ availableDefinitions.pushObject(shared_def); } }); - return availableDefinitions.map (function (def) { - return Em.Object.create ({ + return availableDefinitions.map(function (def) { + return Em.Object.create({ name: def.get('name'), serviceName: def.get('serviceName'), componentName: def.get('componentName'), @@ -247,9 +326,10 @@ App.ManageAlertGroupsController = Em.Controller.extend({ /** * add alert definitions to a group + * @method addDefinitions */ addDefinitions: function () { - if (this.get('selectedAlertGroup.isAddDefinitionsDisabled')){ + if (this.get('selectedAlertGroup.isAddDefinitionsDisabled')) { return false; } var availableDefinitions = this.getAvailableDefinitions(this.get('selectedAlertGroup')); @@ -271,20 +351,37 @@ App.ManageAlertGroupsController = Em.Controller.extend({ selected: false }); }); - this.launchDefsSelectionDialog (availableDefinitions, [], validServices, validComponents, this.addDefinitionsCallback.bind(this), popupDescription); + this.launchDefsSelectionDialog(availableDefinitions, [], validServices, validComponents, this.addDefinitionsCallback.bind(this), popupDescription); }, /** * Launch a table view of all available definitions to choose + * @method launchDefsSelectionDialog + * @return {App.ModalPopup} */ - launchDefsSelectionDialog : function(initialDefs, selectedDefs, validServices, validComponents, callback, popupDescription) { + launchDefsSelectionDialog: function (initialDefs, selectedDefs, validServices, validComponents, callback, popupDescription) { + + return App.ModalPopup.show({ - App.ModalPopup.show({ classNames: [ 'sixty-percent-width-modal' ], + header: popupDescription.header, + + /** + * @type {string} + */ dialogMessage: popupDescription.dialogMessage, + + /** + * @type {string|null} + */ warningMessage: null, + + /** + * @type {App.AlertDefinition[]} + */ availableDefs: [], + onPrimary: function () { this.set('warningMessage', null); var arrayOfSelectedDefs = this.get('availableDefs').filterProperty('selected', true); @@ -296,114 +393,36 @@ App.ManageAlertGroupsController = Em.Controller.extend({ console.debug('(new-selectedDefs)=', arrayOfSelectedDefs); this.hide(); }, + + /** + * Primary button should be disabled while alert definitions are not loaded + * @type {boolean} + */ disablePrimary: function () { return !this.get('isLoaded'); }.property('isLoaded'), + onSecondary: function () { callback(null); this.hide(); }, - bodyClass: App.TableView.extend({ - templateName: require('templates/main/alerts/add_definition_to_group_popup'), - controllerBinding: 'App.router.manageAlertGroupsController', - isPaginate: true, - filteredContent: function() { - return this.get('parentView.availableDefs').filterProperty('filtered') || []; - }.property('parentView.availableDefs.@each.filtered'), - - showOnlySelectedDefs: false, + + bodyClass: App.SelectDefinitionsPopupBodyView.extend({ + filterComponents: validComponents, + filterServices: validServices, - filterComponent: null, - filterService: null, - isDisabled: function () { - return !this.get('parentView.isLoaded'); - }.property('parentView.isLoaded'), - didInsertElement: function(){ - initialDefs.setEach('filtered', true); - this.set('parentView.availableDefs', initialDefs); - this.set('parentView.isLoaded', true); - }, - filterDefs: function () { - var showOnlySelectedDefs = this.get('showOnlySelectedDefs'); - var filterComponent = this.get('filterComponent'); - var filterService = this.get('filterService'); - this.get('parentView.availableDefs').forEach(function (defObj) { - var componentOnObj = true; - var serviceOnObj = true; - if (filterComponent) { - componentOnObj = (defObj.componentName == filterComponent.get('componentName')); - } - if (defObj.serviceName && filterService) { - serviceOnObj = (defObj.serviceName == filterService.get('serviceName')); - } - if (showOnlySelectedDefs) { - defObj.set('filtered', componentOnObj && serviceOnObj && defObj.get('selected')); - } else { - defObj.set('filtered', componentOnObj && serviceOnObj); - } - }, this); - this.set('startIndex', 1); - }.observes('parentView.availableDefs', 'filterService', 'filterService.serviceName', 'filterComponent', 'filterComponent.componentName', 'showOnlySelectedDefs'), - defSelectMessage: function () { - var defs = this.get('parentView.availableDefs'); - var selectedDefs = defs.filterProperty('selected', true); - return this.t('alerts.actions.manage_alert_groups_popup.selectDefsDialog.selectedDefsLink').format(selectedDefs.get('length'), defs.get('length')); - }.property('parentView.availableDefs.@each.selected'), - - selectFilterComponent: function (event) { - if (event != null && event.context != null && event.context.componentName != null) { - var currentFilter = this.get('filterComponent'); - if (currentFilter != null) { - currentFilter.set('selected', false); - } - if (currentFilter != null && currentFilter.componentName === event.context.componentName) { - // selecting the same filter deselects it. - this.set('filterComponent', null); - } else { - this.set('filterComponent', event.context); - event.context.set('selected', true); - } - } - }, - selectFilterService: function (event) { - if (event != null && event.context != null && event.context.serviceName != null) { - var currentFilter = this.get('filterService'); - if (currentFilter != null) { - currentFilter.set('selected', false); - } - if (currentFilter != null && currentFilter.serviceName === event.context.serviceName) { - // selecting the same filter deselects it. - this.set('filterService', null); - } else { - this.set('filterService', event.context); - event.context.set('selected', true); - } - } - }, - allDefsSelected: false, - toggleSelectAllDefs: function (event) { - this.get('parentView.availableDefs').filterProperty('filtered').setEach('selected', this.get('allDefsSelected')); - }.observes('allDefsSelected'), - toggleShowSelectedDefs: function () { - var filter1 = this.get('filterComponent'); - if (filter1 != null) { - filter1.set('selected', false); - } - var filter2 = this.get('filterService'); - if (filter2 != null) { - filter2.set('selected', false); - } - this.set('filterComponent', null); - this.set('filterService', null); - this.set('showOnlySelectedDefs', !this.get('showOnlySelectedDefs')); - } + + initialDefs: initialDefs + }) + }); }, /** * add alert definitions callback + * @method addDefinitionsCallback */ addDefinitionsCallback: function (selectedDefs) { var group = this.get('selectedAlertGroup'); @@ -416,76 +435,26 @@ App.ManageAlertGroupsController = Em.Controller.extend({ }, /** - * observes if any group changed including: group name, newly created group, deleted group, group with definitions/notifications changed - */ - defsModifiedAlertGroups: function () { - if (!this.get('isLoaded')) { - return false; - } - var groupsToDelete = []; - var groupsToSet = []; - var groupsToCreate = []; - var groups = this.get('alertGroups'); //current alert groups - var originalGroups = this.get('originalAlertGroups'); // original alert groups - var originalGroupsIds = originalGroups.mapProperty('id'); - groups.forEach(function (group) { - var originalGroup = originalGroups.findProperty('id', group.get('id')); - if (originalGroup) { - // should update definitions or nitifications - if (!(JSON.stringify(group.get('definitions').slice().sort()) === JSON.stringify(originalGroup.get('definitions').slice().sort())) - || !(JSON.stringify(group.get('notifications').slice().sort()) === JSON.stringify(originalGroup.get('notifications').slice().sort()))) { - groupsToSet.push(group.set('id', originalGroup.get('id'))); - } else if (group.get('name') !== originalGroup.get('name') ) { - // should update name - groupsToSet.push(group.set('id', originalGroup.get('id'))); - } - originalGroupsIds = originalGroupsIds.without(group.get('id')); - } else { - // should add new group - groupsToCreate.push(group); - } - }); - // should delete groups - originalGroupsIds.forEach(function (id) { - groupsToDelete.push(originalGroups.findProperty('id', id)); - }, this); - return { - toDelete: groupsToDelete, - toSet: groupsToSet, - toCreate: groupsToCreate - }; - }.property('selectedAlertGroup.definitions.@each', 'selectedAlertGroup.definitions.length', 'selectedAlertGroup.notifications.@each', 'selectedAlertGroup.notifications.length', 'alertGroups', 'isLoaded'), - - isDefsModified: function () { - var modifiedGroups = this.get('defsModifiedAlertGroups'); - if (!this.get('isLoaded')) { - return false; - } - return !!(modifiedGroups.toSet.length || modifiedGroups.toCreate.length || modifiedGroups.toDelete.length); - }.property('defsModifiedAlertGroups'), - - /** * copy alert groups for backup, to compare with current alert groups, so will know if some groups changed/added/deleted - * @param originGroups - * @return {Array} + * @param {App.AlertGroup[]} originGroups + * @return {App.AlertGroup[]} + * @method copyAlertGroups */ copyAlertGroups: function (originGroups) { var alertGroups = []; originGroups.forEach(function (alertGroup) { - var copiedGroup = Em.Object.create($.extend(true, {}, alertGroup)); + var copiedGroup = Em.Object.create($.extend(true, {}, alertGroup)); alertGroups.pushObject(copiedGroup); }); return alertGroups; }, /** - * ==============on API side: following are four functions to an alert group: create, delete, update definitions/notificationss/label of a group =========== - */ - /** * Create a new alert group - * @param newAlertGroupData - * @param callback Callback function for Success or Error handling - * @return Returns the created alert group + * @param {Em.Object} newAlertGroupData + * @param {callback} callback Callback function for Success or Error handling + * @return {App.AlertGroup} Returns the created alert group + * @method postNewAlertGroup */ postNewAlertGroup: function (newAlertGroupData, callback) { // create a new group with name , definition and notifications @@ -527,6 +496,7 @@ App.ManageAlertGroupsController = Em.Controller.extend({ * @param {App.AlertGroup} alertGroup * @param {Function} successCallback * @param {Function} errorCallback + * @method updateAlertGroup */ updateAlertGroup: function (alertGroup, successCallback, errorCallback) { var sendData = { @@ -554,6 +524,13 @@ App.ManageAlertGroupsController = Em.Controller.extend({ App.ajax.send(sendData); }, + /** + * Request for deleting alert group + * @param {App.AlertGroup} alertGroup + * @param {callback} successCallback + * @param {callback} errorCallback + * @method removeAlertGroup + */ removeAlertGroup: function (alertGroup, successCallback, errorCallback) { var sendData = { name: 'alert_groups.delete', @@ -578,22 +555,20 @@ App.ManageAlertGroupsController = Em.Controller.extend({ }, /** - * =============on UI side: following are four operations to an alert group: add, remove, rename and duplicate================== - */ - - /** * confirm delete alert group + * @method confirmDelete */ - confirmDelete : function () { + confirmDelete: function () { if (this.get('isRemoveButtonDisabled')) return; var self = this; - App.showConfirmationPopup(function() { + App.showConfirmationPopup(function () { self.deleteAlertGroup(); }); }, /** * delete selected alert group + * @method deleteAlertGroup */ deleteAlertGroup: function () { var selectedAlertGroup = this.get('selectedAlertGroup'); @@ -605,20 +580,38 @@ App.ManageAlertGroupsController = Em.Controller.extend({ }, /** - * rename non-default alert group + * Rename non-default alert group + * @method renameAlertGroup */ renameAlertGroup: function () { - if(this.get('selectedAlertGroup.default')) { + + if (this.get('selectedAlertGroup.default')) { return; } var self = this; - this.renameGroupPopup = App.ModalPopup.show({ + var popup; + popup = App.ModalPopup.show({ + header: Em.I18n.t('alerts.actions.manage_alert_groups_popup.renameButton'), + bodyClass: Ember.View.extend({ templateName: require('templates/main/alerts/create_new_alert_group') }), + + /** + * @type {string} + */ alertGroupName: self.get('selectedAlertGroup.name'), + + /** + * @type {string|null} + */ warningMessage: null, + + /** + * New group name should be unique and valid + * @method validate + */ validate: function () { var warningMessage = ''; var originalGroup = self.get('selectedAlertGroup'); @@ -626,57 +619,95 @@ App.ManageAlertGroupsController = Em.Controller.extend({ if (originalGroup.get('name').trim() === groupName) { warningMessage = Em.I18n.t("alerts.actions.manage_alert_groups_popup.addGroup.exist"); - } else { + } + else { if (self.get('alertGroups').mapProperty('displayName').contains(groupName)) { warningMessage = Em.I18n.t("alerts.actions.manage_alert_groups_popup.addGroup.exist"); } - else if (groupName && !validator.isValidAlertGroupName(groupName)) { - warningMessage = Em.I18n.t("form.validator.alertGroupName"); + else { + if (groupName && !validator.isValidAlertGroupName(groupName)) { + warningMessage = Em.I18n.t("form.validator.alertGroupName"); + } } } this.set('warningMessage', warningMessage); }.observes('alertGroupName'), + + /** + * Primary button is disabled while user doesn't input valid group name + * @type {boolean} + */ disablePrimary: function () { return !(this.get('alertGroupName').trim().length > 0 && (this.get('warningMessage') !== null && !this.get('warningMessage'))); }.property('warningMessage', 'alertGroupName'), + onPrimary: function () { self.set('selectedAlertGroup.name', this.get('alertGroupName')); this.hide(); } + }); + this.set('renameGroupPopup', popup); }, /** - * create new alert group + * Create new alert group + * @param {boolean} duplicated is new group a copy of the existing group + * @method addAlertGroup */ addAlertGroup: function (duplicated) { duplicated = (duplicated === true); var self = this; - this.addGroupPopup = App.ModalPopup.show({ + var popup = App.ModalPopup.show({ + header: Em.I18n.t('alerts.actions.manage_alert_groups_popup.addButton'), - bodyClass: Ember.View.extend({ + + bodyClass: Em.View.extend({ templateName: require('templates/main/alerts/create_new_alert_group') }), + + /** + * Name for new alert group + * @type {string} + */ alertGroupName: duplicated ? self.get('selectedAlertGroup.name') + ' Copy' : "", + + /** + * @type {string} + */ warningMessage: '', - didInsertElement: function(){ + + didInsertElement: function () { + this._super(); this.validate(); - this.$('input').focus(); }, + + /** + * alert group name should be unique and valid + * @method validate + */ validate: function () { var warningMessage = ''; var groupName = this.get('alertGroupName').trim(); if (self.get('alertGroups').mapProperty('displayName').contains(groupName)) { warningMessage = Em.I18n.t("alerts.actions.manage_alert_groups_popup.addGroup.exist"); } - else if (groupName && !validator.isValidAlertGroupName(groupName)) { - warningMessage = Em.I18n.t("form.validator.alertGroupName"); + else { + if (groupName && !validator.isValidAlertGroupName(groupName)) { + warningMessage = Em.I18n.t("form.validator.alertGroupName"); + } } this.set('warningMessage', warningMessage); }.observes('alertGroupName'), + + /** + * Primary button is disabled while user doesn't input valid group name + * @type {boolean} + */ disablePrimary: function () { return !(this.get('alertGroupName').trim().length > 0 && !this.get('warningMessage')); }.property('warningMessage', 'alertGroupName'), + onPrimary: function () { var newAlertGroup = Em.Object.create({ name: this.get('alertGroupName').trim(), @@ -700,10 +731,15 @@ App.ManageAlertGroupsController = Em.Controller.extend({ self.set('selectedAlertGroup', newAlertGroup); this.hide(); } + }); + this.set('addGroupPopup', popup); }, - duplicateAlertGroup: function() { + /** + * @method duplicateAlertGroup + */ + duplicateAlertGroup: function () { this.addAlertGroup(true); } http://git-wip-us.apache.org/repos/asf/ambari/blob/8cf3fa11/ambari-web/app/views.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js index 44d4cce..7dc70a9 100644 --- a/ambari-web/app/views.js +++ b/ambari-web/app/views.js @@ -57,6 +57,7 @@ require('views/main/alert_definitions_view'); require('views/main/alerts/definition_details_view'); require('views/main/alerts/alert_definitions_actions_view'); require('views/main/alerts/definition_configs_view'); +require('views/main/alerts/manage_alert_groups/select_definitions_popup_body_view'); require('views/main/alerts/add_alert_definition/add_alert_definition_view'); require('views/main/alerts/add_alert_definition/step1_view'); require('views/main/alerts/add_alert_definition/step2_view'); http://git-wip-us.apache.org/repos/asf/ambari/blob/8cf3fa11/ambari-web/app/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view.js b/ambari-web/app/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view.js new file mode 100644 index 0000000..f92b804 --- /dev/null +++ b/ambari-web/app/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view.js @@ -0,0 +1,133 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var App = require('app'); + +App.SelectDefinitionsPopupBodyView = App.TableView.extend({ + + templateName: require('templates/main/alerts/add_definition_to_group_popup'), + + controllerBinding: 'App.router.manageAlertGroupsController', + + isPaginate: true, + + filteredContent: function () { + return this.get('parentView.availableDefs').filterProperty('filtered') || []; + }.property('parentView.availableDefs.@each.filtered'), + + showOnlySelectedDefs: false, + + filterComponent: null, + + filterService: null, + + isDisabled: function () { + return !this.get('parentView.isLoaded'); + }.property('parentView.isLoaded'), + + didInsertElement: function () { + var initialDefs = this.get('initialDefs'); + initialDefs.setEach('filtered', true); + this.set('parentView.availableDefs', initialDefs); + this.set('parentView.isLoaded', true); + }, + + filterDefs: function () { + var showOnlySelectedDefs = this.get('showOnlySelectedDefs'); + var filterComponent = this.get('filterComponent'); + var filterService = this.get('filterService'); + this.get('parentView.availableDefs').forEach(function (defObj) { + var componentOnObj = true; + var serviceOnObj = true; + if (filterComponent) { + componentOnObj = (defObj.componentName == filterComponent.get('componentName')); + } + if (defObj.serviceName && filterService) { + serviceOnObj = (defObj.serviceName == filterService.get('serviceName')); + } + defObj.set('filtered', showOnlySelectedDefs ? (componentOnObj && serviceOnObj && defObj.get('selected')) : (componentOnObj && serviceOnObj)); + }, this); + this.set('startIndex', 1); + }.observes('parentView.availableDefs', 'filterService', 'filterService.serviceName', 'filterComponent', 'filterComponent.componentName', 'showOnlySelectedDefs'), + + defSelectMessage: function () { + var defs = this.get('parentView.availableDefs'); + var selectedDefs = defs.filterProperty('selected', true); + return this.t('alerts.actions.manage_alert_groups_popup.selectDefsDialog.selectedDefsLink').format(selectedDefs.get('length'), defs.get('length')); + }.property('parentView.availableDefs.@each.selected'), + + selectFilterComponent: function (event) { + if (event != null && event.context != null && event.context.componentName != null) { + var currentFilter = this.get('filterComponent'); + if (currentFilter != null) { + currentFilter.set('selected', false); + } + if (currentFilter != null && currentFilter.componentName === event.context.componentName) { + // selecting the same filter deselects it. + this.set('filterComponent', null); + } else { + this.set('filterComponent', event.context); + event.context.set('selected', true); + } + } + }, + + selectFilterService: function (event) { + if (event != null && event.context != null && event.context.serviceName != null) { + var currentFilter = this.get('filterService'); + if (currentFilter != null) { + currentFilter.set('selected', false); + } + if (currentFilter != null && currentFilter.serviceName === event.context.serviceName) { + // selecting the same filter deselects it. + this.set('filterService', null); + } else { + this.set('filterService', event.context); + event.context.set('selected', true); + } + } + }, + + /** + * Determines if all alert definitions are selected + * @type {boolean} + */ + allDefsSelected: false, + + /** + * Inverse selection for alert definitions + * @method toggleSelectAllDefs + */ + toggleSelectAllDefs: function () { + this.get('parentView.availableDefs').filterProperty('filtered').setEach('selected', this.get('allDefsSelected')); + }.observes('allDefsSelected'), + + toggleShowSelectedDefs: function () { + var filter1 = this.get('filterComponent'); + if (filter1 != null) { + filter1.set('selected', false); + } + var filter2 = this.get('filterService'); + if (filter2 != null) { + filter2.set('selected', false); + } + this.set('filterComponent', null); + this.set('filterService', null); + this.set('showOnlySelectedDefs', !this.get('showOnlySelectedDefs')); + } +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/8cf3fa11/ambari-web/test/controllers/main/alerts/manage_alert_groups_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/alerts/manage_alert_groups_controller_test.js b/ambari-web/test/controllers/main/alerts/manage_alert_groups_controller_test.js index cdf46c6..67d3397 100644 --- a/ambari-web/test/controllers/main/alerts/manage_alert_groups_controller_test.js +++ b/ambari-web/test/controllers/main/alerts/manage_alert_groups_controller_test.js @@ -17,24 +17,29 @@ */ var App = require('app'); -describe('App.ManageAlertGroupsController', function() { - var manageAlertGroupsController = App.ManageAlertGroupsController.create({}); +var manageAlertGroupsController; +describe('App.ManageAlertGroupsController', function () { - describe('#addAlertGroup', function() { - beforeEach(function() { + beforeEach(function () { + manageAlertGroupsController = App.ManageAlertGroupsController.create({}); + }); + + describe('#addAlertGroup', function () { + + beforeEach(function () { manageAlertGroupsController.addAlertGroup(); }); - describe("#validate", function() { - it("should display no warning if user inputs valid characters into group name", function() { + describe("#validate", function () { + it("should display no warning if user inputs valid characters into group name", function () { manageAlertGroupsController.addGroupPopup.set('alertGroupName', 'test'); expect(manageAlertGroupsController.addGroupPopup.warningMessage).to.be.empty; }); - it("should display warning if user inputs invalid characters into group name", function() { + it("should display warning if user inputs invalid characters into group name", function () { manageAlertGroupsController.addGroupPopup.set('alertGroupName', '/{"!@#$%'); expect(manageAlertGroupsController.addGroupPopup.warningMessage).to.equal('Invalid Alert Group Name. Only alphanumerics, hyphens, spaces and underscores are allowed.'); @@ -43,9 +48,9 @@ describe('App.ManageAlertGroupsController', function() { }); }); - describe('#duplicateAlertGroup', function() { - beforeEach(function() { - var group = Ember.Object.create ({ + describe('#duplicateAlertGroup', function () { + beforeEach(function () { + var group = Ember.Object.create({ name: 'test' }); @@ -53,8 +58,8 @@ describe('App.ManageAlertGroupsController', function() { manageAlertGroupsController.duplicateAlertGroup(); }); - describe("#validate", function() { - it("should display no warning if user duplicate an existed group", function() { + describe("#validate", function () { + it("should display no warning if user duplicate an existed group", function () { manageAlertGroupsController.addGroupPopup.set('alertGroupName', 'test Copy'); expect(manageAlertGroupsController.addGroupPopup.warningMessage).to.be.empty; @@ -62,9 +67,9 @@ describe('App.ManageAlertGroupsController', function() { }); }); - describe('#renameAlertGroup', function() { - beforeEach(function() { - var group = Ember.Object.create ({ + describe('#renameAlertGroup', function () { + beforeEach(function () { + var group = Ember.Object.create({ name: 'test' }); @@ -72,14 +77,14 @@ describe('App.ManageAlertGroupsController', function() { manageAlertGroupsController.renameAlertGroup(); }); - describe("#validate", function() { - it("should display no warning if user inputs valid characters into group name", function() { + describe("#validate", function () { + it("should display no warning if user inputs valid characters into group name", function () { manageAlertGroupsController.renameGroupPopup.set('alertGroupName', 'hello'); expect(manageAlertGroupsController.renameGroupPopup.warningMessage).to.be.empty; }); - it("should display warning if user inputs invalid characters into group name", function() { + it("should display warning if user inputs invalid characters into group name", function () { manageAlertGroupsController.renameGroupPopup.set('alertGroupName', '/{"!@#$%'); expect(manageAlertGroupsController.renameGroupPopup.warningMessage).to.equal('Invalid Alert Group Name. Only alphanumerics, hyphens, spaces and underscores are allowed.'); @@ -87,7 +92,7 @@ describe('App.ManageAlertGroupsController', function() { }); }); - describe('#deleteDefinitions', function() { + describe('#deleteDefinitions', function () { var definitions = [ Em.Object.create({ name: 'def1', @@ -109,11 +114,11 @@ describe('App.ManageAlertGroupsController', function() { }) ]; - beforeEach(function() { + beforeEach(function () { manageAlertGroupsController = App.ManageAlertGroupsController.create({}); }); - var createAlertGroupMock = function(groupDefs) { + var createAlertGroupMock = function (groupDefs) { return Em.Object.create({ definitions: groupDefs, name: 'group' @@ -138,8 +143,8 @@ describe('App.ManageAlertGroupsController', function() { } ]; - tests.forEach(function(test) { - it('delete definitions length {0} definitions'.format(test.selectedDefinitions.slice(0).length), function() { + tests.forEach(function (test) { + it('delete definitions length {0} definitions'.format(test.selectedDefinitions.slice(0).length), function () { manageAlertGroupsController.reopen({ selectedDefinitions: test.selectedDefinitions, selectedAlertGroup: test.selectedAlertGroup @@ -151,7 +156,7 @@ describe('App.ManageAlertGroupsController', function() { }); - describe('#addDefinitionsCallback', function() { + describe('#addDefinitionsCallback', function () { var definitions = [ Em.Object.create({ @@ -195,18 +200,18 @@ describe('App.ManageAlertGroupsController', function() { }) ]; - beforeEach(function() { + beforeEach(function () { manageAlertGroupsController = App.ManageAlertGroupsController.create({}); }); - var createAlertGroupMock = function(groupDefs) { + var createAlertGroupMock = function (groupDefs) { return Em.Object.create({ definitions: groupDefs, name: 'group' }); }; - var result = function(originalDefs, addedDefs) { + var result = function (originalDefs, addedDefs) { var result = originalDefs.concat(addedDefs); return result; }; @@ -229,8 +234,8 @@ describe('App.ManageAlertGroupsController', function() { } ]; - tests.forEach(function(test) { - it('add Definitions length {0} definitions'.format(test.selectedDefinitions.slice(0).length), function() { + tests.forEach(function (test) { + it('add Definitions length {0} definitions'.format(test.selectedDefinitions.slice(0).length), function () { manageAlertGroupsController.set('selectedAlertGroup', test.selectedAlertGroup); manageAlertGroupsController.addDefinitionsCallback(test.selectedDefinitions); expect(manageAlertGroupsController.get('selectedAlertGroup.definitions').toArray()).to.eql(test.e); @@ -238,5 +243,6 @@ describe('App.ManageAlertGroupsController', function() { }); }); + });