Browse Source

Feature/remove exchange rates from admin control overview (#4439)

* Remove exchange rates

* Update changelog
pull/4441/head^2
Thomas Kaul 5 days ago
committed by GitHub
parent
commit
b90e3076d0
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 28
      apps/api/src/app/admin/admin.service.ts
  3. 44
      apps/client/src/app/components/admin-overview/admin-overview.component.ts
  4. 67
      apps/client/src/app/components/admin-overview/admin-overview.html
  5. 7
      libs/common/src/lib/interfaces/admin-data.interface.ts

1
CHANGELOG.md

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improved the usability of the user account registration
- Improved the usability of the _Copy AI prompt to clipboard_ actions on the analysis page (experimental)
- Removed the exchange rates from the overview of the admin control panel
- Improved the language localization for German (`de`)
- Upgraded `angular` from version `19.0.5` to `19.2.1`
- Upgraded `Nx` from version `20.3.2` to `20.5.0`

28
apps/api/src/app/admin/admin.service.ts

@ -10,7 +10,6 @@ import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
import {
DEFAULT_CURRENCY,
PROPERTY_CURRENCIES,
PROPERTY_IS_READ_ONLY_MODE,
PROPERTY_IS_USER_SIGNUP_ENABLED
@ -37,7 +36,6 @@ import { BadRequestException, Injectable, Logger } from '@nestjs/common';
import {
AssetClass,
AssetSubClass,
DataSource,
Prisma,
PrismaClient,
Property,
@ -132,31 +130,6 @@ export class AdminService {
}
public async get(): Promise<AdminData> {
const exchangeRates = this.exchangeRateDataService
.getCurrencies()
.filter((currency) => {
return currency !== DEFAULT_CURRENCY;
})
.map((currency) => {
const label1 = DEFAULT_CURRENCY;
const label2 = currency;
return {
label1,
label2,
dataSource:
DataSource[
this.configurationService.get('DATA_SOURCE_EXCHANGE_RATES')
],
symbol: `${label1}${label2}`,
value: this.exchangeRateDataService.toCurrency(
1,
DEFAULT_CURRENCY,
currency
)
};
});
const [settings, transactionCount, userCount] = await Promise.all([
this.propertyService.get(),
this.prismaService.order.count(),
@ -164,7 +137,6 @@ export class AdminService {
]);
return {
exchangeRates,
settings,
transactionCount,
userCount,

44
apps/client/src/app/components/admin-overview/admin-overview.component.ts

@ -6,7 +6,6 @@ import { DataService } from '@ghostfolio/client/services/data.service';
import { UserService } from '@ghostfolio/client/services/user/user.service';
import {
PROPERTY_COUPONS,
PROPERTY_CURRENCIES,
PROPERTY_IS_DATA_GATHERING_ENABLED,
PROPERTY_IS_READ_ONLY_MODE,
PROPERTY_IS_USER_SIGNUP_ENABLED,
@ -41,8 +40,6 @@ import { takeUntil } from 'rxjs/operators';
export class AdminOverviewComponent implements OnDestroy, OnInit {
public couponDuration: StringValue = '14 days';
public coupons: Coupon[];
public customCurrencies: string[];
public exchangeRates: { label1: string; label2: string; value: number }[];
public hasPermissionForSubscription: boolean;
public hasPermissionForSystemMessage: boolean;
public hasPermissionToToggleReadOnlyMode: boolean;
@ -138,19 +135,6 @@ export class AdminOverviewComponent implements OnDestroy, OnInit {
});
}
public onDeleteCurrency(aCurrency: string) {
this.notificationService.confirm({
confirmFn: () => {
const currencies = this.customCurrencies.filter((currency) => {
return currency !== aCurrency;
});
this.putAdminSetting({ key: PROPERTY_CURRENCIES, value: currencies });
},
confirmType: ConfirmationDialogType.Warn,
title: $localize`Do you really want to delete this currency?`
});
}
public onDeleteSystemMessage() {
this.notificationService.confirm({
confirmFn: () => {
@ -231,25 +215,17 @@ export class AdminOverviewComponent implements OnDestroy, OnInit {
this.adminService
.fetchAdminData()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(
({ exchangeRates, settings, transactionCount, userCount, version }) => {
this.coupons = (settings[PROPERTY_COUPONS] as Coupon[]) ?? [];
this.customCurrencies = settings[PROPERTY_CURRENCIES] as string[];
this.exchangeRates = exchangeRates;
this.isDataGatheringEnabled =
settings[PROPERTY_IS_DATA_GATHERING_ENABLED] === false
? false
: true;
this.systemMessage = settings[
PROPERTY_SYSTEM_MESSAGE
] as SystemMessage;
this.transactionCount = transactionCount;
this.userCount = userCount;
this.version = version;
.subscribe(({ settings, transactionCount, userCount, version }) => {
this.coupons = (settings[PROPERTY_COUPONS] as Coupon[]) ?? [];
this.isDataGatheringEnabled =
settings[PROPERTY_IS_DATA_GATHERING_ENABLED] === false ? false : true;
this.systemMessage = settings[PROPERTY_SYSTEM_MESSAGE] as SystemMessage;
this.transactionCount = transactionCount;
this.userCount = userCount;
this.version = version;
this.changeDetectorRef.markForCheck();
}
);
this.changeDetectorRef.markForCheck();
});
}
private generateCouponCode(aLength: number) {

67
apps/client/src/app/components/admin-overview/admin-overview.html

@ -30,73 +30,6 @@
}
</div>
</div>
<div class="align-items-start d-flex my-3">
<div class="w-50" i18n>Exchange Rates</div>
<div class="w-50">
<table>
@for (exchangeRate of exchangeRates; track exchangeRate) {
<tr>
<td>
<gf-value [locale]="user?.settings?.locale" [value]="1" />
</td>
<td class="pl-1">{{ exchangeRate.label1 }}</td>
<td class="px-1">=</td>
<td align="right">
<gf-value
class="d-inline-block"
[locale]="user?.settings?.locale"
[precision]="4"
[value]="exchangeRate.value"
/>
</td>
<td class="pl-1">{{ exchangeRate.label2 }}</td>
<td>
<button
class="mx-1 no-min-width px-2"
mat-button
[matMenuTriggerFor]="exchangeRateActionsMenu"
(click)="$event.stopPropagation()"
>
<ion-icon name="ellipsis-horizontal" />
</button>
<mat-menu
#exchangeRateActionsMenu="matMenu"
class="h-100 mx-1 no-min-width px-2"
xPosition="before"
>
<a
mat-menu-item
[queryParams]="{
assetProfileDialog: true,
dataSource: exchangeRate.dataSource,
symbol: exchangeRate.symbol
}"
[routerLink]="['/admin', 'market-data']"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="create-outline" />
<span i18n>Edit</span>
</span>
</a>
@if (customCurrencies.includes(exchangeRate.label2)) {
<hr class="m-0" />
<button
mat-menu-item
(click)="onDeleteCurrency(exchangeRate.label2)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<span i18n>Delete</span>
</span>
</button>
}
</mat-menu>
</td>
</tr>
}
</table>
</div>
</div>
<div class="d-flex my-3">
<div class="w-50" i18n>User Signup</div>
<div class="w-50">

7
libs/common/src/lib/interfaces/admin-data.interface.ts

@ -1,11 +1,4 @@
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
export interface AdminData {
exchangeRates: ({
label1: string;
label2: string;
value: number;
} & AssetProfileIdentifier)[];
settings: { [key: string]: boolean | object | string | string[] };
transactionCount: number;
userCount: number;

Loading…
Cancel
Save