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
.run([
'loadGlobalData',
'operator',
function(loadGlobalData, operator) {
loadGlobalData(); 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,15 +103,18 @@
<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>
<a href="" ng-click="switchLanguage('en')">
<i class="fa fa-flag"></i> <i class="fa fa-flag"></i>
<translate>English</translate> (EN) <translate>English</translate> (EN)
</a> </a>
<li><a href="" ng-click="switchLanguage('de')"> <li>
<a href="" ng-click="switchLanguage('de')">
<i class="fa fa-flag"></i> <i class="fa fa-flag"></i>
<translate>German</translate> (DE) <translate>German</translate> (DE)
</a> </a>
<li><a href="" ng-click="switchLanguage('fr')"> <li>
<a href="" ng-click="switchLanguage('fr')">
<i class="fa fa-flag"></i> <i class="fa fa-flag"></i>
<translate>French</translate> (FR) <translate>French</translate> (FR)
</a> </a>
@ -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,13 +178,21 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
}); });
}) })
.factory('operator', function(User, Group) { .factory('operator', [
'User',
'Group',
'loadGlobalData',
function(User, Group, loadGlobalData) {
var operatorChangeCallbacks = [];
var operator = { var operator = {
user: null, user: null,
perms: [], perms: [],
isAuthenticated: function() { isAuthenticated: function () {
return !!this.user; return !!this.user;
}, },
onOperatorChange: function (func) {
operatorChangeCallbacks.push(func);
},
setUser: function(user_id) { setUser: function(user_id) {
if (user_id) { if (user_id) {
User.find(user_id).then(function(user) { User.find(user_id).then(function(user) {
@ -179,15 +200,22 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
// TODO: load only the needed groups // TODO: load only the needed groups
Group.findAll().then(function() { Group.findAll().then(function() {
operator.perms = user.getPerms(); 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();
});
}); });
} }
}, },
// Returns true if the operator has at least one perm of the perms-list.
hasPerms: function(perms) { hasPerms: function(perms) {
if (typeof perms == 'string') { if (typeof perms == 'string') {
perms = perms.split(' '); perms = perms.split(' ');
@ -196,7 +224,8 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
}, },
} }
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