Various improvements (#807)
This commit is contained in:
parent
52d113e71f
commit
2a854e2574
@ -320,6 +320,16 @@ export class PortfolioController {
|
|||||||
public async getSummary(
|
public async getSummary(
|
||||||
@Headers('impersonation-id') impersonationId
|
@Headers('impersonation-id') impersonationId
|
||||||
): Promise<PortfolioSummary> {
|
): Promise<PortfolioSummary> {
|
||||||
|
if (
|
||||||
|
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
|
||||||
|
this.request.user.subscription.type === 'Basic'
|
||||||
|
) {
|
||||||
|
throw new HttpException(
|
||||||
|
getReasonPhrase(StatusCodes.FORBIDDEN),
|
||||||
|
StatusCodes.FORBIDDEN
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let summary = await this.portfolioServiceStrategy
|
let summary = await this.portfolioServiceStrategy
|
||||||
.get()
|
.get()
|
||||||
.getSummary(impersonationId);
|
.getSummary(impersonationId);
|
||||||
|
@ -67,7 +67,7 @@ export class UserService {
|
|||||||
settings: {
|
settings: {
|
||||||
...(<UserSettings>Settings.settings),
|
...(<UserSettings>Settings.settings),
|
||||||
baseCurrency: Settings?.currency ?? UserService.DEFAULT_CURRENCY,
|
baseCurrency: Settings?.currency ?? UserService.DEFAULT_CURRENCY,
|
||||||
locale: (<UserSettings>Settings.settings).locale ?? aLocale,
|
locale: (<UserSettings>Settings.settings)?.locale ?? aLocale,
|
||||||
viewMode: Settings?.viewMode ?? ViewMode.DEFAULT
|
viewMode: Settings?.viewMode ?? ViewMode.DEFAULT
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -70,9 +70,10 @@ export class PortfolioPerformanceComponent implements OnChanges, OnInit {
|
|||||||
'value',
|
'value',
|
||||||
this.performance?.currentNetPerformancePercent * 100,
|
this.performance?.currentNetPerformancePercent * 100,
|
||||||
{
|
{
|
||||||
|
decimal: getNumberFormatDecimal(this.locale),
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
duration: 0.75,
|
duration: 1,
|
||||||
separator: `'`
|
separator: getNumberFormatGroup(this.locale)
|
||||||
}
|
}
|
||||||
).start();
|
).start();
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,14 @@ import { DataService } from '@ghostfolio/client/services/data.service';
|
|||||||
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
|
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
|
||||||
import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service';
|
import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service';
|
||||||
import { InfoItem } from '@ghostfolio/common/interfaces';
|
import { InfoItem } from '@ghostfolio/common/interfaces';
|
||||||
|
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
|
||||||
import { StatusCodes } from 'http-status-codes';
|
import { StatusCodes } from 'http-status-codes';
|
||||||
import { Observable, throwError } from 'rxjs';
|
import { Observable, throwError } from 'rxjs';
|
||||||
import { catchError, tap } from 'rxjs/operators';
|
import { catchError, tap } from 'rxjs/operators';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class HttpResponseInterceptor implements HttpInterceptor {
|
export class HttpResponseInterceptor implements HttpInterceptor {
|
||||||
|
public hasPermissionForSubscription: boolean;
|
||||||
public info: InfoItem;
|
public info: InfoItem;
|
||||||
public snackBarRef: MatSnackBarRef<TextOnlySnackBar>;
|
public snackBarRef: MatSnackBarRef<TextOnlySnackBar>;
|
||||||
|
|
||||||
@ -34,6 +36,11 @@ export class HttpResponseInterceptor implements HttpInterceptor {
|
|||||||
private webAuthnService: WebAuthnService
|
private webAuthnService: WebAuthnService
|
||||||
) {
|
) {
|
||||||
this.info = this.dataService.fetchInfo();
|
this.info = this.dataService.fetchInfo();
|
||||||
|
|
||||||
|
this.hasPermissionForSubscription = hasPermission(
|
||||||
|
this.info?.globalPermissions,
|
||||||
|
permissions.enableSubscription
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public intercept(
|
public intercept(
|
||||||
@ -56,7 +63,7 @@ export class HttpResponseInterceptor implements HttpInterceptor {
|
|||||||
} else {
|
} else {
|
||||||
this.snackBarRef = this.snackBar.open(
|
this.snackBarRef = this.snackBar.open(
|
||||||
'This feature requires a subscription.',
|
'This feature requires a subscription.',
|
||||||
'Upgrade Plan',
|
this.hasPermissionForSubscription ? 'Upgrade Plan' : undefined,
|
||||||
{ duration: 6000 }
|
{ duration: 6000 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
<h4 class="align-items-center d-flex">
|
<h4 class="align-items-center d-flex">
|
||||||
<span i18n>Allocations</span>
|
<span i18n>Allocations</span>
|
||||||
<ion-icon
|
<ion-icon
|
||||||
*ngIf="hasPermissionForSubscription"
|
*ngIf="user?.subscription?.type === 'Basic'"
|
||||||
class="ml-1 text-muted"
|
class="ml-1 text-muted"
|
||||||
name="diamond-outline"
|
name="diamond-outline"
|
||||||
></ion-icon>
|
></ion-icon>
|
||||||
@ -38,7 +38,6 @@
|
|||||||
<a
|
<a
|
||||||
color="primary"
|
color="primary"
|
||||||
mat-button
|
mat-button
|
||||||
[disabled]="hasPermissionForSubscription && user?.settings?.viewMode !== 'DEFAULT'"
|
|
||||||
[routerLink]="['/portfolio', 'allocations']"
|
[routerLink]="['/portfolio', 'allocations']"
|
||||||
>
|
>
|
||||||
<span i18n>Open Allocations</span>
|
<span i18n>Open Allocations</span>
|
||||||
@ -52,7 +51,7 @@
|
|||||||
<h4 class="align-items-center d-flex">
|
<h4 class="align-items-center d-flex">
|
||||||
<span i18n>Analysis</span>
|
<span i18n>Analysis</span>
|
||||||
<ion-icon
|
<ion-icon
|
||||||
*ngIf="hasPermissionForSubscription"
|
*ngIf="user?.subscription?.type === 'Basic'"
|
||||||
class="ml-1 text-muted"
|
class="ml-1 text-muted"
|
||||||
name="diamond-outline"
|
name="diamond-outline"
|
||||||
></ion-icon>
|
></ion-icon>
|
||||||
@ -65,7 +64,6 @@
|
|||||||
<a
|
<a
|
||||||
color="primary"
|
color="primary"
|
||||||
mat-button
|
mat-button
|
||||||
[disabled]="hasPermissionForSubscription && user?.settings?.viewMode !== 'DEFAULT'"
|
|
||||||
[routerLink]="['/portfolio', 'analysis']"
|
[routerLink]="['/portfolio', 'analysis']"
|
||||||
>
|
>
|
||||||
<span i18n>Open Analysis</span>
|
<span i18n>Open Analysis</span>
|
||||||
@ -79,7 +77,7 @@
|
|||||||
<h4 class="align-items-center d-flex">
|
<h4 class="align-items-center d-flex">
|
||||||
<span i18n>X-ray</span>
|
<span i18n>X-ray</span>
|
||||||
<ion-icon
|
<ion-icon
|
||||||
*ngIf="hasPermissionForSubscription"
|
*ngIf="user?.subscription?.type === 'Basic'"
|
||||||
class="ml-1 text-muted"
|
class="ml-1 text-muted"
|
||||||
name="diamond-outline"
|
name="diamond-outline"
|
||||||
></ion-icon>
|
></ion-icon>
|
||||||
@ -89,12 +87,7 @@
|
|||||||
risks in your portfolio.
|
risks in your portfolio.
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 text-right">
|
<div class="mt-2 text-right">
|
||||||
<a
|
<a color="primary" mat-button [routerLink]="['/portfolio', 'report']">
|
||||||
color="primary"
|
|
||||||
mat-button
|
|
||||||
[disabled]="hasPermissionForSubscription && user?.settings?.viewMode !== 'DEFAULT'"
|
|
||||||
[routerLink]="['/portfolio', 'report']"
|
|
||||||
>
|
|
||||||
<span i18n>Open X-ray</span>
|
<span i18n>Open X-ray</span>
|
||||||
<ion-icon class="ml-1" name="arrow-forward-outline"></ion-icon>
|
<ion-icon class="ml-1" name="arrow-forward-outline"></ion-icon>
|
||||||
</a>
|
</a>
|
||||||
@ -106,7 +99,7 @@
|
|||||||
<h4 class="align-items-center d-flex">
|
<h4 class="align-items-center d-flex">
|
||||||
<span i18n>FIRE</span>
|
<span i18n>FIRE</span>
|
||||||
<ion-icon
|
<ion-icon
|
||||||
*ngIf="hasPermissionForSubscription"
|
*ngIf="user?.subscription?.type === 'Basic'"
|
||||||
class="ml-1 text-muted"
|
class="ml-1 text-muted"
|
||||||
name="diamond-outline"
|
name="diamond-outline"
|
||||||
></ion-icon>
|
></ion-icon>
|
||||||
@ -116,12 +109,7 @@
|
|||||||
<i>Financial Independence, Retire Early</i> lifestyle.
|
<i>Financial Independence, Retire Early</i> lifestyle.
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 text-right">
|
<div class="mt-2 text-right">
|
||||||
<a
|
<a color="primary" mat-button [routerLink]="['/portfolio', 'fire']">
|
||||||
color="primary"
|
|
||||||
mat-button
|
|
||||||
[disabled]="hasPermissionForSubscription && user?.settings?.viewMode !== 'DEFAULT'"
|
|
||||||
[routerLink]="['/portfolio', 'fire']"
|
|
||||||
>
|
|
||||||
<span i18n>Open FIRE</span>
|
<span i18n>Open FIRE</span>
|
||||||
<ion-icon class="ml-1" name="arrow-forward-outline"></ion-icon>
|
<ion-icon class="ml-1" name="arrow-forward-outline"></ion-icon>
|
||||||
</a>
|
</a>
|
||||||
|
@ -119,5 +119,9 @@ export class ValueComponent implements OnChanges {
|
|||||||
if (this.formattedValue === '0.00') {
|
if (this.formattedValue === '0.00') {
|
||||||
this.useAbsoluteValue = true;
|
this.useAbsoluteValue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.isPercent) {
|
||||||
|
this.formattedValue = '– ';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user