Feature/set up a notification service for prompt dialogs (#4117)
* Set up a notification service for prompt dialogs * Update changelog
This commit is contained in:
parent
6d8240dfed
commit
46422f731e
@ -11,9 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Added a new static portfolio analysis rule: _Asset Class Cluster Risk_ (Equity)
|
||||
- Added a new static portfolio analysis rule: _Asset Class Cluster Risk_ (Fixed Income)
|
||||
- Set up a notification service for prompt dialogs
|
||||
|
||||
### Changed
|
||||
|
||||
- Improved the usability to edit the emergency fund
|
||||
- Extracted the market data management from the admin control panel endpoint to a dedicated endpoint
|
||||
- Upgraded `big.js` from version `6.2.1` to `6.2.2`
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { NotificationService } from '@ghostfolio/client/core/notification/notification.service';
|
||||
import { getDateFnsLocale, getLocale } from '@ghostfolio/common/helper';
|
||||
import { PortfolioSummary, User } from '@ghostfolio/common/interfaces';
|
||||
import { translate } from '@ghostfolio/ui/i18n';
|
||||
@ -34,6 +35,8 @@ export class PortfolioSummaryComponent implements OnChanges {
|
||||
);
|
||||
public timeInMarket: string;
|
||||
|
||||
public constructor(private notificationService: NotificationService) {}
|
||||
|
||||
public ngOnChanges() {
|
||||
if (this.summary) {
|
||||
if (this.summary.firstOrderDate) {
|
||||
@ -49,14 +52,15 @@ export class PortfolioSummaryComponent implements OnChanges {
|
||||
}
|
||||
|
||||
public onEditEmergencyFund() {
|
||||
const emergencyFundInput = prompt(
|
||||
$localize`Please enter the amount of your emergency fund:`,
|
||||
this.summary.emergencyFund?.total?.toString() ?? '0'
|
||||
);
|
||||
const emergencyFund = parseFloat(emergencyFundInput?.trim());
|
||||
this.notificationService.prompt({
|
||||
confirmFn: (value) => {
|
||||
const emergencyFund = parseFloat(value.trim()) || 0;
|
||||
|
||||
if (emergencyFund >= 0) {
|
||||
this.emergencyFundChanged.emit(emergencyFund);
|
||||
}
|
||||
this.emergencyFundChanged.emit(emergencyFund);
|
||||
},
|
||||
confirmLabel: $localize`Save`,
|
||||
defaultValue: this.summary.emergencyFund?.total?.toString() ?? '0',
|
||||
title: $localize`Please set the amount of your emergency fund.`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -17,3 +17,12 @@ export interface IConfirmParams {
|
||||
message?: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface IPromptParams {
|
||||
confirmFn: (value: string) => void;
|
||||
confirmLabel?: string;
|
||||
defaultValue?: string;
|
||||
discardLabel?: string;
|
||||
title: string;
|
||||
valueLabel?: string;
|
||||
}
|
||||
|
@ -7,7 +7,12 @@ import { isFunction } from 'lodash';
|
||||
import { GfAlertDialogComponent } from './alert-dialog/alert-dialog.component';
|
||||
import { GfConfirmationDialogComponent } from './confirmation-dialog/confirmation-dialog.component';
|
||||
import { ConfirmationDialogType } from './confirmation-dialog/confirmation-dialog.type';
|
||||
import { IAlertParams, IConfirmParams } from './interfaces/interfaces';
|
||||
import {
|
||||
IAlertParams,
|
||||
IConfirmParams,
|
||||
IPromptParams
|
||||
} from './interfaces/interfaces';
|
||||
import { GfPromptDialogComponent } from './prompt-dialog/prompt-dialog.component';
|
||||
|
||||
@Injectable()
|
||||
export class NotificationService {
|
||||
@ -73,6 +78,36 @@ export class NotificationService {
|
||||
});
|
||||
}
|
||||
|
||||
public prompt(aParams: IPromptParams) {
|
||||
if (!aParams.confirmLabel) {
|
||||
aParams.confirmLabel = translate('OK');
|
||||
}
|
||||
|
||||
if (!aParams.discardLabel) {
|
||||
aParams.discardLabel = translate('CANCEL');
|
||||
}
|
||||
|
||||
const dialog = this.matDialog.open(GfPromptDialogComponent, {
|
||||
autoFocus: true,
|
||||
maxWidth: this.dialogMaxWidth,
|
||||
width: this.dialogWidth
|
||||
});
|
||||
|
||||
dialog.componentInstance.initialize({
|
||||
confirmLabel: aParams.confirmLabel,
|
||||
defaultValue: aParams.defaultValue,
|
||||
discardLabel: aParams.discardLabel,
|
||||
title: aParams.title,
|
||||
valueLabel: aParams.valueLabel
|
||||
});
|
||||
|
||||
return dialog.afterClosed().subscribe((result: string) => {
|
||||
if (result !== 'discard' && isFunction(aParams.confirmFn)) {
|
||||
aParams.confirmFn(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public setDialogMaxWidth(aDialogMaxWidth: string) {
|
||||
this.dialogMaxWidth = aDialogMaxWidth;
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
|
||||
@Component({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
MatButtonModule,
|
||||
MatDialogModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule
|
||||
],
|
||||
selector: 'gf-prompt-dialog',
|
||||
standalone: true,
|
||||
templateUrl: './prompt-dialog.html'
|
||||
})
|
||||
export class GfPromptDialogComponent {
|
||||
public confirmLabel: string;
|
||||
public defaultValue: string;
|
||||
public discardLabel: string;
|
||||
public title: string;
|
||||
public value: string;
|
||||
public valueLabel: string;
|
||||
|
||||
public constructor(public dialogRef: MatDialogRef<GfPromptDialogComponent>) {}
|
||||
|
||||
public initialize(aParams: {
|
||||
confirmLabel?: string;
|
||||
defaultValue?: string;
|
||||
discardLabel?: string;
|
||||
title: string;
|
||||
valueLabel?: string;
|
||||
}) {
|
||||
this.confirmLabel = aParams.confirmLabel;
|
||||
this.defaultValue = aParams.defaultValue;
|
||||
this.discardLabel = aParams.discardLabel;
|
||||
this.title = aParams.title;
|
||||
this.value = aParams.defaultValue;
|
||||
this.valueLabel = aParams.valueLabel;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
@if (title) {
|
||||
<div mat-dialog-title [innerHTML]="title"></div>
|
||||
}
|
||||
|
||||
<div class="py-3" mat-dialog-content>
|
||||
<mat-form-field appearance="outline" class="w-100 without-hint">
|
||||
@if (valueLabel) {
|
||||
<mat-label>{{ valueLabel }}</mat-label>
|
||||
}
|
||||
<input matInput [(ngModel)]="value" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div align="end" mat-dialog-actions>
|
||||
<button mat-button (click)="dialogRef.close('discard')">
|
||||
{{ discardLabel }}
|
||||
</button>
|
||||
<button color="primary" mat-flat-button (click)="dialogRef.close(value)">
|
||||
{{ confirmLabel }}
|
||||
</button>
|
||||
</div>
|
Loading…
x
Reference in New Issue
Block a user