Feature/integrate add currency to create asset profile dialog (#3819)
* Integrate add currency to create asset profile dialog * Update changelog --------- Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
This commit is contained in:
parent
64c1d25e64
commit
8d0890a400
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Integrated the add currency functionality into the market data section of the admin control panel
|
||||
- Improved the language localization for German (`de`)
|
||||
- Upgraded `webpack-bundle-analyzer` from version `4.10.1` to `4.10.2`
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
import { AdminService } from '@ghostfolio/client/services/admin.service';
|
||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||
import { PROPERTY_CURRENCIES } from '@ghostfolio/common/config';
|
||||
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
OnDestroy,
|
||||
OnInit
|
||||
@ -15,6 +18,10 @@ import {
|
||||
Validators
|
||||
} from '@angular/forms';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { uniq } from 'lodash';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
|
||||
import { CreateAssetProfileDialogMode } from './interfaces/interfaces';
|
||||
|
||||
@Component({
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
@ -25,17 +32,29 @@ import { MatDialogRef } from '@angular/material/dialog';
|
||||
})
|
||||
export class CreateAssetProfileDialog implements OnInit, OnDestroy {
|
||||
public createAssetProfileForm: FormGroup;
|
||||
public mode: 'auto' | 'manual';
|
||||
public mode: CreateAssetProfileDialogMode;
|
||||
|
||||
private customCurrencies: string[];
|
||||
private unsubscribeSubject = new Subject<void>();
|
||||
|
||||
public constructor(
|
||||
public readonly adminService: AdminService,
|
||||
private readonly changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly dataService: DataService,
|
||||
public readonly dialogRef: MatDialogRef<CreateAssetProfileDialog>,
|
||||
public readonly formBuilder: FormBuilder
|
||||
) {}
|
||||
|
||||
public ngOnInit() {
|
||||
this.initializeCustomCurrencies();
|
||||
|
||||
this.createAssetProfileForm = this.formBuilder.group(
|
||||
{
|
||||
addCurrency: new FormControl(null, [
|
||||
Validators.maxLength(3),
|
||||
Validators.minLength(3),
|
||||
Validators.required
|
||||
]),
|
||||
addSymbol: new FormControl(null, [Validators.required]),
|
||||
searchSymbol: new FormControl(null, [Validators.required])
|
||||
},
|
||||
@ -51,34 +70,75 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
public onRadioChange(mode: 'auto' | 'manual') {
|
||||
public onRadioChange(mode: CreateAssetProfileDialogMode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
public onSubmit() {
|
||||
this.mode === 'auto'
|
||||
? this.dialogRef.close({
|
||||
dataSource:
|
||||
this.createAssetProfileForm.get('searchSymbol').value.dataSource,
|
||||
symbol: this.createAssetProfileForm.get('searchSymbol').value.symbol
|
||||
if (this.mode === 'auto') {
|
||||
this.dialogRef.close({
|
||||
dataSource:
|
||||
this.createAssetProfileForm.get('searchSymbol').value.dataSource,
|
||||
symbol: this.createAssetProfileForm.get('searchSymbol').value.symbol
|
||||
});
|
||||
} else if (this.mode === 'currency') {
|
||||
const currency = this.createAssetProfileForm
|
||||
.get('addCurrency')
|
||||
.value.toUpperCase();
|
||||
|
||||
const currencies = uniq([...this.customCurrencies, currency]);
|
||||
|
||||
this.dataService
|
||||
.putAdminSetting(PROPERTY_CURRENCIES, {
|
||||
value: JSON.stringify(currencies)
|
||||
})
|
||||
: this.dialogRef.close({
|
||||
dataSource: 'MANUAL',
|
||||
symbol: this.createAssetProfileForm.get('addSymbol').value
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.subscribe(() => {
|
||||
this.dialogRef.close();
|
||||
});
|
||||
} else if (this.mode === 'manual') {
|
||||
this.dialogRef.close({
|
||||
dataSource: 'MANUAL',
|
||||
symbol: this.createAssetProfileForm.get('addSymbol').value
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public ngOnDestroy() {}
|
||||
public get showCurrencyErrorMessage() {
|
||||
const addCurrencyFormControl =
|
||||
this.createAssetProfileForm.get('addCurrency');
|
||||
|
||||
if (
|
||||
addCurrencyFormControl.hasError('maxlength') ||
|
||||
addCurrencyFormControl.hasError('minlength')
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
this.unsubscribeSubject.next();
|
||||
this.unsubscribeSubject.complete();
|
||||
}
|
||||
|
||||
private atLeastOneValid(control: AbstractControl): ValidationErrors {
|
||||
const addCurrencyControl = control.get('addCurrency');
|
||||
const addSymbolControl = control.get('addSymbol');
|
||||
const searchSymbolControl = control.get('searchSymbol');
|
||||
|
||||
if (addSymbolControl.valid && searchSymbolControl.valid) {
|
||||
if (
|
||||
addCurrencyControl.valid &&
|
||||
addSymbolControl.valid &&
|
||||
searchSymbolControl.valid
|
||||
) {
|
||||
return { atLeastOneValid: true };
|
||||
}
|
||||
|
||||
if (
|
||||
addCurrencyControl.valid ||
|
||||
!addCurrencyControl ||
|
||||
addSymbolControl.valid ||
|
||||
!addSymbolControl ||
|
||||
searchSymbolControl.valid ||
|
||||
@ -89,4 +149,15 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy {
|
||||
|
||||
return { atLeastOneValid: true };
|
||||
}
|
||||
|
||||
private initializeCustomCurrencies() {
|
||||
this.adminService
|
||||
.fetchAdminData()
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.subscribe(({ settings }) => {
|
||||
this.customCurrencies = settings[PROPERTY_CURRENCIES] as string[];
|
||||
|
||||
this.changeDetectorRef.markForCheck();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,9 @@
|
||||
<mat-radio-button class="ml-3" name="manual" value="manual">
|
||||
</mat-radio-button>
|
||||
<label class="m-0" for="manual" i18n>Add Manually</label>
|
||||
<mat-radio-button class="ml-3" name="currency" value="currency">
|
||||
</mat-radio-button>
|
||||
<label class="m-0" for="currency" i18n>Add Currency</label>
|
||||
</mat-radio-group>
|
||||
</div>
|
||||
|
||||
@ -37,6 +40,16 @@
|
||||
<input formControlName="addSymbol" matInput />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
} @else if (mode === 'currency') {
|
||||
<div>
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
<mat-label i18n>Currency</mat-label>
|
||||
<input formControlName="addCurrency" matInput />
|
||||
@if (showCurrencyErrorMessage) {
|
||||
<mat-error i18n>Oops! Invalid currency.</mat-error>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="d-flex justify-content-end" mat-dialog-actions>
|
||||
|
@ -2,3 +2,5 @@ export interface CreateAssetProfileDialogParams {
|
||||
deviceType: string;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
export type CreateAssetProfileDialogMode = 'auto' | 'currency' | 'manual';
|
||||
|
@ -126,7 +126,10 @@ export class AdminOverviewComponent implements OnDestroy, OnInit {
|
||||
|
||||
if (currency) {
|
||||
if (currency.length === 3) {
|
||||
const currencies = uniq([...this.customCurrencies, currency]);
|
||||
const currencies = uniq([
|
||||
...this.customCurrencies,
|
||||
currency.toUpperCase()
|
||||
]);
|
||||
this.putAdminSetting({ key: PROPERTY_CURRENCIES, value: currencies });
|
||||
} else {
|
||||
this.notificationService.alert({
|
||||
|
@ -52,8 +52,10 @@
|
||||
</p>
|
||||
<ol>
|
||||
<li>Go to the <i>Admin Control</i> panel</li>
|
||||
<li>Click on the <i>Add Currency</i> button</li>
|
||||
<li>Insert e.g. <code>EUR</code> in the prompt</li>
|
||||
<li>Go to the <i>Market Data</i> section</li>
|
||||
<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>
|
||||
</ol>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
Loading…
x
Reference in New Issue
Block a user