diff --git a/CHANGELOG.md b/CHANGELOG.md index 99e73d30f..d70a69808 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Moved the assistant from experimental to general availability - Improved the usability by reloading the content with a logo click on the home page ## 2.48.1 - 2024-02-06 diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts index d5dfc7680..80d9bf429 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts @@ -10,7 +10,6 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Sort, SortDirection } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; 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 { downloadAsFile } from '@ghostfolio/common/helper'; import { @@ -43,7 +42,6 @@ export class AccountDetailDialog implements OnDestroy, OnInit { public currency: string; public dataSource: MatTableDataSource; public equity: number; - public hasImpersonationId: boolean; public hasPermissionToDeleteAccountBalance: boolean; public historicalDataItems: HistoricalDataItem[]; public holdings: PortfolioPosition[]; @@ -65,7 +63,6 @@ export class AccountDetailDialog implements OnDestroy, OnInit { @Inject(MAT_DIALOG_DATA) public data: AccountDetailDialogParams, private dataService: DataService, public dialogRef: MatDialogRef, - private impersonationStorageService: ImpersonationStorageService, private userService: UserService ) { this.userService.stateChanged @@ -136,13 +133,6 @@ export class AccountDetailDialog implements OnDestroy, OnInit { this.changeDetectorRef.markForCheck(); }); - this.impersonationStorageService - .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((impersonationId) => { - this.hasImpersonationId = !!impersonationId; - }); - this.fetchAccountBalances(); this.fetchActivities(); this.fetchPortfolioPerformance(); @@ -165,17 +155,9 @@ export class AccountDetailDialog implements OnDestroy, OnInit { } public onExport() { - let activityIds = []; - - if (this.user?.settings?.isExperimentalFeatures === true) { - activityIds = this.dataSource.data.map(({ id }) => { - return id; - }); - } else { - activityIds = this.activities.map(({ id }) => { - return id; - }); - } + let activityIds = this.dataSource.data.map(({ id }) => { + return id; + }); this.dataService .fetchExport({ activityIds }) @@ -215,36 +197,21 @@ export class AccountDetailDialog implements OnDestroy, OnInit { private fetchActivities() { this.isLoadingActivities = true; - if (this.user?.settings?.isExperimentalFeatures === true) { - this.dataService - .fetchActivities({ - filters: [{ id: this.data.accountId, type: 'ACCOUNT' }], - sortColumn: this.sortColumn, - sortDirection: this.sortDirection - }) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ activities, count }) => { - this.dataSource = new MatTableDataSource(activities); - this.totalItems = count; - - this.isLoadingActivities = false; - - this.changeDetectorRef.markForCheck(); - }); - } else { - this.dataService - .fetchActivities({ - filters: [{ id: this.data.accountId, type: 'ACCOUNT' }] - }) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ activities }) => { - this.activities = activities; + this.dataService + .fetchActivities({ + filters: [{ id: this.data.accountId, type: 'ACCOUNT' }], + sortColumn: this.sortColumn, + sortDirection: this.sortDirection + }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(({ activities, count }) => { + this.dataSource = new MatTableDataSource(activities); + this.totalItems = count; - this.isLoadingActivities = false; + this.isLoadingActivities = false; - this.changeDetectorRef.markForCheck(); - }); - } + this.changeDetectorRef.markForCheck(); + }); } private fetchPortfolioPerformance() { @@ -268,7 +235,8 @@ export class AccountDetailDialog implements OnDestroy, OnInit { return { date, value: - this.hasImpersonationId || this.user.settings.isRestrictedView + this.data.hasImpersonationId || + this.user.settings.isRestrictedView ? netWorthInPercentage : netWorth }; diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html index 19b3e8a4e..462dd37fd 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html @@ -25,7 +25,7 @@ class="h-100" [currency]="user?.settings?.baseCurrency" [historicalDataItems]="historicalDataItems" - [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" + [isInPercent]="data.hasImpersonationId || user.settings.isRestrictedView" [isLoading]="isLoadingChart" [locale]="user?.settings?.locale" /> @@ -87,12 +87,11 @@
Activities
- @@ -126,7 +112,7 @@ [accountBalances]="accountBalances" [accountId]="data.accountId" [locale]="user?.settings?.locale" - [showActions]="!hasImpersonationId && hasPermissionToDeleteAccountBalance && !user.settings.isRestrictedView" + [showActions]="!data.hasImpersonationId && hasPermissionToDeleteAccountBalance && !user.settings.isRestrictedView" (accountBalanceDeleted)="onDeleteAccountBalance($event)" /> diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts index d015883df..8465be470 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts @@ -9,7 +9,6 @@ import { GfHoldingsTableModule } from '@ghostfolio/ui/holdings-table/holdings-ta import { GfInvestmentChartModule } from '@ghostfolio/client/components/investment-chart/investment-chart.module'; import { GfAccountBalancesModule } from '@ghostfolio/ui/account-balances/account-balances.module'; import { GfActivitiesTableLazyModule } from '@ghostfolio/ui/activities-table-lazy/activities-table-lazy.module'; -import { GfActivitiesTableModule } from '@ghostfolio/ui/activities-table/activities-table.module'; import { GfValueModule } from '@ghostfolio/ui/value'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; @@ -20,7 +19,6 @@ import { AccountDetailDialog } from './account-detail-dialog.component'; imports: [ CommonModule, GfAccountBalancesModule, - GfActivitiesTableModule, GfActivitiesTableLazyModule, GfDialogFooterModule, GfDialogHeaderModule, diff --git a/apps/client/src/app/components/header/header.component.html b/apps/client/src/app/components/header/header.component.html index b1bbaea67..e8188bd59 100644 --- a/apps/client/src/app/components/header/header.component.html +++ b/apps/client/src/app/components/header/header.component.html @@ -120,11 +120,7 @@ [matMenuTriggerRestoreFocus]="false" (menuOpened)="onOpenAssistant()" > - @if (user?.settings?.isExperimentalFeatures) { - - } @else { - - } + -
- -
diff --git a/apps/client/src/app/components/home-overview/home-overview.html b/apps/client/src/app/components/home-overview/home-overview.html index a29eea324..6bec27243 100644 --- a/apps/client/src/app/components/home-overview/home-overview.html +++ b/apps/client/src/app/components/home-overview/home-overview.html @@ -96,17 +96,6 @@ [showDetails]="showDetails" [unit]="unit" /> -
- -
diff --git a/apps/client/src/app/components/home-overview/home-overview.module.ts b/apps/client/src/app/components/home-overview/home-overview.module.ts index e838775f2..dad95c9cb 100644 --- a/apps/client/src/app/components/home-overview/home-overview.module.ts +++ b/apps/client/src/app/components/home-overview/home-overview.module.ts @@ -3,7 +3,6 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; import { GfPortfolioPerformanceModule } from '@ghostfolio/client/components/portfolio-performance/portfolio-performance.module'; -import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.module'; import { GfLineChartModule } from '@ghostfolio/ui/line-chart/line-chart.module'; import { GfNoTransactionsInfoModule } from '@ghostfolio/ui/no-transactions-info'; @@ -16,7 +15,6 @@ import { HomeOverviewComponent } from './home-overview.component'; GfLineChartModule, GfNoTransactionsInfoModule, GfPortfolioPerformanceModule, - GfToggleModule, MatButtonModule, RouterModule ], diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts index 55dcadec3..9418f7f28 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts @@ -268,17 +268,9 @@ export class PositionDetailDialog implements OnDestroy, OnInit { } public onExport() { - let activityIds = []; - - if (this.user?.settings?.isExperimentalFeatures === true) { - activityIds = this.dataSource.data.map(({ id }) => { - return id; - }); - } else { - activityIds = this.activities.map(({ id }) => { - return id; - }); - } + let activityIds = this.dataSource.data.map(({ id }) => { + return id; + }); this.dataService .fetchExport({ activityIds }) diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html index e2b72366b..2830f37dd 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -250,12 +250,11 @@
Activities
-
diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts index 46ae87f66..bc03e8190 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts @@ -6,7 +6,6 @@ import { MatDialogModule } from '@angular/material/dialog'; import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module'; import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module'; import { GfActivitiesTableLazyModule } from '@ghostfolio/ui/activities-table-lazy/activities-table-lazy.module'; -import { GfActivitiesTableModule } from '@ghostfolio/ui/activities-table/activities-table.module'; import { GfDataProviderCreditsModule } from '@ghostfolio/ui/data-provider-credits/data-provider-credits.module'; import { GfLineChartModule } from '@ghostfolio/ui/line-chart/line-chart.module'; import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart/portfolio-proportion-chart.module'; @@ -19,7 +18,6 @@ import { PositionDetailDialog } from './position-detail-dialog.component'; declarations: [PositionDetailDialog], imports: [ CommonModule, - GfActivitiesTableModule, GfActivitiesTableLazyModule, GfDataProviderCreditsModule, GfDialogFooterModule, diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts index 01f939905..92df83516 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts @@ -121,43 +121,25 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit { } public fetchActivities() { - if (this.user?.settings?.isExperimentalFeatures === true) { - this.dataService - .fetchActivities({ - filters: this.userService.getFilters(), - skip: this.pageIndex * this.pageSize, - sortColumn: this.sortColumn, - sortDirection: this.sortDirection, - take: this.pageSize - }) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ activities, count }) => { - this.dataSource = new MatTableDataSource(activities); - this.totalItems = count; - - if (this.hasPermissionToCreateActivity && this.totalItems <= 0) { - this.router.navigate([], { queryParams: { createDialog: true } }); - } + this.dataService + .fetchActivities({ + filters: this.userService.getFilters(), + skip: this.pageIndex * this.pageSize, + sortColumn: this.sortColumn, + sortDirection: this.sortDirection, + take: this.pageSize + }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(({ activities, count }) => { + this.dataSource = new MatTableDataSource(activities); + this.totalItems = count; - this.changeDetectorRef.markForCheck(); - }); - } else { - this.dataService - .fetchActivities({}) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ activities }) => { - this.activities = activities; - - if ( - this.hasPermissionToCreateActivity && - this.activities?.length <= 0 - ) { - this.router.navigate([], { queryParams: { createDialog: true } }); - } + if (this.hasPermissionToCreateActivity && this.totalItems <= 0) { + this.router.navigate([], { queryParams: { createDialog: true } }); + } - this.changeDetectorRef.markForCheck(); - }); - } + this.changeDetectorRef.markForCheck(); + }); } public onChangePage(page: PageEvent) { diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.html b/apps/client/src/app/pages/portfolio/activities/activities-page.html index 3322ff184..9422f0b0d 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.html +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -3,7 +3,6 @@

