From 17a5742d070a9a36d471e27d29c2701db39b43a9 Mon Sep 17 00:00:00 2001 From: Javier Borrego Date: Thu, 30 Apr 2026 17:13:00 +0200 Subject: [PATCH 1/4] Add option to account button --- .../account-button.component.html | 4 ++ .../account-button.component.ts | 13 +++++ .../participant-list.component.html | 9 +--- ...articipant-list-info-dialog.component.html | 54 +++++-------------- .../participant-list-info-dialog.service.ts | 33 ++++++++++-- 5 files changed, 60 insertions(+), 53 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 378314685a..f4a2f85409 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 @@ -94,6 +94,10 @@ } } + } 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 e675251346..e0c2ed20d3 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 @@ -9,6 +9,7 @@ import { allAvailableTranslations, availableTranslations } from 'src/app/domain/ import { getOmlVerboseName } from 'src/app/domain/definitions/organization-permission'; import { largeDialogSettings } from 'src/app/infrastructure/utils/dialog-settings'; import { mediumDialogSettings } from 'src/app/infrastructure/utils/dialog-settings'; +import { ParticipantListInfoDialogService } from 'src/app/site/pages/meetings/pages/participants/pages/participant-list/modules/participant-list-info-dialog'; import { ActiveMeetingIdService } from 'src/app/site/pages/meetings/services/active-meeting-id.service'; import { MeetingSettingsService } from 'src/app/site/pages/meetings/services/meeting-settings.service'; import { ViewUser } from 'src/app/site/pages/meetings/view-models/view-user'; @@ -88,6 +89,7 @@ export class AccountButtonComponent extends BaseUiComponent implements OnInit { private userRepo: UserControllerService, private authService: AuthService, private dialog: MatDialog, + private ParticipantListDialog: ParticipantListInfoDialogService, private router: Router, private theme: ThemeService, private meetingSettingsService: MeetingSettingsService, @@ -226,4 +228,15 @@ export class AccountButtonComponent extends BaseUiComponent implements OnInit { } return stringForUserPresent.replace(`{}`, this.user.short_name); } + + public async openDialogEditInfo(user: ViewUser) { + await this.ParticipantListDialog.open({ + id: user.id, + name: user.getName(), + number: user.number(), + structure_level_ids: this.user.structure_level_ids(), + vote_delegations_from_ids: this.user.vote_delegations_from_meeting_user_ids(), + vote_delegated_to_id: this.user.vote_delegated_to_meeting_user_id() + }); + } } diff --git a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.html b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.html index 34658da893..62eea91151 100644 --- a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.html +++ b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/components/participant-list/participant-list.component.html @@ -341,14 +341,7 @@

Participants

