| /** |
| * 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'); |
| var filters = require('views/common/filter_view'); |
| |
| App.MainDashboardWidgetsView = Em.View.extend(App.UserPref, App.LocalStorage, App.TimeRangeMixin, { |
| |
| name: 'mainDashboardWidgetsView', |
| |
| templateName: require('templates/main/dashboard/widgets'), |
| |
| didInsertElement: function () { |
| this._super(); |
| this.setWidgetsDataModel(); |
| this.setInitPrefObject(); |
| this.setOnLoadVisibleWidgets(); |
| this.set('isDataLoaded', true); |
| App.loadTimer.finish('Dashboard Metrics Page'); |
| Em.run.next(this, 'makeSortable'); |
| }, |
| |
| /** |
| * List of services |
| * @type {Ember.Enumerable} |
| */ |
| content: [], |
| |
| /** |
| * @type {boolean} |
| */ |
| isDataLoaded: false, |
| |
| /** |
| * Define if some widget is currently moving |
| * @type {boolean} |
| */ |
| isMoving: false, |
| |
| timeRangeClassName: 'pull-left', |
| |
| /** |
| * Make widgets' list sortable on New Dashboard style |
| */ |
| makeSortable: function () { |
| var self = this; |
| $("#sortable").sortable({ |
| items: "> div", |
| //placeholder: "sortable-placeholder", |
| cursor: "move", |
| tolerance: "pointer", |
| scroll: false, |
| update: function (event, ui) { |
| if (!App.get('testMode')) { |
| // update persist then translate to real |
| var widgetsArray = $('div[viewid]'); // get all in DOM |
| self.getUserPref(self.get('persistKey')).complete(function () { |
| var oldValue = self.get('currentPrefObject') || self.getDBProperty(self.get('persistKey')); |
| var newValue = Em.Object.create({ |
| dashboardVersion: oldValue.dashboardVersion, |
| visible: [], |
| hidden: oldValue.hidden, |
| threshold: oldValue.threshold |
| }); |
| var size = oldValue.visible.length; |
| for (var j = 0; j <= size - 1; j++) { |
| var viewID = widgetsArray.get(j).getAttribute('viewid'); |
| var id = viewID.split("-").get(1); |
| newValue.visible.push(id); |
| } |
| self.postUserPref(self.get('persistKey'), newValue); |
| self.setDBProperty(self.get('persistKey'), newValue); |
| //self.translateToReal(newValue); |
| }); |
| } |
| }, |
| activate: function (event, ui) { |
| self.set('isMoving', true); |
| }, |
| deactivate: function (event, ui) { |
| self.set('isMoving', false); |
| } |
| }).disableSelection(); |
| }, |
| |
| /** |
| * Set Service model values |
| */ |
| setWidgetsDataModel: function () { |
| if (App.get('services.hostMetrics').length > 0) { |
| this.set('host_metrics_model', App.get('services.hostMetrics')); |
| } |
| App.Service.find().forEach(function (item) { |
| var extendedModel = App.Service.extendedModel[item.get('serviceName')]; |
| var key = item.get('serviceName').toLowerCase() + '_model'; |
| if (extendedModel && App[extendedModel].find(item.get('id'))) { |
| this.set(key, App[extendedModel].find(item.get('id'))); |
| } else { |
| this.set(key, item); |
| } |
| }, this); |
| }, |
| |
| resolveConfigDependencies: function(visibleFull, hiddenFull) { |
| var clusterEnv = App.router.get('clusterController.clusterEnv').properties; |
| |
| if (clusterEnv['hide_yarn_memory_widget'] === 'true') { |
| hiddenFull.push(['20', 'YARN Memory']); |
| } else { |
| visibleFull.splice(visibleFull.indexOf('19'), 0, '20'); |
| } |
| }, |
| |
| /** |
| * Load widget statuses to <code>initPrefObject</code> |
| */ |
| setInitPrefObject: function () { |
| //in case of some service not installed |
| var visibleFull = [ |
| '2', '4', '11', //hdfs |
| '6', '7', '8', '9', //host metrics |
| '1', '5', '3', '10', //hdfs |
| '13', '12', '14', '16', //hbase |
| '17', '18', '19', '23', // all yarn |
| '21', // storm |
| '22', // flume |
| '24', // hawq |
| '25' // pxf |
| ]; // all in order |
| var hiddenFull = [ |
| ['15', 'Region In Transition'] |
| ]; |
| this.resolveConfigDependencies(visibleFull, hiddenFull); |
| |
| // Display widgets for host metrics if the stack definition has a host metrics service to display it. |
| if (this.get('host_metrics_model') == null) { |
| var hostMetrics = ['6', '7', '8', '9']; |
| hostMetrics.forEach(function (item) { |
| visibleFull = visibleFull.without(item); |
| }, this); |
| } |
| |
| if (this.get('hdfs_model') == null) { |
| var hdfs = ['1', '2', '3', '4', '5', '10', '11']; |
| hdfs.forEach(function (item) { |
| visibleFull = visibleFull.without(item); |
| }, this); |
| } |
| if (this.get('hbase_model') == null) { |
| var hbase = ['12', '13', '14', '16']; |
| hbase.forEach(function (item) { |
| visibleFull = visibleFull.without(item); |
| }, this); |
| hiddenFull = hiddenFull.filter(function(item) { |
| return item[0] !== '15'; |
| }); |
| } |
| if (this.get('yarn_model') == null) { |
| var yarn = ['17', '18', '19', '20', '23']; |
| yarn.forEach(function (item) { |
| visibleFull = visibleFull.without(item); |
| }, this); |
| } |
| if (this.get('storm_model') == null) { |
| var storm = ['21']; |
| storm.forEach(function (item) { |
| visibleFull = visibleFull.without(item); |
| }, this); |
| } |
| if (this.get('flume_model') == null) { |
| var flume = ['22']; |
| flume.forEach(function (item) { |
| visibleFull = visibleFull.without(item); |
| }, this); |
| } |
| if (this.get('hawq_model') == null) { |
| var hawq = ['24']; |
| hawq.forEach(function (item) { |
| visibleFull = visibleFull.without(item); |
| }, this); |
| } |
| if (this.get('pxf_model') == null) { |
| var pxf = ['25']; |
| pxf.forEach(function (item) { |
| visibleFull = visibleFull.without(item); |
| }, this); |
| } |
| var obj = this.get('initPrefObject'); |
| obj.set('visible', visibleFull); |
| obj.set('hidden', hiddenFull); |
| }, |
| |
| host_metrics_model: null, |
| |
| hdfs_model: null, |
| |
| mapreduce2_model: null, |
| |
| yarn_model: null, |
| |
| hbase_model: null, |
| |
| storm_model: null, |
| |
| flume_model: null, |
| |
| hawq_model: null, |
| |
| pxf_model: null, |
| |
| /** |
| * List of visible widgets |
| * @type {Ember.Enumerable} |
| */ |
| visibleWidgets: [], |
| |
| /** |
| * List of hidden widgets |
| * @type {Ember.Enumerable} |
| */ |
| hiddenWidgets: [], // widget child view will push object in this array if deleted |
| |
| /** |
| * Submenu view for New Dashboard style |
| * @type {Ember.View} |
| * @class |
| */ |
| plusButtonFilterView: Ember.View.extend({ |
| templateName: require('templates/main/dashboard/plus_button_filter'), |
| hiddenWidgetsBinding: 'parentView.hiddenWidgets', |
| visibleWidgetsBinding: 'parentView.visibleWidgets', |
| valueBinding: '', |
| widgetCheckbox: Em.Checkbox.extend({ |
| didInsertElement: function () { |
| $('.checkbox').click(function (event) { |
| event.stopPropagation(); |
| }); |
| } |
| }), |
| closeFilter: Em.K, |
| applyFilter: function () { |
| var self = this; |
| var parent = this.get('parentView'); |
| var hiddenWidgets = this.get('hiddenWidgets'); |
| var checkedWidgets = hiddenWidgets.filterProperty('checked', true); |
| |
| if (App.get('testMode')) { |
| var visibleWidgets = this.get('visibleWidgets'); |
| checkedWidgets.forEach(function (item) { |
| var newObj = parent.widgetsMapper(item.id); |
| visibleWidgets.pushObject(newObj); |
| hiddenWidgets.removeObject(item); |
| }, this); |
| } else { |
| //save in persist |
| parent.getUserPref(parent.get('persistKey')).complete(function(){ |
| self.applyFilterComplete.apply(self); |
| }); |
| } |
| }, |
| applyFilterComplete: function () { |
| var parent = this.get('parentView'), |
| hiddenWidgets = this.get('hiddenWidgets'), |
| oldValue = parent.get('currentPrefObject'), |
| newValue = Em.Object.create({ |
| dashboardVersion: oldValue.dashboardVersion, |
| visible: oldValue.visible, |
| hidden: [], |
| threshold: oldValue.threshold |
| }); |
| hiddenWidgets.filterProperty('checked').forEach(function (item) { |
| newValue.visible.push(item.id); |
| hiddenWidgets.removeObject(item); |
| }, this); |
| hiddenWidgets.forEach(function (item) { |
| newValue.hidden.push([item.id, item.displayName]); |
| }, this); |
| parent.postUserPref(parent.get('persistKey'), newValue); |
| parent.translateToReal(newValue); |
| } |
| }), |
| |
| /** |
| * Translate from Json value got from persist to real widgets view |
| */ |
| translateToReal: function (value) { |
| var version = value.dashboardVersion; |
| var visible = value.visible; |
| var hidden = value.hidden; |
| var threshold = value.threshold; |
| |
| if (version === 'new') { |
| var visibleWidgets = []; |
| var hiddenWidgets = []; |
| // re-construct visibleWidgets and hiddenWidgets |
| for (var i = 0; i < visible.length; i++) { |
| var id = visible[i]; |
| var widgetClass = this.widgetsMapper(id); |
| //override with new threshold |
| if (threshold[id].length > 0) { |
| widgetClass.reopen({ |
| thresh1: threshold[id][0], |
| thresh2: threshold[id][1] |
| }); |
| } |
| visibleWidgets.pushObject(widgetClass); |
| } |
| for (var j = 0; j < hidden.length; j++) { |
| var title = hidden[j][1]; |
| hiddenWidgets.pushObject(Em.Object.create({displayName: title, id: hidden[j][0], checked: false})); |
| } |
| this.set('visibleWidgets', visibleWidgets); |
| this.set('hiddenWidgets', hiddenWidgets); |
| } |
| }, |
| |
| /** |
| * Set visibility-status for widgets |
| */ |
| setOnLoadVisibleWidgets: function () { |
| var self = this; |
| if (App.get('testMode')) { |
| this.translateToReal(this.get('initPrefObject')); |
| } else { |
| // called when first load/refresh/jump back page |
| this.getUserPref(this.get('persistKey')).complete(function () { |
| if (self.get('state') === 'inDOM') { |
| self.setOnLoadVisibleWidgetsComplete.apply(self); |
| } |
| }); |
| } |
| }, |
| |
| /** |
| * complete load of visible widgets |
| */ |
| setOnLoadVisibleWidgetsComplete: function () { |
| var currentPrefObject = this.get('currentPrefObject') || this.getDBProperty(this.get('persistKey')); |
| if (currentPrefObject) { // fit for no dashboard version |
| if (!currentPrefObject.dashboardVersion) { |
| currentPrefObject.dashboardVersion = 'new'; |
| this.postUserPref(this.get('persistKey'), currentPrefObject); |
| this.setDBProperty(this.get('persistKey'), currentPrefObject); |
| } |
| this.set('currentPrefObject', this.checkServicesChange(currentPrefObject)); |
| this.translateToReal(this.get('currentPrefObject')); |
| } |
| else { |
| // post persist then translate init object |
| this.postUserPref(this.get('persistKey'), this.get('initPrefObject')); |
| this.setDBProperty(this.get('persistKey'), this.get('initPrefObject')); |
| this.translateToReal(this.get('initPrefObject')); |
| } |
| }, |
| |
| /** |
| * Remove widget from visible and hidden lists |
| * @param {Object} value |
| * @param {Object} widget |
| * @returns {*} |
| */ |
| removeWidget: function (value, widget) { |
| value.visible = value.visible.without(widget); |
| for (var j = 0; j < value.hidden.length; j++) { |
| if (value.hidden[j][0] == widget) { |
| value.hidden.splice(j, 1); |
| } |
| } |
| return value; |
| }, |
| |
| /** |
| * Check if widget is in visible or hidden list |
| * @param {Object} value |
| * @param {Object} widget |
| * @returns {bool} |
| */ |
| containsWidget: function (value, widget) { |
| var flag = value.visible.contains(widget); |
| for (var j = 0; j < value.hidden.length; j++) { |
| if (!flag && value.hidden[j][0] == widget) { |
| flag = true; |
| break; |
| } |
| } |
| return flag; |
| }, |
| |
| /** |
| * check if stack has upgraded from HDP 1.0 to 2.0 OR add/delete services. |
| * Update the value on server if true. |
| * @param {Object} currentPrefObject |
| * @return {Object} |
| */ |
| checkServicesChange: function (currentPrefObject) { |
| var toDelete = $.extend(true, {}, currentPrefObject); |
| var toAdd = []; |
| var serviceWidgetsMap = { |
| hdfs_model: ['1', '2', '3', '4', '5', '10', '11'], |
| host_metrics_model: ['6', '7', '8', '9'], |
| hbase_model: ['12', '13', '14', '15', '16'], |
| yarn_model: ['17', '18', '19', '20', '23'], |
| storm_model: ['21'], |
| flume_model: ['22'], |
| hawq_model: ['24'], |
| pxf_model: ['25'] |
| }; |
| |
| // check each service, find out the newly added service and already deleted service |
| Em.keys(serviceWidgetsMap).forEach(function (modelName) { |
| if (!Em.isNone(this.get(modelName))) { |
| var ids = serviceWidgetsMap[modelName]; |
| var flag = this.containsWidget(toDelete, ids[0]); |
| if (flag) { |
| ids.forEach(function (item) { |
| toDelete = this.removeWidget(toDelete, item); |
| }, this); |
| } else { |
| toAdd = toAdd.concat(ids); |
| } |
| } |
| }, this); |
| |
| var value = currentPrefObject; |
| if (toDelete.visible.length || toDelete.hidden.length) { |
| toDelete.visible.forEach(function (item) { |
| value = this.removeWidget(value, item); |
| }, this); |
| toDelete.hidden.forEach(function (item) { |
| value = this.removeWidget(value, item[0]); |
| }, this); |
| } |
| if (toAdd.length) { |
| value.visible = value.visible.concat(toAdd); |
| var allThreshold = this.get('initPrefObject').threshold; |
| // add new threshold OR override with default value |
| toAdd.forEach(function (item) { |
| value.threshold[item] = allThreshold[item]; |
| }, this); |
| } |
| return value; |
| }, |
| |
| /** |
| * Get view for widget by widget's id |
| * @param {string} id |
| * @returns {Ember.View} |
| */ |
| widgetsMapper: function (id) { |
| return Em.get({ |
| '1': App.NameNodeHeapPieChartView, |
| '2': App.NameNodeCapacityPieChartView, |
| '3': App.NameNodeCpuPieChartView, |
| '4': App.DataNodeUpView, |
| '5': App.NameNodeRpcView, |
| '6': App.ChartClusterMetricsMemoryWidgetView, |
| '7': App.ChartClusterMetricsNetworkWidgetView, |
| '8': App.ChartClusterMetricsCPUWidgetView, |
| '9': App.ChartClusterMetricsLoadWidgetView, |
| '10': App.NameNodeUptimeView, |
| '11': App.HDFSLinksView, |
| '12': App.HBaseLinksView, |
| '13': App.HBaseMasterHeapPieChartView, |
| '14': App.HBaseAverageLoadView, |
| '15': App.HBaseRegionsInTransitionView, |
| '16': App.HBaseMasterUptimeView, |
| '17': App.ResourceManagerHeapPieChartView, |
| '18': App.ResourceManagerUptimeView, |
| '19': App.NodeManagersLiveView, |
| '20': App.YARNMemoryPieChartView, |
| '21': App.SuperVisorUpView, |
| '22': App.FlumeAgentUpView, |
| '23': App.YARNLinksView, |
| '24': App.HawqSegmentUpView, |
| '25': App.PxfUpView |
| }, id); |
| }, |
| |
| /** |
| * @type {Object|null} |
| */ |
| currentPrefObject: null, |
| |
| /** |
| * @type {Ember.Object} |
| */ |
| initPrefObject: Em.Object.create({ |
| dashboardVersion: 'new', |
| visible: [], |
| hidden: [], |
| threshold: {1: [80, 90], 2: [85, 95], 3: [90, 95], 4: [80, 90], 5: [1000, 3000], 6: [], 7: [], 8: [], 9: [], 10: [], 11: [], 12: [], 13: [70, 90], 14: [150, 250], 15: [3, 10], 16: [], |
| 17: [70, 90], 18: [], 19: [50, 75], 20: [50, 75], 21: [85, 95], 22: [85, 95], 23: [], 24: [75, 90], 25: []} // id:[thresh1, thresh2] |
| }), |
| |
| /** |
| * Key-name to store data in Local Storage and Persist |
| * @type {string} |
| */ |
| persistKey: Em.computed.format('user-pref-{0}-dashboard', 'App.router.loginName'), |
| |
| getUserPrefSuccessCallback: function (response, request, data) { |
| if (response) { |
| var initPrefObject = this.get('initPrefObject'); |
| initPrefObject.get('threshold'); |
| for(var k in response.threshold) { |
| if (response.threshold.hasOwnProperty(k)) { |
| if (response.threshold[k].length === 0 && initPrefObject.get('threshold')[k] && initPrefObject.get('threshold')[k].length) { |
| response.threshold[k] = initPrefObject.get('threshold')[k]; |
| } |
| } |
| } |
| this.set('currentPrefObject', response); |
| } |
| }, |
| |
| getUserPrefErrorCallback: function (request) { |
| }, |
| |
| /** |
| * Reset widgets visibility-status |
| */ |
| resetAllWidgets: function () { |
| var self = this; |
| App.showConfirmationPopup(function () { |
| if (!App.get('testMode')) { |
| self.postUserPref(self.get('persistKey'), self.get('initPrefObject')); |
| self.setDBProperty(self.get('persistKey'), self.get('initPrefObject')); |
| } |
| self.setProperties({ |
| currentTimeRangeIndex: 0, |
| customStartTime: null, |
| customEndTime: null |
| }); |
| self.translateToReal(self.get('initPrefObject')); |
| }); |
| }, |
| |
| showAlertsPopup: Em.K |
| |
| }); |