Merge pull request #1591 from ostcar/angular_modules
Added a way to load angular apps dynamical
This commit is contained in:
commit
e2dc496352
@ -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.
|
||||||
|
@ -1 +1 @@
|
|||||||
default_app_config = 'openslides.assignments.apps.AssignmentAppConfig'
|
default_app_config = 'openslides.assignments.apps.AssignmentsAppConfig'
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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';
|
|
||||||
});
|
|
@ -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
|
@ -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>
|
|
||||||
|
@ -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>
|
|
||||||
|
@ -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()),
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
@ -1 +1 @@
|
|||||||
default_app_config = 'openslides.mediafiles.apps.MediafileAppConfig'
|
default_app_config = 'openslides.mediafiles.apps.MediafilesAppConfig'
|
||||||
|
@ -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.
|
||||||
|
@ -85,3 +85,6 @@ angular.module('OpenSlidesApp.mediafiles.site', ['OpenSlidesApp.mediafiles'])
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
angular.module('OpenSlidesApp.mediafiles.projector', ['OpenSlidesApp.mediafiles']);
|
||||||
|
@ -1 +1 @@
|
|||||||
default_app_config = 'openslides.motions.apps.MotionAppConfig'
|
default_app_config = 'openslides.motions.apps.MotionsAppConfig'
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user