Merge pull request #1591 from ostcar/angular_modules

Added a way to load angular apps dynamical
This commit is contained in:
Norman Jäckel 2015-07-01 22:21:02 +02:00
commit e2dc496352
17 changed files with 116 additions and 77 deletions

View File

@ -4,6 +4,9 @@ from django.apps import AppConfig
class AgendaAppConfig(AppConfig):
name = 'openslides.agenda'
verbose_name = 'OpenSlides Agenda'
angular_site_module = True
angular_projector_module = True
js_files = ['js/agenda/agenda.js']
def ready(self):
# Load projector elements.

View File

@ -1 +1 @@
default_app_config = 'openslides.assignments.apps.AssignmentAppConfig'
default_app_config = 'openslides.assignments.apps.AssignmentsAppConfig'

View File

@ -1,9 +1,12 @@
from django.apps import AppConfig
class AssignmentAppConfig(AppConfig):
class AssignmentsAppConfig(AppConfig):
name = 'openslides.assignments'
verbose_name = 'OpenSlides Assignments'
angular_site_module = True
angular_projector_module = True
js_files = ['js/assignments/assignments.js']
def ready(self):
# Load projector elements.

View File

@ -4,6 +4,9 @@ from django.apps import AppConfig
class CoreAppConfig(AppConfig):
name = 'openslides.core'
verbose_name = 'OpenSlides Core'
angular_site_module = True
angular_projector_module = True
js_files = ['js/core/core.js']
def ready(self):
# Load projector elements.

View File

@ -1,52 +0,0 @@
angular.module('OpenSlidesApp', [
'angular-loading-bar',
'js-data',
'gettext',
'ngAnimate',
'ui.bootstrap',
'ui.tree',
]);
angular.module('OpenSlidesApp.projector', [
'OpenSlidesApp',
'OpenSlidesApp.core.projector',
'OpenSlidesApp.agenda.projector',
'OpenSlidesApp.motions.projector',
'OpenSlidesApp.assignments.projector',
'OpenSlidesApp.users.projector',
'OpenSlidesApp.mediafiles',
]);
angular.module('OpenSlidesApp.site', [
'OpenSlidesApp',
'ui.router',
'ngBootbox',
'ngFabForm',
'ngMessages',
'ngCsvImport',
'ngSanitize', // TODO: remove this as global dependency
'ui.select',
'xeditable',
'OpenSlidesApp.core.site',
'OpenSlidesApp.agenda.site',
'OpenSlidesApp.motions.site',
'OpenSlidesApp.assignments.site',
'OpenSlidesApp.users.site',
'OpenSlidesApp.mediafiles.site',
])
.config(function($urlRouterProvider, $locationProvider) {
// define fallback url and html5Mode
$urlRouterProvider.otherwise('/');
$locationProvider.html5Mode(true);
})
.config(function($httpProvider) {
// Combine the django csrf system with the angular csrf system
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
})
.config(function(uiSelectConfig) {
uiSelectConfig.theme = 'bootstrap';
});

View File

