Browse Source

nx upgraded to 21.2

pull/5221/head
Attila Cseh 1 day ago
parent
commit
5e8fdfe518
  1. 3
      apps/client/eslint.config.cjs
  2. 4
      apps/client/src/app/app.component.ts
  3. 8
      apps/client/src/app/components/admin-settings/admin-settings.component.scss
  4. 2
      apps/client/src/app/components/home-holdings/home-holdings.scss
  5. 2
      apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/create-watchlist-item-dialog.component.ts
  6. 2
      apps/client/src/app/components/home-watchlist/home-watchlist.component.ts
  7. 2
      apps/client/src/app/components/markets/markets.component.ts
  8. 2
      apps/client/src/app/components/user-account-access/user-account-access.component.ts
  9. 2
      apps/client/src/app/components/user-account-settings/user-account-settings.component.ts
  10. 4
      apps/client/src/app/pages/portfolio/allocations/allocations-page.scss
  11. 3
      apps/client/src/app/pages/user-account/user-account-page.component.ts
  12. 38
      apps/client/src/styles.scss
  13. 6
      apps/client/src/styles/theme.scss
  14. 25
      doctor-storybook.log
  15. 12
      libs/ui/.storybook/main.js
  16. 3
      libs/ui/eslint.config.cjs
  17. 3
      libs/ui/src/lib/activities-filter/activities-filter.component.ts
  18. 9
      libs/ui/src/lib/activities-table/activities-table.component.ts
  19. 4
      libs/ui/src/lib/activity-type/activity-type.component.ts
  20. 11
      libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts
  21. 8
      libs/ui/src/lib/assistant/assistant.component.ts
  22. 4
      libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.component.ts
  23. 6
      libs/ui/src/lib/benchmark/benchmark.component.ts
  24. 9
      libs/ui/src/lib/currency-selector/currency-selector.component.ts
  25. 5
      libs/ui/src/lib/holdings-table/holdings-table.component.ts
  26. 3
      libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts
  27. 9
      libs/ui/src/lib/shared/abstract-mat-form-field.ts
  28. 9
      libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts
  29. 3
      libs/ui/src/lib/top-holdings/top-holdings.component.ts
  30. 2
      libs/ui/src/lib/value/value.component.ts
  31. 104
      migrations.json
  32. 57
      nx.json
  33. 13210
      package-lock.json
  34. 90
      package.json
  35. 37
      storybook-migration-summary.md

3
apps/client/eslint.config.cjs

@ -30,7 +30,8 @@ module.exports = [
prefix: 'gf',
style: 'camelCase'
}
]
],
'@angular-eslint/prefer-inject': 'off'
}
},
{

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

@ -6,7 +6,6 @@ import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { internalRoutes, publicRoutes } from '@ghostfolio/common/routes/routes';
import { ColorScheme } from '@ghostfolio/common/types';
import { DOCUMENT } from '@angular/common';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
@ -14,7 +13,8 @@ import {
HostBinding,
Inject,
OnDestroy,
OnInit
OnInit,
DOCUMENT
} from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Title } from '@angular/platform-browser';

8
apps/client/src/app/components/admin-settings/admin-settings.component.scss

