Browse Source

Feature/extend search in assistant by quick links (#4870)

* Extend search in assistant by quick links

* Update changelog
pull/4884/head
Kenrick Tandrian 3 weeks ago
committed by GitHub
parent
commit
ced7f1f206
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      CHANGELOG.md
  2. 2
      apps/client/src/app/app-routing.module.ts
  3. 2
      apps/client/src/app/app.component.ts
  4. 2
      apps/client/src/app/components/access-table/access-table.component.ts
  5. 2
      apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts
  6. 2
      apps/client/src/app/components/admin-settings/admin-settings.component.ts
  7. 2
      apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts
  8. 2
      apps/client/src/app/components/header/header.component.ts
  9. 2
      apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts
  10. 2
      apps/client/src/app/components/home-holdings/home-holdings.component.ts
  11. 2
      apps/client/src/app/components/home-overview/home-overview.component.ts
  12. 2
      apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.component.ts
  13. 2
      apps/client/src/app/components/user-account-membership/user-account-membership.component.ts
  14. 2
      apps/client/src/app/core/auth.guard.ts
  15. 2
      apps/client/src/app/core/http-response.interceptor.ts
  16. 2
      apps/client/src/app/pages/about/about-page-routing.module.ts
  17. 2
      apps/client/src/app/pages/about/about-page.component.ts
  18. 2
      apps/client/src/app/pages/about/overview/about-overview-page.component.ts
  19. 2
      apps/client/src/app/pages/accounts/accounts-page-routing.module.ts
  20. 2
      apps/client/src/app/pages/admin/admin-page-routing.module.ts
  21. 2
      apps/client/src/app/pages/admin/admin-page.component.ts
  22. 2
      apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts
  23. 2
      apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts
  24. 2
      apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.component.ts
  25. 2
      apps/client/src/app/pages/blog/2022/07/ghostfolio-meets-internet-identity/ghostfolio-meets-internet-identity-page.component.ts
  26. 2
      apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.component.ts
  27. 2
      apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts
  28. 2
      apps/client/src/app/pages/blog/2022/10/hacktoberfest-2022/hacktoberfest-2022-page.component.ts
  29. 2
      apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts
  30. 2
      apps/client/src/app/pages/blog/2022/12/the-importance-of-tracking-your-personal-finances/the-importance-of-tracking-your-personal-finances-page.component.ts
  31. 2
      apps/client/src/app/pages/blog/2023/01/ghostfolio-auf-sackgeld-vorgestellt/ghostfolio-auf-sackgeld-vorgestellt-page.component.ts
  32. 2
      apps/client/src/app/pages/blog/2023/02/ghostfolio-meets-umbrel/ghostfolio-meets-umbrel-page.component.ts
  33. 2
      apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts
  34. 2
      apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts
  35. 2
      apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.component.ts
  36. 2
      apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts
  37. 2
      apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts
  38. 2
      apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts
  39. 2
      apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts
  40. 2
      apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts
  41. 2
      apps/client/src/app/pages/blog/2024/09/hacktoberfest-2024/hacktoberfest-2024-page.component.ts
  42. 2
      apps/client/src/app/pages/blog/2024/11/black-weeks-2024/black-weeks-2024-page.component.ts
  43. 2
      apps/client/src/app/pages/faq/faq-page-routing.module.ts
  44. 2
      apps/client/src/app/pages/faq/faq-page.component.ts
  45. 2
      apps/client/src/app/pages/faq/overview/faq-overview-page.component.ts
  46. 2
      apps/client/src/app/pages/faq/saas/saas-page.component.ts
  47. 2
      apps/client/src/app/pages/faq/self-hosting/self-hosting-page.component.ts
  48. 2
      apps/client/src/app/pages/features/features-page.component.ts
  49. 2
      apps/client/src/app/pages/home/home-page-routing.module.ts
  50. 2
      apps/client/src/app/pages/home/home-page.component.ts
  51. 2
      apps/client/src/app/pages/landing/landing-page.component.ts
  52. 2
      apps/client/src/app/pages/open/open-page-routing.module.ts
  53. 2
      apps/client/src/app/pages/portfolio/activities/activities-page-routing.module.ts
  54. 2
      apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts
  55. 2
      apps/client/src/app/pages/portfolio/portfolio-page.component.ts
  56. 2
      apps/client/src/app/pages/pricing/pricing-page.component.ts
  57. 2
      apps/client/src/app/pages/register/register-page-routing.module.ts
  58. 2
      apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.component.ts
  59. 2
      apps/client/src/app/pages/resources/glossary/resources-glossary.component.ts
  60. 2
      apps/client/src/app/pages/resources/overview/resources-overview.component.ts
  61. 2
      apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts
  62. 2
      apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts
  63. 2
      apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts
  64. 2
      apps/client/src/app/pages/resources/resources-page-routing.module.ts
  65. 2
      apps/client/src/app/pages/resources/resources-page.component.ts
  66. 2
      apps/client/src/app/pages/user-account/user-account-page-routing.module.ts
  67. 2
      apps/client/src/app/pages/user-account/user-account-page.component.ts
  68. 2
      apps/client/src/app/pages/zen/zen-page-routing.module.ts
  69. 2
      apps/client/src/app/pages/zen/zen-page.component.ts
  70. 7
      libs/common/src/lib/routes/interfaces/interfaces.ts
  71. 5
      libs/common/src/lib/routes/routes.ts
  72. 38
      libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts
  73. 6
      libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.html
  74. 238
      libs/ui/src/lib/assistant/assistant.component.ts
  75. 31
      libs/ui/src/lib/assistant/assistant.html
  76. 5
      libs/ui/src/lib/assistant/enums/search-mode.ts
  77. 20
      libs/ui/src/lib/assistant/interfaces/interfaces.ts
  78. 2
      libs/ui/src/lib/membership-card/membership-card.component.ts
  79. 2
      libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts
  80. 2
      libs/ui/src/lib/premium-indicator/premium-indicator.component.ts

4
CHANGELOG.md

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- Included quick links in the search results of the assistant
### Changed
- Improved the language localization for Portuguese (`pt`)

2
apps/client/src/app/app-routing.module.ts

@ -4,7 +4,7 @@ import {
publicRoutes,
routes as ghostfolioRoutes,
internalRoutes
} from '@ghostfolio/common/routes';
} from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes, TitleStrategy } from '@angular/router';

