Browse Source

Task/widen input types in holdings and activities tables and enable strictInputTypes (#8083)

Widen input types
pull/8085/head
Kenrick Tandrian 23 hours ago
committed by GitHub
parent
commit
035462af00
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      apps/client/tsconfig.json
  2. 32
      libs/ui/src/lib/activities-table/activities-table.component.ts
  3. 1
      libs/ui/src/lib/activities-table/index.ts
  4. 21
      libs/ui/src/lib/activities-table/interfaces/interfaces.ts
  5. 14
      libs/ui/src/lib/holdings-table/holdings-table.component.ts
  6. 1
      libs/ui/src/lib/holdings-table/index.ts
  7. 17
      libs/ui/src/lib/holdings-table/interfaces/interfaces.ts

2
apps/client/tsconfig.json

@ -21,7 +21,7 @@
"strictDomEventTypes": true, "strictDomEventTypes": true,
"strictDomLocalRefTypes": true, "strictDomLocalRefTypes": true,
"strictInputAccessModifiers": true, "strictInputAccessModifiers": true,
"strictInputTypes": false, "strictInputTypes": true,
"strictLiteralTypes": true, "strictLiteralTypes": true,
"strictNullInputTypes": true, "strictNullInputTypes": true,
"strictOutputEventTypes": true, "strictOutputEventTypes": true,

32
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 { GfEntityLogoComponent } from '../entity-logo/entity-logo.component';
import { GfNoActivitiesInfoComponent } from '../no-activities-info/no-activities-info.component'; import { GfNoActivitiesInfoComponent } from '../no-activities-info/no-activities-info.component';
import { GfValueComponent } from '../value/value.component'; import { GfValueComponent } from '../value/value.component';
import { ActivitiesTableItem } from './interfaces/interfaces';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
@ -99,7 +100,11 @@ import { GfValueComponent } from '../value/value.component';
styleUrls: ['./activities-table.component.scss'], styleUrls: ['./activities-table.component.scss'],
templateUrl: './activities-table.component.html' 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 baseCurrency?: string;
@Input() public deviceType: string; @Input() public deviceType: string;
@Input() public hasActivities: boolean; @Input() public hasActivities: boolean;
@ -127,7 +132,7 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
@Output() import = new EventEmitter<void>(); @Output() import = new EventEmitter<void>();
@Output() importDividends = new EventEmitter<AssetProfileIdentifier>(); @Output() importDividends = new EventEmitter<AssetProfileIdentifier>();
@Output() pageChanged = new EventEmitter<PageEvent>(); @Output() pageChanged = new EventEmitter<PageEvent>();
@Output() selectedActivities = new EventEmitter<Activity[]>(); @Output() selectedActivities = new EventEmitter<T[]>();
@Output() sortChanged = new EventEmitter<Sort>(); @Output() sortChanged = new EventEmitter<Sort>();
@Output() typesFilterChanged = new EventEmitter<string[]>(); @Output() typesFilterChanged = new EventEmitter<string[]>();
@ -138,12 +143,12 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
public hasErrors = false; public hasErrors = false;
public isDraftActivity = isDraftActivity; public isDraftActivity = isDraftActivity;
public isUUID = isUUID; public isUUID = isUUID;
public selectedRows = new SelectionModel<Activity>(true, []); public selectedRows = new SelectionModel<T>(true, []);
public typesFilter = new FormControl<string[]>([]); public typesFilter = new FormControl<string[]>([]);
public readonly activityTypes = input<ActivityType[]>([]); public readonly activityTypes = input<ActivityType[]>([]);
public readonly dataSource = input.required< public readonly dataSource = input.required<
MatTableDataSource<Activity> | undefined MatTableDataSource<T> | undefined
>(); >();
public readonly showAccountColumn = input(true); public readonly showAccountColumn = input(true);
public readonly showCheckbox = input(false); public readonly showCheckbox = input(false);
@ -158,11 +163,13 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
{ clone: string[]; update: string[] } { clone: string[]; update: string[] }
>(); >();
for (const { id } of this.dataSource()?.data ?? []) { for (const activity of this.dataSource()?.data ?? []) {
routerLinks.set(id, { if (activity.id) {
clone: clone.routerLink(id), routerLinks.set(activity.id, {
update: update.routerLink(id) clone: clone.routerLink(activity.id),
}); update: update.routerLink(activity.id)
});
}
} }
return routerLinks; return routerLinks;
@ -276,7 +283,7 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
return numSelectedRows === numTotalRows; return numSelectedRows === numTotalRows;
} }
public canClickActivity(activity: Activity) { public canClickActivity(activity: T) {
return ( return (
this.hasPermissionToOpenDetails && this.hasPermissionToOpenDetails &&
isDraftActivity(activity) === false && isDraftActivity(activity) === false &&
@ -302,7 +309,7 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
this.pageChanged.emit(page); this.pageChanged.emit(page);
} }
public onClickActivity(activity: Activity) { public onClickActivity(activity: T) {
if (this.showCheckbox()) { if (this.showCheckbox()) {
if (!activity.error) { if (!activity.error) {
this.selectedRows.toggle(activity); this.selectedRows.toggle(activity);
@ -355,6 +362,9 @@ export class GfActivitiesTableComponent implements AfterViewInit, OnInit {
.map((activity) => { .map((activity) => {
return activity.id; return activity.id;
}) })
.filter((id): id is string => {
return !!id;
})
); );
} }

1
libs/ui/src/lib/activities-table/index.ts

@ -1 +1,2 @@
export * from './activities-table.component'; export * from './activities-table.component';
export * from './interfaces/interfaces';

21
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<Pick<Activity, 'account' | 'comment' | 'error' | 'id' | 'tags'>> {
assetProfile: Pick<
EnhancedAssetProfile,
'currency' | 'dataSource' | 'name' | 'symbol'
>;
}

14
libs/ui/src/lib/holdings-table/holdings-table.component.ts

@ -6,10 +6,7 @@ import {
getLowercase, getLowercase,
isCashPosition isCashPosition
} from '@ghostfolio/common/helper'; } from '@ghostfolio/common/helper';
import { import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
AssetProfileIdentifier,
PortfolioPosition
} from '@ghostfolio/common/interfaces';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
@ -31,6 +28,7 @@ import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component'; import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component';
import { GfValueComponent } from '../value/value.component'; import { GfValueComponent } from '../value/value.component';
import { HoldingsTableItem } from './interfaces/interfaces';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
@ -53,7 +51,7 @@ export class GfHoldingsTableComponent {
public readonly hasPermissionToOpenDetails = input(true); public readonly hasPermissionToOpenDetails = input(true);
public readonly hasPermissionToShowQuantities = input(true); public readonly hasPermissionToShowQuantities = input(true);
public readonly hasPermissionToShowValues = input(true); public readonly hasPermissionToShowValues = input(true);
public readonly holdings = input.required<PortfolioPosition[] | undefined>(); public readonly holdings = input.required<HoldingsTableItem[] | undefined>();
public readonly locale = input(getLocale(), { public readonly locale = input(getLocale(), {
transform: (value?: string) => { transform: (value?: string) => {
@ -69,7 +67,7 @@ export class GfHoldingsTableComponent {
protected readonly paginator = viewChild.required(MatPaginator); protected readonly paginator = viewChild.required(MatPaginator);
protected readonly sort = viewChild.required(MatSort); protected readonly sort = viewChild.required(MatSort);
protected readonly dataSource = new MatTableDataSource<PortfolioPosition>([]); protected readonly dataSource = new MatTableDataSource<HoldingsTableItem>([]);
protected readonly displayedColumns = computed(() => { protected readonly displayedColumns = computed(() => {
if (this.mode() === 'simple') { 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); return this.hasPermissionToOpenDetails() && canOpenHoldingDetail(holding);
} }
protected getCountryCodeForCashPosition({ protected getCountryCodeForCashPosition({
assetProfile assetProfile
}: PortfolioPosition): string { }: HoldingsTableItem): string {
return isCashPosition(assetProfile) return isCashPosition(assetProfile)
? getCountryCodeFromCurrency(assetProfile.currency) ? getCountryCodeFromCurrency(assetProfile.currency)
: ''; : '';

1
libs/ui/src/lib/holdings-table/index.ts

@ -1 +1,2 @@
export * from './holdings-table.component'; export * from './holdings-table.component';
export * from './interfaces/interfaces';

17
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'
>
> {}
Loading…
Cancel
Save