From 2df87ca9e3f794bd1989ae17a927c4d2b2aa2d8b Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Thu, 1 Aug 2024 15:29:36 +0200 Subject: [PATCH 01/18] Fix motions --- .../motion-permission.service/motion-permission.service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/app/site/pages/meetings/pages/motions/services/common/motion-permission.service/motion-permission.service.ts b/client/src/app/site/pages/meetings/pages/motions/services/common/motion-permission.service/motion-permission.service.ts index 32d0bf57fc..0e876d5917 100644 --- a/client/src/app/site/pages/meetings/pages/motions/services/common/motion-permission.service/motion-permission.service.ts +++ b/client/src/app/site/pages/meetings/pages/motions/services/common/motion-permission.service/motion-permission.service.ts @@ -57,6 +57,7 @@ export class MotionPermissionService { public canDoActionWhileDelegationEnabled(isAdditionalDelegationSettingEnabled: boolean): boolean { return !( + !this.operator.isAnonymous && this.operator.user.isVoteRightDelegated && this._delegationEnabled && isAdditionalDelegationSettingEnabled From 306cf7ebd36c24915e7f16e6ddf3976cc61d938e Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Fri, 2 Aug 2024 09:09:48 +0200 Subject: [PATCH 02/18] Fix account button on orga level --- client/src/app/site/services/operator.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/app/site/services/operator.service.ts b/client/src/app/site/services/operator.service.ts index 2a488cb306..9702c8cef2 100644 --- a/client/src/app/site/services/operator.service.ts +++ b/client/src/app/site/services/operator.service.ts @@ -379,7 +379,7 @@ export class OperatorService { public isInMeeting(meetingId: Id): boolean { const meeting = this.meetingRepo.getViewModel(meetingId); - return (meeting.enable_anonymous && this.isAnonymous) || this.user.meeting_ids?.includes(meetingId) || false; + return (meeting?.enable_anonymous && this.isAnonymous) || this.user.meeting_ids?.includes(meetingId) || false; } private updateUser(user: ViewUser): void { From 80e100e588a88761024e7929a9a07e37167888fd Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Fri, 2 Aug 2024 11:02:43 +0200 Subject: [PATCH 03/18] Allow orga level guest login --- .../account-button.component.ts | 6 ++++- .../login-mask/login-mask.component.ts | 27 +++++++++++++++++-- .../pages/dashboard/dashboard.subscription.ts | 1 + .../dashboard/dashboard.component.ts | 5 +++- .../app/site/services/auth-check.service.ts | 8 +++++- 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.ts b/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.ts index 2054c2da0e..b929733715 100644 --- a/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.ts +++ b/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.ts @@ -135,7 +135,11 @@ export class AccountButtonComponent extends BaseUiComponent implements OnInit { public async login(): Promise { await this.authService.logoutAnonymous(); - this.router.navigate([`/`, this.activeMeetingId, `login`]); + if (this.activeMeetingId) { + this.router.navigate([`/`, this.activeMeetingId, `login`]); + } else { + this.router.navigate([`/`, `login`]); + } } public async logout(): Promise { diff --git a/client/src/app/site/pages/login/pages/login-mask/components/login-mask/login-mask.component.ts b/client/src/app/site/pages/login/pages/login-mask/components/login-mask/login-mask.component.ts index 3fbea6454d..50f5aac231 100644 --- a/client/src/app/site/pages/login/pages/login-mask/components/login-mask/login-mask.component.ts +++ b/client/src/app/site/pages/login/pages/login-mask/components/login-mask/login-mask.component.ts @@ -8,7 +8,7 @@ import { Meeting } from 'src/app/domain/models/meetings/meeting'; import { fadeInAnim } from 'src/app/infrastructure/animations'; import { BaseMeetingComponent } from 'src/app/site/pages/meetings/base/base-meeting.component'; import { ViewMeeting } from 'src/app/site/pages/meetings/view-models/view-meeting'; -import { OrganizationService } from 'src/app/site/pages/organization/services/organization.service'; +import { ORGANIZATION_ID, OrganizationService } from 'src/app/site/pages/organization/services/organization.service'; import { OrganizationSettingsService } from 'src/app/site/pages/organization/services/organization-settings.service'; import { ViewOrganization } from 'src/app/site/pages/organization/view-models/view-organization'; import { AuthService } from 'src/app/site/services/auth.service'; @@ -90,6 +90,7 @@ export class LoginMaskComponent extends BaseMeetingComponent implements OnInit, private loginMessage = `Loading data. Please wait ...`; private currentMeetingId: number | null = null; + private guestMeetingId: number | null = null; public constructor( protected override translate: TranslateService, @@ -134,6 +135,8 @@ export class LoginMaskComponent extends BaseMeetingComponent implements OnInit, this.route.params.subscribe(params => { if (params[`meetingId`]) { this.loadMeeting(params[`meetingId`]); + } else { + this.loadActiveMeetings(); } }); @@ -184,7 +187,7 @@ export class LoginMaskComponent extends BaseMeetingComponent implements OnInit, public async guestLogin(): Promise { await this.authService.anonLogin(); - this.osRouter.navigateAfterLogin(this.currentMeetingId); + this.osRouter.navigateAfterLogin(this.currentMeetingId || this.guestMeetingId); } public async samlLogin(): Promise { @@ -239,6 +242,26 @@ export class LoginMaskComponent extends BaseMeetingComponent implements OnInit, this.guestsEnabled = this.meeting.enable_anonymous; } + private async loadActiveMeetings(): Promise { + const resp = await this.autoupdate.single( + await this.modelRequestBuilder.build({ + ids: [ORGANIZATION_ID], + viewModelCtor: ViewOrganization, + follow: [{ idField: `active_meeting_ids`, fieldset: [`enable_anonymous`] }] + }), + `meeting_login` + ); + if (!resp || !resp[`meeting`]) { + return; + } + const publicMeetings = Object.values(resp[`meeting`]).filter(m => m[`enable_anonymous`]); + + this.guestsEnabled = !!publicMeetings.length; + if (publicMeetings.length === 1) { + this.guestMeetingId = publicMeetings[0][`id`]; + } + } + private checkDevice(): void { if (!this.browserSupport.isBrowserSupported()) { this.router.navigate([`./unsupported-browser`], { relativeTo: this.route }); diff --git a/client/src/app/site/pages/organization/pages/dashboard/dashboard.subscription.ts b/client/src/app/site/pages/organization/pages/dashboard/dashboard.subscription.ts index a038fc9c7b..87629411a5 100644 --- a/client/src/app/site/pages/organization/pages/dashboard/dashboard.subscription.ts +++ b/client/src/app/site/pages/organization/pages/dashboard/dashboard.subscription.ts @@ -13,6 +13,7 @@ export const meetingFields: (keyof Meeting)[] = [ `committee_id`, `is_active_in_organization_id`, `template_for_organization_id`, + `enable_anonymous`, `description`, `location`, `organization_tag_ids` diff --git a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.ts b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.ts index 3958a7b552..b89b2faa46 100644 --- a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.ts +++ b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.ts @@ -83,7 +83,10 @@ export class DashboardComponent extends BaseComponent { this.subscriptions.push( this.meetingRepo.getViewModelListObservable().subscribe(meetings => { const filteredMeetings = meetings.filter( - meeting => this.operator.isInMeeting(meeting.id) || this.operator.isSuperAdmin + meeting => + this.operator.isInMeeting(meeting.id) || + this.operator.isSuperAdmin || + (meeting.enable_anonymous && this.operator.isAnonymous) ); const currentDate = new Date(); currentDate.setHours(0, 0, 0, 0); diff --git a/client/src/app/site/services/auth-check.service.ts b/client/src/app/site/services/auth-check.service.ts index a91b85ecb1..36c42aab37 100644 --- a/client/src/app/site/services/auth-check.service.ts +++ b/client/src/app/site/services/auth-check.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@angular/core'; import { Data } from '@angular/router'; +import { CookieService } from 'ngx-cookie-service'; import { Id } from 'src/app/domain/definitions/key-types'; import { CML, OML } from 'src/app/domain/definitions/organization-permission'; import { Permission } from 'src/app/domain/definitions/permission'; @@ -39,6 +40,7 @@ export class AuthCheckService { private meetingRepo: MeetingRepositoryService, private meetingSettingsService: MeetingSettingsService, private autoupdate: AutoupdateService, + private cookie: CookieService, private modelRequestBuilder: ModelRequestBuilderService, private osRouter: OpenSlidesRouterService ) {} @@ -69,7 +71,11 @@ export class AuthCheckService { meeting = this.meetingRepo.getViewModel(+meetingIdString); } - return (this.operator.isAnonymous && meeting?.enable_anonymous) || this.operator.isAuthenticated; + return ( + (!meeting && this.cookie.check(`anonymous-auth`)) || + (this.operator.isAnonymous && meeting?.enable_anonymous) || + this.operator.isAuthenticated + ); } public async isAuthorizedToSeeOrganization(): Promise { From 6b7fb096ae6afcd95c1d2bfcd23cf90c3a1f0738 Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Fri, 2 Aug 2024 11:22:24 +0200 Subject: [PATCH 04/18] Update guest user orga nav --- .../organization-navigation.component.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/src/app/site/pages/organization/modules/navigation/organization-navigation/organization-navigation.component.ts b/client/src/app/site/pages/organization/modules/navigation/organization-navigation/organization-navigation.component.ts index 678e8c2fb4..0c9f7fa436 100644 --- a/client/src/app/site/pages/organization/modules/navigation/organization-navigation/organization-navigation.component.ts +++ b/client/src/app/site/pages/organization/modules/navigation/organization-navigation/organization-navigation.component.ts @@ -2,7 +2,9 @@ import { Component } from '@angular/core'; import { CML, OML } from 'src/app/domain/definitions/organization-permission'; import { BaseMenuEntry, getCustomStyleForEntry } from 'src/app/site/base/base-menu-entry'; import { MainMenuService } from 'src/app/site/pages/meetings/services/main-menu.service'; +import { AuthCheckService } from 'src/app/site/services/auth-check.service'; import { AuthService } from 'src/app/site/services/auth.service'; +import { OperatorService } from 'src/app/site/services/operator.service'; import { ViewPortService } from 'src/app/site/services/view-port.service'; interface OrgaMenuEntry extends BaseMenuEntry { @@ -78,9 +80,14 @@ export class OrganizationNavigationComponent { public constructor( private authService: AuthService, + private operator: OperatorService, private menuService: MainMenuService, private vp: ViewPortService - ) {} + ) { + if (this.operator.isAnonymous) { + this.menuEntries = [this.menuEntries[0]]; + } + } public getCustomStyleForEntry(entry: OrgaMenuEntry): { [key: string]: any } { return getCustomStyleForEntry(entry); From 8a1451bbfc21897e9042cce2ed8ea903bc34ea1b Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Fri, 2 Aug 2024 13:31:57 +0200 Subject: [PATCH 05/18] Orga level redirect --- .../meetings-navigation-wrapper.component.ts | 5 +---- client/src/app/site/services/auth.service.ts | 5 +++-- .../src/app/site/services/operator.service.ts | 22 +++++++++++++++++-- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/client/src/app/site/pages/meetings/modules/meetings-navigation/components/meetings-navigation-wrapper/meetings-navigation-wrapper.component.ts b/client/src/app/site/pages/meetings/modules/meetings-navigation/components/meetings-navigation-wrapper/meetings-navigation-wrapper.component.ts index 560198c0eb..c69376e0ac 100644 --- a/client/src/app/site/pages/meetings/modules/meetings-navigation/components/meetings-navigation-wrapper/meetings-navigation-wrapper.component.ts +++ b/client/src/app/site/pages/meetings/modules/meetings-navigation/components/meetings-navigation-wrapper/meetings-navigation-wrapper.component.ts @@ -38,10 +38,7 @@ export class MeetingsNavigationWrapperComponent extends BaseMeetingComponent imp } public get showMeetingNav(): boolean { - return ( - !this.operator.isAnonymous && - (this.operator.knowsMultipleMeetings || this.operator.hasOrganizationPermissions()) - ); + return this.operator.knowsMultipleMeetings || this.operator.hasOrganizationPermissions(); } public get meeting(): ViewMeeting | null { diff --git a/client/src/app/site/services/auth.service.ts b/client/src/app/site/services/auth.service.ts index 5ec4cca6ba..3ab464dc58 100644 --- a/client/src/app/site/services/auth.service.ts +++ b/client/src/app/site/services/auth.service.ts @@ -96,7 +96,8 @@ export class AuthService { public async anonLogin(): Promise { this.cookie.set(`anonymous-auth`, ``, { - sameSite: `Strict` + sameSite: `Strict`, + path: `/` }); return; } @@ -150,7 +151,7 @@ export class AuthService { } public async logoutAnonymous(): Promise { - this.cookie.delete(`anonymous-auth`); + this.cookie.delete(`anonymous-auth`, `/`); } public isAuthenticated(): boolean { diff --git a/client/src/app/site/services/operator.service.ts b/client/src/app/site/services/operator.service.ts index 9702c8cef2..6e9b2ec624 100644 --- a/client/src/app/site/services/operator.service.ts +++ b/client/src/app/site/services/operator.service.ts @@ -30,6 +30,7 @@ import { NoActiveMeetingError } from '../pages/meetings/services/active-meeting- import { MeetingControllerService } from '../pages/meetings/services/meeting-controller.service'; import { MeetingSettingsService } from '../pages/meetings/services/meeting-settings.service'; import { ViewMeeting } from '../pages/meetings/view-models/view-meeting'; +import { OrganizationService } from '../pages/organization/services/organization.service'; import { AuthService } from './auth.service'; import { AutoupdateService, ModelSubscription } from './autoupdate'; import { DataStoreService } from './data-store.service'; @@ -103,7 +104,10 @@ export class OperatorService { } public get knowsMultipleMeetings(): boolean { - return this.isAnyManager || this.user.hasMultipleMeetings; + return ( + this.isAnyManager || + (this.isAnonymous ? this.defaultAnonUser.hasMultipleMeetings : this.user.hasMultipleMeetings) + ); } public get onlyMeeting(): Id { @@ -259,7 +263,8 @@ export class OperatorService { private autoupdateService: AutoupdateService, private modelRequestBuilder: ModelRequestBuilderService, private meetingRepo: MeetingControllerService, - private meetingSettings: MeetingSettingsService + private meetingSettings: MeetingSettingsService, + private organizationService: OrganizationService ) { this.setNotReady(); // General environment in which the operator moves @@ -347,6 +352,19 @@ export class OperatorService { } } }); + this.organizationService.organizationObservable.pipe().subscribe(organization => { + if (this.isAnonymous) { + this.defaultAnonUser = new ViewUser( + new User({ + id: 0, + first_name: `Guest`, + meeting_ids: + organization?.active_meetings.filter(m => m.enable_anonymous).map(m => m.id) || null + }) + ); + this._operatorUpdatedSubject.next(); + } + }); this.operatorUpdated.subscribe(() => { this.checkReadyState(); }); From bf9b7a993095d564a2cc26382a4b533b04fe1792 Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Fri, 2 Aug 2024 13:41:14 +0200 Subject: [PATCH 06/18] Fix linter errors --- .../organization-navigation/organization-navigation.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/app/site/pages/organization/modules/navigation/organization-navigation/organization-navigation.component.ts b/client/src/app/site/pages/organization/modules/navigation/organization-navigation/organization-navigation.component.ts index 0c9f7fa436..230d352d0c 100644 --- a/client/src/app/site/pages/organization/modules/navigation/organization-navigation/organization-navigation.component.ts +++ b/client/src/app/site/pages/organization/modules/navigation/organization-navigation/organization-navigation.component.ts @@ -2,7 +2,6 @@ import { Component } from '@angular/core'; import { CML, OML } from 'src/app/domain/definitions/organization-permission'; import { BaseMenuEntry, getCustomStyleForEntry } from 'src/app/site/base/base-menu-entry'; import { MainMenuService } from 'src/app/site/pages/meetings/services/main-menu.service'; -import { AuthCheckService } from 'src/app/site/services/auth-check.service'; import { AuthService } from 'src/app/site/services/auth.service'; import { OperatorService } from 'src/app/site/services/operator.service'; import { ViewPortService } from 'src/app/site/services/view-port.service'; From 4b8aff52173cbf0cea58bd491fbedf3bba8967ad Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Fri, 2 Aug 2024 13:42:58 +0200 Subject: [PATCH 07/18] Cleanup dashboard --- .../dashboard/dashboard.component.html | 186 +++++++++--------- 1 file changed, 94 insertions(+), 92 deletions(-) diff --git a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html index 1fb53932a3..1eb783eb49 100644 --- a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html +++ b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html @@ -10,109 +10,111 @@

{{ 'Calendar' | translate }}

} -@if (noMeetingsToShow && ready) { - - - {{ 'No meetings available' | translate }} - - -} -@if (noMeetingsToShow && !ready) { -
- -
-} -@if (!noMeetingsToShow) { -
- - @if (organizationDescription) { -
-
-
- } -
-
- access_alarm - {{ 'today' | translate }} -
-
- @if (!currentMeetings.length) { - - - {{ 'No meetings available' | translate }} - - - } - @for (meeting of currentMeetings; track meeting; let last = $last) { - - @if (!last) { - - } - } -
+@if (noMeetingsToShow) { + @if (ready) { + + + {{ 'No meetings available' | translate }} + + + } @else { +
+
- -
-
- update - {{ 'future' | translate }} -
- + + @if (organizationDescription) { +
+
+
+ } +
+
+ access_alarm + {{ 'today' | translate }} +
+
+ @if (!currentMeetings.length) { + + + {{ 'No meetings available' | translate }} + + } - }" - > -
- -
-
- - {{ 'ended' | translate }} -
- + @if (!last) { + + } } - }" - > -
- - @if (!noNoDateMeetingsToShow) { -
+
+
+ +
- - {{ 'dateless' | translate }} + update + {{ 'future' | translate }}
- } -
+ +
+
+ + {{ 'ended' | translate }} +
+ +
+ + @if (!noNoDateMeetingsToShow) { +
+
+ + {{ 'dateless' | translate }} +
+ +
+ } +
+ } } From 45c0eb992b0c2ebd8048448ede1f7a9bc8e46657 Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Tue, 13 Aug 2024 11:24:33 +0200 Subject: [PATCH 08/18] Use anonymous group --- .../domain/definitions/permission.config.ts | 32 ++++++++++++++----- .../src/app/domain/models/meetings/meeting.ts | 4 ++- client/src/app/domain/models/users/group.ts | 6 ++++ .../definitions/relations/relations.ts | 6 ++++ .../base-poll-form.component.html | 2 +- .../chat-group-dialog.component.ts | 2 +- ...g-settings-group-detail-field.component.ts | 2 +- .../comment-section-list.component.ts | 2 +- .../group-list/group-list.component.html | 12 ++++--- .../group-list/group-list.component.ts | 2 +- .../services/group-controller.service.ts | 21 ++++++++++-- .../modules/groups/view-models/view-group.ts | 1 + .../participant-detail-view.component.ts | 2 +- .../participant-create-wizard.component.ts | 2 +- .../participant-list.component.ts | 2 +- .../participant-list-info-dialog.component.ts | 2 +- .../services/active-meeting.subscription.ts | 2 ++ .../meetings/view-models/view-meeting.ts | 1 + .../src/app/site/services/operator.service.ts | 12 ++++--- 19 files changed, 86 insertions(+), 29 deletions(-) diff --git a/client/src/app/domain/definitions/permission.config.ts b/client/src/app/domain/definitions/permission.config.ts index d4e77a95b0..d8a46f3499 100644 --- a/client/src/app/domain/definitions/permission.config.ts +++ b/client/src/app/domain/definitions/permission.config.ts @@ -7,6 +7,7 @@ export type PermissionsMap = { [key in Permission]?: Permission[] }; export interface DisplayPermission { display_name: string; help_text?: string; + anon_allowed?: boolean; value: Permission; } @@ -24,6 +25,7 @@ export const PERMISSIONS: AppPermission[] = [ help_text: _( `Can see the Autopilot menu item with all content for which appropriate permissions are set.` ), + anon_allowed: true, value: Permission.meetingCanSeeAutopilot }, { @@ -31,6 +33,7 @@ export const PERMISSIONS: AppPermission[] = [ help_text: _( `Can see the Projector menu item and all projectors (in the Autopilot as well as in the Projector menu item)` ), + anon_allowed: true, value: Permission.projectorCanSee }, { @@ -46,11 +49,13 @@ export const PERMISSIONS: AppPermission[] = [ { display_name: _(`Can see agenda`), help_text: _(`Can see the Agenda menu item and all public topics in the agenda.`), + anon_allowed: true, value: Permission.agendaItemCanSee }, { display_name: _(`Can see internal items and time scheduling of agenda`), help_text: _(`Can see all internal topics, schedules and comments.`), + anon_allowed: true, value: Permission.agendaItemCanSeeInternal }, { @@ -63,6 +68,7 @@ export const PERMISSIONS: AppPermission[] = [ { display_name: _(`Can see list of speakers`), help_text: _(`Can see all lists of speakers`), + anon_allowed: true, value: Permission.listOfSpeakersCanSee }, { @@ -74,7 +80,7 @@ export const PERMISSIONS: AppPermission[] = [ }, { display_name: _(`Can put oneself on the list of speakers`), - help_text: _(`Is allowed to add himself/herself to the list of speakers. + help_text: _(`Is allowed to add himself/herself to the list of speakers. Note: Optional combination of requests to speak with presence status is possible. ( > [Settings] > [List of speakers] > [General] )`), @@ -88,6 +94,7 @@ Optional combination of requests to speak with presence status is possible. ( > { display_name: _(`Can see moderation notes`), help_text: _(`Can see all moderation notes in each list of speakers.`), + anon_allowed: true, value: Permission.agendaItemCanSeeModeratorNotes }, { @@ -105,6 +112,7 @@ Optional combination of requests to speak with presence status is possible. ( > help_text: _( `Can see the Motions menu item and all motions unless they are limited by access restrictions in the workflow.` ), + anon_allowed: true, value: Permission.motionCanSee }, { @@ -114,6 +122,7 @@ Optional combination of requests to speak with presence status is possible. ( > Tip: Cross-check desired visibility of motions with test delegate account. ` ), + anon_allowed: true, value: Permission.motionCanSeeInternal }, { @@ -133,10 +142,10 @@ Tip: Cross-check desired visibility of motions with test delegate account. ` { display_name: _(`Can forward motions`), help_text: _( - `Can forward motions to other meetings within the OpenSlides instance. + `Can forward motions to other meetings within the OpenSlides instance. Further requirements: -1. forwarding hierarchy must be set at the organizational level in the committee. +1. forwarding hierarchy must be set at the organizational level in the committee. 2. target meeting must be created. 3. forwarding must be activated in the workflow in the state.` ), @@ -176,10 +185,11 @@ Further requirements: { display_name: _(`Can see elections`), help_text: _( - `Can see the menu item Elections, including the list of candidates and results. + `Can see the menu item Elections, including the list of candidates and results. Note: The right to vote is defined directly in the ballot.` ), + anon_allowed: true, value: Permission.assignmentCanSee }, { @@ -191,7 +201,7 @@ Note: The right to vote is defined directly in the ballot.` }, { display_name: _(`Can nominate another participant`), - help_text: _(`Can nominate other participants as candidates. + help_text: _(`Can nominate other participants as candidates. Requires group permission: [Can see participants]`), value: Permission.assignmentCanNominateOther @@ -209,15 +219,17 @@ Requires group permission: [Can see participants]`), { display_name: _(`Can see participants`), help_text: _( - `Can see the menu item Participants and therefore the following data from all participants: -Personal data: Name, pronoun, gender. + `Can see the menu item Participants and therefore the following data from all participants: +Personal data: Name, pronoun, gender. Meeting specific information: Structure level, Group, Participant number, About me, Presence status.` ), + anon_allowed: true, value: Permission.userCanSee }, { display_name: _(`Can see sensitive data`), help_text: _(`Can see email, username and SSO identification of all participants.`), + anon_allowed: true, value: Permission.userCanSeeSensitiveData }, { @@ -245,6 +257,7 @@ Meeting specific information: Structure level, Group, Participant number, About help_text: _(`Can see the Files menu item and all shared folders and files. Note: Sharing of folders and files may be restricted by group assignment.`), + anon_allowed: true, value: Permission.mediafileCanSee }, { @@ -267,6 +280,7 @@ Note: Sharing of folders and files may be restricted by group assignment.`), { display_name: _(`Can see the front page`), help_text: _(`Can see the Home menu item.`), + anon_allowed: true, value: Permission.meetingCanSeeFrontpage }, { @@ -274,15 +288,17 @@ Note: Sharing of folders and files may be restricted by group assignment.`), help_text: _( `Can see the livestream if there is a livestream URL entered in > [Settings] > [Livestream].` ), + anon_allowed: true, value: Permission.meetingCanSeeLivestream }, { display_name: _(`Can see history`), help_text: _( - `Can see the History menu item with the history of processing timestamps for motions, elections and participants. + `Can see the History menu item with the history of processing timestamps for motions, elections and participants. Note: For privacy reasons, it is recommended to limit the rights to view the History significantly.` ), + anon_allowed: true, value: Permission.meetingCanSeeHistory }, { diff --git a/client/src/app/domain/models/meetings/meeting.ts b/client/src/app/domain/models/meetings/meeting.ts index 76fbd3aab0..98916be690 100644 --- a/client/src/app/domain/models/meetings/meeting.ts +++ b/client/src/app/domain/models/meetings/meeting.ts @@ -252,6 +252,7 @@ export class Meeting extends BaseModel { public default_group_id!: Id; // group/default_group_for_meeting_id; public admin_group_id!: Id; // group/admin_group_for_meeting_id; + public anonymous_group_id!: Id; // group/anonymous_group_for_meeting_id; public list_of_speakers_countdown_id: Id; // projector_countdown/used_as_list_of_speakers_meeting_id; public poll_countdown_id: Id; // projector_countdown/used_as_poll_countdown_meeting_id; @@ -511,7 +512,8 @@ export class Meeting extends BaseModel { `default_projector_motion_poll_ids`, `default_projector_poll_ids`, `default_group_id`, - `admin_group_id` + `admin_group_id`, + `anonymous_group_id` ]; } export interface Meeting diff --git a/client/src/app/domain/models/users/group.ts b/client/src/app/domain/models/users/group.ts index fd4f4bc153..3de6bffd5b 100644 --- a/client/src/app/domain/models/users/group.ts +++ b/client/src/app/domain/models/users/group.ts @@ -17,6 +17,7 @@ export class Group extends BaseModel { public meeting_user_ids!: Id[]; // (meeting_user/group_ids)[]; public default_group_for_meeting_id!: Id; // meeting/default_group_id; + public anonymous_group_for_meeting_id!: Id; // meeting/admin_group_id; public admin_group_for_meeting_id!: Id; // meeting/admin_group_id; public mediafile_access_group_ids!: Id[]; // (mediafile/access_group_ids)[]; public mediafile_inherited_access_group_ids!: Id[]; // (mediafile/inherited_access_group_ids)[]; @@ -34,6 +35,10 @@ export class Group extends BaseModel { return !!this.admin_group_for_meeting_id; } + public get isAnonymousGroup(): boolean { + return !!this.anonymous_group_for_meeting_id; + } + public get isDefaultGroup(): boolean { return !!this.default_group_for_meeting_id; } @@ -50,6 +55,7 @@ export class Group extends BaseModel { `weight`, `meeting_user_ids`, `default_group_for_meeting_id`, + `anonymous_group_for_meeting_id`, `admin_group_for_meeting_id`, `mediafile_access_group_ids`, `mediafile_inherited_access_group_ids`, diff --git a/client/src/app/infrastructure/definitions/relations/relations.ts b/client/src/app/infrastructure/definitions/relations/relations.ts index ed1e487918..a2eb1f0976 100644 --- a/client/src/app/infrastructure/definitions/relations/relations.ts +++ b/client/src/app/infrastructure/definitions/relations/relations.ts @@ -633,6 +633,12 @@ export const RELATIONS: Relation[] = [ AField: `default_group`, BField: `default_group_for_meeting` }), + ...makeO2O({ + AViewModel: ViewMeeting, + BViewModel: ViewGroup, + AField: `anonymous_group`, + BField: `anonymous_group_for_meeting` + }), ...makeO2O({ AViewModel: ViewMeeting, BViewModel: ViewGroup, diff --git a/client/src/app/site/pages/meetings/modules/poll/components/base-poll-form/base-poll-form.component.html b/client/src/app/site/pages/meetings/modules/poll/components/base-poll-form/base-poll-form.component.html index 3e59be74cc..aba0ec4fbd 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/base-poll-form/base-poll-form.component.html +++ b/client/src/app/site/pages/meetings/modules/poll/components/base-poll-form/base-poll-form.component.html @@ -36,7 +36,7 @@

groupA.weight - groupB.weight; diff --git a/client/src/app/site/pages/meetings/pages/meeting-settings/pages/meeting-settings-group-detail/components/meeting-settings-group-detail-field/meeting-settings-group-detail-field.component.ts b/client/src/app/site/pages/meetings/pages/meeting-settings/pages/meeting-settings-group-detail/components/meeting-settings-group-detail-field/meeting-settings-group-detail-field.component.ts index 480b7a216e..79b76f94be 100644 --- a/client/src/app/site/pages/meetings/pages/meeting-settings/pages/meeting-settings-group-detail/components/meeting-settings-group-detail-field/meeting-settings-group-detail-field.component.ts +++ b/client/src/app/site/pages/meetings/pages/meeting-settings/pages/meeting-settings-group-detail/components/meeting-settings-group-detail-field/meeting-settings-group-detail-field.component.ts @@ -194,7 +194,7 @@ export class MeetingSettingsGroupDetailFieldComponent extends BaseComponent impl public ngOnInit(): void { // filter out empty results in group observable. We never have no groups and it messes up // the settings change detection - this.groupObservable = this.groupRepo.getViewModelListWithoutDefaultGroupObservable().pipe( + this.groupObservable = this.groupRepo.getViewModelListWithoutSystemGroupsObservable().pipe( filter(groups => !!groups.length), map(groups => this.getRestrictedValue(groups)) ); diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/comments/components/comment-section-list/comment-section-list.component.ts b/client/src/app/site/pages/meetings/pages/motions/pages/comments/components/comment-section-list/comment-section-list.component.ts index bb052770bd..8b796fe787 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/comments/components/comment-section-list/comment-section-list.component.ts +++ b/client/src/app/site/pages/meetings/pages/motions/pages/comments/components/comment-section-list/comment-section-list.component.ts @@ -67,7 +67,7 @@ export class CommentSectionListComponent extends BaseComponent implements OnInit public ngOnInit(): void { super.setTitle(`Comment fields`); - this.groups = this.groupRepo.getViewModelListObservable(); + this.groups = this.groupRepo.getViewModelListWithoutAnonymousGroupObservable(); this.subscriptions.push( this.repo .getViewModelListObservable() diff --git a/client/src/app/site/pages/meetings/pages/participants/modules/groups/components/group-list/group-list.component.html b/client/src/app/site/pages/meetings/pages/participants/modules/groups/components/group-list/group-list.component.html index 7320cefadb..879f1c5add 100644 --- a/client/src/app/site/pages/meetings/pages/participants/modules/groups/components/group-list/group-list.component.html +++ b/client/src/app/site/pages/meetings/pages/participants/modules/groups/components/group-list/group-list.component.html @@ -57,16 +57,20 @@

{{ 'Groups' | translate }}

- @if (!group.isAdminGroup) { + @if ( + group.isAdminGroup || (group.isAnonymousGroup && !perm.anon_allowed) + ) { + + } @else { } - @if (group.isAdminGroup) { - - }
diff --git a/client/src/app/site/pages/meetings/pages/participants/modules/groups/components/group-list/group-list.component.ts b/client/src/app/site/pages/meetings/pages/participants/modules/groups/components/group-list/group-list.component.ts index a624408094..e86e55572e 100644 --- a/client/src/app/site/pages/meetings/pages/participants/modules/groups/components/group-list/group-list.component.ts +++ b/client/src/app/site/pages/meetings/pages/participants/modules/groups/components/group-list/group-list.component.ts @@ -239,7 +239,7 @@ export class GroupListComponent extends BaseMeetingComponent implements OnInit, * @param group ViewGroup */ public isProtected(group: ViewGroup): boolean { - return group.isAdminGroup || group.isDefaultGroup; + return group.isAdminGroup || group.isDefaultGroup || group.isAnonymousGroup; } /** diff --git a/client/src/app/site/pages/meetings/pages/participants/modules/groups/services/group-controller.service.ts b/client/src/app/site/pages/meetings/pages/participants/modules/groups/services/group-controller.service.ts index fcffcccbc0..6351f7e50f 100644 --- a/client/src/app/site/pages/meetings/pages/participants/modules/groups/services/group-controller.service.ts +++ b/client/src/app/site/pages/meetings/pages/participants/modules/groups/services/group-controller.service.ts @@ -62,11 +62,26 @@ export class GroupControllerService extends BaseMeetingControllerService groups.filter(group => !group.isDefaultGroup)); } + public getFilterSystemGroupFn(): OperatorFunction { + return map(groups => groups.filter(group => !group.isDefaultGroup && !group.isAnonymousGroup)); + } + + public getFilterAnonymousGroupFn(): OperatorFunction { + return map(groups => groups.filter(group => !group.isAnonymousGroup)); + } + + /** + * Returns an Observable for all groups except the default and anonymous group. + */ + public getViewModelListWithoutSystemGroupsObservable(): Observable { + return this.getViewModelListObservable().pipe(this.getFilterSystemGroupFn()); + } + /** - * Returns an Observable for all groups except the default group. + * Returns an Observable for all groups except the anonymous group. */ - public getViewModelListWithoutDefaultGroupObservable(): Observable { - return this.getViewModelListObservable().pipe(this.getFilterDefaultGroupFn()); + public getViewModelListWithoutAnonymousGroupObservable(): Observable { + return this.getViewModelListObservable().pipe(this.getFilterAnonymousGroupFn()); } public getNameForIds(...ids: number[]): string { diff --git a/client/src/app/site/pages/meetings/pages/participants/modules/groups/view-models/view-group.ts b/client/src/app/site/pages/meetings/pages/participants/modules/groups/view-models/view-group.ts index 8842018ca1..81e2bd1905 100644 --- a/client/src/app/site/pages/meetings/pages/participants/modules/groups/view-models/view-group.ts +++ b/client/src/app/site/pages/meetings/pages/participants/modules/groups/view-models/view-group.ts @@ -27,6 +27,7 @@ export class ViewGroup extends BaseHasMeetingUsersViewModel { interface IGroupRelations { default_group_for_meeting: ViewMeeting; admin_group_for_meeting: ViewMeeting; + anonymous_group_for_meeting: ViewMeeting; mediafile_access_groups: ViewMediafile[]; mediafile_inherited_access_groups: ViewMediafile[]; read_comment_sections: ViewMotionCommentSection[]; diff --git a/client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/components/participant-detail-view/participant-detail-view.component.ts b/client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/components/participant-detail-view/participant-detail-view.component.ts index be13c4051d..0829bbea2f 100644 --- a/client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/components/participant-detail-view/participant-detail-view.component.ts +++ b/client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/components/participant-detail-view/participant-detail-view.component.ts @@ -198,7 +198,7 @@ export class ParticipantDetailViewComponent extends BaseMeetingComponent { this.structureLevelObservable = this.structureLevelRepo.getViewModelListObservable(); // TODO: Open groups subscription - this.groups = this.groupRepo.getViewModelListWithoutDefaultGroupObservable(); + this.groups = this.groupRepo.getViewModelListWithoutSystemGroupsObservable(); } public isAllowed(action: string): boolean { diff --git a/client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/pages/participant-detail-manage/components/participant-create-wizard/participant-create-wizard.component.ts b/client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/pages/participant-detail-manage/components/participant-create-wizard/participant-create-wizard.component.ts index c96f25cb1a..5418f99fdb 100644 --- a/client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/pages/participant-detail-manage/components/participant-create-wizard/participant-create-wizard.component.ts +++ b/client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/pages/participant-detail-manage/components/participant-create-wizard/participant-create-wizard.component.ts @@ -191,7 +191,7 @@ export class ParticipantCreateWizardComponent extends BaseMeetingComponent imple public ngOnInit(): void { // TODO: Fetch groups for repo search selection - this.groupsObservable = this.groupRepo.getViewModelListWithoutDefaultGroupObservable(); + this.groupsObservable = this.groupRepo.getViewModelListWithoutSystemGroupsObservable(); this.structureLevelObservable = this.structureLevelRepo.getViewModelListObservable(); diff --git a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.ts b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.ts index 2c21579e4b..33ade3fc55 100644 --- a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.ts +++ b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.ts @@ -53,7 +53,7 @@ export class ParticipantListComponent extends BaseMeetingListViewComponent = this.groupRepo.getViewModelListWithoutDefaultGroupObservable(); + public groupsObservable: Observable = this.groupRepo.getViewModelListWithoutSystemGroupsObservable(); /** * All available structure level, where the user can be in. diff --git a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/modules/participant-list-info-dialog/components/participant-list-info-dialog/participant-list-info-dialog.component.ts b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/modules/participant-list-info-dialog/components/participant-list-info-dialog/participant-list-info-dialog.component.ts index 098e5022a9..69583e3a02 100644 --- a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/modules/participant-list-info-dialog/components/participant-list-info-dialog/participant-list-info-dialog.component.ts +++ b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/modules/participant-list-info-dialog/components/participant-list-info-dialog/participant-list-info-dialog.component.ts @@ -24,7 +24,7 @@ export class ParticipantListInfoDialogComponent extends BaseUiComponent implemen public readonly genders = GENDERS; public get groupsObservable(): Observable { - return this.groupRepo.getViewModelListWithoutDefaultGroupObservable(); + return this.groupRepo.getViewModelListWithoutSystemGroupsObservable(); } public get otherParticipantsObservable(): Observable { diff --git a/client/src/app/site/pages/meetings/services/active-meeting.subscription.ts b/client/src/app/site/pages/meetings/services/active-meeting.subscription.ts index cb4e60f6b1..5eb77117b7 100644 --- a/client/src/app/site/pages/meetings/services/active-meeting.subscription.ts +++ b/client/src/app/site/pages/meetings/services/active-meeting.subscription.ts @@ -67,6 +67,7 @@ export function getActiveMeetingSubscriptionConfig(id: Id, settingsKeys: string[ idField: `group_ids`, fieldset: [ `admin_group_for_meeting_id`, + `anonymous_group_for_meeting_id`, `default_group_for_meeting_id`, `name`, `permissions`, @@ -119,6 +120,7 @@ export function getActiveMeetingSubscriptionConfig(id: Id, settingsKeys: string[ `jitsi_room_name`, `jitsi_room_password`, `admin_group_id`, + `anonymous_group_id`, `default_group_id` ] }, diff --git a/client/src/app/site/pages/meetings/view-models/view-meeting.ts b/client/src/app/site/pages/meetings/view-models/view-meeting.ts index 546e079f6e..249926f704 100644 --- a/client/src/app/site/pages/meetings/view-models/view-meeting.ts +++ b/client/src/app/site/pages/meetings/view-models/view-meeting.ts @@ -185,6 +185,7 @@ interface IMeetingRelations { reference_projector: ViewProjector; projections: ViewProjection[]; default_group: ViewGroup; + anonymous_group: ViewGroup; admin_group: ViewGroup; is_active_in_organization: ViewOrganization; is_archived_in_organization: ViewOrganization; diff --git a/client/src/app/site/services/operator.service.ts b/client/src/app/site/services/operator.service.ts index 8a789745b7..54621b0f9f 100644 --- a/client/src/app/site/services/operator.service.ts +++ b/client/src/app/site/services/operator.service.ts @@ -200,6 +200,11 @@ export class OperatorService { return activeMeeting ? activeMeeting.default_group_id : null; } + private get anonymousGroupId(): number | null { + const activeMeeting = this.activeMeetingService.meeting; + return activeMeeting ? activeMeeting.anonymous_group_id : null; + } + private get adminGroupId(): number | null { const activeMeeting = this.activeMeetingService.meeting; return activeMeeting ? activeMeeting.admin_group_id : null; @@ -338,7 +343,7 @@ export class OperatorService { if (!this.activeMeetingId || !group) { return; } - if (this.isAnonymous && group.id === this.defaultGroupId) { + if (this.isAnonymous && group.id === this.anonymousGroupId) { this._groupIds = this._groupIds || []; this._permissions = this.calcPermissions(); this._operatorUpdatedSubject.next(); @@ -539,8 +544,7 @@ export class OperatorService { private calcPermissions(): Permission[] { const permissionSet = new Set(); if (this.isAnonymous) { - // Anonymous is always in the default group. - this.activeMeeting?.default_group?.permissions.forEach(perm => permissionSet.add(perm)); + this.activeMeeting?.anonymous_group?.permissions.forEach(perm => permissionSet.add(perm)); } else { if (this._groupIds?.length) { this.DS.getMany(Group, this._groupIds).forEach(group => { @@ -760,7 +764,7 @@ export class OperatorService { return false; } if (this.isAnonymous) { - return !!groupIds.find(id => id === this.defaultGroupId); // any anonymous is in the default group. + return !!groupIds.find(id => id === this.anonymousGroupId); } return groupIds.some(id => this._groupIds?.includes(id)); } From da31002a987dd7adf07dd2b0c755f4bc94ae15cc Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Tue, 13 Aug 2024 11:52:33 +0200 Subject: [PATCH 09/18] Fix meetings without permissions set --- client/src/app/site/services/operator.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/app/site/services/operator.service.ts b/client/src/app/site/services/operator.service.ts index 54621b0f9f..29c59d6702 100644 --- a/client/src/app/site/services/operator.service.ts +++ b/client/src/app/site/services/operator.service.ts @@ -544,7 +544,7 @@ export class OperatorService { private calcPermissions(): Permission[] { const permissionSet = new Set(); if (this.isAnonymous) { - this.activeMeeting?.anonymous_group?.permissions.forEach(perm => permissionSet.add(perm)); + this.activeMeeting?.anonymous_group?.permissions?.forEach(perm => permissionSet.add(perm)); } else { if (this._groupIds?.length) { this.DS.getMany(Group, this._groupIds).forEach(group => { From 5907a054d4e39dd3ad57ed0f43953739dfa17d0d Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Tue, 27 Aug 2024 15:57:41 +0200 Subject: [PATCH 10/18] CRs --- .../login-mask/login-mask.component.html | 5 ++--- .../meeting-settings-definitions.ts | 22 +++++++++---------- .../dashboard/dashboard.component.html | 18 ++++++++------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/client/src/app/site/pages/login/pages/login-mask/components/login-mask/login-mask.component.html b/client/src/app/site/pages/login/pages/login-mask/components/login-mask/login-mask.component.html index dfac839708..2be7757bda 100644 --- a/client/src/app/site/pages/login/pages/login-mask/components/login-mask/login-mask.component.html +++ b/client/src/app/site/pages/login/pages/login-mask/components/login-mask/login-mask.component.html @@ -43,7 +43,7 @@


@if (guestsEnabled) { }
@@ -93,7 +93,6 @@


- @if (guestsEnabled && showExtra) { } diff --git a/client/src/app/site/pages/meetings/services/meeting-settings-definition.service/meeting-settings-definitions.ts b/client/src/app/site/pages/meetings/services/meeting-settings-definition.service/meeting-settings-definitions.ts index a5d018d9bf..d9c9ec9ea3 100644 --- a/client/src/app/site/pages/meetings/services/meeting-settings-definition.service/meeting-settings-definitions.ts +++ b/client/src/app/site/pages/meetings/services/meeting-settings-definition.service/meeting-settings-definitions.ts @@ -152,16 +152,6 @@ export const meetingSettings: SettingsGroup[] = fillInSettingsDefaults([ label: _(`General`), icon: `home`, subgroups: [ - { - label: _(`System`), - settings: [ - { - key: `enable_anonymous`, - label: _(`Allow access for anonymous guest users`), - type: `boolean` - } - ] - }, { label: _(`Meeting information`), settings: [ @@ -195,12 +185,22 @@ export const meetingSettings: SettingsGroup[] = fillInSettingsDefaults([ { key: `external_id`, label: _(`External ID`) - }, + } + ] + }, + { + label: _(`System`), + settings: [ { key: `locked_from_inside`, label: _(`Close your meeting from the inside`), type: `boolean`, forbidden: meetingView => meetingView.isTemplate + }, + { + key: `enable_anonymous`, + label: _(`Allow access for anonymous guest users`), + type: `boolean` } ] }, diff --git a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html index 5dae719472..1e46a84d11 100644 --- a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html +++ b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html @@ -214,13 +214,15 @@

{{ 'Calendar' | translate }}

@if (meeting.isArchived) { archive } - - layers - + @if (meeting.committee_id) { + + layers + + }

From fb1713b210fb0dbfbc4eb13461c99874ac027163 Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Thu, 29 Aug 2024 17:43:50 +0200 Subject: [PATCH 11/18] Change username to public --- .../components/account-button/account-button.component.html | 6 +++++- .../components/account-button/account-button.component.ts | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.html b/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.html index 90bdca4abf..962c9db760 100644 --- a/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.html +++ b/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.html @@ -1,7 +1,11 @@
- {{ username }} + @if (isLoggedIn) { + {{ username }} + } @else { + {{ 'Public' | translate }} + }
diff --git a/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.ts b/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.ts index b929733715..ccf97598e7 100644 --- a/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.ts +++ b/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.ts @@ -185,7 +185,7 @@ export class AccountButtonComponent extends BaseUiComponent implements OnInit { private onOperatorUpdate(): void { this.isLoggedIn = !this.operator.isAnonymous; - this.username = this.isLoggedIn ? this.operator.shortName : this.translate.instant(`Guest`); + this.username = this.operator.shortName; const userId = this.operator.operatorId; if (this._userId !== userId) { this._userId = userId; From 007e21bb067bb5264427529875a15830f21bf614 Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Thu, 29 Aug 2024 17:50:08 +0200 Subject: [PATCH 12/18] Fix dashboard box not fully clickable --- .../components/dashboard/dashboard.component.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.scss b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.scss index 95313c9d24..1cf339d362 100644 --- a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.scss +++ b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.scss @@ -247,6 +247,7 @@ os-dashboard { .meeting-box-left { width: calc(95% - 50px); + flex-grow: 1; @media (max-width: 960px) { width: 90%; From 65759b394467e75c6b79996a65c4cce94a19da03 Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Tue, 24 Sep 2024 13:28:31 +0200 Subject: [PATCH 13/18] Hide anonymous group if option is disabled --- .../groups/components/group-list/group-list.component.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/src/app/site/pages/meetings/pages/participants/modules/groups/components/group-list/group-list.component.ts b/client/src/app/site/pages/meetings/pages/participants/modules/groups/components/group-list/group-list.component.ts index e86e55572e..21708f51f8 100644 --- a/client/src/app/site/pages/meetings/pages/participants/modules/groups/components/group-list/group-list.component.ts +++ b/client/src/app/site/pages/meetings/pages/participants/modules/groups/components/group-list/group-list.component.ts @@ -95,7 +95,12 @@ export class GroupListComponent extends BaseMeetingComponent implements OnInit, this.repo.getViewModelListObservable().subscribe(newViewGroups => { if (newViewGroups) { - this.groups = newViewGroups.slice().sort((groupA, groupB) => groupA.weight - groupB.weight); + if (!this.meetingSettingsService.instant(`enable_anonymous`)) { + newViewGroups = newViewGroups.filter(group => !group.anonymous_group_for_meeting_id); + } else { + newViewGroups = newViewGroups.slice(); + } + this.groups = newViewGroups.sort((groupA, groupB) => groupA.weight - groupB.weight); this.updateRowDef(); } }); From bd982e2285aa2f96aa709cf07a012740df698059 Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Tue, 24 Sep 2024 15:10:10 +0200 Subject: [PATCH 14/18] Add anonymous icons --- .../meeting-repository.service.ts | 3 +- .../committee-meeting-preview.component.html | 5 + .../dashboard/dashboard.component.html | 94 +++++++++---------- .../meeting-list/meeting-list.component.html | 9 +- .../meeting-list-filter.service.ts | 8 ++ 5 files changed, 65 insertions(+), 54 deletions(-) diff --git a/client/src/app/gateways/repositories/meeting-repository.service.ts b/client/src/app/gateways/repositories/meeting-repository.service.ts index 254df4d5bc..0b04cf6021 100644 --- a/client/src/app/gateways/repositories/meeting-repository.service.ts +++ b/client/src/app/gateways/repositories/meeting-repository.service.ts @@ -73,7 +73,8 @@ export class MeetingRepositoryService extends BaseRepository = [ `default_meeting_for_committee_id`, diff --git a/client/src/app/site/pages/organization/pages/committees/modules/committee-meeting-preview/committee-meeting-preview.component.html b/client/src/app/site/pages/organization/pages/committees/modules/committee-meeting-preview/committee-meeting-preview.component.html index 2cc1e68136..227326b7c8 100644 --- a/client/src/app/site/pages/organization/pages/committees/modules/committee-meeting-preview/committee-meeting-preview.component.html +++ b/client/src/app/site/pages/organization/pages/committees/modules/committee-meeting-preview/committee-meeting-preview.component.html @@ -4,6 +4,11 @@ [ngClass]="{ 'background-accent': meeting.isActive, 'background-dark-brighter': meeting.isArchived }" > + @if (meeting.enable_anonymous) { +
+ public +
+ } @if (meeting.locked_from_inside) {
lock diff --git a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html index bc0b93cae9..cbdafbd525 100644 --- a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html +++ b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html @@ -160,61 +160,17 @@

{{ 'Calendar' | translate }}

[ngClass]="context?.cssClass" [routerLink]="meeting.id" > -
-
- -
{{ meeting.name }}
-
-
-
- @if (meeting.location) { - {{ meeting.location }} - } - @if (meeting.location && (meeting.start_time || meeting.end_time)) { -  ·  - } - @if (meeting.start_time || meeting.end_time) { - - - - } -
-
+ } @else {
-
-
- -
{{ meeting.name }}
-
-
-
- @if (meeting.location) { - {{ meeting.location }} - } - @if (meeting.location && (meeting.start_time || meeting.end_time)) { -  ·  - } - @if (meeting.start_time || meeting.end_time) { - - - - } -
-
+
} @if (meeting.isArchived) { @@ -232,3 +188,37 @@

{{ 'Calendar' | translate }}

}
+ + +
+
+ @let meetingIcon = meeting.locked_from_inside ? 'lock' : 'public'; + +
{{ meeting.name }}
+
+
+
+ @if (meeting.location) { + {{ meeting.location }} + } + @if (meeting.location && (meeting.start_time || meeting.end_time)) { +  ·  + } + @if (meeting.start_time || meeting.end_time) { + + + + } +
+
+
diff --git a/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/components/meeting-list/meeting-list.component.html b/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/components/meeting-list/meeting-list.component.html index 36e2f5a324..8bb89ad4f5 100644 --- a/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/components/meeting-list/meeting-list.component.html +++ b/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/components/meeting-list/meeting-list.component.html @@ -54,7 +54,14 @@

{{ 'Meetings' | translate }}

} - + + @if (meeting.enable_anonymous) { + + public + + } + + @if (meeting.locked_from_inside) { lock diff --git a/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/services/meeting-list-filter/meeting-list-filter.service.ts b/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/services/meeting-list-filter/meeting-list-filter.service.ts index 332fa8ff9e..43b00fb404 100644 --- a/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/services/meeting-list-filter/meeting-list-filter.service.ts +++ b/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/services/meeting-list-filter/meeting-list-filter.service.ts @@ -45,6 +45,14 @@ export class MeetingListFilterService extends BaseFilterListService { label: _(`Is not archived`), condition: [false, null] } ] }, + { + property: `enable_anonymous`, + label: _(`Public`), + options: [ + { label: _(`Is public`), condition: true }, + { label: _(`Is closed`), condition: [false, null] } + ] + }, { property: `relatedTime`, label: _(`Time`), From 835fdc44d63fc870f11260f52511b2c53c737a4f Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Tue, 24 Sep 2024 15:33:58 +0200 Subject: [PATCH 15/18] Update account button --- .../account-button/account-button.component.html | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.html b/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.html index 962c9db760..b0cf5113a9 100644 --- a/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.html +++ b/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.html @@ -4,7 +4,7 @@ @if (isLoggedIn) { {{ username }} } @else { - {{ 'Public' | translate }} + {{ 'Public Access' | translate }} }
@@ -19,7 +19,13 @@
-
{{ username }}
+
+ @if (isLoggedIn) { + {{ username }} + } @else { + {{ 'Public Access' | translate }} + } +
@if (user) {
{{ getOmlVerboseName() | translate }}
} From 8e51c0a1c0a53bc308f3e28e3ade92e26950e186 Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Tue, 24 Sep 2024 15:48:54 +0200 Subject: [PATCH 16/18] Fix meeting info page not working --- .../src/app/site/pages/meetings/meetings-routing.module.ts | 4 +--- .../site/pages/meetings/pages/home/home-routing.module.ts | 6 +++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/client/src/app/site/pages/meetings/meetings-routing.module.ts b/client/src/app/site/pages/meetings/meetings-routing.module.ts index 69da5bf801..33e401572f 100644 --- a/client/src/app/site/pages/meetings/meetings-routing.module.ts +++ b/client/src/app/site/pages/meetings/meetings-routing.module.ts @@ -13,9 +13,7 @@ const routes: Routes = [ children: [ { path: ``, - loadChildren: () => import(`./pages/home/home.module`).then(m => m.HomeModule), - data: { meetingPermissions: [Permission.meetingCanSeeFrontpage] }, - canLoad: [PermissionGuard] + loadChildren: () => import(`./pages/home/home.module`).then(m => m.HomeModule) }, { path: `agenda`, diff --git a/client/src/app/site/pages/meetings/pages/home/home-routing.module.ts b/client/src/app/site/pages/meetings/pages/home/home-routing.module.ts index 7e7d5e7ecf..f8ba342025 100644 --- a/client/src/app/site/pages/meetings/pages/home/home-routing.module.ts +++ b/client/src/app/site/pages/meetings/pages/home/home-routing.module.ts @@ -1,11 +1,15 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { Permission } from 'src/app/domain/definitions/permission'; +import { PermissionGuard } from 'src/app/site/guards/permission.guard'; const routes: Routes = [ { path: ``, pathMatch: `full`, - loadChildren: () => import(`./pages/start/start.module`).then(m => m.StartModule) + loadChildren: () => import(`./pages/start/start.module`).then(m => m.StartModule), + data: { meetingPermissions: [Permission.meetingCanSeeFrontpage] }, + canLoad: [PermissionGuard] }, { path: `info`, From 131dd128e1bff7aed28abb5f49c4d4e8ef594a33 Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Fri, 27 Sep 2024 11:18:34 +0200 Subject: [PATCH 17/18] Rename public filter --- .../services/meeting-list-filter/meeting-list-filter.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/services/meeting-list-filter/meeting-list-filter.service.ts b/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/services/meeting-list-filter/meeting-list-filter.service.ts index 43b00fb404..d3a89dffa9 100644 --- a/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/services/meeting-list-filter/meeting-list-filter.service.ts +++ b/client/src/app/site/pages/organization/pages/orga-meetings/pages/meeting-list/services/meeting-list-filter/meeting-list-filter.service.ts @@ -50,7 +50,7 @@ export class MeetingListFilterService extends BaseFilterListService label: _(`Public`), options: [ { label: _(`Is public`), condition: true }, - { label: _(`Is closed`), condition: [false, null] } + { label: _(`Is not public`), condition: [false, null] } ] }, { From 605c4d5c8e3a1ee22a6e2517a6fb6d712d934484 Mon Sep 17 00:00:00 2001 From: Bastian Rihm Date: Fri, 27 Sep 2024 11:31:27 +0200 Subject: [PATCH 18/18] Move public icon and hide for anonymous users --- .../components/dashboard/dashboard.component.html | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html index cbdafbd525..1a6e6321d8 100644 --- a/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html +++ b/client/src/app/site/pages/organization/pages/dashboard/pages/dashboard-detail/components/dashboard/dashboard.component.html @@ -176,6 +176,9 @@

{{ 'Calendar' | translate }}

@if (meeting.isArchived) { archive } + @if (meeting.enable_anonymous && !operator.isAnonymous) { + public + } @if (meeting.committee_id) { {{ 'Calendar' | translate }}
- @let meetingIcon = meeting.locked_from_inside ? 'lock' : 'public'; - +
{{ meeting.name }}