Feature/persist view mode of holdings tab on home page (#3624)

* Persist view mode of holdings in user settings

* Update changelog
pull/3629/head
Thomas Kaul 6 months ago committed by GitHub
parent c87b08ca8b
commit 02db0db733
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Improved the color assignment in the chart of the holdings tab on the home page (experimental)
- Persisted the view mode of the holdings tab on the home page (experimental)
- Improved the language localization for Catalan (`ca`)
- Improved the language localization for Spanish (`es`)

@ -2,6 +2,7 @@ import { IsCurrencyCode } from '@ghostfolio/api/validators/is-currency-code';
import type {
ColorScheme,
DateRange,
HoldingsViewMode,
ViewMode
} from '@ghostfolio/common/types';
@ -66,6 +67,10 @@ export class UpdateUserSettingDto {
@IsOptional()
'filters.tags'?: string[];
@IsIn(<HoldingsViewMode[]>['CHART', 'TABLE'])
@IsOptional()
holdingsViewMode?: HoldingsViewMode;
@IsBoolean()
@IsOptional()
isExperimentalFeatures?: boolean;

@ -190,7 +190,7 @@ export class UserService {
(user.Settings.settings as UserSettings).dateRange =
(user.Settings.settings as UserSettings).viewMode === 'ZEN'
? 'max'
: (user.Settings.settings as UserSettings)?.dateRange ?? 'max';
: ((user.Settings.settings as UserSettings)?.dateRange ?? 'max');
// Set default value for view mode
if (!(user.Settings.settings as UserSettings).viewMode) {
@ -243,6 +243,9 @@ export class UserService {
// Reset benchmark
user.Settings.settings.benchmark = undefined;
// Reset holdings view mode
user.Settings.settings.holdingsViewMode = undefined;
} else if (user.subscription?.type === 'Premium') {
currentPermissions.push(permissions.reportDataGlitch);

@ -9,7 +9,7 @@ import {
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import {
HoldingType,
HoldingViewMode,
HoldingsViewMode,
ToggleOption
} from '@ghostfolio/common/types';
@ -18,7 +18,7 @@ import { FormControl } from '@angular/forms';
import { Router } from '@angular/router';
import { DeviceDetectorService } from 'ngx-device-detector';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { skip, takeUntil } from 'rxjs/operators';
@Component({
selector: 'gf-home-holdings',
@ -26,6 +26,8 @@ import { takeUntil } from 'rxjs/operators';
templateUrl: './home-holdings.html'
})
export class HomeHoldingsComponent implements OnDestroy, OnInit {
public static DEFAULT_HOLDINGS_VIEW_MODE: HoldingsViewMode = 'TABLE';
public deviceType: string;
public hasImpersonationId: boolean;
public hasPermissionToAccessHoldingsChart: boolean;
@ -37,7 +39,9 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit {
{ label: $localize`Closed`, value: 'CLOSED' }
];
public user: User;
public viewModeFormControl = new FormControl<HoldingViewMode>('TABLE');
public viewModeFormControl = new FormControl<HoldingsViewMode>(
HomeHoldingsComponent.DEFAULT_HOLDINGS_VIEW_MODE
);
private unsubscribeSubject = new Subject<void>();
@ -81,6 +85,21 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit {
this.changeDetectorRef.markForCheck();
}
});
this.viewModeFormControl.valueChanges
.pipe(
// Skip inizialization: "new FormControl"
skip(1),
takeUntil(this.unsubscribeSubject)
)
.subscribe((holdingsViewMode) => {
this.dataService
.putUserSetting({ holdingsViewMode })
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
this.userService.remove();
});
});
}
public onChangeHoldingType(aHoldingType: HoldingType) {
@ -122,9 +141,20 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit {
this.hasPermissionToAccessHoldingsChart &&
this.holdingType === 'ACTIVE'
) {
this.viewModeFormControl.enable();
this.viewModeFormControl.enable({ emitEvent: false });
this.viewModeFormControl.setValue(
this.deviceType === 'mobile'
? HomeHoldingsComponent.DEFAULT_HOLDINGS_VIEW_MODE
: this.user?.settings?.holdingsViewMode ||
HomeHoldingsComponent.DEFAULT_HOLDINGS_VIEW_MODE,
{ emitEvent: false }
);
} else if (this.holdingType === 'CLOSED') {
this.viewModeFormControl.setValue('TABLE');
this.viewModeFormControl.setValue(
HomeHoldingsComponent.DEFAULT_HOLDINGS_VIEW_MODE,
{ emitEvent: false }
);
}
this.holdings = undefined;

@ -1,4 +1,9 @@
import { ColorScheme, DateRange, ViewMode } from '@ghostfolio/common/types';
import {
ColorScheme,
DateRange,
HoldingsViewMode,
ViewMode
} from '@ghostfolio/common/types';
export interface UserSettings {
annualInterestRate?: number;
@ -9,6 +14,7 @@ export interface UserSettings {
emergencyFund?: number;
'filters.accounts'?: string[];
'filters.tags'?: string[];
holdingsViewMode?: HoldingsViewMode;
isExperimentalFeatures?: boolean;
isRestrictedView?: boolean;
language?: string;

@ -1 +0,0 @@
export type HoldingViewMode = 'CHART' | 'TABLE';

@ -0,0 +1 @@
export type HoldingsViewMode = 'CHART' | 'TABLE';

@ -8,7 +8,7 @@ import type { DateRange } from './date-range.type';
import type { Granularity } from './granularity.type';
import type { GroupBy } from './group-by.type';
import type { HoldingType } from './holding-type.type';
import type { HoldingViewMode } from './holding-view-mode.type';
import type { HoldingsViewMode } from './holdings-view-mode.type';
import type { MarketAdvanced } from './market-advanced.type';
import type { MarketDataPreset } from './market-data-preset.type';
import type { MarketState } from './market-state.type';
@ -31,7 +31,7 @@ export type {
Granularity,
GroupBy,
HoldingType,
HoldingViewMode,
HoldingsViewMode,
Market,
MarketAdvanced,
MarketDataPreset,

Loading…
Cancel
Save