You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
376 lines
11 KiB
376 lines
11 KiB
<form
|
|
class="d-flex flex-column h-100"
|
|
[formGroup]="assetProfileForm"
|
|
(keyup.enter)="assetProfileForm.valid && onSubmit()"
|
|
(ngSubmit)="onSubmit()"
|
|
>
|
|
<div class="d-flex mb-3">
|
|
<h1 class="flex-grow-1 m-0" mat-dialog-title>
|
|
{{ assetProfile?.name ?? data.symbol }}
|
|
</h1>
|
|
<button
|
|
class="mx-1 no-min-width px-2"
|
|
mat-button
|
|
type="button"
|
|
[matMenuTriggerFor]="assetProfileActionsMenu"
|
|
(click)="$event.stopPropagation()"
|
|
>
|
|
<ion-icon name="ellipsis-vertical" />
|
|
</button>
|
|
<mat-menu #assetProfileActionsMenu="matMenu" xPosition="before">
|
|
<button mat-menu-item type="button" (click)="initialize()">
|
|
<ng-container i18n>Refresh</ng-container>
|
|
</button>
|
|
<button
|
|
mat-menu-item
|
|
type="button"
|
|
[disabled]="assetProfileForm.dirty"
|
|
(click)="
|
|
onGatherSymbol({ dataSource: data.dataSource, symbol: data.symbol })
|
|
"
|
|
>
|
|
<ng-container i18n>Gather Historical Data</ng-container>
|
|
</button>
|
|
<button
|
|
mat-menu-item
|
|
type="button"
|
|
[disabled]="assetProfileForm.dirty"
|
|
(click)="
|
|
onGatherProfileDataBySymbol({
|
|
dataSource: data.dataSource,
|
|
symbol: data.symbol
|
|
})
|
|
"
|
|
>
|
|
<ng-container i18n>Gather Profile Data</ng-container>
|
|
</button>
|
|
<button
|
|
mat-menu-item
|
|
type="button"
|
|
[disabled]="
|
|
assetProfile?.activitiesCount !== 0 ||
|
|
isBenchmark ||
|
|
data.symbol.startsWith(ghostfolioScraperApiSymbolPrefix)
|
|
"
|
|
(click)="
|
|
onDeleteProfileData({
|
|
dataSource: data.dataSource,
|
|
symbol: data.symbol
|
|
})
|
|
"
|
|
>
|
|
<ng-container i18n>Delete</ng-container>
|
|
</button>
|
|
</mat-menu>
|
|
</div>
|
|
|
|
<div class="flex-grow-1" mat-dialog-content>
|
|
<gf-admin-market-data-detail
|
|
class="mb-3"
|
|
[currency]="assetProfile?.currency"
|
|
[dataSource]="data.dataSource"
|
|
[dateOfFirstActivity]="assetProfile?.dateOfFirstActivity"
|
|
[locale]="data.locale"
|
|
[marketData]="marketDataDetails"
|
|
[symbol]="data.symbol"
|
|
(marketDataChanged)="onMarketDataChanged($event)"
|
|
/>
|
|
|
|
<div class="mt-3" formGroupName="historicalData">
|
|
<mat-form-field appearance="outline" class="w-100 without-hint">
|
|
<mat-label>
|
|
<ng-container i18n>Historical Data</ng-container> (CSV)
|
|
</mat-label>
|
|
<textarea
|
|
cdkAutosizeMaxRows="5"
|
|
cdkTextareaAutosize
|
|
formControlName="csvString"
|
|
matInput
|
|
type="text"
|
|
(keyup.enter)="$event.stopPropagation()"
|
|
></textarea>
|
|
</mat-form-field>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-end mt-2">
|
|
<button
|
|
color="accent"
|
|
mat-flat-button
|
|
type="button"
|
|
[disabled]="
|
|
!assetProfileForm.controls['historicalData']?.controls['csvString']
|
|
.touched ||
|
|
assetProfileForm.controls['historicalData']?.controls['csvString']
|
|
?.value === ''
|
|
"
|
|
(click)="onImportHistoricalData()"
|
|
>
|
|
<ng-container i18n>Import</ng-container>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-6 mb-3">
|
|
<gf-value i18n size="medium" [value]="assetProfile?.symbol"
|
|
>Symbol</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value i18n size="medium" [value]="assetProfile?.currency"
|
|
>Currency</gf-value
|
|
>
|
|
</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 ?? 0"
|
|
>Activities</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[hidden]="!assetProfileClass"
|
|
[value]="assetProfileClass"
|
|
>Asset Class</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[hidden]="!assetProfileSubClass"
|
|
[value]="assetProfileSubClass"
|
|
>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">
|
|
<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"
|
|
[isInPercent]="true"
|
|
[keys]="['name']"
|
|
[maxItems]="10"
|
|
[positions]="sectors"
|
|
/>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<div class="h5" i18n>Countries</div>
|
|
<gf-portfolio-proportion-chart
|
|
[colorScheme]="data.colorScheme"
|
|
[isInPercent]="true"
|
|
[keys]="['name']"
|
|
[maxItems]="10"
|
|
[positions]="countries"
|
|
/>
|
|
</div>
|
|
}
|
|
}
|
|
</div>
|
|
<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" />
|
|
<mat-option
|
|
*ngFor="let assetClass of assetClasses"
|
|
[value]="assetClass.id"
|
|
>{{ assetClass.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" />
|
|
<mat-option
|
|
*ngFor="let assetSubClass of assetSubClasses"
|
|
[value]="assetSubClass.id"
|
|
>{{ assetSubClass.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"
|
|
(change)="
|
|
isBenchmark
|
|
? onUnsetBenchmark({
|
|
dataSource: data.dataSource,
|
|
symbol: data.symbol
|
|
})
|
|
: onSetBenchmark({
|
|
dataSource: data.dataSource,
|
|
symbol: data.symbol
|
|
})
|
|
"
|
|
>Benchmark</mat-checkbox
|
|
>
|
|
</div>
|
|
</div>
|
|
<div class="mt-3">
|
|
<mat-form-field appearance="outline" class="w-100">
|
|
<mat-label i18n>Symbol Mapping</mat-label>
|
|
<textarea
|
|
cdkTextareaAutosize
|
|
formControlName="symbolMapping"
|
|
matInput
|
|
type="text"
|
|
></textarea>
|
|
</mat-form-field>
|
|
</div>
|
|
@if (assetProfile?.dataSource === 'MANUAL') {
|
|
<div>
|
|
<mat-form-field appearance="outline" class="w-100">
|
|
<mat-label i18n>Scraper Configuration</mat-label>
|
|
<div class="align-items-end d-flex">
|
|
<textarea
|
|
cdkTextareaAutosize
|
|
formControlName="scraperConfiguration"
|
|
matInput
|
|
type="text"
|
|
(keyup.enter)="$event.stopPropagation()"
|
|
></textarea>
|
|
<button
|
|
color="accent"
|
|
mat-flat-button
|
|
type="button"
|
|
[disabled]="
|
|
assetProfileForm.get('scraperConfiguration').value === '{}'
|
|
"
|
|
(click)="onTestMarketData()"
|
|
>
|
|
<ng-container i18n>Test</ng-container>
|
|
</button>
|
|
</div>
|
|
</mat-form-field>
|
|
</div>
|
|
<div>
|
|
<mat-form-field appearance="outline" class="w-100">
|
|
<mat-label i18n>Sectors</mat-label>
|
|
<textarea
|
|
cdkTextareaAutosize
|
|
formControlName="sectors"
|
|
matInput
|
|
type="text"
|
|
></textarea>
|
|
</mat-form-field>
|
|
</div>
|
|
<div>
|
|
<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-asset-profile-icon
|
|
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>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-end" mat-dialog-actions>
|
|
<button i18n mat-button type="button" (click)="onClose()">Cancel</button>
|
|
<button
|
|
color="primary"
|
|
mat-flat-button
|
|
type="submit"
|
|
[disabled]="!(assetProfileForm.dirty && assetProfileForm.valid)"
|
|
>
|
|
<ng-container i18n>Save</ng-container>
|
|
</button>
|
|
</div>
|
|
</form>
|