mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-11 08:35:13 +00:00
feat: add confirmation field for user deletion, self warning (#2971)
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
UserNameQuery,
|
||||
UserState,
|
||||
} from 'src/app/proto/generated/zitadel/user_pb';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
@@ -38,9 +39,7 @@ enum UserListSearchKey {
|
||||
selector: 'cnsl-user-table',
|
||||
templateUrl: './user-table.component.html',
|
||||
styleUrls: ['./user-table.component.scss'],
|
||||
animations: [
|
||||
enterAnimations,
|
||||
],
|
||||
animations: [enterAnimations],
|
||||
})
|
||||
export class UserTableComponent implements OnInit {
|
||||
public userSearchKey: UserListSearchKey | undefined = undefined;
|
||||
@@ -66,6 +65,7 @@ export class UserTableComponent implements OnInit {
|
||||
|
||||
constructor(
|
||||
public translate: TranslateService,
|
||||
private authService: GrpcAuthService,
|
||||
private userService: ManagementService,
|
||||
private toast: ToastService,
|
||||
private dialog: MatDialog,
|
||||
@@ -77,7 +77,7 @@ export class UserTableComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.route.queryParams.pipe(take(1)).subscribe(params => {
|
||||
this.route.queryParams.pipe(take(1)).subscribe((params) => {
|
||||
this.getData(10, 0, this.type);
|
||||
if (params.deferredReload) {
|
||||
setTimeout(() => {
|
||||
@@ -94,43 +94,48 @@ export class UserTableComponent implements OnInit {
|
||||
}
|
||||
|
||||
public masterToggle(): void {
|
||||
this.isAllSelected() ?
|
||||
this.selection.clear() :
|
||||
this.dataSource.data.forEach(row => this.selection.select(row));
|
||||
this.isAllSelected() ? this.selection.clear() : this.dataSource.data.forEach((row) => this.selection.select(row));
|
||||
}
|
||||
|
||||
|
||||
public changePage(event: PageEvent): void {
|
||||
this.selection.clear();
|
||||
this.getData(event.pageSize, event.pageIndex * event.pageSize, this.type);
|
||||
}
|
||||
|
||||
public deactivateSelectedUsers(): void {
|
||||
Promise.all(this.selection.selected.map(value => {
|
||||
return this.userService.deactivateUser(value.id);
|
||||
})).then(() => {
|
||||
this.toast.showInfo('USER.TOAST.SELECTEDDEACTIVATED', true);
|
||||
this.selection.clear();
|
||||
setTimeout(() => {
|
||||
this.refreshPage();
|
||||
}, 1000);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
Promise.all(
|
||||
this.selection.selected.map((value) => {
|
||||
return this.userService.deactivateUser(value.id);
|
||||
}),
|
||||
)
|
||||
.then(() => {
|
||||
this.toast.showInfo('USER.TOAST.SELECTEDDEACTIVATED', true);
|
||||
this.selection.clear();
|
||||
setTimeout(() => {
|
||||
this.refreshPage();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
public reactivateSelectedUsers(): void {
|
||||
Promise.all(this.selection.selected.map(value => {
|
||||
return this.userService.reactivateUser(value.id);
|
||||
})).then(() => {
|
||||
this.toast.showInfo('USER.TOAST.SELECTEDREACTIVATED', true);
|
||||
this.selection.clear();
|
||||
setTimeout(() => {
|
||||
this.refreshPage();
|
||||
}, 1000);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
Promise.all(
|
||||
this.selection.selected.map((value) => {
|
||||
return this.userService.reactivateUser(value.id);
|
||||
}),
|
||||
)
|
||||
.then(() => {
|
||||
this.toast.showInfo('USER.TOAST.SELECTEDREACTIVATED', true);
|
||||
this.selection.clear();
|
||||
setTimeout(() => {
|
||||
this.refreshPage();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
private async getData(limit: number, offset: number, type: Type, searchValue?: string): Promise<void> {
|
||||
@@ -180,21 +185,24 @@ export class UserTableComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
this.userService.listUsers(limit, offset, [query]).then(resp => {
|
||||
if (resp.details?.totalResult) {
|
||||
this.totalResult = resp.details?.totalResult;
|
||||
} else {
|
||||
this.totalResult = 0;
|
||||
}
|
||||
if (resp.details?.viewTimestamp) {
|
||||
this.viewTimestamp = resp.details?.viewTimestamp;
|
||||
}
|
||||
this.dataSource.data = resp.resultList;
|
||||
this.loadingSubject.next(false);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
this.loadingSubject.next(false);
|
||||
});
|
||||
this.userService
|
||||
.listUsers(limit, offset, [query])
|
||||
.then((resp) => {
|
||||
if (resp.details?.totalResult) {
|
||||
this.totalResult = resp.details?.totalResult;
|
||||
} else {
|
||||
this.totalResult = 0;
|
||||
}
|
||||
if (resp.details?.viewTimestamp) {
|
||||
this.viewTimestamp = resp.details?.viewTimestamp;
|
||||
}
|
||||
this.dataSource.data = resp.resultList;
|
||||
this.loadingSubject.next(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
this.loadingSubject.next(false);
|
||||
});
|
||||
}
|
||||
|
||||
public refreshPage(): void {
|
||||
@@ -205,12 +213,7 @@ export class UserTableComponent implements OnInit {
|
||||
this.selection.clear();
|
||||
const filterValue = (event.target as HTMLInputElement).value;
|
||||
|
||||
this.getData(
|
||||
this.paginator.pageSize,
|
||||
this.paginator.pageIndex * this.paginator.pageSize,
|
||||
this.type,
|
||||
filterValue,
|
||||
);
|
||||
this.getData(this.paginator.pageSize, this.paginator.pageIndex * this.paginator.pageSize, this.type, filterValue);
|
||||
}
|
||||
|
||||
public setFilter(key: UserListSearchKey): void {
|
||||
@@ -229,27 +232,57 @@ export class UserTableComponent implements OnInit {
|
||||
}
|
||||
|
||||
public deleteUser(user: User.AsObject): void {
|
||||
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||
data: {
|
||||
confirmKey: 'ACTIONS.DELETE',
|
||||
cancelKey: 'ACTIONS.CANCEL',
|
||||
titleKey: 'USER.DIALOG.DELETE_TITLE',
|
||||
descriptionKey: 'USER.DIALOG.DELETE_DESCRIPTION',
|
||||
},
|
||||
width: '400px',
|
||||
});
|
||||
const authUserData = {
|
||||
confirmKey: 'ACTIONS.DELETE',
|
||||
cancelKey: 'ACTIONS.CANCEL',
|
||||
titleKey: 'USER.DIALOG.DELETE_SELF_TITLE',
|
||||
descriptionKey: 'USER.DIALOG.DELETE_SELF_DESCRIPTION',
|
||||
confirmationKey: 'USER.DIALOG.TYPEUSERNAME',
|
||||
confirmation: user.preferredLoginName,
|
||||
};
|
||||
|
||||
dialogRef.afterClosed().subscribe(resp => {
|
||||
if (resp) {
|
||||
this.userService.removeUser(user.id).then(() => {
|
||||
setTimeout(() => {
|
||||
this.refreshPage();
|
||||
}, 1000);
|
||||
this.toast.showInfo('USER.TOAST.DELETED', true);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
const mgmtUserData = {
|
||||
confirmKey: 'ACTIONS.DELETE',
|
||||
cancelKey: 'ACTIONS.CANCEL',
|
||||
titleKey: 'USER.DIALOG.DELETE_TITLE',
|
||||
descriptionKey: 'USER.DIALOG.DELETE_DESCRIPTION',
|
||||
confirmationKey: 'USER.DIALOG.TYPEUSERNAME',
|
||||
confirmation: user.preferredLoginName,
|
||||
};
|
||||
|
||||
if (user && user.id) {
|
||||
const authUser = this.authService.userSubject.getValue();
|
||||
const isMe = authUser?.id === user.id;
|
||||
|
||||
let dialogRef;
|
||||
|
||||
if (isMe) {
|
||||
dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||
data: authUserData,
|
||||
width: '400px',
|
||||
});
|
||||
} else {
|
||||
dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||
data: mgmtUserData,
|
||||
width: '400px',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((resp) => {
|
||||
if (resp) {
|
||||
this.userService
|
||||
.removeUser(user.id)
|
||||
.then(() => {
|
||||
setTimeout(() => {
|
||||
this.refreshPage();
|
||||
}, 1000);
|
||||
this.toast.showInfo('USER.TOAST.DELETED', true);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user