Skip to content

Instantly share code, notes, and snippets.

@jazdw
Created September 7, 2016 15:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jazdw/8a28f156fa3a39d1712b929be8866248 to your computer and use it in GitHub Desktop.
Save jazdw/8a28f156fa3a39d1712b929be8866248 to your computer and use it in GitHub Desktop.
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