@ -10,7 +10,7 @@
}
.mat-mdc-card {
--mdc-outlined-card-container-color: whitesmoke;
--mat-card-outlined-container-color: whitesmoke;
.mat-mdc-card-actions {
min-height: 0;
@ -18,8 +18,8 @@
}
.mat-mdc-progress-bar {
--mdc-linear-progress-active-indicator-height: 0.5rem;
--mdc-linear-progress-track-height: 0.5rem;
--mat-progress-bar-active-indicator-height: 0.5rem;
--mat-progress-bar-track-height: 0.5rem;
border-radius: 0.25rem;
::ng-deep {
@ -32,6 +32,6 @@
:host-context(.theme-dark) {
.mat-mdc-card {
--mdc-outlined-card-container-color: #222222;
--mat-card-outlined-container-color: #222222;
}
}

2
apps/client/src/app/components/home-holdings/home-holdings.scss

@ -3,7 +3,7 @@
.mat-button-toggle-group {
.mat-button-toggle-appearance-standard {
--mat-standard-button-toggle-height: 1.5rem;
--mat-button-toggle-height: 1.5rem;
}
}
}

2
apps/client/src/app/components/home-watchlist/create-watchlist-item-dialog/create-watchlist-item-dialog.component.ts

@ -1,6 +1,5 @@
import { GfSymbolAutocompleteComponent } from '@ghostfolio/ui/symbol-autocomplete';
import { CommonModule } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
@ -26,7 +25,6 @@ import { Subject } from 'rxjs';
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'h-100' },
imports: [
CommonModule,
FormsModule,
GfSymbolAutocompleteComponent,
MatButtonModule,

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

@ -11,7 +11,6 @@ import { BenchmarkTrend } from '@ghostfolio/common/types';
import { GfBenchmarkComponent } from '@ghostfolio/ui/benchmark';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { CommonModule } from '@angular/common';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
@ -36,7 +35,6 @@ import { CreateWatchlistItemDialogParams } from './create-watchlist-item-dialog/
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
CommonModule,
GfBenchmarkComponent,
GfPremiumIndicatorComponent,
IonIcon,

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

@ -14,7 +14,6 @@ import { FearAndGreedIndexMode } from '@ghostfolio/common/types';
import { GfBenchmarkComponent } from '@ghostfolio/ui/benchmark';
import { GfLineChartComponent } from '@ghostfolio/ui/line-chart';
import { CommonModule } from '@angular/common';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
@ -30,7 +29,6 @@ import { takeUntil } from 'rxjs/operators';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
CommonModule,
GfBenchmarkComponent,
GfFearAndGreedIndexModule,
GfLineChartComponent,

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

@ -9,7 +9,6 @@ import { Access, User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { CommonModule } from '@angular/common';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
@ -38,7 +37,6 @@ import { GfCreateOrUpdateAccessDialogModule } from './create-or-update-access-di
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'has-fab' },
imports: [
CommonModule,
GfAccessTableComponent,
GfCreateOrUpdateAccessDialogModule,
GfPremiumIndicatorComponent,

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

@ -13,7 +13,6 @@ import { downloadAsFile } from '@ghostfolio/common/helper';
import { User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { CommonModule } from '@angular/common';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
@ -50,7 +49,6 @@ import { catchError, takeUntil } from 'rxjs/operators';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
CommonModule,
FormsModule,
IonIcon,
MatButtonModule,

4
apps/client/src/app/pages/portfolio/allocations/allocations-page.scss

@ -31,8 +31,8 @@
}
.mat-mdc-progress-bar {
--mdc-linear-progress-active-indicator-height: 0.5rem;
--mdc-linear-progress-track-height: 0.5rem;
--mat-progress-bar-active-indicator-height: 0.5rem;
--mat-progress-bar-track-height: 0.5rem;
border-radius: 0.25rem;
::ng-deep {

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

@ -2,7 +2,6 @@ import { UserService } from '@ghostfolio/client/services/user/user.service';
import { TabConfiguration, User } from '@ghostfolio/common/interfaces';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { CommonModule } from '@angular/common';
import {
ChangeDetectorRef,
Component,
@ -20,7 +19,7 @@ import { Subject, takeUntil } from 'rxjs';
@Component({
host: { class: 'page has-tabs' },
imports: [CommonModule, IonIcon, MatTabsModule, RouterModule],
imports: [IonIcon, MatTabsModule, RouterModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-user-account-page',
styleUrls: ['./user-account-page.scss'],

38
apps/client/src/styles.scss

@ -237,10 +237,10 @@ body {
}
.mat-mdc-dialog-container {
--mdc-dialog-container-color: var(--dark-background);
--mat-dialog-container-color: var(--dark-background);
.mdc-dialog__content {
--mdc-dialog-supporting-text-color: rgba(var(--light-primary-text));
--mat-dialog-supporting-text-color: rgba(var(--light-primary-text));
}
}
@ -252,13 +252,13 @@ body {
}
.mat-mdc-card {
--mdc-elevated-card-container-color: var(--dark-background);
--mdc-outlined-card-container-color: var(--dark-background);
--mat-card-elevated-container-color: var(--dark-background);
--mat-card-outlined-container-color: var(--dark-background);
}
.mat-mdc-fab {
&.mat-primary {
--mdc-fab-icon-color: rgba(var(--dark-primary-text));
--mat-fab-icon-color: rgba(var(--dark-primary-text));
--mat-mdc-fab-color: rgba(var(--dark-primary-text));
}
}
@ -270,16 +270,14 @@ body {
.mdc-button {
&.mat-accent,
&.mat-primary {
--mdc-filled-button-label-text-color: rgba(var(--dark-primary-text));
--mat-button-filled-label-text-color: rgba(var(--dark-primary-text));
}
}
.page {
&.has-tabs {
.mat-mdc-tab-nav-bar {
--mat-tab-header-inactive-label-text-color: rgba(
var(--light-primary-text)
);
--mat-tab-inactive-label-text-color: rgba(var(--light-primary-text));
}
@media (min-width: 576px) {
@ -430,7 +428,7 @@ ngx-skeleton-loader {
.mat-mdc-dialog-container {
.mdc-dialog__content {
--mdc-dialog-supporting-text-color: rgba(var(--dark-primary-text));
--mat-dialog-supporting-text-color: rgba(var(--dark-primary-text));
}
}
@ -445,7 +443,7 @@ ngx-skeleton-loader {
color: var(--mat-mdc-fab-color, inherit) !important;
&.mat-primary {
--mdc-fab-icon-color: rgba(var(--light-primary-text));
--mat-fab-icon-color: rgba(var(--light-primary-text));
--mat-mdc-fab-color: rgba(var(--light-primary-text));
}
}
@ -507,7 +505,7 @@ ngx-skeleton-loader {
.mdc-button {
&.mat-accent,
&.mat-primary {
--mdc-filled-button-label-text-color: rgba(var(--light-primary-text));
--mat-button-filled-label-text-color: rgba(var(--light-primary-text));
}
}
@ -557,12 +555,10 @@ ngx-skeleton-loader {
}
.mat-mdc-tab-nav-bar {
--mat-tab-header-active-focus-indicator-color: transparent;
--mat-tab-header-active-hover-indicator-color: transparent;
--mat-tab-header-inactive-label-text-color: rgba(
var(--dark-primary-text)
);
--mdc-tab-indicator-active-indicator-color: transparent;
--mat-tab-active-focus-indicator-color: transparent;
--mat-tab-active-hover-indicator-color: transparent;
--mat-tab-inactive-label-text-color: rgba(var(--dark-primary-text));
--mat-tab-active-indicator-color: transparent;
}
.mat-mdc-tab-nav-panel {
@ -571,7 +567,7 @@ ngx-skeleton-loader {
@media (max-width: 575.98px) {
.mat-mdc-tab-link {
--mdc-secondary-navigation-tab-container-height: 3rem;
--mat-tab-container-height: 3rem;
}
}
@ -582,8 +578,8 @@ ngx-skeleton-loader {
background-color: rgba(var(--palette-foreground-base), 0.02);
padding: 2rem 0;
width: 14rem;
--mat-tab-header-label-text-tracking: normal;
--mdc-secondary-navigation-tab-container-height: 2rem;
--mat-tab-label-text-tracking: normal;
--mat-tab-container-height: 2rem;
.mat-mdc-tab-links {
flex-direction: column;

6
apps/client/src/styles/theme.scss

@ -116,7 +116,7 @@ $gf-theme-dark: mat.m2-define-dark-theme(
--gf-theme-secondary-500-rgb: 78, 208, 94;
--mat-dialog-container-small-max-width: 96vw;
--mdc-filled-button-label-text-tracking: normal;
--mdc-outlined-button-label-text-tracking: normal;
--mdc-text-button-label-text-tracking: normal;
--mat-button-filled-label-text-tracking: normal;
--mat-button-outlined-label-text-tracking: normal;
--mat-button-text-label-text-tracking: normal;
}

25
doctor-storybook.log

@ -0,0 +1,25 @@
🩺 The doctor is checking the health of your Storybook..
╭ Incompatible packages found ────────────────────────────────────────────────────────────────────────╮
│ │
│ You are currently using Storybook 9.0.9 but you have packages which are incompatible with it: │
│ - @storybook/addon-docs@9.0.17 which depends on 9.0.17 │
│ Repo: https://github.com/storybookjs/storybook/tree/next/code/addons/docs │
│ │
│ │
│ Please consider updating your packages or contacting the maintainers for compatibility details. │
│ For more on Storybook 9 compatibility, see the linked GitHub issue: │
│ https://github.com/storybookjs/storybook/issues/30944 │
│ │
│ │
│ The version of storybook@9.0.9 is behind the following core packages: │
│ - @storybook/addon-docs@9.0.17 │
│ Upgrade Storybook with: │
│ npx storybook@latest upgrade │
│ │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯
You can always recheck the health of your project by running:
npx storybook doctor
Full logs are available in /home/attila/projects/ghostfolio/doctor-storybook.log

12
libs/ui/.storybook/main.js

@ -1,8 +1,12 @@
import { createRequire } from 'node:module';
import { dirname, join } from 'node:path';
const require = createRequire(import.meta.url);
/** @type {import('@storybook/angular').StorybookConfig} */
const config = {
addons: ['@storybook/addon-essentials'],
addons: [getAbsolutePath('@storybook/addon-docs')],
framework: {
name: '@storybook/angular',
name: getAbsolutePath('@storybook/angular'),
options: {}
},
staticDirs: [
@ -19,3 +23,7 @@ export default config;
// To customize your webpack configuration you can use the webpackFinal field.
// Check https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config
// and https://nx.dev/packages/storybook/documents/custom-builder-configs
function getAbsolutePath(value) {
return dirname(require.resolve(join(value, 'package.json')));
}

3
libs/ui/eslint.config.cjs

@ -40,7 +40,8 @@ module.exports = [
style: 'kebab-case'
}
],
'@angular-eslint/prefer-standalone': 'off'
'@angular-eslint/prefer-standalone': 'off',
'@angular-eslint/prefer-inject': 'off'
},
languageOptions: {
parserOptions: {

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

@ -1,6 +1,5 @@
import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module';
import { Filter, FilterGroup } from '@ghostfolio/common/interfaces';
import { translate } from '@ghostfolio/ui/i18n';
import { COMMA, ENTER } from '@angular/cdk/keycodes';
import { CommonModule } from '@angular/common';
@ -34,6 +33,8 @@ import { groupBy } from 'lodash';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { translate } from '../i18n';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [

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

@ -6,10 +6,6 @@ import { DEFAULT_PAGE_SIZE } from '@ghostfolio/common/config';
import { getDateFormatString, getLocale } from '@ghostfolio/common/helper';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
import { OrderWithAccount } from '@ghostfolio/common/types';
import { GfActivityTypeComponent } from '@ghostfolio/ui/activity-type';
import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo';
import { GfNoTransactionsInfoComponent } from '@ghostfolio/ui/no-transactions-info';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { SelectionModel } from '@angular/cdk/collections';
import { CommonModule } from '@angular/common';
@ -62,6 +58,11 @@ import {
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { Subject, Subscription, takeUntil } from 'rxjs';
import { GfActivityTypeComponent } from '../activity-type/activity-type.component';
import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component';
import { GfNoTransactionsInfoComponent } from '../no-transactions-info/no-transactions-info.component';
import { GfValueComponent } from '../value/value.component';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [

4
libs/ui/src/lib/activity-type/activity-type.component.ts

@ -1,5 +1,3 @@
import { translate } from '@ghostfolio/ui/i18n';
import { CommonModule } from '@angular/common';
import {
CUSTOM_ELEMENTS_SCHEMA,
@ -20,6 +18,8 @@ import {
hammerOutline
} from 'ionicons/icons';
import { translate } from '../i18n';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule, IonIcon],

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

@ -1,10 +1,5 @@
import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { SearchMode } from '@ghostfolio/ui/assistant/enums/search-mode';
import {
IAssetSearchResultItem,
ISearchResultItem
} from '@ghostfolio/ui/assistant/interfaces/interfaces';
import { FocusableOption } from '@angular/cdk/a11y';
import {
@ -21,6 +16,12 @@ import {
} from '@angular/core';
import { Params, RouterModule } from '@angular/router';
import { SearchMode } from '../enums/search-mode';
import {
IAssetSearchResultItem,
ISearchResultItem
} from '../interfaces/interfaces';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [GfSymbolModule, RouterModule],

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

@ -6,11 +6,8 @@ import { Filter, PortfolioPosition, User } from '@ghostfolio/common/interfaces';
import { InternalRoute } from '@ghostfolio/common/routes/interfaces/internal-route.interface';
import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { DateRange } from '@ghostfolio/common/types';
import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo';
import { translate } from '@ghostfolio/ui/i18n';
import { FocusKeyManager } from '@angular/cdk/a11y';
import { CommonModule } from '@angular/common';
import {
CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy,
@ -63,6 +60,8 @@ import {
tap
} from 'rxjs/operators';
import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component';
import { translate } from '../i18n';
import { GfAssistantListItemComponent } from './assistant-list-item/assistant-list-item.component';
import { SearchMode } from './enums/search-mode';
import {
@ -74,7 +73,6 @@ import {
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
CommonModule,
FormsModule,
GfAssistantListItemComponent,
GfEntityLogoComponent,
@ -529,7 +527,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit {
}
public onChangeDateRange(dateRangeString: string) {
this.dateRangeChanged.emit(dateRangeString as DateRange);
this.dateRangeChanged.emit(dateRangeString);
}
public onCloseAssistant() {

4
libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.component.ts

@ -6,8 +6,6 @@ import {
AdminMarketDataDetails,
LineChartItem
} from '@ghostfolio/common/interfaces';
import { GfLineChartComponent } from '@ghostfolio/ui/line-chart';
import { GfValueComponent } from '@ghostfolio/ui/value';
import {
CUSTOM_ELEMENTS_SCHEMA,
@ -27,6 +25,8 @@ import { format } from 'date-fns';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { GfLineChartComponent } from '../../line-chart/line-chart.component';
import { GfValueComponent } from '../../value/value.component';
import { BenchmarkDetailDialogParams } from './interfaces/interfaces';
@Component({

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

@ -6,9 +6,6 @@ import {
Benchmark,
User
} from '@ghostfolio/common/interfaces';
import { translate } from '@ghostfolio/ui/i18n';
import { GfTrendIndicatorComponent } from '@ghostfolio/ui/trend-indicator';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import {
@ -35,6 +32,9 @@ import { get, isNumber } from 'lodash';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { Subject, takeUntil } from 'rxjs';
import { translate } from '../i18n';
import { GfTrendIndicatorComponent } from '../trend-indicator/trend-indicator.component';
import { GfValueComponent } from '../value/value.component';
import { GfBenchmarkDetailDialogComponent } from './benchmark-detail-dialog/benchmark-detail-dialog.component';
import { BenchmarkDetailDialogParams } from './benchmark-detail-dialog/interfaces/interfaces';

9
libs/ui/src/lib/currency-selector/currency-selector.component.ts

@ -1,5 +1,3 @@
import { AbstractMatFormField } from '@ghostfolio/ui/shared/abstract-mat-form-field';
import { FocusMonitor } from '@angular/cdk/a11y';
import {
CUSTOM_ELEMENTS_SCHEMA,
@ -10,7 +8,8 @@ import {
Input,
OnDestroy,
OnInit,
ViewChild
ViewChild,
DoCheck
} from '@angular/core';
import {
FormControl,
@ -32,6 +31,8 @@ import { MatInput, MatInputModule } from '@angular/material/input';
import { Subject } from 'rxjs';
import { map, startWith, takeUntil } from 'rxjs/operators';
import { AbstractMatFormField } from '../shared/abstract-mat-form-field';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
@ -58,7 +59,7 @@ import { map, startWith, takeUntil } from 'rxjs/operators';
})
export class GfCurrencySelectorComponent
extends AbstractMatFormField<string>
implements OnInit, OnDestroy
implements OnInit, OnDestroy, DoCheck
{
@Input() private currencies: string[] = [];
@Input() private formControlName: string;

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

@ -4,8 +4,6 @@ import {
AssetProfileIdentifier,
PortfolioPosition
} from '@ghostfolio/common/interfaces';
import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import {
@ -28,6 +26,9 @@ import { AssetSubClass } from '@prisma/client';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { Subject, Subscription } from 'rxjs';
import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component';
import { GfValueComponent } from '../value/value.component';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [

3
libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts

@ -6,7 +6,6 @@ import {
PortfolioPosition
} from '@ghostfolio/common/interfaces';
import { ColorScheme } from '@ghostfolio/common/types';
import { translate } from '@ghostfolio/ui/i18n';
import { CommonModule } from '@angular/common';
import {
@ -33,6 +32,8 @@ import { isUUID } from 'class-validator';
import Color from 'color';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { translate } from '../i18n';
const {
blue,
cyan,

9
libs/ui/src/lib/shared/abstract-mat-form-field.ts

@ -17,7 +17,6 @@ import { Subject } from 'rxjs';
template: '',
standalone: false
})
// eslint-disable-next-line @angular-eslint/component-class-suffix
export abstract class AbstractMatFormField<T>
implements ControlValueAccessor, DoCheck, MatFormFieldControl<T>, OnDestroy
{
@ -35,7 +34,7 @@ export abstract class AbstractMatFormField<T>
protected onChange?: (value: T) => void;
protected onTouched?: () => void;
private static nextId: number = 0;
private static nextId = 0;
protected constructor(
protected _elementRef: ElementRef,
@ -83,7 +82,7 @@ export abstract class AbstractMatFormField<T>
return !this._value;
}
public _placeholder: string = '';
public _placeholder = '';
public get placeholder() {
return this._placeholder;
@ -95,7 +94,7 @@ export abstract class AbstractMatFormField<T>
this.stateChanges.next();
}
public _required: boolean = false;
public _required = false;
public get required() {
return (
@ -110,7 +109,7 @@ export abstract class AbstractMatFormField<T>
this.stateChanges.next();
}
public _disabled: boolean = false;
public _disabled = false;
public get disabled() {
if (this.ngControl?.disabled !== null) {

9
libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts

@ -1,8 +1,6 @@
import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module';
import { DataService } from '@ghostfolio/client/services/data.service';
import { LookupItem } from '@ghostfolio/common/interfaces';
import { translate } from '@ghostfolio/ui/i18n';
import { AbstractMatFormField } from '@ghostfolio/ui/shared/abstract-mat-form-field';
import { FocusMonitor } from '@angular/cdk/a11y';
import {
@ -16,7 +14,8 @@ import {
OnDestroy,
OnInit,
SimpleChanges,
ViewChild
ViewChild,
DoCheck
} from '@angular/core';
import {
FormControl,
@ -45,7 +44,9 @@ import {
takeUntil
} from 'rxjs/operators';
import { translate } from '../i18n';
import { GfPremiumIndicatorComponent } from '../premium-indicator';
import { AbstractMatFormField } from '../shared/abstract-mat-form-field';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
@ -76,7 +77,7 @@ import { GfPremiumIndicatorComponent } from '../premium-indicator';
})
export class GfSymbolAutocompleteComponent
extends AbstractMatFormField<LookupItem>
implements OnChanges, OnDestroy, OnInit
implements OnChanges, OnDestroy, OnInit, DoCheck
{
@Input() public defaultLookupItems: LookupItem[] = [];
@Input() public isLoading = false;

3
libs/ui/src/lib/top-holdings/top-holdings.component.ts

@ -4,7 +4,6 @@ import {
AssetProfileIdentifier,
HoldingWithParents
} from '@ghostfolio/common/interfaces';
import { GfValueComponent } from '@ghostfolio/ui/value';
import {
animate,
@ -31,6 +30,8 @@ import { MatTableDataSource, MatTableModule } from '@angular/material/table';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { Subject } from 'rxjs';
import { GfValueComponent } from '../value/value.component';
@Component({
animations: [
trigger('detailExpand', [

2
libs/ui/src/lib/value/value.component.ts

@ -48,7 +48,7 @@ export class GfValueComponent implements OnChanges {
if (isNumber(this.value)) {
this.isNumber = true;
this.isString = false;
this.absoluteValue = Math.abs(this.value as number);
this.absoluteValue = Math.abs(this.value);
if (this.colorizeSign) {
if (this.isCurrency) {

104
migrations.json

@ -0,0 +1,104 @@
{
"migrations": [
{
"cli": "nx",
"version": "21.2.0-beta.3",
"requires": { "@angular/core": ">=20.0.0" },
"description": "Update the @angular/cli package version to ~20.0.0.",
"factory": "./src/migrations/update-21-2-0/update-angular-cli",
"package": "@nx/angular",
"name": "update-angular-cli-version-20-0-0"
},
{
"version": "21.2.0-beta.3",
"requires": { "@angular/core": ">=20.0.0" },
"description": "Migrate imports of `provideServerRendering` from `@angular/platform-server` to `@angular/ssr`.",
"factory": "./src/migrations/update-21-2-0/migrate-provide-server-rendering-import",
"package": "@nx/angular",
"name": "migrate-provide-server-rendering-import"
},
{
"version": "21.2.0-beta.3",
"requires": { "@angular/core": ">=20.0.0" },
"description": "Replace `provideServerRouting` and `provideServerRoutesConfig` with `provideServerRendering` using `withRoutes`.",
"factory": "./src/migrations/update-21-2-0/replace-provide-server-routing",
"package": "@nx/angular",
"name": "replace-provide-server-routing"
},
{
"version": "21.2.0-beta.3",
"requires": { "@angular/core": ">=20.0.0" },
"description": "Update the generator defaults to maintain the previous style guide behavior.",
"factory": "./src/migrations/update-21-2-0/set-generator-defaults-for-previous-style-guide",
"package": "@nx/angular",
"name": "set-generator-defaults-for-previous-style-guide"
},
{
"version": "21.2.0-beta.3",
"requires": { "@angular/core": ">=20.0.0" },
"description": "Update 'moduleResolution' to 'bundler' in TypeScript configurations. You can read more about this here: https://www.typescriptlang.org/tsconfig/#moduleResolution.",
"factory": "./src/migrations/update-21-2-0/update-module-resolution",
"package": "@nx/angular",
"name": "update-module-resolution"
},
{
"cli": "nx",
"version": "21.2.0-beta.3",
"description": "Update workspace to use Storybook v9",
"implementation": "./src/migrations/update-21-1-0/update-sb-9",
"package": "@nx/storybook",
"name": "update-21-2-0-migrate-storybook-v9"
},
{
"cli": "nx",
"version": "21.2.0-beta.3",
"description": "Remove deprecated Storybook addon dependencies",
"implementation": "./src/migrations/update-21-2-0/remove-addon-dependencies",
"package": "@nx/storybook",
"name": "update-21-2-0-remove-addon-dependencies"
},
{
"version": "20.0.0",
"description": "Replaces usages of the deprecated InjectFlags enum",
"factory": "./bundles/inject-flags.cjs#migrate",
"package": "@angular/core",
"name": "inject-flags"
},
{
"version": "20.0.0",
"description": "Replaces usages of the deprecated TestBed.get method with TestBed.inject",
"factory": "./bundles/test-bed-get.cjs#migrate",
"package": "@angular/core",
"name": "test-bed-get"
},
{
"version": "20.0.0",
"description": "Converts the entire application to block control flow syntax",
"factory": "./bundles/control-flow-migration.cjs#migrate",
"optional": true,
"package": "@angular/core",
"name": "control-flow-migration"
},
{
"version": "20.0.0",
"description": "Moves imports of `DOCUMENT` from `@angular/common` to `@angular/core`",
"factory": "./bundles/document-core.cjs#migrate",
"package": "@angular/core",
"name": "document-core"
},
{
"version": "20.0.0-0",
"description": "Updates Angular Material to v20",
"factory": "./ng-update/index_bundled#updateToV20",
"package": "@angular/material",
"name": "migration-v20"
},
{
"version": "20.0.0-0",
"description": "Updates the Angular CDK to v20",
"factory": "./ng-update/index#updateToV20",
"package": "@angular/cdk",
"name": "migration-v20"
}
]
}

57
nx.json

@ -10,8 +10,61 @@
"linter": "eslint",
"unitTestRunner": "jest"
},
"@nx/angular:component": {},
"@nx/nest": {}
"@nx/angular:component": {
"type": "component"
},
"@nx/nest": {},
"@schematics/angular:component": {
"type": "component"
},
"@nx/angular:directive": {
"type": "directive"
},
"@schematics/angular:directive": {
"type": "directive"
},
"@nx/angular:service": {
"type": "service"
},
"@schematics/angular:service": {
"type": "service"
},
"@nx/angular:scam": {
"type": "component"
},
"@nx/angular:scam-directive": {
"type": "directive"
},
"@nx/angular:guard": {
"typeSeparator": "."
},
"@schematics/angular:guard": {
"typeSeparator": "."
},
"@nx/angular:interceptor": {
"typeSeparator": "."
},
"@schematics/angular:interceptor": {
"typeSeparator": "."
},
"@nx/angular:module": {
"typeSeparator": "."
},
"@schematics/angular:module": {
"typeSeparator": "."
},
"@nx/angular:pipe": {
"typeSeparator": "."
},
"@schematics/angular:pipe": {
"typeSeparator": "."
},
"@nx/angular:resolver": {
"typeSeparator": "."
},
"@schematics/angular:resolver": {
"typeSeparator": "."
}
},
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"targetDefaults": {

13210
package-lock.json

File diff suppressed because it is too large

90
package.json

@ -56,17 +56,17 @@
"workspace-generator": "nx workspace-generator"
},
"dependencies": {
"@angular/animations": "19.2.1",
"@angular/cdk": "19.2.2",
"@angular/common": "19.2.1",
"@angular/compiler": "19.2.1",
"@angular/core": "19.2.1",
"@angular/forms": "19.2.1",
"@angular/material": "19.2.2",
"@angular/platform-browser": "19.2.1",
"@angular/platform-browser-dynamic": "19.2.1",
"@angular/router": "19.2.1",
"@angular/service-worker": "19.2.1",
"@angular/animations": "20.0.7",
"@angular/cdk": "20.0.6",
"@angular/common": "20.0.7",
"@angular/compiler": "20.0.7",
"@angular/core": "20.0.7",
"@angular/forms": "20.0.7",
"@angular/material": "20.0.6",
"@angular/platform-browser": "20.0.7",
"@angular/platform-browser-dynamic": "20.0.7",
"@angular/router": "20.0.7",
"@angular/service-worker": "20.0.7",
"@codewithdan/observable-store": "2.2.15",
"@date-fns/utc": "2.1.0",
"@dfinity/agent": "0.15.7",
@ -123,10 +123,10 @@
"marked": "15.0.4",
"ms": "3.0.0-canary.1",
"ng-extract-i18n-merge": "2.15.1",
"ngx-device-detector": "9.0.0",
"ngx-markdown": "19.0.0",
"ngx-device-detector": "10.0.2",
"ngx-markdown": "20.0.0",
"ngx-skeleton-loader": "11.2.1",
"ngx-stripe": "19.7.0",
"ngx-stripe": "20.7.0",
"open-color": "1.9.1",
"papaparse": "5.3.1",
"passport": "0.7.0",
@ -143,37 +143,35 @@
"zone.js": "0.15.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "19.2.1",
"@angular-devkit/core": "19.2.1",
"@angular-devkit/schematics": "19.2.1",
"@angular-eslint/eslint-plugin": "19.2.1",
"@angular-eslint/eslint-plugin-template": "19.2.1",
"@angular-eslint/template-parser": "19.2.1",
"@angular/cli": "19.2.1",
"@angular/compiler-cli": "19.2.1",
"@angular/language-service": "19.2.1",
"@angular/localize": "19.2.1",
"@angular/pwa": "19.2.1",
"@angular-devkit/build-angular": "20.0.6",
"@angular-devkit/core": "20.0.6",
"@angular-devkit/schematics": "20.0.6",
"@angular-eslint/eslint-plugin": "20.1.1",
"@angular-eslint/eslint-plugin-template": "20.1.1",
"@angular-eslint/template-parser": "20.1.1",
"@angular/cli": "20.0.6",
"@angular/compiler-cli": "20.0.7",
"@angular/language-service": "20.0.7",
"@angular/localize": "20.0.7",
"@angular/pwa": "20.0.6",
"@eslint/eslintrc": "3.3.1",
"@eslint/js": "9.24.0",
"@nestjs/schematics": "11.0.5",
"@nestjs/testing": "11.1.3",
"@nx/angular": "21.1.2",
"@nx/cypress": "21.1.2",
"@nx/eslint-plugin": "21.1.2",
"@nx/jest": "21.1.2",
"@nx/js": "21.1.2",
"@nx/module-federation": "21.1.2",
"@nx/nest": "21.1.2",
"@nx/node": "21.1.2",
"@nx/storybook": "21.1.2",
"@nx/web": "21.1.2",
"@nx/workspace": "21.1.2",
"@schematics/angular": "19.2.1",
"@storybook/addon-essentials": "8.6.12",
"@storybook/addon-interactions": "8.6.12",
"@storybook/angular": "8.6.12",
"@storybook/core-server": "8.6.12",
"@nx/angular": "21.2.4",
"@nx/cypress": "21.2.4",
"@nx/eslint-plugin": "21.2.4",
"@nx/jest": "21.2.4",
"@nx/js": "21.2.4",
"@nx/module-federation": "21.2.4",
"@nx/nest": "21.2.4",
"@nx/node": "21.2.4",
"@nx/storybook": "21.2.4",
"@nx/web": "21.2.4",
"@nx/workspace": "21.2.4",
"@schematics/angular": "20.0.6",
"@storybook/addon-docs": "9.0.17",
"@storybook/angular": "9.0.17",
"@trivago/prettier-plugin-sort-imports": "5.2.2",
"@types/big.js": "6.2.2",
"@types/google-spreadsheet": "3.1.5",
@ -190,12 +188,12 @@
"eslint-config-prettier": "10.1.1",
"eslint-plugin-cypress": "4.2.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-storybook": "0.12.0",
"eslint-plugin-storybook": "9.0.17",
"husky": "9.1.7",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"jest-preset-angular": "14.4.2",
"nx": "21.1.2",
"jest-preset-angular": "14.6.0",
"nx": "21.2.4",
"prettier": "3.6.2",
"prettier-plugin-organize-attributes": "1.0.0",
"prisma": "6.11.1",
@ -203,11 +201,11 @@
"react-dom": "18.2.0",
"replace-in-file": "8.3.0",
"shx": "0.3.4",
"storybook": "8.6.12",
"storybook": "9.0.17",
"ts-jest": "29.1.0",
"ts-node": "10.9.2",
"tslib": "2.8.1",
"typescript": "5.7.3",
"typescript": "5.8.3",
"webpack-bundle-analyzer": "4.10.2"
},
"engines": {

37
storybook-migration-summary.md

@ -0,0 +1,37 @@
# Storybook 9 Migration Summary
## Upgrade Storybook packages
The following command was ran to upgrade the Storybook packages:
```bash
npx storybook@latest upgrade
```
## The Storybook automigration scripts were ran
The following commands ran successfully and your Storybook configuration was successfully migrated to the latest version 9:
- `npx storybook automigrate --config-dir libs/ui/.storybook`
Please make sure to check the results yourself and make sure that everything is working as expected.
Also, we may have missed something. Please make sure to check the logs of the Storybook CLI commands that were run, and look for
the `❌ Failed trying to evaluate` message or `❌ The migration failed to update` message. This will indicate if a command was
unsuccessful, and will help you run the migration again, manually.
## Next steps
You can make sure everything is working as expected by trying
to build or serve your Storybook as you normally would.
```bash
npx nx build-storybook project-name
```
```bash
npx nx storybook project-name
```
Please read the [Storybook 9.0.0 migration guide](https://github.com/storybookjs/storybook/blob/next/MIGRATION.md)
for more information.
Loading…
Cancel
Save