From 05fd8a9c378367df2b512de86f94cbcadea86d4f Mon Sep 17 00:00:00 2001 From: Biswajit Mandal Date: Fri, 18 Jul 2014 17:22:23 +0530 Subject: [PATCH 01/13] Merging resources object across multiple feature packages --- src/serverroot/utils/common.utils.js | 139 +++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 10 deletions(-) diff --git a/src/serverroot/utils/common.utils.js b/src/serverroot/utils/common.utils.js index 72a01d259..9f30c06d6 100644 --- a/src/serverroot/utils/common.utils.js +++ b/src/serverroot/utils/common.utils.js @@ -26,6 +26,7 @@ var commonUtils = module.exports, dir = require('node-dir'), xml2js = require('xml2js'), js2xml = require('data2xml')(), + pd = require('pretty-data').pd, contrailPath = '/contrail'; if (!module.parent) { logutils.logger.warn(util.format( @@ -1378,6 +1379,116 @@ function getAllJsons (menuDir, callback) }); } +function createEmptyResourceObj () +{ + var obj = {}; + obj['resources'] = []; + obj['resources'][0] = {}; + obj['resources'][0]['resource'] = []; + return obj; +} + +function mergeResourceObjs (obj1, obj2) +{ + if (null == obj2['resources']) { + return obj1; + } + if (null == obj1['resources']) { + obj1 = createEmptyResourceObj(); + } + obj1['resources'][0]['resource'] = + obj1['resources'][0]['resource'].concat(obj2['resources'][0]['resource']); + return obj1; +} + +function mergeMenuItems (obj1, obj2) +{ + var found = false; + if (obj1['label'][0] == obj2['label'][0]) { + found = true; + var itemObj1 = obj1['items'][0]['item']; + var itemObj2 = obj2['items'][0]['item']; + var itemObj1Len = itemObj1.length; + var itemObj2Len = itemObj2.length; + + for (var i = 0; i < itemObj2Len; i++) { + for (var j = 0; j < itemObj1Len; j++) { + if (itemObj1[j]['label'][0] == itemObj2[i]['label'][0]) { + itemObj1[j] = mergeResourceObjs(itemObj1[j], itemObj2[i]); + break; + } + } + if (j == itemObj1Len) { + /* Not found so push it */ + itemObj1.push(itemObj2[i]); + } + } + } + return {obj: obj1, found: found}; +} + +function createResourceObject (obj) +{ + if ((null != obj['js']) || (null != obj['view']) || + (null != obj['class']) || (null != obj['rootDir']) || + (null != obj['css'])) {// || (null != obj['access'])) { + obj['resources'] = []; + obj['resources'][0] = {}; + obj['resources'][0]['resource'] = []; + obj['resources'][0]['resource'][0] = {}; + if (null != obj['rootDir']) { + obj['resources'][0]['resource'][0]['rootDir'] = obj['rootDir']; + delete obj['rootDir']; + } + if (null != obj['js']) { + obj['resources'][0]['resource'][0]['js'] = obj['js']; + delete obj['js']; + } + if (null != obj['view']) { + obj['resources'][0]['resource'][0]['view'] = obj['view']; + delete obj['view']; + } + if (null != obj['css']) { + obj['resources'][0]['resource'][0]['css'] = obj['css']; + delete obj['css']; + } + if (null != obj['class']) { + obj['resources'][0]['resource'][0]['class'] = obj['class']; + delete obj['class']; + } + /* + if (null != obj['access']) { + obj['resources'][0]['resource'][0]['access'] = obj['access']; + delete obj['access']; + } + */ + } + return obj; +} + +function checkAndCreateResourceObject (obj, isDeep) +{ + if (null != obj['resources']) { + return obj; + } + obj = createResourceObject(obj); + if (true == isDeep) { + if ((null != obj['items']) && (null != obj['items'][0]['item'])) { + var cnt = obj['items'][0]['item'].length; + for (var i = 0; i < cnt; i++) { + obj['items'][0]['item'][i] = + createResourceObject(obj['items'][0]['item'][i]); + } + } + } + return obj; +} + +function convertResourceObject (object) +{ + var obj = object['items'][0]['item']; +} + function mergeMenuObjects (menuObj1, menuObj2) { var found = false; @@ -1387,8 +1498,12 @@ function mergeMenuObjects (menuObj1, menuObj2) var itms1Len = itms1.length; var itms2Len = itms2.length; for (var k = 0; k < itms2Len; k++) { + found = false; for (var l = 0; l < itms1Len; l++) { + itms1[l] = checkAndCreateResourceObject(itms1[l], false); + itms2[k] = checkAndCreateResourceObject(itms2[k], false); if (itms1[l]['label'][0] == itms2[k]['label'][0]) { + found = true; if ((null == itms2[k]['items']) || (null == itms2[k]['items'][0]) || (null == itms2[k]['items'][0]['item'])) { @@ -1400,28 +1515,32 @@ function mergeMenuObjects (menuObj1, menuObj2) itms1[l]['items'] = []; itms1[l]['items'][0] = {}; itms1[l]['items'][0] = itms2[k]['items'][0]; + continue; } var items1 = itms1[l]['items'][0]['item']; var items2 = itms2[k]['items'][0]['item']; + var items1Len = items1.length; var items2Len = items2.length; for (var i = 0; i < items2Len; i++) { for (var j = 0; j < items1Len; j++) { - if (items1[j]['label'][0] == items2[i]['label'][0]) { - items1[j]['items'][0]['item'] = - items1[j]['items'][0]['item'].concat(items2[j]['items'][0]['item']); - found = true; - break; - } + items1[j] = checkAndCreateResourceObject(items1[j], + true); + items2[i] = checkAndCreateResourceObject(items2[i], true); + var newObj = mergeMenuItems(items1[j], items2[i]); + items1[j] = newObj['obj']; + objFound = newObj['found']; + break; } - if (j == items1Len) { + if (false == objFound) { items1.push(items2[i]); } } + break; } - if (l == itms1Len) { - itms1.push(itms2[k]); - } + } + if (found == false) { + itms1.push(itms2[k]); } } return menuObj1; From 0aac88d4e65d478e1e4c484bdc56d9769bf449ac Mon Sep 17 00:00:00 2001 From: Naga Kiran Date: Fri, 18 Jul 2014 12:59:58 +0530 Subject: [PATCH 02/13] Added support for specifying multiple resources for each feature in menu.xml --- webroot/js/web-utils.js | 128 +++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 62 deletions(-) diff --git a/webroot/js/web-utils.js b/webroot/js/web-utils.js index a9d91cc60..6129aa679 100644 --- a/webroot/js/web-utils.js +++ b/webroot/js/web-utils.js @@ -838,6 +838,7 @@ function pushBreadcrumb(breadcrumbsArr) { function MenuHandler() { var self = this; var menuObj; + //onHashChange is triggered once it is resolved self.deferredObj = $.Deferred(); var menuDefferedObj = $.Deferred(),statDefferredObj = $.Deferred(),webServerDefObj = $.Deferred(); @@ -1058,6 +1059,10 @@ function MenuHandler() { * JSON expectes item to be an array,but xml2json make item as an object if there is only one instance */ function processXMLJSON(json) { + if((json['resources'] != null) && json['resources']['resource'] != null) { + if(!(json['resources']['resource'] instanceof Array)) + json['resources']['resource'] = [json['resources']['resource']]; + } if ((json['items'] != null) && (json['items']['item'] != null)) { if (json['items']['item'] instanceof Array) { for (var i = 0; i < json['items']['item'].length; i++) { @@ -1175,7 +1180,7 @@ function MenuHandler() { this.loadResourcesFromMenuObj = function(currMenuObj,deferredObj) { var parents = currMenuObj['parents']; - if (currMenuObj['rootDir'] != null) { + if (currMenuObj['rootDir'] != null || getValueByJsonPath(currMenuObj,'resources;resource',[]).length > 0) { //Update page Hash only if we are moving to a different view var currHashObj = layoutHandler.getURLHashObj(); if (currHashObj['p'] != currMenuObj['hash']) { @@ -1189,85 +1194,84 @@ function MenuHandler() { if(parents != null && parents.length > 0){ $.each(parents,function(i,parent){ var parentRootDir = parent['rootDir']; - if (parentRootDir != null && parent['view'] != null) { + if (parentRootDir != null || getValueByJsonPath(parent,'resources;resource',[]).length > 0) { loadViewResources(parent,currMenuObj['hash']); loadCssResources(parent,currMenuObj['hash']); } }); } //Load the feature views - if (currMenuObj['view'] != null) { - loadViewResources(currMenuObj,currMenuObj['hash']); - } + loadViewResources(currMenuObj,currMenuObj['hash']); //Load the feature css files - if(currMenuObj['css'] != null) { - loadCssResources(currMenuObj); - } + loadCssResources(currMenuObj); + //View file need to be downloaded first before executing any JS file $.when.apply(window, viewDeferredObjs).done(function() { //Load the parent js if(parents != null && parents.length > 0){ $.each(parents,function(i,parent){ var parentRootDir = parent['rootDir']; - if (parentRootDir != null && parent['js'] != null) { + if (parentRootDir != null || getValueByJsonPath(parent,'resources;resource',[]).length > 0) { loadJsResources(parent); } }); } loadJsResources(currMenuObj); - /*$.each(currMenuObj['css'],function() { - deferredObjs.push(loadCSS(rootDir + '/css/' + this)); - });*/ $.when.apply(window, deferredObjs).done(function () { deferredObj.resolve(); }); }); - } - function loadViewResources(menuObj,hash){ - if (!(menuObj['view'] instanceof Array)) { - menuObj['view'] = [menuObj['view']]; + function loadViewResources(menuObj,hash) { + $.each(getValueByJsonPath(menuObj,'resources;resource',[]),function(idx,currResourceObj) { + if (!(currResourceObj['view'] instanceof Array)) { + currResourceObj['view'] = [currResourceObj['view']]; + } + $.each(currResourceObj['view'], function () { + var viewDeferredObj = $.Deferred(); + viewDeferredObjs.push(viewDeferredObj); + var viewPath = currResourceObj['rootDir'] + '/views/' + this + '?built_at=' + built_at; + templateLoader.loadExtTemplate(viewPath, viewDeferredObj, hash); + }); + }) } - $.each(menuObj['view'], function () { - var viewDeferredObj = $.Deferred(); - viewDeferredObjs.push(viewDeferredObj); - var viewPath = menuObj['rootDir'] + '/views/' + this + '?built_at=' + built_at; - templateLoader.loadExtTemplate(viewPath, viewDeferredObj, hash); - }); - } - function loadCssResources(menuObj,hash) { - if(menuObj['css'] == null) - return; - if (!(menuObj['css'] instanceof Array)) { - menuObj['css'] = [menuObj['css']]; + function loadCssResources(menuObj,hash) { + $.each(menuObj['resources']['resource'],function(idx,currResourceObj) { + if(currResourceObj['css'] == null) + return; + if (!(currResourceObj['css'] instanceof Array)) { + currResourceObj['css'] = [currResourceObj['css']]; + } + $.each(currResourceObj['css'],function() { + var cssPath = currResourceObj['rootDir'] + '/css/' + this; + if($.inArray(cssPath,globalObj['loadedCSS']) == -1) { + globalObj['loadedCSS'].push(cssPath); + var cssLink = $(""); + $('head').append(cssLink); + } + }); + }); + } + + function loadJsResources(menuObj) { + $.each(menuObj['resources']['resource'],function(idx,currResourceObj) { + if (!(currResourceObj['js'] instanceof Array)) + currResourceObj['js'] = [currResourceObj['js']]; + var isLoadFn = currResourceObj['loadFn'] != null ? true : false; + var isReloadRequired = true; + //Restrict not re-loading scripts only for monitor infrastructure and monitor networks for now + if(currResourceObj['class'] == 'infraMonitorView' || currResourceObj['class'] == 'tenantNetworkMonitorView') + isReloadRequired = false; + $.each(currResourceObj['js'], function () { + //Load the JS file only if it's not loaded already + //if (window[currResourceObj['class']] == null) + if(($.inArray(currResourceObj['rootDir'] + '/js/' + this,globalObj['loadedScripts']) == -1) || + (isLoadFn == true) || (isReloadRequired == true)) + deferredObjs.push(getScript(currResourceObj['rootDir'] + '/js/' + this)); + }); + }); } - $.each(menuObj['css'],function() { - var cssPath = menuObj['rootDir'] + '/css/' + this; - if($.inArray(cssPath,globalObj['loadedCSS']) == -1) { - globalObj['loadedCSS'].push(cssPath); - var cssLink = $(""); - $('head').append(cssLink); - } - }); - } - - function loadJsResources(menuObj){ - if (menuObj['js'] instanceof Array) { - } else - menuObj['js'] = [menuObj['js']]; - var isLoadFn = menuObj['loadFn'] != null ? true : false; - var isReloadRequired = true; - //Restrict not re-loading scripts only for monitor infrastructure and monitor networks for now - if(menuObj['class'] == 'infraMonitorView' || menuObj['class'] == 'tenantNetworkMonitorView') - isReloadRequired = false; - $.each(menuObj['js'], function () { - //Load the JS file only if it's not loaded already - //if (window[menuObj['class']] == null) - if(($.inArray(menuObj['rootDir'] + '/js/' + this,globalObj['loadedScripts']) == -1) || - (isLoadFn == true) || (isReloadRequired == true)) - deferredObjs.push(getScript(menuObj['rootDir'] + '/js/' + this)); - }); } } @@ -1278,14 +1282,14 @@ function MenuHandler() { try { self.loadResourcesFromMenuObj(currMenuObj,deferredObj); deferredObj.done(function () { - if (currMenuObj['loadFn'] != null) { - window[currMenuObj['loadFn']](); - } else if (currMenuObj['class'] != null) { - //Cleanup the container - $(contentContainer).html(''); - if(window[currMenuObj['class']] != null) - window[currMenuObj['class']].load({containerId:contentContainer, hashParams:layoutHandler.getURLHashParams()}); - } + //Cleanup the container + $(contentContainer).html(''); + $.each(currMenuObj['resources']['resource'],function(idx,currResourceObj) { + if (currResourceObj['class'] != null) { + if(window[currResourceObj['class']] != null) + window[currResourceObj['class']].load({containerId:contentContainer, hashParams:layoutHandler.getURLHashParams()}); + } + }); }); } catch (error) { console.log(error.stack); From 4d4a52872be979cce5b1485d374d57e5a7e3b4d7 Mon Sep 17 00:00:00 2001 From: Biswajit Mandal Date: Sat, 19 Jul 2014 01:36:14 +0530 Subject: [PATCH 03/13] Missed merging resources in some places --- src/serverroot/utils/common.utils.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/serverroot/utils/common.utils.js b/src/serverroot/utils/common.utils.js index 9f30c06d6..d68cac7a4 100644 --- a/src/serverroot/utils/common.utils.js +++ b/src/serverroot/utils/common.utils.js @@ -1405,6 +1405,7 @@ function mergeMenuItems (obj1, obj2) { var found = false; if (obj1['label'][0] == obj2['label'][0]) { + obj1 = mergeResourceObjs(obj1, obj2); found = true; var itemObj1 = obj1['items'][0]['item']; var itemObj2 = obj2['items'][0]['item']; @@ -1503,6 +1504,7 @@ function mergeMenuObjects (menuObj1, menuObj2) itms1[l] = checkAndCreateResourceObject(itms1[l], false); itms2[k] = checkAndCreateResourceObject(itms2[k], false); if (itms1[l]['label'][0] == itms2[k]['label'][0]) { + itms1[l] = mergeResourceObjs(itms1[l], itms2[k]); found = true; if ((null == itms2[k]['items']) || (null == itms2[k]['items'][0]) || From d74aa8c767ccd865f5665015df22615b5fb2d040 Mon Sep 17 00:00:00 2001 From: Naga Kiran Date: Mon, 21 Jul 2014 15:48:25 +0530 Subject: [PATCH 04/13] Fixed the issue that view is not loaded correctly when we change the URL hash parameters within the same page, Update the code that parses menu.xml to be consistent with the new format i.e specifying multiple resources for each feature --- webroot/js/contrail-layout.js | 20 ++++++++++---------- webroot/js/web-utils.js | 31 ++++++++++++++++++------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/webroot/js/contrail-layout.js b/webroot/js/contrail-layout.js index 0af040302..406e4564a 100644 --- a/webroot/js/contrail-layout.js +++ b/webroot/js/contrail-layout.js @@ -403,21 +403,21 @@ function onHashChange(lastHash, currHash) { menuHandler.toggleMenuButton(null, currPageHash, lastPageHash); //If curr URL is same as default URL, remove non-menu breadcrumbs //Always re-load the view if menu is clicked - if (((lastPageHash == currPageHash) || ((currMenuObj['class'] != null) && (currMenuObj['class'] == lastMenuObj['class']))) + + //If hashchange is within the same page + if ((lastPageHash == currPageHash) && (globalObj['menuClicked'] == null || globalObj['menuClicked'] == false)) { var deferredObj = $.Deferred(); - //Load JS files - if(currMenuObj['js'].length > 0) { - menuHandler.loadResourcesFromMenuObj(currMenuObj,deferredObj); - } else - deferredObj.resolve(); + menuHandler.loadResourcesFromMenuObj(currMenuObj,deferredObj); deferredObj.done(function() { //If hashchange is within the same page var currMenuObj = menuHandler.getMenuObjByHash(currPageHash); - if (window[currMenuObj['class']] != null && - window[currMenuObj['class']]['updateViewByHash'] != null) { - window[currMenuObj['class']].updateViewByHash(currPageQueryStr, lastPageQueryStr); - } + $.each(currMenuObj['resources']['resource'],function(idx,currResourceObj) { + if (window[currResourceObj['class']] != null && + window[currResourceObj['class']]['updateViewByHash'] != null) { + window[currResourceObj['class']].updateViewByHash(currPageQueryStr, lastPageQueryStr); + } + }); }); } else { globalObj['menuClicked'] = false; diff --git a/webroot/js/web-utils.js b/webroot/js/web-utils.js index 6129aa679..ef6b4cfa0 100644 --- a/webroot/js/web-utils.js +++ b/webroot/js/web-utils.js @@ -1132,19 +1132,24 @@ function MenuHandler() { if (currMenuObj == null) return; //Call destory function on viewClass which is being unloaded - if ((currMenuObj['class'] != null) && (typeof(window[currMenuObj['class']]) == 'function' || typeof(window[currMenuObj['class']]) == 'object') && - (typeof(window[currMenuObj['class']]['destroy']) == 'function')) { - $.allajax.abort(); - - try { - window[currMenuObj['class']]['destroy'](); - } catch (error) { - console.log(error.stack); + $.each(currMenuObj['resources']['resource'],function(idx,currResourceObj) { + if ((currResourceObj['class'] != null) && (typeof(window[currResourceObj['class']]) == 'function' || typeof(window[currResourceObj['class']]) == 'object') && + (typeof(window[currResourceObj['class']]['destroy']) == 'function')) { + $.allajax.abort(); + + try { + window[currResourceObj['class']]['destroy'](); + } catch (error) { + console.log(error.stack); + } } - } - //window[currMenuObj['class']] = null; + //window[currResourceObj['class']] = null; + }); } + /** + * parentsArr is used to load the resources specified in the menu hierarchy + */ this.getMenuObjByHash = function (menuHash, currMenuObj, parentsArr) { parentsArr = ifNull(parentsArr,[]) ; if (currMenuObj == null) @@ -1237,7 +1242,7 @@ function MenuHandler() { } function loadCssResources(menuObj,hash) { - $.each(menuObj['resources']['resource'],function(idx,currResourceObj) { + $.each(getValueByJsonPath(menuObj,'resources;resource',[]),function(idx,currResourceObj) { if(currResourceObj['css'] == null) return; if (!(currResourceObj['css'] instanceof Array)) { @@ -1255,7 +1260,7 @@ function MenuHandler() { } function loadJsResources(menuObj) { - $.each(menuObj['resources']['resource'],function(idx,currResourceObj) { + $.each(getValueByJsonPath(menuObj,'resources;resource',[]),function(idx,currResourceObj) { if (!(currResourceObj['js'] instanceof Array)) currResourceObj['js'] = [currResourceObj['js']]; var isLoadFn = currResourceObj['loadFn'] != null ? true : false; @@ -1284,7 +1289,7 @@ function MenuHandler() { deferredObj.done(function () { //Cleanup the container $(contentContainer).html(''); - $.each(currMenuObj['resources']['resource'],function(idx,currResourceObj) { + $.each(getValueByJsonPath(currMenuObj,'resources;resource',[]),function(idx,currResourceObj) { if (currResourceObj['class'] != null) { if(window[currResourceObj['class']] != null) window[currResourceObj['class']].load({containerId:contentContainer, hashParams:layoutHandler.getURLHashParams()}); From 5fead779b39cc2dd0765a4ab3fab386d6d7317c1 Mon Sep 17 00:00:00 2001 From: Vishnu Vardhan V Date: Wed, 23 Jul 2014 23:43:28 +0530 Subject: [PATCH 05/13] Fixed the issue Bug #1338520,where alerts popup dont show any alerts,widget in right bottom show alerts Now we are updating alerts popup grid datasource whenever the infra nodes datasource change event triggers and separated the info boxes and alerts updating functions Change-Id: Ia37d5ffa6e26d3b57a80db37f93cd251b125743e Conflicts: webroot/js/dashboard-utils.js webroot/js/web-utils.js --- webroot/js/dashboard-utils.js | 85 ++++++++++----- webroot/js/web-utils.js | 199 ++++++++++++++++++---------------- 2 files changed, 165 insertions(+), 119 deletions(-) diff --git a/webroot/js/dashboard-utils.js b/webroot/js/dashboard-utils.js index baceeb0f0..5dbeb538c 100644 --- a/webroot/js/dashboard-utils.js +++ b/webroot/js/dashboard-utils.js @@ -7,7 +7,6 @@ function infraMonitorClass() { var viewModels=[]; var dashboardConfig = []; var tabs = []; - //Show down node count only if it's > 0 function showHideDownNodeCnt() { var downSelectors = $('[data-bind="text:downCnt"]'); @@ -35,18 +34,11 @@ function infraMonitorClass() { this.updateViewByHash = function (hashObj, lastHashObj) { self.load({hashParams:hashObj}); } - - this.updateAlertsAndInfoBoxes = function() { - var infoListTemplate = contrail.getTemplate4Id("infoList-template"); - var alertTemplate=contrail.getTemplate4Id("alerts-template"); - var dashboardDataArr = []; - var nodeAlerts=self.getNodeAlerts(viewModels); + this.updateInfoBoxes = function() { + var infoListTemplate = contrail.getTemplate4Id("infoList-template"),dashboardDataArr = [];; $.each(viewModels,function(idx,currViewModel) { dashboardDataArr = dashboardDataArr.concat(currViewModel.data()); }); - var processAlerts = self.getAllProcessAlerts(viewModels); - var allAlerts = nodeAlerts.concat(processAlerts); - allAlerts.sort(dashboardUtils.sortInfraAlerts); var dashboardCF = crossfilter(dashboardDataArr); var nameDimension = dashboardCF.dimension(function(d) { return d.name }); var verDimension = dashboardCF.dimension(function(d) { return d.version }); @@ -71,24 +63,54 @@ function infraMonitorClass() { infoData.push({lbl:'version',value:verGroup.all()[0]['key']}); $('#system-info-stat').html(infoListTemplate(infoData)); endWidgetLoading('sysinfo'); - if(timeStampAlert.length > 0) - allAlerts = allAlerts.concat(timeStampAlert) - globalObj['alertsData'] = allAlerts; - if(globalObj.showAlertsPopup){ - loadAlertsContent(); - } - var detailAlerts = []; - for(var i = 0; i < allAlerts.length; i++ ){ - if(allAlerts[i]['detailAlert'] != false) - detailAlerts.push(allAlerts[i]); - } - //Display only 5 alerts in "Dashboard" - $('#alerts-box-content').html(alertTemplate(detailAlerts.slice(0,5))); - endWidgetLoading('alerts'); - $("#moreAlertsLink").click(loadAlertsContent); } - + this.updateAlerts = function(){ + var alertTemplate=contrail.getTemplate4Id("alerts-template"); + var nodeAlerts=self.getNodeAlerts(viewModels); + var processAlerts = self.getAllProcessAlerts(viewModels); + var allAlerts = nodeAlerts.concat(processAlerts); + allAlerts.sort(dashboardUtils.sortInfraAlerts); + if(timeStampAlert.length > 0) + allAlerts = allAlerts.concat(timeStampAlert) + //Filtering the alerts for alerts popup based on the detailAlert flag + var popupAlerts = []; + for(var i=0;i 0) + alertDS['dataSource'].setData(popupAlerts); + if(globalObj.showAlertsPopup){ + alertsDef = alertDS['deferredObj']; + loadAlertsContent(alertsDef); + } + /*Need to resolve the alertsDef once all the alertsDS depend datasource are loaded + */ + var allDSResolved = true; + if(alertDS['depends'] instanceof Array) { + for(var i = 0; i < alertDS['depends'].length; i++){ + var dataSource = globalObj['dataSources'][alertDS['depends'][i]]; + if(manageDataSource.isLoading(dataSource)) + allDSResolved = false + } + } + if(allDSResolved && alertsDef != null) + alertsDef.resolve(); + var detailAlerts = []; + for(var i = 0; i < allAlerts.length; i++ ){ + if(allAlerts[i]['detailAlert'] != false) + detailAlerts.push(allAlerts[i]); + } + //Display only 5 alerts in "Dashboard" + $('#alerts-box-content').html(alertTemplate(detailAlerts.slice(0,5))); + endWidgetLoading('alerts'); + $("#moreAlertsLink").click(function(){ + loadAlertsContent(); + }); + } + this.addInfoBox = function(infoBoxObj) { //If dashboard is not already loaded,load it if($('.infobox-container').length == 0) @@ -111,7 +133,8 @@ function infraMonitorClass() { $(nodeDS).on('change',function() { var data = dataSource.getItems(); obj['viewModel'].data(data); - self.updateAlertsAndInfoBoxes(); + self.updateInfoBoxes(); + self.updateAlerts(); }); infoBoxObj['viewModel'].downCnt.subscribe(function(newValue) { showHideDownNodeCnt(); @@ -220,7 +243,13 @@ function infraMonitorClass() { loadInfoBoxes(); loadLogs(); - + //Setting the alertsDS in global datasource object + //depends attribute conveys the datasource dependcies + globalObj['dataSources']['alertsDS'] = { + dataSource:new ContrailDataView(), + depends:['controlNodeDS','computeNodeDS','analyticsNodeDS','configNodeDS'], + deferredObj: $.Deferred() + } //Initialize the common stuff $($('#dashboard-stats .widget-header')[0]).initWidgetHeader({title:'Logs',widgetBoxId :'logs'}); $($('#dashboard-stats .widget-header')[1]).initWidgetHeader({title:'System Information', widgetBoxId: 'sysinfo'}); diff --git a/webroot/js/web-utils.js b/webroot/js/web-utils.js index ef6b4cfa0..530f0452f 100644 --- a/webroot/js/web-utils.js +++ b/webroot/js/web-utils.js @@ -1843,102 +1843,107 @@ function processDrillDownForNodes(e) { } } -function loadAlertsContent(){ - if(globalObj.alertsData!=undefined) { - var data = globalObj.alertsData; - var renderPopupEveryTime = true,alertsData = []; - $('#header ul li.nav-header').text(data.length+' New Alerts'); - var alerts = contrail.getTemplate4Id("alerts-template"); - for(var i=0;i"+statusTemplate({sevLevel:dc['sevLevel'],sevLevels:sevLevels})+dc['name']+""; - else - return dc['name']; - }, - events: { - onClick: function(e,dc) { - var nodeType = dc['pName']; - if(dc['link'] != null) - layoutHandler.setURLHashObj(dc['link']); - } - }, - cssClass: 'cell-hyperlink-blue', - },{ - field:'type', - name:'Process', - minWidth:100 - },{ - field:'msg', - name:'Status', - minWidth:200, - },{ - field:'timeStamp', - name:'Time', - minWidth:100, - formatter:function(r,c,v,cd,dc) { - if(typeof(dc['timeStamp']) != "undefined") - return getFormattedDate(dc['timeStamp']/1000); - else - return ""; - } - }] + dataSource: { + dataView: alertsDS, + }, + statusMessages: { + empty: { + text: 'No Alerts to display' + }, + errorGettingData: { + type: 'error', + iconClasses: 'icon-warning', + text: 'Error in getting Data.' + } } - }); - } - alertsWindow.modal('show'); - alertsGrid = $('#alertContent').data('contrailGrid'); + }, + columnHeader: { + columns:[ + { + field:'name', + name:'Node', + minWidth:150, + formatter: function(r,c,v,cd,dc){ + if(typeof(dc['sevLevel']) != "undefined" && typeof(dc['name']) != "undefined") + return ""+statusTemplate({sevLevel:dc['sevLevel'],sevLevels:sevLevels})+dc['name']+""; + else + return dc['name']; + }, + events: { + onClick: function(e,dc) { + var nodeType = dc['pName']; + if(dc['link'] != null) + layoutHandler.setURLHashObj(dc['link']); + } + }, + cssClass: 'cell-hyperlink-blue', + },{ + field:'type', + name:'Process', + minWidth:100 + },{ + field:'msg', + name:'Status', + minWidth:200, + },{ + field:'timeStamp', + name:'Time', + minWidth:100, + formatter:function(r,c,v,cd,dc) { + if(typeof(dc['timeStamp']) != "undefined") + return getFormattedDate(dc['timeStamp']/1000); + else + return ""; + } + }] + } + }); + } + alertsWindow.modal('show'); + alertsGrid = $('#alertContent').data('contrailGrid'); + if(alertsGrid != null) { alertsGrid.refreshView(); alertsGrid._grid.resizeCanvas(); - alertsGrid.removeGridLoading(); - globalObj.showAlertsPopup = false; + if(deferredObj != null) { + deferredObj.always(function(){ + alertsGrid.removeGridLoading(); + alertsGrid._eventHandlerMap.dataView['onUpdateData'](); + }); + } else { + alertsGrid.removeGridLoading(); + alertsGrid._eventHandlerMap.dataView['onUpdateData'](); + } } + globalObj.showAlertsPopup = false; } @@ -1985,7 +1990,6 @@ function ManageDataSource() { dataSource:null, error:null }, - //PortRange data for Port Distribution drill-down 'portRangeData':{ }, @@ -2098,6 +2102,19 @@ function ManageDataSource() { }); return dsObj; } + /** + * This function returns the state of the Datasource, whether it is populated or in progress based on the deferred object state + */ + this.isLoading = function(dsObj) { + if(dsObj['deferredObj'] != null) { + var defObj = dsObj['deferredObj'],state = defObj.state(); + if(state == 'pending') + return true; + else(state == 'resolved' || state == 'rejected') + return false; + } + return null; + } /** * Cache the portRange data retrieved at 2nd level (Port Range) in Port Distribution drill-down to use at 3rd level (Specific Port) From 4f08ce2659d023761eeea1f041cec95b45e73f9f Mon Sep 17 00:00:00 2001 From: Naga Kiran Date: Wed, 30 Jul 2014 12:04:07 +0530 Subject: [PATCH 06/13] While drilling down on overlapped tooltip, Currently processDrillDownForNodes function is called. Modified to use the 'clickFn' if provided as part of initScatterChart config option which handles drilldown Change-Id: Ia925c2952e47f43023286af892dad81c607e6960 --- webroot/js/chart-utils.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/webroot/js/chart-utils.js b/webroot/js/chart-utils.js index a91894378..7cbfd3597 100644 --- a/webroot/js/chart-utils.js +++ b/webroot/js/chart-utils.js @@ -289,7 +289,10 @@ } function bubbleDrillDown(nodeName,nodeMap) { var e = nodeMap[nodeName]; - processDrillDownForNodes(e); + if(typeof(chartOptions['clickFn']) == 'function') + chartOptions['clickFn'](e['point']); + else + processDrillDownForNodes(e); } $(window).off('resize.multiTooltip'); $(window).on('resize.multiTooltip',function(e){ From 66f2211345cae56c7c8ae2c73280a564533107fa Mon Sep 17 00:00:00 2001 From: Naga Kiran Date: Thu, 24 Jul 2014 16:05:39 +0530 Subject: [PATCH 07/13] Fixed issue that feature screens are not loaded on clicking feature menu in Firefox browser Change-Id: I86d2e0a8234d46af4b752b6baa9a4897a5fd81ec --- webroot/js/web-utils.js | 65 +++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/webroot/js/web-utils.js b/webroot/js/web-utils.js index 530f0452f..97fa17e85 100644 --- a/webroot/js/web-utils.js +++ b/webroot/js/web-utils.js @@ -1132,7 +1132,7 @@ function MenuHandler() { if (currMenuObj == null) return; //Call destory function on viewClass which is being unloaded - $.each(currMenuObj['resources']['resource'],function(idx,currResourceObj) { + $.each(getValueByJsonPath(currMenuObj,'resources;resource',[]),function(idx,currResourceObj) { if ((currResourceObj['class'] != null) && (typeof(window[currResourceObj['class']]) == 'function' || typeof(window[currResourceObj['class']]) == 'object') && (typeof(window[currResourceObj['class']]['destroy']) == 'function')) { $.allajax.abort(); @@ -1195,38 +1195,7 @@ function MenuHandler() { var deferredObjs = []; var rootDir = currMenuObj['rootDir']; var viewDeferredObjs = []; - //Load the parent views - if(parents != null && parents.length > 0){ - $.each(parents,function(i,parent){ - var parentRootDir = parent['rootDir']; - if (parentRootDir != null || getValueByJsonPath(parent,'resources;resource',[]).length > 0) { - loadViewResources(parent,currMenuObj['hash']); - loadCssResources(parent,currMenuObj['hash']); - } - }); - } - //Load the feature views - loadViewResources(currMenuObj,currMenuObj['hash']); - //Load the feature css files - loadCssResources(currMenuObj); - //View file need to be downloaded first before executing any JS file - $.when.apply(window, viewDeferredObjs).done(function() { - //Load the parent js - if(parents != null && parents.length > 0){ - $.each(parents,function(i,parent){ - var parentRootDir = parent['rootDir']; - if (parentRootDir != null || getValueByJsonPath(parent,'resources;resource',[]).length > 0) { - loadJsResources(parent); - } - }); - } - loadJsResources(currMenuObj); - $.when.apply(window, deferredObjs).done(function () { - deferredObj.resolve(); - }); - }); - function loadViewResources(menuObj,hash) { $.each(getValueByJsonPath(menuObj,'resources;resource',[]),function(idx,currResourceObj) { if (!(currResourceObj['view'] instanceof Array)) { @@ -1277,6 +1246,38 @@ function MenuHandler() { }); }); } + + //Load the parent views + if(parents != null && parents.length > 0){ + $.each(parents,function(i,parent){ + var parentRootDir = parent['rootDir']; + if (parentRootDir != null || getValueByJsonPath(parent,'resources;resource',[]).length > 0) { + loadViewResources(parent,currMenuObj['hash']); + loadCssResources(parent,currMenuObj['hash']); + } + }); + } + //Load the feature views + loadViewResources(currMenuObj,currMenuObj['hash']); + //Load the feature css files + loadCssResources(currMenuObj); + + //View file need to be downloaded first before executing any JS file + $.when.apply(window, viewDeferredObjs).done(function() { + //Load the parent js + if(parents != null && parents.length > 0){ + $.each(parents,function(i,parent){ + var parentRootDir = parent['rootDir']; + if (parentRootDir != null || getValueByJsonPath(parent,'resources;resource',[]).length > 0) { + loadJsResources(parent); + } + }); + } + loadJsResources(currMenuObj); + $.when.apply(window, deferredObjs).done(function () { + deferredObj.resolve(); + }); + }); } } From dc8aebd740ab4cc49c932312e2458f510526f5b1 Mon Sep 17 00:00:00 2001 From: Naga Kiran Date: Fri, 1 Aug 2014 15:32:41 +0530 Subject: [PATCH 08/13] Fixes bug#1349401:With longer user names, config tab is not available in Contrail UI Earlier, the width of div enclosing logged-in username is not enough to enclose bigger usernames which is making "Alerts" button to come in next row blocking the access to click on "Configure" menu button. Increase the width of div such that "Alerts" button doesn't come in second row. Change-Id: I99f18b13521115dacec5fc9f5ea0e882b603839b --- webroot/css/contrail.custom.css | 6 +++++- webroot/html/dashboard.tmpl | 34 ++++++++++++++++----------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/webroot/css/contrail.custom.css b/webroot/css/contrail.custom.css index 06a1a1cb5..6738b968a 100644 --- a/webroot/css/contrail.custom.css +++ b/webroot/css/contrail.custom.css @@ -1487,4 +1487,8 @@ color: #b94a48; } .rule-item .select2-container, .rule-item input { background : transparent; -} \ No newline at end of file +} + +#pageHeader.navbar .nav > li { + float:right; +} diff --git a/webroot/html/dashboard.tmpl b/webroot/html/dashboard.tmpl index 4cf595fbd..d250a738d 100644 --- a/webroot/html/dashboard.tmpl +++ b/webroot/html/dashboard.tmpl @@ -48,13 +48,28 @@ - + +