Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions client/src/app/domain/models/meetings/meeting.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@ import { PROJECTIONDEFAULTS, ProjectiondefaultValue } from '../projector/project

export type ExportCsvEncoding = `utf-8` | `iso-8859-15`;

/**
* Server side ballot choice definitions.
* Server-defined methods to determine the number of ballots to print
* Options are:
* - NUMBER_OF_DELEGATES Amount of users belonging to the predefined 'delegates' group (group id 2)
* - NUMBER_OF_ALL_PARTICIPANTS The amount of all registered users
* - CUSTOM_NUMBER a given number of ballots
*/
export type BallotPaperSelection = `NUMBER_OF_DELEGATES` | `NUMBER_OF_ALL_PARTICIPANTS` | `CUSTOM_NUMBER`;

export type ViewMeetingMediafileUsageKey = `logo_${LogoPlace}` | `font_${FontPlace}`;

export type MeetingMediafileUsageIdKey = `${ViewMeetingMediafileUsageKey}_id`;
Expand Down
42 changes: 8 additions & 34 deletions client/src/app/domain/models/meetings/meeting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@ import { ChangeRecoMode, LineNumberingMode } from '../motions/motions.constants'
import { PollVisibility } from '../poll';
import { BaseOnehundredPercentBase } from '../poll/poll-config-types';
import { ApplauseType } from './applause';
import {
BallotPaperSelection,
ExportCsvEncoding,
MeetingDefaultProjectorIdsKey,
MeetingMediafileUsageIdKey
} from './meeting.constants';
import { ExportCsvEncoding, MeetingDefaultProjectorIdsKey, MeetingMediafileUsageIdKey } from './meeting.constants';

