Browse Source

Task/migrate rule settings dialog from ngModel to form control (#7037)

* Migrate from ngModel to form control

* Update changelog
pull/7040/head
Thomas Kaul 1 week ago
committed by GitHub
parent
commit
06863c7bec
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 30
      apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts
  3. 262
      apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html

1
CHANGELOG.md

@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improved the styling of the tabs across various dialogs - Improved the styling of the tabs across various dialogs
- Improved the styling of the page tabs component on desktop - Improved the styling of the page tabs component on desktop
- Enabled the _Bull Dashboard_ tab in the admin control panel (experimental) - Enabled the _Bull Dashboard_ tab in the admin control panel (experimental)
- Migrated the settings dialog to customize the rule thresholds of the _X-ray_ page from `ngModel` to form control
- Improved the language localization for Spanish (`es`) - Improved the language localization for Spanish (`es`)
- Upgraded `bull-board` from version `7.1.5` to `7.2.1` - Upgraded `bull-board` from version `7.1.5` to `7.2.1`
- Upgraded `date-fns` from version `4.1.0` to `4.4.0` - Upgraded `date-fns` from version `4.1.0` to `4.4.0`

30
apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts

@ -1,8 +1,7 @@
import { XRayRulesSettings } from '@ghostfolio/common/interfaces';
import { GfValueComponent } from '@ghostfolio/ui/value'; import { GfValueComponent } from '@ghostfolio/ui/value';
import { Component, Inject } from '@angular/core'; import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { import {
MAT_DIALOG_DATA, MAT_DIALOG_DATA,
@ -14,22 +13,37 @@ import { MatSliderModule } from '@angular/material/slider';
import { RuleSettingsDialogParams } from './interfaces/interfaces'; import { RuleSettingsDialogParams } from './interfaces/interfaces';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ imports: [
FormsModule,
GfValueComponent, GfValueComponent,
MatButtonModule, MatButtonModule,
MatDialogModule, MatDialogModule,
MatSliderModule MatSliderModule,
ReactiveFormsModule
], ],
selector: 'gf-rule-settings-dialog', selector: 'gf-rule-settings-dialog',
styleUrls: ['./rule-settings-dialog.scss'], styleUrls: ['./rule-settings-dialog.scss'],
templateUrl: './rule-settings-dialog.html' templateUrl: './rule-settings-dialog.html'
}) })
export class GfRuleSettingsDialogComponent { export class GfRuleSettingsDialogComponent {
public settings: XRayRulesSettings['AccountClusterRiskCurrentInvestment']; public settingsForm: FormGroup;
public constructor( public constructor(
@Inject(MAT_DIALOG_DATA) public data: RuleSettingsDialogParams, @Inject(MAT_DIALOG_DATA) public data: RuleSettingsDialogParams,
public dialogRef: MatDialogRef<GfRuleSettingsDialogComponent> public dialogRef: MatDialogRef<GfRuleSettingsDialogComponent>,
) {} private formBuilder: FormBuilder
) {
this.settingsForm = this.formBuilder.group({
thresholdMax: [this.data.settings.thresholdMax],
thresholdMin: [this.data.settings.thresholdMin]
});
}
public onSubmit() {
this.dialogRef.close({
...this.data.settings,
thresholdMax: this.settingsForm.get('thresholdMax')?.value,
thresholdMin: this.settingsForm.get('thresholdMin')?.value
});
}
} }

262
apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html

