Browse Source

Merge remote-tracking branch 'origin/main' into feature/enable-strict-null-checks-in-ui

pull/6264/head
Kenrick Tandrian 1 week ago
parent
commit
c6d0a37a21
  1. 12
      CHANGELOG.md
  2. 12
      apps/api/src/services/data-provider/data-provider.service.ts
  3. 2
      apps/client/src/app/components/admin-market-data/admin-market-data.component.ts
  4. 12
      apps/client/src/app/pages/admin/admin-page.component.ts
  5. 15
      apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts
  6. 8
      apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html
  7. 8
      apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.component.ts
  8. 4
      package-lock.json
  9. 2
      package.json

12
CHANGELOG.md

@ -5,6 +5,17 @@ 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.242.0 - 2026-02-22
### Changed
- Changed the account field to optional in the create or update activity dialog
### Fixed
- Fixed a validation issue for valuables used in the create and import activity logic
- Fixed the page size for presets in the historical market data table of the admin control panel
## 2.241.0 - 2026-02-21 ## 2.241.0 - 2026-02-21
### Changed ### Changed
@ -19,7 +30,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed an issue with `balanceInBaseCurrency` of the accounts in the value redaction interceptor for the impersonation mode - Fixed an issue with `balanceInBaseCurrency` of the accounts in the value redaction interceptor for the impersonation mode
- Fixed an issue with `comment` of the accounts in the value redaction interceptor for the impersonation mode - Fixed an issue with `comment` of the accounts in the value redaction interceptor for the impersonation mode
- Fixed an issue with `dividendInBaseCurrency` of the accounts in the value redaction interceptor for the impersonation mode - Fixed an issue with `dividendInBaseCurrency` of the accounts in the value redaction interceptor for the impersonation mode
- Fixed an issue with `dividendInBaseCurrency` of the accounts in the value redaction interceptor for the impersonation mode
- Fixed an issue with `interestInBaseCurrency` of the accounts in the value redaction interceptor for the impersonation mode - Fixed an issue with `interestInBaseCurrency` of the accounts in the value redaction interceptor for the impersonation mode
- Fixed an issue with `value` of the accounts in the value redaction interceptor for the impersonation mode - Fixed an issue with `value` of the accounts in the value redaction interceptor for the impersonation mode

12
apps/api/src/services/data-provider/data-provider.service.ts

