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 = { const data = {
assignment_id: originalPoll.assignment_id, assignment_id: originalPoll.assignment_id,
votes: votes, votes: votes,
votesabstain: null, votesabstain: poll.votesabstain || null,
votescast: poll.votescast || null, votescast: poll.votescast || null,
votesinvalid: poll.votesinvalid || null, votesinvalid: poll.votesinvalid || null,
votesno: null, votesno: poll.votesno || null,
votesvalid: poll.votesvalid || null votesvalid: poll.votesvalid || null
}; };
await this.httpService.put(`${this.restPollPath}${originalPoll.id}/`, data); 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. * The possible keys of a poll object that represent numbers.
* TODO Should be 'key of MotionPoll|AssinmentPoll if type of key is number' * 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 * TODO: may be obsolete if the server switches to lower case only
@ -119,8 +127,10 @@ export abstract class PollService {
case 'yes': case 'yes':
return 'thumb_up'; return 'thumb_up';
case 'no': case 'no':
case 'votesno':
return 'thumb_down'; return 'thumb_down';
case 'abstain': case 'abstain':
case 'votesabstain':
return 'not_interested'; return 'not_interested';
// TODO case 'votescast': // TODO case 'votescast':
// sum // sum
@ -144,8 +154,10 @@ export abstract class PollService {
case 'yes': case 'yes':
return 'Yes'; return 'Yes';
case 'no': case 'no':
case 'votesno':
return 'No'; return 'No';
case 'abstain': case 'abstain':
case 'votesabstain':
return 'Abstain'; return 'Abstain';
case 'votescast': case 'votescast':
return _('Total votes cast'); return _('Total votes cast');

View File

@ -7,7 +7,7 @@ import { AssignmentPollOption } from './assignment-poll-option';
* @ignore * @ignore
*/ */
export class AssignmentPoll extends Deserializer { 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 id: number;
public pollmethod: AssignmentPollMethod; public pollmethod: AssignmentPollMethod;
@ -15,6 +15,8 @@ export class AssignmentPoll extends Deserializer {
public published: boolean; public published: boolean;
public options: AssignmentPollOption[]; public options: AssignmentPollOption[];
public votesvalid: number; public votesvalid: number;
public votesno: number;
public votesabstain: number;
public votesinvalid: number; public votesinvalid: number;
public votescast: number; public votescast: number;
public has_votes: boolean; 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 { ViewAssignmentPoll } from '../../models/view-assignment-poll';
import { ViewAssignmentPollOption } from '../../models/view-assignment-poll-option'; 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. * 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 * 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. * List of accepted special non-numerical values.

View File

@ -35,10 +35,23 @@ export class ViewAssignmentPoll implements Identifiable, Updateable, Projectable
return this.poll.published; 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 { public get votesvalid(): number {
return this.poll.votesvalid; return this.poll.votesvalid;
} }
public set votesvalid(amount: number) { public set votesvalid(amount: number) {
this.poll.votesvalid = amount; this.poll.votesvalid = amount;
} }
@ -53,7 +66,6 @@ export class ViewAssignmentPoll implements Identifiable, Updateable, Projectable
public get votescast(): number { public get votescast(): number {
return this.poll.votescast; return this.poll.votescast;
} }
public set votescast(amount: number) { public set votescast(amount: number) {
this.poll.votescast = amount; 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 * 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) * the method used for polls (as per config)
@ -92,6 +92,7 @@ export class AssignmentPollService extends PollService {
if (Math.min(...yes) < 0) { if (Math.min(...yes) < 0) {
return null; return null;
} else { } else {
// TODO: Counting 'No (and possibly 'Abstain') here?
return yes.reduce((a, b) => a + b); return yes.reduce((a, b) => a + b);
} }
} else { } else {

View File

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