Autogenerate the main menu.

This commit is contained in:
Oskar Hahn 2015-09-05 17:15:37 +02:00
parent 948e776d33
commit 2da2177c49
7 changed files with 213 additions and 89 deletions

View File

@ -47,6 +47,19 @@ angular.module('OpenSlidesApp.agenda', ['OpenSlidesApp.users'])
angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda']) angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
.config([
'mainMenuProvider',
function (mainMenuProvider) {
mainMenuProvider.register({
'ui_sref': 'agenda.item.list',
'img_class': 'calendar-o',
'title': 'Agenda',
'weight': 200,
'perm': 'agenda.can_see',
});
}
])
.config(function($stateProvider) { .config(function($stateProvider) {
$stateProvider $stateProvider
.state('agenda', { .state('agenda', {

View File

@ -20,6 +20,19 @@ angular.module('OpenSlidesApp.assignments', [])
angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
.config([
'mainMenuProvider',
function (mainMenuProvider) {
mainMenuProvider.register({
'ui_sref': 'assignments.assignment.list',
'img_class': 'pie-chart',
'title': 'Elections',
'weight': 400,
'perm': 'assignments.can_see'
});
}
])
.config(function($stateProvider) { .config(function($stateProvider) {
$stateProvider $stateProvider
.state('assignments', { .state('assignments', {

View File

@ -99,9 +99,15 @@ angular.module('OpenSlidesApp.core', [
} }
]) ])
.run(['loadGlobalData', function(loadGlobalData) { // Load the global data on startup and when the operator changes
loadGlobalData(); .run([
}]) 'loadGlobalData',
'operator',
function(loadGlobalData, operator) {
loadGlobalData();
operator.onOperatorChange(loadGlobalData);
}
])
.factory('jsDataModel', ['$http', 'Projector', function($http, Projector) { .factory('jsDataModel', ['$http', 'Projector', function($http, Projector) {
var BaseModel = function() {}; var BaseModel = function() {};
@ -176,6 +182,70 @@ angular.module('OpenSlidesApp.core.site', [
'xeditable', 'xeditable',
]) ])
// Provider to register entries for the main menu.
.provider('mainMenu', [
function() {
var mainMenuList = [];
var scope;
this.register = function(config) {
mainMenuList.push(config);
};
this.$get = ['operator', function(operator) {
return {
registerScope: function (scope) {
var that = this;
this.scope = scope;
this.updateMainMenu();
operator.onOperatorChange(function () {that.updateMainMenu()});
},
updateMainMenu: function () {
this.scope.elements = this.getElements();
},
getElements: function() {
var elements = mainMenuList.filter(function (element) {
return typeof element.perm === "undefined" || operator.hasPerms(element.perm);
});
elements.sort(function (a, b) {
return a.weight - b.weight;
});
return elements;
}
}
}];
}
])
.config([
'mainMenuProvider',
function (mainMenuProvider) {
mainMenuProvider.register({
'ui_sref': 'dashboard',
'img_class': 'home',
'title': 'Home',
'weight': 100,
});
mainMenuProvider.register({
'ui_sref': 'core.customslide.list',
'img_class': 'video-camera',
'title': 'Projector',
'weight': 110,
'perm': 'core.can_see_projector',
});
mainMenuProvider.register({
'ui_sref': 'config',
'img_class': 'cog',
'title': 'Settings',
'weight': 1000,
'perm': 'core.can_manage_config',
});
}
])
.config(function($urlRouterProvider, $locationProvider) { .config(function($urlRouterProvider, $locationProvider) {
// define fallback url and html5Mode // define fallback url and html5Mode
$urlRouterProvider.otherwise('/'); $urlRouterProvider.otherwise('/');
@ -419,6 +489,14 @@ angular.module('OpenSlidesApp.core.site', [
} }
}) })
.controller("MainMenuCtrl", [
'$scope',
'mainMenu',
function ($scope, mainMenu) {
mainMenu.registerScope($scope);
}
])
.controller("LanguageCtrl", function ($scope, gettextCatalog) { .controller("LanguageCtrl", function ($scope, gettextCatalog) {
// controller to switch app language // controller to switch app language
// TODO: detect browser language for default language // TODO: detect browser language for default language
@ -449,8 +527,7 @@ angular.module('OpenSlidesApp.core.site', [
'$modalInstance', '$modalInstance',
'$http', '$http',
'operator', 'operator',
'loadGlobalData', function ($scope, $modalInstance, $http, operator) {
function ($scope, $modalInstance, $http, operator, loadGlobalData) {
$scope.login = function () { $scope.login = function () {
$http.post( $http.post(
'/users/login/', '/users/login/',
@ -458,7 +535,6 @@ angular.module('OpenSlidesApp.core.site', [
).success(function(data) { ).success(function(data) {
if (data.success) { if (data.success) {
operator.setUser(data.user_id); operator.setUser(data.user_id);
loadGlobalData();
$scope.loginFailed = false; $scope.loginFailed = false;
$modalInstance.close(); $modalInstance.close();
} else { } else {

View File

@ -103,18 +103,21 @@
<span class="caret"></span> <span class="caret"></span>
</button> </button>
<ul class="dropdown-menu dropdown-menu-right" role="menu"> <ul class="dropdown-menu dropdown-menu-right" role="menu">
<li><a href="" ng-click="switchLanguage('en')"> <li>
<i class="fa fa-flag"></i> <a href="" ng-click="switchLanguage('en')">
<translate>English</translate> (EN) <i class="fa fa-flag"></i>
</a> <translate>English</translate> (EN)
<li><a href="" ng-click="switchLanguage('de')"> </a>
<i class="fa fa-flag"></i> <li>
<translate>German</translate> (DE) <a href="" ng-click="switchLanguage('de')">
</a> <i class="fa fa-flag"></i>
<li><a href="" ng-click="switchLanguage('fr')"> <translate>German</translate> (DE)
<i class="fa fa-flag"></i> </a>
<translate>French</translate> (FR) <li>
</a> <a href="" ng-click="switchLanguage('fr')">
<i class="fa fa-flag"></i>
<translate>French</translate> (FR)
</a>
</ul> </ul>
</div> </div>
</div> </div>
@ -124,48 +127,12 @@
<!-- Container --> <!-- Container -->
<div class="container-fluid" id="container"> <div class="container-fluid" id="container">
<div class="row"> <div class="row">
<!-- TODO: Build main menu automatically from installed apps, see issue #1469 -->
<div class="col-md-2 leftmenu lefticon"> <div class="col-md-2 leftmenu lefticon">
<ul> <ul ng-controller="MainMenuCtrl">
<li> <li ng-repeat="element in elements">
<a ui-sref="dashboard"> <a ui-sref="{{ element.ui_sref }}">
<span class="ico"><i class="fa fa-home fa-lg"></i></span> <span class="ico"><i class="fa fa-{{ element.img_class }} fa-lg"></i></span>
<span class="text" translate>Home</span> <span class="text" translate>{{ element.title }}</span>
</a>
<li>
<a ui-sref="core.customslide.list">
<span class="ico"><i class="fa fa-video-camera fa-lg"></i></span>
<span class="text" translate>Projector</span>
</a>
<li>
<a ui-sref="agenda.item.list">
<span class="ico"><i class="fa fa-calendar-o fa-lg"></i></span>
<span class="text" translate>Agenda</span>
</a>
<li>
<a ui-sref="motions.motion.list">
<span class="ico"><i class="fa fa-file-text fa-lg"></i></span>
<span class="text" translate>Motions</span>
</a>
<li>
<a ui-sref="assignments.assignment.list">
<span class="ico"><i class="fa fa-pie-chart fa-lg"></i></span>
<span class="text" translate>Elections</span>
</a>
<li>
<a ui-sref="users.user.list">
<span class="ico"><i class="fa fa-user fa-lg"></i></span>
<span class="text" translate>Participants</span>
</a>
<li>
<a ui-sref="mediafiles.mediafile.list">
<span class="ico"><i class="fa fa-paperclip fa-lg"></i></span>
<span class="text" translate>Files</span>
</a>
<li>
<a ui-sref="config">
<span class="ico"><i class="fa fa-cog fa-lg"></i></span>
<span class="text" translate>Settings</span>
</a> </a>
</ul> </ul>
</div> </div>

View File

@ -13,6 +13,19 @@ angular.module('OpenSlidesApp.mediafiles', [])
angular.module('OpenSlidesApp.mediafiles.site', ['OpenSlidesApp.mediafiles']) angular.module('OpenSlidesApp.mediafiles.site', ['OpenSlidesApp.mediafiles'])
.config([
'mainMenuProvider',
function (mainMenuProvider) {
mainMenuProvider.register({
'ui_sref': 'mediafiles.mediafile.list',
'img_class': 'paperclip',
'title': 'Files',
'weight': 600,
'perm': 'mediafiles.can_see',
});
}
])
.config(function($stateProvider) { .config(function($stateProvider) {
$stateProvider $stateProvider
.state('mediafiles', { .state('mediafiles', {

View File

@ -77,6 +77,19 @@ angular.module('OpenSlidesApp.motions', [])
angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions']) angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
.config([
'mainMenuProvider',
function (mainMenuProvider) {
mainMenuProvider.register({
'ui_sref': 'motions.motion.list',
'img_class': 'file-text',
'title': 'Motions',
'weight': 300,
'perm': 'motions.can_see',
});
}
])
.config(function($stateProvider) { .config(function($stateProvider) {
$stateProvider $stateProvider
.state('motions', { .state('motions', {

View File

@ -77,6 +77,19 @@ angular.module('OpenSlidesApp.users', [])
angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users']) angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
.config([
'mainMenuProvider',
function (mainMenuProvider) {
mainMenuProvider.register({
'ui_sref': 'users.user.list',
'img_class': 'user',
'title': 'Participants',
'weight': 500,
'perm': 'users.can_see_name',
});
}
])
.config(function($stateProvider) { .config(function($stateProvider) {
$stateProvider $stateProvider
.state('users', { .state('users', {
@ -165,38 +178,54 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
}); });
}) })
.factory('operator', function(User, Group) { .factory('operator', [
var operator = { 'User',
user: null, 'Group',
perms: [], 'loadGlobalData',
isAuthenticated: function() { function(User, Group, loadGlobalData) {
return !!this.user; var operatorChangeCallbacks = [];
}, var operator = {
setUser: function(user_id) { user: null,
if (user_id) { perms: [],
User.find(user_id).then(function(user) { isAuthenticated: function () {
operator.user = user; return !!this.user;
// TODO: load only the needed groups },
Group.findAll().then(function() { onOperatorChange: function (func) {
operator.perms = user.getPerms(); operatorChangeCallbacks.push(func);
},
setUser: function(user_id) {
if (user_id) {
User.find(user_id).then(function(user) {
operator.user = user;
// TODO: load only the needed groups
Group.findAll().then(function() {
operator.perms = user.getPerms();
_.forEach(operatorChangeCallbacks, function (callback) {
callback();
});
});
}); });
}); } else {
} else { operator.user = null;
operator.user = null; Group.find(1).then(function(group) {
Group.find(1).then(function(group) { operator.perms = group.permissions;
operator.perms = group.permissions; _.forEach(operatorChangeCallbacks, function (callback) {
}); callback();
} });
}, });
hasPerms: function(perms) { }
if (typeof perms == 'string') { },
perms = perms.split(' '); // Returns true if the operator has at least one perm of the perms-list.
} hasPerms: function(perms) {
return _.intersection(perms, operator.perms).length > 0; if (typeof perms == 'string') {
}, perms = perms.split(' ');
}
return _.intersection(perms, operator.perms).length > 0;
},
}
return operator;
} }
return operator; ])
})
.run(function(operator, $rootScope, $http) { .run(function(operator, $rootScope, $http) {
// Put the operator into the root scope // Put the operator into the root scope