diff --git a/CHANGELOG b/CHANGELOG index 8642875f9..d7293c68b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,7 +13,7 @@ Agenda: - Changed API of related objects. All assignments, motions and custom slides are now agenda items and can be hidden. - Removed mptt. -- Added attachments to agenda items. +- Added attachments to custom sldies. - Improved csv import. Assignments: - Renamed app from assignment to assignments. diff --git a/bower.json b/bower.json index d4ba767ab..1e4c02839 100644 --- a/bower.json +++ b/bower.json @@ -11,6 +11,7 @@ "angular-animate": "~1.4.9", "angular-sanitize": "~1.4.9", "angular-bootstrap": "~0.14.3", + "angular-bootstrap-colorpicker": "~3.0.24", "angular-csv-import": "~0.0.27", "angular-formly-templates-bootstrap": "~6.2.0", "angular-formly": "~7.3.9", diff --git a/openslides/agenda/signals.py b/openslides/agenda/signals.py index b91a5f8e1..63c309be3 100644 --- a/openslides/agenda/signals.py +++ b/openslides/agenda/signals.py @@ -20,45 +20,18 @@ def validate_start_time(value): def setup_agenda_config(sender, **kwargs): """ - Receiver function to setup all agenda config variables. They are not - grouped. This function connected to the signal - openslides.core.signals.config_signal during app loading. + Receiver function to setup all agenda config variables. + This function connected to the signal openslides.core.signals.config_signal + during app loading. """ - # TODO: Use an input type with generic datetime support. - yield ConfigVariable( - name='agenda_start_event_date_time', - default_value='', - label=ugettext_lazy('Begin of event'), - help_text=ugettext_lazy('Input format: DD.MM.YYYY HH:MM'), - weight=210, - group=ugettext_lazy('Agenda'), - validators=(validate_start_time,)) - - yield ConfigVariable( - name='agenda_show_last_speakers', - default_value=1, - input_type='integer', - label=ugettext_lazy('Number of last speakers to be shown on the projector'), - weight=220, - group=ugettext_lazy('Agenda'), - validators=(MinValueValidator(0),)) - - yield ConfigVariable( - name='agenda_couple_countdown_and_speakers', - default_value=False, - input_type='boolean', - label=ugettext_lazy('Couple countdown with the list of speakers'), - help_text=ugettext_lazy('[Begin speech] starts the countdown, [End speech] stops the countdown.'), - weight=230, - group=ugettext_lazy('Agenda')) - yield ConfigVariable( name='agenda_number_prefix', default_value='', label=ugettext_lazy('Numbering prefix for agenda items'), help_text=ugettext_lazy('This prefix will be set if you run the automatic agenda numbering.'), - weight=240, + weight=210, group=ugettext_lazy('Agenda'), + subgroup=ugettext_lazy('General'), validators=(MaxLengthValidator(20),)) yield ConfigVariable( @@ -69,8 +42,53 @@ def setup_agenda_config(sender, **kwargs): choices=( {'value': 'arabic', 'display_name': ugettext_lazy('Arabic')}, {'value': 'roman', 'display_name': ugettext_lazy('Roman')}), - weight=250, - group=ugettext_lazy('Agenda')) + weight=215, + group=ugettext_lazy('Agenda'), + subgroup=ugettext_lazy('General')) + + # TODO: Use an input type with generic datetime support. + yield ConfigVariable( + name='agenda_start_event_date_time', + default_value='', + label=ugettext_lazy('Begin of event'), + help_text=ugettext_lazy('Input format: DD.MM.YYYY HH:MM'), + weight=220, + group=ugettext_lazy('Agenda'), + subgroup=ugettext_lazy('General'), + validators=(validate_start_time,)) + + # List of speakers + + yield ConfigVariable( + name='agenda_show_last_speakers', + default_value=1, + input_type='integer', + label=ugettext_lazy('Number of last speakers to be shown on the projector'), + weight=230, + group=ugettext_lazy('Agenda'), + subgroup=ugettext_lazy('List of speakers'), + validators=(MinValueValidator(0),)) + + yield ConfigVariable( + name='agenda_countdown_warning_time', + default_value=0, + input_type='integer', + label=ugettext_lazy('Show orange countdown in the last x seconds of speaking time'), + help_text=ugettext_lazy('Enter duration in seconds. Choose 0 to disable warning color.'), + weight=235, + group=ugettext_lazy('Agenda'), + subgroup=ugettext_lazy('List of speakers'), + validators=(MinValueValidator(0),)) + + yield ConfigVariable( + name='agenda_couple_countdown_and_speakers', + default_value=False, + input_type='boolean', + label=ugettext_lazy('Couple countdown with the list of speakers'), + help_text=ugettext_lazy('[Begin speech] starts the countdown, [End speech] stops the countdown.'), + weight=240, + group=ugettext_lazy('Agenda'), + subgroup=ugettext_lazy('List of speakers')) def listen_to_related_object_post_save(sender, instance, created, **kwargs): diff --git a/openslides/agenda/static/js/agenda/site.js b/openslides/agenda/static/js/agenda/site.js index bf279cf53..490677f9a 100644 --- a/openslides/agenda/static/js/agenda/site.js +++ b/openslides/agenda/static/js/agenda/site.js @@ -209,8 +209,9 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda']) 'operator', 'Agenda', 'User', + 'LimitUsers', 'item', - function ($scope, $filter, $http, $state, operator, Agenda, User, item) { + function ($scope, $filter, $http, $state, operator, Agenda, User, LimitUsers, item) { Agenda.bindOne(item.id, $scope, 'item'); User.bindAll({}, $scope, 'users'); $scope.speakerSelectBox = {}; @@ -218,7 +219,7 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda']) $scope.speakers = $filter('orderBy')(item.speakers, 'weight'); // limit the number of users in ui-select field - $scope.limitUsers = 50; + $scope.LimitUsers = LimitUsers; $scope.$watch(function () { return Agenda.lastModified(); diff --git a/openslides/agenda/static/templates/agenda/item-detail.html b/openslides/agenda/static/templates/agenda/item-detail.html index 12ffaafca..0d81a4ee4 100644 --- a/openslides/agenda/static/templates/agenda/item-detail.html +++ b/openslides/agenda/static/templates/agenda/item-detail.html @@ -135,7 +135,7 @@ {{ $select.selected.get_full_name() }} - +
diff --git a/openslides/assignments/static/js/assignments/site.js b/openslides/assignments/static/js/assignments/site.js index 82f7e2a31..322cfc42a 100644 --- a/openslides/assignments/static/js/assignments/site.js +++ b/openslides/assignments/static/js/assignments/site.js @@ -268,9 +268,10 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) 'operator', 'Assignment', 'User', + 'LimitUsers', 'assignment', 'phases', - function($scope, $http, filterFilter, gettext, ngDialog, AssignmentForm, operator, Assignment, User, assignment, phases) { + function($scope, $http, filterFilter, gettext, ngDialog, AssignmentForm, operator, Assignment, User, LimitUsers, assignment, phases) { User.bindAll({}, $scope, 'users'); Assignment.bindOne(assignment.id, $scope, 'assignment'); Assignment.loadRelations(assignment, 'agenda_item'); @@ -279,7 +280,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) $scope.alert = {}; // limit the number of users in ui-select field - $scope.limitUsers = 50; + $scope.LimitUsers = LimitUsers; // open edit dialog $scope.openDialog = function (assignment) { diff --git a/openslides/assignments/static/templates/assignments/assignment-detail.html b/openslides/assignments/static/templates/assignments/assignment-detail.html index 747fb35eb..8063ebb89 100644 --- a/openslides/assignments/static/templates/assignments/assignment-detail.html +++ b/openslides/assignments/static/templates/assignments/assignment-detail.html @@ -95,7 +95,7 @@ {{ $select.selected.get_full_name() }} - +
diff --git a/openslides/core/config.py b/openslides/core/config.py index d06a78092..d4d52113d 100644 --- a/openslides/core/config.py +++ b/openslides/core/config.py @@ -9,7 +9,8 @@ INPUT_TYPE_MAPPING = { 'text': str, 'integer': int, 'boolean': bool, - 'choice': str} + 'choice': str, + 'colorpicker': str} class ConfigHandler: diff --git a/openslides/core/signals.py b/openslides/core/signals.py index 4dd295746..e3193a5ce 100644 --- a/openslides/core/signals.py +++ b/openslides/core/signals.py @@ -154,6 +154,7 @@ def setup_general_config(sender, **kwargs): yield ConfigVariable( name='projector_backgroundcolor', default_value='#317796', + input_type='colorpicker', label=ugettext_lazy('Background color of projector header'), help_text=ugettext_lazy('Use web color names like "red" or hex numbers like "#ff0000".'), weight=160, diff --git a/openslides/core/static/css/app.css b/openslides/core/static/css/app.css index c229a6f9f..4bd284e9e 100644 --- a/openslides/core/static/css/app.css +++ b/openslides/core/static/css/app.css @@ -466,6 +466,10 @@ img { padding-right: 10px; } +.col2 .countdown_timer.warning { + color: #ed940d; +} + .col2 .countdown_timer.negative { color: #CC0000; } diff --git a/openslides/core/static/css/projector.css b/openslides/core/static/css/projector.css index ef187c35d..5b5abbc11 100644 --- a/openslides/core/static/css/projector.css +++ b/openslides/core/static/css/projector.css @@ -207,9 +207,13 @@ hr { margin-top: 20px; padding-right: 5px; } +.countdown.warning { + color: #ed940d; +} .countdown.negative { color: #CC0000; } + .message_background { background-color: #777777; opacity: 0.8; diff --git a/openslides/core/static/js/core/site.js b/openslides/core/static/js/core/site.js index b06b2cb0a..53be79942 100644 --- a/openslides/core/static/js/core/site.js +++ b/openslides/core/static/js/core/site.js @@ -7,6 +7,7 @@ angular.module('OpenSlidesApp.core.site', [ 'OpenSlidesApp.core', 'ui.router', 'angular-loading-bar', + 'colorpicker.module', 'formly', 'formlyBootstrap', 'ngBootbox', @@ -402,6 +403,7 @@ angular.module('OpenSlidesApp.core.site', [ integer: 'number', boolean: 'checkbox', choice: 'choice', + colorpicker: 'colorpicker', }[type]; } @@ -989,9 +991,10 @@ angular.module('OpenSlidesApp.core.site', [ .controller('ChatMessageCtrl', [ '$scope', '$http', + '$timeout', 'ChatMessage', 'NewChatMessages', - function ($scope, $http, ChatMessage, NewChatMessages) { + function ($scope, $http, $timeout, ChatMessage, NewChatMessages) { ChatMessage.bindAll({}, $scope, 'chatmessages'); $scope.unreadMessages = NewChatMessages.length; $scope.chatboxIsCollapsed = true; @@ -999,6 +1002,9 @@ angular.module('OpenSlidesApp.core.site', [ $scope.chatboxIsCollapsed = !$scope.chatboxIsCollapsed; NewChatMessages = []; $scope.unreadMessages = NewChatMessages.length; + $timeout(function () { + angular.element('#messageInput').focus(); + }, 0); }; $scope.sendMessage = function () { angular.element('#messageSendButton').addClass('disabled'); @@ -1011,6 +1017,9 @@ angular.module('OpenSlidesApp.core.site', [ $scope.newMessage = ''; angular.element('#messageSendButton').removeClass('disabled'); angular.element('#messageInput').removeAttr('disabled'); + $timeout(function () { + angular.element('#messageInput').focus(); + }, 0); }) .error(function () { angular.element('#messageSendButton').removeClass('disabled'); @@ -1031,6 +1040,9 @@ angular.module('OpenSlidesApp.core.site', [ } ]) +// define maximum number of users shown in users select fields (e.g. in motion or speakers forms) +.value('LimitUsers', 50) + .directive('osFocusMe', [ '$timeout', function ($timeout) { diff --git a/openslides/core/static/templates/config-form-field.html b/openslides/core/static/templates/config-form-field.html index 1e9c10952..64cd7f555 100644 --- a/openslides/core/static/templates/config-form-field.html +++ b/openslides/core/static/templates/config-form-field.html @@ -2,19 +2,30 @@
- + + type="{{ type }}"> + + + + +