Browse Source

Feature/simplified mode in holdings table component (#7830)

* Add simplified mode to holdings table component

* Update changelog
pull/7836/head
Thomas Kaul 3 days ago
committed by GitHub
parent
commit
7a6f54ab3b
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      CHANGELOG.md
  2. 18
      libs/ui/src/lib/holdings-table/holdings-table.component.html
  3. 15
      libs/ui/src/lib/holdings-table/holdings-table.component.stories.ts
  4. 21
      libs/ui/src/lib/holdings-table/holdings-table.component.ts

4
CHANGELOG.md

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased ## Unreleased
### Added
- Added a simplified mode to the holdings table component
### Changed ### Changed
- Made the details of holdings excluded from analysis accessible via the activities table - Made the details of holdings excluded from analysis accessible via the activities table

18
libs/ui/src/lib/holdings-table/holdings-table.component.html

@ -3,9 +3,9 @@
class="gf-table w-100" class="gf-table w-100"
mat-table mat-table
matSort matSort
matSortActive="allocationInPercentage"
matSortDirection="desc"
[dataSource]="dataSource" [dataSource]="dataSource"
[matSortActive]="sortActive()"
[matSortDirection]="sortDirection()"
> >
<ng-container matColumnDef="icon" sticky> <ng-container matColumnDef="icon" sticky>
<th *matHeaderCellDef class="px-1" mat-header-cell></th> <th *matHeaderCellDef class="px-1" mat-header-cell></th>
@ -34,9 +34,11 @@
<span>({{ element.assetProfile.assetSubClassLabel }})</span> <span>({{ element.assetProfile.assetSubClassLabel }})</span>
} }
</div> </div>
<div> @if (mode() === 'default') {
<small class="text-muted">{{ element.assetProfile.symbol }}</small> <div>
</div> <small class="text-muted">{{ element.assetProfile.symbol }}</small>
</div>
}
</td> </td>
</ng-container> </ng-container>
@ -181,7 +183,11 @@
</td> </td>
</ng-container> </ng-container>
<tr *matHeaderRowDef="displayedColumns()" mat-header-row></tr> <tr
*matHeaderRowDef="displayedColumns()"
mat-header-row
[class.d-none]="mode() === 'simple'"
></tr>
<tr <tr
*matRowDef="let row; columns: displayedColumns()" *matRowDef="let row; columns: displayedColumns()"
mat-row mat-row

15
libs/ui/src/lib/holdings-table/holdings-table.component.stories.ts

@ -9,6 +9,8 @@ import type { Meta, StoryObj } from '@storybook/angular';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { GfEntityLogoComponent } from '../entity-logo'; import { GfEntityLogoComponent } from '../entity-logo';
import { EntityLogoImageSourceService } from '../entity-logo/entity-logo-image-source.service';
import { EntityLogoImageSourceServiceMock } from '../mocks/entity-logo-image-source.service.mock';
import { holdings } from '../mocks/holdings'; import { holdings } from '../mocks/holdings';
import { GfValueComponent } from '../value'; import { GfValueComponent } from '../value';
import { GfHoldingsTableComponent } from './holdings-table.component'; import { GfHoldingsTableComponent } from './holdings-table.component';
@ -28,6 +30,12 @@ export default {
MatSortModule, MatSortModule,
MatTableModule, MatTableModule,
NgxSkeletonLoaderModule NgxSkeletonLoaderModule
],
providers: [
{
provide: EntityLogoImageSourceService,
useValue: new EntityLogoImageSourceServiceMock()
}
] ]
}) })
] ]
@ -56,3 +64,10 @@ export const Default: Story = {
pageSize: Number.MAX_SAFE_INTEGER pageSize: Number.MAX_SAFE_INTEGER
} }
}; };
export const Simple: Story = {
args: {
...Default.args,
mode: 'simple'
}
};

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

@ -22,7 +22,7 @@ import {
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog'; import { MatDialogModule } from '@angular/material/dialog';
import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
import { MatSort, MatSortModule } from '@angular/material/sort'; import { MatSort, MatSortModule, SortDirection } from '@angular/material/sort';
import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { MatTableDataSource, MatTableModule } from '@angular/material/table';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
@ -52,6 +52,7 @@ export class GfHoldingsTableComponent {
public readonly hasPermissionToShowValues = input(true); public readonly hasPermissionToShowValues = input(true);
public readonly holdings = input.required<PortfolioPosition[] | undefined>(); public readonly holdings = input.required<PortfolioPosition[] | undefined>();
public readonly locale = input(getLocale()); public readonly locale = input(getLocale());
public readonly mode = input<'default' | 'simple'>('default');
public readonly pageSize = model(Number.MAX_SAFE_INTEGER); public readonly pageSize = model(Number.MAX_SAFE_INTEGER);
public readonly holdingClicked = output<AssetProfileIdentifier>(); public readonly holdingClicked = output<AssetProfileIdentifier>();
@ -62,6 +63,10 @@ export class GfHoldingsTableComponent {
protected readonly dataSource = new MatTableDataSource<PortfolioPosition>([]); protected readonly dataSource = new MatTableDataSource<PortfolioPosition>([]);
protected readonly displayedColumns = computed(() => { protected readonly displayedColumns = computed(() => {
if (this.mode() === 'simple') {
return ['icon', 'nameWithSymbol', 'performanceInPercentage'];
}
const columns = ['icon', 'nameWithSymbol', 'dateOfFirstActivity']; const columns = ['icon', 'nameWithSymbol', 'dateOfFirstActivity'];
if (this.hasPermissionToShowQuantities()) { if (this.hasPermissionToShowQuantities()) {
@ -82,7 +87,19 @@ export class GfHoldingsTableComponent {
return columns; return columns;
}); });
protected readonly isLoading = computed(() => !this.holdings()); protected readonly isLoading = computed(() => {
return !this.holdings();
});
protected readonly sortActive = computed(() => {
return this.mode() === 'default'
? 'allocationInPercentage'
: 'assetProfile.name';
});
protected readonly sortDirection = computed<SortDirection>(() => {
return this.mode() === 'default' ? 'desc' : 'asc';
});
public constructor() { public constructor() {
this.dataSource.sortingDataAccessor = getLowercase; this.dataSource.sortingDataAccessor = getLowercase;

Loading…
Cancel
Save