Browse Source

migrate to angular fow syntax

pull/4321/head
Shaunak 6 months ago
parent
commit
6aad3172c4
  1. 2
      apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.component.ts
  2. 4
      apps/client/src/app/components/asset-profile-icon/asset-profile-icon.component.ts
  3. 9
      apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts
  4. 4
      apps/client/src/app/core/notification/alert-dialog/alert-dialog.component.ts
  5. 4
      apps/client/src/app/core/notification/confirmation-dialog/confirmation-dialog.component.ts
  6. 2
      apps/client/src/app/core/notification/prompt-dialog/prompt-dialog.component.ts
  7. 4
      apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts
  8. 5
      libs/ui/src/lib/assistant/assistant.component.ts
  9. 305
      libs/ui/src/lib/assistant/assistant.html
  10. 5
      libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.component.ts
  11. 13
      libs/ui/src/lib/data-provider-credits/data-provider-credits.component.html
  12. 4
      libs/ui/src/lib/data-provider-credits/data-provider-credits.component.ts
  13. 5
      libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.component.ts
  14. 5
      libs/ui/src/lib/tags-selector/tags-selector.component.ts
  15. 4
      libs/ui/src/lib/trend-indicator/trend-indicator.component.ts
  16. 145
      libs/ui/src/lib/value/value.component.html

2
apps/client/src/app/components/admin-settings/ghostfolio-premium-api-dialog/ghostfolio-premium-api-dialog.component.ts