@ -1,5 +1,12 @@
// The core module used for the OpenSlides site and the projector
angular.module('OpenSlidesApp.core', [])
angular.module('OpenSlidesApp.core', [
'angular-loading-bar',
'js-data',
'gettext',
'ngAnimate',
'ui.bootstrap',
'ui.tree',
])
.config(function(DSProvider) {
// Reloads everything after 5 minutes.
@ -146,7 +153,33 @@ angular.module('OpenSlidesApp.core', [])
// The core module for the OpenSlides site
angular.module('OpenSlidesApp.core.site', ['OpenSlidesApp.core'])
angular.module('OpenSlidesApp.core.site', [
'OpenSlidesApp.core',
'ui.router',
'ngBootbox',
'ngFabForm',
'ngMessages',
'ngCsvImport',
'ngSanitize', // TODO: only use this in functions that need it.
'ui.select',
'xeditable',
])
.config(function($urlRouterProvider, $locationProvider) {
// define fallback url and html5Mode
$urlRouterProvider.otherwise('/');
$locationProvider.html5Mode(true);
})
.config(function($httpProvider) {
// Combine the django csrf system with the angular csrf system
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
})
.config(function(uiSelectConfig) {
uiSelectConfig.theme = 'bootstrap';
})
.config(function($stateProvider, $urlMatcherFactoryProvider) {
// Make the trailing slash optional

View File

@ -2,7 +2,7 @@
<!--[if lt IE 7]> <html lang="en" ng-app="myApp" class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html lang="en" ng-app="myApp" class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html lang="en" ng-app="myApp" class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html lang="en" ng-app="OpenSlidesApp.site" class="no-js"> <!--<![endif]-->
<!--[if gt IE 8]><!--> <html lang="en" class="no-js"> <!--<![endif]-->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<base href="/">
@ -189,10 +189,4 @@
</div><!--/.row-->
</div><!--/#container-->
<script src="static/js/app.js"></script>
<script src="static/js/core.js"></script>
<script src="static/js/agenda/agenda.js"></script>
<script src="static/js/motions/motions.js"></script>
<script src="static/js/assignments/assignments.js"></script>
<script src="static/js/users/users.js"></script>
<script src="static/js/mediafiles/mediafiles.js"></script>
<script src="/angular_js/site/"></script>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en" ng-app="OpenSlidesApp.projector" class="no-js">
<html lang="en" class="no-js">
<meta charset="utf-8">
<base href="/">
<title>OpenSlides Projector</title>
@ -48,10 +48,4 @@
</div>
</div>
<script src="static/js/app.js"></script>
<script src="static/js/core.js"></script>
<script src="static/js/agenda/agenda.js"></script>
<script src="static/js/motions/motions.js"></script>
<script src="static/js/assignments/assignments.js"></script>
<script src="static/js/users/users.js"></script>
<script src="static/js/mediafiles/mediafiles.js"></script>
<script src="/angular_js/projector/"></script>

View File

@ -7,10 +7,15 @@ urlpatterns = patterns(
url(r'^core/url_patterns/$',
views.UrlPatternsView.as_view(),
name='core_url_patterns'),
url(r'^core/version/$',
views.VersionView.as_view(),
name='core_version'),
url(r'^angular_js/(?P<openslides_app>site|projector)/$',
views.AppsJsView.as_view(),
name='core_apps_js'),
# View for the projectors are handelt by angular.
url(r'^projector.*$', views.ProjectorView.as_view()),

View File

@ -2,6 +2,7 @@ import re
from collections import OrderedDict
from operator import attrgetter
from django.apps import apps
from django.conf import settings
from django.contrib.staticfiles import finders
from django.core.urlresolvers import get_resolver
@ -308,3 +309,46 @@ class ConfigViewSet(ViewSet):
# Return response.
return Response({'key': key, 'value': value})
class AppsJsView(utils_views.View):
"""
Returns javascript code to be called in the angular app.
The javascript code loads all js-files defined by the installed (django)
apps and creates the angular modules for each angular app.
"""
def get(self, *args, **kwargs):
angular_modules = []
js_files = []
for app_config in apps.get_app_configs():
# Add the angular app, if the module has one.
if getattr(app_config,
'angular_{}_module'.format(kwargs.get('openslides_app')),
False):
angular_modules.append('OpenSlidesApp.{app_name}.{app}'.format(
app=kwargs.get('openslides_app'),
app_name=app_config.label))
# Add all js files that the module needs
try:
app_js_files = app_config.js_files
except AttributeError:
# The app needs no js-files
pass
else:
js_files += [
'{static}{path}'.format(
static=settings.STATIC_URL,
path=path)
for path in app_js_files]
return HttpResponse(
"angular.module('OpenSlidesApp.{app}', {angular_modules});"
"var deferres = [];"
"{js_files}.forEach(function(js_file)deferres.push($.getScript(js_file)));"
"$.when.apply(this, deferres).done(function() angular.bootstrap(document,['OpenSlidesApp.{app}']));"
.format(
app=kwargs.get('openslides_app'),
angular_modules=angular_modules,
js_files=js_files))

View File

@ -1 +1 @@
default_app_config = 'openslides.mediafiles.apps.MediafileAppConfig'
default_app_config = 'openslides.mediafiles.apps.MediafilesAppConfig'

View File

@ -1,9 +1,12 @@
from django.apps import AppConfig
class MediafileAppConfig(AppConfig):
class MediafilesAppConfig(AppConfig):
name = 'openslides.mediafiles'
verbose_name = 'OpenSlides Mediafiles'
angular_site_module = True
angular_projector_module = True
js_files = ['js/mediafiles/mediafiles.js']
def ready(self):
# Load projector elements.

View File

@ -85,3 +85,6 @@ angular.module('OpenSlidesApp.mediafiles.site', ['OpenSlidesApp.mediafiles'])
);
};
});
angular.module('OpenSlidesApp.mediafiles.projector', ['OpenSlidesApp.mediafiles']);

View File

@ -1 +1 @@
default_app_config = 'openslides.motions.apps.MotionAppConfig'
default_app_config = 'openslides.motions.apps.MotionsAppConfig'

View File

@ -2,9 +2,12 @@ from django.apps import AppConfig
from django.db.models.signals import post_migrate
class MotionAppConfig(AppConfig):
class MotionsAppConfig(AppConfig):
name = 'openslides.motions'
verbose_name = 'OpenSlides Motion'
angular_site_module = True
angular_projector_module = True
js_files = ['js/motions/motions.js']
def ready(self):
# Load projector elements.

View File

@ -4,6 +4,9 @@ from django.apps import AppConfig
class UsersAppConfig(AppConfig):
name = 'openslides.users'
verbose_name = 'OpenSlides Users'
angular_site_module = True
angular_projector_module = True
js_files = ['js/users/users.js']
def ready(self):
# Load projector elements.

View File

@ -2,7 +2,7 @@
-r requirements_production.txt
# Requirements for development and tests in alphabetical order
coverage>=4.0a5,<4.1.0
coverage==4.0a5
flake8
isort