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'])
.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) {
$stateProvider
.state('agenda', {

View File

@ -20,6 +20,19 @@ angular.module('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) {
$stateProvider
.state('assignments', {

View File

@ -99,9 +99,15 @@ angular.module('OpenSlidesApp.core', [
}
])
.run(['loadGlobalData', function(loadGlobalData) {
loadGlobalData();
}])
// Load the global data on startup and when the operator changes
.run([
'loadGlobalData',
'operator',
function(loadGlobalData, operator) {
loadGlobalData();
operator.onOperatorChange(loadGlobalData);
}
])
.factory('jsDataModel', ['$http', 'Projector', function($http, Projector) {
var BaseModel = function() {};
@ -176,6 +182,70 @@ angular.module('OpenSlidesApp.core.site', [
'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) {
// define fallback url and html5Mode
$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 to switch app language
// TODO: detect browser language for default language
@ -449,8 +527,7 @@ angular.module('OpenSlidesApp.core.site', [
'$modalInstance',
'$http',
'operator',
'loadGlobalData',
function ($scope, $modalInstance, $http, operator, loadGlobalData) {
function ($scope, $modalInstance, $http, operator) {
$scope.login = function () {
$http.post(
'/users/login/',
@ -458,7 +535,6 @@ angular.module('OpenSlidesApp.core.site', [
).success(function(data) {
if (data.success) {
operator.setUser(data.user_id);
loadGlobalData();
$scope.loginFailed = false;
$modalInstance.close();
} else {

View File

@ -103,18 +103,21 @@
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li><a href="" ng-click="switchLanguage('en')">
<i class="fa fa-flag"></i>
<translate>English</translate> (EN)
</a>
<li><a href="" ng-click="switchLanguage('de')">
<i class="fa fa-flag"></i>
<translate>German</translate> (DE)
</a>
<li><a href="" ng-click="switchLanguage('fr')">
<i class="fa fa-flag"></i>
<translate>French</translate> (FR)
</a>
<li>
<a href="" ng-click="switchLanguage('en')">
<i class="fa fa-flag"></i>
<translate>English</translate> (EN)
</a>
<li>
<a href="" ng-click="switchLanguage('de')">
<i class="fa fa-flag"></i>
<translate>German</translate> (DE)
</a>
<li>
<a href="" ng-click="switchLanguage('fr')">
<i class="fa fa-flag"></i>
<translate>French</translate> (FR)
</a>
</ul>
</div>
</div>
@ -124,48 +127,12 @@
<!-- Container -->
<div class="container-fluid" id="container">
<div class="row">
<!-- TODO: Build main menu automatically from installed apps, see issue #1469 -->
<div class="col-md-2 leftmenu lefticon">
<ul>
<li>
<a ui-sref="dashboard">
<span class="ico"><i class="fa fa-home fa-lg"></i></span>
<span class="text" translate>Home</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>
<ul ng-controller="MainMenuCtrl">
<li ng-repeat="element in elements">
<a ui-sref="{{ element.ui_sref }}">
<span class="ico"><i class="fa fa-{{ element.img_class }} fa-lg"></i></span>
<span class="text" translate>{{ element.title }}</span>
</a>
</ul>
</div>

View File

@ -13,6 +13,19 @@ angular.module('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) {
$stateProvider
.state('mediafiles', {

View File

@ -77,6 +77,19 @@ angular.module('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) {
$stateProvider
.state('motions', {

View File

@ -77,6 +77,19 @@ angular.module('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) {
$stateProvider
.state('users', {
@ -165,38 +178,54 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
});
})
.factory('operator', function(User, Group) {
var operator = {
user: null,
perms: [],
isAuthenticated: function() {
return !!this.user;
},
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();
.factory('operator', [
'User',
'Group',
'loadGlobalData',
function(User, Group, loadGlobalData) {
var operatorChangeCallbacks = [];
var operator = {
user: null,
perms: [],
isAuthenticated: function () {
return !!this.user;
},
onOperatorChange: function (func) {
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 {
operator.user = null;
Group.find(1).then(function(group) {
operator.perms = group.permissions;
});
}
},
hasPerms: function(perms) {
if (typeof perms == 'string') {
perms = perms.split(' ');
}
return _.intersection(perms, operator.perms).length > 0;
},
} else {
operator.user = null;
Group.find(1).then(function(group) {
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) {
if (typeof perms == 'string') {
perms = perms.split(' ');
}
return _.intersection(perms, operator.perms).length > 0;
},
}
return operator;
}
return operator;
})
])
.run(function(operator, $rootScope, $http) {
// Put the operator into the root scope