Browse Source

Feature/introduce tabs in asset profile dialog (#5693)

* Introduce tabs in asset profile dialog

* Update changelog
pull/5704/head
Bence Hornyák 1 week ago
committed by GitHub
parent
commit
0e43bb048a
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 11
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts
  3. 884
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html

1
CHANGELOG.md

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Added support to edit a granted access (experimental) - Added support to edit a granted access (experimental)
- Introduced tabs to the asset profile details dialog in the admin control panel
- Added support for a date range query parameter in the data gathering endpoint - Added support for a date range query parameter in the data gathering endpoint
- Added a _Storybook_ story for the activities table component - Added a _Storybook_ story for the activities table component

11
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts

@ -65,6 +65,7 @@ import { MatInputModule } from '@angular/material/input';
import { MatMenuModule } from '@angular/material/menu'; import { MatMenuModule } from '@angular/material/menu';
import { MatSelectModule } from '@angular/material/select'; import { MatSelectModule } from '@angular/material/select';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
import { MatTabsModule } from '@angular/material/tabs';
import { IonIcon } from '@ionic/angular/standalone'; import { IonIcon } from '@ionic/angular/standalone';
import { import {
AssetClass, AssetClass,
@ -77,7 +78,12 @@ import { isUUID } from 'class-validator';
import { format } from 'date-fns'; import { format } from 'date-fns';
import { StatusCodes } from 'http-status-codes'; import { StatusCodes } from 'http-status-codes';
import { addIcons } from 'ionicons'; import { addIcons } from 'ionicons';
import { createOutline, ellipsisVertical } from 'ionicons/icons'; import {
createOutline,
ellipsisVertical,
readerOutline,
serverOutline
} from 'ionicons/icons';
import ms from 'ms'; import ms from 'ms';
import { EMPTY, Subject } from 'rxjs'; import { EMPTY, Subject } from 'rxjs';
import { catchError, takeUntil } from 'rxjs/operators'; import { catchError, takeUntil } from 'rxjs/operators';
@ -106,6 +112,7 @@ import { AssetProfileDialogParams } from './interfaces/interfaces';
MatMenuModule, MatMenuModule,
MatSelectModule, MatSelectModule,
MatSnackBarModule, MatSnackBarModule,
MatTabsModule,
ReactiveFormsModule, ReactiveFormsModule,
TextFieldModule TextFieldModule
], ],
@ -223,7 +230,7 @@ export class GfAssetProfileDialogComponent implements OnDestroy, OnInit {
private snackBar: MatSnackBar, private snackBar: MatSnackBar,
private userService: UserService private userService: UserService
) { ) {
addIcons({ createOutline, ellipsisVertical }); addIcons({ createOutline, ellipsisVertical, readerOutline, serverOutline });
} }
public get canEditAssetProfileIdentifier() { public get canEditAssetProfileIdentifier() {

884
apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html

@ -79,463 +79,485 @@
[showXAxis]="true" [showXAxis]="true"
[showYAxis]="true" [showYAxis]="true"
/> />
<div class="mb-3">
<mat-accordion class="my-3">
<mat-expansion-panel class="shadow-none">
<mat-expansion-panel-header class="p-0 pr-3">
<mat-panel-title class="font-weight-bold" i18n
>Historical Market Data</mat-panel-title
>
</mat-expansion-panel-header>
<gf-historical-market-data-editor <mat-tab-group
class="mb-3" animationDuration="0ms"
[currency]="assetProfile?.currency" [dynamicHeight]="true"
[dataSource]="data.dataSource" [mat-stretch-tabs]="false"
[dateOfFirstActivity]="assetProfile?.dateOfFirstActivity" >
[locale]="data.locale" <mat-tab>
[marketData]="marketDataItems" <ng-template mat-tab-label>
[symbol]="data.symbol" <ion-icon name="reader-outline" />
[user]="user" <div class="d-none d-sm-block ml-2" i18n>Overview</div>
(marketDataChanged)="onMarketDataChanged($event)" </ng-template>
/> <div class="container mt-3 p-0">
</mat-expansion-panel> <div class="row w-100">
</mat-accordion> @if (isEditAssetProfileIdentifierMode) {
</div> <div class="col-12 mb-4">
<form
<div class="row"> class="align-items-center d-flex"
@if (isEditAssetProfileIdentifierMode) { [formGroup]="assetProfileIdentifierForm"
<div class="col-12 mb-4"> (keyup.enter)="
<form assetProfileIdentifierForm.valid &&
class="align-items-center d-flex" onSubmitAssetProfileIdentifierForm()
[formGroup]="assetProfileIdentifierForm" "
(keyup.enter)=" (ngSubmit)="onSubmitAssetProfileIdentifierForm()"
assetProfileIdentifierForm.valid && >
onSubmitAssetProfileIdentifierForm() <mat-form-field
" appearance="outline"
(ngSubmit)="onSubmitAssetProfileIdentifierForm()" class="gf-spacer without-hint"
> >
<mat-form-field appearance="outline" class="gf-spacer without-hint"> <mat-label i18n>Name, symbol or ISIN</mat-label>
<mat-label i18n>Name, symbol or ISIN</mat-label> <gf-symbol-autocomplete
<gf-symbol-autocomplete formControlName="assetProfileIdentifier"
formControlName="assetProfileIdentifier" [includeIndices]="true"
[includeIndices]="true" />
/> </mat-form-field>
</mat-form-field> <button
<button class="ml-2 no-min-width px-2"
class="ml-2 no-min-width px-2" color="primary"
color="primary" mat-flat-button
mat-flat-button type="submit"
type="submit" [disabled]="
[disabled]=" assetProfileIdentifierForm.hasError(
assetProfileIdentifierForm.hasError( 'invalidData',
'invalidData', 'assetProfileIdentifier'
'assetProfileIdentifier' ) ||
) || assetProfileIdentifierForm.hasError(
assetProfileIdentifierForm.hasError( 'equalsPreviousProfileIdentifier'
'equalsPreviousProfileIdentifier' )
) "
" >
> <ng-container i18n>Apply</ng-container>
<ng-container i18n>Apply</ng-container> </button>
</button> <button
<button class="ml-2 no-min-width px-2"
class="ml-2 no-min-width px-2" mat-button
mat-button type="button"
type="button" (click)="onCancelEditAssetProfileIdentifierMode()"
(click)="onCancelEditAssetProfileIdentifierMode()" >
> <ng-container i18n>Cancel</ng-container>
<ng-container i18n>Cancel</ng-container> </button>
</button> </form>
</form> </div>
</div> } @else {
} @else { <div class="col-6 mb-3">
<div class="col-6 mb-3"> <gf-value i18n size="medium" [value]="assetProfile?.symbol"
<gf-value i18n size="medium" [value]="assetProfile?.symbol" >Symbol</gf-value
>Symbol</gf-value >
> </div>
</div> <div class="col-6 mb-3">
<div class="col-6 mb-3"> <gf-value
<gf-value i18n
i18n size="medium"
size="medium" [value]="
[value]=" assetProfile?.dataProviderInfo?.name ??
assetProfile?.dataProviderInfo?.name ?? assetProfile?.dataSource assetProfile?.dataSource
" "
>Data Source</gf-value >Data Source</gf-value
> >
<div <div
class="edit-asset-profile-identifier-container position-absolute" class="edit-asset-profile-identifier-container position-absolute"
> >
<button <button
class="h-100 no-min-width px-2" class="h-100 no-min-width px-2"
mat-button mat-button
type="button" type="button"
[disabled]="!canSaveAssetProfileIdentifier" [disabled]="!canSaveAssetProfileIdentifier"
[ngClass]="{ [ngClass]="{
'd-none': !canEditAssetProfileIdentifier 'd-none': !canEditAssetProfileIdentifier
}" }"
(click)="onSetEditAssetProfileIdentifierMode()" (click)="onSetEditAssetProfileIdentifierMode()"
> >
<ion-icon name="create-outline" /> <ion-icon name="create-outline" />
</button> </button>
</div> </div>
</div> </div>
} }
<div class="col-6 mb-3"> <div class="col-6 mb-3">
<gf-value i18n size="medium" [value]="assetProfile?.currency" <gf-value i18n size="medium" [value]="assetProfile?.currency"
>Currency</gf-value >Currency</gf-value
> >
</div> </div>
<div class="col-6 mb-3"></div> <div class="col-6 mb-3"></div>
<div class="col-6 mb-3">
<gf-value
i18n
size="medium"
[isDate]="assetProfile?.dateOfFirstActivity ? true : false"
[locale]="data.locale"
[value]="assetProfile?.dateOfFirstActivity ?? '-'"
>First Activity</gf-value
>
</div>
<div class="col-6 mb-3">
<gf-value
i18n
size="medium"
[locale]="data.locale"
[value]="assetProfile?.activitiesCount"
>Activities</gf-value
>
</div>
<div class="col-6 mb-3">
<gf-value
i18n
size="medium"
[hidden]="!assetClassLabel"
[value]="assetClassLabel"
>Asset Class</gf-value
>
</div>
<div class="col-6 mb-3">
<gf-value
i18n
size="medium"
[hidden]="!assetSubClassLabel"
[value]="assetSubClassLabel"
>Asset Sub Class</gf-value
>
</div>
@if (
assetProfile?.countries?.length > 0 || assetProfile?.sectors?.length > 0
) {
@if (
assetProfile?.countries?.length === 1 &&
assetProfile?.sectors?.length === 1
) {
@if (assetProfile?.sectors?.length === 1) {
<div class="col-6 mb-3"> <div class="col-6 mb-3">
<gf-value <gf-value
i18n i18n
size="medium" size="medium"
[isDate]="assetProfile?.dateOfFirstActivity ? true : false"
[locale]="data.locale" [locale]="data.locale"
[value]="assetProfile?.sectors[0].name" [value]="assetProfile?.dateOfFirstActivity ?? '-'"
>Sector</gf-value >First Activity</gf-value
> >
</div> </div>
}
@if (assetProfile?.countries?.length === 1) {
<div class="col-6 mb-3"> <div class="col-6 mb-3">
<gf-value <gf-value
i18n i18n
size="medium" size="medium"
[locale]="data.locale" [locale]="data.locale"
[value]="assetProfile?.countries[0].name" [value]="assetProfile?.activitiesCount"
>Country</gf-value >Activities</gf-value
> >
</div> </div>
} <div class="col-6 mb-3">
} @else { <gf-value
<div class="col-md-6 mb-3"> i18n
<div class="h5" i18n>Sectors</div> size="medium"
<gf-portfolio-proportion-chart [hidden]="!assetClassLabel"
[colorScheme]="data.colorScheme" [value]="assetClassLabel"
[data]="sectors" >Asset Class</gf-value
[isInPercent]="true" >
[keys]="['name']" </div>
[maxItems]="10" <div class="col-6 mb-3">
/> <gf-value
</div> i18n
<div class="col-md-6 mb-3"> size="medium"
<div class="h5" i18n>Countries</div> [hidden]="!assetSubClassLabel"
<gf-portfolio-proportion-chart [value]="assetSubClassLabel"
[colorScheme]="data.colorScheme" >Asset Sub Class</gf-value
[data]="countries" >
[isInPercent]="true" </div>
[keys]="['name']" @if (
[maxItems]="10" assetProfile?.countries?.length > 0 ||
/> assetProfile?.sectors?.length > 0
</div>
}
}
</div>
<form
#assetProfileFormElement
[formGroup]="assetProfileForm"
(keyup.enter)="assetProfileForm.valid && onSubmitAssetProfileForm()"
(ngSubmit)="onSubmitAssetProfileForm()"
>
<div class="mt-3">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-label i18n>Name</mat-label>
<input formControlName="name" matInput type="text" />
</mat-form-field>
</div>
@if (assetProfile?.dataSource === 'MANUAL') {
<div class="mt-3">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-label i18n>Currency</mat-label>
<gf-currency-selector
formControlName="currency"
[currencies]="currencies"
/>
</mat-form-field>
</div>
}
<div class="mt-3">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-label i18n>Asset Class</mat-label>
<mat-select formControlName="assetClass">
<mat-option [value]="null" />
@for (
assetClassOption of assetClassOptions;
track assetClassOption.id
) {
<mat-option [value]="assetClassOption.id">{{
assetClassOption.label
}}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-label i18n>Asset Sub Class</mat-label>
<mat-select formControlName="assetSubClass">
<mat-option [value]="null" />
@for (
assetSubClassOption of assetSubClassOptions;
track assetSubClassOption.id
) { ) {
<mat-option [value]="assetSubClassOption.id">{{ @if (
assetSubClassOption.label assetProfile?.countries?.length === 1 &&
}}</mat-option> assetProfile?.sectors?.length === 1
) {
@if (assetProfile?.sectors?.length === 1) {
<div class="col-6 mb-3">
<gf-value
i18n
size="medium"
[locale]="data.locale"
[value]="assetProfile?.sectors[0].name"
>Sector</gf-value
>
</div>
}
@if (assetProfile?.countries?.length === 1) {
<div class="col-6 mb-3">
<gf-value
i18n
size="medium"
[locale]="data.locale"
[value]="assetProfile?.countries[0].name"
>Country</gf-value
>
</div>
}
} @else {
<div class="col-md-6 mb-3">
<div class="h5" i18n>Sectors</div>
<gf-portfolio-proportion-chart
[colorScheme]="data.colorScheme"
[data]="sectors"
[isInPercent]="true"
[keys]="['name']"
[maxItems]="10"
/>
</div>
<div class="col-md-6 mb-3">
<div class="h5" i18n>Countries</div>
<gf-portfolio-proportion-chart
[colorScheme]="data.colorScheme"
[data]="countries"
[isInPercent]="true"
[keys]="['name']"
[maxItems]="10"
/>
</div>
}
} }
</mat-select> </div>
</mat-form-field> <form
</div> #assetProfileFormElement
<div class="d-flex my-3"> [formGroup]="assetProfileForm"
<div class="w-50"> (keyup.enter)="assetProfileForm.valid && onSubmitAssetProfileForm()"
<mat-checkbox (ngSubmit)="onSubmitAssetProfileForm()"
color="primary"
i18n
[checked]="isBenchmark"
[disabled]="isEditAssetProfileIdentifierMode"
(change)="
isBenchmark
? onUnsetBenchmark({
dataSource: data.dataSource,
symbol: data.symbol
})
: onSetBenchmark({
dataSource: data.dataSource,
symbol: data.symbol
})
"
>Benchmark</mat-checkbox
> >
</div> <div class="mt-3">
</div> <mat-form-field appearance="outline" class="w-100 without-hint">
<div class="mt-3"> <mat-label i18n>Name</mat-label>
<mat-form-field appearance="outline" class="w-100"> <input formControlName="name" matInput type="text" />
<mat-label i18n>Symbol Mapping</mat-label> </mat-form-field>
<textarea </div>
cdkTextareaAutosize @if (assetProfile?.dataSource === 'MANUAL') {
formControlName="symbolMapping" <div class="mt-3">
matInput <mat-form-field appearance="outline" class="w-100 without-hint">
type="text" <mat-label i18n>Currency</mat-label>
></textarea> <gf-currency-selector
</mat-form-field> formControlName="currency"
</div> [currencies]="currencies"
@if (assetProfile?.dataSource === 'MANUAL') { />
<div class="mb-3"> </mat-form-field>
<mat-accordion class="my-3"> </div>
<mat-expansion-panel }
class="shadow-none" <div class="mt-3">
[expanded]=" <mat-form-field appearance="outline" class="w-100 without-hint">
assetProfileForm.controls.scraperConfiguration.controls.selector <mat-label i18n>Asset Class</mat-label>
.value !== '' && <mat-select formControlName="assetClass">
assetProfileForm.controls.scraperConfiguration.controls.url <mat-option [value]="null" />
.value !== '' @for (
" assetClassOption of assetClassOptions;
(closed)="scraperConfiguationIsExpanded.set(false)" track assetClassOption.id
(opened)="scraperConfiguationIsExpanded.set(true)" ) {
> <mat-option [value]="assetClassOption.id">{{
<mat-expansion-panel-header class="p-0 pr-3"> assetClassOption.label
<mat-panel-title class="font-weight-bold" i18n }}</mat-option>
>Scraper Configuration</mat-panel-title }
</mat-select>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-label i18n>Asset Sub Class</mat-label>
<mat-select formControlName="assetSubClass">
<mat-option [value]="null" />
@for (
assetSubClassOption of assetSubClassOptions;
track assetSubClassOption.id
) {
<mat-option [value]="assetSubClassOption.id">{{
assetSubClassOption.label
}}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
<div class="d-flex my-3">
<div class="w-50">
<mat-checkbox
color="primary"
i18n
[checked]="isBenchmark"
[disabled]="isEditAssetProfileIdentifierMode"
(change)="
isBenchmark
? onUnsetBenchmark({
dataSource: data.dataSource,
symbol: data.symbol
})
: onSetBenchmark({
dataSource: data.dataSource,
symbol: data.symbol
})
"
>Benchmark</mat-checkbox
> >
</mat-expansion-panel-header> </div>
<div formGroupName="scraperConfiguration"> </div>
<div class="mt-3"> <div class="mt-3">
<mat-form-field <mat-form-field appearance="outline" class="w-100">
appearance="outline" <mat-label i18n>Symbol Mapping</mat-label>
class="w-100 without-hint" <textarea
> cdkTextareaAutosize
<mat-label i18n>Default Market Price</mat-label> formControlName="symbolMapping"
<input matInput
formControlName="defaultMarketPrice" type="text"
matInput ></textarea>
type="number" </mat-form-field>
/> </div>
</mat-form-field> @if (assetProfile?.dataSource === 'MANUAL') {
</div> <div class="mb-3">
<div class="mt-3"> <mat-accordion class="my-3">
<mat-form-field <mat-expansion-panel
appearance="outline" class="shadow-none"
class="w-100 without-hint" [expanded]="
>
<mat-label i18n>HTTP Request Headers</mat-label>
<textarea
cdkTextareaAutosize
formControlName="headers"
matInput
type="text"
[matAutocomplete]="auto"
></textarea>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field
appearance="outline"
class="w-100 without-hint"
>
<mat-label i18n>Locale</mat-label>
<input formControlName="locale" matInput type="text" />
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field
appearance="outline"
class="w-100 without-hint"
>
<mat-label i18n>Mode</mat-label>
<mat-select formControlName="mode">
@for (modeValue of modeValues; track modeValue) {
<mat-option [value]="modeValue.value">{{
modeValue.viewValue
}}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field
appearance="outline"
class="w-100 without-hint"
>
<mat-label>
<ng-container i18n>Selector</ng-container>*
</mat-label>
<textarea
cdkTextareaAutosize
formControlName="selector"
matInput
type="text"
></textarea>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field
appearance="outline"
class="w-100 without-hint"
>
<mat-label>
<ng-container i18n>Url</ng-container>*
</mat-label>
<input formControlName="url" matInput type="text" />
</mat-form-field>
</div>
<div class="my-3 text-right">
<button
color="accent"
mat-flat-button
type="button"
[disabled]="
assetProfileForm.controls.scraperConfiguration.controls assetProfileForm.controls.scraperConfiguration.controls
.selector.value === '' || .selector.value !== '' &&
assetProfileForm.controls.scraperConfiguration.controls assetProfileForm.controls.scraperConfiguration.controls
.url.value === '' .url.value !== ''
" "
(click)="onTestMarketData()" (closed)="scraperConfiguationIsExpanded.set(false)"
(opened)="scraperConfiguationIsExpanded.set(true)"
> >
<ng-container i18n>Test</ng-container> <mat-expansion-panel-header class="p-0 pr-3">
</button> <mat-panel-title class="font-weight-bold" i18n
</div> >Scraper Configuration</mat-panel-title
>
</mat-expansion-panel-header>
<div formGroupName="scraperConfiguration">
<div class="mt-3">
<mat-form-field
appearance="outline"
class="w-100 without-hint"
>
<mat-label i18n>Default Market Price</mat-label>
<input
formControlName="defaultMarketPrice"
matInput
type="number"
/>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field
appearance="outline"
class="w-100 without-hint"
>
<mat-label i18n>HTTP Request Headers</mat-label>
<textarea
cdkTextareaAutosize
formControlName="headers"
matInput
type="text"
[matAutocomplete]="auto"
></textarea>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field
appearance="outline"
class="w-100 without-hint"
>
<mat-label i18n>Locale</mat-label>
<input
formControlName="locale"
matInput
type="text"
/>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field
appearance="outline"
class="w-100 without-hint"
>
<mat-label i18n>Mode</mat-label>
<mat-select formControlName="mode">
@for (modeValue of modeValues; track modeValue) {
<mat-option [value]="modeValue.value">{{
modeValue.viewValue
}}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field
appearance="outline"
class="w-100 without-hint"
>
<mat-label>
<ng-container i18n>Selector</ng-container>*
</mat-label>
<textarea
cdkTextareaAutosize
formControlName="selector"
matInput
type="text"
></textarea>
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field
appearance="outline"
class="w-100 without-hint"
>
<mat-label>
<ng-container i18n>Url</ng-container>*
</mat-label>
<input formControlName="url" matInput type="text" />
</mat-form-field>
</div>
<div class="my-3 text-right">
<button
color="accent"
mat-flat-button
type="button"
[disabled]="
assetProfileForm.controls.scraperConfiguration
.controls.selector.value === '' ||
assetProfileForm.controls.scraperConfiguration
.controls.url.value === ''
"
(click)="onTestMarketData()"
>
<ng-container i18n>Test</ng-container>
</button>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
</div> </div>
</mat-expansion-panel> }
</mat-accordion> @if (assetProfile?.dataSource === 'MANUAL') {
</div> <div>
} <mat-form-field appearance="outline" class="w-100">
@if (assetProfile?.dataSource === 'MANUAL') { <mat-label i18n>Sectors</mat-label>
<div> <textarea
<mat-form-field appearance="outline" class="w-100"> cdkTextareaAutosize
<mat-label i18n>Sectors</mat-label> formControlName="sectors"
<textarea matInput
cdkTextareaAutosize type="text"
formControlName="sectors" ></textarea>
matInput </mat-form-field>
type="text" </div>
></textarea> <div>
</mat-form-field> <mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Countries</mat-label>
<textarea
cdkTextareaAutosize
formControlName="countries"
matInput
type="text"
></textarea>
</mat-form-field>
</div>
}
<div>
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-label i18n>Url</mat-label>
<input formControlName="url" matInput type="text" />
@if (assetProfileForm.get('url').value) {
<gf-entity-logo
class="mr-3"
matSuffix
[url]="assetProfileForm.get('url').value"
/>
}
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Note</mat-label>
<textarea
cdkAutosizeMinRows="2"
cdkTextareaAutosize
formControlName="comment"
matInput
(keyup.enter)="$event.stopPropagation()"
></textarea>
</mat-form-field>
</div>
</form>
</div> </div>
<div> </mat-tab>
<mat-form-field appearance="outline" class="w-100"> <mat-tab>
<mat-label i18n>Countries</mat-label> <ng-template mat-tab-label>
<textarea <ion-icon name="server-outline" />
cdkTextareaAutosize <div class="d-none d-sm-block ml-2" i18n>Historical Market Data</div>
formControlName="countries" </ng-template>
matInput <div class="container mt-3 p-0">
type="text" <div class="no-gutters row w-100">
></textarea> <div class="col-12">
</mat-form-field> <gf-historical-market-data-editor
[currency]="assetProfile?.currency"
[dataSource]="data.dataSource"
[dateOfFirstActivity]="assetProfile?.dateOfFirstActivity"
[locale]="data.locale"
[marketData]="marketDataItems"
[symbol]="data.symbol"
[user]="user"
(marketDataChanged)="onMarketDataChanged($event)"
/>
</div>
</div>
</div> </div>
} </mat-tab>
<div> </mat-tab-group>
<mat-form-field appearance="outline" class="w-100 without-hint">
<mat-label i18n>Url</mat-label>
<input formControlName="url" matInput type="text" />
@if (assetProfileForm.get('url').value) {
<gf-entity-logo
class="mr-3"
matSuffix
[url]="assetProfileForm.get('url').value"
/>
}
</mat-form-field>
</div>
<div class="mt-3">
<mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Note</mat-label>
<textarea
cdkAutosizeMinRows="2"
cdkTextareaAutosize
formControlName="comment"
matInput
(keyup.enter)="$event.stopPropagation()"
></textarea>
</mat-form-field>
</div>
</form>
</div> </div>
<div class="d-flex" mat-dialog-actions> <div class="d-flex" mat-dialog-actions>

Loading…
Cancel
Save