diff --git a/apps/client/tsconfig.json b/apps/client/tsconfig.json index 2899fc61c6..a6815ec125 100644 --- a/apps/client/tsconfig.json +++ b/apps/client/tsconfig.json @@ -21,7 +21,7 @@ "strictDomEventTypes": true, "strictDomLocalRefTypes": true, "strictInputAccessModifiers": true, - "strictInputTypes": false, + "strictInputTypes": true, "strictLiteralTypes": true, "strictNullInputTypes": true, "strictOutputEventTypes": true, diff --git a/libs/ui/src/lib/activities-table/activities-table.component.ts b/libs/ui/src/lib/activities-table/activities-table.component.ts index c8ee009508..8a7b59645a 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.ts +++ b/libs/ui/src/lib/activities-table/activities-table.component.ts @@ -71,6 +71,7 @@ import { GfActivityTypeComponent } from '../activity-type/activity-type.componen import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component'; import { GfNoActivitiesInfoComponent } from '../no-activities-info/no-activities-info.component'; import { GfValueComponent } from '../value/value.component'; +import { ActivitiesTableItem } from './interfaces/interfaces'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -99,7 +100,11 @@ import { GfValueComponent } from '../value/value.component'; styleUrls: ['./activities-table.component.scss'], templateUrl: './activities-table.component.html' }) -export class GfActivitiesTableComponent implements AfterViewInit, OnInit { +export class GfActivitiesTableComponent< + T extends ActivitiesTableItem = Activity +> + implements AfterViewInit, OnInit +{ @Input() public baseCurrency?: string; @Input() public deviceType: string; @Input() public hasActivities: boolean; @@ -127,7 +132,7 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit { @Output() import = new EventEmitter(); @Output() importDividends = new EventEmitter(); @Output() pageChanged = new EventEmitter(); - @Output() selectedActivities = new EventEmitter(); + @Output() selectedActivities = new EventEmitter(); @Output() sortChanged = new EventEmitter(); @Output() typesFilterChanged = new EventEmitter(); @@ -138,12 +143,12 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit { public hasErrors = false; public isDraftActivity = isDraftActivity; public isUUID = isUUID; - public selectedRows = new SelectionModel(true, []); + public selectedRows = new SelectionModel(true, []); public typesFilter = new FormControl([]); public readonly activityTypes = input([]); public readonly dataSource = input.required< - MatTableDataSource | undefined + MatTableDataSource | undefined >(); public readonly showAccountColumn = input(true); public readonly showCheckbox = input(false); @@ -158,11 +163,13 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit { { clone: string[]; update: string[] } >(); - for (const { id } of this.dataSource()?.data ?? []) { - routerLinks.set(id, { - clone: clone.routerLink(id), - update: update.routerLink(id) - }); + for (const activity of this.dataSource()?.data ?? []) { + if (activity.id) { + routerLinks.set(activity.id, { + clone: clone.routerLink(activity.id), + update: update.routerLink(activity.id) + }); + } } return routerLinks; @@ -276,7 +283,7 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit { return numSelectedRows === numTotalRows; } - public canClickActivity(activity: Activity) { + public canClickActivity(activity: T) { return ( this.hasPermissionToOpenDetails && isDraftActivity(activity) === false && @@ -302,7 +309,7 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit { this.pageChanged.emit(page); } - public onClickActivity(activity: Activity) { + public onClickActivity(activity: T) { if (this.showCheckbox()) { if (!activity.error) { this.selectedRows.toggle(activity); @@ -355,6 +362,9 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit { .map((activity) => { return activity.id; }) + .filter((id): id is string => { + return !!id; + }) ); } diff --git a/libs/ui/src/lib/activities-table/index.ts b/libs/ui/src/lib/activities-table/index.ts index 82eee49b1c..dae66efe42 100644 --- a/libs/ui/src/lib/activities-table/index.ts +++ b/libs/ui/src/lib/activities-table/index.ts @@ -1 +1,2 @@ export * from './activities-table.component'; +export * from './interfaces/interfaces'; diff --git a/libs/ui/src/lib/activities-table/interfaces/interfaces.ts b/libs/ui/src/lib/activities-table/interfaces/interfaces.ts new file mode 100644 index 0000000000..ac95331159 --- /dev/null +++ b/libs/ui/src/lib/activities-table/interfaces/interfaces.ts @@ -0,0 +1,21 @@ +import { Activity, EnhancedAssetProfile } from '@ghostfolio/common/interfaces'; + +export interface ActivitiesTableItem + extends + Pick< + Activity, + | 'currency' + | 'date' + | 'fee' + | 'quantity' + | 'type' + | 'unitPrice' + | 'value' + | 'valueInBaseCurrency' + >, + Partial> { + assetProfile: Pick< + EnhancedAssetProfile, + 'currency' | 'dataSource' | 'name' | 'symbol' + >; +} diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.ts b/libs/ui/src/lib/holdings-table/holdings-table.component.ts index 0be6e54f6e..3181cc1347 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.ts +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.ts @@ -6,10 +6,7 @@ import { getLowercase, isCashPosition } from '@ghostfolio/common/helper'; -import { - AssetProfileIdentifier, - PortfolioPosition -} from '@ghostfolio/common/interfaces'; +import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import { CUSTOM_ELEMENTS_SCHEMA, @@ -31,6 +28,7 @@ import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component'; import { GfValueComponent } from '../value/value.component'; +import { HoldingsTableItem } from './interfaces/interfaces'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -53,7 +51,7 @@ export class GfHoldingsTableComponent { public readonly hasPermissionToOpenDetails = input(true); public readonly hasPermissionToShowQuantities = input(true); public readonly hasPermissionToShowValues = input(true); - public readonly holdings = input.required(); + public readonly holdings = input.required(); public readonly locale = input(getLocale(), { transform: (value?: string) => { @@ -69,7 +67,7 @@ export class GfHoldingsTableComponent { protected readonly paginator = viewChild.required(MatPaginator); protected readonly sort = viewChild.required(MatSort); - protected readonly dataSource = new MatTableDataSource([]); + protected readonly dataSource = new MatTableDataSource([]); protected readonly displayedColumns = computed(() => { if (this.mode() === 'simple') { @@ -134,13 +132,13 @@ export class GfHoldingsTableComponent { }); } - protected canShowDetails(holding: PortfolioPosition): boolean { + protected canShowDetails(holding: HoldingsTableItem): boolean { return this.hasPermissionToOpenDetails() && canOpenHoldingDetail(holding); } protected getCountryCodeForCashPosition({ assetProfile - }: PortfolioPosition): string { + }: HoldingsTableItem): string { return isCashPosition(assetProfile) ? getCountryCodeFromCurrency(assetProfile.currency) : ''; diff --git a/libs/ui/src/lib/holdings-table/index.ts b/libs/ui/src/lib/holdings-table/index.ts index f2dd696ceb..75a3238b90 100644 --- a/libs/ui/src/lib/holdings-table/index.ts +++ b/libs/ui/src/lib/holdings-table/index.ts @@ -1 +1,2 @@ export * from './holdings-table.component'; +export * from './interfaces/interfaces'; diff --git a/libs/ui/src/lib/holdings-table/interfaces/interfaces.ts b/libs/ui/src/lib/holdings-table/interfaces/interfaces.ts new file mode 100644 index 0000000000..56743b872d --- /dev/null +++ b/libs/ui/src/lib/holdings-table/interfaces/interfaces.ts @@ -0,0 +1,17 @@ +import { PortfolioPosition } from '@ghostfolio/common/interfaces'; + +export interface HoldingsTableItem + extends + Pick< + PortfolioPosition, + | 'allocationInPercentage' + | 'assetProfile' + | 'dateOfFirstActivity' + | 'netPerformancePercentWithCurrencyEffect' + >, + Partial< + Pick< + PortfolioPosition, + 'netPerformanceWithCurrencyEffect' | 'quantity' | 'valueInBaseCurrency' + > + > {}