From b5075728a2599004ed7d80627c1d8fbad68cf2ff Mon Sep 17 00:00:00 2001 From: anbebe Date: Wed, 20 Nov 2024 16:38:34 +0100 Subject: [PATCH 1/5] Added VoteWeight to entitled users list, added VoteWeight to Pdf export and added search for translated vote values --- .../poll/base/base-poll-detail.component.ts | 1 + .../poll/base/base-poll-pdf.service.ts | 109 +++++++++++------- .../entitled-users-table.component.html | 4 + .../entitled-users-table.component.ts | 6 + .../motion-poll-detail.component.html | 2 + .../motion-poll-detail.component.ts | 10 +- 6 files changed, 91 insertions(+), 41 deletions(-) diff --git a/client/src/app/site/pages/meetings/modules/poll/base/base-poll-detail.component.ts b/client/src/app/site/pages/meetings/modules/poll/base/base-poll-detail.component.ts index 2935e980ef..d9826c567d 100644 --- a/client/src/app/site/pages/meetings/modules/poll/base/base-poll-detail.component.ts +++ b/client/src/app/site/pages/meetings/modules/poll/base/base-poll-detail.component.ts @@ -24,6 +24,7 @@ import { BasePollPdfService } from './base-poll-pdf.service'; export interface BaseVoteData extends Identifiable { user?: ViewUser; + vote_verbose_translated?: string | null; } @Directive() diff --git a/client/src/app/site/pages/meetings/modules/poll/base/base-poll-pdf.service.ts b/client/src/app/site/pages/meetings/modules/poll/base/base-poll-pdf.service.ts index 9fd2c350f3..24a01298e4 100644 --- a/client/src/app/site/pages/meetings/modules/poll/base/base-poll-pdf.service.ts +++ b/client/src/app/site/pages/meetings/modules/poll/base/base-poll-pdf.service.ts @@ -64,6 +64,10 @@ export abstract class BasePollPdfService { return this.activeMeetingService.meetingId!; } + private get activeVoteWeight(): boolean { + return this.meetingSettingsService.instant(`users_enable_vote_weight`); + } + protected meetingSettingsService = inject(MeetingSettingsService); protected userRepo = inject(ParticipantControllerService); protected activeMeetingService = inject(ActiveMeetingService); @@ -382,7 +386,7 @@ export abstract class BasePollPdfService { margin: [0, 20, 0, 5], bold: true }); - const votesData = this.createVotesTable(exportInfo.votesData); + const votesData = this.createVotesTable(exportInfo.votesData, poll.type); pollResultPdfContent.push(votesData); } @@ -392,7 +396,7 @@ export abstract class BasePollPdfService { margin: [0, 20, 0, 5], bold: true }); - const usersData = this.createUsersTable(exportInfo.entitledUsersData); + const usersData = this.createUsersTable(exportInfo.entitledUsersData, poll.type); pollResultPdfContent.push(usersData); } @@ -559,23 +563,30 @@ export abstract class BasePollPdfService { * * @returns the table as pdfmake object */ - private createVotesTable(votesData: BaseVoteData[]): object { - const pollTableBody: any[] = [ - [ - { - text: ``, - style: `tableHeader` - }, - { - text: this.translate.instant(`Participant`), - style: `tableHeader` - }, - { - text: this.translate.instant(`Votes`), - style: `tableHeader` - } - ] + private createVotesTable(votesData: BaseVoteData[], pollType: PollType): object { + const showVoteWeight: boolean = this.activeVoteWeight && pollType == PollType.Named; + let pollTableBody: any[] = []; + const pollTableHeader = [ + { + text: ``, + style: `tableHeader` + }, + { + text: this.translate.instant(`Participant`), + style: `tableHeader` + }, + { + text: this.translate.instant(`Votes`), + style: `tableHeader` + } ]; + if (showVoteWeight) { + pollTableHeader.splice(2, 0, { + text: this.translate.instant(`Vote Weight`), + style: `tableHeader` + }); + } + pollTableBody = [pollTableHeader]; let index = 1; for (const date of votesData.sort((entryA, entryB) => @@ -592,11 +603,15 @@ export abstract class BasePollPdfService { text: this.parseSingleResult(date[`votes`] ?? date[`value`]) } ]; - + if (showVoteWeight) { + tableLine.splice(2, 0, { + text: this.getUserVoteWeightForExport(date.user) + }); + } pollTableBody.push(tableLine); index++; } - return this.generateTableObject(pollTableBody); + return this.generateTableObject(pollTableBody, showVoteWeight); } /** @@ -604,23 +619,30 @@ export abstract class BasePollPdfService { * * @returns the table as pdfmake object */ - private createUsersTable(usersData: EntitledUsersTableEntry[]): object { - const pollTableBody: any[] = [ - [ - { - text: ``, - style: `tableHeader` - }, - { - text: this.translate.instant(`Participant`), - style: `tableHeader` - }, - { - text: this.translate.instant(`Has voted`), - style: `tableHeader` - } - ] + private createUsersTable(usersData: EntitledUsersTableEntry[], pollType: PollType): object { + const showVoteWeight: boolean = this.activeVoteWeight && pollType == PollType.Named; + let pollTableBody: any[] = []; + const pollTableHeader = [ + { + text: ``, + style: `tableHeader` + }, + { + text: this.translate.instant(`Participant`), + style: `tableHeader` + }, + { + text: this.translate.instant(`Has voted`), + style: `tableHeader` + } ]; + if (showVoteWeight) { + pollTableHeader.splice(2, 0, { + text: this.translate.instant(`Vote Weight`), + style: `tableHeader` + }); + } + pollTableBody = [pollTableHeader]; let index = 1; for (const date of usersData.sort((entryA, entryB) => @@ -651,18 +673,23 @@ export abstract class BasePollPdfService { text: this.translate.instant(date.voted ? `Yes` : `No`) } ]; + if (showVoteWeight) { + tableLine.splice(2, 0, { + text: this.getUserVoteWeightForExport(date.user) + }); + } pollTableBody.push(tableLine); index++; } - return this.generateTableObject(pollTableBody); + return this.generateTableObject(pollTableBody, showVoteWeight); } - private generateTableObject(pollTableBody: any[]): object { + private generateTableObject(pollTableBody: any[], showVoteWeight: boolean): object { return [ { table: { - widths: [`4%`, `48%`, `48%`], + widths: showVoteWeight ? [`4%`, `32%`, `32%`, `32%`] : [`4%`, `48%`, `48%`], headerRows: 1, body: pollTableBody }, @@ -675,6 +702,10 @@ export abstract class BasePollPdfService { return user?.getShortName() ?? this.translate.instant(`Anonymous`); } + private getUserVoteWeightForExport(user: ViewUser | undefined): string { + return user?.voteWeight.toString(); + } + private parseSingleResult(resultData: any, indent = 0): string { const indentation = ` `.repeat(indent); if (Array.isArray(resultData)) { diff --git a/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.html b/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.html index 3d25052e90..b85deeb4eb 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.html +++ b/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.html @@ -20,6 +20,10 @@ {{ entry.user.getLevelAndNumber() }} } + + @if ((parent.voteWeightEnabled | async) && parent.poll.isNamed) { +
{{ 'Vote weight' | translate }}: {{ entry.user.vote_weight() }}
+ } @if (entry.vote_delegated_to_user_id && !entry.delegation_user_merged_into_id) {
diff --git a/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.ts b/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.ts index 3b2652615c..90aeb47dd8 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.ts +++ b/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.ts @@ -1,10 +1,13 @@ import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation } from '@angular/core'; import { map, Observable } from 'rxjs'; import { Permission } from 'src/app/domain/definitions/permission'; +import { PollContentObject } from 'src/app/domain/models/poll'; import { ParticipantControllerService } from '../../../../pages/participants/services/common/participant-controller.service'; +import { BasePollDetailComponent } from '../../base/base-poll-detail.component'; import { EntitledUsersTableEntry } from '../../definitions/entitled-users-table-entry'; import { EntitledUsersListFilterService } from '../../services/entitled-user-filter.service'; +import { PollService } from '../../services/poll.service'; @Component({ selector: `os-entitled-users-table`, @@ -42,6 +45,9 @@ export class EntitledUsersTableComponent { return this._isViewingThis; } + @Input() + public parent: BasePollDetailComponent; + public readonly permission = Permission; public filterPropsEntitledUsersTable = [ diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.html b/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.html index d5561a1d0f..9eb5ffdf66 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.html +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.html @@ -46,6 +46,7 @@

{{ poll.title | translate }}

{{ poll.title | translate }} diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.ts b/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.ts index 9cced9740c..a49fc7e055 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.ts +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.ts @@ -19,7 +19,7 @@ import { MotionPollPdfService } from '../../../../modules/motion-poll/services/m encapsulation: ViewEncapsulation.None }) export class MotionPollDetailComponent extends BasePollDetailComponent { - public filterPropsSingleVotesTable = [`user.full_name`, `valueVerbose`]; + public filterPropsSingleVotesTable = [`user.full_name`, `valueVerbose`, `vote_verbose_translated`]; public get showResults(): boolean { return this.hasPerms() || this.poll.isPublished; @@ -35,7 +35,13 @@ export class MotionPollDetailComponent extends BasePollDetailComponent + (element.vote_verbose_translated = this.translate.instant(voteData[index].vote.valueVerbose)) + ); + return baseVoteData; } public openDialog(): void { From ccb2fff60e07ddd042738cdbb7098de590a3f862 Mon Sep 17 00:00:00 2001 From: anbebe Date: Fri, 22 Nov 2024 15:05:49 +0100 Subject: [PATCH 2/5] Addenew spieifc type of BaseVoteData and boolean property for checking vote weights --- .../poll/base/base-poll-detail.component.ts | 1 - .../entitled-users-table.component.html | 2 +- .../entitled-users-table.component.ts | 2 +- .../motion-poll-detail.component.html | 2 +- .../motion-poll-detail.component.ts | 24 +++++++++++++------ 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/client/src/app/site/pages/meetings/modules/poll/base/base-poll-detail.component.ts b/client/src/app/site/pages/meetings/modules/poll/base/base-poll-detail.component.ts index d9826c567d..2935e980ef 100644 --- a/client/src/app/site/pages/meetings/modules/poll/base/base-poll-detail.component.ts +++ b/client/src/app/site/pages/meetings/modules/poll/base/base-poll-detail.component.ts @@ -24,7 +24,6 @@ import { BasePollPdfService } from './base-poll-pdf.service'; export interface BaseVoteData extends Identifiable { user?: ViewUser; - vote_verbose_translated?: string | null; } @Directive() diff --git a/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.html b/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.html index b85deeb4eb..814e7cc20a 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.html +++ b/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.html @@ -21,7 +21,7 @@
} - @if ((parent.voteWeightEnabled | async) && parent.poll.isNamed) { + @if (displayVoteWeight) {
{{ 'Vote weight' | translate }}: {{ entry.user.vote_weight() }}
} diff --git a/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.ts b/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.ts index 90aeb47dd8..243ea02578 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.ts +++ b/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.ts @@ -46,7 +46,7 @@ export class EntitledUsersTableComponent { } @Input() - public parent: BasePollDetailComponent; + public displayVoteWeight: boolean; public readonly permission = Permission; diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.html b/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.html index 9eb5ffdf66..ad4ff8046a 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.html +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.html @@ -55,9 +55,9 @@

{{ poll.title | translate }}

diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.ts b/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.ts index a49fc7e055..ec2432b843 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.ts +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.ts @@ -11,6 +11,10 @@ import { MotionPollService } from '../../../../modules/motion-poll/services'; import { MotionPollDialogService } from '../../../../modules/motion-poll/services/motion-poll-dialog.service'; import { MotionPollPdfService } from '../../../../modules/motion-poll/services/motion-poll-pdf.service'; +export interface ExtendedVoteData extends BaseVoteData { + vote_verbose_translated?: string | null; +} + @Component({ selector: `os-motion-poll-detail`, templateUrl: `./motion-poll-detail.component.html`, @@ -25,6 +29,10 @@ export class MotionPollDetailComponent extends BasePollDetailComponent - (element.vote_verbose_translated = this.translate.instant(voteData[index].vote.valueVerbose)) - ); - return baseVoteData; + const extendedVoteData: ExtendedVoteData[] = this.poll?.options[0]?.votes; + if (extendedVoteData) { + extendedVoteData.map( + (element, index) => + (element.vote_verbose_translated = this.translate.instant(voteData[index].vote.valueVerbose)) + ); + } + return extendedVoteData; } public openDialog(): void { From 544378843441dd85684ec128e83e83ce3dcb4dd2 Mon Sep 17 00:00:00 2001 From: anbebe Date: Fri, 22 Nov 2024 16:11:16 +0100 Subject: [PATCH 3/5] Run npm run cleanup --- .../entitled-users-table/entitled-users-table.component.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.ts b/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.ts index 243ea02578..87805b9b57 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.ts +++ b/client/src/app/site/pages/meetings/modules/poll/components/entitled-users-table/entitled-users-table.component.ts @@ -1,13 +1,10 @@ import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation } from '@angular/core'; import { map, Observable } from 'rxjs'; import { Permission } from 'src/app/domain/definitions/permission'; -import { PollContentObject } from 'src/app/domain/models/poll'; import { ParticipantControllerService } from '../../../../pages/participants/services/common/participant-controller.service'; -import { BasePollDetailComponent } from '../../base/base-poll-detail.component'; import { EntitledUsersTableEntry } from '../../definitions/entitled-users-table-entry'; import { EntitledUsersListFilterService } from '../../services/entitled-user-filter.service'; -import { PollService } from '../../services/poll.service'; @Component({ selector: `os-entitled-users-table`, From 29d974fec9c82bb021e67e88f8eba118ccc1ed7b Mon Sep 17 00:00:00 2001 From: anbebe Date: Tue, 26 Nov 2024 15:03:36 +0100 Subject: [PATCH 4/5] Change vote weight to be displayed for nominal/non-nominal for entitled users list and handle anonymisedvotes list --- .../meetings/modules/poll/base/base-poll-pdf.service.ts | 9 +++++---- .../motion-poll-detail/motion-poll-detail.component.ts | 5 ++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/src/app/site/pages/meetings/modules/poll/base/base-poll-pdf.service.ts b/client/src/app/site/pages/meetings/modules/poll/base/base-poll-pdf.service.ts index 24a01298e4..2a8930baf0 100644 --- a/client/src/app/site/pages/meetings/modules/poll/base/base-poll-pdf.service.ts +++ b/client/src/app/site/pages/meetings/modules/poll/base/base-poll-pdf.service.ts @@ -396,7 +396,7 @@ export abstract class BasePollPdfService { margin: [0, 20, 0, 5], bold: true }); - const usersData = this.createUsersTable(exportInfo.entitledUsersData, poll.type); + const usersData = this.createUsersTable(exportInfo.entitledUsersData); pollResultPdfContent.push(usersData); } @@ -564,7 +564,8 @@ export abstract class BasePollPdfService { * @returns the table as pdfmake object */ private createVotesTable(votesData: BaseVoteData[], pollType: PollType): object { - const showVoteWeight: boolean = this.activeVoteWeight && pollType == PollType.Named; + const isAnonymised: boolean = votesData[0].user ? false : true; + const showVoteWeight: boolean = this.activeVoteWeight && pollType == PollType.Named && !isAnonymised; let pollTableBody: any[] = []; const pollTableHeader = [ { @@ -619,8 +620,8 @@ export abstract class BasePollPdfService { * * @returns the table as pdfmake object */ - private createUsersTable(usersData: EntitledUsersTableEntry[], pollType: PollType): object { - const showVoteWeight: boolean = this.activeVoteWeight && pollType == PollType.Named; + private createUsersTable(usersData: EntitledUsersTableEntry[]): object { + const showVoteWeight: boolean = this.activeVoteWeight; let pollTableBody: any[] = []; const pollTableHeader = [ { diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.ts b/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.ts index ec2432b843..bfa9049d5b 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.ts +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-polls/components/motion-poll-detail/motion-poll-detail.component.ts @@ -29,9 +29,7 @@ export class MotionPollDetailComponent extends BasePollDetailComponent (this.displayVoteWeight = data))); } protected createVotesData(): ExtendedVoteData[] { From 32f7425b6278b520a879db9927bd865ac3eb6f68 Mon Sep 17 00:00:00 2001 From: anbebe Date: Tue, 3 Dec 2024 11:59:55 +0100 Subject: [PATCH 5/5] Add vote weights to election polls --- .../assignment-poll-detail.component.html | 1 + .../assignment-poll-detail/assignment-poll-detail.component.ts | 3 +++ 2 files changed, 4 insertions(+) diff --git a/client/src/app/site/pages/meetings/pages/assignments/pages/assignment-polls/components/assignment-poll-detail/assignment-poll-detail.component.html b/client/src/app/site/pages/meetings/pages/assignments/pages/assignment-polls/components/assignment-poll-detail/assignment-poll-detail.component.html index 276074d182..85cf33ecc7 100644 --- a/client/src/app/site/pages/meetings/pages/assignments/pages/assignment-polls/components/assignment-poll-detail/assignment-poll-detail.component.html +++ b/client/src/app/site/pages/meetings/pages/assignments/pages/assignment-polls/components/assignment-poll-detail/assignment-poll-detail.component.html @@ -57,6 +57,7 @@

{{ poll.title }}

diff --git a/client/src/app/site/pages/meetings/pages/assignments/pages/assignment-polls/components/assignment-poll-detail/assignment-poll-detail.component.ts b/client/src/app/site/pages/meetings/pages/assignments/pages/assignment-polls/components/assignment-poll-detail/assignment-poll-detail.component.ts index a77b41f416..4b595ba83a 100644 --- a/client/src/app/site/pages/meetings/pages/assignments/pages/assignment-polls/components/assignment-poll-detail/assignment-poll-detail.component.ts +++ b/client/src/app/site/pages/meetings/pages/assignments/pages/assignment-polls/components/assignment-poll-detail/assignment-poll-detail.component.ts @@ -38,12 +38,15 @@ export class AssignmentPollDetailComponent return this.hasPerms() || this.poll.isPublished; } + public displayVoteWeight: boolean; + public constructor( pollService: AssignmentPollService, private pollDialog: AssignmentPollDialogService, pollPdfService: AssignmentPollPdfService ) { super(pollService, pollPdfService); + this.subscriptions.push(this.voteWeightEnabled.subscribe(data => (this.displayVoteWeight = data))); } public openDialog(poll: ViewPoll): void {