Browse Source

Various improvements

pull/5538/head
Thomas Kaul 3 months ago
parent
commit
56f991b00a
  1. 61
      apps/api/src/app/endpoints/public/public.controller.ts
  2. 18
      apps/client/src/app/pages/public/public-page.component.ts
  3. 4
      apps/client/src/app/pages/public/public-page.html
  4. 10
      libs/common/src/lib/interfaces/responses/public-portfolio-response.interface.ts

61
apps/api/src/app/endpoints/public/public.controller.ts

@ -1,3 +1,11 @@
import { AccessService } from '@ghostfolio/api/app/access/access.service';
import { OrderService } from '@ghostfolio/api/app/order/order.service';
import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service';
import { UserService } from '@ghostfolio/api/app/user/user.service';
import { RedactValuesInResponseInterceptor } from '@ghostfolio/api/interceptors/redact-values-in-response/redact-values-in-response.interceptor';
import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { getSum } from '@ghostfolio/common/helper'; import { getSum } from '@ghostfolio/common/helper';
import { PublicPortfolioResponse } from '@ghostfolio/common/interfaces'; import { PublicPortfolioResponse } from '@ghostfolio/common/interfaces';
@ -16,15 +24,6 @@ import { Type as ActivityType } from '@prisma/client';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { StatusCodes, getReasonPhrase } from 'http-status-codes';
import { RedactValuesInResponseInterceptor } from '../../../interceptors/redact-values-in-response/redact-values-in-response.interceptor';
import { TransformDataSourceInResponseInterceptor } from '../../../interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor';
import { ConfigurationService } from '../../../services/configuration/configuration.service';
import { ExchangeRateDataService } from '../../../services/exchange-rate-data/exchange-rate-data.service';
import { AccessService } from '../../access/access.service';
import { OrderService } from '../../order/order.service';
import { PortfolioService } from '../../portfolio/portfolio.service';
import { UserService } from '../../user/user.service';
@Controller('public') @Controller('public')
export class PublicController { export class PublicController {
public constructor( public constructor(
@ -87,22 +86,42 @@ export class PublicController {
sortColumn: 'date', sortColumn: 'date',
sortDirection: 'desc', sortDirection: 'desc',
take: 10, take: 10,
types: [ActivityType.BUY, ActivityType.SELL],
userCurrency: user.settings?.settings.baseCurrency ?? DEFAULT_CURRENCY, userCurrency: user.settings?.settings.baseCurrency ?? DEFAULT_CURRENCY,
userId: user.id, userId: user.id,
types: [ActivityType.BUY, ActivityType.SELL],
withExcludedAccountsAndActivities: false withExcludedAccountsAndActivities: false
}); });
const latestActivities = activities.map((a) => ({
currency: a.currency, // Experimental
date: a.date, const latestActivities = this.configurationService.get(
fee: a.fee, 'ENABLE_FEATURE_SUBSCRIPTION'
quantity: a.quantity, )
SymbolProfile: a.SymbolProfile, ? []
type: a.type, : activities.map(
unitPrice: a.unitPrice, ({
value: a.value, currency,
valueInBaseCurrency: a.valueInBaseCurrency date,
})); fee,
quantity,
SymbolProfile,
type,
unitPrice,
value,
valueInBaseCurrency
}) => {
return {
currency,
date,
fee,
quantity,
SymbolProfile,
type,
unitPrice,
value,
valueInBaseCurrency
};
}
);
Object.values(markets ?? {}).forEach((market) => { Object.values(markets ?? {}).forEach((market) => {
delete market.valueInBaseCurrency; delete market.valueInBaseCurrency;

18
apps/client/src/app/pages/public/public-page.component.ts

@ -1,9 +1,12 @@
import { DataService } from '@ghostfolio/client/services/data.service';
import { UNKNOWN_KEY } from '@ghostfolio/common/config'; import { UNKNOWN_KEY } from '@ghostfolio/common/config';
import { prettifySymbol } from '@ghostfolio/common/helper'; import { prettifySymbol } from '@ghostfolio/common/helper';
import { import {
InfoItem,
PortfolioPosition, PortfolioPosition,
PublicPortfolioResponse PublicPortfolioResponse
} from '@ghostfolio/common/interfaces'; } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { Market } from '@ghostfolio/common/types'; import { Market } from '@ghostfolio/common/types';
import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table/activities-table.component'; import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table/activities-table.component';
import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table/holdings-table.component'; import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table/holdings-table.component';
@ -29,8 +32,6 @@ import { DeviceDetectorService } from 'ngx-device-detector';
import { EMPTY, Subject } from 'rxjs'; import { EMPTY, Subject } from 'rxjs';
import { catchError, takeUntil } from 'rxjs/operators'; import { catchError, takeUntil } from 'rxjs/operators';
import { DataService } from '../../services/data.service';
@Component({ @Component({
host: { class: 'page' }, host: { class: 'page' },
imports: [ imports: [
@ -57,7 +58,9 @@ export class GfPublicPageComponent implements OnInit {
}; };
public defaultAlias = $localize`someone`; public defaultAlias = $localize`someone`;
public deviceType: string; public deviceType: string;
public hasPermissionForSubscription: boolean;
public holdings: PublicPortfolioResponse['holdings'][string][]; public holdings: PublicPortfolioResponse['holdings'][string][];
public info: InfoItem;
public latestActivitiesDataSource: MatTableDataSource< public latestActivitiesDataSource: MatTableDataSource<
PublicPortfolioResponse['latestActivities'][0] PublicPortfolioResponse['latestActivities'][0]
>; >;
@ -92,6 +95,13 @@ export class GfPublicPageComponent implements OnInit {
this.activatedRoute.params.subscribe((params) => { this.activatedRoute.params.subscribe((params) => {
this.accessId = params['id']; this.accessId = params['id'];
}); });
this.info = this.dataService.fetchInfo();
this.hasPermissionForSubscription = hasPermission(
this.info?.globalPermissions,
permissions.enableSubscription
);
} }
public ngOnInit() { public ngOnInit() {
@ -113,12 +123,12 @@ export class GfPublicPageComponent implements OnInit {
.subscribe((portfolioPublicDetails) => { .subscribe((portfolioPublicDetails) => {
this.publicPortfolioDetails = portfolioPublicDetails; this.publicPortfolioDetails = portfolioPublicDetails;
this.initializeAnalysisData();
this.latestActivitiesDataSource = new MatTableDataSource( this.latestActivitiesDataSource = new MatTableDataSource(
this.publicPortfolioDetails.latestActivities this.publicPortfolioDetails.latestActivities
); );
this.initializeAnalysisData();
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
}); });
} }

4
apps/client/src/app/pages/public/public-page.html

@ -203,9 +203,9 @@
</div> </div>
</div> </div>
} }
<div class="row"> <div class="row" [ngClass]="{ 'd-none': hasPermissionForSubscription }">
<div class="col-md-12"> <div class="col-md-12">
<mat-card appearance="outlined" class="mb-3"> <mat-card appearance="outlined">
<mat-card-header class="overflow-hidden w-100"> <mat-card-header class="overflow-hidden w-100">
<mat-card-title class="text-truncate" i18n <mat-card-title class="text-truncate" i18n
>Latest activities</mat-card-title >Latest activities</mat-card-title

10
libs/common/src/lib/interfaces/responses/public-portfolio-response.interface.ts

@ -1,7 +1,11 @@
import type { Order } from '@prisma/client'; import {
EnhancedSymbolProfile,
PortfolioDetails,
PortfolioPosition
} from '@ghostfolio/common/interfaces';
import { Market } from '@ghostfolio/common/types';
import { EnhancedSymbolProfile, PortfolioDetails, PortfolioPosition } from '..'; import { Order } from '@prisma/client';
import { Market } from '../../types';
export interface PublicPortfolioResponse extends PublicPortfolioResponseV1 { export interface PublicPortfolioResponse extends PublicPortfolioResponseV1 {
alias?: string; alias?: string;

Loading…
Cancel
Save