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): class AgendaAppConfig(AppConfig):
name = 'openslides.agenda' name = 'openslides.agenda'
verbose_name = 'OpenSlides Agenda' verbose_name = 'OpenSlides Agenda'
angular_site_module = True
angular_projector_module = True
js_files = ['js/agenda/agenda.js']
def ready(self): def ready(self):
# Load projector elements. # 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 from django.apps import AppConfig
class AssignmentAppConfig(AppConfig): class AssignmentsAppConfig(AppConfig):
name = 'openslides.assignments' name = 'openslides.assignments'
verbose_name = 'OpenSlides Assignments' verbose_name = 'OpenSlides Assignments'
angular_site_module = True
angular_projector_module = True
js_files = ['js/assignments/assignments.js']
def ready(self): def ready(self):
# Load projector elements. # Load projector elements.

View File

@ -4,6 +4,9 @@ from django.apps import AppConfig
class CoreAppConfig(AppConfig): class CoreAppConfig(AppConfig):
name = 'openslides.core' name = 'openslides.core'
verbose_name = 'OpenSlides Core' verbose_name = 'OpenSlides Core'
angular_site_module = True
angular_projector_module = True
js_files = ['js/core/core.js']
def ready(self): def ready(self):
# Load projector elements. # 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 // 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) { .config(function(DSProvider) {
// Reloads everything after 5 minutes. // Reloads everything after 5 minutes.
@ -146,7 +153,33 @@ angular.module('OpenSlidesApp.core', [])
// The core module for the OpenSlides site // 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) { .config(function($stateProvider, $urlMatcherFactoryProvider) {
// Make the trailing slash optional // 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 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 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 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 charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<base href="/"> <base href="/">
@ -189,10 +189,4 @@
</div><!--/.row--> </div><!--/.row-->
</div><!--/#container--> </div><!--/#container-->
<script src="static/js/app.js"></script> <script src="/angular_js/site/"></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>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" ng-app="OpenSlidesApp.projector" class="no-js"> <html lang="en" class="no-js">
<meta charset="utf-8"> <meta charset="utf-8">
<base href="/"> <base href="/">
<title>OpenSlides Projector</title> <title>OpenSlides Projector</title>
@ -48,10 +48,4 @@
</div> </div>
</div> </div>
<script src="static/js/app.js"></script> <script src="/angular_js/projector/"></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>

View File

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

View File

@ -2,6 +2,7 @@ import re
from collections import OrderedDict from collections import OrderedDict
from operator import attrgetter from operator import attrgetter
from django.apps import apps
from django.conf import settings from django.conf import settings
from django.contrib.staticfiles import finders from django.contrib.staticfiles import finders
from django.core.urlresolvers import get_resolver from django.core.urlresolvers import get_resolver
@ -308,3 +309,46 @@ class ConfigViewSet(ViewSet):
# Return response. # Return response.
return Response({'key': key, 'value': value}) 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 from django.apps import AppConfig
class MediafileAppConfig(AppConfig): class MediafilesAppConfig(AppConfig):
name = 'openslides.mediafiles' name = 'openslides.mediafiles'
verbose_name = 'OpenSlides Mediafiles' verbose_name = 'OpenSlides Mediafiles'
angular_site_module = True
angular_projector_module = True
js_files = ['js/mediafiles/mediafiles.js']
def ready(self): def ready(self):
# Load projector elements. # 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 from django.db.models.signals import post_migrate
class MotionAppConfig(AppConfig): class MotionsAppConfig(AppConfig):
name = 'openslides.motions' name = 'openslides.motions'
verbose_name = 'OpenSlides Motion' verbose_name = 'OpenSlides Motion'
angular_site_module = True
angular_projector_module = True
js_files = ['js/motions/motions.js']
def ready(self): def ready(self):
# Load projector elements. # Load projector elements.

View File

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

View File

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