Browse Source

Merge f9b47b4de1 into 7dc74fe681

pull/5839/merge
H_S 2 days ago
committed by GitHub
parent
commit
36e018f61a
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 11
      CHANGELOG.md
  2. 80
      apps/client/src/app/components/admin-users/admin-users.component.ts
  3. 6
      apps/client/src/app/pages/admin/admin-page.routes.ts

11
CHANGELOG.md

@ -7,17 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased ## Unreleased
### Added
- Added a close holding button to the holding detail dialog
- Extended the user detail dialog in the users section of the admin control panel
### Changed
- Refactored the generation of the holdings table in the _Copy AI prompt to clipboard for analysis_ action on the analysis page (experimental)
- Refactored the generation of the holdings table in the _Copy portfolio data to clipboard for AI prompt_ action on the analysis page (experimental)
- Improved the language localization for German (`de`)
### Fixed ### Fixed
- Ensured the locale is available in the settings dialog to customize the rule thresholds of the _X-ray_ page - Ensured the locale is available in the settings dialog to customize the rule thresholds of the _X-ray_ page

80
apps/client/src/app/components/admin-users/admin-users.component.ts

@ -133,14 +133,6 @@ export class GfAdminUsersComponent implements OnDestroy, OnInit {
]; ];
} }
this.route.queryParams
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((params) => {
if (params['userDetailDialog'] && params['userId']) {
this.openUserDetailDialog(params['userId']);
}
});
this.userService.stateChanged this.userService.stateChanged
.pipe(takeUntil(this.unsubscribeSubject)) .pipe(takeUntil(this.unsubscribeSubject))
.subscribe((state) => { .subscribe((state) => {
@ -169,6 +161,23 @@ export class GfAdminUsersComponent implements OnDestroy, OnInit {
public ngOnInit() { public ngOnInit() {
this.fetchUsers(); this.fetchUsers();
// Handle route parameter changes when component is reused
this.route.params
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((params) => {
if (params['userId']) {
// If data is already loaded, open dialog immediately
if (this.dataSource.data.length > 0) {
this.openUserDetailDialog(params['userId']);
} else {
// If data is not loaded yet, wait for it to load
this.fetchUsers().then(() => {
this.openUserDetailDialog(params['userId']);
});
}
}
});
} }
public formatDistanceToNow(aDateString: string) { public formatDistanceToNow(aDateString: string) {
@ -245,9 +254,7 @@ export class GfAdminUsersComponent implements OnDestroy, OnInit {
} }
public onOpenUserDetailDialog(userId: string) { public onOpenUserDetailDialog(userId: string) {
this.router.navigate([], { this.router.navigate(['./', userId], { relativeTo: this.route });
queryParams: { userId, userDetailDialog: true }
});
} }
public ngOnDestroy() { public ngOnDestroy() {
@ -255,50 +262,51 @@ export class GfAdminUsersComponent implements OnDestroy, OnInit {
this.unsubscribeSubject.complete(); this.unsubscribeSubject.complete();
} }
private fetchUsers({ pageIndex }: { pageIndex: number } = { pageIndex: 0 }) { private fetchUsers(
{ pageIndex }: { pageIndex: number } = { pageIndex: 0 }
): Promise<void> {
this.isLoading = true; this.isLoading = true;
if (pageIndex === 0 && this.paginator) { if (pageIndex === 0 && this.paginator) {
this.paginator.pageIndex = 0; this.paginator.pageIndex = 0;
} }
this.adminService return new Promise((resolve) => {
.fetchUsers({ this.adminService
skip: pageIndex * this.pageSize, .fetchUsers({
take: this.pageSize skip: pageIndex * this.pageSize,
}) take: this.pageSize
.pipe(takeUntil(this.unsubscribeSubject)) })
.subscribe(({ count, users }) => { .pipe(takeUntil(this.unsubscribeSubject))
this.dataSource = new MatTableDataSource(users); .subscribe(({ count, users }) => {
this.totalItems = count; this.dataSource = new MatTableDataSource(users);
this.totalItems = count;
this.isLoading = false;
this.isLoading = false;
this.changeDetectorRef.markForCheck();
}); this.changeDetectorRef.markForCheck();
resolve();
});
});
} }
private openUserDetailDialog(aUserId: string) { private openUserDetailDialog(userId: string) {
const userData = this.dataSource.data.find(({ id }) => { const userData = this.dataSource.data.find(({ id }) => {
return id === aUserId; return id === userId;
}); });
if (!userData) { if (!userData) {
this.router.navigate(['.'], { relativeTo: this.route }); this.router.navigate(['../'], { relativeTo: this.route });
return; return;
} }
const dialogRef = this.dialog.open< const dialogRef = this.dialog.open(GfUserDetailDialogComponent, {
GfUserDetailDialogComponent,
UserDetailDialogParams
>(GfUserDetailDialogComponent, {
autoFocus: false, autoFocus: false,
data: { data: {
userData, userData,
deviceType: this.deviceType, deviceType: this.deviceType,
hasPermissionForSubscription: this.hasPermissionForSubscription,
locale: this.user?.settings?.locale locale: this.user?.settings?.locale
}, } as UserDetailDialogParams,
height: this.deviceType === 'mobile' ? '98vh' : '60vh', height: this.deviceType === 'mobile' ? '98vh' : '60vh',
width: this.deviceType === 'mobile' ? '100vw' : '50rem' width: this.deviceType === 'mobile' ? '100vw' : '50rem'
}); });
@ -308,7 +316,7 @@ export class GfAdminUsersComponent implements OnDestroy, OnInit {
.pipe(takeUntil(this.unsubscribeSubject)) .pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => { .subscribe(() => {
this.fetchUsers(); this.fetchUsers();
this.router.navigate(['.'], { relativeTo: this.route }); this.router.navigate(['../'], { relativeTo: this.route });
}); });
} }
} }

6
apps/client/src/app/pages/admin/admin-page.routes.ts

@ -38,6 +38,12 @@ export const routes: Routes = [
path: internalRoutes.adminControl.subRoutes.users.path, path: internalRoutes.adminControl.subRoutes.users.path,
component: GfAdminUsersComponent, component: GfAdminUsersComponent,
title: internalRoutes.adminControl.subRoutes.users.title title: internalRoutes.adminControl.subRoutes.users.title
},
{
path: `${internalRoutes.adminControl.subRoutes.users.path}/:userId`,
component: GfAdminUsersComponent,
title: internalRoutes.adminControl.subRoutes.users.title,
runGuardsAndResolvers: 'paramsOrQueryParamsChange'
} }
], ],
component: AdminPageComponent, component: AdminPageComponent,

Loading…
Cancel
Save