Merge branch 'main' of github.com:ghostfolio/ghostfolio
All checks were successful
Docker image CD / build_and_push (push) Successful in 34m50s
All checks were successful
Docker image CD / build_and_push (push) Successful in 34m50s
This commit is contained in:
commit
ea05e61bd4
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Changed
|
||||
|
||||
- Reloaded the available tags after creating a custom tag in the holding detail dialog (experimental)
|
||||
- Improved the validation of the currency management in the admin control panel
|
||||
- Migrated the `@ghostfolio/client` components to control flow
|
||||
- Migrated the `@ghostfolio/ui` components to control flow
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { AdminService } from '@ghostfolio/api/app/admin/admin.service';
|
||||
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
|
||||
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
|
||||
import { getCurrencyFromSymbol, isCurrency } from '@ghostfolio/common/helper';
|
||||
import { MarketDataDetailsResponse } from '@ghostfolio/common/interfaces';
|
||||
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
|
||||
import { RequestWithUser } from '@ghostfolio/common/types';
|
||||
@ -42,7 +43,7 @@ export class MarketDataController {
|
||||
{ dataSource, symbol }
|
||||
]);
|
||||
|
||||
if (!assetProfile) {
|
||||
if (!assetProfile && !isCurrency(getCurrencyFromSymbol(symbol))) {
|
||||
throw new HttpException(
|
||||
getReasonPhrase(StatusCodes.NOT_FOUND),
|
||||
StatusCodes.NOT_FOUND
|
||||
@ -55,7 +56,7 @@ export class MarketDataController {
|
||||
);
|
||||
|
||||
const canReadOwnAssetProfile =
|
||||
assetProfile.userId === this.request.user.id &&
|
||||
assetProfile?.userId === this.request.user.id &&
|
||||
hasPermission(
|
||||
this.request.user.permissions,
|
||||
permissions.readMarketDataOfOwnAssetProfile
|
||||
|
@ -15,9 +15,11 @@ import {
|
||||
FormControl,
|
||||
FormGroup,
|
||||
ValidationErrors,
|
||||
ValidatorFn,
|
||||
Validators
|
||||
} from '@angular/forms';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { isISO4217CurrencyCode } from 'class-validator';
|
||||
import { uniq } from 'lodash';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
|
||||
@ -52,9 +54,7 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy {
|
||||
this.createAssetProfileForm = this.formBuilder.group(
|
||||
{
|
||||
addCurrency: new FormControl(null, [
|
||||
Validators.maxLength(3),
|
||||
Validators.minLength(3),
|
||||
Validators.required
|
||||
this.iso4217CurrencyCodeValidator()
|
||||
]),
|
||||
addSymbol: new FormControl(null, [Validators.required]),
|
||||
searchSymbol: new FormControl(null, [Validators.required])
|
||||
@ -83,11 +83,11 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy {
|
||||
symbol: this.createAssetProfileForm.get('searchSymbol').value.symbol
|
||||
});
|
||||
} else if (this.mode === 'currency') {
|
||||
const currency = this.createAssetProfileForm
|
||||
.get('addCurrency')
|
||||
.value.toUpperCase();
|
||||
const currency = (
|
||||
this.createAssetProfileForm.get('addCurrency').value as string
|
||||
).toUpperCase();
|
||||
|
||||
const currencies = uniq([...this.customCurrencies, currency]);
|
||||
const currencies = uniq([...this.customCurrencies, currency]).sort();
|
||||
|
||||
this.dataService
|
||||
.putAdminSetting(PROPERTY_CURRENCIES, {
|
||||
@ -109,10 +109,7 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy {
|
||||
const addCurrencyFormControl =
|
||||
this.createAssetProfileForm.get('addCurrency');
|
||||
|
||||
if (
|
||||
addCurrencyFormControl.hasError('maxlength') ||
|
||||
addCurrencyFormControl.hasError('minlength')
|
||||
) {
|
||||
if (addCurrencyFormControl.hasError('invalidCurrency')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -161,4 +158,14 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy {
|
||||
this.changeDetectorRef.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
private iso4217CurrencyCodeValidator(): ValidatorFn {
|
||||
return (control: AbstractControl): ValidationErrors | null => {
|
||||
if (!isISO4217CurrencyCode(control.value?.toUpperCase())) {
|
||||
return { invalidCurrency: true };
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ import {
|
||||
formatDistanceToNowStrict,
|
||||
parseISO
|
||||
} from 'date-fns';
|
||||
import { uniq } from 'lodash';
|
||||
import { StringValue } from 'ms';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
@ -122,24 +121,6 @@ export class AdminOverviewComponent implements OnDestroy, OnInit {
|
||||
this.putAdminSetting({ key: PROPERTY_COUPONS, value: coupons });
|
||||
}
|
||||
|
||||
public onAddCurrency() {
|
||||
const currency = prompt($localize`Please add a currency:`);
|
||||
|
||||
if (currency) {
|
||||
if (currency.length === 3) {
|
||||
const currencies = uniq([
|
||||
...this.customCurrencies,
|
||||
currency.toUpperCase()
|
||||
]);
|
||||
this.putAdminSetting({ key: PROPERTY_CURRENCIES, value: currencies });
|
||||
} else {
|
||||
this.notificationService.alert({
|
||||
title: $localize`${currency} is an invalid currency!`
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public onChangeCouponDuration(aCouponDuration: StringValue) {
|
||||
this.couponDuration = aCouponDuration;
|
||||
}
|
||||
|
@ -95,16 +95,6 @@
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
<div class="mt-2">
|
||||
<button
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
(click)="onAddCurrency()"
|
||||
>
|
||||
<ion-icon class="mr-1" name="add-outline" />
|
||||
<span i18n>Add Currency</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex my-3">
|
||||
|
@ -56,6 +56,11 @@
|
||||
<li>Click on the <i>+</i> button</li>
|
||||
<li>Switch to <i>Add Currency</i></li>
|
||||
<li>Insert e.g. <code>EUR</code> for Euro</li>
|
||||
<li>Select <i>Filter by Currencies</i></li>
|
||||
<li>Find the entry <i>USDEUR</i></li>
|
||||
<li>
|
||||
Click the menu item <i>Gather Historical Data</i> in the dialog
|
||||
</li>
|
||||
</ol>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
Loading…
x
Reference in New Issue
Block a user