include per-poll values, some travis fix

This commit is contained in:
Maximilian Krambach 2019-04-05 12:13:34 +02:00
parent e6daf32924
commit 464fb89b53
8 changed files with 70 additions and 27 deletions

View File

@ -181,12 +181,11 @@ export class AssignmentRepositoryService extends BaseAgendaContentObjectReposito
assignment_id: originalPoll.assignment_id,
votes: votes,
votesabstain: null,
votescast: null,
votesinvalid: null,
votescast: poll.votescast || null,
votesinvalid: poll.votesinvalid || null,
votesno: null,
votesvalid: null
votesvalid: poll.votesvalid || null
};
// TODO no response, no error shown, votes are not accepted
const restPath = `/rest/assignments/poll/${originalPoll.id}/`;
await this.httpService.put(restPath, data);
}

View File

@ -180,6 +180,8 @@ export abstract class PollService {
return 'progress-red';
case 'abstain':
return 'progress-yellow';
case 'votes':
return 'progress-green';
default:
return '';
}

View File

@ -41,8 +41,34 @@
</div>
<mat-divider *ngIf="data.poll.pollmethod !== 'votes'"></mat-divider>
</div>
<mat-form-field>
<input
type="number"
matInput
[value]="getSumValue('votesvalid')"
(change)="setSumValue('votesvalid', $event.target.value)"
/>
<mat-label translate>Valid votes</mat-label>
</mat-form-field>
<mat-form-field>
<input
type="number"
matInput
[value]="getSumValue('votesinvalid')"
(change)="setSumValue('votesinvalid', $event.target.value)"
/>
<mat-label translate>Invalid votes</mat-label>
</mat-form-field>
<mat-form-field>
<input
type="number"
matInput
[value]="getSumValue('votestotal')"
(change)="setSumValue('votestotal', $event.target.value)"
/>
<mat-label translate>Total votes</mat-label>
</mat-form-field>
<!-- TODO: total votes -->
</div>
<div class="submit-buttons">
<button mat-button (click)="submit()">{{ 'Save' | translate }}</button>

View File

@ -8,6 +8,11 @@ import { Poll } from 'app/shared/models/assignments/poll';
import { PollOption } from 'app/shared/models/assignments/poll-option';
import { ViewUser } from 'app/site/users/models/view-user';
/**
* Vote entries included once for summary (e.g. total votes cast)
*/
type summaryPollKeys = 'votescast' | 'votesvalid' | 'votesinvalid';
/**
* A dialog for updating the values of an assignment-related poll.
*/
@ -29,11 +34,6 @@ export class AssignmentPollDialogComponent {
*/
public optionPollKeys: PollVoteValue[];
/**
* Vote entries included once for summary (e.g. total votes cast)
*/
public summaryPollKeys: CalculablePollKey[];
/**
* Constructor. Retrieves necessary metadata from the pollService,
* injects the poll itself
@ -146,4 +146,24 @@ export class AssignmentPollDialogComponent {
const val = candidate.votes.find(v => v.value === value);
return val ? val.weight : undefined;
}
/**
* Retrieves a per-poll value
*
* @param value
* @returns integer or null
*/
public getSumValue(value: summaryPollKeys): number | null {
return this.data.poll[value] || null;
}
/**
* Sets a per-poll value
*
* @param value
* @param weight
*/
public setSumValue(value: summaryPollKeys, weight: string): void {
this.data.poll[value] = +weight;
}
}

View File

@ -67,7 +67,7 @@
{{ getCandidateName(option) }}
</div>
<!-- Votes -->
<div *ngIf="poll.published">
<div *ngIf="poll.published && poll.has_votes">
<div *ngFor="let vote of option.votes">
<div class="poll-progress on-transition-fade">
<span>{{ pollService.getLabel(vote.value) | translate }}:</span>
@ -88,6 +88,7 @@
</div>
<div
*ngIf="
poll.has_votes &&
poll.published &&
majorityChoice &&
majorityChoice.value !== 'disabled' &&
@ -106,13 +107,11 @@
<div>
<!-- summary -->
<div *ngFor="let key of pollValues">
<div *ngIf="!pollService.isAbstractValue(key)" class="poll-progress-bar">
<mat-progress-bar
mode="determinate"
[value]="pollService.getPercent(key)"
[ngClass]="pollService.getProgressBarColor(key)"
>
</mat-progress-bar>
<div>
<span>{{ key | translate }}</span>:
</div>
<div>
{{ pollService.getSpecialLabel(poll[key]) }}
</div>
</div>
</div>

View File

@ -152,7 +152,8 @@ export class AssignmentPollComponent implements OnInit {
* @returns true if the quorum is successfully met
*/
public quorumReached(option: PollOption): boolean {
const amount = option.votes.find(v => v.value === 'Yes').weight;
const yesValue = this.poll.pollmethod === 'votes' ? 'Votes' : 'Yes';
const amount = option.votes.find(v => v.value === yesValue).weight;
const yesQuorum = this.pollService.yesQuorum(this.majorityChoice, this.poll, option);
return yesQuorum && amount >= yesQuorum;
}

View File

@ -90,14 +90,15 @@ export class AssignmentPollService extends PollService {
}
case 'CAST':
return poll.votescast > 0 && poll.votesinvalid >= 0 ? poll.votescast : null;
case 'VALID':
return poll.votesvalid > 0 ? poll.votesvalid : null;
default:
return null;
}
}
/**
* Get the percentage for an option that calculates only on their own yes/no/abstain
* values
* Get the percentage for an option
*
* @param poll
* @param option
@ -105,10 +106,7 @@ export class AssignmentPollService extends PollService {
* @returns a percentage number with two digits, null if the value cannot be calculated
*/
public getPercent(poll: Poll, option: PollOption, value: PollVoteValue): number | null {
if (poll.pollmethod === 'votes') {
return null;
}
const base = this.getOptionBaseAmount(poll, option);
const base = poll.pollmethod === 'votes' ? poll.pollBase : this.getOptionBaseAmount(poll, option);
if (!base) {
return null;
}

View File

@ -6,7 +6,6 @@ from openslides.utils.rest_api import (
DictField,
IntegerField,
ListField,
ListSerializer,
ModelSerializer,
SerializerMethodField,
ValidationError,
@ -20,7 +19,6 @@ from .models import (
AssignmentPoll,
AssignmentRelatedUser,
AssignmentVote,
models,
)