mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-01 11:52:15 +00:00
* cli core * update material * imports * schematics * lint * rm ng-qrcode, ngx-quicklink * replace qr code lib * rm shared module as quicklink is removed * lazy loading imports * rm public * chore(deps): bump @grpc/grpc-js from 1.7.1 to 1.8.0 in /console (#4857) Bumps [@grpc/grpc-js](https://github.com/grpc/grpc-node) from 1.7.1 to 1.8.0. - [Release notes](https://github.com/grpc/grpc-node/releases) - [Commits](https://github.com/grpc/grpc-node/compare/v1.7.1...@grpc/[email protected]) --- updated-dependencies: - dependency-name: "@grpc/grpc-js" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump libphonenumber-js from 1.10.13 to 1.10.15 in /console (#4861) Bumps [libphonenumber-js](https://gitlab.com/catamphetamine/libphonenumber-js) from 1.10.13 to 1.10.15. - [Release notes](https://gitlab.com/catamphetamine/libphonenumber-js/tags) - [Changelog](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/CHANGELOG.md) - [Commits](https://gitlab.com/catamphetamine/libphonenumber-js/compare/v1.10.13...v1.10.15) --- updated-dependencies: - dependency-name: libphonenumber-js dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * rxjs * chore(deps): bump engine.io from 6.2.0 to 6.2.1 in /console (#4734) Bumps [engine.io](https://github.com/socketio/engine.io) from 6.2.0 to 6.2.1. - [Release notes](https://github.com/socketio/engine.io/releases) - [Changelog](https://github.com/socketio/engine.io/blob/main/CHANGELOG.md) - [Commits](https://github.com/socketio/engine.io/compare/6.2.0...6.2.1) --- updated-dependencies: - dependency-name: engine.io dependency-type: indirect ... Signed-off-by: dependabot[bot] <[email protected]> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * lock * lint * rm comments * tsconfig ES2022 * get rid of polyfills file * use node 18 * rm age policy, legacy components * packages * build beta prerelease * remove pre-release build Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Florian Forster <[email protected]> Co-authored-by: Livio Spring <[email protected]>
273 lines
10 KiB
TypeScript
273 lines
10 KiB
TypeScript
import { SelectionModel } from '@angular/cdk/collections';
|
|
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
|
|
import { MatLegacyTable as MatTable } from '@angular/material/legacy-table';
|
|
import { Router } from '@angular/router';
|
|
import { Subject } from 'rxjs';
|
|
import { takeUntil } from 'rxjs/operators';
|
|
import { Org } from 'src/app/proto/generated/zitadel/org_pb';
|
|
import { Membership } from 'src/app/proto/generated/zitadel/user_pb';
|
|
import { AdminService } from 'src/app/services/admin.service';
|
|
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
|
import { ManagementService } from 'src/app/services/mgmt.service';
|
|
import { OverlayWorkflowService } from 'src/app/services/overlay/overlay-workflow.service';
|
|
import { OrgContextChangedWorkflowOverlays } from 'src/app/services/overlay/workflows';
|
|
import { StorageLocation, StorageService } from 'src/app/services/storage.service';
|
|
import { ToastService } from 'src/app/services/toast.service';
|
|
import { getMembershipColor } from 'src/app/utils/color';
|
|
|
|
import { PageEvent, PaginatorComponent } from '../paginator/paginator.component';
|
|
import { MembershipsDataSource } from './memberships-datasource';
|
|
|
|
@Component({
|
|
selector: 'cnsl-memberships-table',
|
|
templateUrl: './memberships-table.component.html',
|
|
styleUrls: ['./memberships-table.component.scss'],
|
|
})
|
|
export class MembershipsTableComponent implements OnInit, OnDestroy {
|
|
public INITIALPAGESIZE: number = 25;
|
|
@ViewChild(PaginatorComponent) public paginator!: PaginatorComponent;
|
|
@ViewChild(MatTable) public table!: MatTable<Membership.AsObject>;
|
|
@Input() public userId: string = '';
|
|
public dataSource: MembershipsDataSource = new MembershipsDataSource(this.authService, this.mgmtService);
|
|
public selection: SelectionModel<Membership.AsObject> = new SelectionModel<Membership.AsObject>(true, []);
|
|
|
|
@Output() public changedSelection: EventEmitter<any[]> = new EventEmitter();
|
|
@Output() public deleteMembership: EventEmitter<Membership.AsObject> = new EventEmitter();
|
|
|
|
private destroyed: Subject<void> = new Subject();
|
|
public membershipRoleOptions: string[] = [];
|
|
|
|
public displayedColumns: string[] = ['displayName', 'type', 'rolesList'];
|
|
public membershipToEdit: string = '';
|
|
public loadingRoles: boolean = false;
|
|
|
|
constructor(
|
|
private authService: GrpcAuthService,
|
|
private toastService: ToastService,
|
|
private mgmtService: ManagementService,
|
|
private adminService: AdminService,
|
|
private toast: ToastService,
|
|
private router: Router,
|
|
private workflowService: OverlayWorkflowService,
|
|
private storageService: StorageService,
|
|
) {
|
|
this.selection.changed.pipe(takeUntil(this.destroyed)).subscribe((_) => {
|
|
this.changedSelection.emit(this.selection.selected);
|
|
});
|
|
}
|
|
|
|
public ngOnInit(): void {
|
|
this.changePage(this.paginator);
|
|
}
|
|
|
|
public loadRoles(membership: Membership.AsObject, opened: boolean): void {
|
|
if (opened) {
|
|
this.loadingRoles = true;
|
|
|
|
if (membership.orgId && !membership.projectId && !membership.projectGrantId) {
|
|
this.membershipToEdit = `${membership.orgId}${membership.projectId}${membership.projectGrantId}`;
|
|
this.mgmtService
|
|
.listOrgMemberRoles()
|
|
.then((resp) => {
|
|
this.membershipRoleOptions = resp.resultList;
|
|
this.loadingRoles = false;
|
|
})
|
|
.catch((error) => {
|
|
this.toastService.showError(error);
|
|
this.loadingRoles = false;
|
|
});
|
|
} else if (membership.projectGrantId) {
|
|
this.membershipToEdit = `${membership.orgId}${membership.projectId}${membership.projectGrantId}`;
|
|
this.mgmtService
|
|
.listProjectGrantMemberRoles()
|
|
.then((resp) => {
|
|
this.membershipRoleOptions = resp.resultList;
|
|
this.loadingRoles = false;
|
|
})
|
|
.catch((error) => {
|
|
this.toastService.showError(error);
|
|
this.loadingRoles = false;
|
|
});
|
|
} else if (membership.projectId) {
|
|
this.membershipToEdit = `${membership.orgId}${membership.projectId}${membership.projectGrantId}`;
|
|
this.mgmtService
|
|
.listProjectMemberRoles()
|
|
.then((resp) => {
|
|
this.membershipRoleOptions = resp.resultList;
|
|
this.loadingRoles = false;
|
|
})
|
|
.catch((error) => {
|
|
this.toastService.showError(error);
|
|
this.loadingRoles = false;
|
|
});
|
|
} else if (membership.iam) {
|
|
this.membershipToEdit = `IAM`;
|
|
this.adminService
|
|
.listIAMMemberRoles()
|
|
.then((resp) => {
|
|
console.log(resp);
|
|
this.membershipRoleOptions = resp.rolesList;
|
|
this.loadingRoles = false;
|
|
})
|
|
.catch((error) => {
|
|
this.toastService.showError(error);
|
|
this.loadingRoles = false;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
public goto(membership: Membership.AsObject): void {
|
|
const org: Org.AsObject | null = this.storageService.getItem('organization', StorageLocation.session);
|
|
|
|
if (membership.orgId && !membership.projectId && !membership.projectGrantId) {
|
|
// only shown on auth user, or if currentOrg === resourceOwner
|
|
this.authService
|
|
.getActiveOrg(membership.orgId)
|
|
.then((membershipOrg) => {
|
|
this.router.navigate(['/org/members']).then(() => {
|
|
this.startOrgContextWorkflow(membershipOrg, org);
|
|
});
|
|
})
|
|
.catch(() => {
|
|
this.toast.showInfo('USER.MEMBERSHIPS.NOPERMISSIONTOEDIT', true);
|
|
});
|
|
} else if (membership.projectGrantId && membership.details?.resourceOwner) {
|
|
// only shown on auth user
|
|
this.authService
|
|
.getActiveOrg(membership.details?.resourceOwner)
|
|
.then((membershipOrg) => {
|
|
this.router.navigate(['/granted-projects', membership.projectId, 'grants', membership.projectGrantId]).then(() => {
|
|
this.startOrgContextWorkflow(membershipOrg, org);
|
|
});
|
|
})
|
|
.catch(() => {
|
|
this.toast.showInfo('USER.MEMBERSHIPS.NOPERMISSIONTOEDIT', true);
|
|
});
|
|
} else if (membership.projectId && membership.details?.resourceOwner) {
|
|
// only shown on auth user, or if currentOrg === resourceOwner
|
|
this.authService
|
|
.getActiveOrg(membership.details?.resourceOwner)
|
|
.then((membershipOrg) => {
|
|
this.router.navigate(['/projects', membership.projectId, 'members']).then(() => {
|
|
this.startOrgContextWorkflow(membershipOrg, org);
|
|
});
|
|
})
|
|
.catch(() => {
|
|
this.toast.showInfo('USER.MEMBERSHIPS.NOPERMISSIONTOEDIT', true);
|
|
});
|
|
} else if (membership.iam) {
|
|
// only shown on auth user
|
|
this.router.navigate(['/instance/members']);
|
|
}
|
|
}
|
|
|
|
private startOrgContextWorkflow(membershipOrg: Org.AsObject, currentOrg?: Org.AsObject | null): void {
|
|
if (!currentOrg || (membershipOrg.id && currentOrg.id && currentOrg.id !== membershipOrg.id)) {
|
|
setTimeout(() => {
|
|
this.workflowService.startWorkflow(OrgContextChangedWorkflowOverlays, null);
|
|
}, 1000);
|
|
}
|
|
}
|
|
|
|
public getType(membership: Membership.AsObject): string {
|
|
if (membership.orgId && !membership.projectId && !membership.projectGrantId) {
|
|
return 'Organization';
|
|
} else if (membership.projectGrantId) {
|
|
return 'Project Grant';
|
|
} else if (membership.projectId) {
|
|
return 'Project';
|
|
} else if (membership.iam) {
|
|
return 'IAM';
|
|
} else {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
public ngOnDestroy(): void {
|
|
this.destroyed.next();
|
|
}
|
|
|
|
public isAllSelected(): boolean {
|
|
const numSelected = this.selection.selected.length;
|
|
const numRows = this.dataSource.membershipsSubject.value.length;
|
|
return numSelected === numRows;
|
|
}
|
|
|
|
public masterToggle(): void {
|
|
this.isAllSelected()
|
|
? this.selection.clear()
|
|
: this.dataSource.membershipsSubject.value.forEach((row) => this.selection.select(row));
|
|
}
|
|
|
|
public changePage(event?: PageEvent): any {
|
|
this.selection.clear();
|
|
return this.userId
|
|
? this.dataSource.loadMemberships(this.userId, event?.pageIndex ?? 0, event?.pageSize ?? this.INITIALPAGESIZE)
|
|
: this.dataSource.loadMyMemberships(event?.pageIndex ?? 0, event?.pageSize ?? this.INITIALPAGESIZE);
|
|
}
|
|
|
|
public isCurrentMembership(membership: Membership.AsObject): boolean {
|
|
return (
|
|
this.membershipToEdit ===
|
|
(membership.iam ? 'IAM' : `${membership.orgId}${membership.projectId}${membership.projectGrantId}`)
|
|
);
|
|
}
|
|
|
|
public getColor(role: string): string {
|
|
const color = getMembershipColor(role);
|
|
return color[500];
|
|
}
|
|
|
|
public removeRole(membership: Membership.AsObject, role: string): void {
|
|
const newRoles = Object.assign([], membership.rolesList);
|
|
const index = newRoles.findIndex((r) => r === role);
|
|
if (index > -1) {
|
|
newRoles.splice(index);
|
|
if (membership.orgId) {
|
|
console.log('org member', membership.userId, newRoles);
|
|
this.mgmtService
|
|
.updateOrgMember(membership.userId, newRoles)
|
|
.then(() => {
|
|
this.toast.showInfo('USER.MEMBERSHIPS.UPDATED', true);
|
|
this.changePage(this.paginator);
|
|
})
|
|
.catch((error) => {
|
|
this.toastService.showError(error);
|
|
});
|
|
} else if (membership.projectGrantId) {
|
|
this.mgmtService
|
|
.updateProjectGrantMember(membership.projectId, membership.projectGrantId, membership.userId, newRoles)
|
|
.then(() => {
|
|
this.toast.showInfo('USER.MEMBERSHIPS.UPDATED', true);
|
|
this.changePage(this.paginator);
|
|
})
|
|
.catch((error) => {
|
|
this.toastService.showError(error);
|
|
});
|
|
} else if (membership.projectId) {
|
|
console.log(membership.projectId, membership.userId, newRoles);
|
|
this.mgmtService
|
|
.updateProjectMember(membership.projectId, membership.userId, newRoles)
|
|
.then(() => {
|
|
this.toast.showInfo('USER.MEMBERSHIPS.UPDATED', true);
|
|
this.changePage(this.paginator);
|
|
})
|
|
.catch((error) => {
|
|
this.toastService.showError(error);
|
|
});
|
|
} else if (membership.iam) {
|
|
this.adminService
|
|
.updateIAMMember(membership.userId, newRoles)
|
|
.then(() => {
|
|
this.toast.showInfo('USER.MEMBERSHIPS.UPDATED', true);
|
|
this.changePage(this.paginator);
|
|
})
|
|
.catch((error) => {
|
|
this.toastService.showError(error);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|