From 38afc839eb4904d1b8376cb240e027ae9e3e4a7a Mon Sep 17 00:00:00 2001 From: David Requeno <108202767+DavidReque@users.noreply.github.com> Date: Sat, 2 Aug 2025 02:47:48 -0600 Subject: [PATCH] Feature/move accounts table component to @ghostfolio/ui (#5278) * Move accounts table component to @ghostfolio/ui * Add Storybook story * Update changelog --- CHANGELOG.md | 1 + .../holding-detail-dialog.component.ts | 2 +- .../pages/accounts/accounts-page.component.ts | 2 +- .../accounts-table.component.html | 0 .../accounts-table.component.scss | 0 .../accounts-table.component.stories.ts | 146 ++++++++++++++++++ .../accounts-table.component.ts | 10 +- libs/ui/src/lib/accounts-table/index.ts | 1 + .../tags-selector.component.stories.ts | 2 +- 9 files changed, 156 insertions(+), 8 deletions(-) rename {apps/client/src/app/components => libs/ui/src/lib}/accounts-table/accounts-table.component.html (100%) rename {apps/client/src/app/components => libs/ui/src/lib}/accounts-table/accounts-table.component.scss (100%) create mode 100644 libs/ui/src/lib/accounts-table/accounts-table.component.stories.ts rename {apps/client/src/app/components => libs/ui/src/lib}/accounts-table/accounts-table.component.ts (94%) create mode 100644 libs/ui/src/lib/accounts-table/index.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 75e40bcb0..62561157d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added support to exclude an activity from analysis based on tags +- Added a _Storybook_ story for the accounts table component - Added a _Storybook_ story for the membership card component ### Changed diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts index 50065e3da..8f0e6ae68 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts @@ -1,5 +1,4 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; -import { GfAccountsTableComponent } from '@ghostfolio/client/components/accounts-table/accounts-table.component'; import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module'; import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module'; import { DataService } from '@ghostfolio/client/services/data.service'; @@ -15,6 +14,7 @@ import { } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { internalRoutes } from '@ghostfolio/common/routes/routes'; +import { GfAccountsTableComponent } from '@ghostfolio/ui/accounts-table'; import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table'; import { GfDataProviderCreditsComponent } from '@ghostfolio/ui/data-provider-credits'; import { GfHistoricalMarketDataEditorComponent } from '@ghostfolio/ui/historical-market-data-editor'; diff --git a/apps/client/src/app/pages/accounts/accounts-page.component.ts b/apps/client/src/app/pages/accounts/accounts-page.component.ts index ff17c861f..f7030173d 100644 --- a/apps/client/src/app/pages/accounts/accounts-page.component.ts +++ b/apps/client/src/app/pages/accounts/accounts-page.component.ts @@ -4,13 +4,13 @@ import { UpdateAccountDto } from '@ghostfolio/api/app/account/update-account.dto import { AccountDetailDialog } from '@ghostfolio/client/components/account-detail-dialog/account-detail-dialog.component'; import { GfAccountDetailDialogModule } from '@ghostfolio/client/components/account-detail-dialog/account-detail-dialog.module'; import { AccountDetailDialogParams } from '@ghostfolio/client/components/account-detail-dialog/interfaces/interfaces'; -import { GfAccountsTableComponent } from '@ghostfolio/client/components/accounts-table/accounts-table.component'; import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; +import { GfAccountsTableComponent } from '@ghostfolio/ui/accounts-table'; import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; diff --git a/apps/client/src/app/components/accounts-table/accounts-table.component.html b/libs/ui/src/lib/accounts-table/accounts-table.component.html similarity index 100% rename from apps/client/src/app/components/accounts-table/accounts-table.component.html rename to libs/ui/src/lib/accounts-table/accounts-table.component.html diff --git a/apps/client/src/app/components/accounts-table/accounts-table.component.scss b/libs/ui/src/lib/accounts-table/accounts-table.component.scss similarity index 100% rename from apps/client/src/app/components/accounts-table/accounts-table.component.scss rename to libs/ui/src/lib/accounts-table/accounts-table.component.scss diff --git a/libs/ui/src/lib/accounts-table/accounts-table.component.stories.ts b/libs/ui/src/lib/accounts-table/accounts-table.component.stories.ts new file mode 100644 index 000000000..e13df2222 --- /dev/null +++ b/libs/ui/src/lib/accounts-table/accounts-table.component.stories.ts @@ -0,0 +1,146 @@ +import { CommonModule } from '@angular/common'; +import { MatButtonModule } from '@angular/material/button'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatSortModule } from '@angular/material/sort'; +import { MatTableModule } from '@angular/material/table'; +import { RouterModule } from '@angular/router'; +import { IonIcon } from '@ionic/angular/standalone'; +import { moduleMetadata } from '@storybook/angular'; +import type { Meta, StoryObj } from '@storybook/angular'; +import { NotificationService } from 'apps/client/src/app/core/notification/notification.service'; +import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; + +import { GfEntityLogoComponent } from '../entity-logo'; +import { GfValueComponent } from '../value'; +import { GfAccountsTableComponent } from './accounts-table.component'; + +const accounts = [ + { + allocationInPercentage: null, + balance: 278, + balanceInBaseCurrency: 278, + comment: null, + createdAt: new Date('2025-06-01T06:52:49.063Z'), + currency: 'USD', + id: '460d7401-ca43-4ed4-b08e-349f1822e9db', + isExcluded: false, + name: 'Coinbase Account', + platform: { + id: '8dc24b88-bb92-4152-af25-fe6a31643e26', + name: 'Coinbase', + url: 'https://www.coinbase.com' + }, + platformId: '8dc24b88-bb92-4152-af25-fe6a31643e26', + transactionCount: 0, + updatedAt: new Date('2025-06-01T06:52:49.063Z'), + userId: '081aa387-487d-4438-83a4-3060eb2a016e', + value: 278, + valueInBaseCurrency: 278 + }, + { + allocationInPercentage: null, + balance: 12000, + balanceInBaseCurrency: 12000, + comment: null, + createdAt: new Date('2025-06-01T06:48:53.055Z'), + currency: 'USD', + id: '6d773e31-0583-4c85-a247-e69870b4f1ee', + isExcluded: false, + name: 'Private Banking Account', + platform: { + id: '43e8fcd1-5b79-4100-b678-d2229bd1660d', + name: 'J.P. Morgan', + url: 'https://www.jpmorgan.com' + }, + platformId: '43e8fcd1-5b79-4100-b678-d2229bd1660d', + transactionCount: 0, + updatedAt: new Date('2025-06-01T06:48:53.055Z'), + userId: '081aa387-487d-4438-83a4-3060eb2a016e', + value: 12000, + valueInBaseCurrency: 12000 + }, + { + allocationInPercentage: null, + balance: 150.2, + balanceInBaseCurrency: 150.2, + comment: null, + createdAt: new Date('2025-05-31T13:00:13.940Z'), + currency: 'USD', + id: '776bd1e9-b2f6-4f7e-933d-18756c2f0625', + isExcluded: false, + name: 'Trading Account', + platform: { + id: '9da3a8a7-4795-43e3-a6db-ccb914189737', + name: 'Interactive Brokers', + url: 'https://interactivebrokers.com' + }, + platformId: '9da3a8a7-4795-43e3-a6db-ccb914189737', + transactionCount: 12, + valueInBaseCurrency: 95693.70321466809, + updatedAt: new Date('2025-06-01T06:53:10.569Z'), + userId: '081aa387-487d-4438-83a4-3060eb2a016e', + value: 95693.70321466809 + } +]; + +export default { + title: 'Accounts Table', + component: GfAccountsTableComponent, + decorators: [ + moduleMetadata({ + imports: [ + CommonModule, + GfEntityLogoComponent, + GfValueComponent, + IonIcon, + MatButtonModule, + MatMenuModule, + MatSortModule, + MatTableModule, + NgxSkeletonLoaderModule, + RouterModule.forChild([]) + ], + providers: [NotificationService] + }) + ] +} as Meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + accounts, + baseCurrency: 'USD', + deviceType: 'desktop', + locale: 'en-US', + showActions: false, + showAllocationInPercentage: false, + showBalance: true, + showFooter: true, + showTransactions: true, + showValue: true, + showValueInBaseCurrency: true, + totalBalanceInBaseCurrency: 12428.2, + totalValueInBaseCurrency: 107971.70321466809, + transactionCount: 12 + } +}; + +export const WithoutFooter: Story = { + args: { + accounts, + baseCurrency: 'USD', + deviceType: 'desktop', + locale: 'en-US', + showActions: false, + showAllocationInPercentage: false, + showBalance: true, + showFooter: false, + showTransactions: true, + showValue: true, + showValueInBaseCurrency: true, + totalBalanceInBaseCurrency: 12428.2, + totalValueInBaseCurrency: 107971.70321466809, + transactionCount: 12 + } +}; diff --git a/apps/client/src/app/components/accounts-table/accounts-table.component.ts b/libs/ui/src/lib/accounts-table/accounts-table.component.ts similarity index 94% rename from apps/client/src/app/components/accounts-table/accounts-table.component.ts rename to libs/ui/src/lib/accounts-table/accounts-table.component.ts index a7ce6e488..607fa67dc 100644 --- a/apps/client/src/app/components/accounts-table/accounts-table.component.ts +++ b/libs/ui/src/lib/accounts-table/accounts-table.component.ts @@ -21,7 +21,7 @@ import { MatSort, MatSortModule } from '@angular/material/sort'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { Router, RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; -import { Account as AccountModel } from '@prisma/client'; +import { Account } from '@prisma/client'; import { addIcons } from 'ionicons'; import { arrowRedoOutline, @@ -54,7 +54,7 @@ import { Subject, Subscription } from 'rxjs'; templateUrl: './accounts-table.component.html' }) export class GfAccountsTableComponent implements OnChanges, OnDestroy { - @Input() accounts: AccountModel[]; + @Input() accounts: Account[]; @Input() baseCurrency: string; @Input() deviceType: string; @Input() hasPermissionToOpenDetails = true; @@ -71,12 +71,12 @@ export class GfAccountsTableComponent implements OnChanges, OnDestroy { @Input() transactionCount: number; @Output() accountDeleted = new EventEmitter(); - @Output() accountToUpdate = new EventEmitter(); + @Output() accountToUpdate = new EventEmitter(); @Output() transferBalance = new EventEmitter(); @ViewChild(MatSort) sort: MatSort; - public dataSource = new MatTableDataSource(); + public dataSource = new MatTableDataSource(); public displayedColumns = []; public isLoading = true; public routeQueryParams: Subscription; @@ -167,7 +167,7 @@ export class GfAccountsTableComponent implements OnChanges, OnDestroy { this.transferBalance.emit(); } - public onUpdateAccount(aAccount: AccountModel) { + public onUpdateAccount(aAccount: Account) { this.accountToUpdate.emit(aAccount); } diff --git a/libs/ui/src/lib/accounts-table/index.ts b/libs/ui/src/lib/accounts-table/index.ts new file mode 100644 index 000000000..6b1909639 --- /dev/null +++ b/libs/ui/src/lib/accounts-table/index.ts @@ -0,0 +1 @@ +export * from './accounts-table.component'; diff --git a/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts b/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts index 42fb68876..d11175fd1 100644 --- a/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts +++ b/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts @@ -21,7 +21,7 @@ const OPTIONS = [ { id: '3ef7e6d9-4598-4eb2-b0e8-00e61cfc0ea6', name: 'Gambling', - userId: 'c6a71541-d0e3-4e22-ae83-b5e5611b6695' + userId: '081aa387-487d-4438-83a4-3060eb2a016e' }, { id: 'EMERGENCY_FUND',