Activities

-
diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.module.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.module.ts index 7f6d708df..cec6e7e89 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.module.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.module.ts @@ -5,7 +5,6 @@ import { MatSnackBarModule } from '@angular/material/snack-bar'; import { RouterModule } from '@angular/router'; import { ImportActivitiesService } from '@ghostfolio/client/services/import-activities.service'; import { GfActivitiesTableLazyModule } from '@ghostfolio/ui/activities-table-lazy/activities-table-lazy.module'; -import { GfActivitiesTableModule } from '@ghostfolio/ui/activities-table/activities-table.module'; import { ActivitiesPageRoutingModule } from './activities-page-routing.module'; import { ActivitiesPageComponent } from './activities-page.component'; @@ -17,7 +16,6 @@ import { GfImportActivitiesDialogModule } from './import-activities-dialog/impor imports: [ ActivitiesPageRoutingModule, CommonModule, - GfActivitiesTableModule, GfActivitiesTableLazyModule, GfCreateOrUpdateActivityDialogModule, GfImportActivitiesDialogModule, diff --git a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html index d98841edf..1abb74cf5 100644 --- a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html +++ b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -117,7 +117,7 @@
-
- - - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - -
- -
-
- {{ - dataSource.data.length > pageSize - ? dataSource.data.length - pageSize * pageIndex - i - : dataSource.data.length - i - }} - - Date - -
- {{ element.date | date: defaultDateFormat }} -
-
Total - Type - - - - Name - -
-
- {{ element.SymbolProfile?.name }} - Draft -
-
-
- {{ - element.SymbolProfile?.symbol | gfSymbol - }} -
-
- Currency - - {{ element.SymbolProfile?.currency }} - - {{ baseCurrency }} - - Quantity - -
- -
-
- Unit Price - -
- -
-
- Fee - -
- -
-
-
- -
-
- Value - -
- -
-
-
- -
-
- Value - -
- -
-
-
- -
-
- Account - -
- - {{ element.Account?.name }} -
-
- - - - - - - - - - - - - - - - - -
-
- - - - - -
- -
diff --git a/libs/ui/src/lib/activities-table/activities-table.component.scss b/libs/ui/src/lib/activities-table/activities-table.component.scss deleted file mode 100644 index ea3dad292..000000000 --- a/libs/ui/src/lib/activities-table/activities-table.component.scss +++ /dev/null @@ -1,19 +0,0 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - -:host { - display: block; - - .activities { - overflow-x: auto; - - .mat-mdc-table { - th { - ::ng-deep { - .mat-sort-header-container { - justify-content: inherit; - } - } - } - } - } -} diff --git a/libs/ui/src/lib/activities-table/activities-table.component.ts b/libs/ui/src/lib/activities-table/activities-table.component.ts deleted file mode 100644 index 66c065709..000000000 --- a/libs/ui/src/lib/activities-table/activities-table.component.ts +++ /dev/null @@ -1,442 +0,0 @@ -import { SelectionModel } from '@angular/cdk/collections'; -import { - ChangeDetectionStrategy, - Component, - EventEmitter, - Input, - OnChanges, - OnDestroy, - OnInit, - Output, - ViewChild -} from '@angular/core'; -import { MatPaginator, PageEvent } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; -import { Router } from '@angular/router'; -import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; -import { DEFAULT_PAGE_SIZE } from '@ghostfolio/common/config'; -import { getDateFormatString } from '@ghostfolio/common/helper'; -import { Filter, UniqueAsset } from '@ghostfolio/common/interfaces'; -import { OrderWithAccount } from '@ghostfolio/common/types'; -import { translate } from '@ghostfolio/ui/i18n'; -import Big from 'big.js'; -import { isUUID } from 'class-validator'; -import { endOfToday, format, isAfter } from 'date-fns'; -import { get, isNumber } from 'lodash'; -import { Subject, Subscription, distinctUntilChanged, takeUntil } from 'rxjs'; - -@Component({ - changeDetection: ChangeDetectionStrategy.OnPush, - selector: 'gf-activities-table', - styleUrls: ['./activities-table.component.scss'], - templateUrl: './activities-table.component.html' -}) -export class ActivitiesTableComponent implements OnChanges, OnDestroy, OnInit { - @Input() activities: Activity[]; - @Input() baseCurrency: string; - @Input() deviceType: string; - @Input() hasPermissionToCreateActivity: boolean; - @Input() hasPermissionToExportActivities: boolean; - @Input() hasPermissionToFilter = true; - @Input() hasPermissionToOpenDetails = true; - @Input() locale: string; - @Input() pageSize = DEFAULT_PAGE_SIZE; - @Input() showActions = true; - @Input() showCheckbox = false; - @Input() showFooter = true; - @Input() showNameColumn = true; - - @Output() activityDeleted = new EventEmitter(); - @Output() activityToClone = new EventEmitter(); - @Output() activityToUpdate = new EventEmitter(); - @Output() deleteAllActivities = new EventEmitter(); - @Output() export = new EventEmitter(); - @Output() exportDrafts = new EventEmitter(); - @Output() import = new EventEmitter(); - @Output() importDividends = new EventEmitter(); - @Output() selectedActivities = new EventEmitter(); - - @ViewChild(MatPaginator) paginator: MatPaginator; - @ViewChild(MatSort) sort: MatSort; - - public allFilters: Filter[]; - public dataSource: MatTableDataSource = new MatTableDataSource(); - public defaultDateFormat: string; - public displayedColumns = []; - public endOfToday = endOfToday(); - public filters$ = new Subject(); - public hasDrafts = false; - public hasErrors = false; - public isAfter = isAfter; - public isLoading = true; - public isUUID = isUUID; - public pageIndex = 0; - public placeholder = ''; - public routeQueryParams: Subscription; - public searchKeywords: string[] = []; - public selectedRows = new SelectionModel(true, []); - public totalFees: number; - public totalValue: number; - - private readonly SEARCH_STRING_SEPARATOR = ','; - private unsubscribeSubject = new Subject(); - - public constructor(private router: Router) { - this.filters$ - .pipe(distinctUntilChanged(), takeUntil(this.unsubscribeSubject)) - .subscribe((filters) => { - this.updateFilters(filters); - }); - } - - public ngOnInit() { - if (this.showCheckbox) { - this.toggleAllRows(); - this.selectedRows.changed - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((selectedRows) => { - this.selectedActivities.emit(selectedRows.source.selected); - }); - } - } - - public areAllRowsSelected() { - const numSelectedRows = this.selectedRows.selected.length; - const numTotalRows = this.dataSource.data.length; - return numSelectedRows === numTotalRows; - } - - public ngOnChanges() { - this.displayedColumns = [ - 'select', - 'importStatus', - 'count', - 'date', - 'type', - 'nameWithSymbol', - 'quantity', - 'unitPrice', - 'fee', - 'value', - 'currency', - 'valueInBaseCurrency', - 'account', - 'comment', - 'actions' - ]; - - if (this.showCheckbox) { - this.displayedColumns = this.displayedColumns.filter((column) => { - return column !== 'count'; - }); - } else { - this.displayedColumns = this.displayedColumns.filter((column) => { - return column !== 'importStatus' && column !== 'select'; - }); - } - - if (!this.showNameColumn) { - this.displayedColumns = this.displayedColumns.filter((column) => { - return column !== 'nameWithSymbol'; - }); - } - - this.defaultDateFormat = getDateFormatString(this.locale); - - if (this.activities) { - this.activities = this.activities.map((activity) => { - return { - ...activity, - error: activity.error - ? { - ...activity.error, - message: translate( - `IMPORT_ACTIVITY_ERROR_${activity.error.code}` - ) - } - : undefined - }; - }); - - this.allFilters = this.getSearchableFieldValues(this.activities); - - this.dataSource = new MatTableDataSource(this.activities); - this.dataSource.filterPredicate = (data, filter) => { - const filterableLabels = this.getFilterableValues(data).map( - ({ label }) => { - return label.toLowerCase(); - } - ); - - let includes = true; - for (const singleFilter of filter.split(this.SEARCH_STRING_SEPARATOR)) { - includes = - includes && - filterableLabels.includes(singleFilter.trim().toLowerCase()); - } - return includes; - }; - this.dataSource.paginator = this.paginator; - this.dataSource.sort = this.sort; - this.dataSource.sortingDataAccessor = get; - - this.updateFilters(); - - this.hasErrors = this.activities.some(({ error }) => { - return !!error; - }); - } else { - this.hasErrors = false; - } - } - - public onChangePage(page: PageEvent) { - this.pageIndex = page.pageIndex; - - this.totalFees = this.getTotalFees(); - this.totalValue = this.getTotalValue(); - } - - public onClickActivity(activity: Activity) { - if (this.showCheckbox) { - if (!activity.error) { - this.selectedRows.toggle(activity); - } - } else if ( - this.hasPermissionToOpenDetails && - !activity.isDraft && - activity.type !== 'FEE' && - activity.type !== 'INTEREST' && - activity.type !== 'ITEM' && - activity.type !== 'LIABILITY' - ) { - this.onOpenPositionDialog({ - dataSource: activity.SymbolProfile.dataSource, - symbol: activity.SymbolProfile.symbol - }); - } - } - - public onCloneActivity(aActivity: OrderWithAccount) { - this.activityToClone.emit(aActivity); - } - - public onDeleteActivity(aId: string) { - const confirmation = confirm( - $localize`Do you really want to delete this activity?` - ); - - if (confirmation) { - this.activityDeleted.emit(aId); - } - } - - public onExport() { - if (this.searchKeywords.length > 0) { - this.export.emit( - this.dataSource.filteredData.map((activity) => { - return activity.id; - }) - ); - } else { - this.export.emit(); - } - } - - public onExportDraft(aActivityId: string) { - this.exportDrafts.emit([aActivityId]); - } - - public onExportDrafts() { - this.exportDrafts.emit( - this.dataSource.filteredData - .filter((activity) => { - return activity.isDraft; - }) - .map((activity) => { - return activity.id; - }) - ); - } - - public onDeleteAllActivities() { - this.deleteAllActivities.emit(); - } - - public onImport() { - this.import.emit(); - } - - public onImportDividends() { - this.importDividends.emit(); - } - - public onOpenComment(aComment: string) { - alert(aComment); - } - - public onOpenPositionDialog({ dataSource, symbol }: UniqueAsset): void { - this.router.navigate([], { - queryParams: { dataSource, symbol, positionDetailDialog: true } - }); - } - - public onUpdateActivity(aActivity: OrderWithAccount) { - this.activityToUpdate.emit(aActivity); - } - - public toggleAllRows() { - this.areAllRowsSelected() - ? this.selectedRows.clear() - : this.dataSource.data.forEach((row) => this.selectedRows.select(row)); - - this.selectedActivities.emit(this.selectedRows.selected); - } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - - private getFilterableValues( - activity: OrderWithAccount, - fieldValueMap: { [id: string]: Filter } = {} - ): Filter[] { - if (activity.Account?.id) { - fieldValueMap[activity.Account.id] = { - id: activity.Account.id, - label: activity.Account.name, - type: 'ACCOUNT' - }; - } - - if (activity.SymbolProfile?.currency) { - fieldValueMap[activity.SymbolProfile.currency] = { - id: activity.SymbolProfile.currency, - label: activity.SymbolProfile.currency, - type: 'TAG' - }; - } - - if ( - activity.SymbolProfile?.symbol && - !isUUID(activity.SymbolProfile.symbol) - ) { - fieldValueMap[activity.SymbolProfile.symbol] = { - id: activity.SymbolProfile.symbol, - label: activity.SymbolProfile.symbol, - type: 'SYMBOL' - }; - } - - fieldValueMap[activity.type] = { - id: activity.type, - label: activity.type, - type: 'TAG' - }; - - fieldValueMap[format(new Date(activity.date), 'yyyy')] = { - id: format(new Date(activity.date), 'yyyy'), - label: format(new Date(activity.date), 'yyyy'), - type: 'TAG' - }; - - return Object.values(fieldValueMap); - } - - private getPaginatedData() { - if (this.dataSource.data.length > this.pageSize) { - const sortedData = this.dataSource.sortData( - this.dataSource.filteredData, - this.dataSource.sort - ); - - return sortedData.slice( - this.pageIndex * this.pageSize, - (this.pageIndex + 1) * this.pageSize - ); - } - return this.dataSource.filteredData; - } - - private getSearchableFieldValues(activities: OrderWithAccount[]): Filter[] { - const fieldValueMap: { [id: string]: Filter } = {}; - - for (const activity of activities) { - this.getFilterableValues(activity, fieldValueMap); - } - - return Object.values(fieldValueMap); - } - - private getTotalFees() { - let totalFees = new Big(0); - const paginatedData = this.getPaginatedData(); - for (const activity of paginatedData) { - if (isNumber(activity.feeInBaseCurrency)) { - totalFees = totalFees.plus(activity.feeInBaseCurrency); - } else { - return null; - } - } - - return totalFees.toNumber(); - } - - private getTotalValue() { - const paginatedData = this.getPaginatedData(); - let totalValue = new Big(0); - - for (const { type, valueInBaseCurrency } of paginatedData) { - if (isNumber(valueInBaseCurrency)) { - if (type === 'BUY' || type === 'ITEM') { - totalValue = totalValue.plus(valueInBaseCurrency); - } else if ( - type === 'DIVIDEND' || - type === 'FEE' || - type === 'INTEREST' || - type === 'LIABILITY' || - type === 'SELL' - ) { - return null; - } - } else { - return null; - } - } - - return totalValue.toNumber(); - } - - private updateFilters(filters: Filter[] = []) { - this.isLoading = true; - - this.dataSource.filter = filters - .map((filter) => { - return filter.label; - }) - .join(this.SEARCH_STRING_SEPARATOR); - - const lowercaseSearchKeywords = filters.map((filter) => { - return filter.label.trim().toLowerCase(); - }); - - this.placeholder = - lowercaseSearchKeywords.length <= 0 - ? $localize`Filter by account, currency, symbol or type...` - : ''; - - this.searchKeywords = filters.map((filter) => { - return filter.label; - }); - - this.hasDrafts = this.dataSource.filteredData.some((activity) => { - return activity.isDraft === true; - }); - this.totalFees = this.getTotalFees(); - this.totalValue = this.getTotalValue(); - - this.isLoading = false; - } -} diff --git a/libs/ui/src/lib/activities-table/activities-table.module.ts b/libs/ui/src/lib/activities-table/activities-table.module.ts deleted file mode 100644 index ae35b902f..000000000 --- a/libs/ui/src/lib/activities-table/activities-table.module.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatPaginatorModule } from '@angular/material/paginator'; -import { MatSortModule } from '@angular/material/sort'; -import { MatTableModule } from '@angular/material/table'; -import { MatTooltipModule } from '@angular/material/tooltip'; -import { RouterModule } from '@angular/router'; -import { GfSymbolIconModule } from '@ghostfolio/client/components/symbol-icon/symbol-icon.module'; -import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; -import { GfActivitiesFilterModule } from '@ghostfolio/ui/activities-filter/activities-filter.module'; -import { GfActivityTypeModule } from '@ghostfolio/ui/activity-type'; -import { GfNoTransactionsInfoModule } from '@ghostfolio/ui/no-transactions-info'; -import { GfValueModule } from '@ghostfolio/ui/value'; -import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; - -import { ActivitiesTableComponent } from './activities-table.component'; - -@NgModule({ - declarations: [ActivitiesTableComponent], - exports: [ActivitiesTableComponent], - imports: [ - CommonModule, - GfActivitiesFilterModule, - GfActivityTypeModule, - GfNoTransactionsInfoModule, - GfSymbolIconModule, - GfSymbolModule, - GfValueModule, - MatButtonModule, - MatCheckboxModule, - MatMenuModule, - MatPaginatorModule, - MatSortModule, - MatTableModule, - MatTooltipModule, - NgxSkeletonLoaderModule, - RouterModule - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfActivitiesTableModule {} diff --git a/libs/ui/src/lib/assistant/assistant.html b/libs/ui/src/lib/assistant/assistant.html index 6889d7348..ee1827142 100644 --- a/libs/ui/src/lib/assistant/assistant.html +++ b/libs/ui/src/lib/assistant/assistant.html @@ -87,11 +87,8 @@
-
-
+ +
Date Range
-
- - Accounts - - - @for (account of accounts; track account.id) { - -
- {{ account.name }} -
-
- } -
-
-
-
- - Tags - - - @for (tag of tags; track tag.id) { - {{ tag.label }} - } - - -
-
- - Asset Classes - - - @for (assetClass of assetClasses; track assetClass.id) { - {{ assetClass.label }} - } - - -
-
- - - +
+
+ + Accounts + + + @for (account of accounts; track account.id) { + +
+ {{ account.name }} +
+
+ } +
+
+
+
+ + Tags + + + @for (tag of tags; track tag.id) { + {{ tag.label }} + } + + +
+
+ + Asset Classes + + + @for (assetClass of assetClasses; track assetClass.id) { + {{ assetClass.label }} + } + + +
+
+ + + +
-
+
diff --git a/libs/ui/src/lib/assistant/assistant.scss b/libs/ui/src/lib/assistant/assistant.scss index 5003d1c39..6ed02f658 100644 --- a/libs/ui/src/lib/assistant/assistant.scss +++ b/libs/ui/src/lib/assistant/assistant.scss @@ -1,16 +1,8 @@ :host { display: block; - .filter-container { - .mat-mdc-tab-group { - max-height: 20vh; - } - - ::ng-deep { - label { - margin-bottom: 0; - } - } + .date-range-selector-container { + border-bottom: 1px solid rgba(var(--dark-dividers)); } .result-container { @@ -35,6 +27,10 @@ } :host-context(.is-dark-theme) { + .date-range-selector-container { + border-color: rgba(var(--light-dividers)); + } + .search-container { border-color: rgba(var(--light-dividers));