Changes in app.js between v3.1.1 and v3.2
diff --git a/Custom Dashboards/web/adminTemplate/app.js b/Custom Dashboards/web/adminTemplate/app.js | |
index f8bc020..3fb06b1 100644 | |
--- a/Custom Dashboards/web/adminTemplate/app.js | |
+++ b/Custom Dashboards/web/adminTemplate/app.js | |
@@ -5,14 +5,15 @@ | |
define([ | |
'angular', | |
- './directives/menu/menuLink', // load directives from the directives folder | |
+ './directives/menu/dashboardMenu', // load directives from the directives folder | |
+ './directives/menu/menuLink', | |
'./directives/menu/menuToggle', | |
'./directives/login/login', | |
- 'mango-3.0/maMaterialDashboards', // load mango-3.0 angular modules | |
- 'mango-3.0/maAppComponents', | |
+ 'mango-3.2/maMaterialDashboards', // load mango-3.2 angular modules | |
+ 'mango-3.2/maAppComponents', | |
'angular-ui-router', // load external angular modules | |
'angular-loading-bar' | |
-], function(angular, menuLink, menuToggle, login, maMaterialDashboards, maAppComponents) { | |
+], function(angular, dashboardMenu, menuLink, menuToggle, login, maMaterialDashboards, maAppComponents) { | |
'use strict'; | |
// create an angular app with our desired dependencies | |
@@ -26,34 +27,37 @@ var myAdminApp = angular.module('myAdminApp', [ | |
// add our directives to the app | |
myAdminApp | |
- .directive('menuLink', menuLink) | |
- .directive('menuToggle', menuToggle) | |
+ .component('dashboardMenu', dashboardMenu) | |
+ .component('menuLink', menuLink) | |
+ .component('menuToggle', menuToggle) | |
.directive('login', login); | |
-// define our pages, these are added to the $stateProvider in the config block below | |
-myAdminApp.constant('PAGES', [ | |
+// define our menu items, these are added to the $stateProvider in the config block below | |
+myAdminApp.constant('MENU_ITEMS', [ | |
{ | |
- state: 'dashboard', | |
- url: '/dashboard', | |
+ name: 'dashboard', | |
templateUrl: 'views/dashboard/main.html', | |
+ abstract: true, | |
+ menuHidden: true, | |
resolve: { | |
- auth: ['$rootScope', 'User', function($rootScope, User) { | |
- // retrieves the current user when we navigate to a dashboard page | |
- // if an error occurs the $stateChangeError listener redirects to the login page | |
- $rootScope.user = User.current(); | |
- return $rootScope.user.$promise; | |
- }], | |
- dashboardTranslations: ['Translate', function(Translate) { | |
+ auth: ['Translate', 'ADMIN_SETTINGS', function(Translate, ADMIN_SETTINGS) { | |
+ // thow an error if no user so the $stateChangeError listener redirects to the login page | |
+ if (!ADMIN_SETTINGS.user) { | |
+ throw 'No user'; | |
+ } | |
// load any translation namespaces you want to use in your app up-front | |
// so they can be used by the 'tr' filter | |
- return Translate.loadNamespaces(['dashboards']); | |
+ return Translate.loadNamespaces(['dashboards', 'common']); | |
}] | |
} | |
}, | |
{ | |
- state: 'login', | |
+ name: 'login', | |
url: '/login', | |
templateUrl: 'views/login.html', | |
+ menuHidden: true, | |
+ menuIcon: 'exit_to_app', | |
+ menuTr: 'header.login', | |
resolve: { | |
loginTranslations: ['Translate', function(Translate) { | |
return Translate.loadNamespaces('login'); | |
@@ -61,78 +65,85 @@ myAdminApp.constant('PAGES', [ | |
} | |
}, | |
{ | |
- state: 'dashboard.home', | |
+ name: 'logout', | |
+ url: '/logout', | |
+ menuHidden: true, | |
+ menuIcon: 'power_settings_new', // material icon name | |
+ menuTr: 'header.logout', | |
+ template: '<div></div>' | |
+ }, | |
+ { | |
+ name: 'dashboard.home', | |
url: '/home', | |
templateUrl: 'views/dashboard/home.html', | |
menuTr: 'dashboards.v3.dox.home', | |
- menuIcon: 'fa fa-home', // font awesome css classes for icon | |
- menuType: 'link' | |
+ menuIcon: 'home' | |
}, | |
{ | |
- state: 'dashboard.apiErrors', | |
+ name: 'dashboard.apiErrors', | |
url: '/api-errors', | |
templateUrl: 'views/dashboard/errors.html', | |
- menuTr: 'dashboards.v3.dox.apiErrors' | |
+ menuTr: 'dashboards.v3.dox.apiErrors', | |
+ menuIcon: 'warning', | |
+ menuHidden: true | |
}, | |
{ | |
- state: 'dashboard.section1', // define some nested pages | |
+ name: 'dashboard.section1', // define some nested pages | |
url: '/section-1', | |
menuText: 'Section 1', | |
- menuIcon: 'fa fa-building', | |
- menuType: 'toggle', | |
+ menuIcon: 'fa-building', | |
children: [ | |
{ | |
- state: 'dashboard.section1.page1', | |
+ name: 'dashboard.section1.page1', | |
templateUrl: 'views/section1/page1.html', // html file to display | |
url: '/page-1', | |
- menuText: 'Page 1', | |
- menuType: 'link' | |
+ menuText: 'Page 1' | |
}, | |
{ | |
- state: 'dashboard.section1.page2', | |
+ name: 'dashboard.section1.page2', | |
templateUrl: 'views/section1/page2.html', | |
url: '/page-2', | |
- menuText: 'Page 2', | |
- menuType: 'link' | |
+ menuText: 'Page 2' | |
} | |
] | |
}, | |
{ | |
- state: 'dashboard.section2', | |
+ name: 'dashboard.section2', | |
url: '/section-2', | |
menuText: 'Section 2', | |
- menuIcon: 'fa fa-bolt', | |
- menuType: 'toggle', | |
+ menuIcon: 'fa-bolt', | |
children: [ | |
{ | |
- state: 'dashboard.section2.page1', | |
+ name: 'dashboard.section2.page1', | |
templateUrl: 'views/section2/page1.html', | |
url: '/page-1', | |
- menuText: 'Page 1', | |
- menuType: 'link' | |
+ menuText: 'Page 1' | |
}, | |
{ | |
- state: 'dashboard.section2.page2', | |
+ name: 'dashboard.section2.page2', | |
templateUrl: 'views/section2/page2.html', | |
url: '/page-2', | |
- menuText: 'Page 2', | |
- menuType: 'link' | |
+ menuText: 'Page 2' | |
} | |
] | |
} | |
]); | |
myAdminApp.config([ | |
- 'PAGES', | |
+ 'MENU_ITEMS', | |
'$stateProvider', | |
'$urlRouterProvider', | |
'$httpProvider', | |
'$mdThemingProvider', | |
'$compileProvider', | |
-function(PAGES, $stateProvider, $urlRouterProvider, $httpProvider, $mdThemingProvider, $compileProvider) { | |
+ '$locationProvider', | |
+ '$mdAriaProvider', | |
+function(MENU_ITEMS, $stateProvider, $urlRouterProvider, $httpProvider, $mdThemingProvider, $compileProvider, $locationProvider, $mdAriaProvider) { | |
// disable angular debug info to speed up app | |
$compileProvider.debugInfoEnabled(false); | |
+ // disable aria warnings | |
+ $mdAriaProvider.disableWarnings(); | |
// configure the angular material colors | |
$mdThemingProvider | |
@@ -144,60 +155,60 @@ function(PAGES, $stateProvider, $urlRouterProvider, $httpProvider, $mdThemingPro | |
$httpProvider.interceptors.push('errorInterceptor'); | |
// set the default state | |
- $urlRouterProvider.otherwise('/dashboard/home'); | |
+ $urlRouterProvider.otherwise('/home'); | |
+ | |
+ // enable html5 mode URLs (i.e. no /#/... urls) | |
+ $locationProvider.html5Mode(true); | |
- // add the pages to $stateProvider | |
- addStates(PAGES); | |
+ // add the menu items to $stateProvider | |
+ var nextId = 1; | |
+ addStates(MENU_ITEMS); | |
- function addStates(pages, parent) { | |
- angular.forEach(pages, function(page, area) { | |
- if (page.state) { | |
- var state = { | |
- url: page.url | |
- } | |
- | |
- if (page.menuTr) { | |
- state.menuTr = page.menuTr; | |
+ function addStates(menuItems, parent) { | |
+ angular.forEach(menuItems, function(menuItem, parent) { | |
+ menuItem.id = nextId++; | |
+ if (menuItem.name || menuItem.state) { | |
+ if (menuItem.templateUrl) { | |
+ delete menuItem.template; | |
} | |
- if (page.menuText) { | |
- state.menuText = page.menuText; | |
+ if (!menuItem.templateUrl && !menuItem.template) { | |
+ menuItem.template = '<div ui-view></div>'; | |
+ menuItem['abstract'] = true; | |
} | |
- if (parent) { | |
- state.parentPage = parent; | |
+ if (!menuItem.name) { | |
+ menuItem.name = menuItem.state; | |
} | |
- if (page.templateUrl) { | |
- state.templateUrl = page.templateUrl; | |
- } else { | |
- state.template = '<div ui-view></div>'; | |
- state['abstract'] = true; | |
- } | |
- | |
- if (page.resolve) { | |
- state.resolve = page.resolve; | |
- } | |
- | |
- $stateProvider.state(page.state, state); | |
+ $stateProvider.state(menuItem); | |
} | |
- addStates(page.children, page); | |
+ addStates(menuItem.children, menuItem); | |
}); | |
} | |
}]); | |
myAdminApp.run([ | |
- 'PAGES', | |
+ 'MENU_ITEMS', | |
'$rootScope', | |
'$state', | |
'$timeout', | |
'$mdSidenav', | |
+ '$mdMedia', | |
'$mdColors', | |
'$MD_THEME_CSS', | |
'cssInjector', | |
-function(PAGES, $rootScope, $state, $timeout, $mdSidenav, $mdColors, $MD_THEME_CSS, cssInjector) { | |
- // add pages to the root scope so we can use them in the template | |
- $rootScope.pages = PAGES; | |
+ '$mdToast', | |
+ 'User', | |
+ 'ADMIN_SETTINGS', | |
+ 'Translate', | |
+function(MENU_ITEMS, $rootScope, $state, $timeout, $mdSidenav, $mdMedia, $mdColors, $MD_THEME_CSS, cssInjector, | |
+ $mdToast, User, ADMIN_SETTINGS, Translate) { | |
+ | |
+ // add the current user to the root scope | |
+ $rootScope.user = ADMIN_SETTINGS.user; | |
+ // add menu items to the root scope so we can use them in the template | |
+ $rootScope.menuItems = MENU_ITEMS; | |
// enables use of Javascript Math functions in the templates | |
$rootScope.Math = Math; | |
@@ -215,48 +226,185 @@ function(PAGES, $rootScope, $state, $timeout, $mdSidenav, $mdColors, $MD_THEME_C | |
// redirect to login page if we can't retrieve the current user when changing state | |
$rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) { | |
- if (error && (error.status === 401 || error.status === 403)) { | |
+ if (error && (error === 'No user' || error.status === 401 || error.status === 403)) { | |
event.preventDefault(); | |
- $state.loginRedirect = toState; | |
+ $state.loginRedirectUrl = $state.href(toState, toParams); | |
$state.go('login'); | |
+ } else { | |
+ $state.go('dashboard.home'); | |
} | |
}); | |
// change the bread-crumbs on the toolbar when we change state | |
$rootScope.$on("$stateChangeSuccess", function(event, toState, toParams, fromState, fromParams) { | |
var crumbs = []; | |
- var state = toState; | |
+ var state = $state.$current; | |
do { | |
if (state.menuTr) { | |
- crumbs.unshift({maTr: state.menuTr}); | |
+ crumbs.unshift({stateName: state.name, maTr: state.menuTr}); | |
} else if (state.menuText) { | |
- crumbs.unshift({text: state.menuText}); | |
+ crumbs.unshift({stateName: state.name, text: state.menuText}); | |
} | |
- } while (state = state.parentPage); | |
+ } while (state = state.parent); | |
$rootScope.crumbs = crumbs; | |
}); | |
// close the menu when we change state | |
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) { | |
- if ($state.includes('dashboard')) { | |
+ if ($state.includes('dashboard') && !$rootScope.navLockedOpen) { | |
$rootScope.closeMenu(); | |
} | |
+ if (toState.name === 'logout') { | |
+ event.preventDefault(); | |
+ User.logout().$promise.then(null, function() { | |
+ // consume error | |
+ }).then(function() { | |
+ $rootScope.user = null; | |
+ ADMIN_SETTINGS.user = null; | |
+ $state.go('login'); | |
+ }); | |
+ } | |
+ }); | |
+ | |
+ // wait for the dashboard view to be loaded then set it to open if the | |
+ // screen is a large one. By default the internal state of the sidenav thinks | |
+ // it is closed even if it is locked open | |
+ $rootScope.$on('$viewContentLoaded', function(event, view) { | |
+ if (view === '@dashboard') { | |
+ if ($mdMedia('gt-sm')) { | |
+ $rootScope.openMenu(); | |
+ } | |
+ } | |
+ }); | |
+ | |
+ // automatically open or close the menu when the screen size is changed | |
+ $rootScope.$watch($mdMedia.bind($mdMedia, 'gt-sm'), function(gtSm, prev) { | |
+ if (gtSm === prev) return; // ignore first "change" | |
+ | |
+ var sideNav = $mdSidenav('left'); | |
+ if (gtSm && !sideNav.isOpen()) { | |
+ sideNav.open(); | |
+ } | |
+ if (!gtSm && sideNav.isOpen()) { | |
+ sideNav.close(); | |
+ } | |
+ $rootScope.navLockedOpen = gtSm; | |
}); | |
+ | |
+ $rootScope.toggleMenu = function() { | |
+ var sideNav = $mdSidenav('left'); | |
+ if (sideNav.isOpen()) { | |
+ this.closeMenu(); | |
+ } else { | |
+ this.openMenu(); | |
+ } | |
+ }; | |
$rootScope.closeMenu = function() { | |
+ angular.element('#menu-button').blur(); | |
+ $rootScope.navLockedOpen = false; | |
$mdSidenav('left').close(); | |
- } | |
+ }; | |
$rootScope.openMenu = function() { | |
angular.element('#menu-button').blur(); | |
+ if ($mdMedia('gt-sm')) { | |
+ $rootScope.navLockedOpen = true; | |
+ } | |
$mdSidenav('left').open(); | |
- } | |
+ }; | |
+ | |
+ /** | |
+ * Watchdog timer alert and re-connect/re-login code | |
+ */ | |
+ | |
+ $rootScope.$on('mangoWatchdog', function(event, current, previous) { | |
+ var message; | |
+ var hideDelay = 0; // dont auto hide message | |
+ | |
+ if (current.status === previous.status) | |
+ return; | |
+ | |
+ switch(current.status) { | |
+ case 'API_DOWN': | |
+ message = Translate.trSync('dashboards.v3.app.apiDown'); | |
+ ADMIN_SETTINGS.user = null; | |
+ break; | |
+ case 'STARTING_UP': | |
+ message = Translate.trSync('dashboards.v3.app.startingUp'); | |
+ ADMIN_SETTINGS.user = null; | |
+ break; | |
+ case 'API_ERROR': | |
+ message = Translate.trSync('dashboards.v3.app.returningErrors'); | |
+ ADMIN_SETTINGS.user = null; | |
+ break; | |
+ case 'API_UP': | |
+ if (previous.status && previous.status !== 'LOGGED_IN') | |
+ message = Translate.trSync('dashboards.v3.app.connectivityRestored'); | |
+ hideDelay = 5000; | |
+ ADMIN_SETTINGS.user = null; | |
+ | |
+ // do automatic re-login if we are not on the login page | |
+ if (!$state.includes('login')) { | |
+ User.autoLogin().then(function(user) { | |
+ ADMIN_SETTINGS.user = user; | |
+ $rootScope.user = user; | |
+ }, function() { | |
+ // redirect to the login page if auto-login fails | |
+ window.location = $state.href('login'); | |
+ }); | |
+ } | |
+ break; | |
+ case 'LOGGED_IN': | |
+ // occurs almost simultaneously with API_UP message, only display if we didn't hit API_UP state | |
+ if (previous.status && previous.status !== 'API_UP') | |
+ message = Translate.trSync('dashboards.v3.app.connectivityRestored'); | |
+ if (!ADMIN_SETTINGS.user) { | |
+ // user logged in elsewhere | |
+ User.current().$promise.then(function(user) { | |
+ ADMIN_SETTINGS.user = user; | |
+ $rootScope.user = user; | |
+ }); | |
+ } | |
+ break; | |
+ } | |
+ $rootScope.user = ADMIN_SETTINGS.user; | |
+ | |
+ if (message) { | |
+ var toast = $mdToast.simple() | |
+ .textContent(message) | |
+ .action('OK') | |
+ .highlightAction(true) | |
+ .position('bottom center') | |
+ .hideDelay(hideDelay); | |
+ $mdToast.show(toast); | |
+ } | |
+ }); | |
+ | |
}]); | |
-// bootstrap the angular application | |
-angular.element(document).ready(function() { | |
- angular.bootstrap(document.documentElement, ['myAdminApp']); | |
+// get an injector to retrieve the User service | |
+var servicesInjector = angular.injector(['maServices'], true); | |
+var User = servicesInjector.get('User'); | |
+ | |
+var adminSettings = {}; | |
+ | |
+// get the current user or do auto login | |
+User.current().$promise.then(null, function() { | |
+ return User.autoLogin(); | |
+}).then(function(user) { | |
+ adminSettings.user = user; | |
+}).then(null, function() { | |
+ // consume error | |
+}).then(function() { | |
+ servicesInjector.get('$rootScope').$destroy(); | |
+ myAdminApp.constant('ADMIN_SETTINGS', adminSettings); | |
+ | |
+ // bootstrap the angular application | |
+ angular.element(document).ready(function() { | |
+ angular.bootstrap(document.documentElement, ['myAdminApp']); | |
+ }); | |
}); | |
}); // define |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment