From f00303d753e67a6821ff2edd6bee2c3d1a5182b1 Mon Sep 17 00:00:00 2001 From: Maximilian Krambach Date: Thu, 25 Apr 2019 16:55:52 +0200 Subject: [PATCH] include global abstain/no option election polls with 'one vote per candidate' should have a global no/abstain option --- .../assignments/assignment-repository.service.ts | 4 ++-- client/src/app/core/ui-services/poll.service.ts | 14 +++++++++++++- .../shared/models/assignments/assignment-poll.ts | 4 +++- .../assignment-poll-dialog.component.ts | 14 +++++++++++++- .../assignments/models/view-assignment-poll.ts | 16 ++++++++++++++-- .../services/assignment-poll.service.ts | 3 ++- .../slides/assignments/poll/poll-slide-data.ts | 2 +- 7 files changed, 48 insertions(+), 9 deletions(-) diff --git a/client/src/app/core/repositories/assignments/assignment-repository.service.ts b/client/src/app/core/repositories/assignments/assignment-repository.service.ts index f3cf68666..e64f6e462 100644 --- a/client/src/app/core/repositories/assignments/assignment-repository.service.ts +++ b/client/src/app/core/repositories/assignments/assignment-repository.service.ts @@ -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); diff --git a/client/src/app/core/ui-services/poll.service.ts b/client/src/app/core/ui-services/poll.service.ts index 09e522c51..181b4e36b 100644 --- a/client/src/app/core/ui-services/poll.service.ts +++ b/client/src/app/core/ui-services/poll.service.ts @@ -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'); diff --git a/client/src/app/shared/models/assignments/assignment-poll.ts b/client/src/app/shared/models/assignments/assignment-poll.ts index 20a95203b..85564e03f 100644 --- a/client/src/app/shared/models/assignments/assignment-poll.ts +++ b/client/src/app/shared/models/assignments/assignment-poll.ts @@ -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; diff --git a/client/src/app/site/assignments/components/assignment-poll-dialog/assignment-poll-dialog.component.ts b/client/src/app/site/assignments/components/assignment-poll-dialog/assignment-poll-dialog.component.ts index 967e5a3e1..b51f97271 100644 --- a/client/src/app/site/assignments/components/assignment-poll-dialog/assignment-poll-dialog.component.ts +++ b/client/src/app/site/assignments/components/assignment-poll-dialog/assignment-poll-dialog.component.ts @@ -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. diff --git a/client/src/app/site/assignments/models/view-assignment-poll.ts b/client/src/app/site/assignments/models/view-assignment-poll.ts index a6b0fcc20..14537c845 100644 --- a/client/src/app/site/assignments/models/view-assignment-poll.ts +++ b/client/src/app/site/assignments/models/view-assignment-poll.ts @@ -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; } diff --git a/client/src/app/site/assignments/services/assignment-poll.service.ts b/client/src/app/site/assignments/services/assignment-poll.service.ts index 5f549e3eb..6824e33f7 100644 --- a/client/src/app/site/assignments/services/assignment-poll.service.ts +++ b/client/src/app/site/assignments/services/assignment-poll.service.ts @@ -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 { diff --git a/client/src/app/slides/assignments/poll/poll-slide-data.ts b/client/src/app/slides/assignments/poll/poll-slide-data.ts index 532389dd3..d532a1e2b 100644 --- a/client/src/app/slides/assignments/poll/poll-slide-data.ts +++ b/client/src/app/slides/assignments/poll/poll-slide-data.ts @@ -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;