include global abstain/no option

election polls with 'one vote per candidate' should have a
 global no/abstain option
This commit is contained in:
Maximilian Krambach 2019-04-25 16:55:52 +02:00
parent d7c6583b7e
commit f00303d753
7 changed files with 48 additions and 9 deletions

View File

@ -214,10 +214,10 @@ export class AssignmentRepositoryService extends BaseAgendaContentObjectReposito
const data = {
assignment_id: originalPoll.assignment_id,
votes: votes,
votesabstain: null,
votesabstain: poll.votesabstain || null,
votescast: poll.votescast || null,
votesinvalid: poll.votesinvalid || null,
votesno: null,
votesno: poll.votesno || null,
votesvalid: poll.votesvalid || null
};
await this.httpService.put(`${this.restPollPath}${originalPoll.id}/`, data);

View File

@ -6,7 +6,15 @@ import { _ } from 'app/core/translate/translation-marker';
* The possible keys of a poll object that represent numbers.
* TODO Should be 'key of MotionPoll|AssinmentPoll if type of key is number'
*/
export type CalculablePollKey = 'votesvalid' | 'votesinvalid' | 'votescast' | 'yes' | 'no' | 'abstain';
export type CalculablePollKey =
| 'votesvalid'
| 'votesinvalid'
| 'votescast'
| 'yes'
| 'no'
| 'abstain'
| 'votesno'
| 'votesabstain';
/**
* TODO: may be obsolete if the server switches to lower case only
@ -119,8 +127,10 @@ export abstract class PollService {
case 'yes':
return 'thumb_up';
case 'no':
case 'votesno':
return 'thumb_down';
case 'abstain':
case 'votesabstain':
return 'not_interested';
// TODO case 'votescast':
// sum
@ -144,8 +154,10 @@ export abstract class PollService {
case 'yes':
return 'Yes';
case 'no':
case 'votesno':
return 'No';
case 'abstain':
case 'votesabstain':
return 'Abstain';
case 'votescast':
return _('Total votes cast');

View File

@ -7,7 +7,7 @@ import { AssignmentPollOption } from './assignment-poll-option';
* @ignore
*/
export class AssignmentPoll extends Deserializer {
private static DECIMAL_FIELDS = ['votesvalid', 'votesinvalid', 'votescast'];
private static DECIMAL_FIELDS = ['votesvalid', 'votesinvalid', 'votescast', 'votesno', 'votesabstain'];
public id: number;
public pollmethod: AssignmentPollMethod;
@ -15,6 +15,8 @@ export class AssignmentPoll extends Deserializer {
public published: boolean;
public options: AssignmentPollOption[];
public votesvalid: number;
public votesno: number;
public votesabstain: number;
public votesinvalid: number;
public votescast: number;
public has_votes: boolean;

View File

@ -9,6 +9,11 @@ import { UserRepositoryService } from 'app/core/repositories/users/user-reposito
import { ViewAssignmentPoll } from '../../models/view-assignment-poll';
import { ViewAssignmentPollOption } from '../../models/view-assignment-poll-option';
/**
* Vote entries included once for summary (e.g. total votes cast)
*/
type summaryPollKey = 'votescast' | 'votesvalid' | 'votesinvalid' | 'votesno' | 'votesabstain';
/**
* A dialog for updating the values of an assignment-related poll.
*/
@ -21,7 +26,14 @@ export class AssignmentPollDialogComponent {
/**
* The summary values that will have fields in the dialog
*/
public sumValues: SummaryPollKey[] = ['votesvalid', 'votesinvalid', 'votescast'];
public get sumValues(): summaryPollKey[] {
const generalValues: summaryPollKey[] = ['votesvalid', 'votesinvalid', 'votescast'];
if (this.data.pollmethod === 'votes') {
return ['votesno', 'votesabstain', ...generalValues];
} else {
return generalValues;
}
}
/**
* List of accepted special non-numerical values.

View File

@ -35,10 +35,23 @@ export class ViewAssignmentPoll implements Identifiable, Updateable, Projectable
return this.poll.published;
}
public get votesno(): number {
return this.poll.votesno;
}
public set votesno(amount: number) {
this.poll.votesno = amount;
}
public get votesabstain(): number {
return this.poll.votesabstain;
}
public set votesabstain(amount: number) {
this.poll.votesabstain = amount;
}
public get votesvalid(): number {
return this.poll.votesvalid;
}
public set votesvalid(amount: number) {
this.poll.votesvalid = amount;
}
@ -53,7 +66,6 @@ export class ViewAssignmentPoll implements Identifiable, Updateable, Projectable
public get votescast(): number {
return this.poll.votescast;
}
public set votescast(amount: number) {
this.poll.votescast = amount;
}

View File

@ -30,7 +30,7 @@ export class AssignmentPollService extends PollService {
/**
* list of poll keys that are numbers and can be part of a quorum calculation
*/
public pollValues: CalculablePollKey[] = ['votesvalid', 'votesinvalid', 'votescast'];
public pollValues: CalculablePollKey[] = ['votesno', 'votesabstain', 'votesvalid', 'votesinvalid', 'votescast'];
/**
* the method used for polls (as per config)
@ -92,6 +92,7 @@ export class AssignmentPollService extends PollService {
if (Math.min(...yes) < 0) {
return null;
} else {
// TODO: Counting 'No (and possibly 'Abstain') here?
return yes.reduce((a, b) => a + b);
}
} else {

View File

@ -19,7 +19,7 @@ export interface PollSlideData {
description?: string;
has_votes?: boolean;
pollmethod?: AssignmentPollMethod;
votesno?: string; // TODO: same conversion needed as for the PollModel
votesno?: string;
votesabstain?: string;
votesvalid?: string;
votesinvalid?: string;