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'):
|
if has_perm(user, 'assignments.can_see') and has_perm(user, 'assignments.can_manage'):
|
||||||
data = full_data
|
data = full_data
|
||||||
elif has_perm(user, 'assignments.can_see'):
|
elif has_perm(user, 'assignments.can_see'):
|
||||||
# Exclude unpublished polls.
|
# Exclude unpublished poll votes.
|
||||||
data = []
|
data = []
|
||||||
for full in full_data:
|
for full in full_data:
|
||||||
full_copy = full.copy()
|
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)
|
data.append(full_copy)
|
||||||
else:
|
else:
|
||||||
data = []
|
data = []
|
||||||
|
@ -337,9 +337,12 @@ angular.module('OpenSlidesApp.assignments', [])
|
|||||||
getResourceName: function () {
|
getResourceName: function () {
|
||||||
return name;
|
return name;
|
||||||
},
|
},
|
||||||
getAgendaTitle: function () {
|
getTitle: function () {
|
||||||
return this.title;
|
return this.title;
|
||||||
},
|
},
|
||||||
|
getAgendaTitle: function () {
|
||||||
|
return this.getTitle();
|
||||||
|
},
|
||||||
// link name which is shown in search result
|
// link name which is shown in search result
|
||||||
getSearchResultName: function () {
|
getSearchResultName: function () {
|
||||||
return this.getAgendaTitle();
|
return this.getAgendaTitle();
|
||||||
|
@ -716,14 +716,12 @@ angular.module('OpenSlidesApp.assignments.site', [
|
|||||||
defaultValue[vote.value.toLowerCase()] = vote.weight;
|
defaultValue[vote.value.toLowerCase()] = vote.weight;
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.formFields.push(
|
var columnClass = (assignmentpoll.pollmethod === 'yna') ? 'col-xs-4' : 'col-xs-6';
|
||||||
{
|
var columns = [
|
||||||
noFormControl: true,
|
|
||||||
template: '<strong>' + option.candidate.get_full_name() + '</strong>'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'yes_' + option.candidate_id,
|
key: 'yes_' + option.candidate_id,
|
||||||
type: 'input',
|
type: 'input',
|
||||||
|
className: columnClass + ' no-padding-left',
|
||||||
templateOptions: {
|
templateOptions: {
|
||||||
label: gettextCatalog.getString('Yes'),
|
label: gettextCatalog.getString('Yes'),
|
||||||
type: 'number',
|
type: 'number',
|
||||||
@ -735,6 +733,8 @@ angular.module('OpenSlidesApp.assignments.site', [
|
|||||||
{
|
{
|
||||||
key: 'no_' + option.candidate_id,
|
key: 'no_' + option.candidate_id,
|
||||||
type: 'input',
|
type: 'input',
|
||||||
|
className: columnClass + ' no-padding-left' +
|
||||||
|
(assignmentpoll.pollmethod === 'yn' ? ' no-padding-right' : ''),
|
||||||
templateOptions: {
|
templateOptions: {
|
||||||
label: gettextCatalog.getString('No'),
|
label: gettextCatalog.getString('No'),
|
||||||
type: 'number',
|
type: 'number',
|
||||||
@ -743,12 +743,12 @@ angular.module('OpenSlidesApp.assignments.site', [
|
|||||||
},
|
},
|
||||||
defaultValue: defaultValue.no
|
defaultValue: defaultValue.no
|
||||||
}
|
}
|
||||||
);
|
];
|
||||||
if (assignmentpoll.pollmethod == 'yna'){
|
if (assignmentpoll.pollmethod == 'yna'){
|
||||||
$scope.formFields.push(
|
columns.push({
|
||||||
{
|
|
||||||
key:'abstain_' + option.candidate_id,
|
key:'abstain_' + option.candidate_id,
|
||||||
type: 'input',
|
type: 'input',
|
||||||
|
className: columnClass + ' no-padding-left no-padding-right',
|
||||||
templateOptions: {
|
templateOptions: {
|
||||||
label: gettextCatalog.getString('Abstain'),
|
label: gettextCatalog.getString('Abstain'),
|
||||||
type: 'number',
|
type: 'number',
|
||||||
@ -758,6 +758,14 @@ angular.module('OpenSlidesApp.assignments.site', [
|
|||||||
defaultValue: defaultValue.abstain
|
defaultValue: defaultValue.abstain
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
$scope.formFields.push({
|
||||||
|
noFormControl: true,
|
||||||
|
template: '<strong>' + option.candidate.get_full_name() + '</strong>'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
className: 'row',
|
||||||
|
fieldGroup: columns,
|
||||||
|
});
|
||||||
} else { // votes method
|
} else { // votes method
|
||||||
if (option.votes.length) {
|
if (option.votes.length) {
|
||||||
defaultValue = option.votes[0].weight;
|
defaultValue = option.votes[0].weight;
|
||||||
|
@ -191,8 +191,10 @@ class AssignmentViewSet(ModelViewSet):
|
|||||||
if not assignment.candidates.exists():
|
if not assignment.candidates.exists():
|
||||||
raise ValidationError({'detail': _('Can not create ballot because there are no candidates.')})
|
raise ValidationError({'detail': _('Can not create ballot because there are no candidates.')})
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
assignment.create_poll()
|
poll = assignment.create_poll()
|
||||||
return Response({'detail': _('Ballot created successfully.')})
|
return Response({
|
||||||
|
'detail': _('Ballot created successfully.'),
|
||||||
|
'createdPollId': poll.pk})
|
||||||
|
|
||||||
@detail_route(methods=['post'])
|
@detail_route(methods=['post'])
|
||||||
def sort_related_users(self, request, pk=None):
|
def sort_related_users(self, request, pk=None):
|
||||||
|
@ -155,6 +155,7 @@ angular.module('OpenSlidesApp.core', [
|
|||||||
'User',
|
'User',
|
||||||
'Group',
|
'Group',
|
||||||
function (User, Group) {
|
function (User, Group) {
|
||||||
|
var setUserCallbacks = [];
|
||||||
var operator = {
|
var operator = {
|
||||||
user: null,
|
user: null,
|
||||||
perms: [],
|
perms: [],
|
||||||
@ -167,6 +168,10 @@ angular.module('OpenSlidesApp.core', [
|
|||||||
} else {
|
} else {
|
||||||
operator.user = null;
|
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.
|
// Returns true if the operator has at least one perm of the perms-list.
|
||||||
hasPerms: function(perms) {
|
hasPerms: function(perms) {
|
||||||
@ -191,6 +196,9 @@ angular.module('OpenSlidesApp.core', [
|
|||||||
}
|
}
|
||||||
return _.indexOf(groups, group.id) > -1;
|
return _.indexOf(groups, group.id) > -1;
|
||||||
},
|
},
|
||||||
|
registerSetUserCallback: function (cb) {
|
||||||
|
setUserCallbacks.push(cb);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
return operator;
|
return operator;
|
||||||
}
|
}
|
||||||
@ -715,6 +723,7 @@ angular.module('OpenSlidesApp.core', [
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope.content = '';
|
||||||
if (attributes.content) {
|
if (attributes.content) {
|
||||||
attributes.$observe('content', function (content) {
|
attributes.$observe('content', function (content) {
|
||||||
scope.content = content;
|
scope.content = content;
|
||||||
@ -816,8 +825,9 @@ angular.module('OpenSlidesApp.core', [
|
|||||||
* provide also html markup for the messages. There are 4 types: 'info',
|
* provide also html markup for the messages. There are 4 types: 'info',
|
||||||
* 'success', 'warning', 'error'. The timeout is for autodeleting the message.
|
* 'success', 'warning', 'error'. The timeout is for autodeleting the message.
|
||||||
* Args that could be provided:
|
* Args that could be provided:
|
||||||
* - timeout: Milliseconds until autoclose the message
|
* - timeout: Milliseconds until autoclose the message (default: not set, no auto close)
|
||||||
* - noClose: Whether to show the close button*/
|
* - noClose: Whether to show the close button (default: false)
|
||||||
|
*/
|
||||||
.factory('Messaging', [
|
.factory('Messaging', [
|
||||||
'$timeout',
|
'$timeout',
|
||||||
function($timeout) {
|
function($timeout) {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
ng-click="model.project(defaultProjectorId, arg)"
|
ng-click="model.project(defaultProjectorId, arg)"
|
||||||
ng-class="{ 'btn-primary': inArray(model.isProjected(arg), defaultProjectorId) }">
|
ng-class="{ 'btn-primary': inArray(model.isProjected(arg), defaultProjectorId) }">
|
||||||
<i class="fa fa-video-camera"></i>
|
<i class="fa fa-video-camera"></i>
|
||||||
{{ content }}
|
{{ content | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-default btn-sm slimDropDown"
|
<button type="button" class="btn btn-default btn-sm slimDropDown"
|
||||||
ng-class="{ 'btn-primary': (model.isProjected(arg).length && !inArray(model.isProjected(arg), defaultProjectorId)) }"
|
ng-class="{ 'btn-primary': (model.isProjected(arg).length && !inArray(model.isProjected(arg), defaultProjectorId)) }"
|
||||||
|
@ -346,6 +346,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<h3 ng-if="motion.polls.length > 0" translate>Voting result</h3>
|
<h3 ng-if="motion.polls.length > 0" translate>Voting result</h3>
|
||||||
|
<template-hook hook-name="motionPollVotingHeader"></template-hook>
|
||||||
<ol>
|
<ol>
|
||||||
<li ng-controller="MotionPollDetailCtrl" ng-repeat="poll in motion.polls" class="spacer"
|
<li ng-controller="MotionPollDetailCtrl" ng-repeat="poll in motion.polls" class="spacer"
|
||||||
ng-if="poll.has_votes || operator.hasPerms('motions.can_manage')">
|
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 createInstance = function(userList) {
|
||||||
|
|
||||||
var creadeUserHeadLine = function(user) {
|
var createUserHeadLine = function(user) {
|
||||||
var titleLine = [];
|
var titleLine = [];
|
||||||
titleLine.push({
|
titleLine.push({
|
||||||
text: user.get_short_name(),
|
text: user.get_short_name(),
|
||||||
@ -260,7 +260,7 @@ angular.module('OpenSlidesApp.users.pdf', ['OpenSlidesApp.core.pdf'])
|
|||||||
var getContent = function() {
|
var getContent = function() {
|
||||||
var content = [];
|
var content = [];
|
||||||
angular.forEach(userList, function (user, index) {
|
angular.forEach(userList, function (user, index) {
|
||||||
content.push(creadeUserHeadLine(user));
|
content.push(createUserHeadLine(user));
|
||||||
content.push(createAccessDataContent(user));
|
content.push(createAccessDataContent(user));
|
||||||
content.push(createWelcomeText());
|
content.push(createWelcomeText());
|
||||||
// No pagebreak after the last user
|
// No pagebreak after the last user
|
||||||
|
@ -355,7 +355,9 @@
|
|||||||
<div os-perms="users.can_manage" ng-class="{'hiddenDiv': !user.hover}">
|
<div os-perms="users.can_manage" ng-class="{'hiddenDiv': !user.hover}">
|
||||||
<small>
|
<small>
|
||||||
<template-hook hook-name="userListEditButton">
|
<template-hook hook-name="userListEditButton">
|
||||||
|
<span>
|
||||||
<a href="" ng-click="openDialog(user)" translate>Edit</a> ·
|
<a href="" ng-click="openDialog(user)" translate>Edit</a> ·
|
||||||
|
</span>
|
||||||
</template-hook>
|
</template-hook>
|
||||||
<a ui-sref="users.user.change-password({id: user.id})" translate>Change password</a> ·
|
<a ui-sref="users.user.change-password({id: user.id})" translate>Change password</a> ·
|
||||||
<a href="" class="text-danger"
|
<a href="" class="text-danger"
|
||||||
|
Loading…
Reference in New Issue
Block a user