diff --git a/client/src/app/domain/definitions/meeting-settings-defaults.ts b/client/src/app/domain/definitions/meeting-settings-defaults.ts index 3dd6d913cfd..bcea5bb4d5a 100644 --- a/client/src/app/domain/definitions/meeting-settings-defaults.ts +++ b/client/src/app/domain/definitions/meeting-settings-defaults.ts @@ -53,11 +53,17 @@ export const meetingSettingsDefaults: Record = { motions_amendments_prefix: '-Ä', motions_amendments_text_mode: 'paragraph', motions_supporters_min_amount: 0, - poll_default_live_voting_enabled: false, motions_enable_origin_motion_display: false, motions_origin_motion_toggle_default: false, - assignment_poll_default_method: 'selection', assignment_poll_add_candidates_to_list_of_speakers: false, + poll_enable_max_votes_per_option: false, + poll_default_live_voting_enabled: false, + poll_default_allow_invalid: false, + poll_default_allow_vote_split: false, + poll_projection_name_order_first: 'last_name', + poll_projection_max_columns: 6, + topic_poll_default_method: 'selection', + assignment_poll_default_method: 'selection', users_allow_self_set_present: true, users_enable_presence_view: false, users_enable_vote_weight: false, diff --git a/client/src/app/domain/models/meetings/meeting.ts b/client/src/app/domain/models/meetings/meeting.ts index aea5708e905..f0686e461d5 100644 --- a/client/src/app/domain/models/meetings/meeting.ts +++ b/client/src/app/domain/models/meetings/meeting.ts @@ -489,6 +489,7 @@ export class Meeting extends BaseModel { `default_projector_countdown_ids`, `default_projector_assignment_poll_ids`, `default_projector_motion_poll_ids`, + `default_projector_topic_poll_ids`, `default_group_id`, `admin_group_id`, `anonymous_group_id`, diff --git a/client/src/app/domain/models/projector/projection-default.ts b/client/src/app/domain/models/projector/projection-default.ts index 7823aa71f6c..148c6b4af7b 100644 --- a/client/src/app/domain/models/projector/projection-default.ts +++ b/client/src/app/domain/models/projector/projection-default.ts @@ -14,7 +14,7 @@ export const PROJECTIONDEFAULT = { projectorCountdown: `countdown`, assignmentPoll: `assignment_poll`, motionPoll: `motion_poll`, - poll: `poll` + topicPoll: `topic_poll` } as const; export type ProjectiondefaultKey = keyof typeof PROJECTIONDEFAULT; @@ -33,9 +33,9 @@ export const PROJECTIONDEFAULT_VERBOSE: Record = { mediafile: _(`Files`), projectorMessage: _(`Messages`), projectorCountdown: _(`Timers`), - assignmentPoll: _(`Ballots`), - motionPoll: _(`Motion votes`), - poll: _(`Polls`) + assignmentPoll: _(`Elections`), + motionPoll: _(`Motion polls`), + topicPoll: _(`Topic polls`) }; export const PROJECTIONDEFAULTS = Object.values(PROJECTIONDEFAULT) as ProjectiondefaultValue[]; diff --git a/client/src/app/site/pages/meetings/modules/poll/components/poll-config-form-base.component.ts b/client/src/app/site/pages/meetings/modules/poll/components/poll-config-form-base.component.ts index 6a163b087de..2c253e25d74 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/poll-config-form-base.component.ts +++ b/client/src/app/site/pages/meetings/modules/poll/components/poll-config-form-base.component.ts @@ -1,16 +1,43 @@ -import { Component, inject } from '@angular/core'; +import { Component, computed, effect, inject, input } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { PollState } from '@app/domain/models/poll'; + +import { ViewPoll } from '../../../pages/polls'; @Component({ template: `` }) export abstract class PollFormBaseComponent { public form: UntypedFormGroup; + public data = input.required>(); + + public pollStarted = computed(() => { + return this.data().state !== PollState.Created; + }); + protected fb = inject(UntypedFormBuilder); public constructor() { this.initForm(); + + effect(this.onDataUpdated.bind(this)); } - public abstract initForm(): void; + protected abstract initForm(): void; + protected abstract getPatchedFormData(data: Partial): Record; public abstract getSerialzedForm(): Record; + + private onDataUpdated(): void { + if (!this.data() || !this.form) { + return; + } + + const patch = this.getPatchedFormData(this.data()); + for (const field of Object.keys(patch)) { + if (!this.form.get(field)?.pristine) { + delete patch[field]; + } + } + + this.form.patchValue(patch); + } } diff --git a/client/src/app/site/pages/meetings/modules/poll/components/poll-edit-result/poll-edit-result.component.ts b/client/src/app/site/pages/meetings/modules/poll/components/poll-edit-result/poll-edit-result.component.ts index 661389e5878..e808af3112f 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/poll-edit-result/poll-edit-result.component.ts +++ b/client/src/app/site/pages/meetings/modules/poll/components/poll-edit-result/poll-edit-result.component.ts @@ -112,15 +112,45 @@ export class PollEditResultComponent implements OnInit { public ngOnInit(): void { const result = this.pollData().result ? JSON.parse(this.pollData().result) : {}; - const builtOptions = this.options().map(opt => ({ - value: { - yes: isNaN(+result[opt.key]) ? null : (result[opt.key] ?? null), - no: null, - abstain: null - }, - majority: result[opt.key] === VOTE_MAJORITY, - majority_value: result[opt.key] === VOTE_MAJORITY ? YES_KEY : null - })); + const builtOptions = + this.configType() === 'approval' + ? [ + { + value: { + yes: this.parseResultAmount(result?.yes), + no: this.parseResultAmount(result?.no), + abstain: this.parseResultAmount(result?.abstain) + }, + majority: null, + majority_value: this.getResultOptionMajorityKey(result) + } + ] + : this.options().map(opt => { + const rOpt = result[opt.key] ?? {}; + const majorityValue = this.getResultOptionMajorityKey(rOpt); + + if (this.configType() === 'rating_approval') { + return { + value: { + yes: this.parseResultAmount(rOpt.yes), + no: this.parseResultAmount(rOpt.no), + abstain: this.parseResultAmount(rOpt.abstain) + }, + majority: null, + majority_value: majorityValue + }; + } + + return { + value: { + yes: this.parseResultAmount(rOpt), + no: null, + abstain: null + }, + majority: rOpt === VOTE_MAJORITY, + majority_value: majorityValue + }; + }); this.model.set({ options: builtOptions, @@ -197,4 +227,29 @@ export class PollEditResultComponent implements OnInit { ...(this.showNota() ? { nota: m.nota } : {}) }; } + + private parseResultAmount(amount: any): number | null { + if (isNaN(+amount)) { + return null; + } + + const parsedAmount = +amount; + if (parsedAmount === VOTE_UNDOCUMENTED || parsedAmount === VOTE_MAJORITY) { + return null; + } + + return amount ?? null; + } + + private getResultOptionMajorityKey(rOpt: any): SingleVoteOptionKey { + if (rOpt?.yes === VOTE_MAJORITY) { + return YES_KEY; + } else if (rOpt?.no === VOTE_MAJORITY) { + return NO_KEY; + } else if (rOpt?.abstain === VOTE_MAJORITY) { + return ABSTAIN_KEY; + } + + return null; + } } diff --git a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-approval/poll-form-approval.component.html b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-approval/poll-form-approval.component.html index c8e12f431ca..3b022e2056b 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-approval/poll-form-approval.component.html +++ b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-approval/poll-form-approval.component.html @@ -1,13 +1,15 @@
-
- - {{ 'Election method' | translate }} - - {{ 'Yes/No' | translate }} - {{ 'Yes/No/Abstain' | translate }} - - -
+ @if (!pollStarted()) { +
+ + {{ 'Election method' | translate }} + + {{ 'Yes/No' | translate }} + {{ 'Yes/No/Abstain' | translate }} + + +
+ } {{ '100% base' | translate }} diff --git a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-approval/poll-form-approval.component.ts b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-approval/poll-form-approval.component.ts index 991340c60c6..36d31e90b1a 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-approval/poll-form-approval.component.ts +++ b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-approval/poll-form-approval.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, effect, input } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -27,29 +27,23 @@ export class PollFormApprovalComponent extends PollFormBaseComponent { [`disabled`, _('Disabled (no percents)')] ]; - public readonly data = input>({}); - - public initForm(): void { + protected initForm(): void { this.form = this.fb.group({ onehundred_percent_base: [`valid`], allow_abstain: [false] }); + } + + protected getPatchedFormData(data: Partial): Record { + const patch: Record = {}; + if (data.config?.allow_abstain !== undefined) patch[`allow_abstain`] = data.config.allow_abstain; + if (data.config?.onehundred_percent_base !== undefined) + patch[`onehundred_percent_base`] = data.config.onehundred_percent_base; - effect(this.updateData.bind(this)); + return patch; } public getSerialzedForm(): Record { return this.form.value; } - - private updateData(): void { - const data = this.data(); - if (data && this.form) { - const patch: Record = {}; - if (data.config?.allow_abstain !== undefined) patch[`allow_abstain`] = data.config.allow_abstain; - if (data.config?.onehundred_percent_base !== undefined) - patch[`onehundred_percent_base`] = data.config.onehundred_percent_base; - this.form.patchValue(patch); - } - } } diff --git a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-approval/poll-form-rating-approval.component.html b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-approval/poll-form-rating-approval.component.html index 0bb85eeaa60..bbfe3d37a3e 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-approval/poll-form-rating-approval.component.html +++ b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-approval/poll-form-rating-approval.component.html @@ -1,28 +1,30 @@
- - {{ 'Election method' | translate }} - - {{ 'Yes/No' | translate }} - {{ 'Yes/No/Abstain' | translate }} - - -
+ @if (!pollStarted()) { - {{ 'Min amount of votes' | translate }} - + {{ 'Election method' | translate }} + + {{ 'Yes/No' | translate }} + {{ 'Yes/No/Abstain' | translate }} + +
+ + {{ 'Min amount of votes' | translate }} + + - - {{ 'Max amount of votes' | translate }} - - + + {{ 'Max amount of votes' | translate }} + + - - {{ 'Max amount of yes votes' | translate }} - - -
+ + {{ 'Max amount of yes votes' | translate }} + + +
+ } {{ '100% base' | translate }} diff --git a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-approval/poll-form-rating-approval.component.ts b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-approval/poll-form-rating-approval.component.ts index 5b711dfa263..caeb7839c56 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-approval/poll-form-rating-approval.component.ts +++ b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-approval/poll-form-rating-approval.component.ts @@ -35,13 +35,12 @@ export class PollFormRatingApprovalComponent extends PollFormBaseComponent { [`disabled`, _('Disabled (no percents)')] ]; - public data = input>(); public optionAmount = input(null); - public initForm(): void { + protected initForm(): void { this.form = this.fb.group({ - onehundred_percent_base: [this.data().config.onehundred_percent_base], - allow_abstain: [this.data().config.allow_abstain], + onehundred_percent_base: [`valid`], + allow_abstain: [false], max_yes_amount: [1, [Validators.required, Validators.min(1)]], max_options_amount: [1, [Validators.required, Validators.min(1)]], min_options_amount: [1, [Validators.required, Validators.min(0), this.minOptionsAmountValidator()]] @@ -50,6 +49,22 @@ export class PollFormRatingApprovalComponent extends PollFormBaseComponent { effect(this.onOptionAmountUpdate.bind(this)); } + protected getPatchedFormData(data: Partial): Record { + const patch: Record = {}; + for (const field of [ + `onehundred_percent_base`, + `allow_abstain`, + `max_yes_amount`, + `max_options_amount`, + `min_options_amount` + ]) { + if (data && data[field] !== undefined) patch[field] = data[field]; + else if (data && data.config[field] !== undefined) patch[field] = data.config[field]; + } + + return patch; + } + public getSerialzedForm(): Record { return this.form.value; } @@ -74,8 +89,13 @@ export class PollFormRatingApprovalComponent extends PollFormBaseComponent { if (optionAmount) { maxCtrl?.setValidators([Validators.required, Validators.min(1), Validators.max(optionAmount)]); maxYesCtrl?.setValidators([Validators.required, Validators.min(1), Validators.max(optionAmount)]); - maxCtrl?.setValue(optionAmount, { emitEvent: false }); - maxYesCtrl.setValue(optionAmount, { emitEvent: false }); + if (maxCtrl?.pristine) { + maxCtrl?.setValue(optionAmount, { emitEvent: false }); + } + + if (maxYesCtrl?.pristine) { + maxYesCtrl.setValue(optionAmount, { emitEvent: false }); + } } else { maxCtrl?.setValidators([Validators.required, Validators.min(1)]); maxYesCtrl?.setValidators([Validators.required, Validators.min(1)]); diff --git a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-score/poll-form-rating-score.component.html b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-score/poll-form-rating-score.component.html index 20a9aad76d0..a310e2ff61f 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-score/poll-form-rating-score.component.html +++ b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-score/poll-form-rating-score.component.html @@ -1,49 +1,51 @@
-
- - {{ 'General abstain' | translate }} - -
+ @if (!pollStarted()) { +
+ + {{ 'General abstain' | translate }} + +
+ +
+ @if (!form.get('allow_general_abstain').value) { + + {{ 'Min amount of votes' | translate }} + + + } @else { +
+ } -
- @if (!form.get('allow_general_abstain').value) { - {{ 'Min amount of votes' | translate }} - + {{ 'Max amount of votes' | translate }} + - } @else { -
- } +
- - {{ 'Max amount of votes' | translate }} - - -
+
+ @if (!form.get('allow_general_abstain').value) { + + {{ 'Min amount of options voted' | translate }} + + + } @else { +
+ } -
- @if (!form.get('allow_general_abstain').value) { - {{ 'Min amount of options voted' | translate }} - + {{ 'Max amount of options voted' | translate }} + - } @else { -
- } +
- - {{ 'Max amount of options voted' | translate }} - - -
- -
- - {{ 'Max votes per option' | translate }} - - -
+
+ + {{ 'Max votes per option' | translate }} + + +
+ } {{ '100% base' | translate }} diff --git a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-score/poll-form-rating-score.component.ts b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-score/poll-form-rating-score.component.ts index 2658cbd8bda..10814bcc6c5 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-score/poll-form-rating-score.component.ts +++ b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-rating-score/poll-form-rating-score.component.ts @@ -34,32 +34,52 @@ export class PollFormRatingScoreComponent extends PollFormBaseComponent { [`disabled`, _('Disabled (no percents)')] ]; - public data = input>(); public optionAmount = input(null); - public initForm(): void { + public getSerialzedForm(): Record { + return { + ...this.form.value, + min_options_amount: this.form.value[`allow_general_abstain`] ? 0 : this.form.value[`min_options_amount`], + min_vote_sum: this.form.value[`allow_general_abstain`] ? 0 : this.form.value[`min_vote_sum`] + }; + } + + protected initForm(): void { this.form = this.fb.group({ - onehundred_percent_base: [this.data().config.onehundred_percent_base], + onehundred_percent_base: [`valid`], allow_general_abstain: [false], max_votes_per_option: [null], - max_options_amount: [this.optionAmount(), [Validators.required, Validators.min(1)]], + max_options_amount: [1, [Validators.required, Validators.min(1)]], min_options_amount: [ 1, [Validators.required, Validators.min(1), this.minOptionsAmountValidator(`max_options_amount`)] ], - max_vote_sum: [this.optionAmount(), [Validators.required, Validators.min(1)]], + max_vote_sum: [1, [Validators.required, Validators.min(1)]], min_vote_sum: [1, [Validators.required, Validators.min(1), this.minOptionsAmountValidator(`max_vote_sum`)]] }); effect(this.onOptionAmountUpdate.bind(this)); } - public getSerialzedForm(): Record { - return { - ...this.form.value, - min_options_amount: this.form.value[`allow_general_abstain`] ? 0 : this.form.value[`min_options_amount`], - min_vote_sum: this.form.value[`allow_general_abstain`] ? 0 : this.form.value[`min_vote_sum`] - }; + protected getPatchedFormData(data: Partial): Record { + const patch: Record = {}; + for (const field of [ + `onehundred_percent_base`, + `max_votes_per_option`, + `max_options_amount`, + `min_options_amount`, + `max_vote_sum`, + `min_vote_sum` + ]) { + if (data && data[field] !== undefined) patch[field] = data[field]; + else if (data && data.config[field] !== undefined) patch[field] = data.config[field]; + } + + if (patch[`min_options_amount`] !== undefined && patch[`min_vote_sum`] !== undefined) { + patch[`allow_general_abstain`] = +patch[`min_options_amount`] === 0 && +patch[`min_vote_sum`] === 0; + } + + return patch; } private minOptionsAmountValidator(dependant: string): ValidatorFn { @@ -79,6 +99,9 @@ export class PollFormRatingScoreComponent extends PollFormBaseComponent { const maxCtrl = this.form.get('max_options_amount'); if (this.optionAmount()) { maxCtrl?.setValidators([Validators.required, Validators.min(1), Validators.max(this.optionAmount())]); + if (maxCtrl?.pristine) { + maxCtrl?.setValue(this.optionAmount(), { emitEvent: false }); + } } else { maxCtrl?.setValidators([Validators.required, Validators.min(1)]); } diff --git a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-selection/poll-form-selection.component.html b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-selection/poll-form-selection.component.html index 5307bf59667..f40ac83155e 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-selection/poll-form-selection.component.html +++ b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-selection/poll-form-selection.component.html @@ -1,44 +1,48 @@ -
- - {{ 'Election method' | translate }} - - {{ 'Approval voting' | translate }} - {{ 'Disapproval voting' | translate }} - - -
+ @if (!pollStarted()) { +
+ + {{ 'Election method' | translate }} + + {{ 'Approval voting' | translate }} + {{ 'Disapproval voting' | translate }} + + +
+ }
-
- - {{ 'General abstain' | translate }} - + @if (!pollStarted()) { +
+ + {{ 'General abstain' | translate }} + - - @if (form.get('strike_out').value) { - {{ 'General approval' | translate }} + + @if (form.get('strike_out').value) { + {{ 'General approval' | translate }} + } @else { + {{ 'General rejection' | translate }} + } + +
+ +
+ @if (!form.get('allow_general_abstain').value) { + + {{ 'Min amount of votes' | translate }} + + } @else { - {{ 'General rejection' | translate }} +
} - -
-
- @if (!form.get('allow_general_abstain').value) { - {{ 'Min amount of votes' | translate }} - + {{ 'Max amount of votes' | translate }} + - } @else { -
- } - - - {{ 'Max amount of votes' | translate }} - - -
+
+ }
diff --git a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-selection/poll-form-selection.component.ts b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-selection/poll-form-selection.component.ts index 1a2919c8c16..afc7273c375 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/poll-form-selection/poll-form-selection.component.ts +++ b/client/src/app/site/pages/meetings/modules/poll/components/poll-form-selection/poll-form-selection.component.ts @@ -26,10 +26,16 @@ export class PollFormSelectionComponent extends PollFormBaseComponent { [`disabled`, _('Disabled (no percents)')] ]; - public data = input.required>(); public optionAmount = input(null); - public initForm(): void { + public getSerialzedForm(): Record { + return { + ...this.form.value, + min_options_amount: this.form.value[`allow_general_abstain`] ? 0 : this.form.value[`min_options_amount`] + }; + } + + protected initForm(): void { this.form = this.fb.group({ onehundred_percent_base: [`valid`], strike_out: [false], @@ -40,55 +46,45 @@ export class PollFormSelectionComponent extends PollFormBaseComponent { display_chart: [`table`] }); - effect(this.onDataUpdated.bind(this)); effect(this.onOptionAmountUpdate.bind(this)); } - public getSerialzedForm(): Record { - return { - ...this.form.value, - min_options_amount: this.form.value[`allow_general_abstain`] ? 0 : this.form.value[`min_options_amount`] - }; - } - - private minOptionsAmountValidator(): ValidatorFn { - return (field: AbstractControl): ValidationErrors | null => { - const min = Number(field.getRawValue()); - const max = Number(field.parent?.get('max_options_amount')?.getRawValue()); - - if (Number.isNaN(min) || Number.isNaN(max)) { - return null; - } - - return min <= max ? null : { minGreaterThanMax: true }; - }; - } - - private onDataUpdated(): void { - if (!this.data() || !this.form) { - return; - } - - const patch: Record = {}; + protected getPatchedFormData(data: Partial): Record { + const patch: Record = {}; for (const field of [ `onehundred_percent_base`, + `strike_out`, `allow_nota`, `max_options_amount`, `min_options_amount`, - `strike_out`, - `display_chart`, - `live_vote_enabled`, `display_chart` ]) { - if (this.data() && this.data()[field] !== undefined) patch[field] = this.data()[field]; - if (this.data() && this.data().config[field] !== undefined) patch[field] = this.data().config[field]; + if (data && data[field] !== undefined) patch[field] = data[field]; + else if (data && data.config[field] !== undefined) patch[field] = data.config[field]; } if (patch[`onehundred_percent_base`] === `yes_no`) { patch[`onehundred_percent_base`] = `valid`; } - this.form.patchValue(patch); + if (patch[`min_options_amount`] !== undefined) { + patch[`allow_general_abstain`] = +patch[`min_options_amount`] === 0; + } + + return patch; + } + + private minOptionsAmountValidator(): ValidatorFn { + return (field: AbstractControl): ValidationErrors | null => { + const min = Number(field.getRawValue()); + const max = Number(field.parent?.get('max_options_amount')?.getRawValue()); + + if (Number.isNaN(min) || Number.isNaN(max)) { + return null; + } + + return min <= max ? null : { minGreaterThanMax: true }; + }; } private onOptionAmountUpdate(): void { diff --git a/client/src/app/site/pages/meetings/pages/agenda/modules/topics/modules/topic-poll/components/topic-poll-dialog/topic-poll-dialog.component.html b/client/src/app/site/pages/meetings/pages/agenda/modules/topics/modules/topic-poll/components/topic-poll-dialog/topic-poll-dialog.component.html index 508e0a09cae..25f16b0ca55 100644 --- a/client/src/app/site/pages/meetings/pages/agenda/modules/topics/modules/topic-poll/components/topic-poll-dialog/topic-poll-dialog.component.html +++ b/client/src/app/site/pages/meetings/pages/agenda/modules/topics/modules/topic-poll/components/topic-poll-dialog/topic-poll-dialog.component.html @@ -1,18 +1,29 @@
- - -
- -
-
- -
+ @if (pollData.isCreated === false) { + @switch (this.getSelectedMethod()) { + @case ('approval') { -
-
-
+ } + @case ('selection') { + + } + } + } @else { + + +
+ +
+
+ +
+ +
+
+
+ }
diff --git a/client/src/app/site/pages/meetings/pages/assignments/modules/assignment-poll/components/assignment-poll-dialog/assignment-poll-dialog.component.html b/client/src/app/site/pages/meetings/pages/assignments/modules/assignment-poll/components/assignment-poll-dialog/assignment-poll-dialog.component.html index 7c35b0388f5..fb780f9838e 100644 --- a/client/src/app/site/pages/meetings/pages/assignments/modules/assignment-poll/components/assignment-poll-dialog/assignment-poll-dialog.component.html +++ b/client/src/app/site/pages/meetings/pages/assignments/modules/assignment-poll/components/assignment-poll-dialog/assignment-poll-dialog.component.html @@ -1,7 +1,22 @@
- @if (hasMultipleOptions) { + @if (pollData.isCreated === false) { + @switch (this.getSelectedMethod()) { + @case ('approval') { + + } + @case ('selection') { + + } + @case ('rating_approval') { + + } + @case ('rating_score') { + + } + } + } @else if (hasMultipleOptions) {
diff --git a/client/src/app/site/pages/meetings/pages/assignments/modules/assignment-poll/components/assignment-poll-dialog/assignment-poll-dialog.component.ts b/client/src/app/site/pages/meetings/pages/assignments/modules/assignment-poll/components/assignment-poll-dialog/assignment-poll-dialog.component.ts index 2a838b65fa5..8b7cc2d7dfb 100644 --- a/client/src/app/site/pages/meetings/pages/assignments/modules/assignment-poll/components/assignment-poll-dialog/assignment-poll-dialog.component.ts +++ b/client/src/app/site/pages/meetings/pages/assignments/modules/assignment-poll/components/assignment-poll-dialog/assignment-poll-dialog.component.ts @@ -62,8 +62,6 @@ export class AssignmentPollDialogComponent extends BasePollDialogComponent { return methods; }); - public method = `rating_approval`; - public get isEVotingEnabled(): boolean { return this.pollService.isElectronicVotingEnabled; } @@ -107,13 +105,17 @@ export class AssignmentPollDialogComponent extends BasePollDialogComponent { public constructor() { super(); + this.allowCumulative.set(this.meetingSettingsService.instant(`poll_enable_max_votes_per_option`)); + let method = this.pollData?.config?.method; if (this.pollData?.config_id) { const collection = collectionFromFqid(this.pollData?.config_id); - this.method = collection.replace(`poll_config_`, ``); - } else if (this.pollData?.config?.method) { - this.method = this.pollData.config.method; + method = collection.replace(`poll_config_`, ``); + } + if (method === `rating_score`) { + this.allowCumulative.set(true); } - this.selectedTab.set(this.tabMethodMap().indexOf(this.method)); + + this.selectedTab.set(this.tabMethodMap().indexOf(method)); this.meetingSettingsService .get(`poll_enable_max_votes_per_option`) diff --git a/client/src/app/site/pages/meetings/pages/polls/view-models/poll.ts b/client/src/app/site/pages/meetings/pages/polls/view-models/poll.ts index f2eab83f7c5..580dd11d794 100644 --- a/client/src/app/site/pages/meetings/pages/polls/view-models/poll.ts +++ b/client/src/app/site/pages/meetings/pages/polls/view-models/poll.ts @@ -6,6 +6,7 @@ import { Poll } from '@app/domain/models/poll/poll'; import { PollConfigApproval } from '@app/domain/models/poll/poll-config-approval'; import { PROJECTIONDEFAULT, ProjectiondefaultValue } from '@app/domain/models/projector/projection-default'; import { Topic } from '@app/domain/models/topics/topic'; +import { collectionFromFqid } from '@app/infrastructure/utils/transform-functions'; import { ViewModelRelations } from '@app/site/base/base-view-model'; import { ViewGroup } from '@app/site/pages/meetings/pages/participants'; import { ViewPollBallot, ViewPollOption } from '@app/site/pages/meetings/pages/polls'; @@ -108,7 +109,17 @@ export class ViewPoll } public getProjectiondefault(): ProjectiondefaultValue { - return PROJECTIONDEFAULT.poll; + if (!this.content_object_id) { + return null; + } + + if (collectionFromFqid(this.content_object_id) === Assignment.COLLECTION) { + return PROJECTIONDEFAULT.assignmentPoll; + } else if (collectionFromFqid(this.content_object_id) === Motion.COLLECTION) { + return PROJECTIONDEFAULT.motionPoll; + } + + return PROJECTIONDEFAULT.topicPoll; } public override getDetailStateUrl(): string { @@ -147,7 +158,7 @@ export class ViewPoll : []; return { content_object_id: this.fqid, - projectionDefault: PROJECTIONDEFAULT.poll, + projectionDefault: this.getProjectiondefault(), type: `poll`, getDialogTitle: this.getTitle, slideOptions