From dc95319b31e2b492123826a90348bc9409c3929f Mon Sep 17 00:00:00 2001 From: Madhab Sahoo Date: Wed, 25 Sep 2024 23:33:14 +0530 Subject: [PATCH] Add currency to create asset profile dialog #3773 --- CHANGELOG.md | 6 ++ ...create-asset-profile-dialog.component.scss | 6 ++ .../create-asset-profile-dialog.component.ts | 95 +++++++++++++++---- .../create-asset-profile-dialog.html | 15 ++- package.json | 2 +- 5 files changed, 102 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c42980218..df5615f21 100644 --- a/CHANGELOG.md +++ b/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/), 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 ### Changed diff --git a/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.scss b/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.scss index 5d4e87f30..5ed343cfc 100644 --- a/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.scss +++ b/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.scss @@ -1,3 +1,9 @@ :host { display: block; } + +.mat-internal-form-field > label { + font-size: 16px; + margin-bottom: 0 !important; + cursor: pointer; +} diff --git a/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts index f0a47ad1b..4854975b6 100644 --- a/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts +++ b/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 { DataService } from '@ghostfolio/client/services/data.service'; +import { PROPERTY_CURRENCIES } from '@ghostfolio/common/config'; import { ChangeDetectionStrategy, Component, OnDestroy, - OnInit + OnInit, + ViewEncapsulation } from '@angular/core'; import { AbstractControl, @@ -15,29 +19,41 @@ import { Validators } from '@angular/forms'; import { MatDialogRef } from '@angular/material/dialog'; +import { Router } from '@angular/router'; +import { uniq } from 'lodash'; +import { Subject, takeUntil } from 'rxjs'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'h-100' }, selector: 'gf-create-asset-profile-dialog', 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 { public createAssetProfileForm: FormGroup; - public mode: 'auto' | 'manual'; + public mode: 'auto' | 'manual' | 'currency'; + public customCurrencies: string[]; + + private unsubscribeSubject = new Subject(); public constructor( public readonly adminService: AdminService, public readonly dialogRef: MatDialogRef, - public readonly formBuilder: FormBuilder + public readonly formBuilder: FormBuilder, + private dataService: DataService, + private notificationService: NotificationService, + private router: Router ) {} public ngOnInit() { + this.fetchAdminData(); this.createAssetProfileForm = this.formBuilder.group( { 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 @@ -51,30 +67,54 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy { this.dialogRef.close(); } - public onRadioChange(mode: 'auto' | 'manual') { + public onRadioChange(mode: 'auto' | 'manual' | 'currency') { 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 - }) - : this.dialogRef.close({ - dataSource: 'MANUAL', - symbol: this.createAssetProfileForm.get('addSymbol').value + 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 === 'manual') { + this.dialogRef.close({ + 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 { const addSymbolControl = control.get('addSymbol'); 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 }; } @@ -82,11 +122,30 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy { addSymbolControl.valid || !addSymbolControl || searchSymbolControl.valid || - !searchSymbolControl + !searchSymbolControl || + addCurrencyControl.valid || + !addCurrencyControl ) { return { atLeastOneValid: false }; } 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)); + } } diff --git a/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html b/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html index 7c228941e..8e1e52e0c 100644 --- a/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html +++ b/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -12,11 +12,13 @@ [value]="mode" (change)="onRadioChange($event.value)" > - - + Search + Add Manually + + + Add Currency - @@ -37,6 +39,13 @@ + } @else if (mode === 'currency') { +
+ + Currency + + +
}
diff --git a/package.json b/package.json index e03fc937c..b6b331db9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.110.0", + "version": "2.111.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio",