Browse Source

Merge branch 'main' into task/restrict-support-for-filtering-to-public-access-for-portfolio-sharing

pull/7753/head
Thomas Kaul 6 hours ago
committed by GitHub
parent
commit
5f1a158dcb
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      CHANGELOG.md
  2. 3
      apps/client/src/app/app.component.ts
  3. 95
      apps/client/src/app/pages/accounts/accounts-page.component.ts
  4. 2
      apps/client/src/locales/messages.de.xlf

2
CHANGELOG.md

@ -9,11 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Added the support for the filters of the assistant to the accounts page
- Extended the `GET api/v1/account` endpoint by the filters `accounts`, `assetClasses` and `tags` - Extended the `GET api/v1/account` endpoint by the filters `accounts`, `assetClasses` and `tags`
### Changed ### Changed
- Restricted the support for filtering to the public access to share the portfolio (experimental) - Restricted the support for filtering to the public access to share the portfolio (experimental)
- Improved the language localization for German (`de`)
### Fixed ### Fixed

3
apps/client/src/app/app.component.ts

@ -147,6 +147,9 @@ export class GfAppComponent implements OnInit {
} }
if ( if (
(this.currentRoute === internalRoutes.accounts.path &&
this.currentSubRoute !==
internalRoutes.accounts.subRoutes.create.path) ||
(this.currentRoute === internalRoutes.home.path && (this.currentRoute === internalRoutes.home.path &&
this.currentSubRoute === this.currentSubRoute ===
internalRoutes.home.subRoutes?.holdings.path) || internalRoutes.home.subRoutes?.holdings.path) ||

95
apps/client/src/app/pages/accounts/accounts-page.component.ts

@ -1,7 +1,7 @@
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
import { UserService } from '@ghostfolio/client/services/user/user.service'; import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TransferBalanceDto } from '@ghostfolio/common/dtos'; import { TransferBalanceDto } from '@ghostfolio/common/dtos';
import { User } from '@ghostfolio/common/interfaces'; import { AccountsResponse, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { internalRoutes } from '@ghostfolio/common/routes/routes'; import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { hasScope, scopes } from '@ghostfolio/common/scopes'; import { hasScope, scopes } from '@ghostfolio/common/scopes';
@ -24,7 +24,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router, RouterModule } from '@angular/router'; import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { DeviceDetectorService } from 'ngx-device-detector'; import { DeviceDetectorService } from 'ngx-device-detector';
import { EMPTY } from 'rxjs'; import { filter, of, switchMap, tap } from 'rxjs';
import { catchError } from 'rxjs/operators'; import { catchError } from 'rxjs/operators';
import { TransferBalanceDialogParams } from './transfer-balance/interfaces/interfaces'; import { TransferBalanceDialogParams } from './transfer-balance/interfaces/interfaces';
@ -39,7 +39,7 @@ import { GfTransferBalanceDialogComponent } from './transfer-balance/transfer-ba
templateUrl: './accounts-page.html' templateUrl: './accounts-page.html'
}) })
export class GfAccountsPageComponent implements OnInit { export class GfAccountsPageComponent implements OnInit {
protected accounts: AccountWithValue[]; protected accounts: AccountWithValue[] | undefined;
protected activitiesCount = 0; protected activitiesCount = 0;
protected hasPermissionToCreateAccount: boolean; protected hasPermissionToCreateAccount: boolean;
protected hasPermissionToDeleteAccount: boolean; protected hasPermissionToDeleteAccount: boolean;
@ -50,7 +50,6 @@ export class GfAccountsPageComponent implements OnInit {
protected user: User; protected user: User;
private hasImpersonationId: boolean; private hasImpersonationId: boolean;
private isInitialFetch = true;
private readonly deviceType = computed( private readonly deviceType = computed(
() => this.deviceDetectorService.deviceInfo().deviceType () => this.deviceDetectorService.deviceInfo().deviceType
@ -88,9 +87,11 @@ export class GfAccountsPageComponent implements OnInit {
}); });
this.userService.stateChanged this.userService.stateChanged
.pipe(takeUntilDestroyed(this.destroyRef)) .pipe(
.subscribe((state) => { filter((state) => {
if (state?.user) { return !!state?.user;
}),
tap((state) => {
this.user = state.user; this.user = state.user;
this.hasPermissionToCreateAccount = this.hasPermissionToCreateAccount =
@ -105,10 +106,15 @@ export class GfAccountsPageComponent implements OnInit {
hasPermission(this.user.permissions, permissions.updateAccount) && hasPermission(this.user.permissions, permissions.updateAccount) &&
hasScope(this.user.scopes, scopes.accountUpdate); hasScope(this.user.scopes, scopes.accountUpdate);
this.fetchAccounts(); this.reset();
}
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
}),
switchMap(() => this.fetchAccounts()),
takeUntilDestroyed(this.destroyRef)
)
.subscribe((response) => {
this.updateAccounts(response);
}); });
} }
@ -133,37 +139,9 @@ export class GfAccountsPageComponent implements OnInit {
} }
private fetchAccounts() { private fetchAccounts() {
this.dataService return this.dataService.fetchAccounts({
.fetchAccounts() filters: this.userService.getFilters()
.pipe(takeUntilDestroyed(this.destroyRef)) });
.subscribe(
({
accounts,
activitiesCount,
totalBalanceInBaseCurrency,
totalValueInBaseCurrency
}) => {
this.accounts = accounts;
this.activitiesCount = activitiesCount;
this.totalBalanceInBaseCurrency = totalBalanceInBaseCurrency;
this.totalValueInBaseCurrency = totalValueInBaseCurrency;
if (
!this.hasImpersonationId &&
this.accounts?.length <= 0 &&
this.hasPermissionToCreateAccount &&
this.isInitialFetch
) {
void this.router.navigate(
internalRoutes.accounts.subRoutes.create.routerLink
);
}
this.isInitialFetch = false;
this.changeDetectorRef.markForCheck();
}
);
} }
private openTransferBalanceDialog() { private openTransferBalanceDialog() {
@ -172,7 +150,7 @@ export class GfAccountsPageComponent implements OnInit {
TransferBalanceDialogParams TransferBalanceDialogParams
>(GfTransferBalanceDialogComponent, { >(GfTransferBalanceDialogComponent, {
data: { data: {
accounts: this.accounts accounts: this.user?.accounts
}, },
width: this.deviceType() === 'mobile' ? '100vw' : '50rem' width: this.deviceType() === 'mobile' ? '100vw' : '50rem'
}); });
@ -199,12 +177,13 @@ export class GfAccountsPageComponent implements OnInit {
title: $localize`Oops, cash balance transfer has failed.` title: $localize`Oops, cash balance transfer has failed.`
}); });
return EMPTY; return of(undefined);
}), }),
switchMap(() => this.fetchAccounts()),
takeUntilDestroyed(this.destroyRef) takeUntilDestroyed(this.destroyRef)
) )
.subscribe(() => { .subscribe((response) => {
this.fetchAccounts(); this.updateAccounts(response);
}); });
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
@ -215,9 +194,33 @@ export class GfAccountsPageComponent implements OnInit {
} }
private reset() { private reset() {
this.accounts = []; this.accounts = undefined;
this.activitiesCount = 0; this.activitiesCount = 0;
this.totalBalanceInBaseCurrency = 0; this.totalBalanceInBaseCurrency = 0;
this.totalValueInBaseCurrency = 0; this.totalValueInBaseCurrency = 0;
} }
private updateAccounts({
accounts,
activitiesCount,
totalBalanceInBaseCurrency,
totalValueInBaseCurrency
}: AccountsResponse) {
this.accounts = accounts;
this.activitiesCount = activitiesCount;
this.totalBalanceInBaseCurrency = totalBalanceInBaseCurrency;
this.totalValueInBaseCurrency = totalValueInBaseCurrency;
if (
!this.hasImpersonationId &&
this.hasPermissionToCreateAccount &&
this.user?.accounts?.length === 0
) {
void this.router.navigate(
internalRoutes.accounts.subRoutes.create.routerLink
);
}
this.changeDetectorRef.markForCheck();
}
} }

2
apps/client/src/locales/messages.de.xlf

@ -2199,7 +2199,7 @@
</trans-unit> </trans-unit>
<trans-unit id="4882027922359285902" datatype="html"> <trans-unit id="4882027922359285902" datatype="html">
<source>Restricted view and manage</source> <source>Restricted view and manage</source>
<target state="new">Restricted view and manage</target> <target state="translated">Eingeschränkte Ansicht und Verwaltung</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/access-level-icon/access-level-icon.component.html</context> <context context-type="sourcefile">libs/ui/src/lib/access-level-icon/access-level-icon.component.html</context>
<context context-type="linenumber">5</context> <context context-type="linenumber">5</context>

Loading…
Cancel
Save