Client side changes

This commit is contained in:
Sean Engelhardt 2020-02-13 15:15:42 +01:00 committed by FinnStutzenstein
parent 0b37c5a857
commit 6ba0d0c5e6
5 changed files with 89 additions and 57 deletions

View File

@ -5,23 +5,19 @@
</div> </div>
<ng-container *ngIf="vmanager.canVote(poll)"> <ng-container *ngIf="vmanager.canVote(poll)">
<!-- TODO: Someone should make this pretty --> <!-- TODO: Someone should make this pretty -->
<span *ngIf="poll.user_has_voted_valid">Your vote is valid!</span> <span *ngIf="poll.user_has_voted_valid">Your vote is valid!</span>
<span *ngIf="poll.user_has_voted_invalid">DANGER: Your vote is invalid!</span> <span *ngIf="poll.user_has_voted_invalid">DANGER: Your vote is invalid!</span>
<span *ngIf="poll.user_has_not_voted">You have not give any voting here!</span> <span *ngIf="poll.user_has_not_voted">You have not give any voting here!</span>
<!-- Leftover votes --> <!-- Leftover votes -->
<h4 *ngIf="poll.pollmethod === pollMethods.Votes"> <h4 *ngIf="poll.pollmethod === pollMethods.Votes && poll.votes_amount > 1 && !currentVotes.global">
{{ 'Votes for this poll' | translate }}: {{ poll.votes_amount }} {{ 'Votes for this poll' | translate }}: {{ getVotesCount() }}/{{ poll.votes_amount }}
<!-- ({{ getVotesCount() }}/{{ poll.votes_amount }} {{ 'Votes' | translate }}) -->
</h4> </h4>
<!-- Options and Actions --> <!-- Options and Actions -->
<div *ngFor="let option of poll.options; let i = index"> <div *ngFor="let option of poll.options; let i = index">
<div *ngIf="option.user_has_voted"> <div *ngIf="poll.type !== PollType.Pseudoanonymous || !option.user_has_voted">
TODO: DO not show buttons, becuase, the user has already voted for this one
</div>
<div <div
[ngClass]="{ [ngClass]="{
'yna-grid': poll.pollmethod === pollMethods.YNA, 'yna-grid': poll.pollmethod === pollMethods.YNA,
@ -38,7 +34,7 @@
<button <button
mat-raised-button mat-raised-button
(click)="saveSingleVote(option.id, action.vote)" (click)="saveSingleVote(option.id, action.vote)"
[ngClass]="currentVotes[option.id] ? action.css : ''" [ngClass]="currentVotes[option.id] === action.label ? action.css : ''"
> >
<mat-icon> {{ action.icon }}</mat-icon> <mat-icon> {{ action.icon }}</mat-icon>
</button> </button>
@ -49,6 +45,7 @@
</div> </div>
<mat-divider *ngIf="poll.options.length - 1 > i"></mat-divider> <mat-divider *ngIf="poll.options.length - 1 > i"></mat-divider>
</div> </div>
</div>
<!-- global no/abstain --> <!-- global no/abstain -->
<ng-container *ngIf="poll.pollmethod === pollMethods.Votes && (poll.global_no || poll.global_abstain)"> <ng-container *ngIf="poll.pollmethod === pollMethods.Votes && (poll.global_no || poll.global_abstain)">

View File

@ -86,7 +86,13 @@ export class AssignmentPollVoteComponent extends BasePollVoteComponent<ViewAssig
} }
} }
public getVotesCount(): number {
return Object.keys(this.currentVotes).filter(key => this.currentVotes[key]).length;
}
protected updateVotes(): void { protected updateVotes(): void {
console.log('currentVotes: ', this.currentVotes);
if (this.user && this.votes && this.poll) { if (this.user && this.votes && this.poll) {
const filtered = this.votes.filter( const filtered = this.votes.filter(
vote => vote.option.poll_id === this.poll.id && vote.user_id === this.user.id vote => vote.option.poll_id === this.poll.id && vote.user_id === this.user.id

View File

@ -81,7 +81,9 @@
formControlName="votes_amount" formControlName="votes_amount"
min="1" min="1"
required required
/> />
<mat-hint *ngIf="showSingleAmountHint"> {{ 'Multiple votes are disabled due to security reasons' | translate }}</mat-hint>
</mat-form-field> </mat-form-field>
<mat-checkbox formControlName="global_no">{{ PollPropertyVerbose.global_no | translate }}</mat-checkbox> <mat-checkbox formControlName="global_no">{{ PollPropertyVerbose.global_no | translate }}</mat-checkbox>
<mat-checkbox formControlName="global_abstain">{{ <mat-checkbox formControlName="global_abstain">{{

View File

@ -77,6 +77,8 @@ export class PollFormComponent extends BaseViewComponent implements OnInit {
*/ */
public publishImmediately = true; public publishImmediately = true;
public showSingleAmountHint = false;
/** /**
* Constructor. Retrieves necessary metadata from the pollService, * Constructor. Retrieves necessary metadata from the pollService,
* injects the poll itself * injects the poll itself
@ -124,12 +126,11 @@ export class PollFormComponent extends BaseViewComponent implements OnInit {
this.updatePollValues(this.contentForm.value); this.updatePollValues(this.contentForm.value);
this.subscriptions.push( this.subscriptions.push(
// changes to whole form
this.contentForm.valueChanges.subscribe(values => { this.contentForm.valueChanges.subscribe(values => {
this.updatePollValues(values); this.updatePollValues(values);
}) }),
); // poll method changes
// update the percent bases when the poll method changes
this.contentForm.get('pollmethod').valueChanges.subscribe(method => { this.contentForm.get('pollmethod').valueChanges.subscribe(method => {
let forbiddenBases: string[]; let forbiddenBases: string[];
if (method === 'YN') { if (method === 'YN') {
@ -138,6 +139,10 @@ export class PollFormComponent extends BaseViewComponent implements OnInit {
forbiddenBases = [PercentBase.Cast]; forbiddenBases = [PercentBase.Cast];
} else if (method === 'votes') { } else if (method === 'votes') {
forbiddenBases = [PercentBase.YN, PercentBase.YNA]; forbiddenBases = [PercentBase.YN, PercentBase.YNA];
if (this.contentForm.get('type').value === PollType.Pseudoanonymous) {
this.setVotesAmountCtrl();
}
} }
const percentBases = {}; const percentBases = {};
@ -148,7 +153,34 @@ export class PollFormComponent extends BaseViewComponent implements OnInit {
} }
this.percentBases = percentBases; this.percentBases = percentBases;
// TODO: update selected base // TODO: update selected base
}); this.setVotesAmountCtrl();
}),
// poll type changes
this.contentForm.get('type').valueChanges.subscribe(() => {
this.setVotesAmountCtrl();
})
);
}
/**
* Disable votes_amount form control if the poll type is anonymous
* and the poll method is votes.
* TODO: Enabling this requires at least another layout and some rework
*/
private setVotesAmountCtrl(): void {
// Disable "Amounts of votes" if anonymous and yes-method
const votesAmountCtrl = this.contentForm.get('votes_amount');
if (
this.contentForm.get('type').value === PollType.Pseudoanonymous &&
this.contentForm.get('pollmethod').value === 'votes'
) {
votesAmountCtrl.disable();
votesAmountCtrl.setValue(1);
this.showSingleAmountHint = true;
} else {
votesAmountCtrl.enable();
this.showSingleAmountHint = false;
}
} }
public getValues<V extends ViewBasePoll>(): Partial<V> { public getValues<V extends ViewBasePoll>(): Partial<V> {
@ -193,8 +225,8 @@ export class PollFormComponent extends BaseViewComponent implements OnInit {
majority_method: ['', Validators.required], majority_method: ['', Validators.required],
votes_amount: [1, [Validators.required, Validators.min(1)]], votes_amount: [1, [Validators.required, Validators.min(1)]],
groups_id: [], groups_id: [],
global_no: [], global_no: [false],
global_abstain: [] global_abstain: [false]
}); });
} }
} }

View File

@ -473,11 +473,6 @@ class AssignmentPollViewSet(BasePollViewSet):
) )
amount_sum += amount amount_sum += amount
if amount_sum <= 0:
raise ValidationError(
{"detail": "You must give at least one vote"}
)
if amount_sum > poll.votes_amount: if amount_sum > poll.votes_amount:
raise ValidationError( raise ValidationError(
{ {