Browse Source

feat: implements frontend logic

pull/4469/head
tobikugel 1 month ago
committed by Thomas Kaul
parent
commit
d3fe2c0720
  1. 9
      apps/api/src/app/admin/admin.controller.ts
  2. 37
      apps/api/src/app/admin/admin.service.ts
  3. 52
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts
  4. 54
      apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html
  5. 34
      apps/client/src/app/services/admin.service.ts

9
apps/api/src/app/admin/admin.controller.ts

@ -338,12 +338,9 @@ export class AdminController {
@Param('dataSource') dataSource: DataSource, @Param('dataSource') dataSource: DataSource,
@Param('symbol') symbol: string @Param('symbol') symbol: string
): Promise<EnhancedSymbolProfile> { ): Promise<EnhancedSymbolProfile> {
return this.adminService.patchAssetProfileData( return this.adminService.patchAssetProfileData(dataSource, symbol, {
{ dataSource, symbol }, ...assetProfileData
{ });
...assetProfileData
}
);
} }
@HasPermission(permissions.accessAdminControl) @HasPermission(permissions.accessAdminControl)

37
apps/api/src/app/admin/admin.service.ts

@ -464,42 +464,48 @@ export class AdminService {
} }
public async patchAssetProfileData( public async patchAssetProfileData(
assetProfileIdentifier: AssetProfileIdentifier, dataSource: DataSource,
symbol: string,
{ {
assetClass, assetClass,
assetSubClass, assetSubClass,
comment, comment,
countries, countries,
currency, currency,
dataSource, dataSource: newDataSource,
holdings, holdings,
name, name,
scraperConfiguration, scraperConfiguration,
sectors, sectors,
symbol, symbol: newSymbol,
symbolMapping, symbolMapping,
url url
}: Prisma.SymbolProfileUpdateInput }: Prisma.SymbolProfileUpdateInput
) { ) {
if ( if (
symbol && newSymbol &&
dataSource && newDataSource &&
assetProfileIdentifier.symbol !== symbol && (newSymbol !== symbol || newDataSource !== dataSource)
assetProfileIdentifier.dataSource !== dataSource
) { ) {
await this.symbolProfileService.updateAssetProfileIdentifier( await this.symbolProfileService.updateAssetProfileIdentifier(
assetProfileIdentifier,
{ {
dataSource: dataSource as DataSource, // TODO change dataSource,
symbol: symbol as string symbol
},
{
dataSource: newDataSource as DataSource,
symbol: newSymbol as string
} }
); );
await this.marketDataService.updateAssetProfileIdentifier( await this.marketDataService.updateAssetProfileIdentifier(
assetProfileIdentifier,
{ {
dataSource: dataSource as DataSource, dataSource,
symbol: symbol as string symbol
},
{
dataSource: newDataSource as DataSource,
symbol: newSymbol as string
} }
); );
@ -544,7 +550,10 @@ export class AdminService {
}; };
await this.symbolProfileService.updateSymbolProfile( await this.symbolProfileService.updateSymbolProfile(
assetProfileIdentifier, {
dataSource,
symbol
},
updatedSymbolProfile updatedSymbolProfile
); );

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

@ -55,7 +55,12 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
return { id: assetSubClass, label: translate(assetSubClass) }; return { id: assetSubClass, label: translate(assetSubClass) };
}); });
public assetProfile: AdminMarketDataDetails['assetProfile']; public assetProfile: AdminMarketDataDetails['assetProfile'];
public assetProfileIdentifierForm; public assetProfileIdentifierForm = this.formBuilder.group({
editedSearchSymbol: new FormControl<AssetProfileIdentifier>(
{ symbol: null, dataSource: null },
[Validators.required]
)
});
public assetProfileForm = this.formBuilder.group({ public assetProfileForm = this.formBuilder.group({
assetClass: new FormControl<AssetClass>(undefined), assetClass: new FormControl<AssetClass>(undefined),
assetSubClass: new FormControl<AssetSubClass>(undefined), assetSubClass: new FormControl<AssetSubClass>(undefined),
@ -225,6 +230,14 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
}); });
} }
public get isSymbolEditable() {
return !this.assetProfileForm.dirty;
}
public get isSymbolEditButtonInvisible() {
return this.assetProfile?.dataSource === 'MANUAL';
}
public onClose() { public onClose() {
this.dialogRef.close(); this.dialogRef.close();
} }
@ -284,9 +297,40 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
this.assetProfileForm.enable(); this.assetProfileForm.enable();
this.assetProfileIdentifierForm.reset();
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
} }
public async onSubmitAssetProfileIdentifierForm() {
const assetProfileIdentifierData: UpdateAssetProfileDto = {
dataSource:
this.assetProfileIdentifierForm.get('editedSearchSymbol').value
.dataSource,
symbol:
this.assetProfileIdentifierForm.get('editedSearchSymbol').value.symbol
};
try {
await validateObjectForForm({
classDto: UpdateAssetProfileDto,
form: this.assetProfileIdentifierForm,
object: assetProfileIdentifierData
});
} catch (error) {
console.error(error);
return;
}
this.adminService
.patchAssetProfile(this.data.dataSource, this.data.symbol, {
...assetProfileIdentifierData
})
.subscribe(() => {
this.initialize();
});
}
public async onSubmitAssetProfileForm() { public async onSubmitAssetProfileForm() {
let countries = []; let countries = [];
let scraperConfiguration = {}; let scraperConfiguration = {};
@ -360,10 +404,8 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
} }
this.adminService this.adminService
.patchAssetProfile({ .patchAssetProfile(this.data.dataSource, this.data.symbol, {
...assetProfileData, ...assetProfileData
dataSource: this.data.dataSource,
symbol: this.data.symbol
}) })
.subscribe(() => { .subscribe(() => {
this.initialize(); this.initialize();

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

@ -88,24 +88,39 @@
<div class="row"> <div class="row">
@if (isEditSymbolMode) { @if (isEditSymbolMode) {
<div class="col-12 mb-3"> <div class="col-12 mb-3">
<mat-form-field appearance="outline"> <form
<mat-label i18n>Name, symbol or ISIN</mat-label> [formGroup]="assetProfileIdentifierForm"
<gf-symbol-autocomplete (keyup.enter)="
formControlName="searchSymbol" assetProfileIdentifierForm.valid &&
[includeIndices]="true" onSubmitAssetProfileIdentifierForm()
/> "
</mat-form-field> (ngSubmit)="onSubmitAssetProfileIdentifierForm()"
<button class="mx-1 no-min-width px-2" mat-button type="button">
Apply
</button>
<button
class="mx-1 no-min-width px-2"
mat-button
type="button"
(click)="onCancelEditSymboleMode()"
> >
Cancel <mat-form-field appearance="outline">
</button> <mat-label i18n>Name, symbol or ISIN</mat-label>
<gf-symbol-autocomplete
formControlName="editedSearchSymbol"
[includeIndices]="true"
/>
</mat-form-field>
<button
class="mx-1 no-min-width px-2"
color="primary"
mat-flat-button
type="submit"
[disabled]="!assetProfileIdentifierForm.valid"
>
Apply
</button>
<button
class="mx-1 no-min-width px-2"
mat-button
type="button"
(click)="onCancelEditSymboleMode()"
>
Cancel
</button>
</form>
</div> </div>
} @else { } @else {
<div class="col-6 mb-3"> <div class="col-6 mb-3">
@ -128,7 +143,10 @@
class="mx-1 no-min-width px-2" class="mx-1 no-min-width px-2"
mat-button mat-button
type="button" type="button"
[disabled]="assetProfileForm.dirty" [disabled]="!isSymbolEditable"
[ngClass]="{
'd-none': isSymbolEditButtonInvisible
}"
(click)="onSetEditSymboleMode()" (click)="onSetEditSymboleMode()"
> >
<ion-icon name="create-outline"></ion-icon> <ion-icon name="create-outline"></ion-icon>

34
apps/client/src/app/services/admin.service.ts

@ -203,20 +203,24 @@ export class AdminService {
return this.http.get<IDataProviderHistoricalResponse>(url); return this.http.get<IDataProviderHistoricalResponse>(url);
} }
public patchAssetProfile({ public patchAssetProfile(
assetClass, dataSource: DataSource,
assetSubClass, symbol: string,
comment, {
countries, assetClass,
currency, assetSubClass,
dataSource, comment,
name, countries,
scraperConfiguration, currency,
sectors, dataSource: newDataSource,
symbol, name,
symbolMapping, scraperConfiguration,
url sectors,
}: AssetProfileIdentifier & UpdateAssetProfileDto) { symbol: newSymbol,
symbolMapping,
url
}: UpdateAssetProfileDto
) {
return this.http.patch<EnhancedSymbolProfile>( return this.http.patch<EnhancedSymbolProfile>(
`/api/v1/admin/profile-data/${dataSource}/${symbol}`, `/api/v1/admin/profile-data/${dataSource}/${symbol}`,
{ {
@ -226,6 +230,8 @@ export class AdminService {
countries, countries,
currency, currency,
name, name,
newDataSource,
newSymbol,
scraperConfiguration, scraperConfiguration,
sectors, sectors,
symbolMapping, symbolMapping,

Loading…
Cancel
Save