From 89fb630aca53efa57bd35ae2d02937deefda8526 Mon Sep 17 00:00:00 2001 From: Luisa Date: Mon, 8 Jul 2024 13:37:43 +0200 Subject: [PATCH 01/11] Make account list openly accessible for committee admin --- .../organization-navigation.component.html | 2 +- .../organization-navigation.component.ts | 9 +++++++-- .../organization-routing.module.ts | 4 ++-- .../app/site/services/auth-check.service.ts | 19 +++++++++++++++---- .../src/app/site/services/operator.service.ts | 4 ++++ .../src/app/site/services/reroute.service.ts | 5 +++++ .../directives/perms/oml-perms.directive.ts | 17 ++++++++++++++++- 7 files changed, 50 insertions(+), 10 deletions(-) diff --git a/client/src/app/site/pages/organization/modules/navigation/organization-navigation/organization-navigation.component.html b/client/src/app/site/pages/organization/modules/navigation/organization-navigation/organization-navigation.component.html index a7878c06f7..dace42d7dd 100644 --- a/client/src/app/site/pages/organization/modules/navigation/organization-navigation/organization-navigation.component.html +++ b/client/src/app/site/pages/organization/modules/navigation/organization-navigation/organization-navigation.component.html @@ -1,7 +1,7 @@ {} +interface OrgaMenuEntry extends BaseMenuEntry { + optionalCML?: CML; +} @Component({ selector: `os-organization-navigation`, @@ -13,6 +15,8 @@ interface OrgaMenuEntry extends BaseMenuEntry {} styleUrls: [`./organization-navigation.component.scss`] }) export class OrganizationNavigationComponent { + public CML = CML; + public menuEntries: OrgaMenuEntry[] = [ { route: `/`, @@ -39,6 +43,7 @@ export class OrganizationNavigationComponent { displayName: `Accounts`, icon: `group`, permission: OML.can_manage_users, + optionalCML: CML.can_manage, weight: 300 }, { diff --git a/client/src/app/site/pages/organization/organization-routing.module.ts b/client/src/app/site/pages/organization/organization-routing.module.ts index 0cc36697ec..0402ab92f7 100644 --- a/client/src/app/site/pages/organization/organization-routing.module.ts +++ b/client/src/app/site/pages/organization/organization-routing.module.ts @@ -1,7 +1,7 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; -import { OML } from '../../../domain/definitions/organization-permission'; +import { CML, OML } from '../../../domain/definitions/organization-permission'; import { AuthGuard } from '../../guards/auth.guard'; import { PermissionGuard } from '../../guards/permission.guard'; import { OrganizationNavigationWrapperComponent } from './modules/navigation/organization-navigation-wrapper/organization-navigation-wrapper.component'; @@ -31,7 +31,7 @@ const routes: Routes = [ { path: `accounts`, loadChildren: () => import(`./pages/accounts/accounts.module`).then(m => m.AccountsModule), - data: { omlPermissions: [OML.can_manage_users] }, + data: { omlPermissions: [OML.can_manage_users], optionalCmlPermissions: [CML.can_manage] }, canLoad: [PermissionGuard] }, { diff --git a/client/src/app/site/services/auth-check.service.ts b/client/src/app/site/services/auth-check.service.ts index ff4c992484..0c6e9a99cf 100644 --- a/client/src/app/site/services/auth-check.service.ts +++ b/client/src/app/site/services/auth-check.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { Data } from '@angular/router'; -import { OML } from 'src/app/domain/definitions/organization-permission'; +import { CML, OML } from 'src/app/domain/definitions/organization-permission'; import { Permission } from 'src/app/domain/definitions/permission'; import { Settings } from 'src/app/domain/models/meetings/meeting'; @@ -38,11 +38,12 @@ export class AuthCheckService { public async isAuthorized(routeData: Data): Promise { const basePerm: Permission[] = routeData[`meetingPermissions`]; const omlPermissions: OML[] = routeData[`omlPermissions`]; - if (!basePerm && !omlPermissions) { + const cmlPermissions: CML[] = routeData[`optionalCmlPermissions`]; + if (!basePerm && !omlPermissions && !cmlPermissions) { return true; } const meetingSetting: keyof Settings = routeData[`meetingSetting`]; - const hasPerm = await this.hasPerms(basePerm, omlPermissions); + const hasPerm = await this.hasPerms(basePerm, omlPermissions, cmlPermissions); const hasSetting = this.isMeetingSettingEnabled(meetingSetting); return hasPerm && hasSetting; } @@ -78,9 +79,19 @@ export class AuthCheckService { return this.operator.isInMeeting(Number(meetingIdString)) || this.operator.isSuperAdmin; } - private async hasPerms(basePerm: Permission | Permission[], omlPerm?: OML | OML[]): Promise { + private async hasPerms( + basePerm: Permission | Permission[], + omlPerm?: OML | OML[], + cmlPerm?: CML | CML[] + ): Promise { await this.operator.ready; let result = true; + if (!!cmlPerm) { + const toCheck = Array.isArray(cmlPerm) ? cmlPerm : [cmlPerm]; + if (toCheck.includes(CML.can_manage) && this.operator.isAnyCommitteeAdmin()) { + return true; + } + } if (!!basePerm && !!this.activeMeeting.meetingId) { const toCheck = Array.isArray(basePerm) ? basePerm : [basePerm]; await this.operator.groupPermissionsLoaded; diff --git a/client/src/app/site/services/operator.service.ts b/client/src/app/site/services/operator.service.ts index 6c45e810c7..174d247ea8 100644 --- a/client/src/app/site/services/operator.service.ts +++ b/client/src/app/site/services/operator.service.ts @@ -630,6 +630,10 @@ export class OperatorService { return permissionsToCheck.some(permission => currentCommitteePermission >= cmlNameMapping[permission]); } + public isAnyCommitteeAdmin(): boolean { + return !!this._CML && !!Object.keys(this._CML).length; + } + /** * Determines whether the current operator is included in at least one of the committees, which are passed. * This function checks also if an operator is a "superadmin" -> then, they is technically in every committee. diff --git a/client/src/app/site/services/reroute.service.ts b/client/src/app/site/services/reroute.service.ts index cb1ee5c233..2f8319b2b9 100644 --- a/client/src/app/site/services/reroute.service.ts +++ b/client/src/app/site/services/reroute.service.ts @@ -48,6 +48,11 @@ export class RerouteService { if (routeData?.[`omlPermissions`]) { routeDataArray = routeDataArray.concat(routeData[`omlPermissions`]); } + if (routeData?.[`optionalCmlPermissions`]) { + routeDataArray = routeDataArray.concat( + routeData[`optionalCmlPermissions`].map(perm => `committee.` + perm) + ); + } const queryParams = { error: `Authorization Error`, diff --git a/client/src/app/ui/directives/perms/oml-perms.directive.ts b/client/src/app/ui/directives/perms/oml-perms.directive.ts index 184e233410..b9564ce6a0 100644 --- a/client/src/app/ui/directives/perms/oml-perms.directive.ts +++ b/client/src/app/ui/directives/perms/oml-perms.directive.ts @@ -7,6 +7,8 @@ import { BasePermsDirective } from './base-perms.directive'; selector: `[osOmlPerms]` }) export class OmlPermsDirective extends BasePermsDirective { + private _checkCML = false; + @Input() public set osOmlPerms(perms: OML | OML[]) { this.setPermissions(perms); @@ -27,6 +29,16 @@ export class OmlPermsDirective extends BasePermsDirective { this.setComplementCondition(value); } + /** + * If set to true in order to also allow anyone who has any committee permissions + * `*osPerms="permission.mediafileCanManage; allowCommitteeAdmin: true"` + */ + @Input() + public set osOmlPermsAllowCommitteeAdmin(value: boolean) { + this._checkCML = value; + this.updatePermission(); + } + @Input() public set osOmlPermsThen(template: TemplateRef) { this.setThenTemplate(template); @@ -38,6 +50,9 @@ export class OmlPermsDirective extends BasePermsDirective { } protected hasPermissions(): boolean { - return this.operator.hasOrganizationPermissions(...this.permissions); + return ( + this.operator.hasOrganizationPermissions(...this.permissions) || + (this._checkCML ? this.operator.isAnyCommitteeAdmin() : false) + ); } } From 5770300e4d62117d00969edc747e852c8b31421a Mon Sep 17 00:00:00 2001 From: Luisa Date: Mon, 8 Jul 2024 18:00:59 +0200 Subject: [PATCH 02/11] Add fake filters and restrict editing of orga user data --- .../user-detail-view.component.html | 4 +- .../user-detail-view.component.ts | 5 +- .../account-main/account-main.component.ts | 97 ++++++++++++++----- .../account-detail.component.html | 5 +- .../account-detail.component.ts | 3 +- .../account-list/account-list.component.html | 15 ++- .../account-list/account-list.component.ts | 21 +++- .../committee-meeting-preview.component.html | 7 +- .../list/components/list/list.component.html | 1 + .../list/components/list/list.component.ts | 8 ++ .../sort-filter-bar.component.html | 13 ++- .../sort-filter-bar.component.ts | 26 ++++- .../view-list/view-list.component.html | 1 + .../view-list/view-list.component.ts | 7 ++ 14 files changed, 172 insertions(+), 41 deletions(-) diff --git a/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.html b/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.html index 6ac26b99fd..a0411d0a76 100644 --- a/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.html +++ b/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.html @@ -6,7 +6,7 @@ - + @@ -15,7 +15,7 @@ diff --git a/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.ts b/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.ts index 3d29432ff9..9f0b520a8c 100644 --- a/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.ts +++ b/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.ts @@ -79,6 +79,9 @@ export class UserDetailViewComponent extends BaseUiComponent implements OnInit, @Input() public useMatcard = true; + @Input() + public useAdditionalEditTemplate = true; + @Input() public set additionalFormControls(controls: any) { this._additionalFormControls = controls; @@ -314,7 +317,7 @@ export class UserDetailViewComponent extends BaseUiComponent implements OnInit, member_number: [``], is_active: [true], is_physical_person: [true], - ...this._additionalFormControls + ...(this.useAdditionalEditTemplate ? this._additionalFormControls : {}) }; } diff --git a/client/src/app/site/pages/organization/pages/accounts/components/account-main/account-main.component.ts b/client/src/app/site/pages/organization/pages/accounts/components/account-main/account-main.component.ts index afa715839c..6f442e449a 100644 --- a/client/src/app/site/pages/organization/pages/accounts/components/account-main/account-main.component.ts +++ b/client/src/app/site/pages/organization/pages/accounts/components/account-main/account-main.component.ts @@ -1,49 +1,75 @@ import { Component } from '@angular/core'; +import { inject } from '@angular/core'; +import { distinctUntilChanged, map } from 'rxjs'; +import { OML } from 'src/app/domain/definitions/organization-permission'; import { BaseModelRequestHandlerComponent } from 'src/app/site/base/base-model-request-handler.component'; +import { ViewUser } from 'src/app/site/pages/meetings/view-models/view-user'; +import { OperatorService } from 'src/app/site/services/operator.service'; import { ORGANIZATION_ID } from '../../../../services/organization.service'; import { ViewOrganization } from '../../../../view-models/view-organization'; const ACCOUNT_LIST_SUBSCRIPTION = `account_list`; +const accountListSubsciptionContent = { + idField: `user_ids`, + fieldset: `accountList`, + follow: [ + { + idField: `meeting_user_ids`, + fieldset: `groups`, + follow: [ + { + idField: `meeting_id`, + fieldset: [`is_active_in_organization_id`, `is_archived_in_organization_id`], + follow: [{ idField: `committee_id`, fieldset: [`manager_ids`] }] + } + ] + } + ] +}; + @Component({ selector: `os-account-main`, templateUrl: `./account-main.component.html`, styleUrls: [`./account-main.component.scss`] }) export class AccountMainComponent extends BaseModelRequestHandlerComponent { + protected operator: OperatorService; + public constructor() { super(); + + this.operator = inject(OperatorService); } - protected override onShouldCreateModelRequests(): void { + protected override async onShouldCreateModelRequests(): Promise { + await this.operator.ready; this.subscribeTo( - [ + this.getAccountSubscriptionForCurrentPerm(this.operator.hasOrganizationPermissions(OML.can_manage_users)), + { hideWhenMeetingChanged: true } + ); + this.operator.userObservable + .pipe( + map(user => user && !!user?.organization_management_level), + distinctUntilChanged() + ) + .subscribe(hasOrgaRights => { + this.updateSubscribeTo(this.getAccountSubscriptionForCurrentPerm(hasOrgaRights), { + hideWhenMeetingChanged: true + }); + }); + } + + private getAccountSubscriptionForCurrentPerm(isUserAdmin: boolean): any { + if (isUserAdmin) { + return [ { modelRequest: { viewModelCtor: ViewOrganization, ids: [ORGANIZATION_ID], follow: [ - { - idField: `user_ids`, - fieldset: `accountList`, - follow: [ - { - idField: `meeting_user_ids`, - fieldset: `groups`, - follow: [ - { - idField: `meeting_id`, - fieldset: [ - `is_active_in_organization_id`, - `is_archived_in_organization_id` - ], - follow: [{ idField: `committee_id`, fieldset: [`manager_ids`] }] - } - ] - } - ] - }, + accountListSubsciptionContent, { idField: `committee_ids`, fieldset: [`name`], @@ -58,8 +84,29 @@ export class AccountMainComponent extends BaseModelRequestHandlerComponent { }, subscriptionName: `${ACCOUNT_LIST_SUBSCRIPTION}` } - ], - { hideWhenMeetingChanged: true } - ); + ]; + } + return [ + { + modelRequest: { + viewModelCtor: ViewUser, + ids: [this.operator.operatorId], + follow: [ + { + idField: `committee_management_ids`, + fieldset: [`name`, `manager_ids`], + follow: [ + accountListSubsciptionContent, + { + idField: `meeting_ids`, + fieldset: [`name`] + } + ] + } + ] + }, + subscriptionName: `committee_manager_${ACCOUNT_LIST_SUBSCRIPTION}` + } + ]; } } diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.html b/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.html index 0ba6b6e785..e0905870d8 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.html +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.html @@ -30,6 +30,7 @@

{{ user?.full_name }}

[additionalFormControls]="additionalFormControls" [generatePasswordFn]="getRandomPasswordFn()" [user]="user" + [useAdditionalEditTemplate]="!!organizationManagementLevels.length" (changeEvent)="personalInfoFormValue = $event" (validEvent)="isFormValid = $event" (errorEvent)="formErrors = $event" @@ -38,7 +39,7 @@

{{ user?.full_name }}

{{ 'Organization specific information' | translate }}

-
+
{{ 'Administration roles (at organization level)' | translate }} @@ -217,7 +218,7 @@

{{ 'Committees and meetings' | translate }}

security {{ 'Change password' | translate }} - + @@ -129,7 +130,11 @@

edit {{ 'Edit' | translate }} - + event_available {{ 'Add to meetings' | translate }} @@ -146,7 +151,7 @@

library_add {{ 'Multiselect' | translate }} - +

-
-
+
+
+ +
+
diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.ts b/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.ts index d3cda5c388..21e3b56cae 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.ts +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.ts @@ -89,6 +89,17 @@ export class AccountDetailComponent extends BaseComponent implements OnInit { return Object.values(this._tableData).filter(row => row[`is_manager`] === true).length; } + public get userOML(): OML { + return this.user.organization_management_level as OML; + } + + public get canEdit(): boolean { + if (!this.userOML) { + return true; + } + return this.operator.hasOrganizationPermissions(this.userOML); + } + public tableDataAscOrderCompare = (a: KeyValue, b: KeyValue): number => { const aName = a.value[`committee_name`] ?? a.value[`meeting_name`] ?? ``; const bName = b.value[`committee_name`] ?? b.value[`meeting_name`] ?? ``; diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html index 7c3040c982..b7178cd056 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html @@ -38,6 +38,7 @@

[alwaysShowMenu]="true" [vScrollFixed]="60" [fakeFilters]="fakeFilters" + [totalCount]="controller.getViewModelList().length" >
diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.ts b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.ts index b115988cc6..7e7b626e05 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.ts +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.ts @@ -58,7 +58,6 @@ export class AccountListComponent extends BaseListViewComponent { this.filterService.filterMeeting(params[`id`] || null); if (params[`id`]) { this.meeting = this.meetingRepo.getViewModelObservable(+params[`id`]); - console.log(`meeting`, params[`id`], this.meeting); } }) ); @@ -73,7 +72,7 @@ export class AccountListComponent extends BaseListViewComponent { } public navigateToBaseList(): void { - this.router.navigate([`..`, `..`], { relativeTo: this.route }); + this.router.navigate([`/accounts`]); } public get fakeFilters(): Observable<{ [key: string]: () => void }> { diff --git a/client/src/app/ui/modules/list/components/list/list.component.html b/client/src/app/ui/modules/list/components/list/list.component.html index 1dd284e84b..536eaa2830 100644 --- a/client/src/app/ui/modules/list/components/list/list.component.html +++ b/client/src/app/ui/modules/list/components/list/list.component.html @@ -17,6 +17,7 @@ [fullScreen]="fullScreen" [addBottomSpacer]="addBottomSpacer" [fakeFilters]="fakeFilters" + [totalCount]="totalCount" (selectedRowsChange)="selectedRowsChange.emit($event)" (searchFilterUpdated)="searchFilterUpdated.emit($event)" > diff --git a/client/src/app/ui/modules/list/components/list/list.component.ts b/client/src/app/ui/modules/list/components/list/list.component.ts index 46d010aced..fded21f9cc 100644 --- a/client/src/app/ui/modules/list/components/list/list.component.ts +++ b/client/src/app/ui/modules/list/components/list/list.component.ts @@ -20,4 +20,7 @@ export class ListComponent extends BaseListComponent */ @Input() public fakeFilters: Observable<{ [key: string]: () => void }> = null; + + @Input() + public totalCount: number | Observable; } diff --git a/client/src/app/ui/modules/list/components/view-list/view-list.component.ts b/client/src/app/ui/modules/list/components/view-list/view-list.component.ts index fd7dc7d369..dbfde13ade 100644 --- a/client/src/app/ui/modules/list/components/view-list/view-list.component.ts +++ b/client/src/app/ui/modules/list/components/view-list/view-list.component.ts @@ -10,7 +10,7 @@ import { ViewChild, ViewEncapsulation } from '@angular/core'; -import { delay, find, map, Observable, of } from 'rxjs'; +import { BehaviorSubject, delay, find, map, Observable, of } from 'rxjs'; import { Identifiable } from 'src/app/domain/interfaces'; import { ViewModelListProvider } from 'src/app/ui/base/view-model-list-provider'; @@ -130,6 +130,19 @@ export class ViewListComponent implements OnInit, OnDest @Input() public fakeFilters: Observable<{ [key: string]: () => void }> = null; + @Input() + public set totalCount(value: number | Observable) { + if (value === undefined) { + this._totalCountObservable = null; + } else if (value instanceof Observable) { + this._totalCountObservable = value; + } else { + this._totalCountObservable = new BehaviorSubject(value); + } + } + + private _totalCountObservable: Observable = null; + /** * Double binding the selected rows */ @@ -146,7 +159,7 @@ export class ViewListComponent implements OnInit, OnDest } public get totalCountObservable(): Observable { - return this._source.pipe(map(items => items.length)); + return this._totalCountObservable ?? this._source.pipe(map(items => items.length)); } public get source(): V[] { From c786013870014e437ce5a5e7fd4d03617c88c8c6 Mon Sep 17 00:00:00 2001 From: Luisa Date: Tue, 9 Jul 2024 15:46:36 +0200 Subject: [PATCH 04/11] Amend scope functionality, fix navigation --- .../get-user-scope-presenter.service.ts | 37 +------------------ .../participant-list-info-dialog.component.ts | 12 ------ .../account-detail.component.html | 2 +- .../account-list/account-list.component.html | 9 +---- .../account-list/account-list.component.ts | 6 ++- client/src/app/site/services/user.service.ts | 28 ++------------ 6 files changed, 12 insertions(+), 82 deletions(-) diff --git a/client/src/app/gateways/presenter/get-user-scope-presenter.service.ts b/client/src/app/gateways/presenter/get-user-scope-presenter.service.ts index 003904c4b9..5b5319ea41 100644 --- a/client/src/app/gateways/presenter/get-user-scope-presenter.service.ts +++ b/client/src/app/gateways/presenter/get-user-scope-presenter.service.ts @@ -14,6 +14,7 @@ interface GetUserScopeIdentifiedScope { collection: UserScope; id: Id; user_oml: OML | ``; + committee_ids: number[]; } export interface GetUserScopePresenterResult { @@ -29,40 +30,4 @@ export class GetUserScopePresenterService { public async call(payload: GetUserScopePresenterPayload): Promise { return await this.presenter.call(Presenter.GET_USER_SCOPE, payload); } - - /** - * Compares two scopes and returns a number depending on the result. - * `0` means it is equal, `1` means it is higher, `-1` means it is lower. - * - * @param scope A first scope - * @param toCompare A scope to compare with the first scope - * @param compareOml Whether the OML differences between the scopes should be taken into account - * @returns The result of the comparison - */ - public compareScope( - scope: GetUserScopeIdentifiedScope, - toCompare: GetUserScopeIdentifiedScope, - compareOml = false - ): number { - if (scope.collection === toCompare.collection && (compareOml ? scope.user_oml === toCompare.user_oml : true)) { - return 0; - } - if (compareOml) { - if (scope.user_oml !== `` || toCompare.user_oml !== ``) { - return scope.user_oml !== `` && - (toCompare.user_oml === `` || - (scope.user_oml === OML.superadmin && toCompare.user_oml !== OML.superadmin) || - (scope.user_oml === OML.can_manage_organization && toCompare.user_oml === OML.can_manage_users)) - ? 1 - : -1; - } - } - if (scope.collection === UserScope.ORGANIZATION) { - return 1; - } - if (scope.collection === UserScope.COMMITTEE && toCompare.collection === UserScope.MEETING) { - return 1; - } - return -1; - } } 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 cf272abf8a..098e5022a9 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 @@ -8,7 +8,6 @@ import { ParticipantControllerService } from 'src/app/site/pages/meetings/pages/ import { MeetingSettingsService } from 'src/app/site/pages/meetings/services/meeting-settings.service'; import { ViewMeetingUser } from 'src/app/site/pages/meetings/view-models/view-meeting-user'; import { ViewUser } from 'src/app/site/pages/meetings/view-models/view-user'; -import { UserService } from 'src/app/site/services/user.service'; import { BaseUiComponent } from 'src/app/ui/base/base-ui-component'; import { StructureLevelControllerService } from '../../../../../structure-levels/services/structure-level-controller.service'; @@ -32,10 +31,6 @@ export class ParticipantListInfoDialogComponent extends BaseUiComponent implemen return this._otherParticipantsSubject; } - public get isUserInScope(): boolean { - return this._isUserInScope; - } - public get showVoteDelegations(): boolean { return this._voteDelegationEnabled; } @@ -43,7 +38,6 @@ export class ParticipantListInfoDialogComponent extends BaseUiComponent implemen public structureLevelObservable: Observable; private readonly _otherParticipantsSubject = new BehaviorSubject([]); - private _isUserInScope = true; private _currentUser: ViewUser | null = null; private _voteDelegationEnabled = false; @@ -53,7 +47,6 @@ export class ParticipantListInfoDialogComponent extends BaseUiComponent implemen private userSortService: ParticipantListSortService, private groupRepo: GroupControllerService, private structureLevelRepo: StructureLevelControllerService, - private userService: UserService, private meetingSettings: MeetingSettingsService ) { super(); @@ -62,7 +55,6 @@ export class ParticipantListInfoDialogComponent extends BaseUiComponent implemen public ngOnInit(): void { this.userSortService.initSorting(); this._currentUser = this.participantRepo.getViewModel(this.infoDialog.id); - this.updateIsUserInScope(); this.structureLevelObservable = this.structureLevelRepo.getViewModelListObservable(); this.subscriptions.push( this.participantRepo @@ -84,8 +76,4 @@ export class ParticipantListInfoDialogComponent extends BaseUiComponent implemen this.userSortService.exitSortService(); super.ngOnDestroy(); } - - private async updateIsUserInScope(): Promise { - this._isUserInScope = await this.userService.isUserInSameScope(this.infoDialog.id); - } } diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.html b/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.html index 8ba2f17874..7e15504598 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.html +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.html @@ -3,7 +3,7 @@ mainButtonIcon="edit" [mainActionTooltip]="'Edit account' | translate" (mainEvent)="editMember()" - [goBack]="false" + [goBack]="true" [nav]="false" [editMode]="isEditingUser" [isSaveButtonEnabled]="isFormValid" diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html index b7178cd056..fed6ab034f 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html @@ -1,7 +1,7 @@

{{ 'Accounts' | translate }} - ({{ m.name }})

@@ -131,11 +130,7 @@

edit {{ 'Edit' | translate }} - + event_available {{ 'Add to meetings' | translate }} diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.ts b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.ts index 7e7b626e05..ea80fef4d9 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.ts +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.ts @@ -3,7 +3,7 @@ import { ActivatedRoute } from '@angular/router'; import { marker as _ } from '@colsen1991/ngx-translate-extract-marker'; import { TranslateService } from '@ngx-translate/core'; import { map, Observable } from 'rxjs'; -import { getOmlVerboseName } from 'src/app/domain/definitions/organization-permission'; +import { getOmlVerboseName, OML } from 'src/app/domain/definitions/organization-permission'; import { OMLMapping } from 'src/app/domain/definitions/organization-permission'; import { BaseListViewComponent } from 'src/app/site/base/base-list-view.component'; import { MeetingControllerService } from 'src/app/site/pages/meetings/services/meeting-controller.service'; @@ -35,6 +35,10 @@ export class AccountListComponent extends BaseListViewComponent { return this.vp.isMobile; } + public get isUserManager(): boolean { + return this.operator.hasOrganizationPermissions(OML.can_manage_users); + } + public constructor( protected override translate: TranslateService, public readonly controller: AccountControllerService, diff --git a/client/src/app/site/services/user.service.ts b/client/src/app/site/services/user.service.ts index b0bb76544e..3b3e12fb20 100644 --- a/client/src/app/site/services/user.service.ts +++ b/client/src/app/site/services/user.service.ts @@ -72,31 +72,6 @@ export class UserService { } } - /** - * Checks, if the passed users (given by their ids) are in the same scope as the operator and returns the result. - * - * @param userIds The id of every user to check - * - * @returns A boolean whether every given user is in the same scope as the operator, if there are no users or only the operator is given, it will always be true - */ - public async isUserInSameScope(...userIds: Id[]): Promise { - userIds = userIds.filter(id => id !== this.operator.operatorId); - if (!userIds.length) { - return true; - } - const result = await this.presenter.call({ user_ids: [...userIds, this.operator.operatorId!] }); - const ownScope = result[this.operator.operatorId!]; - return !Object.keys(result) - .map(userId => parseInt(userId, 10)) - .some(userId => { - const toCompare = result[userId]; - return ( - this.presenter.compareScope(ownScope, toCompare) === -1 || - (ownScope.collection === toCompare.collection && ownScope.id !== toCompare.id) - ); - }); - } - /** * Checks, if the operator has the correct perms to edit the passed users (given by their ids) in accordance with their scopes. * May not return true if a meeting scope outside of the current meeting is returned, even if the operator has the correct permission. @@ -112,6 +87,9 @@ export class UserService { .every(userId => { const toCompare = result[userId]; let hasPerms = this.operator.hasOrganizationPermissions(toCompare.user_oml || OML.can_manage_users); + if (!hasPerms && toCompare.committee_ids.length) { + hasPerms = true; + } if (!hasPerms && toCompare.collection === UserScope.COMMITTEE) { hasPerms = hasPerms || this.operator.hasCommitteePermissions(toCompare.id, CML.can_manage); } From 1f02831d0180e0feef1c29a4b1aa87cb6ed630bd Mon Sep 17 00:00:00 2001 From: Luisa Date: Tue, 9 Jul 2024 16:29:01 +0200 Subject: [PATCH 05/11] Fix scope --- client/src/app/site/services/user.service.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/src/app/site/services/user.service.ts b/client/src/app/site/services/user.service.ts index 3b3e12fb20..1586e08e98 100644 --- a/client/src/app/site/services/user.service.ts +++ b/client/src/app/site/services/user.service.ts @@ -87,7 +87,12 @@ export class UserService { .every(userId => { const toCompare = result[userId]; let hasPerms = this.operator.hasOrganizationPermissions(toCompare.user_oml || OML.can_manage_users); - if (!hasPerms && toCompare.committee_ids.length) { + if ( + !hasPerms && + toCompare.collection === UserScope.ORGANIZATION && + !toCompare.user_oml && + toCompare.committee_ids.intersect(this.operator.user.committee_management_ids || []) + ) { hasPerms = true; } if (!hasPerms && toCompare.collection === UserScope.COMMITTEE) { From 1c3aa0a471f5a7a6fc5841f560f7bbc1a4575db5 Mon Sep 17 00:00:00 2001 From: Luisa Date: Wed, 10 Jul 2024 10:36:36 +0200 Subject: [PATCH 06/11] Fix participant edit --- .../participant-detail-view.component.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) 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 eea971eec6..4199856d2d 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 @@ -9,7 +9,10 @@ import { OML } from 'src/app/domain/definitions/organization-permission'; import { Permission } from 'src/app/domain/definitions/permission'; import { BaseMeetingComponent } from 'src/app/site/pages/meetings/base/base-meeting.component'; import { ViewGroup } from 'src/app/site/pages/meetings/pages/participants'; -import { ParticipantControllerService } from 'src/app/site/pages/meetings/pages/participants/services/common/participant-controller.service'; +import { + MEETING_RELATED_FORM_CONTROLS, + ParticipantControllerService +} from 'src/app/site/pages/meetings/pages/participants/services/common/participant-controller.service'; import { PERSONAL_FORM_CONTROLS, ViewUser } from 'src/app/site/pages/meetings/view-models/view-user'; import { OrganizationSettingsService } from 'src/app/site/pages/organization/services/organization-settings.service'; import { OperatorService } from 'src/app/site/services/operator.service'; @@ -72,7 +75,9 @@ export class ParticipantDetailViewComponent extends BaseMeetingComponent { if (this._isUserInScope || (this.newUser && canUpdateUsers)) { return true; } else if (canUpdateUsers) { - return controlName === `is_present` ? this.operator.hasPerms(Permission.userCanManagePresence) : true; + return controlName === `is_present` + ? this.operator.hasPerms(Permission.userCanManagePresence) + : MEETING_RELATED_FORM_CONTROLS.includes(controlName); } else { return PERSONAL_FORM_CONTROLS.includes(controlName); } @@ -291,6 +296,7 @@ export class ParticipantDetailViewComponent extends BaseMeetingComponent { public async setEditMode(edit: boolean): Promise { if (!this.newUser && edit) { this._isUserInScope = await this.userService.hasScopeManagePerms(this._userId!); + console.log(`IS IN SCOPE`, this._isUserInScope); } this.isEditingSubject.next(edit); From ad5264ea5f5176fd2bd5f6d0c4fcc94540d13142 Mon Sep 17 00:00:00 2001 From: Luisa Date: Wed, 10 Jul 2024 10:58:07 +0200 Subject: [PATCH 07/11] Fix account-list navigation --- .../pages/accounts/accounts-routing.module.ts | 16 ++++++++-- .../account-detail.component.html | 2 +- .../account-list/account-list.component.html | 31 ++++++++++--------- .../account-list/account-list.component.ts | 6 ++-- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/client/src/app/site/pages/organization/pages/accounts/accounts-routing.module.ts b/client/src/app/site/pages/organization/pages/accounts/accounts-routing.module.ts index 0e87bd639d..461452d1c9 100644 --- a/client/src/app/site/pages/organization/pages/accounts/accounts-routing.module.ts +++ b/client/src/app/site/pages/organization/pages/accounts/accounts-routing.module.ts @@ -14,8 +14,20 @@ const routes: Routes = [ loadChildren: () => import(`./pages/account-list/account-list.module`).then(m => m.AccountListModule) }, { - path: `meeting/:id`, - loadChildren: () => import(`./pages/account-list/account-list.module`).then(m => m.AccountListModule) + path: `meeting/:meetingId`, + children: [ + { + path: ``, + pathMatch: `full`, + loadChildren: () => + import(`./pages/account-list/account-list.module`).then(m => m.AccountListModule) + }, + { + path: `:id`, + loadChildren: () => + import(`./pages/account-detail/account-detail.module`).then(m => m.AccountDetailModule) + } + ] }, { path: `create`, diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.html b/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.html index 7e15504598..8ba2f17874 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.html +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.html @@ -3,7 +3,7 @@ mainButtonIcon="edit" [mainActionTooltip]="'Edit account' | translate" (mainEvent)="editMember()" - [goBack]="true" + [goBack]="false" [nav]="false" [editMode]="isEditingUser" [isSaveButtonEnabled]="isFormValid" diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html index fed6ab034f..ae47db6718 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html @@ -1,7 +1,7 @@ >
- +
@@ -126,11 +126,11 @@

- + edit {{ 'Edit' | translate }} - + event_available {{ 'Add to meetings' | translate }} @@ -147,17 +147,20 @@

library_add {{ 'Multiselect' | translate }} - - - - + + +

{ this.listStorageIndex = ACCOUNT_LIST_STORAGE_INDEX; this.subscriptions.push( this.route.params.subscribe(async params => { - this.filterService.filterMeeting(params[`id`] || null); - if (params[`id`]) { - this.meeting = this.meetingRepo.getViewModelObservable(+params[`id`]); + this.filterService.filterMeeting(params[`meetingId`] || null); + if (params[`meetingId`]) { + this.meeting = this.meetingRepo.getViewModelObservable(+params[`meetingId`]); } }) ); From ecb0859d14d088ac089806b82ea6d99ceb6ca2d1 Mon Sep 17 00:00:00 2001 From: Luisa Date: Wed, 10 Jul 2024 13:46:45 +0200 Subject: [PATCH 08/11] Fix account create button --- .../get-user-scope-presenter.service.spec.ts | 74 +++++++++---------- .../account-detail.component.ts | 2 +- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/client/src/app/gateways/presenter/get-user-scope-presenter.service.spec.ts b/client/src/app/gateways/presenter/get-user-scope-presenter.service.spec.ts index af0277b0b6..21484acd66 100644 --- a/client/src/app/gateways/presenter/get-user-scope-presenter.service.spec.ts +++ b/client/src/app/gateways/presenter/get-user-scope-presenter.service.spec.ts @@ -20,9 +20,9 @@ describe(`GetUserScopePresenterService`, () => { 8: { title: `superadmin` } }; - function getExpectedCompareResult(key1: keyof typeof scopeMap, key2: keyof typeof scopeMap): number { - return key1 > key2 ? 1 : -1; - } + // function getExpectedCompareResult(key1: keyof typeof scopeMap, key2: keyof typeof scopeMap): number { + // return key1 > key2 ? 1 : -1; + // } const testScopes: { [key in keyof typeof scopeMap]: any } = { 2: { @@ -82,39 +82,39 @@ describe(`GetUserScopePresenterService`, () => { expect(await service.call({ user_ids: [2, 3, 5, 6, 7, 8] })).toEqual(testScopes); }); - for (const key of Object.keys(scopeMap).map(x => +x as keyof typeof scopeMap)) { - const otherKeys: (keyof typeof scopeMap)[] = Object.keys(scopeMap) - .map(key => +key as keyof typeof scopeMap) - .filter(otherKey => otherKey !== key); - it(`test compareScope with oml comparison for ${scopeMap[key].title}`, async () => { - expect(await service.compareScope(testScopes[key], testScopes[otherKeys[0]], true)).toBe( - getExpectedCompareResult(key, otherKeys[0]) - ); - expect(await service.compareScope(testScopes[key], testScopes[otherKeys[1]], true)).toBe( - getExpectedCompareResult(key, otherKeys[1]) - ); - expect(await service.compareScope(testScopes[key], testScopes[otherKeys[2]], true)).toBe( - getExpectedCompareResult(key, otherKeys[2]) - ); - expect(await service.compareScope(testScopes[key], testScopes[otherKeys[3]], true)).toBe( - getExpectedCompareResult(key, otherKeys[3]) - ); - expect(await service.compareScope(testScopes[key], testScopes[otherKeys[4]], true)).toBe( - getExpectedCompareResult(key, otherKeys[4]) - ); - expect(await service.compareScope(testScopes[key], testScopes[key], true)).toBe(0); - expect(await service.compareScope(testScopes[key], { ...testScopes[key], id: 9 }, true)).toBe(0); - }); - } + // for (const key of Object.keys(scopeMap).map(x => +x as keyof typeof scopeMap)) { + // const otherKeys: (keyof typeof scopeMap)[] = Object.keys(scopeMap) + // .map(key => +key as keyof typeof scopeMap) + // .filter(otherKey => otherKey !== key); + // it(`test compareScope with oml comparison for ${scopeMap[key].title}`, async () => { + // expect(await service.compareScope(testScopes[key], testScopes[otherKeys[0]], true)).toBe( + // getExpectedCompareResult(key, otherKeys[0]) + // ); + // expect(await service.compareScope(testScopes[key], testScopes[otherKeys[1]], true)).toBe( + // getExpectedCompareResult(key, otherKeys[1]) + // ); + // expect(await service.compareScope(testScopes[key], testScopes[otherKeys[2]], true)).toBe( + // getExpectedCompareResult(key, otherKeys[2]) + // ); + // expect(await service.compareScope(testScopes[key], testScopes[otherKeys[3]], true)).toBe( + // getExpectedCompareResult(key, otherKeys[3]) + // ); + // expect(await service.compareScope(testScopes[key], testScopes[otherKeys[4]], true)).toBe( + // getExpectedCompareResult(key, otherKeys[4]) + // ); + // expect(await service.compareScope(testScopes[key], testScopes[key], true)).toBe(0); + // expect(await service.compareScope(testScopes[key], { ...testScopes[key], id: 9 }, true)).toBe(0); + // }); + // } - it(`test compareScope with default settings`, async () => { - expect(await service.compareScope(testScopes[2], testScopes[3])).toBe(-1); - expect(await service.compareScope(testScopes[2], testScopes[5])).toBe(-1); - expect(await service.compareScope(testScopes[3], testScopes[5])).toBe(-1); - expect(await service.compareScope(testScopes[3], testScopes[2])).toBe(1); - expect(await service.compareScope(testScopes[5], testScopes[2])).toBe(1); - expect(await service.compareScope(testScopes[5], testScopes[3])).toBe(1); - expect(await service.compareScope(testScopes[7], testScopes[6])).toBe(0); - expect(await service.compareScope(testScopes[6], testScopes[6])).toBe(0); - }); + // it(`test compareScope with default settings`, async () => { + // expect(await service.compareScope(testScopes[2], testScopes[3])).toBe(-1); + // expect(await service.compareScope(testScopes[2], testScopes[5])).toBe(-1); + // expect(await service.compareScope(testScopes[3], testScopes[5])).toBe(-1); + // expect(await service.compareScope(testScopes[3], testScopes[2])).toBe(1); + // expect(await service.compareScope(testScopes[5], testScopes[2])).toBe(1); + // expect(await service.compareScope(testScopes[5], testScopes[3])).toBe(1); + // expect(await service.compareScope(testScopes[7], testScopes[6])).toBe(0); + // expect(await service.compareScope(testScopes[6], testScopes[6])).toBe(0); + // }); }); diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.ts b/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.ts index 21e3b56cae..96b94ffcc7 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.ts +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-detail/components/account-detail/account-detail.component.ts @@ -90,7 +90,7 @@ export class AccountDetailComponent extends BaseComponent implements OnInit { } public get userOML(): OML { - return this.user.organization_management_level as OML; + return this.user?.organization_management_level as OML; } public get canEdit(): boolean { From 5d7010e56e87a2da01e9790ca640e3803ee1535c Mon Sep 17 00:00:00 2001 From: Luisa Date: Wed, 10 Jul 2024 14:06:11 +0200 Subject: [PATCH 09/11] cleanup --- .../get-user-scope-presenter.service.spec.ts | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/client/src/app/gateways/presenter/get-user-scope-presenter.service.spec.ts b/client/src/app/gateways/presenter/get-user-scope-presenter.service.spec.ts index 21484acd66..4643cd0b94 100644 --- a/client/src/app/gateways/presenter/get-user-scope-presenter.service.spec.ts +++ b/client/src/app/gateways/presenter/get-user-scope-presenter.service.spec.ts @@ -20,10 +20,6 @@ describe(`GetUserScopePresenterService`, () => { 8: { title: `superadmin` } }; - // function getExpectedCompareResult(key1: keyof typeof scopeMap, key2: keyof typeof scopeMap): number { - // return key1 > key2 ? 1 : -1; - // } - const testScopes: { [key in keyof typeof scopeMap]: any } = { 2: { collection: UserScope.MEETING, @@ -81,40 +77,4 @@ describe(`GetUserScopePresenterService`, () => { it(`should correctly call get_user_scope`, async () => { expect(await service.call({ user_ids: [2, 3, 5, 6, 7, 8] })).toEqual(testScopes); }); - - // for (const key of Object.keys(scopeMap).map(x => +x as keyof typeof scopeMap)) { - // const otherKeys: (keyof typeof scopeMap)[] = Object.keys(scopeMap) - // .map(key => +key as keyof typeof scopeMap) - // .filter(otherKey => otherKey !== key); - // it(`test compareScope with oml comparison for ${scopeMap[key].title}`, async () => { - // expect(await service.compareScope(testScopes[key], testScopes[otherKeys[0]], true)).toBe( - // getExpectedCompareResult(key, otherKeys[0]) - // ); - // expect(await service.compareScope(testScopes[key], testScopes[otherKeys[1]], true)).toBe( - // getExpectedCompareResult(key, otherKeys[1]) - // ); - // expect(await service.compareScope(testScopes[key], testScopes[otherKeys[2]], true)).toBe( - // getExpectedCompareResult(key, otherKeys[2]) - // ); - // expect(await service.compareScope(testScopes[key], testScopes[otherKeys[3]], true)).toBe( - // getExpectedCompareResult(key, otherKeys[3]) - // ); - // expect(await service.compareScope(testScopes[key], testScopes[otherKeys[4]], true)).toBe( - // getExpectedCompareResult(key, otherKeys[4]) - // ); - // expect(await service.compareScope(testScopes[key], testScopes[key], true)).toBe(0); - // expect(await service.compareScope(testScopes[key], { ...testScopes[key], id: 9 }, true)).toBe(0); - // }); - // } - - // it(`test compareScope with default settings`, async () => { - // expect(await service.compareScope(testScopes[2], testScopes[3])).toBe(-1); - // expect(await service.compareScope(testScopes[2], testScopes[5])).toBe(-1); - // expect(await service.compareScope(testScopes[3], testScopes[5])).toBe(-1); - // expect(await service.compareScope(testScopes[3], testScopes[2])).toBe(1); - // expect(await service.compareScope(testScopes[5], testScopes[2])).toBe(1); - // expect(await service.compareScope(testScopes[5], testScopes[3])).toBe(1); - // expect(await service.compareScope(testScopes[7], testScopes[6])).toBe(0); - // expect(await service.compareScope(testScopes[6], testScopes[6])).toBe(0); - // }); }); From f7d859073fcfe58c6af640d69b7277e51533ee52 Mon Sep 17 00:00:00 2001 From: Luisa Date: Thu, 11 Jul 2024 16:53:50 +0200 Subject: [PATCH 10/11] Fix detail view, remove merge option for committee admins --- .../user-detail-view/user-detail-view.component.ts | 9 +++++++-- .../components/account-list/account-list.component.html | 7 ++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.ts b/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.ts index 9f0b520a8c..24a4bdfbd9 100644 --- a/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.ts +++ b/client/src/app/site/modules/user-components/components/user-detail-view/user-detail-view.component.ts @@ -317,7 +317,7 @@ export class UserDetailViewComponent extends BaseUiComponent implements OnInit, member_number: [``], is_active: [true], is_physical_person: [true], - ...(this.useAdditionalEditTemplate ? this._additionalFormControls : {}) + ...this._additionalFormControls }; } @@ -347,7 +347,12 @@ export class UserDetailViewComponent extends BaseUiComponent implements OnInit, }; } - private getChangedValues(data: { [key: string]: any }): { [key: string]: any } { + private getChangedValues(formData: { [key: string]: any }): { [key: string]: any } { + const data = this.useAdditionalEditTemplate + ? formData + : Object.keys(formData).mapToObject(key => + Object.keys(this._additionalFormControls ?? {}).includes(key) ? {} : { [key]: formData[key] } + ); const newData = {}; if (this.user) { Object.keys(data).forEach(key => { diff --git a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html index fc587933d0..6067c0ca18 100644 --- a/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html +++ b/client/src/app/site/pages/organization/pages/accounts/pages/account-list/components/account-list/account-list.component.html @@ -181,7 +181,12 @@

block {{ 'Enable/disable accounts' | translate }} ... - From fe952d4cea0f822d7d7acb7a1682153f58c845b4 Mon Sep 17 00:00:00 2001 From: luisa-beerboom <101706784+luisa-beerboom@users.noreply.github.com> Date: Mon, 15 Jul 2024 14:21:50 +0200 Subject: [PATCH 11/11] Update client/src/app/site/pages/meetings/pages/participants/pages/participant-detail/components/participant-detail-view/participant-detail-view.component.ts Co-authored-by: Bastian Rihm --- .../participant-detail-view/participant-detail-view.component.ts | 1 - 1 file changed, 1 deletion(-) 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 4199856d2d..be13c4051d 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 @@ -296,7 +296,6 @@ export class ParticipantDetailViewComponent extends BaseMeetingComponent { public async setEditMode(edit: boolean): Promise { if (!this.newUser && edit) { this._isUserInScope = await this.userService.hasScopeManagePerms(this._userId!); - console.log(`IS IN SCOPE`, this._isUserInScope); } this.isEditingSubject.next(edit);