export class Settings {
// Old "general_*" configs
Expand Down Expand Up @@ -146,13 +141,13 @@ export class Settings {
public motions_enable_restricted_editor_for_manager: boolean;
public motions_enable_restricted_editor_for_non_manager: boolean;

public motion_poll_ballot_paper_selection!: BallotPaperSelection;
public motion_poll_ballot_paper_number!: number;
// DELETE
public motion_poll_default_type!: PollVisibility;
public motion_poll_default_onehundred_percent_base!: BaseOnehundredPercentBase;
public motion_poll_default_group_ids!: Id[]; // (group/used_as_motion_poll_default_id)[];
public motion_poll_projection_name_order_first!: `first_name` | `last_name`;
public motion_poll_projection_max_columns!: number;
// DELETE END

// Users
public users_enable_presence_view!: boolean;
Expand All @@ -177,26 +172,27 @@ export class Settings {
public assignments_export_title!: string;
public assignments_export_preamble!: string;

public assignment_poll_ballot_paper_selection!: BallotPaperSelection;
public assignment_poll_ballot_paper_number!: number;
public assignment_poll_add_candidates_to_list_of_speakers!: boolean;

// DELETE
public assignment_poll_enable_max_votes_per_option!: boolean;
public assignment_poll_sort_poll_result_by_votes!: boolean;
public assignment_poll_default_type!: PollVisibility;
public assignment_poll_default_onehundred_percent_base!: BaseOnehundredPercentBase;
public assignment_poll_default_group_ids!: Id[]; // (group/used_as_assignment_poll_default_id)[];
// DELETE END

// topic poll
public topic_poll_default_group_ids: Id[]; // (group/used_as_poll_default_id)[];

// default poll
public poll_ballot_paper_selection: BallotPaperSelection;
public poll_ballot_paper_number: number;
// DELETE
public poll_sort_poll_result_by_votes: boolean;
public poll_default_type: PollVisibility;
public poll_default_onehundred_percent_base: BaseOnehundredPercentBase;
public poll_default_group_ids: Id[]; // (group/used_as_poll_default_id)[];
public poll_default_live_voting_enabled: boolean;
// DELETE END

// SSO
public external_id!: string;
Expand Down Expand Up @@ -406,13 +402,6 @@ export class Meeting extends BaseModel<Meeting> {
`motions_export_follow_recommendation`,
`motions_enable_restricted_editor_for_manager`,
`motions_enable_restricted_editor_for_non_manager`,
`motion_poll_ballot_paper_selection`,
`motion_poll_ballot_paper_number`,
`motion_poll_default_type`,
`motion_poll_default_onehundred_percent_base`,
`motion_poll_default_group_ids`,
`motion_poll_projection_name_order_first`,
`motion_poll_projection_max_columns`,
`meeting_user_ids`,
`users_enable_presence_view`,
`users_enable_vote_weight`,
Expand All @@ -433,22 +422,8 @@ export class Meeting extends BaseModel<Meeting> {
`users_forbid_delegator_to_vote`,
`assignments_export_title`,
`assignments_export_preamble`,
`assignment_poll_ballot_paper_selection`,
`assignment_poll_ballot_paper_number`,
`assignment_poll_add_candidates_to_list_of_speakers`,
`assignment_poll_enable_max_votes_per_option`,
`assignment_poll_sort_poll_result_by_votes`,
`assignment_poll_default_type`,
`assignment_poll_default_onehundred_percent_base`,
`assignment_poll_default_group_ids`,
`poll_ballot_paper_selection`,
`poll_ballot_paper_number`,
`poll_sort_poll_result_by_votes`,
`poll_default_type`,
`poll_default_onehundred_percent_base`,
`poll_default_group_ids`,
`poll_default_live_voting_enabled`,
`topic_poll_default_group_ids`,
`projector_ids`,
`all_projection_ids`,
`projector_message_ids`,
Expand Down Expand Up @@ -521,7 +496,6 @@ export class Meeting extends BaseModel<Meeting> {
`default_projector_countdown_ids`,
`default_projector_assignment_poll_ids`,
`default_projector_motion_poll_ids`,
`default_projector_poll_ids`,
`default_group_id`,
`admin_group_id`,
`anonymous_group_id`,
Expand Down
6 changes: 6 additions & 0 deletions client/src/app/domain/models/poll/generic-poll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import { ViewAssignment } from 'src/app/site/pages/meetings/pages/assignments';
import { ViewMotion } from 'src/app/site/pages/meetings/pages/motions';
import { ViewMeetingUser } from 'src/app/site/pages/meetings/view-models/view-meeting-user';

import { PollConfigApproval } from './poll-config-approval';
import { PollConfigRatingApproval } from './poll-config-rating-approval';
import { PollConfigRatingScore } from './poll-config-rating-score';
import { PollConfigSelection } from './poll-config-selection';

export type PollContentObject = ViewAssignment | ViewMotion | ViewTopic;
export type AnyPollConfig = PollConfigApproval | PollConfigRatingApproval | PollConfigRatingScore | PollConfigSelection;

/**
* The main interface to describe everything related to polls
Expand Down
3 changes: 0 additions & 3 deletions client/src/app/domain/models/users/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,6 @@ export class Group extends BaseModel<Group> {
`write_comment_section_ids`,
`read_chat_group_ids`,
`write_chat_group_ids`,
`used_as_motion_poll_default_id`,
`used_as_assignment_poll_default_id`,
`used_as_topic_poll_default_id`,
`meeting_id`
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,30 +52,16 @@ export class PollRepositoryService extends BaseMeetingRelatedRepository<ViewPoll

public async update(poll: ViewPoll, payload: PollUpdatePayload): Promise<void> {
if (payload.visibility === PollVisibility.Manually) {
return this.updateAnalogPoll(poll.id, payload);
return this.updateAnalogPoll(poll, payload);
}

return this.updateElectronicPoll(poll, payload);
}

private async createAnalogPoll(_poll: any): Promise<Identifiable> {
/*
const payload = {
meeting_id: this.activeMeetingId,
title: poll.title,
publish_immediately: poll.publish_immediately,
type: poll.type,
global_abstain: poll.global_abstain,
global_no: poll.global_no,
global_yes: poll.global_yes,
options: this.getAnalogOptions(poll.options),
content_object_id: poll.content_object_id,
...this.getAnalogPollVotesValues(poll),
...this.getAnalogPollGlobalValues(poll)
};
return this.sendActionToBackend(PollAction.CREATE, payload);
*/
throw new Error(`not implemented`);
private async createAnalogPoll(payload: any): Promise<Identifiable> {
delete payload.live_voting_enabled;

return this.voteApi.create(payload);
}

private async createElectronicPoll(payload: PollCreatePayload): Promise<Identifiable> {
Expand All @@ -86,21 +72,12 @@ export class PollRepositoryService extends BaseMeetingRelatedRepository<ViewPoll
return this.voteApi.create(payload);
}

private async updateAnalogPoll(_pollId: Id, _payload: PollUpdatePayload): Promise<void> {
/*
let payload: any;
if (poll.state === PollState.Created) {
payload = this.getUpdateCreatedAnalogPollPayload(update, poll);
} else {
payload = this.updateOtherStateAnalogPoll(update, poll);
private async updateAnalogPoll(poll: ViewPoll, payload: PollUpdatePayload): Promise<void> {
if (poll.config.METHOD_NAME === payload.method) {
delete payload[`method`];
}
const optionUpdatePayload = this.getAnalogOptions(option, true);
return this.sendActionsToBackend([
{ action: PollAction.UPDATE, data: [payload] },
{ action: PollAction.UPDATE_OPTION, data: optionUpdatePayload }
]);
*/
throw new Error(`not implemented`);

return this.voteApi.update(poll.id, payload);
}

private async updateElectronicPoll(poll: ViewPoll, payload: PollUpdatePayload): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { Directive, inject, viewChild } from '@angular/core';
import { Directive, inject, signal, viewChild } from '@angular/core';
import { rxResource } from '@angular/core/rxjs-interop';
import { UntypedFormBuilder } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { map } from 'rxjs';
import { Fqid, Id } from 'src/app/domain/definitions/key-types';
import { BaseModel } from 'src/app/domain/models/base/base-model';
import { PollVisibility } from 'src/app/domain/models/poll';
import { PollUpdatePayload } from 'src/app/gateways/vote-api.service';
import { ViewPoll } from 'src/app/site/pages/meetings/pages/polls';
import { BaseUiComponent } from 'src/app/ui/base/base-ui-component';

import { PollEditResultComponent } from '../components/poll-edit-result/poll-edit-result.component';
import { PollFormComponent } from '../components/poll-form/poll-form.component';

export interface OptionsObject {
Expand All @@ -19,12 +24,23 @@ export interface OptionsObjectForText {
text: string;
}

export interface PollMethodPayload {
method: string;
method_config: unknown;
}

export interface PollOptionsPayload {
option_type?: 'text' | 'meeting_user';
options?: (string | number)[];
}

/**
* A dialog for updating the values of a poll.
*/
@Directive()
export abstract class BasePollDialogComponent extends BaseUiComponent {
protected pollForm = viewChild.required(PollFormComponent);
protected pollResultForm = viewChild(PollEditResultComponent);

public get formsValid(): boolean {
if (!this.pollForm) {
Expand All @@ -34,6 +50,15 @@ export abstract class BasePollDialogComponent extends BaseUiComponent {
return this.pollForm().pollForm.valid;
}

public analogPollFormOpen = signal(false);
public isAnalogPoll = rxResource({
params: () => this.pollForm(),
defaultValue: false,
stream({ params }) {
return params.pollForm.get(`visibility`).valueChanges.pipe(map(v => v === PollVisibility.Manually));
}
});

protected formBuilder = inject(UntypedFormBuilder);
public dialogRef = inject(MatDialogRef<BasePollDialogComponent>);
public pollData: ViewPoll = inject(MAT_DIALOG_DATA);
Expand All @@ -43,6 +68,44 @@ export abstract class BasePollDialogComponent extends BaseUiComponent {
this.addKeyListener();
}

/**
* Submits the values from dialog.
*/
public submitPoll(): void {
const formValues = this.pollForm().getValues();
const visibility: PollVisibility = formValues?.visibility;

const payload: PollUpdatePayload = {
title: formValues?.title,
...this.methodPayload(),
...this.optionsPayload(),
visibility,
allow_vote_split: false
};

if (visibility !== PollVisibility.Manually) {
payload.entitled_group_ids = formValues?.entitled_group_ids ?? [];
payload.live_voting_enabled = formValues?.live_voting_enabled ?? false;
} else if (this.pollResultForm()) {
const result = this.pollResultForm().serializeResult();
if (result) {
payload.result = result;
}
}

this.dialogRef.close(payload);
}

/**
* Returns the poll method related part of the payload
*/
public abstract methodPayload(): PollMethodPayload;

/**
* Returns the poll options related part of the payload
*/
public abstract optionsPayload(): PollOptionsPayload;

private addKeyListener(): void {
if (!this.dialogRef) {
return;
Expand All @@ -60,9 +123,4 @@ export abstract class BasePollDialogComponent extends BaseUiComponent {
})
);
}

/**
* Submits the values from dialog.
*/
public abstract submitPoll(): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Component, inject } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';

@Component({ template: `` })
export abstract class PollFormBaseComponent {
public form: UntypedFormGroup;

protected fb = inject(UntypedFormBuilder);

public constructor() {
this.initForm();
}

public abstract initForm(): void;
public abstract getSerialzedForm(): Record<string, unknown>;
}
Loading
Loading