Browse Source

Merge branch 'main' into feature/improve-language-localization-for-tr-20240501

pull/3355/head
Thomas Kaul 1 year ago
committed by GitHub
parent
commit
a4f79afc6a
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 28
      CHANGELOG.md
  2. 2
      README.md
  3. 5
      apps/api/src/app/portfolio/interfaces/portfolio-positions.interface.ts
  4. 30
      apps/api/src/app/portfolio/portfolio.controller.ts
  5. 2
      apps/api/src/events/portfolio-changed.listener.ts
  6. 87
      apps/client/src/app/app.component.ts
  7. 1
      apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html
  8. 1
      apps/client/src/app/components/admin-market-data/admin-market-data.component.ts
  9. 5
      apps/client/src/app/components/header/header.component.html
  10. 11
      apps/client/src/app/components/header/header.component.scss
  11. 3
      apps/client/src/app/components/header/header.component.ts
  12. 2
      apps/client/src/app/components/header/header.module.ts
  13. 66
      apps/client/src/app/components/home-holdings/home-holdings.component.ts
  14. 1
      apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html
  15. 1
      apps/client/src/app/components/user-account-access/user-account-access.component.ts
  16. 2
      apps/client/src/app/pages/about/overview/about-overview-page.html
  17. 2
      apps/client/src/app/pages/accounts/accounts-page.component.ts
  18. 6
      apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html
  19. 10
      apps/client/src/app/pages/home/home-page.component.ts
  20. 62
      apps/client/src/app/pages/portfolio/activities/activities-page.component.ts
  21. 1
      apps/client/src/app/pages/portfolio/activities/activities-page.html
  22. 10
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts
  23. 1
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html
  24. 55
      apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts
  25. 90
      apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts
  26. 28
      apps/client/src/app/pages/portfolio/analysis/analysis-page.html
  27. 31
      apps/client/src/app/services/data.service.ts
  28. 10
      apps/client/src/app/services/user/user.service.ts
  29. 296
      apps/client/src/locales/messages.de.xlf
  30. 293
      apps/client/src/locales/messages.es.xlf
  31. 293
      apps/client/src/locales/messages.fr.xlf
  32. 293
      apps/client/src/locales/messages.it.xlf
  33. 293
      apps/client/src/locales/messages.nl.xlf
  34. 296
      apps/client/src/locales/messages.pl.xlf
  35. 293
      apps/client/src/locales/messages.pt.xlf
  36. 293
      apps/client/src/locales/messages.tr.xlf
  37. 289
      apps/client/src/locales/messages.xlf
  38. 296
      apps/client/src/locales/messages.zh.xlf
  39. 12
      apps/client/src/styles.scss
  40. 4
      libs/common/src/lib/config.ts
  41. 9
      libs/ui/src/lib/activities-table/activities-table.component.html
  42. 3
      libs/ui/src/lib/activities-table/activities-table.component.ts
  43. 4
      libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts
  44. 6
      libs/ui/src/lib/assistant/assistant.component.ts
  45. 27
      libs/ui/src/lib/holdings-table/holdings-table.component.html
  46. 9
      libs/ui/src/lib/holdings-table/holdings-table.component.ts
  47. 26
      package.json
  48. 485
      yarn.lock

28
CHANGELOG.md

@ -7,9 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- Added an indicator for active filters (experimental)
### Changed
- Disabled the button to delete all activities on the portfolio activities page if there are active filters
- Improved the language localization for Türkçe (`tr`)
- Upgraded `Nx` from version `18.3.3` to `19.0.2`
### Fixed
- Fixed the position detail dialog close functionality
## 2.80.0 - 2024-05-08
### Added
- Added the absolute change column to the holdings table on the home page
### Changed
- Increased the spacing around the floating action buttons (FAB)
- Set the icon column of the activities table to stick at the beginning
- Set the icon column of the holdings table to stick at the beginning
- Increased the number of attempts of queue jobs from `10` to `12` (fail later)
- Upgraded `ionicons` from version `7.3.0` to `7.4.0`
### Fixed
- Fixed the position detail dialog open functionality when searching for a holding in the assistant
## 2.79.0 - 2024-05-04

2
README.md