@ -3,7 +3,6 @@ import { DataService } from '@ghostfolio/client/services/data.service';
import { PROPERTY_API_KEY_GHOSTFOLIO } from '@ghostfolio/common/config'; import { PROPERTY_API_KEY_GHOSTFOLIO } from '@ghostfolio/common/config';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { CommonModule } from '@angular/common';
import { Component, Inject } from '@angular/core'; import { Component, Inject } from '@angular/core';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { import {
@ -18,7 +17,6 @@ import { GhostfolioPremiumApiDialogParams } from './interfaces/interfaces';
@Component({ @Component({
imports: [ imports: [
CommonModule,
GfDialogFooterModule, GfDialogFooterModule,
GfDialogHeaderModule, GfDialogHeaderModule,
GfPremiumIndicatorComponent, GfPremiumIndicatorComponent,

4
apps/client/src/app/components/asset-profile-icon/asset-profile-icon.component.ts

@ -1,4 +1,4 @@
import { CommonModule } from '@angular/common';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy, ChangeDetectionStrategy,
@ -10,7 +10,7 @@ import { DataSource } from '@prisma/client';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule], imports: [],
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-asset-profile-icon', selector: 'gf-asset-profile-icon',
styleUrls: ['./asset-profile-icon.component.scss'], styleUrls: ['./asset-profile-icon.component.scss'],

9
apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts

@ -1,6 +1,5 @@
import { XRayRulesSettings } from '@ghostfolio/common/interfaces'; import { XRayRulesSettings } from '@ghostfolio/common/interfaces';
import { CommonModule } from '@angular/common';
import { Component, Inject } from '@angular/core'; import { Component, Inject } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
@ -14,13 +13,7 @@ import { MatSliderModule } from '@angular/material/slider';
import { IRuleSettingsDialogParams } from './interfaces/interfaces'; import { IRuleSettingsDialogParams } from './interfaces/interfaces';
@Component({ @Component({
imports: [ imports: [FormsModule, MatButtonModule, MatDialogModule, MatSliderModule],
CommonModule,
FormsModule,
MatButtonModule,
MatDialogModule,
MatSliderModule
],
selector: 'gf-rule-settings-dialog', selector: 'gf-rule-settings-dialog',
styleUrls: ['./rule-settings-dialog.scss'], styleUrls: ['./rule-settings-dialog.scss'],
templateUrl: './rule-settings-dialog.html' templateUrl: './rule-settings-dialog.html'

4
apps/client/src/app/core/notification/alert-dialog/alert-dialog.component.ts

@ -1,4 +1,4 @@
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
@ -6,7 +6,7 @@ import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { IAlertDialogParams } from './interfaces/interfaces'; import { IAlertDialogParams } from './interfaces/interfaces';
@Component({ @Component({
imports: [CommonModule, MatButtonModule, MatDialogModule], imports: [MatButtonModule, MatDialogModule],
selector: 'gf-alert-dialog', selector: 'gf-alert-dialog',
styleUrls: ['./alert-dialog.scss'], styleUrls: ['./alert-dialog.scss'],
templateUrl: './alert-dialog.html' templateUrl: './alert-dialog.html'

4
apps/client/src/app/core/notification/confirmation-dialog/confirmation-dialog.component.ts

@ -1,4 +1,4 @@
import { CommonModule } from '@angular/common';
import { Component, HostListener } from '@angular/core'; import { Component, HostListener } from '@angular/core';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
@ -7,7 +7,7 @@ import { ConfirmationDialogType } from './confirmation-dialog.type';
import { IConfirmDialogParams } from './interfaces/interfaces'; import { IConfirmDialogParams } from './interfaces/interfaces';
@Component({ @Component({
imports: [CommonModule, MatButtonModule, MatDialogModule], imports: [MatButtonModule, MatDialogModule],
selector: 'gf-confirmation-dialog', selector: 'gf-confirmation-dialog',
styleUrls: ['./confirmation-dialog.scss'], styleUrls: ['./confirmation-dialog.scss'],
templateUrl: './confirmation-dialog.html' templateUrl: './confirmation-dialog.html'

2
apps/client/src/app/core/notification/prompt-dialog/prompt-dialog.component.ts

@ -1,4 +1,3 @@
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
@ -8,7 +7,6 @@ import { MatInputModule } from '@angular/material/input';
@Component({ @Component({
imports: [ imports: [
CommonModule,
FormsModule, FormsModule,
MatButtonModule, MatButtonModule,
MatDialogModule, MatDialogModule,

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

@ -3,14 +3,14 @@ import { Product } from '@ghostfolio/common/interfaces';
import { personalFinanceTools } from '@ghostfolio/common/personal-finance-tools'; import { personalFinanceTools } from '@ghostfolio/common/personal-finance-tools';
import { translate } from '@ghostfolio/ui/i18n'; import { translate } from '@ghostfolio/ui/i18n';
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { ActivatedRoute, RouterModule } from '@angular/router'; import { ActivatedRoute, RouterModule } from '@angular/router';
@Component({ @Component({
host: { class: 'page' }, host: { class: 'page' },
imports: [CommonModule, MatButtonModule, RouterModule], imports: [MatButtonModule, RouterModule],
selector: 'gf-product-page', selector: 'gf-product-page',
styleUrls: ['./product-page.scss'], styleUrls: ['./product-page.scss'],
templateUrl: './product-page.html' templateUrl: './product-page.html'

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

@ -8,7 +8,7 @@ import { DateRange } from '@ghostfolio/common/types';
import { translate } from '@ghostfolio/ui/i18n'; import { translate } from '@ghostfolio/ui/i18n';
import { FocusKeyManager } from '@angular/cdk/a11y'; import { FocusKeyManager } from '@angular/cdk/a11y';
import { CommonModule } from '@angular/common';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy, ChangeDetectionStrategy,
@ -59,7 +59,6 @@ import {
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ imports: [
CommonModule,
FormsModule, FormsModule,
GfAssetProfileIconComponent, GfAssetProfileIconComponent,
GfAssistantListItemComponent, GfAssistantListItemComponent,
@ -70,7 +69,7 @@ import {
NgxSkeletonLoaderModule, NgxSkeletonLoaderModule,
ReactiveFormsModule, ReactiveFormsModule,
RouterModule RouterModule
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-assistant', selector: 'gf-assistant',
styleUrls: ['./assistant.scss'], styleUrls: ['./assistant.scss'],

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

@ -2,7 +2,7 @@
<div <div
[style.width]="deviceType === 'mobile' ? '85vw' : '30rem'" [style.width]="deviceType === 'mobile' ? '85vw' : '30rem'"
(keydown.tab)="$event.stopPropagation()" (keydown.tab)="$event.stopPropagation()"
> >
<div class="align-items-center d-flex search-container"> <div class="align-items-center d-flex search-container">
<ion-icon class="ml-2 mr-0" name="search-outline" /> <ion-icon class="ml-2 mr-0" name="search-outline" />
<input <input
@ -14,77 +14,91 @@
type="text" type="text"
[formControl]="searchFormControl" [formControl]="searchFormControl"
[placeholder]="placeholder" [placeholder]="placeholder"
/>
<div
*ngIf="deviceType !== 'mobile' && !searchFormControl.value"
class="hot-key-hint mx-1 px-1"
>
/
</div>
<button
*ngIf="searchFormControl.value"
class="h-100 no-min-width px-3 rounded-0"
mat-button
(click)="initialize()"
>
<ion-icon class="m-0" name="close-circle-outline" />
</button>
<button
*ngIf="!searchFormControl.value"
class="h-100 no-min-width px-3 rounded-0"
mat-button
(click)="onCloseAssistant()"
>
<ion-icon class="m-0" name="close-outline" />
</button>
</div>
<div
*ngIf="isLoading || searchFormControl.value"
class="overflow-auto py-3 result-container"
>
<div>
<div class="h6 mb-1 px-2" i18n>Holdings</div>
<gf-assistant-list-item
*ngFor="let searchResultItem of searchResults?.holdings"
mode="holding"
[item]="searchResultItem"
(clicked)="onCloseAssistant()"
/> />
<ng-container *ngIf="searchResults?.holdings?.length === 0"> @if (deviceType !== 'mobile' && !searchFormControl.value) {
<ngx-skeleton-loader <div
*ngIf="isLoading" class="hot-key-hint mx-1 px-1"
animation="pulse" >
class="mx-2" /
</div>
}
@if (searchFormControl.value) {
<button
class="h-100 no-min-width px-3 rounded-0"
mat-button
(click)="initialize()"
>
<ion-icon class="m-0" name="close-circle-outline" />
</button>
}
@if (!searchFormControl.value) {
<button
class="h-100 no-min-width px-3 rounded-0"
mat-button
(click)="onCloseAssistant()"
>
<ion-icon class="m-0" name="close-outline" />
</button>
}
</div>
@if (isLoading || searchFormControl.value) {
<div
class="overflow-auto py-3 result-container"
>
<div>
<div class="h6 mb-1 px-2" i18n>Holdings</div>
@for (searchResultItem of searchResults?.holdings; track searchResultItem) {
<gf-assistant-list-item
mode="holding"
[item]="searchResultItem"
(clicked)="onCloseAssistant()"
/>
}
@if (searchResults?.holdings?.length === 0) {
@if (isLoading) {
<ngx-skeleton-loader
animation="pulse"
class="mx-2"
[theme]="{ [theme]="{
height: '1.5rem', height: '1.5rem',
width: '100%' width: '100%'
}" }"
/> />
<div *ngIf="!isLoading" class="px-2 py-1" i18n>No entries...</div> }
</ng-container> @if (!isLoading) {
</div> <div class="px-2 py-1" i18n>No entries...</div>
<div *ngIf="hasPermissionToAccessAdminControl" class="mt-3"> }
<div class="h6 mb-1 px-2" i18n>Asset Profiles</div> }
<gf-assistant-list-item </div>
*ngFor="let searchResultItem of searchResults?.assetProfiles" @if (hasPermissionToAccessAdminControl) {
mode="assetProfile" <div class="mt-3">
[item]="searchResultItem" <div class="h6 mb-1 px-2" i18n>Asset Profiles</div>
(clicked)="onCloseAssistant()" @for (searchResultItem of searchResults?.assetProfiles; track searchResultItem) {
/> <gf-assistant-list-item
<ng-container *ngIf="searchResults?.assetProfiles?.length === 0"> mode="assetProfile"
<ngx-skeleton-loader [item]="searchResultItem"
*ngIf="isLoading" (clicked)="onCloseAssistant()"
animation="pulse" />
class="mx-2" }
@if (searchResults?.assetProfiles?.length === 0) {
@if (isLoading) {
<ngx-skeleton-loader
animation="pulse"
class="mx-2"
[theme]="{ [theme]="{
height: '1.5rem', height: '1.5rem',
width: '100%' width: '100%'
}" }"
/> />
<div *ngIf="!isLoading" class="px-2 py-1" i18n>No entries...</div> }
</ng-container> @if (!isLoading) {
<div class="px-2 py-1" i18n>No entries...</div>
}
}
</div>
}
</div> </div>
</div> }
</div> </div>
<form [formGroup]="filterForm"> <form [formGroup]="filterForm">
@if (!searchFormControl.value) { @if (!searchFormControl.value) {
@ -94,7 +108,7 @@
<mat-select <mat-select
[formControl]="dateRangeFormControl" [formControl]="dateRangeFormControl"
(selectionChange)="onChangeDateRange($event.value)" (selectionChange)="onChangeDateRange($event.value)"
> >
@for (range of dateRangeOptions; track range) { @for (range of dateRangeOptions; track range) {
<mat-option [value]="range.value">{{ range.label }}</mat-option> <mat-option [value]="range.value">{{ range.label }}</mat-option>
} }
@ -110,93 +124,94 @@
@for (account of accounts; track account.id) { @for (account of accounts; track account.id) {
<mat-option [value]="account.id"> <mat-option [value]="account.id">
<div class="d-flex"> <div class="d-flex">
<gf-asset-profile-icon @if (account.Platform?.url) {
*ngIf="account.Platform?.url" <gf-asset-profile-icon
class="mr-1" class="mr-1"
[tooltip]="account.Platform?.name" [tooltip]="account.Platform?.name"
[url]="account.Platform?.url" [url]="account.Platform?.url"
/><span>{{ account.name }}</span> />
</div> }<span>{{ account.name }}</span>
</mat-option> </div>
} </mat-option>
</mat-select> }
</mat-form-field> </mat-select>
</div> </mat-form-field>
<div class="mb-3"> </div>
<mat-form-field appearance="outline" class="w-100 without-hint"> <div class="mb-3">
<mat-label i18n>Holding</mat-label> <mat-form-field appearance="outline" class="w-100 without-hint">
<mat-select <mat-label i18n>Holding</mat-label>
formControlName="holding" <mat-select
[compareWith]="holdingComparisonFunction" formControlName="holding"
> [compareWith]="holdingComparisonFunction"
<mat-select-trigger>{{ >
filterForm.get('holding')?.value?.name <mat-select-trigger>{{
}}</mat-select-trigger> filterForm.get('holding')?.value?.name
<mat-option [value]="null" /> }}</mat-select-trigger>
@for (holding of holdings; track holding.name) { <mat-option [value]="null" />
<mat-option [value]="holding"> @for (holding of holdings; track holding.name) {
<div class="line-height-1 text-truncate"> <mat-option [value]="holding">
<span <div class="line-height-1 text-truncate">
><b>{{ holding.name }}</b></span <span
> ><b>{{ holding.name }}</b></span
<br /> >
<small class="text-muted" <br />
>{{ holding.symbol | gfSymbol }} · <small class="text-muted"
{{ holding.currency }}</small >{{ holding.symbol | gfSymbol }} ·
> {{ holding.currency }}</small
</div> >
</mat-option> </div>
} </mat-option>
</mat-select> }
</mat-form-field> </mat-select>
</div> </mat-form-field>
<div class="mb-3"> </div>
<mat-form-field appearance="outline" class="w-100 without-hint"> <div class="mb-3">
<mat-label i18n>Tag</mat-label> <mat-form-field appearance="outline" class="w-100 without-hint">
<mat-select formControlName="tag"> <mat-label i18n>Tag</mat-label>
<mat-option [value]="null" /> <mat-select formControlName="tag">
@for (tag of tags; track tag.id) { <mat-option [value]="null" />
<mat-option [value]="tag.id">{{ tag.label }}</mat-option> @for (tag of tags; track tag.id) {
} <mat-option [value]="tag.id">{{ tag.label }}</mat-option>
</mat-select> }
</mat-form-field> </mat-select>
</div> </mat-form-field>
<div class="mb-3"> </div>
<mat-form-field appearance="outline" class="w-100 without-hint"> <div class="mb-3">
<mat-label i18n>Asset Class</mat-label> <mat-form-field appearance="outline" class="w-100 without-hint">
<mat-select formControlName="assetClass"> <mat-label i18n>Asset Class</mat-label>
<mat-option [value]="null" /> <mat-select formControlName="assetClass">
@for (assetClass of assetClasses; track assetClass.id) { <mat-option [value]="null" />
<mat-option [value]="assetClass.id">{{ @for (assetClass of assetClasses; track assetClass.id) {
assetClass.label <mat-option [value]="assetClass.id">{{
}}</mat-option> assetClass.label
} }}</mat-option>
</mat-select> }
</mat-form-field> </mat-select>
</div> </mat-form-field>
<div class="d-flex w-100"> </div>
<button <div class="d-flex w-100">
i18n <button
mat-button i18n
mat-button
[disabled]=" [disabled]="
!hasFilter(filterForm.value) || !hasPermissionToChangeFilters !hasFilter(filterForm.value) || !hasPermissionToChangeFilters
" "
(click)="onResetFilters()" (click)="onResetFilters()"
> >
Reset Filters Reset Filters
</button> </button>
<span class="gf-spacer"></span> <span class="gf-spacer"></span>
<button <button
color="primary" color="primary"
i18n i18n
mat-flat-button mat-flat-button
[disabled]="!filterForm.dirty || !hasPermissionToChangeFilters" [disabled]="!filterForm.dirty || !hasPermissionToChangeFilters"
(click)="onApplyFilters()" (click)="onApplyFilters()"
> >
Apply Filters Apply Filters
</button> </button>
</div> </div>
</div>
}
</form>
</div> </div>
}
</form>
</div>

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

@ -8,7 +8,7 @@ import {
} from '@ghostfolio/common/interfaces'; } from '@ghostfolio/common/interfaces';
import { GfLineChartComponent } from '@ghostfolio/ui/line-chart'; import { GfLineChartComponent } from '@ghostfolio/ui/line-chart';
import { CommonModule } from '@angular/common';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy, ChangeDetectionStrategy,
@ -33,12 +33,11 @@ import { BenchmarkDetailDialogParams } from './interfaces/interfaces';
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'd-flex flex-column h-100' }, host: { class: 'd-flex flex-column h-100' },
imports: [ imports: [
CommonModule,
GfDialogFooterModule, GfDialogFooterModule,
GfDialogHeaderModule, GfDialogHeaderModule,
GfLineChartComponent, GfLineChartComponent,
MatDialogModule MatDialogModule
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-benchmark-detail-dialog', selector: 'gf-benchmark-detail-dialog',
styleUrls: ['./benchmark-detail-dialog.component.scss'], styleUrls: ['./benchmark-detail-dialog.component.scss'],

13
libs/ui/src/lib/data-provider-credits/data-provider-credits.component.html

@ -1,9 +1,10 @@
<small class="text-muted"> <small class="text-muted">
<ng-container i18n>Market data provided by</ng-container>&nbsp;<ng-container <ng-container i18n>Market data provided by</ng-container>&nbsp;@for (dataProviderInfo of dataProviderInfos; track dataProviderInfo; let last = $last) {
*ngFor="let dataProviderInfo of dataProviderInfos; let last = last" <a target="_blank" [href]="dataProviderInfo.url">{{
><a target="_blank" [href]="dataProviderInfo.url">{{ dataProviderInfo.name
dataProviderInfo.name
}}</a }}</a
><ng-container *ngIf="!last">, </ng-container></ng-container >@if (!last) {
>. ,
}
}.
</small> </small>

4
libs/ui/src/lib/data-provider-credits/data-provider-credits.component.ts

@ -1,6 +1,6 @@
import { DataProviderInfo } from '@ghostfolio/common/interfaces'; import { DataProviderInfo } from '@ghostfolio/common/interfaces';
import { CommonModule } from '@angular/common';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy, ChangeDetectionStrategy,
@ -10,7 +10,7 @@ import {
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule], imports: [],
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-data-provider-credits', selector: 'gf-data-provider-credits',
styleUrls: ['./data-provider-credits.component.scss'], styleUrls: ['./data-provider-credits.component.scss'],

5
libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.component.ts

@ -1,7 +1,7 @@
import { AdminService } from '@ghostfolio/client/services/admin.service'; import { AdminService } from '@ghostfolio/client/services/admin.service';
import { DataService } from '@ghostfolio/client/services/data.service'; import { DataService } from '@ghostfolio/client/services/data.service';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
@ -29,7 +29,6 @@ import { HistoricalMarketDataEditorDialogParams } from './interfaces/interfaces'
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'h-100' }, host: { class: 'h-100' },
imports: [ imports: [
CommonModule,
FormsModule, FormsModule,
MatButtonModule, MatButtonModule,
MatDatepickerModule, MatDatepickerModule,
@ -37,7 +36,7 @@ import { HistoricalMarketDataEditorDialogParams } from './interfaces/interfaces'
MatFormFieldModule, MatFormFieldModule,
MatInputModule, MatInputModule,
ReactiveFormsModule ReactiveFormsModule
], ],
selector: 'gf-historical-market-data-editor-dialog', selector: 'gf-historical-market-data-editor-dialog',
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
styleUrls: ['./historical-market-data-editor-dialog.scss'], styleUrls: ['./historical-market-data-editor-dialog.scss'],

5
libs/ui/src/lib/tags-selector/tags-selector.component.ts

@ -1,5 +1,5 @@
import { COMMA, ENTER } from '@angular/cdk/keycodes'; import { COMMA, ENTER } from '@angular/cdk/keycodes';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
Component, Component,
@ -28,14 +28,13 @@ import { BehaviorSubject, Subject, takeUntil } from 'rxjs';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ imports: [
CommonModule,
FormsModule, FormsModule,
MatAutocompleteModule, MatAutocompleteModule,
MatChipsModule, MatChipsModule,
MatFormFieldModule, MatFormFieldModule,
MatInputModule, MatInputModule,
ReactiveFormsModule ReactiveFormsModule
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-tags-selector', selector: 'gf-tags-selector',
styleUrls: ['./tags-selector.component.scss'], styleUrls: ['./tags-selector.component.scss'],

4
libs/ui/src/lib/trend-indicator/trend-indicator.component.ts

@ -1,6 +1,6 @@
import { DateRange, MarketState } from '@ghostfolio/common/types'; import { DateRange, MarketState } from '@ghostfolio/common/types';
import { CommonModule } from '@angular/common';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy, ChangeDetectionStrategy,
@ -11,7 +11,7 @@ import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule, NgxSkeletonLoaderModule], imports: [NgxSkeletonLoaderModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-trend-indicator', selector: 'gf-trend-indicator',
styleUrls: ['./trend-indicator.component.scss'], styleUrls: ['./trend-indicator.component.scss'],

145
libs/ui/src/lib/value/value.component.html

@ -1,54 +1,66 @@
<div *ngIf="icon" class="align-self-center mr-3"> @if (icon) {
<ion-icon class="h3 m-0" [name]="icon" /> <div class="align-self-center mr-3">
</div> <ion-icon class="h3 m-0" [name]="icon" />
</div>
}
<div class="d-flex flex-column w-100"> <div class="d-flex flex-column w-100">
<ng-template #label><ng-content></ng-content></ng-template> <ng-template #label><ng-content></ng-content></ng-template>
<ng-container *ngIf="value || value === 0 || value === null"> @if (value || value === 0 || value === null) {
<div <div
class="align-items-center d-flex" class="align-items-center d-flex"
[ngClass]="position === 'end' ? 'justify-content-end' : ''" [ngClass]="position === 'end' ? 'justify-content-end' : ''"
> >
<ng-container *ngIf="isNumber || value === null"> @if (isNumber || value === null) {
<ng-container *ngIf="colorizeSign && !useAbsoluteValue"> @if (colorizeSign && !useAbsoluteValue) {
<div *ngIf="value > 0" class="mr-1 text-success">+</div> @if (+value > 0) {
<div *ngIf="value < 0" class="mr-1 text-danger">-</div> <div class="mr-1 text-success">+</div>
</ng-container>
<div
*ngIf="isPercent"
class="mb-0 value"
[ngClass]="{
'font-weight-bold h2': size === 'large',
h4: size === 'medium'
}"
>
@if (value === null) {
<span class="text-monospace text-muted">*****</span>%
} @else {
{{ formattedValue }}%
} }
</div> @if (+value < 0) {
<div <div class="mr-1 text-danger">-</div>
*ngIf="!isPercent"
class="mb-0 value"
[ngClass]="{
'font-weight-bold h2': size === 'large',
h4: size === 'medium'
}"
>
@if (value === null) {
<span class="text-monospace text-muted">*****</span>
} @else {
{{ formattedValue }}
} }
</div> }
<small *ngIf="unit && size === 'medium'" class="ml-1"> @if (isPercent) {
{{ unit }} <div
</small> class="mb-0 value"
<div *ngIf="unit && size !== 'medium'" class="ml-1"> [ngClass]="{
{{ unit }} 'font-weight-bold h2': size === 'large',
</div> h4: size === 'medium'
</ng-container> }"
<ng-container *ngIf="isString"> >
@if (value === null) {
<span class="text-monospace text-muted">*****</span>%
} @else {
{{ formattedValue }}%
}
</div>
}
@if (!isPercent) {
<div
class="mb-0 value"
[ngClass]="{
'font-weight-bold h2': size === 'large',
h4: size === 'medium'
}"
>
@if (value === null) {
<span class="text-monospace text-muted">*****</span>
} @else {
{{ formattedValue }}
}
</div>
}
@if (unit && size === 'medium') {
<small class="ml-1">
{{ unit }}
</small>
}
@if (unit && size !== 'medium') {
<div class="ml-1">
{{ unit }}
</div>
}
}
@if (isString) {
<div <div
class="mb-0 text-truncate value" class="mb-0 text-truncate value"
[ngClass]="{ [ngClass]="{
@ -58,29 +70,36 @@
> >
{{ formattedValue }} {{ formattedValue }}
</div> </div>
</ng-container> }
</div> </div>
</ng-container> }
<ngx-skeleton-loader @if (value === undefined) {
*ngIf="value === undefined" <ngx-skeleton-loader
animation="pulse" animation="pulse"
[theme]="{ [theme]="{
height: height:
size === 'large' ? '2rem' : size === 'medium' ? '1.8rem' : '1.5rem', size === 'large' ? '2rem' : size === 'medium' ? '1.8rem' : '1.5rem',
width: '5rem' width: '5rem'
}" }"
/> />
}
<ng-container> <ng-container>
<div *ngIf="size === 'large'" class="text-truncate"> @if (size === 'large') {
<span class="h6" <div class="text-truncate">
><ng-container *ngTemplateOutlet="label"></ng-container <span class="h6"
></span> ><ng-container *ngTemplateOutlet="label"></ng-container
<span *ngIf="subLabel" class="text-muted"> {{ subLabel }}</span> ></span>
</div> @if (subLabel) {
<small *ngIf="size !== 'large'" class="d-block text-truncate"> <span class="text-muted"> {{ subLabel }}</span>
<ng-container *ngTemplateOutlet="label"></ng-container> }
</small> </div>
}
@if (size !== 'large') {
<small class="d-block text-truncate">
<ng-container *ngTemplateOutlet="label"></ng-container>
</small>
}
</ng-container> </ng-container>
</div> </div>

Loading…
Cancel
Save