@ -1,132 +1,142 @@
<div mat-dialog-title>{{ data.categoryName }} › {{ data.rule.name }}</div> <div mat-dialog-title>{{ data.categoryName }} › {{ data.rule.name }}</div>
<div class="py-3" mat-dialog-content> <form
@if ( class="d-flex flex-column h-100"
data.rule.configuration.thresholdMin && data.rule.configuration.thresholdMax [formGroup]="settingsForm"
) { (ngSubmit)="onSubmit()"
<div class="w-100"> >
<h6 class="d-flex mb-0"> <div class="py-3" mat-dialog-content>
<ng-container i18n>Threshold range</ng-container>: @if (
<gf-value data.rule.configuration.thresholdMin &&
class="ml-1" data.rule.configuration.thresholdMax
[isPercent]="data.rule.configuration.threshold.unit === '%'" ) {
[locale]="data.locale" <div class="w-100">
[precision]="2" <h6 class="d-flex mb-0">
[value]="data.settings.thresholdMin" <ng-container i18n>Threshold range</ng-container>:
/> <gf-value
<span class="mx-1">-</span> class="ml-1"
<gf-value [isPercent]="data.rule.configuration.threshold.unit === '%'"
[isPercent]="data.rule.configuration.threshold.unit === '%'" [locale]="data.locale"
[locale]="data.locale" [precision]="2"
[precision]="2" [value]="settingsForm.get('thresholdMin').value"
[value]="data.settings.thresholdMax" />
/> <span class="mx-1">-</span>
</h6> <gf-value
<div class="align-items-center d-flex w-100"> [isPercent]="data.rule.configuration.threshold.unit === '%'"
<gf-value [locale]="data.locale"
[isPercent]="data.rule.configuration.threshold.unit === '%'" [precision]="2"
[locale]="data.locale" [value]="settingsForm.get('thresholdMax').value"
[precision]="2" />
[value]="data.rule.configuration.threshold.min" </h6>
/> <div class="align-items-center d-flex w-100">
<mat-slider <gf-value
class="flex-grow-1" [isPercent]="data.rule.configuration.threshold.unit === '%'"
[max]="data.rule.configuration.threshold.max" [locale]="data.locale"
[min]="data.rule.configuration.threshold.min" [precision]="2"
[step]="data.rule.configuration.threshold.step" [value]="data.rule.configuration.threshold.min"
> />
<input matSliderStartThumb [(ngModel)]="data.settings.thresholdMin" /> <mat-slider
<input matSliderEndThumb [(ngModel)]="data.settings.thresholdMax" /> class="flex-grow-1"
</mat-slider> [max]="data.rule.configuration.threshold.max"
<gf-value [min]="data.rule.configuration.threshold.min"
[isPercent]="data.rule.configuration.threshold.unit === '%'" [step]="data.rule.configuration.threshold.step"
[locale]="data.locale" >
[precision]="2" <input formControlName="thresholdMin" matSliderStartThumb />
[value]="data.rule.configuration.threshold.max" <input formControlName="thresholdMax" matSliderEndThumb />
/> </mat-slider>
<gf-value
[isPercent]="data.rule.configuration.threshold.unit === '%'"
[locale]="data.locale"
[precision]="2"
[value]="data.rule.configuration.threshold.max"
/>
</div>
</div> </div>
</div> } @else {
} @else { <div class="w-100" [class.d-none]="!data.rule.configuration.thresholdMin">
<div class="w-100" [class.d-none]="!data.rule.configuration.thresholdMin"> <h6 class="d-flex mb-0">
<h6 class="d-flex mb-0"> <ng-container i18n>Threshold Min</ng-container>:
<ng-container i18n>Threshold Min</ng-container>: <gf-value
<gf-value class="ml-1"
class="ml-1" [isPercent]="data.rule.configuration.threshold.unit === '%'"
[isPercent]="data.rule.configuration.threshold.unit === '%'" [locale]="data.locale"
[locale]="data.locale" [precision]="2"
[precision]="2" [value]="settingsForm.get('thresholdMin').value"
[value]="data.settings.thresholdMin" />
/> </h6>
</h6> <div class="align-items-center d-flex w-100">
<div class="align-items-center d-flex w-100"> <gf-value
<gf-value [isPercent]="data.rule.configuration.threshold.unit === '%'"
[isPercent]="data.rule.configuration.threshold.unit === '%'" [locale]="data.locale"
[locale]="data.locale" [precision]="2"
[precision]="2" [value]="data.rule.configuration.threshold.min"
[value]="data.rule.configuration.threshold.min" />
/> <mat-slider
<mat-slider class="flex-grow-1"
class="flex-grow-1" name="thresholdMin"
name="thresholdMin" [max]="data.rule.configuration.threshold.max"
[max]="data.rule.configuration.threshold.max" [min]="data.rule.configuration.threshold.min"
[min]="data.rule.configuration.threshold.min" [step]="data.rule.configuration.threshold.step"
[step]="data.rule.configuration.threshold.step" >
> <input formControlName="thresholdMin" matSliderThumb />
<input matSliderThumb [(ngModel)]="data.settings.thresholdMin" /> </mat-slider>
</mat-slider> <gf-value
<gf-value [isPercent]="data.rule.configuration.threshold.unit === '%'"
[isPercent]="data.rule.configuration.threshold.unit === '%'" [locale]="data.locale"
[locale]="data.locale" [precision]="2"
[precision]="2" [value]="data.rule.configuration.threshold.max"
[value]="data.rule.configuration.threshold.max" />
/> </div>
</div> </div>
</div> <div class="w-100" [class.d-none]="!data.rule.configuration.thresholdMax">
<div class="w-100" [class.d-none]="!data.rule.configuration.thresholdMax"> <h6 class="d-flex mb-0">
<h6 class="d-flex mb-0"> <ng-container i18n>Threshold Max</ng-container>:
<ng-container i18n>Threshold Max</ng-container>: <gf-value
<gf-value class="ml-1"
class="ml-1" [isPercent]="data.rule.configuration.threshold.unit === '%'"
[isPercent]="data.rule.configuration.threshold.unit === '%'" [locale]="data.locale"
[locale]="data.locale" [precision]="2"
[precision]="2" [value]="settingsForm.get('thresholdMax').value"
[value]="data.settings.thresholdMax" />
/> </h6>
</h6> <div class="align-items-center d-flex w-100">
<div class="align-items-center d-flex w-100"> <gf-value
<gf-value [isPercent]="data.rule.configuration.threshold.unit === '%'"
[isPercent]="data.rule.configuration.threshold.unit === '%'" [locale]="data.locale"
[locale]="data.locale" [precision]="2"
[precision]="2" [value]="data.rule.configuration.threshold.min"
[value]="data.rule.configuration.threshold.min" />
/> <mat-slider
<mat-slider class="flex-grow-1"
class="flex-grow-1" name="thresholdMax"
name="thresholdMax" [max]="data.rule.configuration.threshold.max"
[max]="data.rule.configuration.threshold.max" [min]="data.rule.configuration.threshold.min"
[min]="data.rule.configuration.threshold.min" [step]="data.rule.configuration.threshold.step"
[step]="data.rule.configuration.threshold.step" >
> <input formControlName="thresholdMax" matSliderThumb />
<input matSliderThumb [(ngModel)]="data.settings.thresholdMax" /> </mat-slider>
</mat-slider> <gf-value
<gf-value [isPercent]="data.rule.configuration.threshold.unit === '%'"
[isPercent]="data.rule.configuration.threshold.unit === '%'" [locale]="data.locale"
[locale]="data.locale" [precision]="2"
[precision]="2" [value]="data.rule.configuration.threshold.max"
[value]="data.rule.configuration.threshold.max" />
/> </div>
</div> </div>
</div> }
} </div>
</div>
<div align="end" mat-dialog-actions> <div align="end" mat-dialog-actions>
<button i18n mat-button (click)="dialogRef.close()">Close</button> <button mat-button type="button" (click)="dialogRef.close()">
<button <ng-container i18n>Close</ng-container>
color="primary" </button>
mat-flat-button <button
(click)="dialogRef.close(data.settings)" color="primary"
> mat-flat-button
<ng-container i18n>Save</ng-container> type="submit"
</button> [disabled]="!settingsForm.dirty"
</div> >
<ng-container i18n>Save</ng-container>
</button>
</div>
</form>

Loading…
Cancel
Save