/** * 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 validator = require('utils/validator'); App.MainAlertDefinitionDetailsController = Em.Controller.extend({ name: 'mainAlertDefinitionDetailsController', alerts: function () { return App.AlertInstanceLocal.find().toArray() .filterProperty('definitionId', this.get('content.id')); }.property('App.router.mainAlertInstancesController.isLoaded', 'App.router.mainAlertInstancesController.reload'), // stores object with editing form data (label) editing: Em.Object.create({ label: Em.Object.create({ name: 'label', isEditing: false, value: '', originalValue: '', isError: false, bindingValue: 'content.label' }) }), /** * Host to count of alerts on this host during last day map * @type {Object} */ lastDayAlertsCount: null, /** * List of all group names related to alert definition * @type {Array} */ groupsList: Em.computed.mapBy('content.groups', 'displayName'), /** * Validation function to define if label field populated correctly * @method labelValidation */ labelValidation: function () { this.set('editing.label.isError', !this.get('editing.label.value').trim()); }.observes('editing.label.value'), /** * Set init values for variables */ clearStep: function () { var editing = this.get('editing'); Em.keys(editing).forEach(function (key) { editing.get(key).set('isEditing', false); }); }, /** * Load alert instances for current alertDefinition * Start updating loaded data * @method loadAlertInstances */ loadAlertInstances: function () { App.router.get('mainAlertInstancesController').loadAlertInstancesByAlertDefinition(this.get('content.id')); App.router.set('mainAlertInstancesController.isUpdating', true); this.loadAlertInstancesHistory(); }, /** * Load alert instances history data * used to count instances number of the last 24 hour * @method loadAlertInstancesHistory */ loadAlertInstancesHistory: function () { this.set('lastDayAlertsCount', null); return App.ajax.send({ name: 'alerts.get_instances_history', sender: this, data: { definitionName: this.get('content.name'), timestamp: App.dateTime() - 86400000 // timestamp for time 24-hours ago }, success: 'loadAlertInstancesHistorySuccess' }); }, /** * Success-callback for loadAlertInstancesHistory */ loadAlertInstancesHistorySuccess: function (data) { var lastDayAlertsCount = {}; data.items.forEach(function (alert) { if (!lastDayAlertsCount[alert.AlertHistory.host_name]) { lastDayAlertsCount[alert.AlertHistory.host_name] = 1; } else { lastDayAlertsCount[alert.AlertHistory.host_name] += 1; } }); this.set('lastDayAlertsCount', lastDayAlertsCount); }, /** * Edit button handler * @param {object} event * @method edit */ edit: function (event) { var element = event.context; var value = this.get(element.get('bindingValue')); element.set('originalValue', value); element.set('value', value); element.set('isEditing', true); }, /** * Cancel button handler * @param {object} event * @method cancelEdit */ cancelEdit: function (event) { var element = event.context; element.set('value', element.get('originalValue')); element.set('isEditing', false); }, /** * Save button handler, could save label of alert definition * @param {object} event * @returns {$.ajax} * @method saveEdit */ saveEdit: function (event) { var element = event.context; this.set(element.get('bindingValue'), element.get('value')); element.set('isEditing', false); var data = Em.Object.create({}); var property_name = "AlertDefinition/" + element.get('name'); data.set(property_name, element.get('value')); var alertDefinition_id = this.get('content.id'); return App.ajax.send({ name: 'alerts.update_alert_definition', sender: this, data: { id: alertDefinition_id, data: data } }); }, /** * Onclick handler for save button on Save popup * Save changes of label and configs */ saveLabelAndConfigs: function () { var configsController = App.router.get('mainAlertDefinitionConfigsController'); if (configsController.get('canEdit')) { configsController.saveConfigs(); } if (this.get('editing.label.isEditing')) { this.saveEdit({ context: this.get('editing.label') }); } }, /** * "Delete" button handler * @param {object} event * @method deleteAlertDefinition */ deleteAlertDefinition: function (event) { var alertDefinition = this.get('content'); var self = this; App.showConfirmationPopup(function () { App.ajax.send({ name: 'alerts.delete_alert_definition', sender: self, success: 'deleteAlertDefinitionSuccess', error: 'deleteAlertDefinitionError', data: { id: alertDefinition.get('id') } }); }, null, function () { }); }, /** * Success-callback for deleteAlertDefinition * @method deleteAlertDefinitionSuccess */ deleteAlertDefinitionSuccess: function () { App.router.transitionTo('main.alerts.index'); }, /** * Error-callback for deleteAlertDefinition * @method deleteAlertDefinitionError */ deleteAlertDefinitionError: function (xhr, textStatus, errorThrown, opt) { xhr.responseText = "{\"message\": \"" + xhr.statusText + "\"}"; App.ajax.defaultErrorHandler(xhr, opt.url, 'DELETE', xhr.status); }, /** * "Disable / Enable" button handler * @method toggleState */ toggleState: function () { var alertDefinition = this.get('content'); var self = this; var bodyMessage = Em.Object.create({ confirmMsg: alertDefinition.get('enabled') ? Em.I18n.t('alerts.table.state.enabled.confirm.msg') : Em.I18n.t('alerts.table.state.disabled.confirm.msg'), confirmButton: alertDefinition.get('enabled') ? Em.I18n.t('alerts.table.state.enabled.confirm.btn') : Em.I18n.t('alerts.table.state.disabled.confirm.btn') }); return App.showConfirmationFeedBackPopup(function (query) { self.toggleDefinitionState(alertDefinition); }, bodyMessage); }, /** * Enable/disable alertDefinition * @param {object} alertDefinition * @param {string} property * @returns {$.ajax} * @method toggleDefinitionState */ toggleDefinitionState: function (alertDefinition) { var newState = !alertDefinition.get('enabled'); alertDefinition.set('enabled', newState); return App.ajax.send({ name: 'alerts.update_alert_definition', sender: this, data: { id: alertDefinition.get('id'), data: { "AlertDefinition/enabled": newState } } }); }, globalAlertsRepeatTolerance: function () { return App.router.get('clusterController.clusterEnv.properties.alerts_repeat_tolerance') || "1"; }.property('App.router.clusterController.clusterEnv'), enableRepeatTolerance: function (enable) { var alertDefinition = this.get('content'); alertDefinition.set('repeat_tolerance_enabled', enable); return App.ajax.send({ name: 'alerts.update_alert_definition', sender: this, data: { id: alertDefinition.get('id'), data: { "AlertDefinition/repeat_tolerance_enabled": enable } } }); }, editRepeatTolerance: function () { var self = this; var alertDefinition = this.get('content'); var alertsRepeatTolerance = App.router.get('clusterController.clusterEnv.properties.alerts_repeat_tolerance') || "1"; return App.ModalPopup.show({ classNames: ['fourty-percent-width-modal'], header: Em.I18n.t('alerts.actions.editRepeatTolerance.header'), primary: Em.I18n.t('common.save'), secondary: Em.I18n.t('common.cancel'), inputValue: self.get('content.repeat_tolerance_enabled') ? (self.get('content.repeat_tolerance') || 1) : alertsRepeatTolerance, errorMessage: Em.I18n.t('alerts.actions.editRepeatTolerance.error'), isInvalid: function () { var intValue = Number(this.get('inputValue')); return this.get('inputValue') !== 'DEBUG' && (!validator.isValidInt(intValue) || intValue < 1 || intValue > 99); }.property('inputValue'), isChanged: function () { var intValue = Number(this.get('inputValue')); var isValueChanged = intValue != alertsRepeatTolerance; return isValueChanged; }.property('inputValue'), doRestoreDefaultValue: function () { this.set('inputValue', alertsRepeatTolerance); this.$('[data-toggle=tooltip]').tooltip('destroy'); }, disablePrimary: Em.computed.alias('isInvalid'), onPrimary: function () { if (this.get('isInvalid')) { return; } var input = this.get('inputValue'); self.set('content.repeat_tolerance', input); if (input == alertsRepeatTolerance) { self.enableRepeatTolerance(false); } else { self.enableRepeatTolerance(true); } App.ajax.send({ name: 'alerts.update_alert_definition', sender: self, data: { id: alertDefinition.get('id'), data: { "AlertDefinition/repeat_tolerance": input } } }); this.hide(); }, didInsertElement: function () { App.tooltip(this.$('[data-toggle=tooltip]')); }, bodyClass: Ember.View.extend({ templateName: require('templates/common/modal_popups/prompt_popup'), title: Em.I18n.t('alerts.actions.editRepeatTolerance.title'), description: Em.I18n.t('alerts.actions.editRepeatTolerance.description'), label: Em.I18n.t('alerts.actions.editRepeatTolerance.label') }) }); }, /** * Define if label or configs are in edit mode * @type {Boolean} */ isEditing: Em.computed.or('editing.label.isEditing', 'App.router.mainAlertDefinitionConfigsController.canEdit'), /** * If some configs or label are changed and user navigates away, show this popup with propose to save changes * @param {String} path * @method showSavePopup */ showSavePopup: function (callback) { var self = this; return App.ModalPopup.show({ header: Em.I18n.t('common.warning'), bodyClass: Em.View.extend({ template: Ember.Handlebars.compile('{{t alerts.saveChanges}}') }), primary: Em.I18n.t('common.save'), secondary: Em.I18n.t('common.discard'), third: Em.I18n.t('common.cancel'), disablePrimary: Em.computed.or('App.router.mainAlertDefinitionDetailsController.editing.label.isError', 'App.router.mainAlertDefinitionConfigsController.hasErrors'), onPrimary: function () { self.saveLabelAndConfigs(); callback(); this.hide(); }, onSecondary: function () { callback(); this.hide(); }, onThird: function () { this.hide(); } }); } });