Merge pull request #3366 from FinnStutzenstein/Issue3363
New permission for managing lists of speakers (fixes #3363)
This commit is contained in:
commit
3a25e87330
@ -11,6 +11,7 @@ Version 2.2 (unreleased)
|
|||||||
Agenda:
|
Agenda:
|
||||||
- Fixed wrong sorting of last speakers [#3193].
|
- Fixed wrong sorting of last speakers [#3193].
|
||||||
- Fixed issue when sorting a new inserted speaker [#3210].
|
- Fixed issue when sorting a new inserted speaker [#3210].
|
||||||
|
- New permission for managing lists of speakers [#3366].
|
||||||
|
|
||||||
Motions:
|
Motions:
|
||||||
- New export dialog [#3185].
|
- New export dialog [#3185].
|
||||||
|
27
openslides/agenda/migrations/0003_auto_20170818_1202.py
Normal file
27
openslides/agenda/migrations/0003_auto_20170818_1202.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2017-08-18 10:02
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('agenda', '0002_item_duration'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='item',
|
||||||
|
options={
|
||||||
|
'default_permissions': (),
|
||||||
|
'permissions': (
|
||||||
|
('can_see', 'Can see agenda'),
|
||||||
|
('can_manage', 'Can manage agenda'),
|
||||||
|
('can_manage_list_of_speakers', 'Can manage list of speakers'),
|
||||||
|
('can_see_hidden_items', 'Can see hidden items and time scheduling of agenda')
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
@ -279,6 +279,7 @@ class Item(RESTModelMixin, models.Model):
|
|||||||
permissions = (
|
permissions = (
|
||||||
('can_see', 'Can see agenda'),
|
('can_see', 'Can see agenda'),
|
||||||
('can_manage', 'Can manage agenda'),
|
('can_manage', 'Can manage agenda'),
|
||||||
|
('can_manage_list_of_speakers', 'Can manage list of speakers'),
|
||||||
('can_see_hidden_items', 'Can see hidden items and time scheduling of agenda'))
|
('can_see_hidden_items', 'Can see hidden items and time scheduling of agenda'))
|
||||||
unique_together = ('content_type', 'object_id')
|
unique_together = ('content_type', 'object_id')
|
||||||
|
|
||||||
|
@ -451,7 +451,6 @@ angular.module('OpenSlidesApp.agenda.site', [
|
|||||||
$http.post('/rest/agenda/item/' + $scope.item.id + '/manage_speaker/', {'user': userId}).then(
|
$http.post('/rest/agenda/item/' + $scope.item.id + '/manage_speaker/', {'user': userId}).then(
|
||||||
function (success) {
|
function (success) {
|
||||||
$scope.alert.show = false;
|
$scope.alert.show = false;
|
||||||
$scope.speakers = $scope.item.speakers;
|
|
||||||
$scope.speakerSelectBox = {};
|
$scope.speakerSelectBox = {};
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
$scope.alert = ErrorMessage.forAlert(error);
|
$scope.alert = ErrorMessage.forAlert(error);
|
||||||
@ -468,11 +467,9 @@ angular.module('OpenSlidesApp.agenda.site', [
|
|||||||
data: JSON.stringify({speaker: speakerId})}
|
data: JSON.stringify({speaker: speakerId})}
|
||||||
)
|
)
|
||||||
.then(function (success) {
|
.then(function (success) {
|
||||||
$scope.speakers = $scope.item.speakers;
|
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
$scope.alert = ErrorMessage.forAlert(error);
|
$scope.alert = ErrorMessage.forAlert(error);
|
||||||
});
|
});
|
||||||
$scope.speakers = $scope.item.speakers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//delete all speakers from list of speakers
|
//delete all speakers from list of speakers
|
||||||
@ -487,11 +484,9 @@ angular.module('OpenSlidesApp.agenda.site', [
|
|||||||
data: JSON.stringify({speaker: speakersOnList})}
|
data: JSON.stringify({speaker: speakersOnList})}
|
||||||
)
|
)
|
||||||
.then(function (success) {
|
.then(function (success) {
|
||||||
$scope.speakers = $scope.item.speakers;
|
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
$scope.alert = ErrorMessage.forAlert(error);
|
$scope.alert = ErrorMessage.forAlert(error);
|
||||||
});
|
});
|
||||||
$scope.speakers = $scope.item.speakers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return true if the requested user is allowed to do a specific action
|
// Return true if the requested user is allowed to do a specific action
|
||||||
@ -512,13 +507,13 @@ angular.module('OpenSlidesApp.agenda.site', [
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case 'removeAll':
|
case 'removeAll':
|
||||||
return (operator.hasPerms('agenda.can_manage') &&
|
return (operator.hasPerms('agenda.can_manage_list_of_speakers') &&
|
||||||
$scope.speakers.length > 0);
|
$scope.speakers.length > 0);
|
||||||
case 'beginNextSpeech':
|
case 'beginNextSpeech':
|
||||||
return (operator.hasPerms('agenda.can_manage') &&
|
return (operator.hasPerms('agenda.can_manage_list_of_speakers') &&
|
||||||
$scope.nextSpeakers.length > 0);
|
$scope.nextSpeakers.length > 0);
|
||||||
case 'endCurrentSpeech':
|
case 'endCurrentSpeech':
|
||||||
return (operator.hasPerms('agenda.can_manage') &&
|
return (operator.hasPerms('agenda.can_manage_list_of_speakers') &&
|
||||||
$scope.currentSpeaker.length > 0);
|
$scope.currentSpeaker.length > 0);
|
||||||
case 'showLastSpeakers':
|
case 'showLastSpeakers':
|
||||||
return $scope.lastSpeakers.length > 0;
|
return $scope.lastSpeakers.length > 0;
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
<div ng-if="item" class="details" ng-controller="ListOfSpeakersManagementCtrl">
|
<div ng-if="item" class="details" ng-controller="ListOfSpeakersManagementCtrl">
|
||||||
<div class="speakers-toolbar">
|
<div class="speakers-toolbar">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<span os-perms="agenda.can_manage">
|
<span os-perms="agenda.can_manage_list_of_speakers">
|
||||||
<button ng-if="isAllowed('removeAll')" class="btn btn-sm btn-danger"
|
<button ng-if="isAllowed('removeAll')" class="btn btn-sm btn-danger"
|
||||||
ng-bootbox-confirm="{{ 'Are you sure you want to remove all speakers from this list?'| translate }}"
|
ng-bootbox-confirm="{{ 'Are you sure you want to remove all speakers from this list?'| translate }}"
|
||||||
ng-bootbox-confirm-action="removeAllSpeakers()">
|
ng-bootbox-confirm-action="removeAllSpeakers()">
|
||||||
<i class="fa fa-trash fa-lg"></i>
|
<i class="fa fa-trash fa-lg"></i>
|
||||||
<translate>Remove all speakers</translate>
|
<translate>Remove all speakers</translate>
|
||||||
</button>
|
</button>
|
||||||
|
</span>
|
||||||
|
<span os-perms="agenda.can_manage">
|
||||||
<button ng-if="item.speaker_list_closed" ng-click="closeList(false)"
|
<button ng-if="item.speaker_list_closed" ng-click="closeList(false)"
|
||||||
class="btn btn-sm btn-default">
|
class="btn btn-sm btn-default">
|
||||||
<i class="fa fa-toggle-off"></i>
|
<i class="fa fa-toggle-off"></i>
|
||||||
@ -57,7 +59,7 @@
|
|||||||
(<translate>Start time</translate>:
|
(<translate>Start time</translate>:
|
||||||
{{ speaker.begin_time | date:'yyyy-MM-dd HH:mm:ss' }})
|
{{ speaker.begin_time | date:'yyyy-MM-dd HH:mm:ss' }})
|
||||||
</small>
|
</small>
|
||||||
<button os-perms="agenda.can_manage" ng-click="removeSpeaker(speaker.id)"
|
<button os-perms="agenda.can_manage_list_of_speakers" ng-click="removeSpeaker(speaker.id)"
|
||||||
class="btn btn-default btn-xs" title="{{ 'Remove' | translate }}">
|
class="btn btn-default btn-xs" title="{{ 'Remove' | translate }}">
|
||||||
<i class="fa fa-times"></i>
|
<i class="fa fa-times"></i>
|
||||||
</button>
|
</button>
|
||||||
@ -69,11 +71,11 @@
|
|||||||
<p ng-repeat="speaker in currentSpeaker" class="currentSpeaker spacer indentation">
|
<p ng-repeat="speaker in currentSpeaker" class="currentSpeaker spacer indentation">
|
||||||
<i class="fa fa-microphone fa-lg"></i>
|
<i class="fa fa-microphone fa-lg"></i>
|
||||||
{{ speaker.user.get_full_name() }}
|
{{ speaker.user.get_full_name() }}
|
||||||
<button os-perms="agenda.can_manage" ng-click="endSpeech()"
|
<button os-perms="agenda.can_manage_list_of_speakers" ng-click="endSpeech()"
|
||||||
class="btn btn-default btn-sm" title="{{ 'End speech' | translate }}">
|
class="btn btn-default btn-sm" title="{{ 'End speech' | translate }}">
|
||||||
<i class="fa fa-microphone-slash"></i> <translate>Stop</translate>
|
<i class="fa fa-microphone-slash"></i> <translate>Stop</translate>
|
||||||
</button>
|
</button>
|
||||||
<button os-perms="agenda.can_manage" ng-click="removeSpeaker(speaker.id)"
|
<button os-perms="agenda.can_manage_list_of_speakers" ng-click="removeSpeaker(speaker.id)"
|
||||||
class="btn btn-default btn-sm" title="{{ 'Remove' | translate }}">
|
class="btn btn-default btn-sm" title="{{ 'Remove' | translate }}">
|
||||||
<i class="fa fa-times"></i>
|
<i class="fa fa-times"></i>
|
||||||
</button>
|
</button>
|
||||||
@ -84,15 +86,15 @@
|
|||||||
<div ui-tree="treeOptions" data-empty-placeholder-enabled="false">
|
<div ui-tree="treeOptions" data-empty-placeholder-enabled="false">
|
||||||
<ol ui-tree-nodes="" ng-model="nextSpeakers">
|
<ol ui-tree-nodes="" ng-model="nextSpeakers">
|
||||||
<li ng-repeat="speaker in nextSpeakers | orderBy:'weight'" ui-tree-node>
|
<li ng-repeat="speaker in nextSpeakers | orderBy:'weight'" ui-tree-node>
|
||||||
<i os-perms="agenda.can_manage" ui-tree-handle="" class="fa fa-arrows-v"></i>
|
<i os-perms="agenda.can_manage_list_of_speakers" ui-tree-handle="" class="fa fa-arrows-v"></i>
|
||||||
{{ $index + 1 }}.
|
{{ $index + 1 }}.
|
||||||
{{ speaker.user.get_full_name() }}
|
{{ speaker.user.get_full_name() }}
|
||||||
|
|
||||||
<button os-perms="agenda.can_manage" ng-click="beginSpeech(speaker.id)"
|
<button os-perms="agenda.can_manage_list_of_speakers" ng-click="beginSpeech(speaker.id)"
|
||||||
class="btn btn-default btn-sm" title="{{ 'Begin speech' | translate }}">
|
class="btn btn-default btn-sm" title="{{ 'Begin speech' | translate }}">
|
||||||
<i class="fa fa-microphone"></i> <translate>Start</translate>
|
<i class="fa fa-microphone"></i> <translate>Start</translate>
|
||||||
</button>
|
</button>
|
||||||
<button os-perms="agenda.can_manage" ng-click="removeSpeaker(speaker.id)"
|
<button os-perms="agenda.can_manage_list_of_speakers" ng-click="removeSpeaker(speaker.id)"
|
||||||
class="btn btn-default btn-sm" title="{{ 'Remove' | translate }}">
|
class="btn btn-default btn-sm" title="{{ 'Remove' | translate }}">
|
||||||
<i class="fa fa-times"></i>
|
<i class="fa fa-times"></i>
|
||||||
</button>
|
</button>
|
||||||
@ -105,7 +107,7 @@
|
|||||||
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" ng-click="alert={}" close="alert={}">
|
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" ng-click="alert={}" close="alert={}">
|
||||||
{{ alert.msg }}
|
{{ alert.msg }}
|
||||||
</div>
|
</div>
|
||||||
<div os-perms="agenda.can_manage">
|
<div os-perms="agenda.can_manage_list_of_speakers">
|
||||||
<select chosen
|
<select chosen
|
||||||
ng-model="speakerSelectBox.selected"
|
ng-model="speakerSelectBox.selected"
|
||||||
ng-change="addSpeaker(speakerSelectBox.selected)"
|
ng-change="addSpeaker(speakerSelectBox.selected)"
|
||||||
|
@ -47,7 +47,10 @@ class ItemViewSet(ListModelMixin, RetrieveModelMixin, UpdateModelMixin, GenericV
|
|||||||
result = (has_perm(self.request.user, 'agenda.can_see') and
|
result = (has_perm(self.request.user, 'agenda.can_see') and
|
||||||
has_perm(self.request.user, 'agenda.can_see_hidden_items') and
|
has_perm(self.request.user, 'agenda.can_see_hidden_items') and
|
||||||
has_perm(self.request.user, 'agenda.can_manage'))
|
has_perm(self.request.user, 'agenda.can_manage'))
|
||||||
elif self.action in ('speak', 'sort_speakers', 'numbering', 'sort'):
|
elif self.action in ('speak', 'sort_speakers'):
|
||||||
|
result = (has_perm(self.request.user, 'agenda.can_see') and
|
||||||
|
has_perm(self.request.user, 'agenda.can_manage_list_of_speakers'))
|
||||||
|
elif self.action in ('numbering', 'sort'):
|
||||||
result = (has_perm(self.request.user, 'agenda.can_see') and
|
result = (has_perm(self.request.user, 'agenda.can_see') and
|
||||||
has_perm(self.request.user, 'agenda.can_manage'))
|
has_perm(self.request.user, 'agenda.can_manage'))
|
||||||
else:
|
else:
|
||||||
@ -88,7 +91,7 @@ class ItemViewSet(ListModelMixin, RetrieveModelMixin, UpdateModelMixin, GenericV
|
|||||||
user = self.request.user
|
user = self.request.user
|
||||||
else:
|
else:
|
||||||
# Add someone else.
|
# Add someone else.
|
||||||
if not has_perm(self.request.user, 'agenda.can_manage'):
|
if not has_perm(self.request.user, 'agenda.can_manage_list_of_speakers'):
|
||||||
self.permission_denied(request)
|
self.permission_denied(request)
|
||||||
try:
|
try:
|
||||||
user = get_user_model().objects.get(pk=int(user_id))
|
user = get_user_model().objects.get(pk=int(user_id))
|
||||||
@ -128,7 +131,7 @@ class ItemViewSet(ListModelMixin, RetrieveModelMixin, UpdateModelMixin, GenericV
|
|||||||
message = _('You are successfully removed from the list of speakers.')
|
message = _('You are successfully removed from the list of speakers.')
|
||||||
else:
|
else:
|
||||||
# Remove someone else.
|
# Remove someone else.
|
||||||
if not has_perm(self.request.user, 'agenda.can_manage'):
|
if not has_perm(self.request.user, 'agenda.can_manage_list_of_speakers'):
|
||||||
self.permission_denied(request)
|
self.permission_denied(request)
|
||||||
if type(speaker_ids) is int:
|
if type(speaker_ids) is int:
|
||||||
speaker_ids = [speaker_ids]
|
speaker_ids = [speaker_ids]
|
||||||
|
@ -31,6 +31,7 @@ def create_builtin_groups_and_admin(**kwargs):
|
|||||||
permission_strings = (
|
permission_strings = (
|
||||||
'agenda.can_be_speaker',
|
'agenda.can_be_speaker',
|
||||||
'agenda.can_manage',
|
'agenda.can_manage',
|
||||||
|
'agenda.can_manage_list_of_speakers',
|
||||||
'agenda.can_see',
|
'agenda.can_see',
|
||||||
'agenda.can_see_hidden_items',
|
'agenda.can_see_hidden_items',
|
||||||
'assignments.can_manage',
|
'assignments.can_manage',
|
||||||
@ -107,6 +108,7 @@ def create_builtin_groups_and_admin(**kwargs):
|
|||||||
permission_dict['agenda.can_see_hidden_items'],
|
permission_dict['agenda.can_see_hidden_items'],
|
||||||
permission_dict['agenda.can_be_speaker'],
|
permission_dict['agenda.can_be_speaker'],
|
||||||
permission_dict['agenda.can_manage'],
|
permission_dict['agenda.can_manage'],
|
||||||
|
permission_dict['agenda.can_manage_list_of_speakers'],
|
||||||
permission_dict['assignments.can_see'],
|
permission_dict['assignments.can_see'],
|
||||||
permission_dict['assignments.can_manage'],
|
permission_dict['assignments.can_manage'],
|
||||||
permission_dict['assignments.can_nominate_other'],
|
permission_dict['assignments.can_nominate_other'],
|
||||||
|
@ -1596,6 +1596,7 @@ angular.module('OpenSlidesApp.users.site', [
|
|||||||
// agenda
|
// agenda
|
||||||
gettext('Can see agenda');
|
gettext('Can see agenda');
|
||||||
gettext('Can manage agenda');
|
gettext('Can manage agenda');
|
||||||
|
gettext('Can manage list of speakers');
|
||||||
gettext('Can see hidden items and time scheduling of agenda');
|
gettext('Can see hidden items and time scheduling of agenda');
|
||||||
gettext('Can put oneself on the list of speakers');
|
gettext('Can put oneself on the list of speakers');
|
||||||
// assignments
|
// assignments
|
||||||
|
Loading…
Reference in New Issue
Block a user