Browse Source

Add currency to create asset profile dialog #3773

pull/3819/head
Madhab Sahoo 11 months ago
parent
commit
dc95319b31
  1. 6
      CHANGELOG.md
  2. 6
      apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.scss
  3. 95
      apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts
  4. 15
      apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html
  5. 2
      package.json

6
CHANGELOG.md

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 2.111.0 - 2024-09-25
### Added
- Integrate add currency into create asset profile dialog
## 2.110.0 - 2024-09-24 ## 2.110.0 - 2024-09-24
### Changed ### Changed

6
apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.scss

@ -1,3 +1,9 @@
:host { :host {
display: block; display: block;
} }
.mat-internal-form-field > label {
font-size: 16px;
margin-bottom: 0 !important;
cursor: pointer;
}

95
apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts

@ -1,10 +1,14 @@
import { NotificationService } from '@ghostfolio/client/core/notification/notification.service';
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,
Component, Component,
OnDestroy, OnDestroy,
OnInit OnInit,
ViewEncapsulation
} from '@angular/core'; } from '@angular/core';
import { import {
AbstractControl, AbstractControl,
@ -15,29 +19,41 @@ import {
Validators Validators
} from '@angular/forms'; } from '@angular/forms';
import { MatDialogRef } from '@angular/material/dialog'; import { MatDialogRef } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { uniq } from 'lodash';
import { Subject, takeUntil } from 'rxjs';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'h-100' }, host: { class: 'h-100' },
selector: 'gf-create-asset-profile-dialog', selector: 'gf-create-asset-profile-dialog',
styleUrls: ['./create-asset-profile-dialog.component.scss'], styleUrls: ['./create-asset-profile-dialog.component.scss'],
templateUrl: 'create-asset-profile-dialog.html' templateUrl: 'create-asset-profile-dialog.html',
encapsulation: ViewEncapsulation.None
}) })
export class CreateAssetProfileDialog implements OnInit, OnDestroy { export class CreateAssetProfileDialog implements OnInit, OnDestroy {
public createAssetProfileForm: FormGroup; public createAssetProfileForm: FormGroup;
public mode: 'auto' | 'manual'; public mode: 'auto' | 'manual' | 'currency';
public customCurrencies: string[];
private unsubscribeSubject = new Subject<void>();
public constructor( public constructor(
public readonly adminService: AdminService, public readonly adminService: AdminService,
public readonly dialogRef: MatDialogRef<CreateAssetProfileDialog>, public readonly dialogRef: MatDialogRef<CreateAssetProfileDialog>,
public readonly formBuilder: FormBuilder public readonly formBuilder: FormBuilder,
private dataService: DataService,
private notificationService: NotificationService,
private router: Router
) {} ) {}
public ngOnInit() { public ngOnInit() {
this.fetchAdminData();
this.createAssetProfileForm = this.formBuilder.group( this.createAssetProfileForm = this.formBuilder.group(
{ {
addSymbol: new FormControl(null, [Validators.required]), addSymbol: new FormControl(null, [Validators.required]),
searchSymbol: new FormControl(null, [Validators.required]) searchSymbol: new FormControl(null, [Validators.required]),
addCurrency: new FormControl(null, [Validators.required])
}, },
{ {
validators: this.atLeastOneValid validators: this.atLeastOneValid
@ -51,30 +67,54 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy {
this.dialogRef.close(); this.dialogRef.close();
} }
public onRadioChange(mode: 'auto' | 'manual') { public onRadioChange(mode: 'auto' | 'manual' | 'currency') {
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
}) });
: this.dialogRef.close({ } else if (this.mode === 'manual') {
dataSource: 'MANUAL', this.dialogRef.close({
symbol: this.createAssetProfileForm.get('addSymbol').value dataSource: 'MANUAL',
symbol: this.createAssetProfileForm.get('addSymbol').value
});
} else {
const currency = this.createAssetProfileForm.get('addCurrency').value;
if (currency.length === 3) {
const currencies = uniq([...this.customCurrencies, currency]);
this.putAdminSetting({ key: PROPERTY_CURRENCIES, value: currencies });
this.dialogRef.close();
this.notificationService.alert({
title: $localize`Currency added successfully!`
});
} else {
this.notificationService.alert({
title: $localize`${currency} is an invalid currency!`
}); });
}
}
} }
public ngOnDestroy() {} public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
}
private atLeastOneValid(control: AbstractControl): ValidationErrors { private atLeastOneValid(control: AbstractControl): ValidationErrors {
const addSymbolControl = control.get('addSymbol'); const addSymbolControl = control.get('addSymbol');
const searchSymbolControl = control.get('searchSymbol'); const searchSymbolControl = control.get('searchSymbol');
const addCurrencyControl = control.get('addCurrency');
if (addSymbolControl.valid && searchSymbolControl.valid) { if (
addSymbolControl.valid &&
searchSymbolControl.valid &&
addCurrencyControl.valid
) {
return { atLeastOneValid: true }; return { atLeastOneValid: true };
} }
@ -82,11 +122,30 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy {
addSymbolControl.valid || addSymbolControl.valid ||
!addSymbolControl || !addSymbolControl ||
searchSymbolControl.valid || searchSymbolControl.valid ||
!searchSymbolControl !searchSymbolControl ||
addCurrencyControl.valid ||
!addCurrencyControl
) { ) {
return { atLeastOneValid: false }; return { atLeastOneValid: false };
} }
return { atLeastOneValid: true }; return { atLeastOneValid: true };
} }
private fetchAdminData() {
this.adminService
.fetchAdminData()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ settings }) => {
this.customCurrencies = settings[PROPERTY_CURRENCIES] as string[];
});
}
private putAdminSetting({ key, value }: { key: string; value: any }) {
this.dataService
.putAdminSetting(key, {
value: value || value === false ? JSON.stringify(value) : undefined
})
.pipe(takeUntil(this.unsubscribeSubject));
}
} }

15
apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html

@ -12,11 +12,13 @@
[value]="mode" [value]="mode"
(change)="onRadioChange($event.value)" (change)="onRadioChange($event.value)"
> >
<mat-radio-button name="auto" value="auto" /> <mat-radio-button name="auto" value="auto"> Search </mat-radio-button>
<label class="m-0" for="auto" i18n>Search</label>
<mat-radio-button class="ml-3" name="manual" value="manual"> <mat-radio-button class="ml-3" name="manual" value="manual">
Add Manually
</mat-radio-button>
<mat-radio-button class="ml-3" name="currency" value="currency">
Add Currency
</mat-radio-button> </mat-radio-button>
<label class="m-0" for="manual" i18n>Add Manually</label>
</mat-radio-group> </mat-radio-group>
</div> </div>
@ -37,6 +39,13 @@
<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 />
</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
package.json

@ -1,6 +1,6 @@
{ {
"name": "ghostfolio", "name": "ghostfolio",
"version": "2.110.0", "version": "2.111.0",
"homepage": "https://ghostfol.io", "homepage": "https://ghostfol.io",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"repository": "https://github.com/ghostfolio/ghostfolio", "repository": "https://github.com/ghostfolio/ghostfolio",

Loading…
Cancel
Save