record_voice_over Contributions - + + @if (activeMeetingSetting) { + + } } 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 e0c2ed20d3..4f395cb916 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 @@ -7,6 +7,7 @@ import { Observable, Subscription } from 'rxjs'; import { Id } from 'src/app/domain/definitions/key-types'; import { allAvailableTranslations, availableTranslations } from 'src/app/domain/definitions/languages'; import { getOmlVerboseName } from 'src/app/domain/definitions/organization-permission'; +import { Permission } from 'src/app/domain/definitions/permission'; import { largeDialogSettings } from 'src/app/infrastructure/utils/dialog-settings'; import { mediumDialogSettings } from 'src/app/infrastructure/utils/dialog-settings'; import { ParticipantListInfoDialogService } from 'src/app/site/pages/meetings/pages/participants/pages/participant-list/modules/participant-list-info-dialog'; @@ -71,6 +72,7 @@ export class AccountButtonComponent extends BaseUiComponent implements OnInit { public username = ``; public isLoggedIn = false; + private _voteDelegationEnabled = false; public show1337 = -20; @@ -78,6 +80,13 @@ export class AccountButtonComponent extends BaseUiComponent implements OnInit { return this.activeMeetingIdService.meetingId; } + public get activeMeetingSetting(): boolean { + this.meetingSettingsService + .get(`users_enable_vote_delegations`) + .subscribe(enabled => (this._voteDelegationEnabled = enabled)); + return this._voteDelegationEnabled; + } + private _isAllowedSelfSetPresent = false; private _languageTrigger: MatMenuTrigger | undefined = undefined; private clickCounter = 0; @@ -89,7 +98,7 @@ export class AccountButtonComponent extends BaseUiComponent implements OnInit { private userRepo: UserControllerService, private authService: AuthService, private dialog: MatDialog, - private ParticipantListDialog: ParticipantListInfoDialogService, + private participantListDialog: ParticipantListInfoDialogService, private router: Router, private theme: ThemeService, private meetingSettingsService: MeetingSettingsService, @@ -229,8 +238,30 @@ export class AccountButtonComponent extends BaseUiComponent implements OnInit { return stringForUserPresent.replace(`{}`, this.user.short_name); } - public async openDialogEditInfo(user: ViewUser) { - await this.ParticipantListDialog.open({ + public canEditOwnDelegation(user: ViewUser): boolean { + if ( + this.operator.hasPerms(Permission.userCanEditOwnDelegation) && + !this.operator.hasPerms(Permission.userCanManage) && + !this.operator.hasPerms(Permission.userCanUpdate) + ) { + return this.operator.operatorId === user.id; + } else if ( + this.operator.hasPerms(Permission.userCanManage) || + this.operator.hasPerms(Permission.userCanUpdate) + ) { + return true; + } else { + return false; + } + } + + public async openDialogEditInfo(user: ViewUser): Promise { + console.log( + this.user, + this.user.vote_delegations_from_meeting_user_ids(), + this.user.vote_delegated_to_meeting_user_id() + ); + await this.participantListDialog.open({ id: user.id, name: user.getName(), number: user.number(), @@ -238,5 +269,6 @@ export class AccountButtonComponent extends BaseUiComponent implements OnInit { vote_delegations_from_ids: this.user.vote_delegations_from_meeting_user_ids(), vote_delegated_to_id: this.user.vote_delegated_to_meeting_user_id() }); + // *osPerms="permission.userCanUpdate; or: canEditOwnDelegation(user)" } } 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.html 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.html index 99440774b8..6312addd51 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.html +++ 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.html @@ -17,7 +17,7 @@

{{ 'Voting right delegated to (proxy)' | translate }} ([]); private _currentUser: ViewUser | null = null; private _voteDelegationEnabled = false; + private participantSubscriptionConfig: SubscribeToConfig; + public userList = this.participantRepo.getViewModelListObservable(); + private modelRequest = inject(ModelRequestService); public constructor( @Inject(MAT_DIALOG_DATA) public readonly infoDialog: InfoDialog, @@ -60,25 +67,33 @@ export class ParticipantListInfoDialogComponent extends BaseUiComponent implemen private groupRepo: GroupControllerService, private structureLevelRepo: StructureLevelControllerService, private meetingSettings: MeetingSettingsService, - private operator: OperatorService + private activeMeetingIdService: ActiveMeetingIdService, + private operator: OperatorService, + protected userRepo: UserRepositoryService = inject(UserRepositoryService) ) { super(); } public ngOnInit(): void { this.userSortService.initSorting(); + this.participantSubscriptionConfig = getParticipantListSubscriptionConfig( + this.activeMeetingIdService.meetingId + ); + this.modelRequest.subscribeTo({ + ...this.participantSubscriptionConfig, + subscriptionName: 'participant_minimal_delegation_dialog:subscription' + }); + console.log(this.userRepo); this._currentUser = this.participantRepo.getViewModel(this.infoDialog.id); this.structureLevelObservable = this.structureLevelRepo.getViewModelListObservable(); this.subscriptions.push( - this.participantRepo - .getSortedViewModelListObservable(this.userSortService.repositorySortingKey) - .subscribe(participants => - this._otherParticipantsSubject.next( - participants - .filter(participant => participant.id !== this._currentUser.id) - .map(participant => participant.getMeetingUser()) - ) - ), + this.userList.subscribe(participants => + this._otherParticipantsSubject.next( + participants + .filter(participant => participant.id !== this._currentUser.id) + .map(participant => participant.getMeetingUser()) + ) + ), this.meetingSettings .get(`users_enable_vote_delegations`) .subscribe(enabled => (this._voteDelegationEnabled = enabled)) @@ -87,6 +102,7 @@ export class ParticipantListInfoDialogComponent extends BaseUiComponent implemen public override ngOnDestroy(): void { this.userSortService.exitSortService(); + this.modelRequest.closeSubscription('participant_minimal_delegation_dialog:subscription'); super.ngOnDestroy(); } diff --git a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/modules/participant-list-info-dialog/services/participant-list-info-dialog.service.ts b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/modules/participant-list-info-dialog/services/participant-list-info-dialog.service.ts index 9b6489e376..b9d291a606 100644 --- a/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/modules/participant-list-info-dialog/services/participant-list-info-dialog.service.ts +++ b/client/src/app/site/pages/meetings/pages/participants/pages/participant-list/modules/participant-list-info-dialog/services/participant-list-info-dialog.service.ts @@ -69,14 +69,10 @@ export class ParticipantListInfoDialogService extends BaseDialogService< } }); const result = await firstValueFrom(dialogRef.afterClosed()); - console.log(data.id, result, result.id, data); - if (result) { if (data instanceof ViewUser) { - console.log('it is'); this.update(result, data); } else { - console.log('something else'); this.create(result); } } From b0d7c97bf8ea6ca77bdd79dee7a317ff50219621 Mon Sep 17 00:00:00 2001 From: Javier Borrego Date: Wed, 6 May 2026 11:44:37 +0200 Subject: [PATCH 3/4] Removed current user from selectable, update user data, able to remove delegation --- .../account-button.component.html | 2 +- .../account-button.component.ts | 7 +--- .../participant-list.component.ts | 11 +---- ...articipant-list-info-dialog.component.html | 11 ++--- .../participant-list-info-dialog.component.ts | 40 +++++++------------ .../participant-list-info-dialog.service.ts | 20 +++------- 6 files changed, 30 insertions(+), 61 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 22b81d3140..3668d5ec33 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 @@ -94,7 +94,7 @@ } } - @if (activeMeetingSetting) { + @if (activeMeetingSetting && canEditOwnDelegation(user)) {