From a060ea34024ca0705534337b82e9317db9842513 Mon Sep 17 00:00:00 2001 From: David Requeno Date: Tue, 29 Jul 2025 22:48:22 -0600 Subject: [PATCH] Feature/move accounts table to ui 20250729 * Move accounts table component to @ghostfolio/ui library * Add Storybook story with sample data from live demo * Update imports in client application --- .../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 | 199 ++++++++++++++++++ .../accounts-table.component.ts | 0 libs/ui/src/lib/accounts-table/index.ts | 1 + 7 files changed, 202 insertions(+), 2 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 (100%) create mode 100644 libs/ui/src/lib/accounts-table/index.ts 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..c8ff855b5 --- /dev/null +++ b/libs/ui/src/lib/accounts-table/accounts-table.component.stories.ts @@ -0,0 +1,199 @@ +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 { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; + +import { GfEntityLogoComponent } from '../entity-logo'; +import { GfValueComponent } from '../value'; +import { GfAccountsTableComponent } from './accounts-table.component'; + +const mockAccounts = [ + { + id: '1', + name: 'Checking Account', + currency: 'USD', + balance: 15000, + value: 15000, + valueInBaseCurrency: 15000, + transactionCount: 25, + allocationInPercentage: 0.15, + isExcluded: false, + comment: 'Primary checking account', + platform: { + name: 'Bank of America', + url: 'https://www.bankofamerica.com' + } + }, + { + id: '2', + name: 'Trading Account', + currency: 'USD', + balance: 5000, + value: 125000, + valueInBaseCurrency: 125000, + transactionCount: 127, + allocationInPercentage: 0.65, + isExcluded: false, + comment: null, + platform: { + name: 'Interactive Brokers', + url: 'https://www.interactivebrokers.com' + } + }, + { + id: '3', + name: 'Savings Account', + currency: 'EUR', + balance: 20000, + value: 20000, + valueInBaseCurrency: 21600, + transactionCount: 8, + allocationInPercentage: 0.2, + isExcluded: false, + comment: 'Emergency fund', + platform: { + name: 'Deutsche Bank', + url: 'https://www.deutsche-bank.de' + } + }, + { + id: '4', + name: 'Excluded Account', + currency: 'USD', + balance: 1000, + value: 1000, + valueInBaseCurrency: 1000, + transactionCount: 3, + allocationInPercentage: 0, + isExcluded: true, + comment: null, + platform: { + name: 'Local Credit Union', + url: null + } + } +]; + +export default { + title: 'Accounts Table', + component: GfAccountsTableComponent, + decorators: [ + moduleMetadata({ + imports: [ + CommonModule, + NgxSkeletonLoaderModule, + MatButtonModule, + MatMenuModule, + MatSortModule, + MatTableModule, + RouterModule.forRoot([]), + IonIcon, + GfEntityLogoComponent, + GfValueComponent + ] + }) + ] +} as Meta; + +type Story = StoryObj; + +export const Loading: Story = { + args: { + accounts: [], + baseCurrency: 'USD', + deviceType: 'web', + locale: 'en-US', + showActions: false, + showAllocationInPercentage: false, + showBalance: true, + showFooter: true, + showTransactions: true, + showValue: true, + showValueInBaseCurrency: true, + totalBalanceInBaseCurrency: 0, + totalValueInBaseCurrency: 0, + transactionCount: 0 + } +}; + +export const Default: Story = { + args: { + accounts: mockAccounts, + baseCurrency: 'USD', + deviceType: 'web', + locale: 'en-US', + showActions: false, + showAllocationInPercentage: false, + showBalance: true, + showFooter: true, + showTransactions: true, + showValue: true, + showValueInBaseCurrency: true, + totalBalanceInBaseCurrency: 56600, + totalValueInBaseCurrency: 161600, + transactionCount: 163 + } +}; + +export const WithActions: Story = { + args: { + accounts: mockAccounts, + baseCurrency: 'USD', + deviceType: 'web', + locale: 'en-US', + showActions: true, + showAllocationInPercentage: true, + showBalance: true, + showFooter: true, + showTransactions: true, + showValue: true, + showValueInBaseCurrency: true, + totalBalanceInBaseCurrency: 56600, + totalValueInBaseCurrency: 161600, + transactionCount: 163 + } +}; + +export const MobileView: Story = { + args: { + accounts: mockAccounts, + baseCurrency: 'USD', + deviceType: 'mobile', + locale: 'en-US', + showActions: false, + showAllocationInPercentage: false, + showBalance: false, + showFooter: false, + showTransactions: true, + showValue: false, + showValueInBaseCurrency: true, + totalBalanceInBaseCurrency: 56600, + totalValueInBaseCurrency: 161600, + transactionCount: 163 + } +}; + +export const WithoutFooter: Story = { + args: { + accounts: mockAccounts, + baseCurrency: 'USD', + deviceType: 'web', + locale: 'en-US', + showActions: false, + showAllocationInPercentage: true, + showBalance: true, + showFooter: false, + showTransactions: true, + showValue: true, + showValueInBaseCurrency: true, + totalBalanceInBaseCurrency: 56600, + totalValueInBaseCurrency: 161600, + transactionCount: 163 + } +}; 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 100% 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 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';