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
|
### Changed
|
||||||
|
|
||||||
|
- Integrated the add currency functionality into the market data section of the admin control panel
|
||||||
- Improved the language localization for German (`de`)
|
- Improved the language localization for German (`de`)
|
||||||
- Upgraded `webpack-bundle-analyzer` from version `4.10.1` to `4.10.2`
|
- 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 { AdminService } from '@ghostfolio/client/services/admin.service';
|
||||||
|
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||||
|
import { PROPERTY_CURRENCIES } from '@ghostfolio/common/config';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef,
|
||||||
Component,
|
Component,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit
|
OnInit
|
||||||
@ -15,6 +18,10 @@ import {
|
|||||||
Validators
|
Validators
|
||||||
} from '@angular/forms';
|
} from '@angular/forms';
|
||||||
import { MatDialogRef } from '@angular/material/dialog';
|
import { MatDialogRef } from '@angular/material/dialog';
|
||||||
|
import { uniq } from 'lodash';
|
||||||
|
import { Subject, takeUntil } from 'rxjs';
|
||||||
|
|
||||||
|
import { CreateAssetProfileDialogMode } from './interfaces/interfaces';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
@ -25,17 +32,29 @@ import { MatDialogRef } from '@angular/material/dialog';
|
|||||||
})
|
})
|
||||||
export class CreateAssetProfileDialog implements OnInit, OnDestroy {
|
export class CreateAssetProfileDialog implements OnInit, OnDestroy {
|
||||||
public createAssetProfileForm: FormGroup;
|
public createAssetProfileForm: FormGroup;
|
||||||
public mode: 'auto' | 'manual';
|
public mode: CreateAssetProfileDialogMode;
|
||||||
|
|
||||||
|
private customCurrencies: string[];
|
||||||
|
private unsubscribeSubject = new Subject<void>();
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
public readonly adminService: AdminService,
|
public readonly adminService: AdminService,
|
||||||
|
private readonly changeDetectorRef: ChangeDetectorRef,
|
||||||
|
private readonly dataService: DataService,
|
||||||
public readonly dialogRef: MatDialogRef<CreateAssetProfileDialog>,
|
public readonly dialogRef: MatDialogRef<CreateAssetProfileDialog>,
|
||||||
public readonly formBuilder: FormBuilder
|
public readonly formBuilder: FormBuilder
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
|
this.initializeCustomCurrencies();
|
||||||
|
|
||||||
this.createAssetProfileForm = this.formBuilder.group(
|
this.createAssetProfileForm = this.formBuilder.group(
|
||||||
{
|
{
|
||||||
|
addCurrency: new FormControl(null, [
|
||||||
|
Validators.maxLength(3),
|
||||||
|
Validators.minLength(3),
|
||||||
|
Validators.required
|
||||||
|
]),
|
||||||
addSymbol: new FormControl(null, [Validators.required]),
|
addSymbol: new FormControl(null, [Validators.required]),
|
||||||
searchSymbol: new FormControl(null, [Validators.required])
|
searchSymbol: new FormControl(null, [Validators.required])
|
||||||
},
|
},
|
||||||
@ -51,34 +70,75 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy {
|
|||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public onRadioChange(mode: 'auto' | 'manual') {
|
public onRadioChange(mode: CreateAssetProfileDialogMode) {
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public onSubmit() {
|
public onSubmit() {
|
||||||
this.mode === 'auto'
|
if (this.mode === 'auto') {
|
||||||
? this.dialogRef.close({
|
this.dialogRef.close({
|
||||||
dataSource:
|
dataSource:
|
||||||
this.createAssetProfileForm.get('searchSymbol').value.dataSource,
|
this.createAssetProfileForm.get('searchSymbol').value.dataSource,
|
||||||
symbol: this.createAssetProfileForm.get('searchSymbol').value.symbol
|
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({
|
.pipe(takeUntil(this.unsubscribeSubject))
|
||||||
dataSource: 'MANUAL',
|
.subscribe(() => {
|
||||||
symbol: this.createAssetProfileForm.get('addSymbol').value
|
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 {
|
private atLeastOneValid(control: AbstractControl): ValidationErrors {
|
||||||
|
const addCurrencyControl = control.get('addCurrency');
|
||||||
const addSymbolControl = control.get('addSymbol');
|
const addSymbolControl = control.get('addSymbol');
|
||||||
const searchSymbolControl = control.get('searchSymbol');
|
const searchSymbolControl = control.get('searchSymbol');
|
||||||
|
|
||||||
if (addSymbolControl.valid && searchSymbolControl.valid) {
|
if (
|
||||||
|
addCurrencyControl.valid &&
|
||||||
|
addSymbolControl.valid &&
|
||||||
|
searchSymbolControl.valid
|
||||||
|
) {
|
||||||
return { atLeastOneValid: true };
|
return { atLeastOneValid: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
addCurrencyControl.valid ||
|
||||||
|
!addCurrencyControl ||
|
||||||
addSymbolControl.valid ||
|
addSymbolControl.valid ||
|
||||||
!addSymbolControl ||
|
!addSymbolControl ||
|
||||||
searchSymbolControl.valid ||
|
searchSymbolControl.valid ||
|
||||||
@ -89,4 +149,15 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
return { atLeastOneValid: true };
|
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 class="ml-3" name="manual" value="manual">
|
||||||
</mat-radio-button>
|
</mat-radio-button>
|
||||||
<label class="m-0" for="manual" i18n>Add Manually</label>
|
<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>
|
</mat-radio-group>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -37,6 +40,16 @@
|
|||||||
<input formControlName="addSymbol" matInput />
|
<input formControlName="addSymbol" matInput />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</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>
|
||||||
<div class="d-flex justify-content-end" mat-dialog-actions>
|
<div class="d-flex justify-content-end" mat-dialog-actions>
|
||||||
|
@ -2,3 +2,5 @@ export interface CreateAssetProfileDialogParams {
|
|||||||
deviceType: string;
|
deviceType: string;
|
||||||
locale: string;
|
locale: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CreateAssetProfileDialogMode = 'auto' | 'currency' | 'manual';
|
||||||
|
@ -126,7 +126,10 @@ export class AdminOverviewComponent implements OnDestroy, OnInit {
|
|||||||
|
|
||||||
if (currency) {
|
if (currency) {
|
||||||
if (currency.length === 3) {
|
if (currency.length === 3) {
|
||||||
const currencies = uniq([...this.customCurrencies, currency]);
|
const currencies = uniq([
|
||||||
|
...this.customCurrencies,
|
||||||
|
currency.toUpperCase()
|
||||||
|
]);
|
||||||
this.putAdminSetting({ key: PROPERTY_CURRENCIES, value: currencies });
|
this.putAdminSetting({ key: PROPERTY_CURRENCIES, value: currencies });
|
||||||
} else {
|
} else {
|
||||||
this.notificationService.alert({
|
this.notificationService.alert({
|
||||||
|
@ -52,8 +52,10 @@
|
|||||||
</p>
|
</p>
|
||||||
<ol>
|
<ol>
|
||||||
<li>Go to the <i>Admin Control</i> panel</li>
|
<li>Go to the <i>Admin Control</i> panel</li>
|
||||||
<li>Click on the <i>Add Currency</i> button</li>
|
<li>Go to the <i>Market Data</i> section</li>
|
||||||
<li>Insert e.g. <code>EUR</code> in the prompt</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>
|
</ol>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user