diff --git a/openslides/assignments/access_permissions.py b/openslides/assignments/access_permissions.py index 65a38bcf7..c3dac3029 100644 --- a/openslides/assignments/access_permissions.py +++ b/openslides/assignments/access_permissions.py @@ -40,11 +40,16 @@ class AssignmentAccessPermissions(BaseAccessPermissions): if has_perm(user, 'assignments.can_see') and has_perm(user, 'assignments.can_manage'): data = full_data elif has_perm(user, 'assignments.can_see'): - # Exclude unpublished polls. + # Exclude unpublished poll votes. data = [] for full in full_data: full_copy = full.copy() - full_copy['polls'] = [poll for poll in full['polls'] if poll['published']] + polls = full_copy['polls'] + for poll in polls: + if not poll['published']: + for option in poll['options']: + option['votes'] = [] # clear votes for not published polls + poll['has_votes'] = False # A user should see, if there are votes. data.append(full_copy) else: data = [] diff --git a/openslides/assignments/static/js/assignments/base.js b/openslides/assignments/static/js/assignments/base.js index f7b46826a..59ce54898 100644 --- a/openslides/assignments/static/js/assignments/base.js +++ b/openslides/assignments/static/js/assignments/base.js @@ -337,9 +337,12 @@ angular.module('OpenSlidesApp.assignments', []) getResourceName: function () { return name; }, - getAgendaTitle: function () { + getTitle: function () { return this.title; }, + getAgendaTitle: function () { + return this.getTitle(); + }, // link name which is shown in search result getSearchResultName: function () { return this.getAgendaTitle(); diff --git a/openslides/assignments/static/js/assignments/site.js b/openslides/assignments/static/js/assignments/site.js index 31320853d..84cd2f6d5 100644 --- a/openslides/assignments/static/js/assignments/site.js +++ b/openslides/assignments/static/js/assignments/site.js @@ -716,14 +716,12 @@ angular.module('OpenSlidesApp.assignments.site', [ defaultValue[vote.value.toLowerCase()] = vote.weight; }); - $scope.formFields.push( - { - noFormControl: true, - template: '' + option.candidate.get_full_name() + '' - }, + var columnClass = (assignmentpoll.pollmethod === 'yna') ? 'col-xs-4' : 'col-xs-6'; + var columns = [ { key: 'yes_' + option.candidate_id, type: 'input', + className: columnClass + ' no-padding-left', templateOptions: { label: gettextCatalog.getString('Yes'), type: 'number', @@ -735,6 +733,8 @@ angular.module('OpenSlidesApp.assignments.site', [ { key: 'no_' + option.candidate_id, type: 'input', + className: columnClass + ' no-padding-left' + + (assignmentpoll.pollmethod === 'yn' ? ' no-padding-right' : ''), templateOptions: { label: gettextCatalog.getString('No'), type: 'number', @@ -743,12 +743,12 @@ angular.module('OpenSlidesApp.assignments.site', [ }, defaultValue: defaultValue.no } - ); + ]; if (assignmentpoll.pollmethod == 'yna'){ - $scope.formFields.push( - { + columns.push({ key:'abstain_' + option.candidate_id, type: 'input', + className: columnClass + ' no-padding-left no-padding-right', templateOptions: { label: gettextCatalog.getString('Abstain'), type: 'number', @@ -758,6 +758,14 @@ angular.module('OpenSlidesApp.assignments.site', [ defaultValue: defaultValue.abstain }); } + $scope.formFields.push({ + noFormControl: true, + template: '' + option.candidate.get_full_name() + '' + }, + { + className: 'row', + fieldGroup: columns, + }); } else { // votes method if (option.votes.length) { defaultValue = option.votes[0].weight; diff --git a/openslides/assignments/views.py b/openslides/assignments/views.py index 3ebf251ea..ef6750960 100644 --- a/openslides/assignments/views.py +++ b/openslides/assignments/views.py @@ -191,8 +191,10 @@ class AssignmentViewSet(ModelViewSet): if not assignment.candidates.exists(): raise ValidationError({'detail': _('Can not create ballot because there are no candidates.')}) with transaction.atomic(): - assignment.create_poll() - return Response({'detail': _('Ballot created successfully.')}) + poll = assignment.create_poll() + return Response({ + 'detail': _('Ballot created successfully.'), + 'createdPollId': poll.pk}) @detail_route(methods=['post']) def sort_related_users(self, request, pk=None): diff --git a/openslides/core/static/js/core/base.js b/openslides/core/static/js/core/base.js index 8daead7d8..06fc85d68 100644 --- a/openslides/core/static/js/core/base.js +++ b/openslides/core/static/js/core/base.js @@ -155,6 +155,7 @@ angular.module('OpenSlidesApp.core', [ 'User', 'Group', function (User, Group) { + var setUserCallbacks = []; var operator = { user: null, perms: [], @@ -167,6 +168,10 @@ angular.module('OpenSlidesApp.core', [ } else { operator.user = null; } + operator.reloadPerms(); + _.forEach(setUserCallbacks, function (cb) { + cb(operator.user); + }); }, // Returns true if the operator has at least one perm of the perms-list. hasPerms: function(perms) { @@ -191,6 +196,9 @@ angular.module('OpenSlidesApp.core', [ } return _.indexOf(groups, group.id) > -1; }, + registerSetUserCallback: function (cb) { + setUserCallbacks.push(cb); + }, }; return operator; } @@ -715,6 +723,7 @@ angular.module('OpenSlidesApp.core', [ }); } + scope.content = ''; if (attributes.content) { attributes.$observe('content', function (content) { scope.content = content; @@ -816,8 +825,9 @@ angular.module('OpenSlidesApp.core', [ * provide also html markup for the messages. There are 4 types: 'info', * 'success', 'warning', 'error'. The timeout is for autodeleting the message. * Args that could be provided: - * - timeout: Milliseconds until autoclose the message - * - noClose: Whether to show the close button*/ + * - timeout: Milliseconds until autoclose the message (default: not set, no auto close) + * - noClose: Whether to show the close button (default: false) + */ .factory('Messaging', [ '$timeout', function($timeout) { diff --git a/openslides/core/static/templates/projector-button.html b/openslides/core/static/templates/projector-button.html index 1628dbf12..ab236c6c2 100644 --- a/openslides/core/static/templates/projector-button.html +++ b/openslides/core/static/templates/projector-button.html @@ -6,7 +6,7 @@ ng-click="model.project(defaultProjectorId, arg)" ng-class="{ 'btn-primary': inArray(model.isProjected(arg), defaultProjectorId) }"> - {{ content }} + {{ content | translate }}