@ -142,7 +142,7 @@ docker compose --env-file ./.env -f docker/docker-compose.build.yml up -d
### Home Server Systems (Community)
Ghostfolio is available for various home server systems, including [CasaOS](https://github.com/bigbeartechworld/big-bear-casaos), Home Assistant, [Runtipi](https://www.runtipi.io/docs/apps-available), [TrueCharts](https://truecharts.org/charts/stable/ghostfolio), [Umbrel](https://apps.umbrel.com/app/ghostfolio), and [Unraid](https://unraid.net/community/apps?q=ghostfolio).
Ghostfolio is available for various home server systems, including [CasaOS](https://github.com/bigbeartechworld/big-bear-casaos), [Home Assistant](https://github.com/lildude/ha-addon-ghostfolio), [Runtipi](https://www.runtipi.io/docs/apps-available), [TrueCharts](https://truecharts.org/charts/stable/ghostfolio), [Umbrel](https://apps.umbrel.com/app/ghostfolio), and [Unraid](https://unraid.net/community/apps?q=ghostfolio).
## Development

5
apps/api/src/app/portfolio/interfaces/portfolio-positions.interface.ts

@ -1,5 +0,0 @@
import { Position } from '@ghostfolio/common/interfaces';
export interface PortfolioPositions {
positions: Position[];
}

30
apps/api/src/app/portfolio/portfolio.controller.ts

@ -52,7 +52,6 @@ import { Big } from 'big.js';
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
import { PortfolioPositionDetail } from './interfaces/portfolio-position-detail.interface';
import { PortfolioPositions } from './interfaces/portfolio-positions.interface';
import { PortfolioService } from './portfolio.service';
@Controller('portfolio')
@ -494,35 +493,6 @@ export class PortfolioController {
return performanceInformation;
}
/**
* @deprecated
*/
@Get('positions')
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
@UseInterceptors(RedactValuesInResponseInterceptor)
@UseInterceptors(TransformDataSourceInResponseInterceptor)
public async getPositions(
@Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId: string,
@Query('accounts') filterByAccounts?: string,
@Query('assetClasses') filterByAssetClasses?: string,
@Query('query') filterBySearchQuery?: string,
@Query('range') dateRange: DateRange = 'max',
@Query('tags') filterByTags?: string
): Promise<PortfolioPositions> {
const filters = this.apiService.buildFiltersFromQueryParams({
filterByAccounts,
filterByAssetClasses,
filterBySearchQuery,
filterByTags
});
return this.portfolioService.getPositions({
dateRange,
filters,
impersonationId
});
}
@Get('public/:accessId')
@UseInterceptors(TransformDataSourceInResponseInterceptor)
public async getPublic(

2
apps/api/src/events/portfolio-changed.listener.ts

@ -12,7 +12,7 @@ export class PortfolioChangedListener {
@OnEvent(PortfolioChangedEvent.getName())
handlePortfolioChangedEvent(event: PortfolioChangedEvent) {
Logger.log(
`Portfolio of user with id ${event.getUserId()} has changed`,
`Portfolio of user '${event.getUserId()}' has changed`,
'PortfolioChangedListener'
);

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

@ -13,13 +13,23 @@ import {
OnDestroy,
OnInit
} from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Title } from '@angular/platform-browser';
import { NavigationEnd, PRIMARY_OUTLET, Router } from '@angular/router';
import {
ActivatedRoute,
NavigationEnd,
PRIMARY_OUTLET,
Router
} from '@angular/router';
import { DataSource } from '@prisma/client';
import { DeviceDetectorService } from 'ngx-device-detector';
import { Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';
import { PositionDetailDialogParams } from './components/position-detail-dialog/interfaces/interfaces';
import { PositionDetailDialog } from './components/position-detail-dialog/position-detail-dialog.component';
import { DataService } from './services/data.service';
import { ImpersonationStorageService } from './services/impersonation-storage.service';
import { TokenStorageService } from './services/token-storage.service';
import { UserService } from './services/user/user.service';
@ -38,6 +48,7 @@ export class AppComponent implements OnDestroy, OnInit {
public currentRoute: string;
public currentYear = new Date().getFullYear();
public deviceType: string;
public hasImpersonationId: boolean;
public hasInfoMessage: boolean;
public hasPermissionForStatistics: boolean;
public hasPermissionForSubscription: boolean;
@ -67,7 +78,10 @@ export class AppComponent implements OnDestroy, OnInit {
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService,
private deviceService: DeviceDetectorService,
private dialog: MatDialog,
@Inject(DOCUMENT) private document: Document,
private impersonationStorageService: ImpersonationStorageService,
private route: ActivatedRoute,
private router: Router,
private title: Title,
private tokenStorageService: TokenStorageService,
@ -75,6 +89,21 @@ export class AppComponent implements OnDestroy, OnInit {
) {
this.initializeTheme();
this.user = undefined;
this.route.queryParams
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((params) => {
if (
params['dataSource'] &&
params['holdingDetailDialog'] &&
params['symbol']
) {
this.openHoldingDetailDialog({
dataSource: params['dataSource'],
symbol: params['symbol']
});
}
});
}
public ngOnInit() {
@ -96,6 +125,13 @@ export class AppComponent implements OnDestroy, OnInit {
permissions.enableFearAndGreedIndex
);
this.impersonationStorageService
.onChangeHasImpersonation()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((impersonationId) => {
this.hasImpersonationId = !!impersonationId;
});
this.router.events
.pipe(filter((event) => event instanceof NavigationEnd))
.subscribe(() => {
@ -197,6 +233,55 @@ export class AppComponent implements OnDestroy, OnInit {
});
}
private openHoldingDetailDialog({
dataSource,
symbol
}: {
dataSource: DataSource;
symbol: string;
}) {
this.userService
.get()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((user) => {
this.user = user;
const dialogRef = this.dialog.open(PositionDetailDialog, {
autoFocus: false,
data: <PositionDetailDialogParams>{
dataSource,
symbol,
baseCurrency: this.user?.settings?.baseCurrency,
colorScheme: this.user?.settings?.colorScheme,
deviceType: this.deviceType,
hasImpersonationId: this.hasImpersonationId,
hasPermissionToReportDataGlitch: hasPermission(
this.user?.permissions,
permissions.reportDataGlitch
),
locale: this.user?.settings?.locale
},
height: this.deviceType === 'mobile' ? '97.5vh' : '80vh',
width: this.deviceType === 'mobile' ? '100vw' : '50rem'
});
dialogRef
.afterClosed()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
this.router.navigate([], {
queryParams: {
dataSource: null,
holdingDetailDialog: null,
symbol: null
},
queryParamsHandling: 'merge',
relativeTo: this.route
});
});
});
}
private toggleTheme(isDarkTheme: boolean) {
const themeColor = getCssVariable(
isDarkTheme ? '--dark-background' : '--light-background'

1
apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html

@ -94,6 +94,7 @@
[dataSource]="dataSource"
[deviceType]="data.deviceType"
[hasPermissionToCreateActivity]="false"
[hasPermissionToDeleteActivity]="false"
[hasPermissionToExportActivities]="
!data.hasImpersonationId && !user.settings.isRestrictedView
"

1
apps/client/src/app/components/admin-market-data/admin-market-data.component.ts

@ -38,6 +38,7 @@ import { CreateAssetProfileDialogParams } from './create-asset-profile-dialog/in
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'has-fab' },
selector: 'gf-admin-market-data',
styleUrls: ['./admin-market-data.scss'],
templateUrl: './admin-market-data.html'

5
apps/client/src/app/components/header/header.component.html

@ -116,7 +116,12 @@
#assistantTrigger="matMenuTrigger"
class="h-100 no-min-width px-2"
mat-button
matBadge="✓"
matBadgeSize="small"
[mat-menu-trigger-for]="assistantMenu"
[matBadgeHidden]="
!hasFilters || !user?.settings?.isExperimentalFeatures
"
[matMenuTriggerRestoreFocus]="false"
(menuOpened)="onOpenAssistant()"
>

11
apps/client/src/app/components/header/header.component.scss

@ -28,6 +28,17 @@
text-underline-offset: 0.25rem;
}
&.mat-badge {
::ng-deep {
.mat-badge-content {
--mat-badge-small-size-container-overlap-offset: -0.9rem;
--mat-badge-small-size-text-size: 0;
transform: scale(0.45);
}
}
}
ion-icon {
font-size: 1.5rem;

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

@ -65,6 +65,7 @@ export class HeaderComponent implements OnChanges {
@ViewChild('assistant') assistantElement: GfAssistantComponent;
@ViewChild('assistantTrigger') assistentMenuTriggerElement: MatMenuTrigger;
public hasFilters: boolean;
public hasPermissionForSocialLogin: boolean;
public hasPermissionForSubscription: boolean;
public hasPermissionToAccessAdminControl: boolean;
@ -106,6 +107,8 @@ export class HeaderComponent implements OnChanges {
}
public ngOnChanges() {
this.hasFilters = this.userService.hasFilters();
this.hasPermissionForSocialLogin = hasPermission(
this.info?.globalPermissions,
permissions.enableSocialLogin

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

@ -5,6 +5,7 @@ import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatBadgeModule } from '@angular/material/badge';
import { MatButtonModule } from '@angular/material/button';
import { MatMenuModule } from '@angular/material/menu';
import { MatToolbarModule } from '@angular/material/toolbar';
@ -21,6 +22,7 @@ import { HeaderComponent } from './header.component';
GfLogoComponent,
GfPremiumIndicatorComponent,
LoginWithAccessTokenDialogModule,
MatBadgeModule,
MatButtonModule,
MatMenuModule,
MatToolbarModule,

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

@ -1,5 +1,3 @@
import { PositionDetailDialogParams } from '@ghostfolio/client/components/position-detail-dialog/interfaces/interfaces';
import { PositionDetailDialog } from '@ghostfolio/client/components/position-detail-dialog/position-detail-dialog.component';
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';
@ -8,9 +6,6 @@ import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { HoldingType, ToggleOption } from '@ghostfolio/common/types';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { DataSource } from '@prisma/client';
import { DeviceDetectorService } from 'ngx-device-detector';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@ -38,27 +33,9 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit {
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService,
private deviceService: DeviceDetectorService,
private dialog: MatDialog,
private impersonationStorageService: ImpersonationStorageService,
private route: ActivatedRoute,
private router: Router,
private userService: UserService
) {
this.route.queryParams
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((params) => {
if (
params['dataSource'] &&
params['positionDetailDialog'] &&
params['symbol']
) {
this.openPositionDialog({
dataSource: params['dataSource'],
symbol: params['symbol']
});
}
});
}
) {}
public ngOnInit() {
this.deviceType = this.deviceService.getDeviceInfo().deviceType;
@ -127,45 +104,4 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit {
range: this.user?.settings?.dateRange
});
}
private openPositionDialog({
dataSource,
symbol
}: {
dataSource: DataSource;
symbol: string;
}) {
this.userService
.get()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((user) => {
this.user = user;
const dialogRef = this.dialog.open(PositionDetailDialog, {
autoFocus: false,
data: <PositionDetailDialogParams>{
dataSource,
symbol,
baseCurrency: this.user?.settings?.baseCurrency,
colorScheme: this.user?.settings?.colorScheme,
deviceType: this.deviceType,
hasImpersonationId: this.hasImpersonationId,
hasPermissionToReportDataGlitch: hasPermission(
this.user?.permissions,
permissions.reportDataGlitch
),
locale: this.user?.settings?.locale
},
height: this.deviceType === 'mobile' ? '97.5vh' : '80vh',
width: this.deviceType === 'mobile' ? '100vw' : '50rem'
});
dialogRef
.afterClosed()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
this.router.navigate(['.'], { relativeTo: this.route });
});
});
}
}

1
apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html

@ -335,6 +335,7 @@
[dataSource]="dataSource"
[deviceType]="data.deviceType"
[hasPermissionToCreateActivity]="false"
[hasPermissionToDeleteActivity]="false"
[hasPermissionToExportActivities]="
!data.hasImpersonationId && !user?.settings?.isRestrictedView
"

1
apps/client/src/app/components/user-account-access/user-account-access.component.ts

@ -21,6 +21,7 @@ import { CreateOrUpdateAccessDialog } from './create-or-update-access-dialog/cre
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'has-fab' },
selector: 'gf-user-account-access',
styleUrls: ['./user-account-access.scss'],
templateUrl: './user-account-access.html'

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

@ -77,7 +77,7 @@
mat-icon-button
title="Follow Ghostfolio on X (formerly Twitter)"
>
<span class="line-height-1 text-center w-100">𝕏</span>
<ion-icon name="logo-x" />
</a>
<a
*ngIf="user?.subscription?.type === 'Premium'"

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

@ -21,7 +21,7 @@ import { CreateOrUpdateAccountDialog } from './create-or-update-account-dialog/c
import { TransferBalanceDialog } from './transfer-balance/transfer-balance-dialog.component';
@Component({
host: { class: 'page' },
host: { class: 'has-fab page' },
selector: 'gf-accounts-page',
styleUrls: ['./accounts-page.scss'],
templateUrl: './accounts-page.html'

6
apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html

@ -30,8 +30,10 @@
systems, including
<a href="https://github.com/bigbeartechworld/big-bear-casaos"
>CasaOS</a
>, Home Assistant,
<a href="https://www.runtipi.io/docs/apps-available">Runtipi</a>,
>,
<a href="https://github.com/lildude/ha-addon-ghostfolio"
>Home Assistant</a
>, <a href="https://www.runtipi.io/docs/apps-available">Runtipi</a>,
<a href="https://truecharts.org/charts/stable/ghostfolio"
>TrueCharts</a
>, <a href="https://apps.umbrel.com/app/ghostfolio">Umbrel</a>, and

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

@ -1,3 +1,4 @@
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';
@ -14,6 +15,7 @@ import { takeUntil } from 'rxjs/operators';
})
export class HomePageComponent implements OnDestroy, OnInit {
public deviceType: string;
public hasImpersonationId: boolean;
public tabs: TabConfiguration[] = [];
public user: User;
@ -22,6 +24,7 @@ export class HomePageComponent implements OnDestroy, OnInit {
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private deviceService: DeviceDetectorService,
private impersonationStorageService: ImpersonationStorageService,
private userService: UserService
) {
this.userService.stateChanged
@ -59,6 +62,13 @@ export class HomePageComponent implements OnDestroy, OnInit {
public ngOnInit() {
this.deviceType = this.deviceService.getDeviceInfo().deviceType;
this.impersonationStorageService
.onChangeHasImpersonation()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((impersonationId) => {
this.hasImpersonationId = !!impersonationId;
});
}
public ngOnDestroy() {

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

@ -1,8 +1,6 @@
import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto';
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
import { UpdateOrderDto } from '@ghostfolio/api/app/order/update-order.dto';
import { PositionDetailDialogParams } from '@ghostfolio/client/components/position-detail-dialog/interfaces/interfaces';
import { PositionDetailDialog } from '@ghostfolio/client/components/position-detail-dialog/position-detail-dialog.component';
import { DataService } from '@ghostfolio/client/services/data.service';
import { IcsService } from '@ghostfolio/client/services/ics/ics.service';
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
@ -18,7 +16,7 @@ import { PageEvent } from '@angular/material/paginator';
import { Sort, SortDirection } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { ActivatedRoute, Router } from '@angular/router';
import { DataSource, Order as OrderModel } from '@prisma/client';
import { Order as OrderModel } from '@prisma/client';
import { format, parseISO } from 'date-fns';
import { DeviceDetectorService } from 'ngx-device-detector';
import { Subject, Subscription } from 'rxjs';
@ -29,6 +27,7 @@ import { ImportActivitiesDialog } from './import-activities-dialog/import-activi
import { ImportActivitiesDialogParams } from './import-activities-dialog/interfaces/interfaces';
@Component({
host: { class: 'has-fab' },
selector: 'gf-activities-page',
styleUrls: ['./activities-page.scss'],
templateUrl: './activities-page.html'
@ -82,15 +81,6 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
} else {
this.router.navigate(['.'], { relativeTo: this.route });
}
} else if (
params['dataSource'] &&
params['positionDetailDialog'] &&
params['symbol']
) {
this.openPositionDialog({
dataSource: params['dataSource'],
symbol: params['symbol']
});
}
});
}
@ -154,7 +144,7 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
public onDeleteActivity(aId: string) {
this.dataService
.deleteOrder(aId)
.deleteActivity(aId)
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe({
next: () => {
@ -170,7 +160,7 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
if (confirmation) {
this.dataService
.deleteAllOrders()
.deleteAllActivities()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe({
next: () => {
@ -350,47 +340,6 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
});
}
private openPositionDialog({
dataSource,
symbol
}: {
dataSource: DataSource;
symbol: string;
}) {
this.userService
.get()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((user) => {
this.updateUser(user);
const dialogRef = this.dialog.open(PositionDetailDialog, {
autoFocus: false,
data: <PositionDetailDialogParams>{
dataSource,
symbol,
baseCurrency: this.user?.settings?.baseCurrency,
colorScheme: this.user?.settings?.colorScheme,
deviceType: this.deviceType,
hasImpersonationId: this.hasImpersonationId,
hasPermissionToReportDataGlitch: hasPermission(
this.user?.permissions,
permissions.reportDataGlitch
),
locale: this.user?.settings?.locale
},
height: this.deviceType === 'mobile' ? '97.5vh' : '80vh',
width: this.deviceType === 'mobile' ? '100vw' : '50rem'
});
dialogRef
.afterClosed()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
this.router.navigate(['.'], { relativeTo: this.route });
});
});
}
private updateUser(aUser: User) {
this.user = aUser;
@ -399,6 +348,7 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
hasPermission(this.user.permissions, permissions.createOrder);
this.hasPermissionToDeleteActivity =
!this.hasImpersonationId &&
hasPermission(this.user.permissions, permissions.deleteOrder);
hasPermission(this.user.permissions, permissions.deleteOrder) &&
!this.userService.hasFilters();
}
}

1
apps/client/src/app/pages/portfolio/activities/activities-page.html

@ -7,6 +7,7 @@
[dataSource]="dataSource"
[deviceType]="deviceType"
[hasPermissionToCreateActivity]="hasPermissionToCreateActivity"
[hasPermissionToDeleteActivity]="hasPermissionToDeleteActivity"
[hasPermissionToExportActivities]="!hasImpersonationId"
[locale]="user?.settings?.locale"
[pageIndex]="pageIndex"

10
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts

@ -2,7 +2,7 @@ import { CreateAccountDto } from '@ghostfolio/api/app/account/create-account.dto
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
import { DataService } from '@ghostfolio/client/services/data.service';
import { ImportActivitiesService } from '@ghostfolio/client/services/import-activities.service';
import { Position } from '@ghostfolio/common/interfaces';
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
import {
StepperOrientation,
@ -43,7 +43,7 @@ export class ImportActivitiesDialog implements OnDestroy {
public deviceType: string;
public dialogTitle = $localize`Import Activities`;
public errorMessages: string[] = [];
public holdings: Position[] = [];
public holdings: PortfolioPosition[] = [];
public importStep: ImportStep = ImportStep.UPLOAD_FILE;
public isLoading = false;
public maxSafeInteger = Number.MAX_SAFE_INTEGER;
@ -88,7 +88,7 @@ export class ImportActivitiesDialog implements OnDestroy {
this.uniqueAssetForm.get('uniqueAsset').disable();
this.dataService
.fetchPositions({
.fetchPortfolioHoldings({
filters: [
{
id: AssetClass.EQUITY,
@ -98,8 +98,8 @@ export class ImportActivitiesDialog implements OnDestroy {
range: 'max'
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ positions }) => {
this.holdings = sortBy(positions, ({ name }) => {
.subscribe(({ holdings }) => {
this.holdings = sortBy(holdings, ({ name }) => {
return name.toLowerCase();
});
this.uniqueAssetForm.get('uniqueAsset').enable();

1
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html

@ -126,6 +126,7 @@
[dataSource]="dataSource"
[deviceType]="data?.deviceType"
[hasPermissionToCreateActivity]="false"
[hasPermissionToDeleteActivity]="false"
[hasPermissionToExportActivities]="false"
[hasPermissionToFilter]="false"
[hasPermissionToOpenDetails]="false"

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

@ -1,7 +1,5 @@
import { AccountDetailDialog } from '@ghostfolio/client/components/account-detail-dialog/account-detail-dialog.component';
import { AccountDetailDialogParams } from '@ghostfolio/client/components/account-detail-dialog/interfaces/interfaces';
import { PositionDetailDialogParams } from '@ghostfolio/client/components/position-detail-dialog/interfaces/interfaces';
import { PositionDetailDialog } from '@ghostfolio/client/components/position-detail-dialog/position-detail-dialog.component';
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';
@ -13,7 +11,6 @@ import {
UniqueAsset,
User
} from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { Market, MarketAdvanced } from '@ghostfolio/common/types';
import { translate } from '@ghostfolio/ui/i18n';
@ -108,15 +105,6 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
.subscribe((params) => {
if (params['accountId'] && params['accountDetailDialog']) {
this.openAccountDetailDialog(params['accountId']);
} else if (
params['dataSource'] &&
params['positionDetailDialog'] &&
params['symbol']
) {
this.openPositionDialog({
dataSource: params['dataSource'],
symbol: params['symbol']
});
}
});
}
@ -178,7 +166,7 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
public onSymbolChartClicked({ dataSource, symbol }: UniqueAsset) {
if (dataSource && symbol) {
this.router.navigate([], {
queryParams: { dataSource, symbol, positionDetailDialog: true }
queryParams: { dataSource, symbol, holdingDetailDialog: true }
});
}
}
@ -551,45 +539,4 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
this.router.navigate(['.'], { relativeTo: this.route });
});
}
private openPositionDialog({
dataSource,
symbol
}: {
dataSource: DataSource;
symbol: string;
}) {
this.userService
.get()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((user) => {
this.user = user;
const dialogRef = this.dialog.open(PositionDetailDialog, {
autoFocus: false,
data: <PositionDetailDialogParams>{
dataSource,
symbol,
baseCurrency: this.user?.settings?.baseCurrency,
colorScheme: this.user?.settings?.colorScheme,
deviceType: this.deviceType,
hasImpersonationId: this.hasImpersonationId,
hasPermissionToReportDataGlitch: hasPermission(
this.user?.permissions,
permissions.reportDataGlitch
),
locale: this.user?.settings?.locale
},
height: this.deviceType === 'mobile' ? '97.5vh' : '80vh',
width: this.deviceType === 'mobile' ? '100vw' : '50rem'
});
dialogRef
.afterClosed()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
this.router.navigate(['.'], { relativeTo: this.route });
});
});
}
}

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

@ -1,5 +1,3 @@
import { PositionDetailDialogParams } from '@ghostfolio/client/components/position-detail-dialog/interfaces/interfaces';
import { PositionDetailDialog } from '@ghostfolio/client/components/position-detail-dialog/position-detail-dialog.component';
import { ToggleComponent } from '@ghostfolio/client/components/toggle/toggle.component';
import { DataService } from '@ghostfolio/client/services/data.service';
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
@ -8,18 +6,15 @@ import {
HistoricalDataItem,
PortfolioInvestments,
PortfolioPerformance,
Position,
PortfolioPosition,
User
} from '@ghostfolio/common/interfaces';
import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { GroupBy, ToggleOption } from '@ghostfolio/common/types';
import { translate } from '@ghostfolio/ui/i18n';
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { DataSource, SymbolProfile } from '@prisma/client';
import { SymbolProfile } from '@prisma/client';
import { differenceInDays } from 'date-fns';
import { isNumber, sortBy } from 'lodash';
import { DeviceDetectorService } from 'ngx-device-detector';
@ -35,7 +30,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
public benchmark: Partial<SymbolProfile>;
public benchmarkDataItems: HistoricalDataItem[] = [];
public benchmarks: Partial<SymbolProfile>[];
public bottom3: Position[];
public bottom3: PortfolioPosition[];
public dateRangeOptions = ToggleComponent.DEFAULT_DATE_RANGE_OPTIONS;
public daysInMarket: number;
public deviceType: string;
@ -60,7 +55,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
public performanceDataItemsInPercentage: HistoricalDataItem[];
public portfolioEvolutionDataLabel = $localize`Investment`;
public streaks: PortfolioInvestments['streaks'];
public top3: Position[];
public top3: PortfolioPosition[];
public unitCurrentStreak: string;
public unitLongestStreak: string;
public user: User;
@ -70,30 +65,12 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService,
private dialog: MatDialog,
private deviceService: DeviceDetectorService,
private impersonationStorageService: ImpersonationStorageService,
private route: ActivatedRoute,
private router: Router,
private userService: UserService
) {
const { benchmarks } = this.dataService.fetchInfo();
this.benchmarks = benchmarks;
this.route.queryParams
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((params) => {
if (
params['dataSource'] &&
params['positionDetailDialog'] &&
params['symbol']
) {
this.openPositionDialog({
dataSource: params['dataSource'],
symbol: params['symbol']
});
}
});
}
get savingsRate() {
@ -212,47 +189,6 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
});
}
private openPositionDialog({
dataSource,
symbol
}: {
dataSource: DataSource;
symbol: string;
}) {
this.userService
.get()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((user) => {
this.user = user;
const dialogRef = this.dialog.open(PositionDetailDialog, {
autoFocus: false,
data: <PositionDetailDialogParams>{
dataSource,
symbol,
baseCurrency: this.user?.settings?.baseCurrency,
colorScheme: this.user?.settings?.colorScheme,
deviceType: this.deviceType,
hasImpersonationId: this.hasImpersonationId,
hasPermissionToReportDataGlitch: hasPermission(
this.user?.permissions,
permissions.reportDataGlitch
),
locale: this.user?.settings?.locale
},
height: this.deviceType === 'mobile' ? '97.5vh' : '80vh',
width: this.deviceType === 'mobile' ? '100vw' : '50rem'
});
dialogRef
.afterClosed()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(() => {
this.router.navigate(['.'], { relativeTo: this.route });
});
});
}
private update() {
this.isLoadingInvestmentChart = true;
@ -308,23 +244,23 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
});
this.dataService
.fetchPositions({
.fetchPortfolioHoldings({
filters: this.userService.getFilters(),
range: this.user?.settings?.dateRange
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ positions }) => {
const positionsSorted = sortBy(
positions.filter(({ netPerformancePercentageWithCurrencyEffect }) => {
return isNumber(netPerformancePercentageWithCurrencyEffect);
.subscribe(({ holdings }) => {
const holdingsSorted = sortBy(
holdings.filter(({ netPerformancePercentWithCurrencyEffect }) => {
return isNumber(netPerformancePercentWithCurrencyEffect);
}),
'netPerformancePercentageWithCurrencyEffect'
'netPerformancePercentWithCurrencyEffect'
).reverse();
this.top3 = positionsSorted.slice(0, 3);
this.top3 = holdingsSorted.slice(0, 3);
if (positions?.length > 3) {
this.bottom3 = positionsSorted.slice(-3).reverse();
if (holdings?.length > 3) {
this.bottom3 = holdingsSorted.slice(-3).reverse();
} else {
this.bottom3 = [];
}

28
apps/client/src/app/pages/portfolio/analysis/analysis-page.html

@ -170,17 +170,17 @@
</mat-card-header>
<mat-card-content>
<ol class="mb-0 ml-1 pl-3">
<li *ngFor="let position of top3" class="py-1">
<li *ngFor="let holding of top3" class="py-1">
<a
class="d-flex"
[queryParams]="{
dataSource: position.dataSource,
positionDetailDialog: true,
symbol: position.symbol
dataSource: holding.dataSource,
holdingDetailDialog: true,
symbol: holding.symbol
}"
[routerLink]="[]"
>
<div class="flex-grow-1 mr-2">{{ position.name }}</div>
<div class="flex-grow-1 mr-2">{{ holding.name }}</div>
<div class="d-flex justify-content-end">
<gf-value
class="justify-content-end"
@ -188,9 +188,7 @@
[colorizeSign]="true"
[isPercent]="true"
[locale]="user?.settings?.locale"
[value]="
position.netPerformancePercentageWithCurrencyEffect
"
[value]="holding.netPerformancePercentWithCurrencyEffect"
/>
</div>
</a>
@ -218,17 +216,17 @@
</mat-card-header>
<mat-card-content>
<ol class="mb-0 ml-1 pl-3">
<li *ngFor="let position of bottom3" class="py-1">
<li *ngFor="let holding of bottom3" class="py-1">
<a
class="d-flex"
[queryParams]="{
dataSource: position.dataSource,
positionDetailDialog: true,
symbol: position.symbol
dataSource: holding.dataSource,
holdingDetailDialog: true,
symbol: holding.symbol
}"
[routerLink]="[]"
>
<div class="flex-grow-1 mr-2">{{ position.name }}</div>
<div class="flex-grow-1 mr-2">{{ holding.name }}</div>
<div class="d-flex justify-content-end">
<gf-value
class="justify-content-end"
@ -236,9 +234,7 @@
[colorizeSign]="true"
[isPercent]="true"
[locale]="user?.settings?.locale"
[value]="
position.netPerformancePercentageWithCurrencyEffect
"
[value]="holding.netPerformancePercentWithCurrencyEffect"
/>
</div>
</a>

31
apps/client/src/app/services/data.service.ts

@ -6,7 +6,6 @@ import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto';
import { Activities } from '@ghostfolio/api/app/order/interfaces/activities.interface';
import { UpdateOrderDto } from '@ghostfolio/api/app/order/update-order.dto';
import { PortfolioPositionDetail } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-position-detail.interface';
import { PortfolioPositions } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-positions.interface';
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { SymbolItem } from '@ghostfolio/api/app/symbol/interfaces/symbol-item.interface';
import { UserItem } from '@ghostfolio/api/app/user/interfaces/user-item.interface';
@ -257,16 +256,16 @@ export class DataService {
return this.http.delete<any>(`/api/v1/account-balance/${aId}`);
}
public deleteAllOrders() {
return this.http.delete<any>(`/api/v1/order/`);
public deleteActivity(aId: string) {
return this.http.delete<any>(`/api/v1/order/${aId}`);
}
public deleteBenchmark({ dataSource, symbol }: UniqueAsset) {
return this.http.delete<any>(`/api/v1/benchmark/${dataSource}/${symbol}`);
public deleteAllActivities() {
return this.http.delete<any>(`/api/v1/order`);
}
public deleteOrder(aId: string) {
return this.http.delete<any>(`/api/v1/order/${aId}`);
public deleteBenchmark({ dataSource, symbol }: UniqueAsset) {
return this.http.delete<any>(`/api/v1/benchmark/${dataSource}/${symbol}`);
}
public deleteUser(aId: string) {
@ -376,24 +375,6 @@ export class DataService {
});
}
/**
* @deprecated
*/
public fetchPositions({
filters,
range
}: {
filters?: Filter[];
range: DateRange;
}): Observable<PortfolioPositions> {
let params = this.buildFiltersAsQueryParams({ filters });
params = params.append('range', range);
return this.http.get<PortfolioPositions>('/api/v1/portfolio/positions', {
params
});
}
public fetchSymbols({
includeIndices = false,
query

10
apps/client/src/app/services/user/user.service.ts

@ -51,21 +51,21 @@ export class UserService extends ObservableStore<UserStoreState> {
const filters: Filter[] = [];
const user = this.getState().user;
if (user.settings['filters.accounts']) {
if (user?.settings['filters.accounts']) {
filters.push({
id: user.settings['filters.accounts'][0],
type: 'ACCOUNT'
});
}
if (user.settings['filters.assetClasses']) {
if (user?.settings['filters.assetClasses']) {
filters.push({
id: user.settings['filters.assetClasses'][0],
type: 'ASSET_CLASS'
});
}
if (user.settings['filters.tags']) {
if (user?.settings['filters.tags']) {
filters.push({
id: user.settings['filters.tags'][0],
type: 'TAG'
@ -75,6 +75,10 @@ export class UserService extends ObservableStore<UserStoreState> {
return filters;
}
public hasFilters() {
return this.getFilters().length > 0;
}
public remove() {
this.setState({ user: null }, UserStoreActions.RemoveUser);
}

296
apps/client/src/locales/messages.de.xlf

File diff suppressed because it is too large

293
apps/client/src/locales/messages.es.xlf

File diff suppressed because it is too large

293
apps/client/src/locales/messages.fr.xlf

File diff suppressed because it is too large

293
apps/client/src/locales/messages.it.xlf

File diff suppressed because it is too large

293
apps/client/src/locales/messages.nl.xlf

File diff suppressed because it is too large

296
apps/client/src/locales/messages.pl.xlf

File diff suppressed because it is too large

293
apps/client/src/locales/messages.pt.xlf

File diff suppressed because it is too large

293
apps/client/src/locales/messages.tr.xlf

File diff suppressed because it is too large

289
apps/client/src/locales/messages.xlf

@ -1589,11 +1589,11 @@
<context context-type="linenumber">134</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">221</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">331</context>
</context-group>
<context-group purpose="location">
@ -1880,7 +1880,7 @@
<context context-type="linenumber">34</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">301</context>
</context-group>
</trans-unit>
@ -1988,7 +1988,7 @@
<context context-type="linenumber">26</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">112</context>
</context-group>
</trans-unit>
@ -2120,7 +2120,7 @@
<context context-type="linenumber">232</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">228</context>
</context-group>
<context-group purpose="location">
@ -2143,7 +2143,7 @@
<context context-type="linenumber">245</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">237</context>
</context-group>
<context-group purpose="location">
@ -2162,7 +2162,7 @@
<context context-type="linenumber">130</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">209</context>
</context-group>
<context-group purpose="location">
@ -2270,7 +2270,7 @@
<context context-type="linenumber">174</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">254</context>
</context-group>
</trans-unit>
@ -2285,7 +2285,7 @@
<context context-type="linenumber">77</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">264</context>
</context-group>
</trans-unit>
@ -2300,7 +2300,7 @@
<context context-type="linenumber">316</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">270</context>
</context-group>
<context-group purpose="location">
@ -2319,7 +2319,7 @@
<context context-type="linenumber">327</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">282</context>
</context-group>
</trans-unit>
@ -2583,7 +2583,7 @@
<context context-type="linenumber">257</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">356</context>
</context-group>
<context-group purpose="location">
@ -2630,7 +2630,7 @@
<context context-type="linenumber">10</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">376</context>
</context-group>
<context-group purpose="location">
@ -2726,12 +2726,12 @@
<context context-type="linenumber">6</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">89</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/holdings-table/holdings-table.component.html</context>
<context context-type="linenumber">119</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="44fcf77e86dc038202ebad6b46d1d833d60d781b" datatype="html">
@ -2756,7 +2756,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts</context>
<context context-type="linenumber">48</context>
<context context-type="linenumber">41</context>
</context-group>
</trans-unit>
<trans-unit id="1931353503905413384" datatype="html">
@ -2878,10 +2878,6 @@
<source>Manage Activities</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-holdings/home-holdings.html</context>
<context context-type="linenumber">22</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/holdings/holdings-page.html</context>
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
@ -2893,7 +2889,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">71</context>
</context-group>
</trans-unit>
<trans-unit id="6844699413925472826" datatype="html">
@ -2904,7 +2900,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">71</context>
<context context-type="linenumber">72</context>
</context-group>
</trans-unit>
<trans-unit id="ce718ababbce63d776cf8b1f91412beb4c0a6e04" datatype="html">
@ -3093,45 +3089,28 @@
<context context-type="linenumber">3</context>
</context-group>
</trans-unit>
<trans-unit id="97226819b093f672baea3bb0c6c0f6da02f88ad2" datatype="html">
<source>
<x id="INTERPOLATION" equiv-text="{{ summary?.ordersCount }}"/>
<x id="ICU" equiv-text="{summary?.ordersCount, plural, =1 {transaction} other {transactions}}"/>
</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">12</context>
</context-group>
</trans-unit>
<trans-unit id="272c7fd98af55bfa5b9d579176f1cfa25cd5489f" datatype="html">
<source>{VAR_PLURAL, plural, =1 {transaction} other {transactions}}</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">14</context>
</context-group>
</trans-unit>
<trans-unit id="1befce3c6f0c468b06ae5199116e5b096a35a3ef" datatype="html">
<source>Buy</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">21</context>
<context context-type="linenumber">31</context>
</context-group>
</trans-unit>
<trans-unit id="fe708b572beec788b18edd1b5852d63c07dfaead" datatype="html">
<source>Sell</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">33</context>
<context context-type="linenumber">43</context>
</context-group>
</trans-unit>
<trans-unit id="9bbc9e4cebf91162be7d3e324ca5984d576e462c" datatype="html">
<source>Investment</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">48</context>
<context context-type="linenumber">58</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">165</context>
</context-group>
</trans-unit>
@ -3139,24 +3118,24 @@
<source>Absolute Gross Performance</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">60</context>
<context context-type="linenumber">70</context>
</context-group>
</trans-unit>
<trans-unit id="a1cfd95460b49b8cfa6c34f0c673715044bcde14" datatype="html">
<source>Gross Performance</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">77</context>
<context context-type="linenumber">85</context>
</context-group>
</trans-unit>
<trans-unit id="c20172223f84462032664d717d739297e5a9e2fe" datatype="html">
<source>Fees</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">100</context>
<context context-type="linenumber">108</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">199</context>
</context-group>
<context-group purpose="location">
@ -3168,35 +3147,35 @@
<source>Absolute Net Performance</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">116</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
<trans-unit id="26de2fb4d52a11f78e22587a48690cba0fc6fa58" datatype="html">
<source>Net Performance</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">133</context>
<context context-type="linenumber">139</context>
</context-group>
</trans-unit>
<trans-unit id="f159ffb7a09c8c1fe7913ef063462db50ddcd878" datatype="html">
<source>Total Assets</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">159</context>
<context context-type="linenumber">165</context>
</context-group>
</trans-unit>
<trans-unit id="59d87bdb983dda90c1e86d086430552ec05c7a4d" datatype="html">
<source>Valuables</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">172</context>
<context context-type="linenumber">178</context>
</context-group>
</trans-unit>
<trans-unit id="2201b2004bc4997a66f6f8ea2511a4e1311f3de1" datatype="html">
<source>Emergency Fund</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">184</context>
<context context-type="linenumber">190</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
@ -3211,35 +3190,35 @@
<source>Cash</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">205</context>
<context context-type="linenumber">211</context>
</context-group>
</trans-unit>
<trans-unit id="ee8f8008bae6ce3a49840c4e1d39b4af23d4c263" datatype="html">
<source>Assets</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">218</context>
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="8cce9d03787606e0052d19c2ae7e7fa5ff785e94" datatype="html">
<source>Buying Power</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">231</context>
<context context-type="linenumber">237</context>
</context-group>
</trans-unit>
<trans-unit id="98fc3013bfcbf452b9f37bbfcdb77b9b882866e3" datatype="html">
<source>Excluded from Analysis</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">243</context>
<context context-type="linenumber">249</context>
</context-group>
</trans-unit>
<trans-unit id="0b1e2c97e139808a34bd77b7da3504ece6c570cb" datatype="html">
<source>Liabilities</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">258</context>
<context context-type="linenumber">264</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
@ -3250,31 +3229,31 @@
<source>Net Worth</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
</trans-unit>
<trans-unit id="e702514cebbfb335331b6d6156ffeacb8c3b14e4" datatype="html">
<source> Annualized Performance </source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">290</context>
<context context-type="linenumber">296</context>
</context-group>
</trans-unit>
<trans-unit id="fe788dd32538034a1afe978e956f3d2403e2df83" datatype="html">
<source>Interest</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">312</context>
<context context-type="linenumber">318</context>
</context-group>
</trans-unit>
<trans-unit id="d3aa83bd247983dd056a62f56ffb25269bd98d47" datatype="html">
<source>Dividend</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">324</context>
<context context-type="linenumber">330</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">177</context>
</context-group>
<context-group purpose="location">
@ -3294,41 +3273,45 @@
<source>Please enter the amount of your emergency fund:</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts</context>
<context context-type="linenumber">53</context>
<context context-type="linenumber">57</context>
</context-group>
</trans-unit>
<trans-unit id="024cdb2814b0cb3f4ced148f1a0b9854447cb214" datatype="html">
<source>Change</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">63</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/holdings-table/holdings-table.component.html</context>
<context context-type="linenumber">119</context>
</context-group>
</trans-unit>
<trans-unit id="3c5ec7bc638db6f37c402e4afab2084f8763e268" datatype="html">
<source>Average Unit Price</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">101</context>
</context-group>
</trans-unit>
<trans-unit id="b1c1c6a43da1ad3e41b7a6e3aa5dcc24226cf580" datatype="html">
<source>Minimum Price</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">128</context>
</context-group>
</trans-unit>
<trans-unit id="6dd84054c52e1edf631f37accb054de0c4071069" datatype="html">
<source>Maximum Price</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">144</context>
</context-group>
</trans-unit>
<trans-unit id="ca30c1aa79fb5ab487fbd2caa4ca01f2f6691d70" datatype="html">
<source>Quantity</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">154</context>
</context-group>
<context-group purpose="location">
@ -3343,7 +3326,7 @@
<trans-unit id="43d544c2e88959f6c59cc4db419528fb0776bd6c" datatype="html">
<source>Report Data Glitch</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">394</context>
</context-group>
</trans-unit>
@ -3993,7 +3976,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/home/home-page.component.ts</context>
<context context-type="linenumber">34</context>
<context context-type="linenumber">61</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/zen/zen-page-routing.module.ts</context>
@ -4174,16 +4157,12 @@
<context context-type="linenumber">23</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/home/home-page.component.ts</context>
<context context-type="linenumber">39</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts</context>
<context context-type="linenumber">13</context>
<context context-type="sourcefile">apps/client/src/app/pages/home/home-page-routing.module.ts</context>
<context context-type="linenumber">28</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/portfolio-page.component.ts</context>
<context context-type="linenumber">39</context>
<context context-type="sourcefile">apps/client/src/app/pages/home/home-page.component.ts</context>
<context context-type="linenumber">66</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/zen/zen-page.component.ts</context>
@ -4194,22 +4173,22 @@
<source>Summary</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/home/home-page-routing.module.ts</context>
<context context-type="linenumber">28</context>
<context context-type="linenumber">33</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/home/home-page.component.ts</context>
<context context-type="linenumber">44</context>
<context context-type="linenumber">71</context>
</context-group>
</trans-unit>
<trans-unit id="7307236732616849044" datatype="html">
<source>Markets</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/home/home-page-routing.module.ts</context>
<context context-type="linenumber">33</context>
<context context-type="linenumber">38</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/home/home-page.component.ts</context>
<context context-type="linenumber">49</context>
<context context-type="linenumber">76</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/markets/markets-page-routing.module.ts</context>
@ -4605,7 +4584,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/portfolio-page.component.ts</context>
<context context-type="linenumber">44</context>
<context context-type="linenumber">39</context>
</context-group>
</trans-unit>
<trans-unit id="5316879909526485230" datatype="html">
@ -4840,7 +4819,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/portfolio-page.component.ts</context>
<context context-type="linenumber">49</context>
<context context-type="linenumber">44</context>
</context-group>
</trans-unit>
<trans-unit id="4e1990e98cbaad9d73fd81e20430a7fc1b06d11a" datatype="html">
@ -5001,7 +4980,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">31</context>
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="5213771062241898526" datatype="html">
@ -5043,42 +5022,42 @@
<source>Bottom</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">216</context>
<context context-type="linenumber">214</context>
</context-group>
</trans-unit>
<trans-unit id="f1a355a1af2e818050a3af693ac8b521fa7edc5f" datatype="html">
<source>Portfolio Evolution</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">268</context>
<context context-type="linenumber">264</context>
</context-group>
</trans-unit>
<trans-unit id="658bfe96ba9d3a3a2ada478c8c855286b841f92a" datatype="html">
<source>Investment Timeline</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">298</context>
<context context-type="linenumber">294</context>
</context-group>
</trans-unit>
<trans-unit id="1c275927e7e22395d21a86e4ab459e428bcac27e" datatype="html">
<source>Current Streak</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">319</context>
<context context-type="linenumber">315</context>
</context-group>
</trans-unit>
<trans-unit id="eabb7b2ede5498042bc9fbb565981a780bf340dc" datatype="html">
<source>Longest Streak</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">328</context>
<context context-type="linenumber">324</context>
</context-group>
</trans-unit>
<trans-unit id="6410cffb96159fcff46d91effc26df0e240bc0e3" datatype="html">
<source>Dividend Timeline</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">356</context>
<context context-type="linenumber">352</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -5137,7 +5116,7 @@
<context context-type="linenumber">77</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/holdings/holdings-page.html</context>
<context context-type="sourcefile">apps/client/src/app/components/home-holdings/home-holdings.html</context>
<context context-type="linenumber">4</context>
</context-group>
<context-group purpose="location">
@ -13648,7 +13627,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">33</context>
<context context-type="linenumber">34</context>
</context-group>
</trans-unit>
<trans-unit id="1054498214311181686" datatype="html">
@ -13669,7 +13648,7 @@
<source>Show all</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/holdings-table/holdings-table.component.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">197</context>
</context-group>
</trans-unit>
<trans-unit id="4086606389696938932" datatype="html">
@ -13704,91 +13683,91 @@
<source>Core</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">8</context>
<context context-type="linenumber">9</context>
</context-group>
</trans-unit>
<trans-unit id="3298117765569632011" datatype="html">
<source>Switch to Ghostfolio Premium or Ghostfolio Open Source easily</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">9</context>
<context context-type="linenumber">10</context>
</context-group>
</trans-unit>
<trans-unit id="1631940846690193897" datatype="html">
<source>Switch to Ghostfolio Premium easily</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">10</context>
<context context-type="linenumber">11</context>
</context-group>
</trans-unit>
<trans-unit id="1921273115613254799" datatype="html">
<source>Switch to Ghostfolio Open Source or Ghostfolio Basic easily</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">11</context>
<context context-type="linenumber">12</context>
</context-group>
</trans-unit>
<trans-unit id="6268646680388419543" datatype="html">
<source>Emergency Fund</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">12</context>
<context context-type="linenumber">13</context>
</context-group>
</trans-unit>
<trans-unit id="5036857680734170026" datatype="html">
<source>Grant</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">13</context>
<context context-type="linenumber">14</context>
</context-group>
</trans-unit>
<trans-unit id="2963674907100579427" datatype="html">
<source>Higher Risk</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">14</context>
<context context-type="linenumber">15</context>
</context-group>
</trans-unit>
<trans-unit id="687928208076721343" datatype="html">
<source>This activity already exists.</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">15</context>
<context context-type="linenumber">16</context>
</context-group>
</trans-unit>
<trans-unit id="80663871075536039" datatype="html">
<source>Japan</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">16</context>
<context context-type="linenumber">17</context>
</context-group>
</trans-unit>
<trans-unit id="4152514811781104574" datatype="html">
<source>Lower Risk</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">17</context>
<context context-type="linenumber">18</context>
</context-group>
</trans-unit>
<trans-unit id="5403684285319082289" datatype="html">
<source>Month</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">18</context>
<context context-type="linenumber">19</context>
</context-group>
</trans-unit>
<trans-unit id="4845030128243887325" datatype="html">
<source>Months</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">19</context>
<context context-type="linenumber">20</context>
</context-group>
</trans-unit>
<trans-unit id="8693603235657020323" datatype="html">
<source>Other</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">20</context>
<context context-type="linenumber">21</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts</context>
@ -13799,231 +13778,231 @@
<source>Preset</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">21</context>
<context context-type="linenumber">22</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
<source>Retirement Provision</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">22</context>
<context context-type="linenumber">23</context>
</context-group>
</trans-unit>
<trans-unit id="8050244774979733855" datatype="html">
<source>Satellite</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">23</context>
<context context-type="linenumber">24</context>
</context-group>
</trans-unit>
<trans-unit id="8106025670158480144" datatype="html">
<source>Symbol</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">24</context>
<context context-type="linenumber">25</context>
</context-group>
</trans-unit>
<trans-unit id="1825829511397926879" datatype="html">
<source>Tag</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">25</context>
<context context-type="linenumber">26</context>
</context-group>
</trans-unit>
<trans-unit id="1464072562214937907" datatype="html">
<source>Year</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">26</context>
<context context-type="linenumber">27</context>
</context-group>
</trans-unit>
<trans-unit id="953022389548488004" datatype="html">
<source>Years</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">27</context>
<context context-type="linenumber">28</context>
</context-group>
</trans-unit>
<trans-unit id="2149165958319691680" datatype="html">
<source>Buy</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">30</context>
<context context-type="linenumber">31</context>
</context-group>
</trans-unit>
<trans-unit id="1666887226757993490" datatype="html">
<source>Fee</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">32</context>
<context context-type="linenumber">33</context>
</context-group>
</trans-unit>
<trans-unit id="7025236479211408772" datatype="html">
<source>Valuable</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">34</context>
<context context-type="linenumber">35</context>
</context-group>
</trans-unit>
<trans-unit id="4230401090765872563" datatype="html">
<source>Liability</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">35</context>
<context context-type="linenumber">36</context>
</context-group>
</trans-unit>
<trans-unit id="4881880242577556" datatype="html">
<source>Sell</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">36</context>
<context context-type="linenumber">37</context>
</context-group>
</trans-unit>
<trans-unit id="787798817533231355" datatype="html">
<source>Cash</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">39</context>
<context context-type="linenumber">40</context>
</context-group>
</trans-unit>
<trans-unit id="8431989971855844965" datatype="html">
<source>Commodity</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">40</context>
<context context-type="linenumber">41</context>
</context-group>
</trans-unit>
<trans-unit id="1983771552391474467" datatype="html">
<source>Equity</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">41</context>
<context context-type="linenumber">42</context>
</context-group>
</trans-unit>
<trans-unit id="6124744839836623630" datatype="html">
<source>Fixed Income</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">42</context>
<context context-type="linenumber">43</context>
</context-group>
</trans-unit>
<trans-unit id="8432027249343784512" datatype="html">
<source>Real Estate</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">44</context>
<context context-type="linenumber">45</context>
</context-group>
</trans-unit>
<trans-unit id="8977365084844053365" datatype="html">
<source>Bond</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">48</context>
</context-group>
</trans-unit>
<trans-unit id="2893204435511484886" datatype="html">
<source>Cryptocurrency</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">48</context>
<context context-type="linenumber">49</context>
</context-group>
</trans-unit>
<trans-unit id="9071695492820527473" datatype="html">
<source>ETF</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">49</context>
<context context-type="linenumber">50</context>
</context-group>
</trans-unit>
<trans-unit id="5734784563242233466" datatype="html">
<source>Mutual Fund</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">50</context>
<context context-type="linenumber">51</context>
</context-group>
</trans-unit>
<trans-unit id="1270654249046226808" datatype="html">
<source>Precious Metal</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">51</context>
<context context-type="linenumber">52</context>
</context-group>
</trans-unit>
<trans-unit id="1346519036036997811" datatype="html">
<source>Private Equity</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">52</context>
<context context-type="linenumber">53</context>
</context-group>
</trans-unit>
<trans-unit id="4613338085351943838" datatype="html">
<source>Stock</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">53</context>
<context context-type="linenumber">54</context>
</context-group>
</trans-unit>
<trans-unit id="1413778527796351850" datatype="html">
<source>Africa</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">60</context>
<context context-type="linenumber">61</context>
</context-group>
</trans-unit>
<trans-unit id="3345512471687795386" datatype="html">
<source>Asia</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">61</context>
<context context-type="linenumber">62</context>
</context-group>
</trans-unit>
<trans-unit id="8350109327144196614" datatype="html">
<source>Europe</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">62</context>
<context context-type="linenumber">63</context>
</context-group>
</trans-unit>
<trans-unit id="1228771048078164312" datatype="html">
<source>North America</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">63</context>
<context context-type="linenumber">64</context>
</context-group>
</trans-unit>
<trans-unit id="3228811828827738441" datatype="html">
<source>Oceania</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">64</context>
<context context-type="linenumber">65</context>
</context-group>
</trans-unit>
<trans-unit id="5957846001261659229" datatype="html">
<source>South America</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">65</context>
<context context-type="linenumber">66</context>
</context-group>
</trans-unit>
<trans-unit id="1189482335778578193" datatype="html">
<source>Extreme Fear</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">68</context>
<context context-type="linenumber">69</context>
</context-group>
</trans-unit>
<trans-unit id="2634398159221205491" datatype="html">
<source>Extreme Greed</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">69</context>
<context context-type="linenumber">70</context>
</context-group>
</trans-unit>
<trans-unit id="3511545370905854666" datatype="html">
<source>Neutral</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">72</context>
<context context-type="linenumber">73</context>
</context-group>
</trans-unit>
<trans-unit id="3c33a66194384cf8c14e25170416767efa56fd98" datatype="html">
@ -14137,7 +14116,7 @@
<source>Market data is delayed for</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">81</context>
</context-group>
</trans-unit>
<trans-unit id="8ce52b52483f502dd23ed290357a17307c60280c" datatype="html">
@ -14359,28 +14338,28 @@
<trans-unit id="7860418101283165917" datatype="html">
<source>Closed</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts</context>
<context context-type="sourcefile">apps/client/src/app/components/home-holdings/home-holdings.component.ts</context>
<context context-type="linenumber">31</context>
</context-group>
</trans-unit>
<trans-unit id="8204176479746810612" datatype="html">
<source>Active</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts</context>
<context context-type="sourcefile">apps/client/src/app/components/home-holdings/home-holdings.component.ts</context>
<context context-type="linenumber">30</context>
</context-group>
</trans-unit>
<trans-unit id="f2005fa461c06dc2e04d8918bbabedf23604b5b7" datatype="html">
<source>Activity</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">219</context>
</context-group>
</trans-unit>
<trans-unit id="00ab08d0337ad99d0fabd37b521f8908a33f8550" datatype="html">
<source>Dividend Yield</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">187</context>
</context-group>
</trans-unit>
@ -14409,23 +14388,37 @@
<source>Liquidity</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">43</context>
<context context-type="linenumber">44</context>
</context-group>
</trans-unit>
<trans-unit id="220d94c89713386f9003dfa237262d17a2cb1c0d" datatype="html">
<source>Change with currency effect</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">52</context>
</context-group>
</trans-unit>
<trans-unit id="f6b690ad88cca4208035a1be392f327d9a2405ac" datatype="html">
<source>Performance with currency effect</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="sourcefile">apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="8903954975609359428" datatype="html">
<source>Buy and sell</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">8</context>
</context-group>
</trans-unit>
<trans-unit id="ebf471e68247ca2110cdc5c98538e2e2bbf6e56e" datatype="html">
<source>{VAR_PLURAL, plural, =1 {activity} other {activities}}</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">14</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

296
apps/client/src/locales/messages.zh.xlf

File diff suppressed because it is too large

12
apps/client/src/styles.scss

@ -387,6 +387,10 @@ ngx-skeleton-loader {
@include gf-table;
}
.has-fab {
padding-bottom: 3rem !important;
}
.has-info-message {
.page.has-tabs {
height: calc(100svh - 2 * var(--mat-toolbar-standard-height));
@ -543,6 +547,10 @@ ngx-skeleton-loader {
--mdc-tab-indicator-active-indicator-color: transparent;
}
.mat-mdc-tab-nav-panel {
padding: 2rem 0;
}
@media (max-width: 575.98px) {
.mat-mdc-tab-link {
--mdc-secondary-navigation-tab-container-height: 3rem;
@ -567,10 +575,6 @@ ngx-skeleton-loader {
}
}
}
.mat-mdc-tab-nav-panel {
padding: 2rem 0;
}
}
}
}

4
libs/common/src/lib/config.ts

@ -66,7 +66,7 @@ export const EMERGENCY_FUND_TAG_ID = '4452656d-9fa4-4bd0-ba38-70492e31d180';
export const GATHER_ASSET_PROFILE_PROCESS = 'GATHER_ASSET_PROFILE';
export const GATHER_ASSET_PROFILE_PROCESS_OPTIONS: JobOptions = {
attempts: 10,
attempts: 12,
backoff: {
delay: ms('1 minute'),
type: 'exponential'
@ -76,7 +76,7 @@ export const GATHER_ASSET_PROFILE_PROCESS_OPTIONS: JobOptions = {
export const GATHER_HISTORICAL_MARKET_DATA_PROCESS =
'GATHER_HISTORICAL_MARKET_DATA';
export const GATHER_HISTORICAL_MARKET_DATA_PROCESS_OPTIONS: JobOptions = {
attempts: 10,
attempts: 12,
backoff: {
delay: ms('1 minute'),
type: 'exponential'

9
libs/ui/src/lib/activities-table/activities-table.component.html

@ -58,6 +58,7 @@
<button
class="align-items-center d-flex"
mat-menu-item
[disabled]="!hasPermissionToDeleteActivity"
(click)="onDeleteAllActivities()"
>
<span class="align-items-center d-flex">
@ -119,7 +120,7 @@
</td>
</ng-container>
<ng-container matColumnDef="icon">
<ng-container matColumnDef="icon" sticky>
<th *matHeaderCellDef class="px-1" mat-header-cell></th>
<td *matCellDef="let element" class="px-1 text-center" mat-cell>
<gf-asset-profile-icon
@ -444,7 +445,11 @@
<span i18n>Export Draft as ICS</span>
</span>
</button>
<button mat-menu-item (click)="onDeleteActivity(element.id)">
<button
mat-menu-item
[disabled]="!hasPermissionToDeleteActivity"
(click)="onDeleteActivity(element.id)"
>
<span class="align-items-center d-flex">
<ion-icon class="mr-2" name="trash-outline" />
<span i18n>Delete</span>

3
libs/ui/src/lib/activities-table/activities-table.component.ts

@ -78,6 +78,7 @@ export class GfActivitiesTableComponent
@Input() dataSource: MatTableDataSource<Activity>;
@Input() deviceType: string;
@Input() hasPermissionToCreateActivity: boolean;
@Input() hasPermissionToDeleteActivity: boolean;
@Input() hasPermissionToExportActivities: boolean;
@Input() hasPermissionToOpenDetails = true;
@Input() locale = getLocale();
@ -258,7 +259,7 @@ export class GfActivitiesTableComponent
public onOpenPositionDialog({ dataSource, symbol }: UniqueAsset) {
this.router.navigate([], {
queryParams: { dataSource, symbol, positionDetailDialog: true }
queryParams: { dataSource, symbol, holdingDetailDialog: true }
});
}

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

@ -60,9 +60,9 @@ export class GfAssistantListItemComponent
this.queryParams = {
dataSource,
symbol,
positionDetailDialog: true
holdingDetailDialog: true
};
this.routerLink = ['/portfolio', 'holdings'];
this.routerLink = [];
}
}

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

@ -416,7 +416,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
private searchHoldings(aSearchTerm: string): Observable<ISearchResultItem[]> {
return this.dataService
.fetchPositions({
.fetchPortfolioHoldings({
filters: [
{
id: aSearchTerm,
@ -429,8 +429,8 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
catchError(() => {
return EMPTY;
}),
map(({ positions }) => {
return positions.map(
map(({ holdings }) => {
return holdings.map(
({ assetSubClass, currency, dataSource, name, symbol }) => {
return {
currency,

27
libs/ui/src/lib/holdings-table/holdings-table.component.html

@ -7,7 +7,7 @@
matSortDirection="desc"
[dataSource]="dataSource"
>
<ng-container matColumnDef="icon">
<ng-container matColumnDef="icon" sticky>
<th *matHeaderCellDef class="px-1" mat-header-cell></th>
<td *matCellDef="let element" class="px-1 text-center" mat-cell>
<gf-asset-profile-icon
@ -109,7 +109,30 @@
</td>
</ng-container>
<ng-container matColumnDef="performance" stickyEnd>
<ng-container matColumnDef="performance">
<th
*matHeaderCellDef
class="justify-content-end px-1"
mat-header-cell
mat-sort-header="netPerformanceWithCurrencyEffect"
>
<ng-container i18n>Change</ng-container>
</th>
<td *matCellDef="let element" class="px-1" mat-cell>
<div class="d-flex justify-content-end">
<gf-value
[colorizeSign]="true"
[isCurrency]="true"
[locale]="locale"
[value]="
isLoading ? undefined : element.netPerformanceWithCurrencyEffect
"
/>
</div>
</td>
</ng-container>
<ng-container matColumnDef="performanceInPercentage" stickyEnd>
<th
*matHeaderCellDef
class="justify-content-end px-1"

9
libs/ui/src/lib/holdings-table/holdings-table.component.ts

@ -84,7 +84,12 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy, OnInit {
}
this.displayedColumns.push('allocationInPercentage');
this.displayedColumns.push('performance');
if (this.hasPermissionToShowValues) {
this.displayedColumns.push('performance');
}
this.displayedColumns.push('performanceInPercentage');
this.isLoading = true;
@ -100,7 +105,7 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy, OnInit {
public onOpenPositionDialog({ dataSource, symbol }: UniqueAsset) {
if (this.hasPermissionToOpenDetails) {
this.router.navigate([], {
queryParams: { dataSource, symbol, positionDetailDialog: true }
queryParams: { dataSource, symbol, holdingDetailDialog: true }
});
}
}

26
package.json

@ -1,6 +1,6 @@
{
"name": "ghostfolio",
"version": "2.79.0",
"version": "2.80.0",
"homepage": "https://ghostfol.io",
"license": "AGPL-3.0",
"repository": "https://github.com/ghostfolio/ghostfolio",
@ -112,7 +112,7 @@
"got": "11.8.6",
"helmet": "7.0.0",
"http-status-codes": "2.3.0",
"ionicons": "7.3.0",
"ionicons": "7.4.0",
"jsonpath": "1.1.1",
"lodash": "4.17.21",
"marked": "9.1.6",
@ -150,16 +150,16 @@
"@angular/pwa": "17.3.5",
"@nestjs/schematics": "10.0.1",
"@nestjs/testing": "10.1.3",
"@nx/angular": "18.3.3",
"@nx/cypress": "18.3.3",
"@nx/eslint-plugin": "18.3.3",
"@nx/jest": "18.3.3",
"@nx/js": "18.3.3",
"@nx/nest": "18.3.3",
"@nx/node": "18.3.3",
"@nx/storybook": "18.3.3",
"@nx/web": "18.3.3",
"@nx/workspace": "18.3.3",
"@nx/angular": "19.0.2",
"@nx/cypress": "19.0.2",
"@nx/eslint-plugin": "19.0.2",
"@nx/jest": "19.0.2",
"@nx/js": "19.0.2",
"@nx/nest": "19.0.2",
"@nx/node": "19.0.2",
"@nx/storybook": "19.0.2",
"@nx/web": "19.0.2",
"@nx/workspace": "19.0.2",
"@schematics/angular": "17.3.3",
"@simplewebauthn/types": "9.0.1",
"@storybook/addon-essentials": "7.6.5",
@ -188,7 +188,7 @@
"jest": "29.4.3",
"jest-environment-jsdom": "29.4.3",
"jest-preset-angular": "14.0.3",
"nx": "18.3.3",
"nx": "19.0.2",
"prettier": "3.2.5",
"prettier-plugin-organize-attributes": "1.0.0",
"react": "18.2.0",

485
yarn.lock

@ -4977,98 +4977,98 @@
read-package-json-fast "^3.0.0"
which "^4.0.0"
"@nrwl/angular@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/angular/-/angular-18.3.3.tgz#63d7b65e4d96637d7361d018ec56d061595cb0d4"
integrity sha512-pQsxy58DZBVna3qeJH+osdiRBpx+FCAnCz5kogO6EmRsM17zP4zGpgijVHorAI4EjCNhl2vWa3X/bZ8yQIFBpg==
"@nrwl/angular@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/angular/-/angular-19.0.2.tgz#6264e03daa40f512e98aba56da7d6e79bc5f631f"
integrity sha512-U7PiGq62bhSjmWnkDY6TXdSjpBPLF2HlYxNd5GtGZo3zC23o2kqPwaXYLFcgMHzG6clm435P3jRcgE5XEOqbhw==
dependencies:
"@nx/angular" "18.3.3"
"@nx/angular" "19.0.2"
tslib "^2.3.0"
"@nrwl/cypress@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-18.3.3.tgz#3b85e45169c3aff23ea46e19835956a355111b22"
integrity sha512-CsoPFX+iLwvc/+Im/zZsk3FP8c8epBMmI8GNvZFnDZe8J9bdBmtlxp8/Yh3LdUw8ycmPGPvW7eggv31yNZmT+Q==
"@nrwl/cypress@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-19.0.2.tgz#f88af85582f5e5fc4a03492fbf9b7eed44b617c9"
integrity sha512-EaRn0IulCRr+yItA2huV6b+lz9Ff7Dcg+rgbuIbDBz88D2WMjsB2fm9gGgLx0zw8OKQdVxe3pQqaHAuGgordUg==
dependencies:
"@nx/cypress" "18.3.3"
"@nx/cypress" "19.0.2"
"@nrwl/devkit@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-18.3.3.tgz#9ec5575afe6d14b17acd5e8da4e98a0de27704c6"
integrity sha512-3zZLE1vfwsNie7qjVUt9lqaM1slU0RTr/dW+Yt/2lxe8Peu6f8bnCM1Pf3kSlzoxQroctfocRtVHFXJsAuAt4g==
"@nrwl/devkit@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-19.0.2.tgz#225d5579f1b52f0476bf3982f09a1d59f8d1e291"
integrity sha512-h/hBltFnJLrDVxVJYcU/qAba9NGfrSp1q4t9U9tl8B8InMtRRgjFKX/whRZd6PE7ZTN7kqr0+XRTETFKv5heDA==
dependencies:
"@nx/devkit" "18.3.3"
"@nx/devkit" "19.0.2"
"@nrwl/eslint-plugin-nx@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-18.3.3.tgz#b41316daa9ac7f55379cb4510767f7a865c920a6"
integrity sha512-ARqwcA2n2NN+8ATrooZtPbaW5fb9WSjDFZaI8RdphMXFnPrEkZnMpbrjFpLTj+wc1R6hIgTcYbli6fv4Gfbo3Q==
"@nrwl/eslint-plugin-nx@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-19.0.2.tgz#51f7cfa878a5963672ac12841e815fe233e2afbb"
integrity sha512-T/01uFi6xAjbpU04kqiD+H4NNlZpuPiQbY8T3k/hn3/+2ePK1je09Z2ilsfWUcsH23p95yM4LMmFDTPlrRjwAw==
dependencies:
"@nx/eslint-plugin" "18.3.3"
"@nx/eslint-plugin" "19.0.2"
"@nrwl/jest@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-18.3.3.tgz#6d75e59c47be007cbe4b78c23fd3e08fe954ed68"
integrity sha512-BPI0mIbmjTHFb0/qtMND59ECld7gorV+SEVLwf4BLl7SWumVB2gLAA2+yx71cvF1jO4R5Ndi2FrBwBC9E2Va5Q==
"@nrwl/jest@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-19.0.2.tgz#d9e9ac42691712cebae122e28d0066775e229dbe"
integrity sha512-z+TQMN57wOK0rocSrhUpYFntYV5rIlSWBcYL/TRjHZAC/2zFR3kmQbgc3bRqEtmmm2pGkpZBLg+abJD/ge+Nxw==
dependencies:
"@nx/jest" "18.3.3"
"@nx/jest" "19.0.2"
"@nrwl/js@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/js/-/js-18.3.3.tgz#e1a83fb43541cd06752aced6dd7ad932d0c1afa1"
integrity sha512-7Wtv5kpeMWUDBUFu5go49HM/S8vDrtMOvZf9xnUcnjsFDReWe8XIEkTWudZDbzID3X4T6WQAftzj2Ov6k566lQ==
"@nrwl/js@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/js/-/js-19.0.2.tgz#af2768630c9098adb95fe4f2729a03ce9cdd085c"
integrity sha512-6bWHnC3rhRFmuUGt7G/0NGTAxm2ig9MpXzCzERYEACcS3fEN4QDMLbUlyojjiRWbQWeCPz9adxWTgkckM4Ispg==
dependencies:
"@nx/js" "18.3.3"
"@nx/js" "19.0.2"
"@nrwl/nest@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/nest/-/nest-18.3.3.tgz#28709e32ef4cef6db06a9e219de46ae9b9f40378"
integrity sha512-LIyCiS73O58n7NRWT/SnuA8xHWDu4ANLd9fvguyAzXk1TcPekFvTo6zpY+iu0lkxJ7RfvZHVDGC90bIFSyV9YA==
"@nrwl/nest@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/nest/-/nest-19.0.2.tgz#02f5166c15a9795fd3b0817c60690bf169d37187"
integrity sha512-0U6DK8lkRhTCsdR8M8Iw4cLoK2q5Kbs6aAhTi7voXVZDvhpNf3BQACbgVqjmSlkxLbhaScFzc0GkXLuDdGBIXQ==
dependencies:
"@nx/nest" "18.3.3"
"@nx/nest" "19.0.2"
"@nrwl/node@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-18.3.3.tgz#eb0850a8e7877332550d7e06e7c959d0842b25e2"
integrity sha512-87PXppPqI/jOl6swYVdQi8RBveOF7Oqmqw9m9eEbts6U2bazPipKTwBO4E9afkz3GMqaxe+d2H794JqH05Mr8w==
"@nrwl/node@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-19.0.2.tgz#b606ca9abf231a938d00110c52a6a6dc03a2992f"
integrity sha512-uVXq86Xi+l4pPh/zquMgXVUHeIeH9GNiQj8wM7WodA4sMnJENQ+9GRENHE5H8NjpbilqutgEDF0WqTDaa3zQ/Q==
dependencies:
"@nx/node" "18.3.3"
"@nx/node" "19.0.2"
"@nrwl/storybook@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-18.3.3.tgz#80c60ef3975150127a9b09e2d7b79900cd962af0"
integrity sha512-i8mZoJz9CTT7hmXJxgqlz8u4nm48S4XTZLH5nARXcArjoiojUQTQnRr8iDZlJsZxa3+kHTMCJVyQ5WQUC6+Uog==
"@nrwl/storybook@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-19.0.2.tgz#d00e9c9191bafd326eadc77dab873e1e5b768f80"
integrity sha512-745jQwv4sI4BywIr9ABlmbrmtWHf2O/jtWl3HYaNuZoDbsvIq+aZAzAVFPZdmRYnhs/vgyOqYqiVbpQwx+uqVw==
dependencies:
"@nx/storybook" "18.3.3"
"@nx/storybook" "19.0.2"
"@nrwl/tao@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-18.3.3.tgz#2d0c60d233f2cc07c85ba08126dd46f21dda1ef0"
integrity sha512-f/PUDLpSMEObiLQ5sIDySJM+5DxSCNunkxxbY1R9rmQ1cFcgrHaXIHQqbSj91mMa3mmtbKACk8u1LbI+oQV0Tg==
"@nrwl/tao@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-19.0.2.tgz#b92ab17b991300f87948b0151ab06fe089b11a72"
integrity sha512-VLU0Ptqq9+R5Ugb4d7ANb/pzZ8Rh+ExNcyg5MVNNrrgrM8ghLOu2/qPoatWyXLZg+cfKr6bH7/c0rWBtPcc69Q==
dependencies:
nx "18.3.3"
nx "19.0.2"
tslib "^2.3.0"
"@nrwl/web@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/web/-/web-18.3.3.tgz#3e31d086fef5aa1e68ac5af9d5c27592ef2fe39d"
integrity sha512-EuEht/tk9VHLKxjVMEh96wu8WNkRFRabpmLBc++pp2bEaoxz8Qm2xDO+sOU3Wp4zGNx/qQVxA1kKMZCjVjk75g==
"@nrwl/web@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/web/-/web-19.0.2.tgz#bcb30cd4c8f6bb32e9bc970e0f7d5e34927c815c"
integrity sha512-/w0ZhhFZvCJv0CgySaIGDhglLiDvvwbF7gM1k4qPPPYZFPPSShmb5BANlDyaBnX6wYRFY42kaXfGE51Dc6qZ5A==
dependencies:
"@nx/web" "18.3.3"
"@nx/web" "19.0.2"
"@nrwl/webpack@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/webpack/-/webpack-18.3.3.tgz#0c29dc1561c9b8e613313fd02f805be72515dfa6"
integrity sha512-E/8vr1qAFSan1FnewvLBRBHYIaPG9dxZeYKRcQvcDx+Jf2oPyJNYI+9kkoNxEZg9FeFJMShK2x8YBgwB+ivH5A==
"@nrwl/webpack@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/webpack/-/webpack-19.0.2.tgz#66e1a0652fc101fbbb8b2b87c73dda5b24174917"
integrity sha512-VpqZxrT8sglXpB9TKUrXS/Cht3j4ZOg53yL/CEse+oeVTUi2BFWFPhhdtFAzDtz27F1nnrcXSTluCcKpisDG/A==
dependencies:
"@nx/webpack" "18.3.3"
"@nx/webpack" "19.0.2"
"@nrwl/workspace@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-18.3.3.tgz#291ecda3c4fddcb534f0cc6b7c7796a21483ae49"
integrity sha512-9Giuec9l3PpS8mekD00W9kBIKmWRpQSkp+/RvYmc+7kKtVC+Uj/kc68exBOanVgq6zKzYrn+FqHWHGWnHxp+ww==
"@nrwl/workspace@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-19.0.2.tgz#7c05d0d898ca8024f78a8c1089bdc0d20999072e"
integrity sha512-DtMbNhTpkcsDRn+pBiqFGUpZkBTzhbwQKRacwD2n+NqBFhCSCMoKYxsRnd5A874hiF3fyGB8AYEmuuTOxhATgg==
dependencies:
"@nx/workspace" "18.3.3"
"@nx/workspace" "19.0.2"
"@nuxtjs/opencollective@0.3.2":
version "0.3.2"
@ -5079,18 +5079,18 @@
consola "^2.15.0"
node-fetch "^2.6.1"
"@nx/angular@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/angular/-/angular-18.3.3.tgz#3648480ddec56e2ca54caed7482eb941b60df3e4"
integrity sha512-KAWpIxd+cNAjSNaArHzJGavES6hBJApE6KVgg3lJwSThkjgTy6loEC4mw8VAQaSlHVx/OEQcbebC1LPkJadG9w==
dependencies:
"@nrwl/angular" "18.3.3"
"@nx/devkit" "18.3.3"
"@nx/eslint" "18.3.3"
"@nx/js" "18.3.3"
"@nx/web" "18.3.3"
"@nx/webpack" "18.3.3"
"@nx/workspace" "18.3.3"
"@nx/angular@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/angular/-/angular-19.0.2.tgz#3fe5757f6d6e173766869527ba50a34f98db873b"
integrity sha512-pwVrE6zevR7ohHlLIcVOgU9Mz+IPEiTBpSkwolnVjvUWlLp4fHC7HdHxos47/VjOaS4IpDg5LTnGanKhHhMg0w==
dependencies:
"@nrwl/angular" "19.0.2"
"@nx/devkit" "19.0.2"
"@nx/eslint" "19.0.2"
"@nx/js" "19.0.2"
"@nx/web" "19.0.2"
"@nx/webpack" "19.0.2"
"@nx/workspace" "19.0.2"
"@phenomnomnominal/tsquery" "~5.0.1"
"@typescript-eslint/type-utils" "^7.3.0"
chalk "^4.1.0"
@ -5104,42 +5104,42 @@
webpack "^5.80.0"
webpack-merge "^5.8.0"
"@nx/cypress@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/cypress/-/cypress-18.3.3.tgz#d0af052f421312018b0d0ddc3476cd4a31ca748f"
integrity sha512-ou7Q6XXM9zIiWFVojZwnnFFJxx4iKACWvusfCOIwJ3zcel1vtamWHffRp2Z9WjdBDxy26Ax/DM+lZj4t6hQRmA==
"@nx/cypress@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/cypress/-/cypress-19.0.2.tgz#90bf24bbbf39074ffc4964e5f4eebc2d3c86a068"
integrity sha512-YNnG1QB2zINiDb4Jc3bjIARxA2yG+/B3nzePwoI4fYzuLqEYAN6DmiYEj+5k9KsS+des3xnGFPSBHBTUPLh/AA==
dependencies:
"@nrwl/cypress" "18.3.3"
"@nx/devkit" "18.3.3"
"@nx/eslint" "18.3.3"
"@nx/js" "18.3.3"
"@nrwl/cypress" "19.0.2"
"@nx/devkit" "19.0.2"
"@nx/eslint" "19.0.2"
"@nx/js" "19.0.2"
"@phenomnomnominal/tsquery" "~5.0.1"
detect-port "^1.5.1"
semver "^7.5.3"
tslib "^2.3.0"
"@nx/devkit@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-18.3.3.tgz#2ec37855020da74ad1e77b51711b057b3cb12fec"
integrity sha512-FtkZ6mA5//vEA5lcbT80m080ROVacHYV5F1peztTRA+IY2JZGJoqx425kn5ylDO8aCSAIAwcn2qIdhI8BnpG3Q==
"@nx/devkit@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-19.0.2.tgz#177a7e236ae5c498cd72b33e766a7d32e2f52906"
integrity sha512-qHBWQ3ZJ4vO8AVdSlz/u/GXDrDxVsBjC1/pY1ImycnUP4NfOtmBlYdhd5aB9XvWcujSmOap0ZJGr1iapYKoWxQ==
dependencies:
"@nrwl/devkit" "18.3.3"
"@nrwl/devkit" "19.0.2"
ejs "^3.1.7"
enquirer "~2.3.6"
ignore "^5.0.4"
minimatch "9.0.3"
semver "^7.5.3"
tmp "~0.2.1"
tslib "^2.3.0"
yargs-parser "21.1.1"
"@nx/eslint-plugin@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/eslint-plugin/-/eslint-plugin-18.3.3.tgz#0410261cf7f1a227eefbe2a979c9482ad9c19894"
integrity sha512-ww3r8VRlzJXOBRG+qCTd+VXHRKxiIrOH+cIokTtuzGrnCXWEMSPO5Ts6z/Jsbb0xAcfZ39WUnxuDZdKbp4aHqA==
"@nx/eslint-plugin@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/eslint-plugin/-/eslint-plugin-19.0.2.tgz#2af83c556842a27c03639dcab567c52e80f32604"
integrity sha512-MVriamwIXTdBgcP66IawjMa+A4hr4DKBRtvLtpv8MWYMXafBvqRXryAOAw490Q31YB1B9xs3n19OCDaTIbSHvQ==
dependencies:
"@nrwl/eslint-plugin-nx" "18.3.3"
"@nx/devkit" "18.3.3"
"@nx/js" "18.3.3"
"@nrwl/eslint-plugin-nx" "19.0.2"
"@nx/devkit" "19.0.2"
"@nx/js" "19.0.2"
"@typescript-eslint/type-utils" "^7.3.0"
"@typescript-eslint/utils" "^7.3.0"
chalk "^4.1.0"
@ -5148,28 +5148,28 @@
semver "^7.5.3"
tslib "^2.3.0"
"@nx/eslint@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/eslint/-/eslint-18.3.3.tgz#ce28b4240e0558333dee08c824d8f82d72a11159"
integrity sha512-cvJjyykTEtQN08b5wQFelD/cbye7Nl5zFVESs+mn9/ezCukjAgP9seOk39nchKykRBAm7zzA1xZOB9thNqw9aA==
"@nx/eslint@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/eslint/-/eslint-19.0.2.tgz#b15b33e849834ed1ce40ea7932f1e817b6f7bd39"
integrity sha512-3kOB6Zna0qp8R2sl7Fy6KxPXlKatbkCEN0aPm4hke5euM6JcsRCz1w9dUFDoQ6e29S43htrv4bMc3A+i89ym7Q==
dependencies:
"@nx/devkit" "18.3.3"
"@nx/js" "18.3.3"
"@nx/linter" "18.3.3"
"@nx/devkit" "19.0.2"
"@nx/js" "19.0.2"
"@nx/linter" "19.0.2"
eslint "^8.0.0"
tslib "^2.3.0"
typescript "~5.4.2"
"@nx/jest@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/jest/-/jest-18.3.3.tgz#4a25f77169d0e630cb9b5f49bd0cde1faf0aae31"
integrity sha512-AwkwYSJqu0vrDFMxKAc3lb0yHZFhsD8rX6rMMwe/fZMlAYml9FvGCp/ixWpcRWIo/1t3pxiF3Vejk9+oq/Avfw==
"@nx/jest@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/jest/-/jest-19.0.2.tgz#9713467bde869d701479d711727c518406db3f5c"
integrity sha512-oV3QBdm/chaAcj+lzrwL937QIGZNXO18puFvol0hJrmVWMNRQr8LADfVHr8+qBrThxfj+w5UhXoDcqPS38zXXg==
dependencies:
"@jest/reporters" "^29.4.1"
"@jest/test-result" "^29.4.1"
"@nrwl/jest" "18.3.3"
"@nx/devkit" "18.3.3"
"@nx/js" "18.3.3"
"@nrwl/jest" "19.0.2"
"@nx/devkit" "19.0.2"
"@nx/js" "19.0.2"
"@phenomnomnominal/tsquery" "~5.0.1"
chalk "^4.1.0"
identity-obj-proxy "3.0.0"
@ -5181,10 +5181,10 @@
tslib "^2.3.0"
yargs-parser "21.1.1"
"@nx/js@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/js/-/js-18.3.3.tgz#977968160d6edc11f320bc0f654b52d36a9101ac"
integrity sha512-e8u56oG0mlTVz48EeH0C7txX0GeLYN0o4mK1LDAMIHQa4tKefNfwrdqHaZBiVqFOPopeFtqi8s0kqce5prwCaw==
"@nx/js@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/js/-/js-19.0.2.tgz#c9aa549156401e97f08c55121b1e43696d53056d"
integrity sha512-pAA9/mFGnBwpF/x+80dSWHZIxY0M1YtgcabQYdQmZ8zwdYOtSkJwuibFvPRkUxqVg0F4E0nTuJ4R1uruSe9P8Q==
dependencies:
"@babel/core" "^7.23.2"
"@babel/plugin-proposal-decorators" "^7.22.7"
@ -5193,10 +5193,9 @@
"@babel/preset-env" "^7.23.2"
"@babel/preset-typescript" "^7.22.5"
"@babel/runtime" "^7.22.6"
"@nrwl/js" "18.3.3"
"@nx/devkit" "18.3.3"
"@nx/workspace" "18.3.3"
"@phenomnomnominal/tsquery" "~5.0.1"
"@nrwl/js" "19.0.2"
"@nx/devkit" "19.0.2"
"@nx/workspace" "19.0.2"
babel-plugin-const-enum "^1.0.1"
babel-plugin-macros "^2.8.0"
babel-plugin-transform-typescript-metadata "^0.3.1"
@ -5217,125 +5216,125 @@
tsconfig-paths "^4.1.2"
tslib "^2.3.0"
"@nx/linter@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/linter/-/linter-18.3.3.tgz#ae861fb7d10c4f1dcdb4389f5b9f25aecab6fee0"
integrity sha512-5HmAN/8jZ2scrA0OiJSUdBPhIjwIHecK8AK7TxYX4fg1VJ3VcpknV8pWcETuNoBW8WlgF1RX2RW7Gog7vjf+Ww==
"@nx/linter@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/linter/-/linter-19.0.2.tgz#a4fb9ab564c8399ff93ba0c295a6e03a870e2b06"
integrity sha512-t9ccK+IVV/pNBbST2cOstuiMaBeC4o31U4yYPYMqrSx6uEkNoIe+YTJoaxLENaxqpvb+oek65Rg6/FlIbkrYVA==
dependencies:
"@nx/eslint" "18.3.3"
"@nx/eslint" "19.0.2"
"@nx/nest@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/nest/-/nest-18.3.3.tgz#16fe7ba6d1f8634ffae58b8e6dda4132ef112c5e"
integrity sha512-e2uPVBsewdLkgf9ncAxN/UEln3ygc1lyy8LTfR5X0Gzx3CUPiayDfd9OxZaxnDFi7Jpu89dpckMO8NhAIBvheA==
"@nx/nest@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/nest/-/nest-19.0.2.tgz#6cb9a093360d91a9ce8827a9d62d15b2a03af179"
integrity sha512-vJz435gdJgPaGwpllD44fJ43/Pb1ZK9cQFPVi2A+hiPcw+9ML3diLiAWH/mrigxHBbRbCY6bpaTrq3t8TBte1w==
dependencies:
"@nestjs/schematics" "^9.1.0"
"@nrwl/nest" "18.3.3"
"@nx/devkit" "18.3.3"
"@nx/eslint" "18.3.3"
"@nx/js" "18.3.3"
"@nx/node" "18.3.3"
"@nrwl/nest" "19.0.2"
"@nx/devkit" "19.0.2"
"@nx/eslint" "19.0.2"
"@nx/js" "19.0.2"
"@nx/node" "19.0.2"
"@phenomnomnominal/tsquery" "~5.0.1"
tslib "^2.3.0"
"@nx/node@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/node/-/node-18.3.3.tgz#a000284eb88dc58cbb4dad9909c1e0a930560c61"
integrity sha512-OoeRuuvqrdEH8AsFKrJ91lnDVL9mlqvLzUy9D5PZCYspjCesc7Tmt7Xmbu3VEGzhQPilqZz4hVfXH6MLE7TvqA==
"@nx/node@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/node/-/node-19.0.2.tgz#03b4ff289f21d2a2015a67a491c15f8d9fd1cfad"
integrity sha512-IrbMPAi3keh0t2zp8RBDjAswjOj6b8XqKkLFQCxisU7/tg1DKXrMUNwZN1F05SdbV/EFvQSUeycnPC7eWWxcBA==
dependencies:
"@nrwl/node" "18.3.3"
"@nx/devkit" "18.3.3"
"@nx/eslint" "18.3.3"
"@nx/jest" "18.3.3"
"@nx/js" "18.3.3"
"@nrwl/node" "19.0.2"
"@nx/devkit" "19.0.2"
"@nx/eslint" "19.0.2"
"@nx/jest" "19.0.2"
"@nx/js" "19.0.2"
tslib "^2.3.0"
"@nx/nx-darwin-arm64@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-18.3.3.tgz#dcdbcfe2796bbe3f1dfd61bce81389b05a50e69b"
integrity sha512-NpA2/7o1uUuaocMYopX9muxKif9HlGfWaXo2UeiR918usF6xri4aUqweZbaXVc9iqCAEbVMWUsjaLYGKPXHAjw==
"@nx/nx-darwin-x64@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-18.3.3.tgz#aa7bdd1a3ea0bb81682422b805914efccab3b179"
integrity sha512-aydPLbc7DeceJ6szRf6DLT4ERoPvwfWyFiGXdAlEZYWhjEuNZLeG8K6jA3yHeWltKfX/qJqhnyKbnubBNzBKlQ==
"@nx/nx-freebsd-x64@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-18.3.3.tgz#331f5dbb56c90b08e99c1ce9ff51e0c5b956f030"
integrity sha512-sEYEWsK/fwC1l7wzls7RNOjhmrooH0lK0mpgj1vDXesLBSZ7k+pddAqaHFECN4QXBSbHZI2PWOEhbnIH+Errsg==
"@nx/nx-linux-arm-gnueabihf@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-18.3.3.tgz#d66d4787f5cfc56b5a7aa9a0453174b96b4729a8"
integrity sha512-B9GGMkrrzwiAfvew22x85ITO9TiNxbgRbKJQWQaoopNpXrnSWpY8WTNxpDT24fwV1qdQfsPKcY3F4O0NOUgPRA==
"@nx/nx-linux-arm64-gnu@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-18.3.3.tgz#2ab08df1d052a55d4a52ba910fe41c25701d5361"
integrity sha512-1EucHf5/0JeqZmhritqkpEdOcdo9Dl32gpFvhNfS6kCAYmaDlEl4zqedz3VIoj4C7+C0pV3mcRO9qB9H7GM5bQ==
"@nx/nx-linux-arm64-musl@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-18.3.3.tgz#69376454bb9759c376d0a90aa876dfff6bbf4d15"
integrity sha512-HPgOgnYYLPVCBEaAkSEGPGzZqTDCiyCAF/qtvx5z0f1U/hZYb1ubgxw70ogY82Cafr7X4gQBz5k4/ZCnoCXlOQ==
"@nx/nx-linux-x64-gnu@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-18.3.3.tgz#0b8ba8ec0c2371f0df462742460d52d63b1cc715"
integrity sha512-FgYTQ3VEE6EUOGtJT9riRK8IBwPGFjKS+N2mudQJn2bB/9IumUvVRYQUIX08gqGLlqZPO6uUUhUjwZY8SnjRLQ==
"@nx/nx-linux-x64-musl@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-18.3.3.tgz#c96d6f8d2d94b99ac8da723077ebbc92f833beea"
integrity sha512-QnWjGViR1Wj9gJXa1RJ9mXyy2/JzQ7NF2C4ulTYSH5St1HoxhkfnLsV0+uNLFEV9PSZq+2BfxmQuT8Appefv1A==
"@nx/nx-win32-arm64-msvc@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-18.3.3.tgz#0d2c7396e7a063849edbd6e3d34ea81445c389b5"
integrity sha512-Xn3LUaPsF8QkEYUVV3lc693NTCMWrfZBFXTy1cQpvLzQ+idsXQ/EGWoq93cIM3Nc2YWyblT2hHHelb8dHCZAlw==
"@nx/nx-win32-x64-msvc@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-18.3.3.tgz#ea1a60ae1ffe805529d5cb95e7b28e6b8ae24621"
integrity sha512-t8HvOnQEiaaoTFOOIrql30NPhIwDFO7jg0Jtz3Tbneulh7ceswJp71yFHsRGGrYZ23Tgg+Sna6M9qLRGzlRGkg==
"@nx/storybook@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/storybook/-/storybook-18.3.3.tgz#4fa01568e3189984d14bae217281f16e2cea5f4e"
integrity sha512-wqca3J20F9HakmPBzq9fwmcZ25LFNb9iWnSngXMgDXjRizbjZrXrCkpyiZe3qlYzhoCNN9oYlUsbas3dec/lwA==
dependencies:
"@nrwl/storybook" "18.3.3"
"@nx/cypress" "18.3.3"
"@nx/devkit" "18.3.3"
"@nx/eslint" "18.3.3"
"@nx/js" "18.3.3"
"@nx/nx-darwin-arm64@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-19.0.2.tgz#096c7c80624bf7af64e17f696059cfb6c67b2c2b"
integrity sha512-JVOz6kNaypyK7Bi/l//BZ6F8i70UXlnQBdnacBM8nZH2oAQ7OIj1foZEw7ANnDvKpUJB2staJ9ZwPc/KzXwr5A==
"@nx/nx-darwin-x64@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-19.0.2.tgz#64cba91c4afbf06c7a4bea6a8d11d1a57edb00f7"
integrity sha512-qfj3AJ/RCbEps+Evbycrf1qUQk/zkwX5NT80dgK/r9eGBbo3qOA3VLa1z0PtaaJaYhZxZkjhwXOqhqAjDNN8bw==
"@nx/nx-freebsd-x64@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-19.0.2.tgz#71454fbcb0f4e7cf8e2559555c38714a1b091003"
integrity sha512-Fe+SQ4ug2RbKQ6saLhntsaOhf0aeoLQ/nJCc6h0TYPIs43go5gFSLFa2xnCOIo90dSL6/0z1r8VsZGSQQHiXMg==
"@nx/nx-linux-arm-gnueabihf@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-19.0.2.tgz#3a389953bf7fc547bc1ac45a42519c7af6bca7fa"
integrity sha512-0IW/gYZo5toGjjrqKL4SqV2twfkVDfMpx6M4BxwJlYEzzl+gtF0VrWfhVU3r4p2YZV8yW3cmH9SNChB6YZgQmA==
"@nx/nx-linux-arm64-gnu@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-19.0.2.tgz#9c018d3423dbc7ab003ada2400c9a037f58aaec4"
integrity sha512-+u5Y7XYf0M/KOnDz+iS6DnaGfwvEFsMJipzv337Mbc2qP2sxBR4pM8hEKcQeqII71as0Xo0sZzmyxXjJvG7bzw==
"@nx/nx-linux-arm64-musl@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-19.0.2.tgz#9fcb897b2217baf942f31aaf827fc178920f2244"
integrity sha512-hmQ6evq9S5a/svQOwpRF5Zcu114A9jpeDKEBysFmbdV1eTFkrxlnvSCs/xXOeYOe/QS8Ijl50d7+1zkOE2HVMA==
"@nx/nx-linux-x64-gnu@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-19.0.2.tgz#1e5940d564d2be516fd4c587061b3a899773ffef"
integrity sha512-zVcAotU7qlunsvg7I3oGp50f6ha44FeU6ITA+CHD0A/wqD11ZpVP0qsqMLawCGiKhNafQmUvkXMEFJ1dUX5aWw==
"@nx/nx-linux-x64-musl@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-19.0.2.tgz#7030782c80aad725ff381c47f8184b85050f37bd"
integrity sha512-72hT2V9IQNMIrC7sBzllrHEnoJOhuPxKXJTUYzz4v/Y11t1ziTHflGXO9nJOpydh8vA+91dPVrDM5mWr6IEPzg==
"@nx/nx-win32-arm64-msvc@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-19.0.2.tgz#089503a0cc91d9b8fb3b5e2ff64a880419e98503"
integrity sha512-aTxQBtUrusAm535DRnHxgM9AXnPYkhzr+eUSjrPUPTu2N3cuckq6JWfpxtjVCMcPfOR+pOC9luG3+bWmO32TQQ==
"@nx/nx-win32-x64-msvc@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-19.0.2.tgz#3eb5c01e4ff7287ebff047dcc01ed6b54e975a5d"
integrity sha512-lgxgj+ilhL9StCLzRxU+EB1n944bMjwbU3CxvYW2TYa+380UXVMUACjbLyzONQPeJPIm9azaVQNKnf5+c+nnBQ==
"@nx/storybook@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/storybook/-/storybook-19.0.2.tgz#8acce07aa73f9e892cf6d678f88ab1785301d285"
integrity sha512-8HBynlwleDpcxYo7oG9DtHseEegidLAcRWaWks7gSn0qdyD43PcR1ppfYdFyg5fvLN38UZm5RYBK60I9WYZUyg==
dependencies:
"@nrwl/storybook" "19.0.2"
"@nx/cypress" "19.0.2"
"@nx/devkit" "19.0.2"
"@nx/eslint" "19.0.2"
"@nx/js" "19.0.2"
"@phenomnomnominal/tsquery" "~5.0.1"
semver "^7.5.3"
tslib "^2.3.0"
"@nx/web@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/web/-/web-18.3.3.tgz#99e6952942b3e43bc52ba444f6933dd279f49a6a"
integrity sha512-/NfQirVd2Ncq2if+1n8DaxNQF0OLaFaDag7qm5pDWJnjXFNh8N7NGZQRry2k/bTSfSc8gN+KJjqSMLAUNNtKgQ==
"@nx/web@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/web/-/web-19.0.2.tgz#8dd3147077ac07c9608072b452420a2b98215ac4"
integrity sha512-sK1avzp/FXtFO/viEtBj/UQTA0ScVfOGlwe92bAAFiX8YnxoazrPQnWiogXbF2AkQwFGyxR0Kp3iiu4Ezrp9Vg==
dependencies:
"@nrwl/web" "18.3.3"
"@nx/devkit" "18.3.3"
"@nx/js" "18.3.3"
"@nrwl/web" "19.0.2"
"@nx/devkit" "19.0.2"
"@nx/js" "19.0.2"
chalk "^4.1.0"
detect-port "^1.5.1"
http-server "^14.1.0"
tslib "^2.3.0"
"@nx/webpack@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/webpack/-/webpack-18.3.3.tgz#2b13c08c99821a413edd4ff7749936871ae6ae32"
integrity sha512-DPs8wfmYe/mEZCQ/TQgUqb/zgXY8hevR23d8bDkYjB3Akjk4OOF3QpQ2OXQ4c+Jf0ckGnQYOg6XAkE682UZqzg==
"@nx/webpack@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/webpack/-/webpack-19.0.2.tgz#0d0390791e7dc40b468c9a721dbfb6be435272ed"
integrity sha512-P26koXvBrThOA0v5SNSbj+t66V8cETpHcR0JpylJ4ANwW36NdpDlMFdFW385IrpBvaWl42dMRqj9wf2h2zJO7w==
dependencies:
"@babel/core" "^7.23.2"
"@nrwl/webpack" "18.3.3"
"@nx/devkit" "18.3.3"
"@nx/js" "18.3.3"
"@nrwl/webpack" "19.0.2"
"@nx/devkit" "19.0.2"
"@nx/js" "19.0.2"
ajv "^8.12.0"
autoprefixer "^10.4.9"
babel-loader "^9.1.2"
@ -5370,16 +5369,16 @@
webpack-node-externals "^3.0.0"
webpack-subresource-integrity "^5.1.0"
"@nx/workspace@18.3.3":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@nx/workspace/-/workspace-18.3.3.tgz#bae369fe9d6c8aca425222ec53f797bcacd715e6"
integrity sha512-SUJJKzOUuNnclpHHde6f6nlF+pQwMjeF026jFpWDFaNzdsADhhRulkz0GLRXB9kKszvzz2JKde9WBWnKrFZ2IQ==
"@nx/workspace@19.0.2":
version "19.0.2"
resolved "https://registry.yarnpkg.com/@nx/workspace/-/workspace-19.0.2.tgz#2dcae81d1791c690c57d5d58638585b94027ad0e"
integrity sha512-4azpf0tDM7mN7kciMHH4e0bw2yEhVu4M6siYDLfq6ELY+rrP7eveh/drKiWaKrV9WVwwWzYdfpk98+1EtrBLAA==
dependencies:
"@nrwl/workspace" "18.3.3"
"@nx/devkit" "18.3.3"
"@nrwl/workspace" "19.0.2"
"@nx/devkit" "19.0.2"
chalk "^4.1.0"
enquirer "~2.3.6"
nx "18.3.3"
nx "19.0.2"
tslib "^2.3.0"
yargs-parser "21.1.1"
@ -13104,10 +13103,10 @@ invariant@^2.2.4:
dependencies:
loose-envify "^1.0.0"
ionicons@7.3.0:
version "7.3.0"
resolved "https://registry.yarnpkg.com/ionicons/-/ionicons-7.3.0.tgz#d2385e87dbe6a8c79fd44fb2e7c87b0de4a2cbcb"
integrity sha512-l9quySYi+o4T6mFzhKRyU/1nKc2Zs0zxs7jWcq9iVRhRPQondV11jYqLTed0lVVXHfGrBCfnedKl9D6BCnA1UQ==
ionicons@7.4.0:
version "7.4.0"
resolved "https://registry.yarnpkg.com/ionicons/-/ionicons-7.4.0.tgz#9c285aaa8089befbd6c5a89ae13292d364cd9ace"
integrity sha512-ZK94MMqgzMCPPMhmk8Ouu6goyVHFIlw/ACP6oe3FrikcI0N7CX0xcwVaEbUc0G/v3W0shI93vo+9ve/KpvcNhQ==
dependencies:
"@stencil/core" "^4.0.3"
@ -15662,12 +15661,12 @@ nwsapi@^2.2.2:
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30"
integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==
nx@18.3.3:
version "18.3.3"
resolved "https://registry.yarnpkg.com/nx/-/nx-18.3.3.tgz#ab96811961b631efd4f0c83550e92f7b0a625e83"
integrity sha512-GqC5ANfTWV6SFbgquZwuRMI2Z2nO0c0Yx4JzM3x32aJOgXsmRml3WcV0a5648bIXSen34gylHYl2EHaxVWkzNQ==
nx@19.0.2:
version "19.0.2"
resolved "https://registry.yarnpkg.com/nx/-/nx-19.0.2.tgz#6e5a592d2daf4752b4fa583abcef9c1f10ca9497"
integrity sha512-59BSYa/Qp8nA764T7Cg7tSisFYBws9zSAMPm0YspCSPndoUy86Mjtg62bEqkHN0MWo6W4MxwOHuB0XSBvQ5DdA==
dependencies:
"@nrwl/tao" "18.3.3"
"@nrwl/tao" "19.0.2"
"@yarnpkg/lockfile" "^1.1.0"
"@yarnpkg/parsers" "3.0.0-rc.46"
"@zkochan/js-yaml" "0.0.6"
@ -15702,16 +15701,16 @@ nx@18.3.3:
yargs "^17.6.2"
yargs-parser "21.1.1"
optionalDependencies:
"@nx/nx-darwin-arm64" "18.3.3"
"@nx/nx-darwin-x64" "18.3.3"
"@nx/nx-freebsd-x64" "18.3.3"
"@nx/nx-linux-arm-gnueabihf" "18.3.3"
"@nx/nx-linux-arm64-gnu" "18.3.3"
"@nx/nx-linux-arm64-musl" "18.3.3"
"@nx/nx-linux-x64-gnu" "18.3.3"
"@nx/nx-linux-x64-musl" "18.3.3"
"@nx/nx-win32-arm64-msvc" "18.3.3"
"@nx/nx-win32-x64-msvc" "18.3.3"
"@nx/nx-darwin-arm64" "19.0.2"
"@nx/nx-darwin-x64" "19.0.2"
"@nx/nx-freebsd-x64" "19.0.2"
"@nx/nx-linux-arm-gnueabihf" "19.0.2"
"@nx/nx-linux-arm64-gnu" "19.0.2"
"@nx/nx-linux-arm64-musl" "19.0.2"
"@nx/nx-linux-x64-gnu" "19.0.2"
"@nx/nx-linux-x64-musl" "19.0.2"
"@nx/nx-win32-arm64-msvc" "19.0.2"
"@nx/nx-win32-x64-msvc" "19.0.2"
oauth@0.9.x:
version "0.9.15"

Loading…
Cancel
Save