2
apps/client/src/app/app.component.ts

@ -7,7 +7,7 @@ import {
internalRoutes,
publicRoutes,
routes
} from '@ghostfolio/common/routes';
} from '@ghostfolio/common/routes/routes';
import { ColorScheme } from '@ghostfolio/common/types';
import { DOCUMENT } from '@angular/common';

2
apps/client/src/app/components/access-table/access-table.component.ts

@ -1,7 +1,7 @@
import { ConfirmationDialogType } from '@ghostfolio/client/core/notification/confirmation-dialog/confirmation-dialog.type';
import { NotificationService } from '@ghostfolio/client/core/notification/notification.service';
import { Access, User } from '@ghostfolio/common/interfaces';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Clipboard } from '@angular/cdk/clipboard';
import {

2
apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts

@ -10,7 +10,7 @@ import {
User
} from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { internalRoutes } from '@ghostfolio/common/routes';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { OrderWithAccount } from '@ghostfolio/common/types';
import {

2
apps/client/src/app/components/admin-settings/admin-settings.component.ts

@ -10,7 +10,7 @@ import {
DataProviderInfo,
User
} from '@ghostfolio/common/interfaces';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import {
ChangeDetectionStrategy,

2
apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts

@ -13,7 +13,7 @@ import {
} from '@ghostfolio/common/helper';
import { LineChartItem, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { ColorScheme } from '@ghostfolio/common/types';
import {

2
apps/client/src/app/components/header/header.component.ts

@ -16,7 +16,7 @@ import {
internalRoutes,
publicRoutes,
routes
} from '@ghostfolio/common/routes';
} from '@ghostfolio/common/routes/routes';
import { DateRange } from '@ghostfolio/common/types';
import { GfAssistantComponent } from '@ghostfolio/ui/assistant/assistant.component';

2
apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts

@ -14,7 +14,7 @@ import {
User
} from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { internalRoutes } from '@ghostfolio/common/routes';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table';
import { GfDataProviderCreditsComponent } from '@ghostfolio/ui/data-provider-credits';
import { GfHistoricalMarketDataEditorComponent } from '@ghostfolio/ui/historical-market-data-editor';

2
apps/client/src/app/components/home-holdings/home-holdings.component.ts

@ -8,7 +8,7 @@ import {
User
} from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { internalRoutes } from '@ghostfolio/common/routes';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { HoldingType, HoldingsViewMode } from '@ghostfolio/common/types';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';

2
apps/client/src/app/components/home-overview/home-overview.component.ts

@ -11,7 +11,7 @@ import {
User
} from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { internalRoutes } from '@ghostfolio/common/routes';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { DeviceDetectorService } from 'ngx-device-detector';

2
apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import {
ChangeDetectionStrategy,

2
apps/client/src/app/components/user-account-membership/user-account-membership.component.ts

@ -5,7 +5,7 @@ import { UserService } from '@ghostfolio/client/services/user/user.service';
import { getDateFormatString } from '@ghostfolio/common/helper';
import { User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import {
ChangeDetectionStrategy,

2
apps/client/src/app/core/auth.guard.ts

@ -5,7 +5,7 @@ import {
internalRoutes,
publicRoutes,
routes
} from '@ghostfolio/common/routes';
} from '@ghostfolio/common/routes/routes';
import { Injectable } from '@angular/core';
import {

2
apps/client/src/app/core/http-response.interceptor.ts

@ -2,7 +2,7 @@ import { DataService } from '@ghostfolio/client/services/data.service';
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service';
import { InfoItem } from '@ghostfolio/common/interfaces';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import {
HTTP_INTERCEPTORS,

2
apps/client/src/app/pages/about/about-page-routing.module.ts

@ -1,5 +1,5 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { routes as ghostfolioRoutes } from '@ghostfolio/common/routes';
import { routes as ghostfolioRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/about/about-page.component.ts

@ -2,7 +2,7 @@ import { DataService } from '@ghostfolio/client/services/data.service';
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { DeviceDetectorService } from 'ngx-device-detector';

2
apps/client/src/app/pages/about/overview/about-overview-page.component.ts

@ -2,7 +2,7 @@ import { DataService } from '@ghostfolio/client/services/data.service';
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { publicRoutes, routes } from '@ghostfolio/common/routes';
import { publicRoutes, routes } from '@ghostfolio/common/routes/routes';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { Subject } from 'rxjs';

2
apps/client/src/app/pages/accounts/accounts-page-routing.module.ts

@ -1,5 +1,5 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { internalRoutes } from '@ghostfolio/common/routes';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/admin/admin-page-routing.module.ts

@ -4,7 +4,7 @@ import { AdminOverviewComponent } from '@ghostfolio/client/components/admin-over
import { AdminSettingsComponent } from '@ghostfolio/client/components/admin-settings/admin-settings.component';
import { AdminUsersComponent } from '@ghostfolio/client/components/admin-users/admin-users.component';
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { routes as ghostfolioRoutes } from '@ghostfolio/common/routes';
import { routes as ghostfolioRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/admin/admin-page.component.ts

@ -1,5 +1,5 @@
import { TabConfiguration } from '@ghostfolio/common/interfaces';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { DeviceDetectorService } from 'ngx-device-detector';

2
apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2022/07/ghostfolio-meets-internet-identity/ghostfolio-meets-internet-identity-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2022/10/hacktoberfest-2022/hacktoberfest-2022-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { Component } from '@angular/core';

2
apps/client/src/app/pages/blog/2022/12/the-importance-of-tracking-your-personal-finances/the-importance-of-tracking-your-personal-finances-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2023/01/ghostfolio-auf-sackgeld-vorgestellt/ghostfolio-auf-sackgeld-vorgestellt-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2023/02/ghostfolio-meets-umbrel/ghostfolio-meets-umbrel-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts

@ -1,4 +1,4 @@
import { publicRoutes, routes } from '@ghostfolio/common/routes';
import { publicRoutes, routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { Component } from '@angular/core';

2
apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2024/09/hacktoberfest-2024/hacktoberfest-2024-page.component.ts

@ -1,4 +1,4 @@
import { publicRoutes, routes } from '@ghostfolio/common/routes';
import { publicRoutes, routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';

2
apps/client/src/app/pages/blog/2024/11/black-weeks-2024/black-weeks-2024-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { Component } from '@angular/core';

2
apps/client/src/app/pages/faq/faq-page-routing.module.ts

@ -1,5 +1,5 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { routes as ghostfolioRoutes } from '@ghostfolio/common/routes';
import { routes as ghostfolioRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/faq/faq-page.component.ts

@ -1,7 +1,7 @@
import { DataService } from '@ghostfolio/client/services/data.service';
import { TabConfiguration } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { DeviceDetectorService } from 'ngx-device-detector';

2
apps/client/src/app/pages/faq/overview/faq-overview-page.component.ts

@ -1,6 +1,6 @@
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { User } from '@ghostfolio/common/interfaces';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { ChangeDetectorRef, Component, OnDestroy } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';

2
apps/client/src/app/pages/faq/saas/saas-page.component.ts

@ -1,6 +1,6 @@
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { User } from '@ghostfolio/common/interfaces';
import { publicRoutes, routes } from '@ghostfolio/common/routes';
import { publicRoutes, routes } from '@ghostfolio/common/routes/routes';
import { ChangeDetectorRef, Component, OnDestroy } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';

2
apps/client/src/app/pages/faq/self-hosting/self-hosting-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';

2
apps/client/src/app/pages/features/features-page.component.ts

@ -2,7 +2,7 @@ import { DataService } from '@ghostfolio/client/services/data.service';
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { InfoItem, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { publicRoutes, routes } from '@ghostfolio/common/routes';
import { publicRoutes, routes } from '@ghostfolio/common/routes/routes';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { ChangeDetectorRef, Component, OnDestroy } from '@angular/core';

2
apps/client/src/app/pages/home/home-page-routing.module.ts

@ -7,7 +7,7 @@ import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import {
routes as ghostfolioRoutes,
internalRoutes
} from '@ghostfolio/common/routes';
} from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/home/home-page.component.ts

@ -1,7 +1,7 @@
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { internalRoutes, routes } from '@ghostfolio/common/routes';
import { internalRoutes, routes } from '@ghostfolio/common/routes/routes';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { DeviceDetectorService } from 'ngx-device-detector';

2
apps/client/src/app/pages/landing/landing-page.component.ts

@ -1,7 +1,7 @@
import { DataService } from '@ghostfolio/client/services/data.service';
import { Statistics } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { publicRoutes, routes } from '@ghostfolio/common/routes';
import { publicRoutes, routes } from '@ghostfolio/common/routes/routes';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { format } from 'date-fns';

2
apps/client/src/app/pages/open/open-page-routing.module.ts

@ -1,5 +1,5 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { publicRoutes } from '@ghostfolio/common/routes';
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/portfolio/activities/activities-page-routing.module.ts

@ -1,5 +1,5 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { internalRoutes } from '@ghostfolio/common/routes';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts

@ -2,7 +2,7 @@ import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import {
routes as ghostfolioRoutes,
internalRoutes
} from '@ghostfolio/common/routes';
} from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/portfolio/portfolio-page.component.ts

@ -1,6 +1,6 @@
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { internalRoutes, routes } from '@ghostfolio/common/routes';
import { internalRoutes, routes } from '@ghostfolio/common/routes/routes';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { DeviceDetectorService } from 'ngx-device-detector';

2
apps/client/src/app/pages/pricing/pricing-page.component.ts

@ -3,7 +3,7 @@ import { DataService } from '@ghostfolio/client/services/data.service';
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { publicRoutes, routes } from '@ghostfolio/common/routes';
import { publicRoutes, routes } from '@ghostfolio/common/routes/routes';
import { translate } from '@ghostfolio/ui/i18n';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';

2
apps/client/src/app/pages/register/register-page-routing.module.ts

@ -1,5 +1,5 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { publicRoutes } from '@ghostfolio/common/routes';
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.component.ts

@ -1,5 +1,5 @@
import { DataService } from '@ghostfolio/client/services/data.service';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import {
ChangeDetectionStrategy,

2
apps/client/src/app/pages/resources/glossary/resources-glossary.component.ts

@ -1,7 +1,7 @@
import { DataService } from '@ghostfolio/client/services/data.service';
import { InfoItem } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component, OnInit } from '@angular/core';

2
apps/client/src/app/pages/resources/overview/resources-overview.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';

2
apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts

@ -1,6 +1,6 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { personalFinanceTools } from '@ghostfolio/common/personal-finance-tools';
import { routes as ghostfolioRoutes } from '@ghostfolio/common/routes';
import { routes as ghostfolioRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts

@ -1,5 +1,5 @@
import { personalFinanceTools } from '@ghostfolio/common/personal-finance-tools';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';

2
apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts

@ -1,7 +1,7 @@
import { DataService } from '@ghostfolio/client/services/data.service';
import { Product } from '@ghostfolio/common/interfaces';
import { personalFinanceTools } from '@ghostfolio/common/personal-finance-tools';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { translate } from '@ghostfolio/ui/i18n';
import { Component, OnInit } from '@angular/core';

2
apps/client/src/app/pages/resources/resources-page-routing.module.ts

@ -1,5 +1,5 @@
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { routes as ghostfolioRoutes } from '@ghostfolio/common/routes';
import { routes as ghostfolioRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/resources/resources-page.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { Component, OnInit } from '@angular/core';
import { DeviceDetectorService } from 'ngx-device-detector';

2
apps/client/src/app/pages/user-account/user-account-page-routing.module.ts

@ -2,7 +2,7 @@ import { UserAccountAccessComponent } from '@ghostfolio/client/components/user-a
import { UserAccountMembershipComponent } from '@ghostfolio/client/components/user-account-membership/user-account-membership.component';
import { UserAccountSettingsComponent } from '@ghostfolio/client/components/user-account-settings/user-account-settings.component';
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { routes as ghostfolioRoutes } from '@ghostfolio/common/routes';
import { routes as ghostfolioRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/user-account/user-account-page.component.ts

@ -1,6 +1,6 @@
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { DeviceDetectorService } from 'ngx-device-detector';

2
apps/client/src/app/pages/zen/zen-page-routing.module.ts

@ -1,7 +1,7 @@
import { HomeHoldingsComponent } from '@ghostfolio/client/components/home-holdings/home-holdings.component';
import { HomeOverviewComponent } from '@ghostfolio/client/components/home-overview/home-overview.component';
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { internalRoutes } from '@ghostfolio/common/routes';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

2
apps/client/src/app/pages/zen/zen-page.component.ts

@ -1,6 +1,6 @@
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { internalRoutes } from '@ghostfolio/common/routes';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { DeviceDetectorService } from 'ngx-device-detector';

7
libs/common/src/lib/routes/interfaces/interfaces.ts

@ -0,0 +1,7 @@
export interface IRoute {
excludeFromAssistant?: boolean;
path: string;
routerLink: string[];
subRoutes?: Record<string, IRoute>;
title: string;
}

5
libs/common/src/lib/routes.ts → libs/common/src/lib/routes/routes.ts

@ -1,5 +1,7 @@
import '@angular/localize/init';
import { IRoute } from './interfaces/interfaces';
export const routes = {
access: 'access',
account: 'account',
@ -44,14 +46,13 @@ export const routes = {
termsOfService: $localize`:kebab-case:terms-of-service`
};
export const internalRoutes = {
export const internalRoutes: Record<string, IRoute> = {
accounts: {
path: 'accounts',
routerLink: ['/accounts'],
title: $localize`Accounts`
},
home: {
excludeFromAssistant: true,
path: 'home',
routerLink: ['/home'],
subRoutes: {

38
libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts

@ -1,5 +1,9 @@
import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module';
import { ISearchResultItem } from '@ghostfolio/ui/assistant/interfaces/interfaces';
import { SearchMode } from '@ghostfolio/ui/assistant/enums/search-mode';
import {
IAssetSearchResultItem,
ISearchResultItem
} from '@ghostfolio/ui/assistant/interfaces/interfaces';
import { FocusableOption } from '@angular/cdk/a11y';
import {
@ -32,7 +36,6 @@ export class GfAssistantListItemComponent
}
@Input() item: ISearchResultItem;
@Input() mode: 'assetProfile' | 'holding';
@Output() clicked = new EventEmitter<void>();
@ -45,23 +48,23 @@ export class GfAssistantListItemComponent
public constructor(private changeDetectorRef: ChangeDetectorRef) {}
public ngOnChanges() {
const dataSource = this.item?.dataSource;
const symbol = this.item?.symbol;
if (this.mode === 'assetProfile') {
if (this.item?.mode === SearchMode.ASSET_PROFILE) {
this.queryParams = {
dataSource,
symbol,
assetProfileDialog: true
assetProfileDialog: true,
dataSource: this.item?.dataSource,
symbol: this.item?.symbol
};
this.routerLink = ['/admin', 'market-data'];
} else if (this.mode === 'holding') {
} else if (this.item?.mode === SearchMode.HOLDING) {
this.queryParams = {
dataSource,
symbol,
holdingDetailDialog: true
dataSource: this.item?.dataSource,
holdingDetailDialog: true,
symbol: this.item?.symbol
};
this.routerLink = [];
} else if (this.item?.mode === SearchMode.QUICK_LINK) {
this.queryParams = {};
this.routerLink = this.item.routerLink;
}
}
@ -71,6 +74,15 @@ export class GfAssistantListItemComponent
this.changeDetectorRef.markForCheck();
}
public isAsset(item: ISearchResultItem): item is IAssetSearchResultItem {
return (
(item.mode === SearchMode.ASSET_PROFILE ||
item.mode === SearchMode.HOLDING) &&
!!item.dataSource &&
!!item.symbol
);
}
public onClick() {
this.clicked.emit();
}

6
libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.html

@ -7,11 +7,13 @@
><span
><b>{{ item?.name }}</b></span
>
@if (item && isAsset(item)) {
<br />
<small class="text-muted"
>{{ item?.symbol | gfSymbol }} · {{ item?.currency }}
@if (item?.assetSubClassString) {
· {{ item.assetSubClassString }}
}
</small></a
>
</small>
}
</a>

238
libs/ui/src/lib/assistant/assistant.component.ts

@ -3,6 +3,8 @@ import { AdminService } from '@ghostfolio/client/services/admin.service';
import { DataService } from '@ghostfolio/client/services/data.service';
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
import { Filter, PortfolioPosition, User } from '@ghostfolio/common/interfaces';
import { IRoute } from '@ghostfolio/common/routes/interfaces/interfaces';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { DateRange } from '@ghostfolio/common/types';
import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo';
import { translate } from '@ghostfolio/ui/i18n';
@ -39,17 +41,20 @@ import { MatSelectModule } from '@angular/material/select';
import { RouterModule } from '@angular/router';
import { Account, AssetClass, DataSource } from '@prisma/client';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { EMPTY, Observable, Subject, lastValueFrom } from 'rxjs';
import { EMPTY, Observable, Subject, merge, of } from 'rxjs';
import {
catchError,
debounceTime,
distinctUntilChanged,
map,
mergeMap,
takeUntil
scan,
switchMap,
takeUntil,
tap
} from 'rxjs/operators';
import { GfAssistantListItemComponent } from './assistant-list-item/assistant-list-item.component';
import { SearchMode } from './enums/search-mode';
import {
IDateRangeOption,
ISearchResultItem,
@ -138,13 +143,18 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
tag: new FormControl<string>(undefined)
});
public holdings: PortfolioPosition[] = [];
public isLoading = false;
public isLoading = {
assetProfiles: false,
holdings: false,
quickLinks: false
};
public isOpen = false;
public placeholder = $localize`Find holding...`;
public placeholder = $localize`Find holding or page...`;
public searchFormControl = new FormControl('');
public searchResults: ISearchResults = {
assetProfiles: [],
holdings: []
holdings: [],
quickLinks: []
};
public tags: Filter[] = [];
@ -177,39 +187,145 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
this.searchFormControl.valueChanges
.pipe(
map((searchTerm) => {
this.isLoading = true;
this.isLoading = {
assetProfiles: true,
holdings: true,
quickLinks: true
};
this.searchResults = {
assetProfiles: [],
holdings: []
holdings: [],
quickLinks: []
};
this.changeDetectorRef.markForCheck();
return searchTerm;
return searchTerm?.trim();
}),
debounceTime(300),
distinctUntilChanged(),
mergeMap(async (searchTerm) => {
const result = {
switchMap((searchTerm) => {
const results = {
assetProfiles: [],
holdings: []
holdings: [],
quickLinks: []
} as ISearchResults;
try {
if (searchTerm) {
return await this.getSearchResults(searchTerm);
if (!searchTerm) {
return of(results).pipe(
tap(() => {
this.isLoading = {
assetProfiles: false,
holdings: false,
quickLinks: false
};
})
);
}
} catch {}
return result;
// Asset profiles
const assetProfiles$: Observable<Partial<ISearchResults>> = this
.hasPermissionToAccessAdminControl
? this.searchAssetProfiles(searchTerm).pipe(
map((assetProfiles) => ({
assetProfiles: assetProfiles.slice(
0,
GfAssistantComponent.SEARCH_RESULTS_DEFAULT_LIMIT
)
})),
catchError((error) => {
console.error(
'Error fetching asset profiles for assistant:',
error
);
return of({ assetProfiles: [] as ISearchResultItem[] });
}),
tap(() => {
this.isLoading.assetProfiles = false;
this.changeDetectorRef.markForCheck();
})
)
: of({ assetProfiles: [] as ISearchResultItem[] }).pipe(
tap(() => {
this.isLoading.assetProfiles = false;
this.changeDetectorRef.markForCheck();
})
);
// Holdings
const holdings$: Observable<Partial<ISearchResults>> =
this.searchHoldings(searchTerm).pipe(
map((holdings) => ({
holdings: holdings.slice(
0,
GfAssistantComponent.SEARCH_RESULTS_DEFAULT_LIMIT
)
})),
catchError((error) => {
console.error('Error fetching holdings for assistant:', error);
return of({ holdings: [] as ISearchResultItem[] });
}),
tap(() => {
this.isLoading.holdings = false;
this.changeDetectorRef.markForCheck();
})
);
// Quick links
const quickLinks$: Observable<Partial<ISearchResults>> = of(
this.searchQuickLinks(searchTerm)
).pipe(
map((quickLinks) => ({
quickLinks: quickLinks.slice(
0,
GfAssistantComponent.SEARCH_RESULTS_DEFAULT_LIMIT
)
})),
tap(() => {
this.isLoading.quickLinks = false;
this.changeDetectorRef.markForCheck();
})
);
// Merge all results
return merge(quickLinks$, assetProfiles$, holdings$).pipe(
scan(
(acc: ISearchResults, curr: Partial<ISearchResults>) => ({
...acc,
...curr
}),
{
assetProfiles: [],
holdings: [],
quickLinks: []
} as ISearchResults
)
);
}),
takeUntil(this.unsubscribeSubject)
)
.subscribe((searchResults) => {
.subscribe({
next: (searchResults) => {
this.searchResults = searchResults;
this.isLoading = false;
this.changeDetectorRef.markForCheck();
},
error: (error) => {
console.error('Assistant search stream error:', error);
this.searchResults = {
assetProfiles: [],
holdings: [],
quickLinks: []
};
this.changeDetectorRef.markForCheck();
},
complete: () => {
this.isLoading = {
assetProfiles: false,
holdings: false,
quickLinks: false
};
this.changeDetectorRef.markForCheck();
}
});
}
@ -307,11 +423,16 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
}
public initialize() {
this.isLoading = true;
this.isLoading = {
assetProfiles: true,
holdings: true,
quickLinks: true
};
this.keyManager = new FocusKeyManager(this.assistantListItems).withWrap();
this.searchResults = {
assetProfiles: [],
holdings: []
holdings: [],
quickLinks: []
};
for (const item of this.assistantListItems) {
@ -323,7 +444,11 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
this.searchElement?.nativeElement?.focus();
});
this.isLoading = false;
this.isLoading = {
assetProfiles: false,
holdings: false,
quickLinks: false
};
this.setIsOpen(true);
this.dataService
@ -412,36 +537,6 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
});
}
private async getSearchResults(aSearchTerm: string) {
let assetProfiles: ISearchResultItem[] = [];
let holdings: ISearchResultItem[] = [];
if (this.hasPermissionToAccessAdminControl) {
try {
assetProfiles = await lastValueFrom(
this.searchAssetProfiles(aSearchTerm)
);
assetProfiles = assetProfiles.slice(
0,
GfAssistantComponent.SEARCH_RESULTS_DEFAULT_LIMIT
);
} catch {}
}
try {
holdings = await lastValueFrom(this.searchHoldings(aSearchTerm));
holdings = holdings.slice(
0,
GfAssistantComponent.SEARCH_RESULTS_DEFAULT_LIMIT
);
} catch {}
return {
assetProfiles,
holdings
};
}
private searchAssetProfiles(
aSearchTerm: string
): Observable<ISearchResultItem[]> {
@ -467,7 +562,8 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
dataSource,
name,
symbol,
assetSubClassString: translate(assetSubClass)
assetSubClassString: translate(assetSubClass),
mode: SearchMode.ASSET_PROFILE as const
};
}
);
@ -499,7 +595,8 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
dataSource,
name,
symbol,
assetSubClassString: translate(assetSubClass)
assetSubClassString: translate(assetSubClass),
mode: SearchMode.HOLDING as const
};
}
);
@ -508,6 +605,37 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
);
}
private searchQuickLinks(aSearchTerm: string): ISearchResultItem[] {
const searchTerm = aSearchTerm.toLowerCase();
const allRoutes = Object.values(internalRoutes)
.filter(({ excludeFromAssistant }) => {
return !excludeFromAssistant;
})
.reduce((acc, route) => {
acc.push(route);
if (route.subRoutes) {
acc.push(...Object.values(route.subRoutes));
}
return acc;
}, [] as IRoute[]);
return allRoutes
.filter(({ title }) => {
return title.toLowerCase().includes(searchTerm);
})
.map(({ routerLink, title }) => {
return {
routerLink,
mode: SearchMode.QUICK_LINK as const,
name: title
};
})
.sort((a, b) => {
return a.name.localeCompare(b.name);
});
}
private setFilterFormValues() {
const dataSource = this.user?.settings?.[
'filters.dataSource'

31
libs/ui/src/lib/assistant/assistant.html

@ -37,19 +37,41 @@
}
</div>
<div
*ngIf="isLoading || searchFormControl.value"
*ngIf="searchFormControl.value"
class="overflow-auto py-3 result-container"
>
<div
*ngIf="searchResults?.quickLinks?.length !== 0 || isLoading.quickLinks"
class="mb-3"
>
<div class="h6 mb-1 px-2" i18n>Quick Links</div>
<gf-assistant-list-item
*ngFor="let searchResultItem of searchResults?.quickLinks"
[item]="searchResultItem"
(clicked)="onCloseAssistant()"
/>
<ng-container>
@if (isLoading.quickLinks) {
<ngx-skeleton-loader
animation="pulse"
class="mx-2"
[theme]="{
height: '1.5rem',
width: '100%'
}"
/>
}
</ng-container>
</div>
<div>
<div class="h6 mb-1 px-2" i18n>Holdings</div>
<gf-assistant-list-item
*ngFor="let searchResultItem of searchResults?.holdings"
mode="holding"
[item]="searchResultItem"
(clicked)="onCloseAssistant()"
/>
<ng-container *ngIf="searchResults?.holdings?.length === 0">
@if (isLoading) {
@if (isLoading.holdings) {
<ngx-skeleton-loader
animation="pulse"
class="mx-2"
@ -67,12 +89,11 @@
<div class="h6 mb-1 px-2" i18n>Asset Profiles</div>
<gf-assistant-list-item
*ngFor="let searchResultItem of searchResults?.assetProfiles"
mode="assetProfile"
[item]="searchResultItem"
(clicked)="onCloseAssistant()"
/>
<ng-container *ngIf="searchResults?.assetProfiles?.length === 0">
@if (isLoading) {
@if (isLoading.assetProfiles) {
<ngx-skeleton-loader
animation="pulse"
class="mx-2"

5
libs/ui/src/lib/assistant/enums/search-mode.ts

@ -0,0 +1,5 @@
export enum SearchMode {
ASSET_PROFILE = 'assetProfile',
HOLDING = 'holding',
QUICK_LINK = 'quickLink'
}

20
libs/ui/src/lib/assistant/interfaces/interfaces.ts

@ -1,18 +1,32 @@
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
import { DateRange } from '@ghostfolio/common/types';
import { SearchMode } from '../enums/search-mode';
export interface IAssetSearchResultItem extends AssetProfileIdentifier {
assetSubClassString: string;
currency: string;
mode: SearchMode.ASSET_PROFILE | SearchMode.HOLDING;
name: string;
}
export interface IDateRangeOption {
label: string;
value: DateRange;
}
export interface ISearchResultItem extends AssetProfileIdentifier {
assetSubClassString: string;
currency: string;
export interface IQuickLinkSearchResultItem {
mode: SearchMode.QUICK_LINK;
name: string;
routerLink: string[];
}
export type ISearchResultItem =
| IAssetSearchResultItem
| IQuickLinkSearchResultItem;
export interface ISearchResults {
assetProfiles: ISearchResultItem[];
holdings: ISearchResultItem[];
quickLinks: ISearchResultItem[];
}

2
libs/ui/src/lib/membership-card/membership-card.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { CommonModule } from '@angular/common';
import {

2
libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts

@ -1,4 +1,4 @@
import { internalRoutes } from '@ghostfolio/common/routes';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import {
CUSTOM_ELEMENTS_SCHEMA,

2
libs/ui/src/lib/premium-indicator/premium-indicator.component.ts

@ -1,4 +1,4 @@
import { routes } from '@ghostfolio/common/routes';
import { routes } from '@ghostfolio/common/routes/routes';
import { CommonModule } from '@angular/common';
import {

Loading…
Cancel
Save