@ -244,11 +244,15 @@ export class DataProviderService implements OnModuleInit {
}); });
if (!assetProfiles[assetProfileIdentifier]) { if (!assetProfiles[assetProfileIdentifier]) {
if (['FEE', 'INTEREST', 'LIABILITY'].includes(type)) { if (
(dataSource === DataSource.MANUAL && type === 'BUY') ||
['FEE', 'INTEREST', 'LIABILITY'].includes(type)
) {
const assetProfileInImport = assetProfilesWithMarketDataDto?.find( const assetProfileInImport = assetProfilesWithMarketDataDto?.find(
(profile) => { (assetProfile) => {
return ( return (
profile.dataSource === dataSource && profile.symbol === symbol assetProfile.dataSource === dataSource &&
assetProfile.symbol === symbol
); );
} }
); );
@ -257,7 +261,7 @@ export class DataProviderService implements OnModuleInit {
currency, currency,
dataSource, dataSource,
symbol, symbol,
name: assetProfileInImport?.name name: assetProfileInImport?.name ?? symbol
}; };
continue; continue;

2
apps/client/src/app/components/admin-market-data/admin-market-data.component.ts

@ -379,7 +379,7 @@ export class GfAdminMarketDataComponent
this.pageSize = this.pageSize =
this.activeFilters.length === 1 && this.activeFilters.length === 1 &&
this.activeFilters[0].type === 'PRESET_ID' this.activeFilters[0].type === 'PRESET_ID'
? undefined ? Number.MAX_SAFE_INTEGER
: DEFAULT_PAGE_SIZE; : DEFAULT_PAGE_SIZE;
if (pageIndex === 0 && this.paginator) { if (pageIndex === 0 && this.paginator) {

12
apps/client/src/app/pages/admin/admin-page.component.ts

@ -1,7 +1,7 @@
import { TabConfiguration } from '@ghostfolio/common/interfaces'; import { TabConfiguration } from '@ghostfolio/common/interfaces';
import { internalRoutes } from '@ghostfolio/common/routes/routes'; import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs'; import { MatTabsModule } from '@angular/material/tabs';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone'; import { IonIcon } from '@ionic/angular/standalone';
@ -14,7 +14,6 @@ import {
settingsOutline settingsOutline
} from 'ionicons/icons'; } from 'ionicons/icons';
import { DeviceDetectorService } from 'ngx-device-detector'; import { DeviceDetectorService } from 'ngx-device-detector';
import { Subject } from 'rxjs';
@Component({ @Component({
host: { class: 'page has-tabs' }, host: { class: 'page has-tabs' },
@ -23,12 +22,10 @@ import { Subject } from 'rxjs';
styleUrls: ['./admin-page.scss'], styleUrls: ['./admin-page.scss'],
templateUrl: './admin-page.html' templateUrl: './admin-page.html'
}) })
export class AdminPageComponent implements OnDestroy, OnInit { export class AdminPageComponent implements OnInit {
public deviceType: string; public deviceType: string;
public tabs: TabConfiguration[] = []; public tabs: TabConfiguration[] = [];
private unsubscribeSubject = new Subject<void>();
public constructor(private deviceService: DeviceDetectorService) { public constructor(private deviceService: DeviceDetectorService) {
addIcons({ addIcons({
flashOutline, flashOutline,
@ -74,9 +71,4 @@ export class AdminPageComponent implements OnDestroy, OnInit {
} }
]; ];
} }
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
}
} }

15
apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts

@ -188,8 +188,7 @@ export class GfCreateOrUpdateActivityDialogComponent implements OnDestroy {
!this.data.activity?.accountId && !this.data.activity?.accountId &&
this.mode === 'create' this.mode === 'create'
? this.data.accounts[0].id ? this.data.accounts[0].id
: this.data.activity?.accountId, : this.data.activity?.accountId
Validators.required
], ],
assetClass: [this.data.activity?.SymbolProfile?.assetClass], assetClass: [this.data.activity?.SymbolProfile?.assetClass],
assetSubClass: [this.data.activity?.SymbolProfile?.assetSubClass], assetSubClass: [this.data.activity?.SymbolProfile?.assetSubClass],
@ -365,11 +364,6 @@ export class GfCreateOrUpdateActivityDialogComponent implements OnDestroy {
(this.activityForm.get('dataSource').value === 'MANUAL' && (this.activityForm.get('dataSource').value === 'MANUAL' &&
type === 'BUY') type === 'BUY')
) { ) {
this.activityForm
.get('accountId')
.removeValidators(Validators.required);
this.activityForm.get('accountId').updateValueAndValidity();
const currency = const currency =
this.data.accounts.find(({ id }) => { this.data.accounts.find(({ id }) => {
return id === this.activityForm.get('accountId').value; return id === this.activityForm.get('accountId').value;
@ -397,11 +391,6 @@ export class GfCreateOrUpdateActivityDialogComponent implements OnDestroy {
this.activityForm.get('updateAccountBalance').disable(); this.activityForm.get('updateAccountBalance').disable();
this.activityForm.get('updateAccountBalance').setValue(false); this.activityForm.get('updateAccountBalance').setValue(false);
} else if (['FEE', 'INTEREST', 'LIABILITY'].includes(type)) { } else if (['FEE', 'INTEREST', 'LIABILITY'].includes(type)) {
this.activityForm
.get('accountId')
.removeValidators(Validators.required);
this.activityForm.get('accountId').updateValueAndValidity();
const currency = const currency =
this.data.accounts.find(({ id }) => { this.data.accounts.find(({ id }) => {
return id === this.activityForm.get('accountId').value; return id === this.activityForm.get('accountId').value;
@ -447,8 +436,6 @@ export class GfCreateOrUpdateActivityDialogComponent implements OnDestroy {
this.activityForm.get('updateAccountBalance').setValue(false); this.activityForm.get('updateAccountBalance').setValue(false);
} }
} else { } else {
this.activityForm.get('accountId').setValidators(Validators.required);
this.activityForm.get('accountId').updateValueAndValidity();
this.activityForm this.activityForm
.get('dataSource') .get('dataSource')
.setValidators(Validators.required); .setValidators(Validators.required);

8
apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html

@ -84,12 +84,8 @@
> >
<mat-label i18n>Account</mat-label> <mat-label i18n>Account</mat-label>
<mat-select formControlName="accountId"> <mat-select formControlName="accountId">
@if ( <mat-option [value]="null" />
!activityForm.get('accountId').hasValidator(Validators.required) ||
(!activityForm.get('accountId').value && mode === 'update')
) {
<mat-option [value]="null" />
}
@for (account of data.accounts; track account) { @for (account of data.accounts; track account) {
<mat-option [value]="account.id"> <mat-option [value]="account.id">
<div class="d-flex"> <div class="d-flex">

8
apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.component.ts

@ -9,6 +9,7 @@ import {
Component, Component,
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
Inject, Inject,
OnDestroy,
ViewChild ViewChild
} from '@angular/core'; } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@ -52,7 +53,7 @@ import { UserAccountRegistrationDialogParams } from './interfaces/interfaces';
styleUrls: ['./user-account-registration-dialog.scss'], styleUrls: ['./user-account-registration-dialog.scss'],
templateUrl: 'user-account-registration-dialog.html' templateUrl: 'user-account-registration-dialog.html'
}) })
export class GfUserAccountRegistrationDialogComponent { export class GfUserAccountRegistrationDialogComponent implements OnDestroy {
@ViewChild(MatStepper) stepper!: MatStepper; @ViewChild(MatStepper) stepper!: MatStepper;
public accessToken: string; public accessToken: string;
@ -95,4 +96,9 @@ export class GfUserAccountRegistrationDialogComponent {
public onChangeDislaimerChecked() { public onChangeDislaimerChecked() {
this.isDisclaimerChecked = !this.isDisclaimerChecked; this.isDisclaimerChecked = !this.isDisclaimerChecked;
} }
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
}
} }

4
package-lock.json

@ -1,12 +1,12 @@
{ {
"name": "ghostfolio", "name": "ghostfolio",
"version": "2.241.0", "version": "2.242.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ghostfolio", "name": "ghostfolio",
"version": "2.241.0", "version": "2.242.0",
"hasInstallScript": true, "hasInstallScript": true,
"license": "AGPL-3.0", "license": "AGPL-3.0",
"dependencies": { "dependencies": {

2
package.json

@ -1,6 +1,6 @@
{ {
"name": "ghostfolio", "name": "ghostfolio",
"version": "2.241.0", "version": "2.242.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