Merge pull request #3740 from FinnStutzenstein/voting-plugin
Changes for the voting plugin and usability improvements
This commit is contained in:
commit
407b640f80
@ -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 = []
|
||||
|
@ -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();
|
||||
|
@ -716,14 +716,12 @@ angular.module('OpenSlidesApp.assignments.site', [
|
||||
defaultValue[vote.value.toLowerCase()] = vote.weight;
|
||||
});
|
||||
|
||||
$scope.formFields.push(
|
||||
{
|
||||
noFormControl: true,
|
||||
template: '<strong>' + option.candidate.get_full_name() + '</strong>'
|
||||
},
|
||||
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: '<strong>' + option.candidate.get_full_name() + '</strong>'
|
||||
},
|
||||
{
|
||||
className: 'row',
|
||||
fieldGroup: columns,
|
||||
});
|
||||
} else { // votes method
|
||||
if (option.votes.length) {
|
||||
defaultValue = option.votes[0].weight;
|
||||
|
@ -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):
|
||||
|
@ -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) {
|
||||
|
@ -6,7 +6,7 @@
|
||||
ng-click="model.project(defaultProjectorId, arg)"
|
||||
ng-class="{ 'btn-primary': inArray(model.isProjected(arg), defaultProjectorId) }">
|
||||
<i class="fa fa-video-camera"></i>
|
||||
{{ content }}
|
||||
{{ content | translate }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-sm slimDropDown"
|
||||
ng-class="{ 'btn-primary': (model.isProjected(arg).length && !inArray(model.isProjected(arg), defaultProjectorId)) }"
|
||||
|
@ -346,6 +346,7 @@
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<h3 ng-if="motion.polls.length > 0" translate>Voting result</h3>
|
||||
<template-hook hook-name="motionPollVotingHeader"></template-hook>
|
||||
<ol>
|
||||
<li ng-controller="MotionPollDetailCtrl" ng-repeat="poll in motion.polls" class="spacer"
|
||||
ng-if="poll.has_votes || operator.hasPerms('motions.can_manage')">
|
||||
|
@ -115,7 +115,7 @@ angular.module('OpenSlidesApp.users.pdf', ['OpenSlidesApp.core.pdf'])
|
||||
|
||||
var createInstance = function(userList) {
|
||||
|
||||
var creadeUserHeadLine = function(user) {
|
||||
var createUserHeadLine = function(user) {
|
||||
var titleLine = [];
|
||||
titleLine.push({
|
||||
text: user.get_short_name(),
|
||||
@ -260,7 +260,7 @@ angular.module('OpenSlidesApp.users.pdf', ['OpenSlidesApp.core.pdf'])
|
||||
var getContent = function() {
|
||||
var content = [];
|
||||
angular.forEach(userList, function (user, index) {
|
||||
content.push(creadeUserHeadLine(user));
|
||||
content.push(createUserHeadLine(user));
|
||||
content.push(createAccessDataContent(user));
|
||||
content.push(createWelcomeText());
|
||||
// No pagebreak after the last user
|
||||
|
@ -355,7 +355,9 @@
|
||||
<div os-perms="users.can_manage" ng-class="{'hiddenDiv': !user.hover}">
|
||||
<small>
|
||||
<template-hook hook-name="userListEditButton">
|
||||
<span>
|
||||
<a href="" ng-click="openDialog(user)" translate>Edit</a> ·
|
||||
</span>
|
||||
</template-hook>
|
||||
<a ui-sref="users.user.change-password({id: user.id})" translate>Change password</a> ·
|
||||
<a href="" class="text-danger"
|
||||
|
Loading…
Reference in New Issue
Block a user