diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index d77fde346..e709722dc 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -622,7 +622,9 @@ export class AdminService { assetClass: assetClass as AssetClass, assetSubClass: assetSubClass as AssetSubClass, name: name as string, - url: url as string + countries: countries as Prisma.JsonArray, + url: url as string, + sectors: sectors as Prisma.JsonArray }; const updatedSymbolProfile: Prisma.SymbolProfileUpdateInput = { diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index cbd8deba3..48b2eacd7 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -15,7 +15,10 @@ import { User } from '@ghostfolio/common/interfaces'; import { DateRange } from '@ghostfolio/common/types'; -import { validateObjectForForm } from '@ghostfolio/common/utils'; +import { + validateObjectForForm, + jsonValidator +} from '@ghostfolio/common/utils/form.util'; import { GfCurrencySelectorComponent } from '@ghostfolio/ui/currency-selector'; import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo'; import { GfHistoricalMarketDataEditorComponent } from '@ghostfolio/ui/historical-market-data-editor'; @@ -145,7 +148,7 @@ export class GfAssetProfileDialogComponent implements OnDestroy, OnInit { assetClass: new FormControl(undefined), assetSubClass: new FormControl(undefined), comment: '', - countries: '', + countries: ['', jsonValidator()], currency: '', historicalData: this.formBuilder.group({ csvString: '' @@ -154,14 +157,14 @@ export class GfAssetProfileDialogComponent implements OnDestroy, OnInit { name: ['', Validators.required], scraperConfiguration: this.formBuilder.group({ defaultMarketPrice: null, - headers: JSON.stringify({}), + headers: [JSON.stringify({}), jsonValidator()], locale: '', mode: '', selector: '', url: '' }), - sectors: '', - symbolMapping: '', + sectors: ['', jsonValidator()], + symbolMapping: ['', jsonValidator()], url: '' }); diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html index a60e10edc..9d2a22c0d 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -391,29 +391,151 @@ @if (assetProfile?.dataSource === 'MANUAL') { -
- - Sectors - - -
-
- - Countries - - +
+ + + + Scraper Configuration + +
+
+ + Default Market Price + + +
+
+ + HTTP Request Headers + + +
+
+ + Locale + + +
+
+ + Mode + + @for (modeValue of modeValues; track modeValue) { + {{ + modeValue.viewValue + }} + } + + +
+
+ + + Selector* + + + +
+
+ + + Url* + + + +
+
+ +
+
+
+
} +
+ + Sectors + + +
+
+ + Countries + + +
Url diff --git a/libs/common/src/lib/utils/form.util.ts b/libs/common/src/lib/utils/form.util.ts index b510e6215..09c9860ed 100644 --- a/libs/common/src/lib/utils/form.util.ts +++ b/libs/common/src/lib/utils/form.util.ts @@ -1,3 +1,4 @@ +import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms'; import { FormGroup } from '@angular/forms'; import { plainToInstance } from 'class-transformer'; import { validate } from 'class-validator'; @@ -44,3 +45,17 @@ export async function validateObjectForForm({ return Promise.reject(nonIgnoredErrors); } + +export function jsonValidator(): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + if (!control.value) { + return null; + } + + try { + JSON.parse(control.value); + } catch { + return { invalidJson: true }; + } + }; +}