Feature/set up a notification service for prompt dialogs (#4117)

* Set up a notification service for prompt dialogs

* Update changelog
pull/3037/merge
Brandon 3 days ago committed by GitHub
parent 6d8240dfed
commit 46422f731e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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());
if (emergencyFund >= 0) {
this.emergencyFundChanged.emit(emergencyFund);
}
this.notificationService.prompt({
confirmFn: (value) => {
const emergencyFund = parseFloat(value.trim()) || 0;
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…
Cancel
Save