diff --git a/client/cli/generate-permissions.ts b/client/cli/generate-permissions.ts index 739e5f6820..c3d6c0436b 100644 --- a/client/cli/generate-permissions.ts +++ b/client/cli/generate-permissions.ts @@ -7,7 +7,7 @@ import { overloadJsFunctions } from '@app/infrastructure/utils/overload-js-funct overloadJsFunctions(); -const SOURCE = path.resolve(path.join(__dirname, '../meta/permission.yml')); +const SOURCE = path.resolve(path.join(__dirname, '../../meta/permission.yml')); const BASE_PATH = path.resolve(path.join(__dirname, `..`)); const DOMAIN_DEFINITIONS_PATH = `src/app/domain/definitions`; @@ -33,21 +33,21 @@ const FILE_TEMPLATE_PERMISSION_RELATIONS = dedent` import { PermissionsMap } from './permission.config'; `; -const permissionMap: { [permission: string]: PermissionNode } = {}; +const permissionMap: Record = {}; /** * Helper class to generate the permission graph. Holds information about its permission as well as * its parents and children. */ class PermissionNode { - parents: PermissionNode[] = []; - children: PermissionNode[] = []; - permission: string; - enumKey: string; + public parents: PermissionNode[] = []; + public children: PermissionNode[] = []; + public permission: string; + public enumKey: string; public constructor(permission: string) { this.permission = permission; - this.enumKey = permission.replace(/[_\.]([a-z])/g, (_, c) => c.toUpperCase()); + this.enumKey = permission.replace(/[_.]([a-z])/g, (_, c) => c.toUpperCase()); } } @@ -137,7 +137,7 @@ function writePermissionRelations(nodes: PermissionNode[]): void { * @returns a set of all relatives of the given node in the given direction */ function getPermissionRelatives(node: PermissionNode, field: PermissionNodeRelativesField): Set { - let relatives = new Set(); + const relatives = new Set(); for (const relative of node[field]) { relatives.add(relative); relatives.update(getPermissionRelatives(relative, field)); diff --git a/client/package-lock.json b/client/package-lock.json index 484899d106..c0b1c87728 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -51,6 +51,7 @@ "@tsparticles/plugin-emitters": "^3.9.1", "@tsparticles/shape-text": "^3.9.1", "@tsparticles/slim": "^3.9.1", + "big.js": "^7.0.1", "chart.js": "^4.5.1", "cm-chess": "^3.6.3", "cm-chessboard": "^8.12.14", @@ -85,6 +86,7 @@ "@angular/compiler-cli": "^22.0.7", "@angular/language-server": "^22.0.7", "@stylistic/eslint-plugin": "^5.10.0", + "@types/big.js": "^7.0.0", "@types/file-saver": "^2.0.7", "@types/jasmine": "~5.1.15", "@types/js-yaml": "^4.0.9", @@ -6035,6 +6037,13 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/@types/big.js": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/big.js/-/big.js-7.0.0.tgz", + "integrity": "sha512-WfAGp7IbJvyB8EmWK4tJD24rJRAL6uVbw3LV/hJntFNam+os9KWKj0PzXo8rRRpjupYK8U0M8FoBB8dBhWF2dg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/cors": { "version": "2.8.17", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", @@ -6984,6 +6993,19 @@ "node": ">=0.6" } }, + "node_modules/big.js": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-7.0.1.tgz", + "integrity": "sha512-iFgV784tD8kq4ccF1xtNMZnXeZzVuXWWM+ERFzKQjv+A5G9HC8CY3DuV45vgzFFcW+u2tIvmF95+AzWgs6BjCg==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bigjs" + } + }, "node_modules/binary": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", diff --git a/client/package.json b/client/package.json index 7ee71cce38..b8b27558f7 100644 --- a/client/package.json +++ b/client/package.json @@ -74,6 +74,7 @@ "@tsparticles/plugin-emitters": "^3.9.1", "@tsparticles/shape-text": "^3.9.1", "@tsparticles/slim": "^3.9.1", + "big.js": "^7.0.1", "chart.js": "^4.5.1", "cm-chess": "^3.6.3", "cm-chessboard": "^8.12.14", @@ -108,6 +109,7 @@ "@angular/compiler-cli": "^22.0.7", "@angular/language-server": "^22.0.7", "@stylistic/eslint-plugin": "^5.10.0", + "@types/big.js": "^7.0.0", "@types/file-saver": "^2.0.7", "@types/jasmine": "~5.1.15", "@types/js-yaml": "^4.0.9", diff --git a/client/src/app/domain/definitions/meeting-settings-defaults.ts b/client/src/app/domain/definitions/meeting-settings-defaults.ts index 3dd6d913cf..bcea5bb4d5 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/definitions/permission-relations.ts b/client/src/app/domain/definitions/permission-relations.ts index 1da7f101d1..02e753edbb 100644 --- a/client/src/app/domain/definitions/permission-relations.ts +++ b/client/src/app/domain/definitions/permission-relations.ts @@ -4,13 +4,20 @@ import { PermissionsMap } from './permission.config'; export const permissionChildren: PermissionsMap = { 'agenda_item.can_manage': [Permission.agendaItemCanSeeInternal, Permission.agendaItemCanSee], + 'agenda_item.can_manage_polls': [ + Permission.agendaItemCanSeePolls, + Permission.agendaItemCanSeeInternal, + Permission.agendaItemCanSee + ], 'agenda_item.can_see': [], 'agenda_item.can_see_internal': [Permission.agendaItemCanSee], + 'agenda_item.can_see_polls': [Permission.agendaItemCanSeeInternal, Permission.agendaItemCanSee], 'assignment.can_manage': [Permission.assignmentCanNominateOther, Permission.assignmentCanSee], - 'assignment.can_manage_polls': [Permission.assignmentCanSee], + 'assignment.can_manage_polls': [Permission.assignmentCanSeePolls, Permission.assignmentCanSee], 'assignment.can_nominate_other': [Permission.assignmentCanSee], 'assignment.can_nominate_self': [Permission.assignmentCanSee], 'assignment.can_see': [], + 'assignment.can_see_polls': [Permission.assignmentCanSee], 'chat.can_manage': [], 'list_of_speakers.can_be_speaker': [], 'list_of_speakers.can_manage': [Permission.listOfSpeakersCanSee], @@ -37,12 +44,12 @@ export const permissionChildren: PermissionsMap = { Permission.motionCanForward ], 'motion.can_manage_metadata': [Permission.motionCanSee], - 'motion.can_manage_polls': [Permission.motionCanSee], + 'motion.can_manage_polls': [Permission.motionCanSeePolls, Permission.motionCanSee], 'motion.can_see': [], 'motion.can_see_internal': [Permission.motionCanSee], 'motion.can_see_origin': [Permission.motionCanSee], + 'motion.can_see_polls': [Permission.motionCanSee], 'motion.can_support': [Permission.motionCanSee], - 'poll.can_manage': [Permission.pollCanSeeProgress], 'poll.can_see_progress': [], 'projector.can_manage': [Permission.projectorCanSee], 'projector.can_see': [], @@ -62,8 +69,19 @@ export const permissionChildren: PermissionsMap = { export const permissionParents: PermissionsMap = { 'agenda_item.can_manage': [], - 'agenda_item.can_see': [Permission.agendaItemCanSeeInternal, Permission.agendaItemCanManage], - 'agenda_item.can_see_internal': [Permission.agendaItemCanManage], + 'agenda_item.can_manage_polls': [], + 'agenda_item.can_see': [ + Permission.agendaItemCanSeeInternal, + Permission.agendaItemCanManage, + Permission.agendaItemCanSeePolls, + Permission.agendaItemCanManagePolls + ], + 'agenda_item.can_see_internal': [ + Permission.agendaItemCanManage, + Permission.agendaItemCanSeePolls, + Permission.agendaItemCanManagePolls + ], + 'agenda_item.can_see_polls': [Permission.agendaItemCanManagePolls], 'assignment.can_manage': [], 'assignment.can_manage_polls': [], 'assignment.can_nominate_other': [Permission.assignmentCanManage], @@ -71,9 +89,11 @@ export const permissionParents: PermissionsMap = { 'assignment.can_see': [ Permission.assignmentCanNominateOther, Permission.assignmentCanManage, + Permission.assignmentCanSeePolls, Permission.assignmentCanManagePolls, Permission.assignmentCanNominateSelf ], + 'assignment.can_see_polls': [Permission.assignmentCanManagePolls], 'chat.can_manage': [], 'list_of_speakers.can_be_speaker': [], 'list_of_speakers.can_manage': [], @@ -101,15 +121,16 @@ export const permissionParents: PermissionsMap = { Permission.motionCanCreate, Permission.motionCanCreateAmendments, Permission.motionCanForward, + Permission.motionCanSeePolls, Permission.motionCanManagePolls, Permission.motionCanSupport, Permission.motionCanSeeOrigin ], 'motion.can_see_internal': [Permission.motionCanManage], 'motion.can_see_origin': [], + 'motion.can_see_polls': [Permission.motionCanManagePolls], 'motion.can_support': [], - 'poll.can_manage': [], - 'poll.can_see_progress': [Permission.pollCanManage], + 'poll.can_see_progress': [], 'projector.can_manage': [], 'projector.can_see': [Permission.projectorCanManage], 'tag.can_manage': [], diff --git a/client/src/app/domain/definitions/permission.config.ts b/client/src/app/domain/definitions/permission.config.ts index 4255c5d966..963f4f9af3 100644 --- a/client/src/app/domain/definitions/permission.config.ts +++ b/client/src/app/domain/definitions/permission.config.ts @@ -89,7 +89,12 @@ Optional combination of requests to speak with presence status is possible. ( > { display_name: _(`Can manage polls`), help_text: _(`Can create, change, start/stop and delete polls.`), - value: Permission.pollCanManage + value: Permission.agendaItemCanManagePolls + }, + { + display_name: _(`Can see ballot results`), + help_text: _(`Can see unpublished ballot results.`), + value: Permission.agendaItemCanSeePolls }, { display_name: _(`Can see moderation notes`), @@ -180,6 +185,11 @@ Further requirements: display_name: _(`Can manage motion polls`), help_text: _(`Can create, modify, start/stop and delete votings.`), value: Permission.motionCanManagePolls + }, + { + display_name: _(`Can see ballot results`), + help_text: _(`Can see unpublished ballot results.`), + value: Permission.motionCanSeePolls } ] }, @@ -208,6 +218,11 @@ Note: The right to vote is defined directly in the ballot.` help_text: _(`Can create, modify, start/stop and delete ballots.`), value: Permission.assignmentCanManagePolls }, + { + display_name: _(`Can see ballot results`), + help_text: _(`Can see unpublished ballot results.`), + value: Permission.assignmentCanSeePolls + }, { display_name: _(`Can nominate another participant`), help_text: _(`Can nominate other participants as candidates. @@ -335,6 +350,11 @@ Note: For privacy reasons, it is recommended to limit the rights to view the His Note: The chat menu item becomes visible to all participants, except admins, as soon as a chat has been created.`), value: Permission.chatCanManage + }, + { + display_name: _(`Can see poll progress`), + help_text: _(`Can see the progress bar of a running poll.`), + value: Permission.pollCanSeeProgress } ] } diff --git a/client/src/app/domain/definitions/permission.ts b/client/src/app/domain/definitions/permission.ts index 653a575683..86328d059f 100644 --- a/client/src/app/domain/definitions/permission.ts +++ b/client/src/app/domain/definitions/permission.ts @@ -5,13 +5,16 @@ */ export enum Permission { agendaItemCanManage = `agenda_item.can_manage`, + agendaItemCanManagePolls = `agenda_item.can_manage_polls`, agendaItemCanSee = `agenda_item.can_see`, agendaItemCanSeeInternal = `agenda_item.can_see_internal`, + agendaItemCanSeePolls = `agenda_item.can_see_polls`, assignmentCanManage = `assignment.can_manage`, assignmentCanManagePolls = `assignment.can_manage_polls`, assignmentCanNominateOther = `assignment.can_nominate_other`, assignmentCanNominateSelf = `assignment.can_nominate_self`, assignmentCanSee = `assignment.can_see`, + assignmentCanSeePolls = `assignment.can_see_polls`, chatCanManage = `chat.can_manage`, listOfSpeakersCanBeSpeaker = `list_of_speakers.can_be_speaker`, listOfSpeakersCanManage = `list_of_speakers.can_manage`, @@ -35,8 +38,8 @@ export enum Permission { motionCanSee = `motion.can_see`, motionCanSeeInternal = `motion.can_see_internal`, motionCanSeeOrigin = `motion.can_see_origin`, + motionCanSeePolls = `motion.can_see_polls`, motionCanSupport = `motion.can_support`, - pollCanManage = `poll.can_manage`, pollCanSeeProgress = `poll.can_see_progress`, projectorCanManage = `projector.can_manage`, projectorCanSee = `projector.can_see`, diff --git a/client/src/app/domain/models/meeting-users/meeting-user.ts b/client/src/app/domain/models/meeting-users/meeting-user.ts index 2d2b26aaea..fe9fec6fb0 100644 --- a/client/src/app/domain/models/meeting-users/meeting-user.ts +++ b/client/src/app/domain/models/meeting-users/meeting-user.ts @@ -24,8 +24,9 @@ export class MeetingUser extends BaseDecimalModel { public motion_supporter_ids!: Id[]; // (motion_supporter/meeting_user_id); public submitted_motion_ids!: Id[]; // (motion_submitter/meeting_user_id)[]; public assignment_candidate_ids!: Id[]; // (assignment_candidate/meeting_user_id)[]; - public vote_delegated_vote_ids!: Id[]; public vote_delegations_from_ids!: Id[]; // meeting_user/vote_delegated_to_id; + public acting_ballot_ids: Id[]; + public represented_ballot_ids: Id[]; public chat_message_ids!: Id[]; // (chat_message/meeting_user_id)[]; public structure_level_ids!: Id[]; // structure_level/meeting_user_ids @@ -52,6 +53,8 @@ export class MeetingUser extends BaseDecimalModel { `assignment_candidate_ids`, `vote_delegated_to_id`, `vote_delegations_from_ids`, + `acting_ballot_ids`, + `represented_ballot_ids`, `chat_message_ids`, `group_ids`, `structure_level_ids` diff --git a/client/src/app/domain/models/meetings/meeting-poll-default.ts b/client/src/app/domain/models/meetings/meeting-poll-default.ts new file mode 100644 index 0000000000..7344f1ee6b --- /dev/null +++ b/client/src/app/domain/models/meetings/meeting-poll-default.ts @@ -0,0 +1,37 @@ +import { HasMeetingId } from '../../interfaces'; +import { BaseModel } from '../base/base-model'; +import { PollVisibility } from '../poll'; +import { BaseOnehundredPercentBase } from '../poll/poll-config-types'; + +export class MeetingPollDefault extends BaseModel { + public static COLLECTION = `meeting_poll_default`; + + public sort_result_by_votes: boolean; + + public allow_abstain!: boolean; + public allow_nota: boolean; + public visibility: PollVisibility; + public strike_out: boolean; + public onehundred_percent_base: BaseOnehundredPercentBase; + public group_ids: number[]; + public display_chart: string; + + public constructor(input?: Partial) { + super(MeetingPollDefault.COLLECTION, input); + } + + public static readonly REQUESTABLE_FIELDS: (keyof MeetingPollDefault)[] = [ + `id`, + `sort_result_by_votes`, + `visibility`, + `allow_abstain`, + `allow_nota`, + `strike_out`, + `onehundred_percent_base`, + `group_ids`, + `display_chart`, + `meeting_id` + ]; +} + +export interface MeetingPollDefault extends HasMeetingId {} diff --git a/client/src/app/domain/models/meetings/meeting.constants.ts b/client/src/app/domain/models/meetings/meeting.constants.ts index d38548ec21..1832cbfbba 100644 --- a/client/src/app/domain/models/meetings/meeting.constants.ts +++ b/client/src/app/domain/models/meetings/meeting.constants.ts @@ -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`; diff --git a/client/src/app/domain/models/meetings/meeting.ts b/client/src/app/domain/models/meetings/meeting.ts index f88342a09d..f0686e461d 100644 --- a/client/src/app/domain/models/meetings/meeting.ts +++ b/client/src/app/domain/models/meetings/meeting.ts @@ -4,14 +4,8 @@ import { HasProperties } from '../../interfaces/has-properties'; import { AgendaItemCreation, AgendaItemType } from '../agenda/agenda-item'; import { BaseModel } from '../base/base-model'; import { ChangeRecoMode, LineNumberingMode } from '../motions/motions.constants'; -import { PollBackendDurationType, PollMethod, PollPercentBase, PollType } from '../poll/poll-constants'; 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 @@ -144,16 +138,7 @@ export class Settings { public motions_create_enable_additional_submitter_text: boolean; 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; - public motion_poll_default_type!: PollType; - public motion_poll_default_onehundred_percent_base!: PollPercentBase; - public motion_poll_default_group_ids!: Id[]; // (group/used_as_motion_poll_default_id)[]; - public motion_poll_default_backend!: PollBackendDurationType; - public motion_poll_default_method!: PollMethod; - public motion_poll_projection_name_order_first!: `first_name` | `last_name`; - public motion_poll_projection_max_columns!: number; + public motion_poll_config_id: Id; // Users public users_enable_presence_view!: boolean; @@ -178,30 +163,20 @@ 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; - public assignment_poll_enable_max_votes_per_option!: boolean; - public assignment_poll_sort_poll_result_by_votes!: boolean; - public assignment_poll_default_type!: PollType; - public assignment_poll_default_method!: PollMethod; - public assignment_poll_default_onehundred_percent_base!: PollPercentBase; - public assignment_poll_default_group_ids!: Id[]; // (group/used_as_assignment_poll_default_id)[]; - public assignment_poll_default_backend!: PollBackendDurationType; + public assignment_poll_default_method: string; + public assignment_poll_config_id: Id; // 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; - public poll_sort_poll_result_by_votes: boolean; - public poll_default_type: PollType; - public poll_default_method: PollMethod; - public poll_default_onehundred_percent_base: PollPercentBase; - public poll_default_group_ids: Id[]; // (group/used_as_poll_default_id)[]; - public poll_default_backend: PollBackendDurationType; + public topic_poll_default_method: string; + public topic_poll_config_id: Id; + + // General poll settings public poll_default_live_voting_enabled: boolean; + public poll_enable_max_votes_per_option: boolean; + public poll_default_allow_invalid: boolean; + public poll_default_allow_vote_split: boolean; + public poll_projection_name_order_first: `first_name` | `last_name`; // SSO public external_id!: string; @@ -411,17 +386,6 @@ export class Meeting extends BaseModel { `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_method`, - `motion_poll_default_onehundred_percent_base`, - `motion_poll_default_group_ids`, - `motion_poll_default_backend`, - `motion_poll_projection_name_order_first`, - `motion_poll_projection_max_columns`, - `poll_candidate_list_ids`, - `poll_candidate_ids`, `meeting_user_ids`, `users_enable_presence_view`, `users_enable_vote_weight`, @@ -442,26 +406,17 @@ export class Meeting extends BaseModel { `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_method`, - `assignment_poll_default_onehundred_percent_base`, - `assignment_poll_default_group_ids`, - `assignment_poll_default_backend`, - `poll_ballot_paper_selection`, - `poll_ballot_paper_number`, - `poll_sort_poll_result_by_votes`, - `poll_default_type`, - `poll_default_method`, - `poll_default_onehundred_percent_base`, - `poll_default_group_ids`, - `poll_default_backend`, + `assignment_poll_config_id`, + `motion_poll_config_id`, + `topic_poll_default_method`, + `topic_poll_config_id`, + `poll_enable_max_votes_per_option`, `poll_default_live_voting_enabled`, - `topic_poll_default_group_ids`, + `poll_default_allow_invalid`, + `poll_default_allow_vote_split`, + `poll_projection_name_order_first`, `projector_ids`, `all_projection_ids`, `projector_message_ids`, @@ -490,8 +445,6 @@ export class Meeting extends BaseModel { `motion_change_recommendation_ids`, `motion_state_ids`, `poll_ids`, - `option_ids`, - `vote_ids`, `assignment_ids`, `assignment_candidate_ids`, `personal_note_ids`, @@ -536,7 +489,7 @@ export class Meeting extends BaseModel { `default_projector_countdown_ids`, `default_projector_assignment_poll_ids`, `default_projector_motion_poll_ids`, - `default_projector_poll_ids`, + `default_projector_topic_poll_ids`, `default_group_id`, `admin_group_id`, `anonymous_group_id`, diff --git a/client/src/app/domain/models/poll-candidate-lists/poll-candidate-list.ts b/client/src/app/domain/models/poll-candidate-lists/poll-candidate-list.ts deleted file mode 100644 index fbfeff3909..0000000000 --- a/client/src/app/domain/models/poll-candidate-lists/poll-candidate-list.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Id } from '../../definitions/key-types'; -import { HasMeetingId } from '../../interfaces'; -import { BaseModel } from '../base/base-model'; - -export class PollCandidateList extends BaseModel { - public static COLLECTION = `poll_candidate_list`; - - public option_id!: Id; // option/content_object_id; - public poll_candidate_ids!: Id[]; // poll_candidate/poll_candidate_list_id; - - public constructor(input?: any) { - super(PollCandidateList.COLLECTION, input); - } - - public static readonly REQUESTABLE_FIELDS: (keyof PollCandidateList)[] = [ - `id`, - `poll_candidate_ids`, - `meeting_id`, - `option_id` - ]; -} -export interface PollCandidateList extends HasMeetingId {} diff --git a/client/src/app/domain/models/poll-candidate-lists/poll-candidate.ts b/client/src/app/domain/models/poll-candidate-lists/poll-candidate.ts deleted file mode 100644 index 5b879d2774..0000000000 --- a/client/src/app/domain/models/poll-candidate-lists/poll-candidate.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Id } from '../../definitions/key-types'; -import { HasMeetingId } from '../../interfaces'; -import { BaseModel } from '../base/base-model'; - -export class PollCandidate extends BaseModel { - public static COLLECTION = `poll_candidate`; - - public weight!: number; - - public poll_candidate_list_id!: Id; // poll_candidate_list/poll_candidate_ids; - public user_id!: Id; // user/poll_candidate_ids; - - public constructor(input?: any) { - super(PollCandidate.COLLECTION, input); - } - - public static readonly REQUESTABLE_FIELDS: (keyof PollCandidate)[] = [ - `id`, - `poll_candidate_list_id`, - `user_id`, - `weight`, - `meeting_id` - ]; -} -export interface PollCandidate extends HasMeetingId {} diff --git a/client/src/app/domain/models/poll/base-poll-config.ts b/client/src/app/domain/models/poll/base-poll-config.ts new file mode 100644 index 0000000000..0b4fa7c023 --- /dev/null +++ b/client/src/app/domain/models/poll/base-poll-config.ts @@ -0,0 +1,6 @@ +import { Id } from '../../definitions/key-types'; +import { BaseModel } from '../base/base-model'; + +export abstract class BasePollConfigModel extends BaseModel { + public poll_id!: Id; +} diff --git a/client/src/app/domain/models/poll/generic-poll.ts b/client/src/app/domain/models/poll/generic-poll.ts index 4d63966ce0..0a61f21886 100644 --- a/client/src/app/domain/models/poll/generic-poll.ts +++ b/client/src/app/domain/models/poll/generic-poll.ts @@ -1,40 +1,21 @@ import { ViewTopic } from '@app/site/pages/meetings/pages/agenda'; import { ViewAssignment } from '@app/site/pages/meetings/pages/assignments'; import { ViewMotion } from '@app/site/pages/meetings/pages/motions'; -import { ViewPollCandidateList } from '@app/site/pages/meetings/pages/polls/view-models/view-poll-candidate-list'; -import { ViewUser } from '@app/site/pages/meetings/view-models/view-user'; -import { Observable } from 'rxjs'; +import { ViewMeetingUser } from '@app/site/pages/meetings/view-models/view-meeting-user'; -import { EntitledUsersEntry, PollClassType, PollMethod, PollPercentBase, PollState, PollType } from './poll-constants'; +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 * This is a unification of the data received in the projector and ViewPoll; both * use this interface, so the poll services can work on this shared view on the data. */ -export interface PollData { - pollClassType?: PollClassType; - pollmethod: PollMethod; - state: PollState; - onehundred_percent_base: PollPercentBase; - votesvalid: number; - votesinvalid: number; - votescast: number; - type: PollType; - entitled_users_at_stop: EntitledUsersEntry[]; - options: OptionData[]; - options$: Observable; - global_option: OptionData; - global_yes?: boolean; - global_no?: boolean; - global_abstain?: boolean; - content_object?: PollContentObject; - getContentObjectTitle: () => string | null; -} - -export type PollDataKey = keyof PollData; export interface OptionTitle { title: string; @@ -53,7 +34,8 @@ export interface OptionData { amount_global_yes?: number; amount_global_no?: number; amount_global_abstain?: number; - content_object?: ViewUser | ViewMotion | ViewPollCandidateList; + meeting_user?: ViewMeetingUser; + text?: string; entries_amount?: number; } diff --git a/client/src/app/domain/models/poll/index.ts b/client/src/app/domain/models/poll/index.ts index 316a36a5fe..0ce0695181 100644 --- a/client/src/app/domain/models/poll/index.ts +++ b/client/src/app/domain/models/poll/index.ts @@ -1,6 +1,5 @@ export * from './generic-poll'; -export * from './option'; export * from './poll'; +export * from './poll-ballot'; export * from './poll-constants'; -export * from './vote'; export * from './vote-constants'; diff --git a/client/src/app/domain/models/poll/option.ts b/client/src/app/domain/models/poll/option.ts deleted file mode 100644 index afd8cd32dc..0000000000 --- a/client/src/app/domain/models/poll/option.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Fqid, Id, Ids } from '../../definitions/key-types'; -import { BaseDecimalModel } from '../base/base-decimal-model'; - -export class Option extends BaseDecimalModel