mirror of https://github.com/ghostfolio/ghostfolio
Thomas Kaul
8 months ago
committed by
GitHub
24 changed files with 302 additions and 9 deletions
@ -0,0 +1,5 @@ |
|||||
|
export interface Holding { |
||||
|
allocationInPercentage?: number; |
||||
|
name: string; |
||||
|
valueInBaseCurrency: number; |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
export * from './top-holdings.component'; |
@ -0,0 +1,61 @@ |
|||||
|
<table |
||||
|
class="gf-table w-100" |
||||
|
mat-table |
||||
|
matSort |
||||
|
matSortActive="allocationInPercentage" |
||||
|
matSortDirection="desc" |
||||
|
[dataSource]="dataSource" |
||||
|
> |
||||
|
<ng-container matColumnDef="name"> |
||||
|
<th *matHeaderCellDef class="px-2" mat-header-cell mat-sort-header> |
||||
|
<ng-container i18n>Name</ng-container> |
||||
|
</th> |
||||
|
<td *matCellDef="let element" class="px-2" mat-cell> |
||||
|
{{ element?.name }} |
||||
|
</td> |
||||
|
</ng-container> |
||||
|
|
||||
|
<ng-container matColumnDef="valueInBaseCurrency"> |
||||
|
<th |
||||
|
*matHeaderCellDef |
||||
|
class="justify-content-end px-2" |
||||
|
mat-header-cell |
||||
|
mat-sort-header |
||||
|
> |
||||
|
<ng-container i18n>Value</ng-container> |
||||
|
</th> |
||||
|
<td *matCellDef="let element" class="px-2" mat-cell> |
||||
|
<div class="d-flex justify-content-end"> |
||||
|
<gf-value |
||||
|
[isCurrency]="true" |
||||
|
[locale]="locale" |
||||
|
[value]="element?.valueInBaseCurrency" |
||||
|
/> |
||||
|
</div> |
||||
|
</td> |
||||
|
</ng-container> |
||||
|
|
||||
|
<ng-container matColumnDef="allocationInPercentage"> |
||||
|
<th |
||||
|
*matHeaderCellDef |
||||
|
class="justify-content-end px-2" |
||||
|
mat-header-cell |
||||
|
mat-sort-header |
||||
|
> |
||||
|
<span class="d-none d-sm-block" i18n>Allocation</span> |
||||
|
<span class="d-block d-sm-none" title="Allocation">%</span> |
||||
|
</th> |
||||
|
<td *matCellDef="let element" class="px-2" mat-cell> |
||||
|
<div class="d-flex justify-content-end"> |
||||
|
<gf-value |
||||
|
[isPercent]="true" |
||||
|
[locale]="locale" |
||||
|
[value]="element?.allocationInPercentage" |
||||
|
/> |
||||
|
</div> |
||||
|
</td> |
||||
|
</ng-container> |
||||
|
|
||||
|
<tr *matHeaderRowDef="displayedColumns" mat-header-row></tr> |
||||
|
<tr *matRowDef="let row; columns: displayedColumns" mat-row></tr> |
||||
|
</table> |
@ -0,0 +1,13 @@ |
|||||
|
:host { |
||||
|
display: block; |
||||
|
|
||||
|
.gf-table { |
||||
|
th { |
||||
|
::ng-deep { |
||||
|
.mat-sort-header-container { |
||||
|
justify-content: inherit; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,63 @@ |
|||||
|
import { getLocale } from '@ghostfolio/common/helper'; |
||||
|
import { Holding } from '@ghostfolio/common/interfaces'; |
||||
|
import { GfValueComponent } from '@ghostfolio/ui/value'; |
||||
|
|
||||
|
import { |
||||
|
CUSTOM_ELEMENTS_SCHEMA, |
||||
|
ChangeDetectionStrategy, |
||||
|
Component, |
||||
|
Input, |
||||
|
OnChanges, |
||||
|
OnDestroy, |
||||
|
OnInit, |
||||
|
ViewChild |
||||
|
} from '@angular/core'; |
||||
|
import { MatButtonModule } from '@angular/material/button'; |
||||
|
import { MatSort, MatSortModule } from '@angular/material/sort'; |
||||
|
import { MatTableDataSource, MatTableModule } from '@angular/material/table'; |
||||
|
import { get } from 'lodash'; |
||||
|
import { Subject } from 'rxjs'; |
||||
|
|
||||
|
@Component({ |
||||
|
changeDetection: ChangeDetectionStrategy.OnPush, |
||||
|
imports: [GfValueComponent, MatButtonModule, MatSortModule, MatTableModule], |
||||
|
schemas: [CUSTOM_ELEMENTS_SCHEMA], |
||||
|
selector: 'gf-top-holdings', |
||||
|
standalone: true, |
||||
|
styleUrls: ['./top-holdings.component.scss'], |
||||
|
templateUrl: './top-holdings.component.html' |
||||
|
}) |
||||
|
export class GfTopHoldingsComponent implements OnChanges, OnDestroy, OnInit { |
||||
|
@Input() baseCurrency: string; |
||||
|
@Input() locale = getLocale(); |
||||
|
@Input() topHoldings: Holding[]; |
||||
|
|
||||
|
@ViewChild(MatSort) sort: MatSort; |
||||
|
|
||||
|
public dataSource: MatTableDataSource<Holding> = new MatTableDataSource(); |
||||
|
public displayedColumns: string[] = [ |
||||
|
'name', |
||||
|
'valueInBaseCurrency', |
||||
|
'allocationInPercentage' |
||||
|
]; |
||||
|
|
||||
|
private unsubscribeSubject = new Subject<void>(); |
||||
|
|
||||
|
public constructor() {} |
||||
|
|
||||
|
public ngOnInit() {} |
||||
|
|
||||
|
public ngOnChanges() { |
||||
|
if (this.topHoldings) { |
||||
|
this.dataSource = new MatTableDataSource(this.topHoldings); |
||||
|
|
||||
|
this.dataSource.sort = this.sort; |
||||
|
this.dataSource.sortingDataAccessor = get; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public ngOnDestroy() { |
||||
|
this.unsubscribeSubject.next(); |
||||
|
this.unsubscribeSubject.complete(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
-- AlterTable |
||||
|
ALTER TABLE "SymbolProfile" ADD COLUMN "holdings" JSONB DEFAULT '[]'; |
||||
|
|
||||
|
-- AlterTable |
||||
|
ALTER TABLE "SymbolProfileOverrides" ADD COLUMN "holdings" JSONB DEFAULT '[]'; |
Loading…
Reference in new issue