From 69b00a7a266321c3b304aa260de219e6126704d9 Mon Sep 17 00:00:00 2001 From: amentis Date: Mon, 26 Feb 2024 19:40:31 +0200 Subject: [PATCH 1/9] add prefilling source frontend --- dmp-frontend/src/app/app-routing.module.ts | 12 + .../external-fetcher-api-http-method-type.ts | 4 + .../enum/external-fetcher-source-type.ts | 4 + .../app/core/common/enum/permission.enum.ts | 6 + ...ence-type-external-api-http-method-type.ts | 4 - .../common/enum/reference-type-source-type.ts | 4 - .../src/app/core/core-service.module.ts | 4 +- .../external-fetcher/external-fetcher.ts | 136 ++++ .../prefilling-source/prefilling-source.ts | 43 ++ .../model/reference-type/reference-type.ts | 135 +--- .../core/query/prefilling-source.lookup.ts | 21 + .../prefilling-source.service.ts | 97 +++ .../services/semantic/semantics.service.ts | 10 + .../services/utilities/enum-utils.service.ts | 16 +- .../prefilling-source-editor.component.html | 136 ++++ .../prefilling-source-editor.component.scss | 43 ++ .../prefilling-source-editor.component.ts | 264 +++++++ .../editor/prefilling-source-editor.model.ts | 244 ++++++ .../prefilling-source-editor.resolver.ts | 101 +++ .../prefilling-source-editor.service.ts | 15 + ...ling-source-listing-filters.component.html | 36 + ...ling-source-listing-filters.component.scss | 25 + ...illing-source-listing-filters.component.ts | 94 +++ .../prefilling-source-listing.component.html | 96 +++ .../prefilling-source-listing.component.scss | 83 ++ .../prefilling-source-listing.component.ts | 171 +++++ .../prefilling-source.module.ts | 40 + .../prefilling-source.routing.ts | 58 ++ .../reference-type-editor.component.html | 67 +- .../editor/reference-type-editor.component.ts | 73 +- .../editor/reference-type-editor.model.ts | 706 +----------------- .../editor/reference-type-editor.resolver.ts | 69 +- .../reference-type/reference-type.module.ts | 4 +- .../dmp/overview/dmp-overview.component.html | 2 +- .../external-fetcher-source-editor.model.ts | 697 +++++++++++++++++ .../external-fetcher-source.component.html | 359 +++++++++ .../external-fetcher-source.component.scss | 0 .../external-fetcher-source.component.ts | 103 +++ .../external-fetcher-source.module.ts | 24 + .../src/app/ui/sidebar/sidebar.component.ts | 1 + dmp-frontend/src/assets/i18n/en.json | 64 +- 41 files changed, 3095 insertions(+), 976 deletions(-) create mode 100644 dmp-frontend/src/app/core/common/enum/external-fetcher-api-http-method-type.ts create mode 100644 dmp-frontend/src/app/core/common/enum/external-fetcher-source-type.ts delete mode 100644 dmp-frontend/src/app/core/common/enum/reference-type-external-api-http-method-type.ts delete mode 100644 dmp-frontend/src/app/core/common/enum/reference-type-source-type.ts create mode 100644 dmp-frontend/src/app/core/model/external-fetcher/external-fetcher.ts create mode 100644 dmp-frontend/src/app/core/model/prefilling-source/prefilling-source.ts create mode 100644 dmp-frontend/src/app/core/query/prefilling-source.lookup.ts create mode 100644 dmp-frontend/src/app/core/services/prefilling-source/prefilling-source.service.ts create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.html create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.scss create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.model.ts create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.resolver.ts create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.service.ts create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/listing/filters/prefilling-source-listing-filters.component.html create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/listing/filters/prefilling-source-listing-filters.component.scss create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/listing/filters/prefilling-source-listing-filters.component.ts create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/listing/prefilling-source-listing.component.html create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/listing/prefilling-source-listing.component.scss create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/listing/prefilling-source-listing.component.ts create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/prefilling-source.module.ts create mode 100644 dmp-frontend/src/app/ui/admin/prefilling-source/prefilling-source.routing.ts create mode 100644 dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source-editor.model.ts create mode 100644 dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.html create mode 100644 dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.scss create mode 100644 dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.ts create mode 100644 dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.module.ts diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts index f5385cbfa..1f33204c8 100644 --- a/dmp-frontend/src/app/app-routing.module.ts +++ b/dmp-frontend/src/app/app-routing.module.ts @@ -258,6 +258,18 @@ const appRoutes: Routes = [ }) }, }, + { + path: 'prefilling-sources', + loadChildren: () => import('./ui/admin/prefilling-source/prefilling-source.module').then(m => m.PrefillingSourceModule), + data: { + authContext: { + permissions: [AppPermission.ViewPrefillingSourcePage] + }, + ...BreadcrumbService.generateRouteDataConfiguration({ + title: 'BREADCRUMBS.PREFILLING-SOURCES' + }) + }, + }, { path: 'tenants', loadChildren: () => import('./ui/admin/tenant/tenant.module').then(m => m.TenantModule), diff --git a/dmp-frontend/src/app/core/common/enum/external-fetcher-api-http-method-type.ts b/dmp-frontend/src/app/core/common/enum/external-fetcher-api-http-method-type.ts new file mode 100644 index 000000000..22c528703 --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/external-fetcher-api-http-method-type.ts @@ -0,0 +1,4 @@ +export enum ExternalFetcherApiHTTPMethodType { + GET = 0, + POST = 1 +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/common/enum/external-fetcher-source-type.ts b/dmp-frontend/src/app/core/common/enum/external-fetcher-source-type.ts new file mode 100644 index 000000000..f7d504c7d --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/external-fetcher-source-type.ts @@ -0,0 +1,4 @@ +export enum ExternalFetcherSourceType { + API = 0, + STATIC = 1 +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/common/enum/permission.enum.ts b/dmp-frontend/src/app/core/common/enum/permission.enum.ts index 0077e5859..bfa9e4966 100644 --- a/dmp-frontend/src/app/core/common/enum/permission.enum.ts +++ b/dmp-frontend/src/app/core/common/enum/permission.enum.ts @@ -36,6 +36,7 @@ export enum AppPermission { ViewNotificationTemplatePage = "ViewNotificationTemplatePage", ViewMineInAppNotificationPage = "ViewMineInAppNotificationPage", ViewNotificationPage = "ViewNotificationPage", + ViewPrefillingSourcePage = "ViewPrefillingSourcePage", //ReferenceType BrowseReferenceType = "BrowseReferenceType", @@ -67,5 +68,10 @@ export enum AppPermission { BrowseNotificationTemplate = "BrowseNotificationTemplate", EditNotificationTemplate = "EditNotificationTemplate", DeleteNotificationTemplate = "DeleteNotificationTemplate", + + //Prefilling Source + BrowsePrefillingSource= "BrowsePrefillingSource", + EditPrefillingSource = "EditPrefillingSource", + DeletePrefillingSource = "DeletePrefillingSource", } diff --git a/dmp-frontend/src/app/core/common/enum/reference-type-external-api-http-method-type.ts b/dmp-frontend/src/app/core/common/enum/reference-type-external-api-http-method-type.ts deleted file mode 100644 index fa98d8e14..000000000 --- a/dmp-frontend/src/app/core/common/enum/reference-type-external-api-http-method-type.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum ReferenceTypeExternalApiHTTPMethodType { - GET = 0, - POST = 1 -} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/common/enum/reference-type-source-type.ts b/dmp-frontend/src/app/core/common/enum/reference-type-source-type.ts deleted file mode 100644 index 3f0de2272..000000000 --- a/dmp-frontend/src/app/core/common/enum/reference-type-source-type.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum ReferenceTypeSourceType { - API = 0, - STATIC = 1 -} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/core-service.module.ts b/dmp-frontend/src/app/core/core-service.module.ts index 5eac92f6e..f7b5e8ecd 100644 --- a/dmp-frontend/src/app/core/core-service.module.ts +++ b/dmp-frontend/src/app/core/core-service.module.ts @@ -47,6 +47,7 @@ import { FileTransformerHttpService } from './services/file-transformer/file-tra import { InAppNotificationService } from './services/inapp-notification/inapp-notification.service'; import { NotificationService } from './services/notification/notification-service'; import { SemanticsService } from './services/semantic/semantics.service'; +import { PrefillingSourceService } from './services/prefilling-source/prefilling-source.service'; // // // This is shared module that provides all the services. Its imported only once on the AppModule. @@ -112,7 +113,8 @@ export class CoreServiceModule { FileTransformerHttpService, InAppNotificationService, NotificationService, - SemanticsService + SemanticsService, + PrefillingSourceService ], }; } diff --git a/dmp-frontend/src/app/core/model/external-fetcher/external-fetcher.ts b/dmp-frontend/src/app/core/model/external-fetcher/external-fetcher.ts new file mode 100644 index 000000000..10b0a7a71 --- /dev/null +++ b/dmp-frontend/src/app/core/model/external-fetcher/external-fetcher.ts @@ -0,0 +1,136 @@ +import { ExternalFetcherApiHTTPMethodType } from "@app/core/common/enum/external-fetcher-api-http-method-type"; +import { ReferenceType } from "../reference-type/reference-type"; +import { ExternalFetcherSourceType } from "@app/core/common/enum/external-fetcher-source-type"; +import { Guid } from "@common/types/guid"; + +export interface ExternalFetcherBaseSourceConfiguration extends ExternalFetcherApiSourceConfiguration, ExternalFetcherStaticOptionSourceConfiguration{ + type: ExternalFetcherSourceType; + key: string; + label: string; + ordinal: number; + referenceTypeDependencies?: ReferenceType[]; +} + +export interface ExternalFetcherApiSourceConfiguration{ + url: string; + results: ResultsConfiguration; + paginationPath: string; + contentType: string; + firstPage: string; + httpMethod: ExternalFetcherApiHTTPMethodType; + requestBody?: string; + filterType?: string; + auth: AuthenticationConfiguration; + queries?: QueryConfig[]; +} + +export interface ResultsConfiguration{ + resultsArrayPath: string; + fieldsMapping: ResultFieldsMappingConfiguration[]; +} + + +export interface ResultFieldsMappingConfiguration{ + code: string; + responsePath: string; +} + +export interface AuthenticationConfiguration{ + enabled: boolean; + authUrl: string; + authMethod: ExternalFetcherApiHTTPMethodType; + authTokenPath: string; + authRequestBody: string; + type: string; +} + +export interface QueryConfig{ + name: string; + defaultValue: string; + cases: QueryCaseConfig[]; +} + +export interface QueryCaseConfig{ + likePattern: string, + separator: string; + value: string; + referenceType?: ReferenceType; + referenceTypeSourceKey: string +} + +export interface ExternalFetcherStaticOptionSourceConfiguration{ + options: StaticOption[]; +} + +export interface StaticOption{ + code: string; + value: string; +} + +// +// Persist +// + +export interface ExternalFetcherBaseSourceConfigurationPersist extends ExternalFetcherApiSourceConfigurationPersist, ExternalFetcherStaticOptionSourceConfigurationPersist{ + type: ExternalFetcherSourceType; + key: string; + label: string; + ordinal: number; + referenceTypeDependencyIds?: Guid[]; +} + +export interface ExternalFetcherApiSourceConfigurationPersist{ + url: string; + results: ResultsConfigurationPersist; + paginationPath: string; + contentType: string; + firstPage: string; + httpMethod: ExternalFetcherApiHTTPMethodType; + requestBody?: string; + filterType?: string; + auth: AuthenticationConfigurationPersist; + queries?: QueryConfigPersist[]; +} + +export interface ResultsConfigurationPersist{ + resultsArrayPath: string; + fieldsMapping: ResultFieldsMappingConfigurationPersist[]; +} + + +export interface ResultFieldsMappingConfigurationPersist{ + code: string; + responsePath: string; +} + +export interface AuthenticationConfigurationPersist{ + enabled: boolean; + authUrl: string; + authMethod: ExternalFetcherApiHTTPMethodType; + authTokenPath: string; + authRequestBody: string; + type: string; +} + +export interface QueryConfigPersist{ + name: string; + defaultValue: string; + cases: QueryCaseConfigPersist[]; +} + +export interface QueryCaseConfigPersist{ + likePattern: string, + separator: string; + value: string; + referenceTypeId: Guid; + referenceTypeSourceKey: string +} + +export interface ExternalFetcherStaticOptionSourceConfigurationPersist { + options: StaticOptionPersist[]; +} + +export interface StaticOptionPersist{ + code: string; + value: string; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/prefilling-source/prefilling-source.ts b/dmp-frontend/src/app/core/model/prefilling-source/prefilling-source.ts new file mode 100644 index 000000000..eb18185ad --- /dev/null +++ b/dmp-frontend/src/app/core/model/prefilling-source/prefilling-source.ts @@ -0,0 +1,43 @@ +import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model"; +import { ExternalFetcherBaseSourceConfiguration, ExternalFetcherBaseSourceConfigurationPersist} from "../external-fetcher/external-fetcher"; + +export interface PrefillingSource extends BaseEntity{ + label: string; + definition: PrefillingSourceDefinition; +} + +export interface PrefillingSourceDefinition{ + fields: PrefillingSourceDefinitionField[]; + searchConfiguration: ExternalFetcherBaseSourceConfiguration; + getConfiguration: ExternalFetcherBaseSourceConfiguration; +} + +export interface PrefillingSourceDefinitionField { + code: string; + systemFieldTarget: string; + semanticTarget: string; + trimRegex: string; + fixedValue: string; +} + +// Persist + +export interface PrefillingSourcePersist extends BaseEntityPersist{ + label: string; + definition: PrefillingSourceDefinitionPersist; +} + +export interface PrefillingSourceDefinitionPersist{ + fields: PrefillingSourceDefinitionFieldPersist[]; + searchConfiguration: ExternalFetcherBaseSourceConfigurationPersist; + getConfiguration: ExternalFetcherBaseSourceConfigurationPersist; +} + +export interface PrefillingSourceDefinitionFieldPersist { + code: string; + systemFieldTarget: string; + semanticTarget: string; + trimRegex: string; + fixedValue: string; +} + diff --git a/dmp-frontend/src/app/core/model/reference-type/reference-type.ts b/dmp-frontend/src/app/core/model/reference-type/reference-type.ts index f0ba458b3..e3410babf 100644 --- a/dmp-frontend/src/app/core/model/reference-type/reference-type.ts +++ b/dmp-frontend/src/app/core/model/reference-type/reference-type.ts @@ -1,8 +1,6 @@ import { ReferenceFieldDataType } from "@app/core/common/enum/reference-field-data-type"; -import { ReferenceTypeExternalApiHTTPMethodType } from "@app/core/common/enum/reference-type-external-api-http-method-type"; -import { ReferenceTypeSourceType } from "@app/core/common/enum/reference-type-source-type"; import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model"; -import { Guid } from "@common/types/guid"; +import { ExternalFetcherBaseSourceConfiguration, ExternalFetcherBaseSourceConfigurationPersist } from "../external-fetcher/external-fetcher"; export interface ReferenceType extends BaseEntity{ name: string; @@ -12,7 +10,7 @@ export interface ReferenceType extends BaseEntity{ export interface ReferenceTypeDefinition{ fields: ReferenceTypeField[]; - sources: ReferenceTypeSourceBaseConfiguration[]; + sources: ExternalFetcherBaseSourceConfiguration[]; } export interface ReferenceTypeField { @@ -22,69 +20,7 @@ export interface ReferenceTypeField { dataType: ReferenceFieldDataType; } -export interface ReferenceTypeSourceBaseConfiguration extends ReferenceTypeSourceExternalApiConfiguration, ReferenceTypeSourceStaticOptionConfiguration{ - type: ReferenceTypeSourceType; - key: string; - label: string; - ordinal: number; - referenceTypeDependencies?: ReferenceType[]; -} -export interface ReferenceTypeSourceExternalApiConfiguration{ - url: string; - results: ResultsConfiguration; - paginationPath: string; - contentType: string; - firstPage: string; - httpMethod: ReferenceTypeExternalApiHTTPMethodType; - requestBody?: string; - filterType?: string; - auth: AuthenticationConfiguration; - queries?: QueryConfig[]; -} - -export interface ResultsConfiguration{ - resultsArrayPath: string; - fieldsMapping: ResultFieldsMappingConfiguration[]; -} - - -export interface ResultFieldsMappingConfiguration{ - code: string; - responsePath: string; -} - -export interface AuthenticationConfiguration{ - enabled: boolean; - authUrl: string; - authMethod: ReferenceTypeExternalApiHTTPMethodType; - authTokenPath: string; - authRequestBody: string; - type: string; -} - -export interface QueryConfig{ - name: string; - defaultValue: string; - cases: QueryCaseConfig[]; -} - -export interface QueryCaseConfig{ - likePattern: string, - separator: string; - value: string; - referenceType?: ReferenceType; - referenceTypeSourceKey: string -} - -export interface ReferenceTypeSourceStaticOptionConfiguration{ - options: ReferenceTypeStaticOption[]; -} - -export interface ReferenceTypeStaticOption{ - code: string; - value: string; -} // Persist @@ -96,7 +32,7 @@ export interface ReferenceTypePersist extends BaseEntityPersist{ export interface ReferenceTypeDefinitionPersist{ fields?: ReferenceTypeFieldPersist[]; - sources: ReferenceTypeSourceBaseConfigurationPersist[]; + sources: ExternalFetcherBaseSourceConfigurationPersist[]; } export interface ReferenceTypeFieldPersist { @@ -105,68 +41,3 @@ export interface ReferenceTypeFieldPersist { description: string; dataType: ReferenceFieldDataType; } - -export interface ReferenceTypeSourceBaseConfigurationPersist extends ReferenceTypeSourceExternalApiConfigurationPersist, ReferenceTypeSourceStaticOptionConfigurationPersist{ - type: ReferenceTypeSourceType; - key: string; - label: string; - ordinal: number; - referenceTypeDependencyIds?: Guid[]; -} - -export interface ReferenceTypeSourceExternalApiConfigurationPersist{ - url: string; - results: ResultsConfigurationPersist; - paginationPath: string; - contentType: string; - firstPage: string; - httpMethod: ReferenceTypeExternalApiHTTPMethodType; - requestBody?: string; - filterType?: string; - auth: AuthenticationConfigurationPersist; - queries?: QueryConfigPersist[]; -} - -export interface ResultsConfigurationPersist{ - resultsArrayPath: string; - fieldsMapping: ResultFieldsMappingConfigurationPersist[]; -} - - - -export interface ResultFieldsMappingConfigurationPersist{ - code: string; - responsePath: string; -} - -export interface AuthenticationConfigurationPersist{ - enabled: boolean; - authUrl: string; - authMethod: ReferenceTypeExternalApiHTTPMethodType; - authTokenPath: string; - authRequestBody: string; - type: string; -} - -export interface QueryConfigPersist{ - name: string; - defaultValue: string; - cases: QueryCaseConfigPersist[]; -} - -export interface QueryCaseConfigPersist{ - likePattern: string, - separator: string; - value: string; - referenceTypeId: Guid; - referenceTypeSourceKey: string -} - -export interface ReferenceTypeSourceStaticOptionConfigurationPersist { - options: ReferenceTypeStaticOptionPersist[]; -} - -export interface ReferenceTypeStaticOptionPersist{ - code: string; - value: string; -} diff --git a/dmp-frontend/src/app/core/query/prefilling-source.lookup.ts b/dmp-frontend/src/app/core/query/prefilling-source.lookup.ts new file mode 100644 index 000000000..154fb871d --- /dev/null +++ b/dmp-frontend/src/app/core/query/prefilling-source.lookup.ts @@ -0,0 +1,21 @@ +import { Lookup } from "@common/model/lookup"; +import { Guid } from "@common/types/guid"; +import { IsActive } from "../common/enum/is-active.enum"; + +export class PrefillingSourceLookup extends Lookup implements PrefillingSourceFilter { + ids: Guid[]; + excludedIds: Guid[]; + like: string; + isActive: IsActive[]; + + constructor() { + super(); + } +} + +export interface PrefillingSourceFilter { + ids: Guid[]; + excludedIds: Guid[]; + like: string; + isActive: IsActive[]; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/prefilling-source/prefilling-source.service.ts b/dmp-frontend/src/app/core/services/prefilling-source/prefilling-source.service.ts new file mode 100644 index 000000000..f2d1fcd73 --- /dev/null +++ b/dmp-frontend/src/app/core/services/prefilling-source/prefilling-source.service.ts @@ -0,0 +1,97 @@ +import { Injectable } from '@angular/core'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { PrefillingSource, PrefillingSourcePersist } from '@app/core/model/prefilling-source/prefilling-source'; +import { PrefillingSourceLookup } from '@app/core/query/prefilling-source.lookup'; +import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; +import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; +import { QueryResult } from '@common/model/query-result'; +import { FilterService } from '@common/modules/text-filter/filter-service'; +import { Guid } from '@common/types/guid'; +import { Observable, throwError } from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; +import { nameof } from 'ts-simple-nameof'; +import { ConfigurationService } from '../configuration/configuration.service'; +import { BaseHttpV2Service } from '../http/base-http-v2.service'; + +@Injectable() +export class PrefillingSourceService { + + constructor( + private http: BaseHttpV2Service, + private configurationService: ConfigurationService, + private filterService: FilterService + ) { + } + + private get apiBase(): string { return `${this.configurationService.server}prefilling-source`; } + + query(q: PrefillingSourceLookup): Observable> { + const url = `${this.apiBase}/query`; + return this.http.post>(url, q).pipe(catchError((error: any) => throwError(error))); + } + + getSingle(id: Guid, reqFields: string[] = []): Observable { + const url = `${this.apiBase}/${id}`; + const options = { params: { f: reqFields } }; + + return this.http + .get(url, options).pipe( + catchError((error: any) => throwError(error))); + } + + persist(item: PrefillingSourcePersist): Observable { + const url = `${this.apiBase}/persist`; + + return this.http + .post(url, item).pipe( + catchError((error: any) => throwError(error))); + } + + delete(id: Guid): Observable { + const url = `${this.apiBase}/${id}`; + + return this.http + .delete(url).pipe( + catchError((error: any) => throwError(error))); + } + + // + // Autocomplete Commons + // + // + public singleAutocompleteConfiguration: SingleAutoCompleteConfiguration = { + initialItems: (data?: any) => this.query(this.buildAutocompleteLookup()).pipe(map(x => x.items)), + filterFn: (searchQuery: string, data?: any) => this.query(this.buildAutocompleteLookup(searchQuery)).pipe(map(x => x.items)), + getSelectedItem: (selectedItem: any) => this.query(this.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])), + displayFn: (item: PrefillingSource) => item.label, + titleFn: (item: PrefillingSource) => item.label, + valueAssign: (item: PrefillingSource) => item.id, + }; + + public multipleAutocompleteConfiguration: MultipleAutoCompleteConfiguration = { + initialItems: (excludedItems: any[], data?: any) => this.query(this.buildAutocompleteLookup(null, excludedItems ? excludedItems : null)).pipe(map(x => x.items)), + filterFn: (searchQuery: string, excludedItems: any[]) => this.query(this.buildAutocompleteLookup(searchQuery, excludedItems)).pipe(map(x => x.items)), + getSelectedItems: (selectedItems: any[]) => this.query(this.buildAutocompleteLookup(null, null, selectedItems)).pipe(map(x => x.items)), + displayFn: (item: PrefillingSource) => item.label, + titleFn: (item: PrefillingSource) => item.label, + valueAssign: (item: PrefillingSource) => item.id, + }; + + private buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[]): PrefillingSourceLookup { + const lookup: PrefillingSourceLookup = new PrefillingSourceLookup(); + lookup.page = { size: 100, offset: 0 }; + if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; } + if (ids && ids.length > 0) { lookup.ids = ids; } + lookup.isActive = [IsActive.Active]; + lookup.project = { + fields: [ + nameof(x => x.id), + nameof(x => x.label) + ] + }; + lookup.order = { items: [nameof(x => x.label)] }; + if (like) { lookup.like = this.filterService.transformLike(like); } + return lookup; + } + +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/semantic/semantics.service.ts b/dmp-frontend/src/app/core/services/semantic/semantics.service.ts index c8b7b8ca5..b229e2e30 100644 --- a/dmp-frontend/src/app/core/services/semantic/semantics.service.ts +++ b/dmp-frontend/src/app/core/services/semantic/semantics.service.ts @@ -7,6 +7,7 @@ import { catchError, map } from 'rxjs/operators'; import { ConfigurationService } from '../configuration/configuration.service'; import { BaseHttpV2Service } from '../http/base-http-v2.service'; import { SemanticsLookup } from '@app/core/query/semantic.lookup'; +import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; @Injectable() export class SemanticsService { @@ -26,6 +27,15 @@ export class SemanticsService { // Autocomplete + + singleAutocompleteConfiguration: SingleAutoCompleteConfiguration = { + initialItems: (data?: any) => this.searchSemantics(this.buildSemanticsAutocompleteLookup()).pipe(map(x => x)), + filterFn: (searchQuery: string, data?: any) => this.searchSemantics(this.buildSemanticsAutocompleteLookup(searchQuery)).pipe(map(x => x)), + displayFn: (item) => item, + titleFn: (item) => item, + valueAssign: (item) => item, + }; + multipleAutocompleteConfiguration: MultipleAutoCompleteConfiguration = { initialItems: (data?: any) => this.searchSemantics(this.buildSemanticsAutocompleteLookup()).pipe(map(x => x)), filterFn: (searchQuery: string, data?: any) => this.searchSemantics(this.buildSemanticsAutocompleteLookup(searchQuery)).pipe(map(x => x)), diff --git a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts index 42277c26f..19d7510b5 100644 --- a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts +++ b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts @@ -24,8 +24,8 @@ import { NotificationType } from '@app/core/common/enum/notification-type'; import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order'; import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-type'; import { ReferenceSourceType } from '@app/core/common/enum/reference-source-type'; -import { ReferenceTypeExternalApiHTTPMethodType } from '@app/core/common/enum/reference-type-external-api-http-method-type'; -import { ReferenceTypeSourceType } from '@app/core/common/enum/reference-type-source-type'; +import { ExternalFetcherApiHTTPMethodType } from '@app/core/common/enum/external-fetcher-api-http-method-type'; +import { ExternalFetcherSourceType } from '@app/core/common/enum/external-fetcher-source-type'; import { RoleOrganizationType } from '@app/core/common/enum/role-organization-type'; import { SupportiveMaterialFieldType } from '@app/core/common/enum/supportive-material-field-type'; import { UserDescriptionTemplateRole } from '@app/core/common/enum/user-description-template-role'; @@ -174,10 +174,10 @@ export class EnumUtils { } } - toReferenceTypeSourceTypeString(status: ReferenceTypeSourceType): string { + toExternalFetcherSourceTypeString(status: ExternalFetcherSourceType): string { switch (status) { - case ReferenceTypeSourceType.API: return this.language.instant('TYPES.REFERENCE-TYPE-SOURCE-TYPE.API'); - case ReferenceTypeSourceType.STATIC: return this.language.instant('TYPES.REFERENCE-TYPE-SOURCE-TYPE.STATIC'); + case ExternalFetcherSourceType.API: return this.language.instant('TYPES.REFERENCE-TYPE-SOURCE-TYPE.API'); + case ExternalFetcherSourceType.STATIC: return this.language.instant('TYPES.REFERENCE-TYPE-SOURCE-TYPE.STATIC'); } } @@ -189,10 +189,10 @@ export class EnumUtils { } - toReferenceTypeExternalApiHTTPMethodTypeString(status: ReferenceTypeExternalApiHTTPMethodType): string { + toExternalFetcherApiHTTPMethodTypeString(status: ExternalFetcherApiHTTPMethodType): string { switch (status) { - case ReferenceTypeExternalApiHTTPMethodType.GET: return this.language.instant('TYPES.REFERENCE-TYPE-EXTERNAL-API-HTTP-METHOD-TYPE.GET'); - case ReferenceTypeExternalApiHTTPMethodType.POST: return this.language.instant('TYPES.REFERENCE-TYPE-EXTERNAL-API-HTTP-METHOD-TYPE.POST'); + case ExternalFetcherApiHTTPMethodType.GET: return this.language.instant('TYPES.REFERENCE-TYPE-EXTERNAL-API-HTTP-METHOD-TYPE.GET'); + case ExternalFetcherApiHTTPMethodType.POST: return this.language.instant('TYPES.REFERENCE-TYPE-EXTERNAL-API-HTTP-METHOD-TYPE.POST'); } } diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.html b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.html new file mode 100644 index 000000000..369a7f40a --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.html @@ -0,0 +1,136 @@ +
+
+ +
+
+

{{'PREFILLING-SOURCE-EDITOR.NEW' | translate}}

+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ + + {{'PREFILLING-SOURCE-EDITOR.NEW' | translate}} + + +
+
+ + {{'PREFILLING-SOURCE-EDITOR.FIELDS.LABEL' | translate}} + + {{formGroup.get('label').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+ +
+

+ +

+
+
+
+
+ {{'PREFILLING-SOURCE-EDITOR.FIELDS.FIELD' | translate}} {{fieldIndex + 1}} +
+
+ +
+
+
+
+ + {{'PREFILLING-SOURCE-EDITOR.FIELDS.CODE' | translate}} + + {{field.get('code').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'PREFILLING-SOURCE-EDITOR.FIELDS.SYSTEM-TARGET' | translate}} + + {{field.get('systemFieldTarget').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'PREFILLING-SOURCE-EDITOR.FIELDS.SEMANTIC-TARGET' | translate}} + + {{field.get('semanticTarget').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'PREFILLING-SOURCE-EDITOR.FIELDS.TRIM-REGEX' | translate}} + + {{field.get('trimRegex').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'PREFILLING-SOURCE-EDITOR.FIELDS.FIXED-VALUE' | translate}} + + {{field.get('fixedValue').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+
+
+ +
+
+
+
+ + + + {{'PREFILLING-SOURCE-EDITOR.FIELDS.SOURCE-CONFIGURATION' | translate}} + + + +
+ + {{'PREFILLING-SOURCE-EDITOR.FIELDS.GET-SOURCE-CONFIGURATION' | translate}} + {{formGroup.get('definition').get('getEnabled').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+
+ + + + {{'PREFILLING-SOURCE-EDITOR.FIELDS.GET-SOURCE-CONFIGURATION' | translate}} + + + + + +
+ +
+
\ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.scss b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.scss new file mode 100644 index 000000000..09a802a50 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.scss @@ -0,0 +1,43 @@ +.prefilling-source-editor { + margin-top: 1.3rem; + margin-left: 1em; + margin-right: 3em; + + .remove { + background-color: white; + color: black; + } + + .add { + background-color: white; + color: #009700; + } +} + +::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background, .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background { + background-color: var(--primary-color-3); + // background-color: #0070c0; +} + +::ng-deep .mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background { + background-color: #b0b0b0; +} + +.action-btn { + border-radius: 30px; + background-color: var(--secondary-color); + border: 1px solid transparent; + padding-left: 2em; + padding-right: 2em; + box-shadow: 0px 3px 6px #1E202029; + + transition-property: background-color, color; + transition-duration: 200ms; + transition-delay: 50ms; + transition-timing-function: ease-in-out; + &:disabled{ + background-color: #CBCBCB; + color: #FFF; + border: 0px; + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts new file mode 100644 index 000000000..7687535f4 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts @@ -0,0 +1,264 @@ + +import { Component, OnInit } from '@angular/core'; +import { FormArray, FormGroup, UntypedFormGroup } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Router } from '@angular/router'; +import { PrefillingSourceService } from '@app/core/services/prefilling-source/prefilling-source.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; +// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; +import { DatePipe } from '@angular/common'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { AppPermission } from '@app/core/common/enum/permission.enum'; +import { PrefillingSource, PrefillingSourcePersist } from '@app/core/model/prefilling-source/prefilling-source'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { LoggingService } from '@app/core/services/logging/logging-service'; +import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; +import { BaseEditor } from '@common/base/base-editor'; +import { FormService } from '@common/forms/form-service'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; +import { FilterService } from '@common/modules/text-filter/filter-service'; +import { Guid } from '@common/types/guid'; +import { TranslateService } from '@ngx-translate/core'; +import { map, takeUntil } from 'rxjs/operators'; +import { PrefillingSourceEditorResolver } from './prefilling-source-editor.resolver'; +import { PrefillingSourceEditorService } from './prefilling-source-editor.service'; +import { PrefillingSourceEditorModel } from './prefilling-source-editor.model'; +import { ResultFieldsMappingConfigurationEditorModel } from '@app/ui/external-fetcher/external-fetcher-source-editor.model'; +import { SemanticsService } from '@app/core/services/semantic/semantics.service'; + +@Component({ + selector: 'app-prefilling-source-editor-component', + templateUrl: 'prefilling-source-editor.component.html', + styleUrls: ['./prefilling-source-editor.component.scss'], + providers: [PrefillingSourceEditorService] +}) +export class PrefillingSourceEditorComponent extends BaseEditor implements OnInit { + + isNew = true; + isDeleted = false; + formGroup: UntypedFormGroup = null; + showInactiveDetails = false; + + protected get canDelete(): boolean { + return !this.isDeleted && !this.isNew && this.hasPermission(this.authService.permissionEnum.DeletePrefillingSource); + } + + protected get canSave(): boolean { + return !this.isDeleted && this.hasPermission(this.authService.permissionEnum.EditPrefillingSource); + } + + private hasPermission(permission: AppPermission): boolean { + return this.authService.hasPermission(permission) || this.editorModel?.permissions?.includes(permission); + } + + constructor( + // BaseFormEditor injected dependencies + protected dialog: MatDialog, + protected language: TranslateService, + protected formService: FormService, + protected router: Router, + protected uiNotificationService: UiNotificationService, + protected httpErrorHandlingService: HttpErrorHandlingService, + protected filterService: FilterService, + protected datePipe: DatePipe, + protected route: ActivatedRoute, + protected queryParamsService: QueryParamsService, + // Rest dependencies. Inject any other needed deps here: + public authService: AuthService, + public enumUtils: EnumUtils, + private prefillingSourceService: PrefillingSourceService, + private logger: LoggingService, + private prefillingSourceEditorService: PrefillingSourceEditorService, + public semanticsService: SemanticsService, + private matomoService: MatomoService + ) { + super(dialog, language, formService, router, uiNotificationService, httpErrorHandlingService, filterService, datePipe, route, queryParamsService); + } + + ngOnInit(): void { + this.matomoService.trackPageView('Admin: PrefillingSources'); + super.ngOnInit(); + } + + getItem(itemId: Guid, successFunction: (item: PrefillingSource) => void) { + this.prefillingSourceService.getSingle(itemId, PrefillingSourceEditorResolver.lookupFields()) + .pipe(map(data => data as PrefillingSource), takeUntil(this._destroyed)) + .subscribe( + data => successFunction(data), + error => this.onCallbackError(error) + ); + } + + prepareForm(data: PrefillingSource) { + try { + this.editorModel = data ? new PrefillingSourceEditorModel().fromModel(data) : new PrefillingSourceEditorModel(); + this.isDeleted = data ? data.isActive === IsActive.Inactive : false; + this.buildForm(); + } catch (error) { + this.logger.error('Could not parse PrefillingSource item: ' + data + error); + this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.ERRORS.DEFAULT'), SnackBarNotificationLevel.Error); + } + } + + buildForm() { + this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.authService.hasPermission(AppPermission.EditPrefillingSource)); + this.prefillingSourceEditorService.setValidationErrorModel(this.editorModel.validationErrorModel); + this.addFieldMapping("prefilling_id", "searchConfiguration"); + this.addFieldMapping("label", "searchConfiguration"); + this.addFieldMapping("description", "searchConfiguration"); + + this.addFieldMapping("prefilling_id", "getConfiguration"); + this.addFieldMapping("label", "getConfiguration"); + this.addFieldMapping("description", "getConfiguration"); + } + + refreshData(): void { + this.getItem(this.editorModel.id, (data: PrefillingSource) => this.prepareForm(data)); + } + + refreshOnNavigateToData(id?: Guid): void { + this.formGroup.markAsPristine(); + let route = []; + + if (id === null) { + route.push('../..'); + } else if (this.isNew) { + route.push('../' + id); + } else { + route.push('..'); + } + + this.router.navigate(route, { queryParams: { 'lookup': this.queryParamsService.serializeLookup(this.lookupParams), 'lv': ++this.lv }, replaceUrl: true, relativeTo: this.route }); + } + + persistEntity(onSuccess?: (response) => void): void { + const formData = this.formService.getValue(this.formGroup.value) as PrefillingSourcePersist; + + this.prefillingSourceService.persist(formData) + .pipe(takeUntil(this._destroyed)).subscribe( + complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete), + error => this.onCallbackError(error) + ); + } + + formSubmit(): void { + this.formService.touchAllFormFields(this.formGroup); + // if (!this.isFormValid()) { + // return; + // } + + this.persistEntity(); + } + + public delete() { + const value = this.formGroup.value; + if (value.id) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '300px', + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.prefillingSourceService.delete(value.id).pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(), + error => this.onCallbackError(error) + ); + } + }); + } + } + + clearErrorModel() { + this.editorModel.validationErrorModel.clear(); + this.formService.validateAllFormFields(this.formGroup); + } + + // + // + // fields + // + // + addField(): void { + (this.formGroup.get('definition').get('fields') as FormArray).push(this.editorModel.createChildField((this.formGroup.get('definition').get('fields') as FormArray).length)); + } + + removeField(fieldIndex: number): void { + const fieldForm = this.formGroup.get('definition').get('fields') as FormArray; + const fieldCode = fieldForm.at(fieldIndex).get('code').value; + + fieldForm.removeAt(fieldIndex); + + //Reapply validators + PrefillingSourceEditorModel.reApplyDefinitionValidators( + { + formGroup: this.formGroup, + validationErrorModel: this.editorModel.validationErrorModel + } + ) + fieldForm.markAsDirty(); + + this.removeFieldMapping((this.formGroup.get('definition').get('searchConfiguration') as FormGroup), fieldCode); + this.removeFieldMapping((this.formGroup.get('definition').get('getConfiguration') as FormGroup), fieldCode); + } + + submitFields(): void { + const fieldsFormArray = (this.formGroup.get('definition').get('fields') as FormArray); + + if (fieldsFormArray.valid) { + for (let i = 0; i < fieldsFormArray.length; i++) { + const code = fieldsFormArray.at(i).get('code').value; + this.addFieldMapping(code, "searchConfiguration"); + this.addFieldMapping(code, "getConfiguration"); + } + } + } + + + // + // + // resultFieldsMapping + // + // + addFieldMapping(code: string, controlName: string): void { + const formArray = (this.formGroup.get('definition').get(controlName).get('results').get('fieldsMapping') as FormArray); + const fieldMappingSize = formArray.length; + + if (fieldMappingSize > 0) { + for (let i = 0; i < fieldMappingSize; i++) { + if (formArray.at(i).get('code').getRawValue() == code) { + return; + } + } + } + const fieldsMapping = new ResultFieldsMappingConfigurationEditorModel(this.editorModel.validationErrorModel); + fieldsMapping.code = code; + formArray.push(fieldsMapping.buildForm({rootPath: "definition." + controlName + ".results.fieldsMapping[" + fieldMappingSize + "]."})); + } + + removeFieldMapping(baseFormGroup: any, fieldCode: string){ + if(baseFormGroup){ + const fieldMappingFormArray = (baseFormGroup.get('results').get('fieldsMapping') as FormArray); + for (let j = 0; j < fieldMappingFormArray.length; j++) { + if (fieldCode == fieldMappingFormArray.at(j).get('code').getRawValue()) { + fieldMappingFormArray.removeAt(j); + + PrefillingSourceEditorModel.reApplyDefinitionValidators({ + formGroup: this.formGroup, + validationErrorModel: this.editorModel.validationErrorModel + } + ); + } + } + } + } + + +} diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.model.ts b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.model.ts new file mode 100644 index 000000000..3807b7f69 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.model.ts @@ -0,0 +1,244 @@ +import { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; +import { PrefillingSource, PrefillingSourceDefinition, PrefillingSourceDefinitionField, PrefillingSourceDefinitionFieldPersist, PrefillingSourceDefinitionPersist, PrefillingSourcePersist } from "@app/core/model/prefilling-source/prefilling-source"; +import { ExternalFetcherBaseSourceConfigurationEditorModel, QueryCaseConfigEditorModel, QueryConfigEditorModel } from "@app/ui/external-fetcher/external-fetcher-source-editor.model"; + +import { BaseEditorModel } from "@common/base/base-form-editor-model"; +import { BackendErrorValidator } from "@common/forms/validation/custom-validator"; +import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model"; +import { Validation, ValidationContext } from "@common/forms/validation/validation-context"; + +export class PrefillingSourceEditorModel extends BaseEditorModel implements PrefillingSourcePersist { + label: string; + definition: PrefillingSourceDefinitionEditorModel = new PrefillingSourceDefinitionEditorModel(); + permissions: string[]; + + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor() { super(); } + + public fromModel(item: PrefillingSource): PrefillingSourceEditorModel { + if (item) { + super.fromModel(item); + this.label = item.label; + if (item.definition) this.definition = new PrefillingSourceDefinitionEditorModel(this.validationErrorModel).fromModel(item.definition); + } + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup { + if (context == null) { context = this.createValidationContext(); } + + return this.formBuilder.group({ + id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators], + label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators], + definition: this.definition.buildForm({ + rootPath: `definition.`, + }), + hash: [{ value: this.hash, disabled: disabled }, context.getValidation('hash').validators] + }); + } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] }); + baseValidationArray.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); + baseValidationArray.push({ key: 'definition', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'definition')] }); + baseValidationArray.push({ key: 'hash', validators: [] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + + static reApplyDefinitionValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + }): void { + + const { formGroup, validationErrorModel } = params; + const control = formGroup?.get('definition'); + PrefillingSourceDefinitionEditorModel.reapplyValidators({ + formArray: control.get('fields') as UntypedFormArray, + rootPath: `definition.`, + validationErrorModel: validationErrorModel + }); + } + + createChildField(index: number): UntypedFormGroup { + const field: PrefillingSourceDefinitionFieldEditorModel = new PrefillingSourceDefinitionFieldEditorModel(this.validationErrorModel); + return field.buildForm({ rootPath: 'definition.fields[' + index + '].' }); + } +} + +export class PrefillingSourceDefinitionEditorModel implements PrefillingSourceDefinitionPersist { + fields: PrefillingSourceDefinitionFieldEditorModel[] = []; + searchConfiguration: ExternalFetcherBaseSourceConfigurationEditorModel = new ExternalFetcherBaseSourceConfigurationEditorModel(); + getConfiguration: ExternalFetcherBaseSourceConfigurationEditorModel = new ExternalFetcherBaseSourceConfigurationEditorModel(); + getEnabled = false; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + public fromModel(item: PrefillingSourceDefinition): PrefillingSourceDefinitionEditorModel { + if (item) { + if (item.fields) { item.fields.map(x => this.fields.push(new PrefillingSourceDefinitionFieldEditorModel(this.validationErrorModel).fromModel(x))); } + if (item.searchConfiguration) this.searchConfiguration = new ExternalFetcherBaseSourceConfigurationEditorModel(this.validationErrorModel).fromModel(item.searchConfiguration); + if (item.getConfiguration) { + this.getConfiguration = new ExternalFetcherBaseSourceConfigurationEditorModel(this.validationErrorModel).fromModel(item.getConfiguration); + this.getEnabled = true; + } + } + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = PrefillingSourceDefinitionEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + fields: this.formBuilder.array( + (this.fields ?? []).map( + (item, index) => item.buildForm({ + rootPath: `${rootPath}fields[${index}].` + }), context.getValidation('fields') + ) + ), + searchConfiguration: this.searchConfiguration.buildForm({ + rootPath: `${rootPath}searchConfiguration.` + }), + getConfiguration: this.getConfiguration.buildForm({ + rootPath: `${rootPath}getConfiguration.` + }), + getEnabled: [{ value: this.getEnabled, disabled: disabled }, context.getValidation('getEnabled').validators], + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'fields', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}fields`)] }); + baseValidationArray.push({ key: 'searchConfiguration', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}searchConfiguration`)] }); + baseValidationArray.push({ key: 'getConfiguration', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}getConfiguration`)] }); + baseValidationArray.push({ key: 'getEnabled', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}getConfiguration`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + + static reapplyValidators(params: { + formArray: UntypedFormArray, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + const { validationErrorModel, rootPath, formArray } = params; + formArray?.controls?.forEach( + (control, index) => PrefillingSourceDefinitionFieldEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}fields[${index}].`, + validationErrorModel: validationErrorModel + }) + ); + } +} + +export class PrefillingSourceDefinitionFieldEditorModel implements PrefillingSourceDefinitionFieldPersist { + code: string; + systemFieldTarget: string; + semanticTarget: string; + trimRegex: string; + fixedValue: string; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + public fromModel(item: PrefillingSourceDefinitionField): PrefillingSourceDefinitionFieldEditorModel { + if (item) { + this.code = item.code; + this.systemFieldTarget = item.systemFieldTarget; + this.semanticTarget = item.semanticTarget; + this.trimRegex = item.trimRegex; + this.fixedValue = item.fixedValue; + } + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = PrefillingSourceDefinitionFieldEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + code: [{ value: this.code, disabled: disabled }, context.getValidation('code').validators], + systemFieldTarget: [{ value: this.systemFieldTarget, disabled: disabled }, context.getValidation('systemFieldTarget').validators], + semanticTarget: [{ value: this.semanticTarget, disabled: disabled }, context.getValidation('semanticTarget').validators], + trimRegex: [{ value: this.trimRegex, disabled: disabled }, context.getValidation('trimRegex').validators], + fixedValue: [{ value: this.fixedValue, disabled: disabled }, context.getValidation('fixedValue').validators], + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'code', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}code`)] }); + baseValidationArray.push({ key: 'systemFieldTarget', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}systemFieldTarget`)] }); + baseValidationArray.push({ key: 'semanticTarget', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}semanticTarget`)] }); + baseValidationArray.push({ key: 'trimRegex', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}trimRegex`)] }); + baseValidationArray.push({ key: 'fixedValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}clientSecret`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = PrefillingSourceDefinitionFieldEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['code', 'systemFieldTarget', 'semanticTarget', 'trimRegex', 'fixedValue'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } +} diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.resolver.ts b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.resolver.ts new file mode 100644 index 000000000..e2a4972b0 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.resolver.ts @@ -0,0 +1,101 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; +import { AuthenticationConfiguration, ExternalFetcherBaseSourceConfiguration, QueryCaseConfig, QueryConfig, ResultFieldsMappingConfiguration, ResultsConfiguration } from '@app/core/model/external-fetcher/external-fetcher'; +import { PrefillingSource, PrefillingSourceDefinition, PrefillingSourceDefinitionField } from '@app/core/model/prefilling-source/prefilling-source'; +import { PrefillingSourceService } from '@app/core/services/prefilling-source/prefilling-source.service'; +import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; +import { BaseEditorResolver } from '@common/base/base-editor.resolver'; +import { Guid } from '@common/types/guid'; +import { takeUntil, tap } from 'rxjs/operators'; +import { nameof } from 'ts-simple-nameof'; + +@Injectable() +export class PrefillingSourceEditorResolver extends BaseEditorResolver { + + constructor(private prefillingSourceService: PrefillingSourceService, private breadcrumbService: BreadcrumbService) { + super(); + } + + public static lookupFields(): string[] { + return [ + ...BaseEditorResolver.lookupFields(), + nameof(x => x.id), + nameof(x => x.label), + + [nameof(x => x.definition), nameof(x => x.fields), nameof(x => x.code)].join('.'), + [nameof(x => x.definition), nameof(x => x.fields), nameof(x => x.systemFieldTarget)].join('.'), + [nameof(x => x.definition), nameof(x => x.fields), nameof(x => x.semanticTarget)].join('.'), + [nameof(x => x.definition), nameof(x => x.fields), nameof(x => x.trimRegex)].join('.'), + [nameof(x => x.definition), nameof(x => x.fields), nameof(x => x.fixedValue)].join('.'), + + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.type)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.key)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.label)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.ordinal)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.url)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.results), nameof(x => x.resultsArrayPath)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.results), nameof(x => x.fieldsMapping), nameof(x => x.code)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.results), nameof(x => x.fieldsMapping), nameof(x => x.responsePath)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.paginationPath)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.contentType)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.firstPage)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.httpMethod)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.requestBody)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.filterType)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.auth), nameof(x => x.enabled)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.auth), nameof(x => x.authUrl)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.auth), nameof(x => x.authMethod)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.auth), nameof(x => x.authTokenPath)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.auth), nameof(x => x.authRequestBody)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.auth), nameof(x => x.type)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.queries), nameof(x => x.name)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.queries), nameof(x => x.defaultValue)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.queries), nameof(x => x.cases),nameof(x => x.likePattern)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.queries), nameof(x => x.cases),nameof(x => x.separator)].join('.'), + [nameof(x => x.definition), nameof(x => x.searchConfiguration), nameof(x => x.queries), nameof(x => x.cases),nameof(x => x.value)].join('.'), + + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.type)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.key)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.label)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.ordinal)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.url)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.results), nameof(x => x.resultsArrayPath)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.results), nameof(x => x.fieldsMapping), nameof(x => x.code)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.results), nameof(x => x.fieldsMapping), nameof(x => x.responsePath)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.paginationPath)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.contentType)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.firstPage)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.httpMethod)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.requestBody)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.filterType)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.auth), nameof(x => x.enabled)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.auth), nameof(x => x.authUrl)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.auth), nameof(x => x.authMethod)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.auth), nameof(x => x.authTokenPath)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.auth), nameof(x => x.authRequestBody)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.auth), nameof(x => x.type)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.queries), nameof(x => x.name)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.queries), nameof(x => x.defaultValue)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.queries), nameof(x => x.cases),nameof(x => x.likePattern)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.queries), nameof(x => x.cases),nameof(x => x.separator)].join('.'), + [nameof(x => x.definition), nameof(x => x.getConfiguration), nameof(x => x.queries), nameof(x => x.cases),nameof(x => x.value)].join('.'), + + nameof(x => x.createdAt), + nameof(x => x.updatedAt), + nameof(x => x.hash), + nameof(x => x.isActive) + ] + } + + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + + const fields = [ + ...PrefillingSourceEditorResolver.lookupFields() + ]; + const id = route.paramMap.get('id'); + + if (id != null) { + return this.prefillingSourceService.getSingle(Guid.parse(id), fields).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed)); + } + } +} diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.service.ts b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.service.ts new file mode 100644 index 000000000..df3e675fc --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.service.ts @@ -0,0 +1,15 @@ +import { Injectable } from "@angular/core"; +import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model"; + +@Injectable() +export class PrefillingSourceEditorService { + private validationErrorModel: ValidationErrorModel; + + public setValidationErrorModel(validationErrorModel: ValidationErrorModel): void { + this.validationErrorModel = validationErrorModel; + } + + public getValidationErrorModel(): ValidationErrorModel { + return this.validationErrorModel; + } +} diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/listing/filters/prefilling-source-listing-filters.component.html b/dmp-frontend/src/app/ui/admin/prefilling-source/listing/filters/prefilling-source-listing-filters.component.html new file mode 100644 index 000000000..0d6059198 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/listing/filters/prefilling-source-listing-filters.component.html @@ -0,0 +1,36 @@ +
+ + + + + +
+
+
+

{{'PREFILLING-SOURCE-LISTING.FILTER.TITLE' | translate}}

+ +
+ + + {{'PREFILLING-SOURCE-LISTING.FILTER.IS-ACTIVE' | translate}} + + +
+ + +
+
+
+
+ + +
diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/listing/filters/prefilling-source-listing-filters.component.scss b/dmp-frontend/src/app/ui/admin/prefilling-source/listing/filters/prefilling-source-listing-filters.component.scss new file mode 100644 index 000000000..c31bf588d --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/listing/filters/prefilling-source-listing-filters.component.scss @@ -0,0 +1,25 @@ +.prefilling-source-listing-filters { + +} + +::ng-deep.mat-mdc-menu-panel { + max-width: 100% !important; + height: 100% !important; +} + +:host::ng-deep.mat-mdc-menu-content:not(:empty) { + padding-top: 0 !important; +} + + +.filter-button{ + padding-top: .6rem; + padding-bottom: .6rem; + // .mat-icon{ + // font-size: 1.5em; + // width: 1.2em; + // height: 1.2em; + // } +} + + diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/listing/filters/prefilling-source-listing-filters.component.ts b/dmp-frontend/src/app/ui/admin/prefilling-source/listing/filters/prefilling-source-listing-filters.component.ts new file mode 100644 index 000000000..6d96affe4 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/listing/filters/prefilling-source-listing-filters.component.ts @@ -0,0 +1,94 @@ +import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { PrefillingSourceFilter } from '@app/core/query/prefilling-source.lookup'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; +import { BaseComponent } from '@common/base/base.component'; +import { nameof } from 'ts-simple-nameof'; + +@Component({ + selector: 'app-prefilling-source-listing-filters', + templateUrl: './prefilling-source-listing-filters.component.html', + styleUrls: ['./prefilling-source-listing-filters.component.scss'] +}) +export class PrefillingSourceListingFiltersComponent extends BaseComponent implements OnInit, OnChanges { + + @Input() readonly filter: PrefillingSourceFilter; + @Output() filterChange = new EventEmitter(); + + // * State + internalFilters: PrefillingSourceListingFilters = this._getEmptyFilters(); + + protected appliedFilterCount: number = 0; + constructor( + public enumUtils: EnumUtils, + ) { super(); } + + ngOnInit() { + } + + ngOnChanges(changes: SimpleChanges): void { + const filterChange = changes[nameof(x => x.filter)]?.currentValue as PrefillingSourceFilter; + if (filterChange) { + this.updateFilters() + } + } + + + onSearchTermChange(searchTerm: string): void { + this.applyFilters() + } + + + protected updateFilters(): void { + this.internalFilters = this._parseToInternalFilters(this.filter); + this.appliedFilterCount = this._computeAppliedFilters(this.internalFilters); + } + + protected applyFilters(): void { + const { isActive, like } = this.internalFilters ?? {} + this.filterChange.emit({ + ...this.filter, + like, + isActive: isActive ? [IsActive.Active] : [IsActive.Inactive] + }) + } + + + private _parseToInternalFilters(inputFilter: PrefillingSourceFilter): PrefillingSourceListingFilters { + if (!inputFilter) { + return this._getEmptyFilters(); + } + + let { excludedIds, ids, isActive, like } = inputFilter; + + return { + isActive: (isActive ?? [])?.includes(IsActive.Active) || !isActive?.length, + like: like + } + + } + + private _getEmptyFilters(): PrefillingSourceListingFilters { + return { + isActive: true, + like: null, + } + } + + private _computeAppliedFilters(filters: PrefillingSourceListingFilters): number { + let count = 0; + if (filters?.isActive) { + count++ + } + return count; + } + + clearFilters() { + this.internalFilters = this._getEmptyFilters(); + } +} + +interface PrefillingSourceListingFilters { + isActive: boolean; + like: string; +} diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/listing/prefilling-source-listing.component.html b/dmp-frontend/src/app/ui/admin/prefilling-source/listing/prefilling-source-listing.component.html new file mode 100644 index 000000000..307834601 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/listing/prefilling-source-listing.component.html @@ -0,0 +1,96 @@ +
+
+ +
+
+

{{'PREFILLING-SOURCE-LISTING.TITLE' | translate}}

+ + +
+
+ +
+
+ + + + + + + + +
+
+ + + + +
+
+ + {{item?.name | nullifyValue}} +
+
+ + + + {{'PREFILLING-SOURCE-LISTING.FIELDS.CODE' | translate}}: + + {{item?.code | nullifyValue}} + + +
+
+ + + + {{'PREFILLING-SOURCE-LISTING.FIELDS.CREATED-AT' | translate}}: + + {{item?.createdAt | dateTimeFormatter : 'short' | nullifyValue}} + + +
+
+ + + {{'PREFILLING-SOURCE-LISTING.FIELDS.UPDATED-AT' | translate}}: + + {{item?.updatedAt | dateTimeFormatter : 'short' | nullifyValue}} + + + +
+
+
+ + +
+
+ + + + + +
+
+
\ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/listing/prefilling-source-listing.component.scss b/dmp-frontend/src/app/ui/admin/prefilling-source/listing/prefilling-source-listing.component.scss new file mode 100644 index 000000000..76392cf77 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/listing/prefilling-source-listing.component.scss @@ -0,0 +1,83 @@ +.mat-table { + margin-top: 47px; + border-radius: 4px; +} + +.prefilling-source-listing { + margin-top: 1.3rem; + margin-left: 1rem; + margin-right: 2rem; + + .mat-header-row { + background: #f3f5f8; + } + + .mat-card { + margin: 16px 0; + padding: 0px; + } + + .mat-row { + cursor: pointer; + min-height: 4.5em; + } + + mat-row:hover { + background-color: #eef5f6; + } + + .mat-fab-bottom-right { + float: right; + z-index: 5; + } +} + +// PAGINATOR +:host ::ng-deep .mat-paginator-container { + flex-direction: row-reverse !important; + justify-content: space-between !important; + background-color: #f6f6f6; + align-items: center; +} + +.create-btn { + border-radius: 30px; + background-color: var(--secondary-color); + padding-left: 2em; + padding-right: 2em; + // color: #000; + + .button-text { + display: inline-block; + } +} + +.import-btn { + background: #ffffff 0% 0% no-repeat padding-box; + border-radius: 30px; + // color: var(--primary-color); + // border: 1px solid var(--primary-color); + padding-left: 2em; + padding-right: 2em; + color: #000; + border: 1px solid #000; +} + +.status-chip { + + border-radius: 20px; + padding-left: 1em; + padding-right: 1em; + padding-top: 0.2em; + font-size: .8em; +} + +.status-chip-finalized { + color: #568b5a; + background: #9dd1a1 0% 0% no-repeat padding-box; +} + +.status-chip-draft { + color: #00c4ff; + background: #d3f5ff 0% 0% no-repeat padding-box; +} diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/listing/prefilling-source-listing.component.ts b/dmp-frontend/src/app/ui/admin/prefilling-source/listing/prefilling-source-listing.component.ts new file mode 100644 index 000000000..42f221f73 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/listing/prefilling-source-listing.component.ts @@ -0,0 +1,171 @@ +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Router } from '@angular/router'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { PrefillingSource } from '@app/core/model/prefilling-source/prefilling-source'; +import { PrefillingSourceLookup } from '@app/core/query/prefilling-source.lookup'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { PrefillingSourceService } from '@app/core/services/prefilling-source/prefilling-source.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; +import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; +import { BaseListingComponent } from '@common/base/base-listing-component'; +import { PipeService } from '@common/formatting/pipe.service'; +import { DataTableDateTimeFormatPipe } from '@common/formatting/pipes/date-time-format.pipe'; +import { QueryResult } from '@common/model/query-result'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; +import { ColumnDefinition, ColumnsChangedEvent, HybridListingComponent, PageLoadEvent } from '@common/modules/hybrid-listing/hybrid-listing.component'; +import { Guid } from '@common/types/guid'; +import { TranslateService } from '@ngx-translate/core'; +import { Observable } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { nameof } from 'ts-simple-nameof'; +import { IsActiveTypePipe } from '@common/formatting/pipes/is-active-type.pipe'; + +@Component({ + templateUrl: './prefilling-source-listing.component.html', + styleUrls: ['./prefilling-source-listing.component.scss'] +}) +export class PrefillingSourceListingComponent extends BaseListingComponent implements OnInit { + publish = false; + userSettingsKey = { key: 'PrefillingSourceListingUserSettings' }; + propertiesAvailableForOrder: ColumnDefinition[]; + + // @ViewChild('PrefillingSourceStatus', { static: true }) PrefillingSourceStatus?: TemplateRef; + @ViewChild('actions', { static: true }) actions?: TemplateRef; + @ViewChild(HybridListingComponent, { static: true }) hybridListingComponent: HybridListingComponent; + + private readonly lookupFields: string[] = [ + nameof(x => x.id), + nameof(x => x.label), + nameof(x => x.updatedAt), + nameof(x => x.createdAt), + nameof(x => x.hash), + nameof(x => x.isActive) + ]; + + rowIdentity = x => x.id; + + constructor( + protected router: Router, + protected route: ActivatedRoute, + protected uiNotificationService: UiNotificationService, + protected httpErrorHandlingService: HttpErrorHandlingService, + protected queryParamsService: QueryParamsService, + private PrefillingSourceService: PrefillingSourceService, + public authService: AuthService, + private pipeService: PipeService, + public enumUtils: EnumUtils, + private language: TranslateService, + private dialog: MatDialog + ) { + super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService); + // Lookup setup + // Default lookup values are defined in the user settings class. + this.lookup = this.initializeLookup(); + } + + ngOnInit() { + super.ngOnInit(); + } + + protected initializeLookup(): PrefillingSourceLookup { + const lookup = new PrefillingSourceLookup(); + lookup.metadata = { countAll: true }; + lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE }; + lookup.isActive = [IsActive.Active]; + lookup.order = { items: [this.toDescSortField(nameof(x => x.createdAt))] }; + this.updateOrderUiFields(lookup.order); + + lookup.project = { + fields: this.lookupFields + }; + + return lookup; + } + + protected setupColumns() { + this.gridColumns.push(...[{ + prop: nameof(x => x.label), + sortable: true, + languageName: 'PREFILLING-SOURCE-LISTING.FIELDS.LABEL' + }, + { + prop: nameof(x => x.createdAt), + sortable: true, + languageName: 'PREFILLING-SOURCE-LISTING.FIELDS.CREATED-AT', + pipe: this.pipeService.getPipe(DataTableDateTimeFormatPipe).withFormat('short') + }, + { + prop: nameof(x => x.updatedAt), + sortable: true, + languageName: 'PREFILLING-SOURCE-LISTING.FIELDS.UPDATED-AT', + pipe: this.pipeService.getPipe(DataTableDateTimeFormatPipe).withFormat('short') + }, + { + prop: nameof(x => x.isActive), + sortable: true, + languageName: 'PREFILLING-SOURCE-LISTING.FIELDS.IS-ACTIVE', + pipe: this.pipeService.getPipe(IsActiveTypePipe) + }, + { + alwaysShown: true, + cellTemplate: this.actions, + maxWidth: 120 + } + ]); + this.propertiesAvailableForOrder = this.gridColumns.filter(x => x.sortable); + } + + // + // Listing Component functions + // + onColumnsChanged(event: ColumnsChangedEvent) { + super.onColumnsChanged(event); + this.onColumnsChangedInternal(event.properties.map(x => x.toString())); + } + + private onColumnsChangedInternal(columns: string[]) { + // Here are defined the projection fields that always requested from the api. + const fields = new Set(this.lookupFields); + this.gridColumns.map(x => x.prop) + .filter(x => !columns?.includes(x as string)) + .forEach(item => { + fields.delete(item as string) + }); + this.lookup.project = { fields: [...fields] }; + this.onPageLoad({ offset: 0 } as PageLoadEvent); + } + + protected loadListing(): Observable> { + return this.PrefillingSourceService.query(this.lookup); + } + + public deleteType(id: Guid) { + if (id) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + data: { + isDeleteConfirmation: true, + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.PrefillingSourceService.delete(id).pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(), + error => this.onCallbackError(error) + ); + } + }); + } + } + + onCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); + this.refresh(); + } +} diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/prefilling-source.module.ts b/dmp-frontend/src/app/ui/admin/prefilling-source/prefilling-source.module.ts new file mode 100644 index 000000000..92f403cf7 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/prefilling-source.module.ts @@ -0,0 +1,40 @@ +import { DragDropModule } from '@angular/cdk/drag-drop'; +import { NgModule } from "@angular/core"; +import { AutoCompleteModule } from "@app/library/auto-complete/auto-complete.module"; +import { CommonFormattingModule } from '@common/formatting/common-formatting.module'; +import { CommonFormsModule } from '@common/forms/common-forms.module'; +import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module'; +import { HybridListingModule } from "@common/modules/hybrid-listing/hybrid-listing.module"; +import { TextFilterModule } from "@common/modules/text-filter/text-filter.module"; +import { UserSettingsModule } from "@common/modules/user-settings/user-settings.module"; +import { CommonUiModule } from '@common/ui/common-ui.module'; +import { NgxDropzoneModule } from "ngx-dropzone"; +import { PrefillingSourceRoutingModule } from './prefilling-source.routing'; +import { RichTextEditorModule } from '@app/library/rich-text-editor/rich-text-editor.module'; +import { PrefillingSourceListingComponent } from './listing/prefilling-source-listing.component'; +import { PrefillingSourceListingFiltersComponent } from './listing/filters/prefilling-source-listing-filters.component'; +import { PrefillingSourceEditorComponent } from './editor/prefilling-source-editor.component'; +import { ExternalFetcherSourceModule } from '@app/ui/external-fetcher/external-fetcher-source.module'; + +@NgModule({ + imports: [ + CommonUiModule, + CommonFormsModule, + ConfirmationDialogModule, + PrefillingSourceRoutingModule, + NgxDropzoneModule, + DragDropModule, + AutoCompleteModule, + HybridListingModule, + TextFilterModule, + UserSettingsModule, + CommonFormattingModule, + RichTextEditorModule, + ExternalFetcherSourceModule + ], + declarations: [ + PrefillingSourceEditorComponent, + PrefillingSourceListingComponent, + PrefillingSourceListingFiltersComponent ] +}) +export class PrefillingSourceModule { } diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/prefilling-source.routing.ts b/dmp-frontend/src/app/ui/admin/prefilling-source/prefilling-source.routing.ts new file mode 100644 index 000000000..4eedc48fe --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/prefilling-source.routing.ts @@ -0,0 +1,58 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { AdminAuthGuard } from '@app/core/admin-auth-guard.service'; +import { PrefillingSourceEditorComponent } from './editor/prefilling-source-editor.component'; +import { PrefillingSourceListingComponent } from './listing/prefilling-source-listing.component'; +import { AppPermission } from '@app/core/common/enum/permission.enum'; +import { AuthGuard } from '@app/core/auth-guard.service'; +import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; +import { PendingChangesGuard } from '@common/forms/pending-form-changes/pending-form-changes-guard.service'; +import { PrefillingSourceEditorResolver } from './editor/prefilling-source-editor.resolver'; + +const routes: Routes = [ + { + path: '', + component: PrefillingSourceListingComponent, + canActivate: [AuthGuard] + }, + { + path: 'new', + canActivate: [AuthGuard], + component: PrefillingSourceEditorComponent, + canDeactivate: [PendingChangesGuard], + data: { + authContext: { + permissions: [AppPermission.EditPrefillingSource] + }, + ...BreadcrumbService.generateRouteDataConfiguration({ + title: 'BREADCRUMBS.NEW-PREFILLING-SOURCE' + }) + } + }, + { + path: ':id', + canActivate: [AuthGuard], + component: PrefillingSourceEditorComponent, + canDeactivate: [PendingChangesGuard], + resolve: { + 'entity': PrefillingSourceEditorResolver + }, + data: { + ...BreadcrumbService.generateRouteDataConfiguration({ + title: 'BREADCRUMBS.EDIT-PREFILLING-SOURCE' + }), + authContext: { + permissions: [AppPermission.EditPrefillingSource] + } + } + + }, + { path: '**', loadChildren: () => import('@common/modules/page-not-found/page-not-found.module').then(m => m.PageNotFoundModule) }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], + providers: [PrefillingSourceEditorResolver] +}) +export class PrefillingSourceRoutingModule { } diff --git a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.html b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.html index d8cf90708..62248ebfd 100644 --- a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.html @@ -123,7 +123,7 @@ + type="button" (click)="submitFields()" [disabled]="!formGroup.get('definition').get('fields').valid">{{'REFERENCE-TYPE-EDITOR.ACTIONS.SUBMIT-FIELDS' | translate}} @@ -142,18 +142,26 @@
- -
-
- {{'REFERENCE-TYPE-EDITOR.FIELDS.SOURCE-CONFIGURATION' | translate}} {{sourceIndex + 1}} -
-
- -
+ +
+
+ {{'REFERENCE-TYPE-EDITOR.FIELDS.SOURCE-CONFIGURATION' | translate}} {{sourceIndex + 1}}
-
+
+ +
+
+ + + + + + Results info

{{'REFERENCE-TYPE-EDITOR.FIELDS.RESULTS' | translate}}

@@ -270,7 +281,7 @@ {{'GENERAL.VALIDATION.REQUIRED' | translate}}
- + fields mapping
@@ -304,7 +315,7 @@
- + Auth info

{{'REFERENCE-TYPE-EDITOR.FIELDS.AUTHENTICATION' | translate}}

@@ -354,7 +365,7 @@
- + Queries info

{{'REFERENCE-TYPE-EDITOR.FIELDS.QUERIES' | translate}}

@@ -397,7 +408,7 @@
- + Query Cases
@@ -437,16 +448,17 @@ {{case.get('value').getError('backendError').message}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} -
-
+
+
{{'REFERENCE-TYPE-EDITOR.FIELDS.REFERENCE-TYPE' | translate}} - - + + {{referenceType.code}} - - {{case.get('referenceTypeId').getError('backendError').message}} + --> + + + Options

{{'REFERENCE-TYPE-EDITOR.FIELDS.OPTIONS' | translate}}

@@ -506,7 +518,7 @@
-
+
--> @@ -514,7 +526,6 @@ {{formGroup.get('definition').get('sources').getError('backendError').message}} - {{formGroup.value | json}} diff --git a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.ts b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.ts index c9e6a0c0b..b6de26213 100644 --- a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.ts @@ -11,8 +11,8 @@ import { DatePipe } from '@angular/common'; import { IsActive } from '@app/core/common/enum/is-active.enum'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-type'; -import { ReferenceTypeExternalApiHTTPMethodType } from '@app/core/common/enum/reference-type-external-api-http-method-type'; -import { ReferenceTypeSourceType } from '@app/core/common/enum/reference-type-source-type'; +import { ExternalFetcherApiHTTPMethodType } from '@app/core/common/enum/external-fetcher-api-http-method-type'; +import { ExternalFetcherSourceType } from '@app/core/common/enum/external-fetcher-source-type'; import { ReferenceType, ReferenceTypeDefinition, ReferenceTypePersist } from '@app/core/model/reference-type/reference-type'; import { AuthService } from '@app/core/services/auth/auth.service'; import { LoggingService } from '@app/core/services/logging/logging-service'; @@ -42,11 +42,11 @@ export class ReferenceTypeEditorComponent extends BaseEditor(ReferenceTypeSourceType); + referenceTypeSourceType = ExternalFetcherSourceType; + referenceTypeExternalApiHTTPMethodType = ExternalFetcherApiHTTPMethodType; + public referenceTypeSourceTypeEnum = this.enumUtils.getEnumValues(ExternalFetcherSourceType); public referenceFieldDataTypeEnum = this.enumUtils.getEnumValues(ReferenceFieldDataType); - public referenceTypeExternalApiHTTPMethodTypeEnum = this.enumUtils.getEnumValues(ReferenceTypeExternalApiHTTPMethodType); + public referenceTypeExternalApiHTTPMethodTypeEnum = this.enumUtils.getEnumValues(ExternalFetcherApiHTTPMethodType); referenceTypes: ReferenceType[] = null; sourceKeysMap: Map = new Map(); @@ -111,14 +111,6 @@ export class ReferenceTypeEditorComponent extends BaseEditor source.queries?.forEach(query => { - query?.cases?.forEach(queryCase => { - if(queryCase.referenceType && queryCase.referenceType.id) this.selectedReferenceTypeChanged(queryCase.referenceType.id); - }) - })); - } - this.isDeleted = data ? data.isActive === IsActive.Inactive : false; this.buildForm(); } catch (error) { @@ -163,9 +155,9 @@ export class ReferenceTypeEditorComponent extends BaseEditor { this.referenceTypes = response.items as ReferenceType[]; this.referenceTypes.forEach(referenceType => { - this.sourceKeysMap.set(referenceType.id, []); + sourceKeys = referenceType.definition.sources.map(x => x.key); + this.sourceKeysMap.set(referenceType.id, sourceKeys); }) }); } diff --git a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.model.ts b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.model.ts index a663ee8f3..b761614dc 100644 --- a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.model.ts +++ b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.model.ts @@ -1,13 +1,11 @@ import { FormArray, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { ReferenceFieldDataType } from "@app/core/common/enum/reference-field-data-type"; -import { ReferenceTypeExternalApiHTTPMethodType } from "@app/core/common/enum/reference-type-external-api-http-method-type"; -import { ReferenceTypeSourceType } from "@app/core/common/enum/reference-type-source-type"; -import { AuthenticationConfiguration, AuthenticationConfigurationPersist, QueryCaseConfig, QueryCaseConfigPersist, QueryConfig, QueryConfigPersist, ReferenceType, ReferenceTypeDefinition, ReferenceTypeDefinitionPersist, ReferenceTypeField, ReferenceTypeFieldPersist, ReferenceTypePersist, ReferenceTypeSourceBaseConfiguration, ReferenceTypeSourceBaseConfigurationPersist, ReferenceTypeStaticOption, ReferenceTypeStaticOptionPersist, ResultFieldsMappingConfiguration, ResultFieldsMappingConfigurationPersist, ResultsConfiguration, ResultsConfigurationPersist } from "@app/core/model/reference-type/reference-type"; +import { ReferenceType, ReferenceTypeDefinition, ReferenceTypeDefinitionPersist, ReferenceTypeField, ReferenceTypeFieldPersist, ReferenceTypePersist } from "@app/core/model/reference-type/reference-type"; import { BaseEditorModel } from "@common/base/base-form-editor-model"; import { BackendErrorValidator } from "@common/forms/validation/custom-validator"; import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model"; import { Validation, ValidationContext } from "@common/forms/validation/validation-context"; -import { Guid } from "@common/types/guid"; +import { ExternalFetcherBaseSourceConfigurationEditorModel, QueryCaseConfigEditorModel, QueryConfigEditorModel, ResultFieldsMappingConfigurationEditorModel, StaticOptionEditorModel } from "@app/ui/external-fetcher/external-fetcher-source-editor.model"; export class ReferenceTypeEditorModel extends BaseEditorModel implements ReferenceTypePersist { name: string; @@ -66,7 +64,7 @@ export class ReferenceTypeEditorModel extends BaseEditorModel implements Referen } createChildSource(index: number): UntypedFormGroup { - const source: ReferenceTypeSourceBaseConfigurationEditorModel = new ReferenceTypeSourceBaseConfigurationEditorModel(this.validationErrorModel); + const source: ExternalFetcherBaseSourceConfigurationEditorModel = new ExternalFetcherBaseSourceConfigurationEditorModel(this.validationErrorModel); return source.buildForm({ rootPath: 'definition.sources[' + index + '].' }); } @@ -76,7 +74,7 @@ export class ReferenceTypeEditorModel extends BaseEditorModel implements Referen } createOptions(sourceIndex: number, index: number): UntypedFormGroup { - const fieldMapping: ReferenceTypeStaticOptionEditorModel = new ReferenceTypeStaticOptionEditorModel(this.validationErrorModel); + const fieldMapping: StaticOptionEditorModel = new StaticOptionEditorModel(this.validationErrorModel); return fieldMapping.buildForm({ rootPath: 'definition.sources[' + sourceIndex + '].options[' + index + '].'}); } @@ -121,7 +119,7 @@ export class ReferenceTypeEditorModel extends BaseEditorModel implements Referen export class ReferenceTypeDefinitionEditorModel implements ReferenceTypeDefinitionPersist { fields: ReferenceTypeFieldEditorModel[] = []; - sources: ReferenceTypeSourceBaseConfigurationEditorModel[] = []; + sources: ExternalFetcherBaseSourceConfigurationEditorModel[] = []; protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); @@ -132,7 +130,7 @@ export class ReferenceTypeDefinitionEditorModel implements ReferenceTypeDefiniti public fromModel(item: ReferenceTypeDefinition): ReferenceTypeDefinitionEditorModel { if (item) { if (item.fields) { item.fields.map(x => this.fields.push(new ReferenceTypeFieldEditorModel(this.validationErrorModel).fromModel(x))); } - if (item.sources) { item.sources.map(x => this.sources.push(new ReferenceTypeSourceBaseConfigurationEditorModel(this.validationErrorModel).fromModel(x))); } + if (item.sources) { item.sources.map(x => this.sources.push(new ExternalFetcherBaseSourceConfigurationEditorModel(this.validationErrorModel).fromModel(x))); } } return this; } @@ -207,7 +205,7 @@ export class ReferenceTypeDefinitionEditorModel implements ReferenceTypeDefiniti }): void { const { validationErrorModel, rootPath, formArray } = params; formArray?.controls?.forEach( - (control, index) => ReferenceTypeSourceBaseConfigurationEditorModel.reapplyValidators({ + (control, index) => ExternalFetcherBaseSourceConfigurationEditorModel.reapplyValidators({ formGroup: control as UntypedFormGroup, rootPath: `${rootPath}sources[${index}].`, validationErrorModel: validationErrorModel @@ -296,693 +294,3 @@ export class ReferenceTypeFieldEditorModel implements ReferenceTypeFieldPersist }) } } - -export class ReferenceTypeSourceBaseConfigurationEditorModel implements ReferenceTypeSourceBaseConfigurationPersist { - type: ReferenceTypeSourceType; - key: string; - label: string; - ordinal: number; - - url: string; - results: ResultsConfigurationEditorModel = new ResultsConfigurationEditorModel(this.validationErrorModel); - paginationPath: string; - contentType: string; - firstPage: string; - httpMethod: ReferenceTypeExternalApiHTTPMethodType; - requestBody?: string; - filterType?: string; - auth: AuthenticationConfigurationEditorModel = new AuthenticationConfigurationEditorModel(this.validationErrorModel); - queries?: QueryConfigEditorModel[] = []; - - options: ReferenceTypeStaticOptionEditorModel[] = []; - - referenceTypeDependencyIds: Guid[] = []; - - protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); - - constructor( - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() - ) { } - - public fromModel(item: ReferenceTypeSourceBaseConfiguration): ReferenceTypeSourceBaseConfigurationEditorModel { - if (item) { - this.type = item.type; - this.key = item.key; - this.label = item.label; - this.ordinal = item.ordinal; - - if (item.url) this.url = item.url; - if (item.results) this.results = new ResultsConfigurationEditorModel(this.validationErrorModel).fromModel(item.results); - if (item.paginationPath) this.paginationPath = item.paginationPath; - if (item.contentType) this.contentType = item.contentType; - if (item.firstPage) this.firstPage = item.firstPage; - if (item.httpMethod != null) this.httpMethod = item.httpMethod; - if (item.requestBody) this.requestBody = item.requestBody; - if (item.filterType) this.filterType = item.filterType; - if (item.auth) this.auth = new AuthenticationConfigurationEditorModel(this.validationErrorModel).fromModel(item.auth); - if (item.queries) { item.queries.map(x => this.queries.push(new QueryConfigEditorModel(this.validationErrorModel).fromModel(x))); } - - if (item.options) { - item.options.map(x => this.options.push(new ReferenceTypeStaticOptionEditorModel(this.validationErrorModel).fromModel(x))); - } else { - this.options.push(new ReferenceTypeStaticOptionEditorModel().fromModel({ code: 'reference_id', value: undefined })); - this.options.push(new ReferenceTypeStaticOptionEditorModel().fromModel({ code: 'label', value: undefined })); - this.options.push(new ReferenceTypeStaticOptionEditorModel().fromModel({ code: 'description', value: undefined })); - } - - if (item.referenceTypeDependencies) { item.referenceTypeDependencies.forEach(referenceType => this.referenceTypeDependencyIds.push(referenceType.id))} - } - return this; - } - - buildForm(params?: { - context?: ValidationContext, - disabled?: boolean, - rootPath?: string - }): UntypedFormGroup { - let { context = null, disabled = false, rootPath } = params ?? {} - if (context == null) { - context = ReferenceTypeSourceBaseConfigurationEditorModel.createValidationContext({ - validationErrorModel: this.validationErrorModel, - rootPath - }); - } - - return this.formBuilder.group({ - type: [{ value: this.type, disabled: disabled }, context.getValidation('type').validators], - key: [{ value: this.key, disabled: disabled }, context.getValidation('key').validators], - label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators], - ordinal: [{ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal').validators], - - url: [{ value: this.url, disabled: disabled }, context.getValidation('url').validators], - results: this.results.buildForm({ - rootPath: `${rootPath}results.`, - }), - paginationPath: [{ value: this.paginationPath, disabled: disabled }, context.getValidation('paginationPath').validators], - contentType: [{ value: this.contentType, disabled: disabled }, context.getValidation('contentType').validators], - firstPage: [{ value: this.firstPage, disabled: disabled }, context.getValidation('firstPage').validators], - httpMethod: [{ value: this.httpMethod, disabled: disabled }, context.getValidation('httpMethod').validators], - requestBody: [{ value: this.requestBody, disabled: disabled }, context.getValidation('requestBody').validators], - filterType: [{ value: this.filterType, disabled: disabled }, context.getValidation('filterType').validators], - auth: this.auth.buildForm({ - rootPath: `${rootPath}auth.` - }), - queries: this.formBuilder.array( - (this.queries ?? []).map( - (item, index) => item.buildForm({ - rootPath: `${rootPath}queries[${index}].` - }) - ), context.getValidation('queries').validators - ), - options: this.formBuilder.array( - (this.options ?? []).map( - (item, index) => new ReferenceTypeStaticOptionEditorModel( - this.validationErrorModel - ).fromModel(item).buildForm({ - rootPath: `${rootPath}options[${index}].` - }) - ), context.getValidation('options').validators - ), - referenceTypeDependencyIds: [{ value: this.referenceTypeDependencyIds, disabled: disabled }, context.getValidation('referenceTypeDependencyIds').validators], - - }); - } - - static createValidationContext(params: { - rootPath?: string, - validationErrorModel: ValidationErrorModel - }): ValidationContext { - const { rootPath = '', validationErrorModel } = params; - - const baseContext: ValidationContext = new ValidationContext(); - const baseValidationArray: Validation[] = new Array(); - baseValidationArray.push({ key: 'type', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}type`)] }); - baseValidationArray.push({ key: 'key', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}key`)] }); - baseValidationArray.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}label`)] }); - baseValidationArray.push({ key: 'ordinal', validators: [Validators.required, Validators.pattern("^[0-9]*$"), BackendErrorValidator(validationErrorModel, `${rootPath}ordinal`)] }); - - baseValidationArray.push({ key: 'url', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}url`)] }); - baseValidationArray.push({ key: 'paginationPath', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}paginationPath`)] }); - baseValidationArray.push({ key: 'contentType', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}contentType`)] }); - baseValidationArray.push({ key: 'firstPage', validators: [Validators.pattern("^[0-9]*$"), BackendErrorValidator(validationErrorModel, `${rootPath}firstPage`)] }); - baseValidationArray.push({ key: 'httpMethod', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}httpMethod`)] }); - baseValidationArray.push({ key: 'requestBody', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}requestBody`)] }); - baseValidationArray.push({ key: 'filterType', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}filterType`)] }); - baseValidationArray.push({ key: 'results', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}results`)] }); - baseValidationArray.push({ key: 'queries', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}queries`)] }); - - baseValidationArray.push({ key: 'options', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}options`)] }); - - baseValidationArray.push({ key: 'referenceTypeDependencyIds', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}referenceTypeDependencyIds`)] }); - - baseContext.validation = baseValidationArray; - return baseContext; - } - - static reapplyValidators(params: { - formGroup: UntypedFormGroup, - validationErrorModel: ValidationErrorModel, - rootPath: string - }): void { - - const { formGroup, rootPath, validationErrorModel } = params; - const context = ReferenceTypeSourceBaseConfigurationEditorModel.createValidationContext({ - rootPath, - validationErrorModel - }); - - ['type', 'key', 'label', 'ordinal', 'url', 'paginationPath', 'contentType', 'firstPage', 'httpMethod', 'requestBody','filterType', 'referenceTypeDependencyIds'].forEach(keyField => { - const control = formGroup?.get(keyField); - control?.clearValidators(); - control?.addValidators(context.getValidation(keyField).validators); - }); - - AuthenticationConfigurationEditorModel.reapplyAuthValidators({ - formGroup: formGroup?.get('auth') as UntypedFormGroup, - rootPath: `${rootPath}auth.`, - validationErrorModel: validationErrorModel - }); - - ResultsConfigurationEditorModel.reapplyValidators({ - formGroup: formGroup?.get('results') as UntypedFormGroup, - rootPath: `${rootPath}results.`, - validationErrorModel: validationErrorModel - }); - - (formGroup.get('options') as FormArray).controls?.forEach( - (control, index) => ReferenceTypeStaticOptionEditorModel.reapplyStaticOptionsValidators({ - formGroup: control as UntypedFormGroup, - rootPath: `${rootPath}options[${index}].`, - validationErrorModel: validationErrorModel - } - ) - ); - - (formGroup.get('queries') as FormArray).controls?.forEach( - (control, index) => QueryConfigEditorModel.reapplyValidators({ - formGroup: control as UntypedFormGroup, - rootPath: `${rootPath}queries[${index}].`, - validationErrorModel: validationErrorModel - }) - ); - - } -} - -export class ResultsConfigurationEditorModel implements ResultsConfigurationPersist { - public resultsArrayPath: string; - public fieldsMapping: ResultFieldsMappingConfigurationEditorModel[] = []; - - protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); - - constructor( - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() - ) { } - - fromModel(item: ResultsConfiguration): ResultsConfigurationEditorModel { - this.resultsArrayPath = item.resultsArrayPath; - if (item.fieldsMapping) { item.fieldsMapping.map(x => this.fieldsMapping.push(new ResultFieldsMappingConfigurationEditorModel(this.validationErrorModel).fromModel(x))); } - else { - this.fieldsMapping.push(new ResultFieldsMappingConfigurationEditorModel(this.validationErrorModel).fromModel({ code: 'reference_id', responsePath: undefined })); - this.fieldsMapping.push(new ResultFieldsMappingConfigurationEditorModel(this.validationErrorModel).fromModel({ code: 'label', responsePath: undefined })); - this.fieldsMapping.push(new ResultFieldsMappingConfigurationEditorModel(this.validationErrorModel).fromModel({ code: 'description', responsePath: undefined })); - } - return this; - } - - buildForm(params?: { - context?: ValidationContext, - disabled?: boolean, - rootPath?: string - }): UntypedFormGroup { - let { context = null, disabled = false, rootPath } = params ?? {} - if (context == null) { - context = ResultsConfigurationEditorModel.createValidationContext({ - validationErrorModel: this.validationErrorModel, - rootPath - }); - } - - return this.formBuilder.group({ - resultsArrayPath: [{ value: this.resultsArrayPath, disabled: disabled }, context.getValidation('resultsArrayPath').validators], - fieldsMapping: this.formBuilder.array( - (this.fieldsMapping ?? []).map( - (item, index) => new ResultFieldsMappingConfigurationEditorModel( - this.validationErrorModel - ).fromModel(item).buildForm({ - rootPath: `${rootPath}fieldsMapping[${index}].` - }) - ), context.getValidation('fieldsMapping').validators - ) - - }); - } - - static createValidationContext(params: { - rootPath?: string, - validationErrorModel: ValidationErrorModel - }): ValidationContext { - const { rootPath = '', validationErrorModel } = params; - - const baseContext: ValidationContext = new ValidationContext(); - const baseValidationArray: Validation[] = new Array(); - baseValidationArray.push({ key: 'resultsArrayPath', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}resultsArrayPath`)] }); - baseValidationArray.push({ key: 'fieldsMapping', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}fieldsMapping`)] }); - - baseContext.validation = baseValidationArray; - return baseContext; - } - - static reapplyValidators(params: { - formGroup: UntypedFormGroup, - validationErrorModel: ValidationErrorModel, - rootPath: string - }): void { - - const { formGroup, rootPath, validationErrorModel } = params; - const context = ResultsConfigurationEditorModel.createValidationContext({ - rootPath, - validationErrorModel - }); - - ['resultsArrayPath'].forEach(keyField => { - const control = formGroup?.get(keyField); - control?.clearValidators(); - control?.addValidators(context.getValidation(keyField).validators); - }); - - (formGroup.get('fieldsMapping') as FormArray).controls?.forEach( - (control, index) => ResultFieldsMappingConfigurationEditorModel.reapplyFieldsMappingValidators({ - formGroup: control as UntypedFormGroup, - rootPath: `${rootPath}fieldsMapping[${index}].`, - validationErrorModel: validationErrorModel - } - ) - ); - } -} - -export class ResultFieldsMappingConfigurationEditorModel implements ResultFieldsMappingConfigurationPersist { - public code: string; - public responsePath: string; - - protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); - - constructor( - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() - ) { } - - fromModel(item: ResultFieldsMappingConfiguration): ResultFieldsMappingConfigurationEditorModel { - this.code = item.code; - this.responsePath = item.responsePath; - - return this; - } - - buildForm(params?: { - context?: ValidationContext, - disabled?: boolean, - rootPath?: string - }): UntypedFormGroup { - let { context = null, disabled = false, rootPath } = params ?? {} - if (context == null) { - context = ResultFieldsMappingConfigurationEditorModel.createValidationContext({ - validationErrorModel: this.validationErrorModel, - rootPath - }); - } - - return this.formBuilder.group({ - code: [{ value: this.code, disabled: true }, context.getValidation('code').validators], - responsePath: [{ value: this.responsePath, disabled: disabled }, context.getValidation('responsePath').validators], - }); - } - - static createValidationContext(params: { - rootPath?: string, - validationErrorModel: ValidationErrorModel - }): ValidationContext { - const { rootPath = '', validationErrorModel } = params; - - const baseContext: ValidationContext = new ValidationContext(); - const baseValidationArray: Validation[] = new Array(); - baseValidationArray.push({ key: 'code', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}code`)] }); - baseValidationArray.push({ key: 'responsePath', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}responsePath`)] }); - - baseContext.validation = baseValidationArray; - return baseContext; - } - - static reapplyFieldsMappingValidators(params: { - formGroup: UntypedFormGroup, - validationErrorModel: ValidationErrorModel, - rootPath: string - }): void { - - const { formGroup, rootPath, validationErrorModel } = params; - const context = ResultFieldsMappingConfigurationEditorModel.createValidationContext({ - rootPath, - validationErrorModel - }); - - ['code', 'responsePath'].forEach(keyField => { - const control = formGroup?.get(keyField); - control?.clearValidators(); - control?.addValidators(context.getValidation(keyField).validators); - }); - } -} - -export class AuthenticationConfigurationEditorModel implements AuthenticationConfigurationPersist { - public enabled: boolean = false; - public authUrl: string; - public authMethod: ReferenceTypeExternalApiHTTPMethodType; - public authTokenPath: string; - public authRequestBody: string; - public type: string; - - protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); - - constructor( - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() - ) { } - - fromModel(item: AuthenticationConfiguration): AuthenticationConfigurationEditorModel { - this.enabled = item.enabled; - this.authUrl = item.authUrl; - this.authMethod = item.authMethod; - this.authTokenPath = item.authTokenPath; - this.authRequestBody = item.authRequestBody; - this.type = item.type; - - return this; - } - - buildForm(params?: { - context?: ValidationContext, - disabled?: boolean, - rootPath?: string - }): UntypedFormGroup { - let { context = null, disabled = false, rootPath } = params ?? {} - if (context == null) { - context = AuthenticationConfigurationEditorModel.createValidationContext({ - validationErrorModel: this.validationErrorModel, - rootPath - }); - } - - return this.formBuilder.group({ - enabled: [{ value: this.enabled, disabled: disabled }, context.getValidation('enabled').validators], - authUrl: [{ value: this.authUrl, disabled: disabled }, context.getValidation('authUrl').validators], - authMethod: [{ value: this.authMethod, disabled: disabled }, context.getValidation('authMethod').validators], - authTokenPath: [{ value: this.authTokenPath, disabled: disabled }, context.getValidation('authTokenPath').validators], - authRequestBody: [{ value: this.authRequestBody, disabled: disabled }, context.getValidation('authRequestBody').validators], - type: [{ value: this.type, disabled: disabled }, context.getValidation('type').validators], - }); - } - - static createValidationContext(params: { - rootPath?: string, - validationErrorModel: ValidationErrorModel - }): ValidationContext { - const { rootPath = '', validationErrorModel } = params; - - const baseContext: ValidationContext = new ValidationContext(); - const baseValidationArray: Validation[] = new Array(); - baseValidationArray.push({ key: 'enabled', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}enabled`)] }); - baseValidationArray.push({ key: 'authUrl', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}authUrl`)] }); - baseValidationArray.push({ key: 'authMethod', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}authMethod`)] }); - baseValidationArray.push({ key: 'authTokenPath', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}authTokenPath`)] }); - baseValidationArray.push({ key: 'authRequestBody', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}authRequestBody`)] }); - baseValidationArray.push({ key: 'type', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}type`)] }); - - baseContext.validation = baseValidationArray; - return baseContext; - } - - static reapplyAuthValidators(params: { - formGroup: UntypedFormGroup, - validationErrorModel: ValidationErrorModel, - rootPath: string - }): void { - - const { formGroup, rootPath, validationErrorModel } = params; - const context = AuthenticationConfigurationEditorModel.createValidationContext({ - rootPath, - validationErrorModel - }); - - ['enabled', 'authUrl', 'authMethod', 'authTokenPath', 'authRequestBody', 'type'].forEach(keyField => { - const control = formGroup?.get(keyField); - control?.clearValidators(); - control?.addValidators(context.getValidation(keyField).validators); - }) - } -} - -export class QueryConfigEditorModel implements QueryConfigPersist { - public name: string; - public defaultValue: string; - public cases: QueryCaseConfigEditorModel[] = []; - - protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); - - constructor( - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() - ) { } - - fromModel(item: QueryConfig): QueryConfigEditorModel { - this.name = item.name; - this.defaultValue = item.defaultValue; - if (item.cases) { item.cases.map(x => this.cases.push(new QueryCaseConfigEditorModel(this.validationErrorModel).fromModel(x))); } - - return this; - } - - buildForm(params?: { - context?: ValidationContext, - disabled?: boolean, - rootPath?: string - }): UntypedFormGroup { - let { context = null, disabled = false, rootPath } = params ?? {} - if (context == null) { - context = QueryConfigEditorModel.createValidationContext({ - validationErrorModel: this.validationErrorModel, - rootPath - }); - } - - return this.formBuilder.group({ - name: [{ value: this.name, disabled: disabled }, context.getValidation('name').validators], - defaultValue: [{ value: this.defaultValue, disabled: disabled }, context.getValidation('defaultValue').validators], - cases: this.formBuilder.array( - (this.cases ?? []).map( - (item, index) => item.buildForm({ - rootPath: `${rootPath}cases[${index}].` - }) - ), context.getValidation('cases').validators - ) - }); - } - - static createValidationContext(params: { - rootPath?: string, - validationErrorModel: ValidationErrorModel - }): ValidationContext { - const { rootPath = '', validationErrorModel } = params; - - const baseContext: ValidationContext = new ValidationContext(); - const baseValidationArray: Validation[] = new Array(); - baseValidationArray.push({ key: 'name', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}name`)] }); - baseValidationArray.push({ key: 'defaultValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}defaultValue`)] }); - baseValidationArray.push({ key: 'cases', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}cases`)] }); - - baseContext.validation = baseValidationArray; - return baseContext; - } - - static reapplyValidators(params: { - formGroup: UntypedFormGroup, - validationErrorModel: ValidationErrorModel, - rootPath: string - }): void { - - const { formGroup, rootPath, validationErrorModel } = params; - const context = QueryConfigEditorModel.createValidationContext({ - rootPath, - validationErrorModel - }); - - ['name', 'defaultValue'].forEach(keyField => { - const control = formGroup?.get(keyField); - control?.clearValidators(); - control?.addValidators(context.getValidation(keyField).validators); - }); - - (formGroup.get('cases') as FormArray).controls?.forEach( - (control, index) => QueryCaseConfigEditorModel.reapplyValidators({ - formGroup: control as UntypedFormGroup, - rootPath: `${rootPath}cases[${index}].`, - validationErrorModel: validationErrorModel - } - ) - ); - } -} - -export class QueryCaseConfigEditorModel implements QueryCaseConfigPersist { - public likePattern: string; - public separator: string; - public value: string; - public referenceTypeId: Guid; - public referenceTypeSourceKey: string; - - protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); - - constructor( - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() - ) { } - - fromModel(item: QueryCaseConfig): QueryCaseConfigEditorModel { - this.likePattern = item.likePattern; - this.separator = item.separator; - this.value = item.value; - if(item?.referenceType?.id) this.referenceTypeId = item.referenceType.id; - this.referenceTypeSourceKey = item.referenceTypeSourceKey; - - return this; - } - - buildForm(params?: { - context?: ValidationContext, - disabled?: boolean, - rootPath?: string - }): UntypedFormGroup { - let { context = null, disabled = false, rootPath } = params ?? {} - if (context == null) { - context = QueryCaseConfigEditorModel.createValidationContext({ - validationErrorModel: this.validationErrorModel, - rootPath - }); - } - - return this.formBuilder.group({ - likePattern: [{ value: this.likePattern, disabled: disabled }, context.getValidation('likePattern').validators], - separator: [{ value: this.separator, disabled: disabled }, context.getValidation('separator').validators], - value: [{ value: this.value, disabled: disabled }, context.getValidation('value').validators], - referenceTypeId: [{ value: this.referenceTypeId, disabled: disabled }, context.getValidation('referenceTypeId').validators], - referenceTypeSourceKey: [{ value: this.referenceTypeSourceKey, disabled: disabled }, context.getValidation('referenceTypeSourceKey').validators], - }); - } - - static createValidationContext(params: { - rootPath?: string, - validationErrorModel: ValidationErrorModel - }): ValidationContext { - const { rootPath = '', validationErrorModel } = params; - - const baseContext: ValidationContext = new ValidationContext(); - const baseValidationArray: Validation[] = new Array(); - baseValidationArray.push({ key: 'likePattern', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}likePattern`)] }); - baseValidationArray.push({ key: 'separator', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}separator`)] }); - baseValidationArray.push({ key: 'value', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}value`)] }); - baseValidationArray.push({ key: 'referenceTypeId', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}referenceTypeId`)] }); - baseValidationArray.push({ key: 'referenceTypeSourceKey', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}referenceTypeSourceKey`)] }); - - baseContext.validation = baseValidationArray; - return baseContext; - } - - static reapplyValidators(params: { - formGroup: UntypedFormGroup, - validationErrorModel: ValidationErrorModel, - rootPath: string - }): void { - - const { formGroup, rootPath, validationErrorModel } = params; - const context = QueryCaseConfigEditorModel.createValidationContext({ - rootPath, - validationErrorModel - }); - - ['likePattern', 'separator', 'value', 'referenceTypeId', 'referenceTypeSourceKey'].forEach(keyField => { - const control = formGroup?.get(keyField); - control?.clearValidators(); - control?.addValidators(context.getValidation(keyField).validators); - }) - } -} - -export class ReferenceTypeStaticOptionEditorModel implements ReferenceTypeStaticOptionPersist { - public code: string; - public value: string; - - - protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); - - constructor( - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() - ) { } - - fromModel(item: ReferenceTypeStaticOption): ReferenceTypeStaticOptionEditorModel { - this.code = item.code; - this.value = item.value; - - return this; - } - - buildForm(params?: { - context?: ValidationContext, - disabled?: boolean, - rootPath?: string - }): UntypedFormGroup { - let { context = null, disabled = false, rootPath } = params ?? {} - if (context == null) { - context = ReferenceTypeStaticOptionEditorModel.createValidationContext({ - validationErrorModel: this.validationErrorModel, - rootPath - }); - } - - return this.formBuilder.group({ - code: [{ value: this.code, disabled: true }, context.getValidation('code').validators], - value: [{ value: this.value, disabled: disabled }, context.getValidation('value').validators], - }); - } - - static createValidationContext(params: { - rootPath?: string, - validationErrorModel: ValidationErrorModel - }): ValidationContext { - const { rootPath = '', validationErrorModel } = params; - - const baseContext: ValidationContext = new ValidationContext(); - const baseValidationArray: Validation[] = new Array(); - baseValidationArray.push({ key: 'code', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}code`)] }); - baseValidationArray.push({ key: 'value', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}value`)] }); - - baseContext.validation = baseValidationArray; - return baseContext; - } - - static reapplyStaticOptionsValidators(params: { - formGroup: UntypedFormGroup, - validationErrorModel: ValidationErrorModel, - rootPath: string - }): void { - - const { formGroup, rootPath, validationErrorModel } = params; - const context = ReferenceTypeStaticOptionEditorModel.createValidationContext({ - rootPath, - validationErrorModel - }); - - ['code', 'value'].forEach(keyField => { - const control = formGroup?.get(keyField); - control?.clearValidators(); - control?.addValidators(context.getValidation(keyField).validators); - }); - - } -} - diff --git a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.resolver.ts b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.resolver.ts index fac38d952..0ec6d22c9 100644 --- a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.resolver.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; -import { AuthenticationConfiguration, QueryConfig, ReferenceType, ReferenceTypeDefinition, ReferenceTypeField, ReferenceTypeSourceBaseConfiguration, ResultsConfiguration, ResultFieldsMappingConfiguration, ReferenceTypeStaticOption, QueryCaseConfig } from '@app/core/model/reference-type/reference-type'; +import { AuthenticationConfiguration, ExternalFetcherBaseSourceConfiguration, QueryCaseConfig, QueryConfig, ResultFieldsMappingConfiguration, ResultsConfiguration, StaticOption } from '@app/core/model/external-fetcher/external-fetcher'; +import { ReferenceType, ReferenceTypeDefinition, ReferenceTypeField } from '@app/core/model/reference-type/reference-type'; import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service'; import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; import { BaseEditorResolver } from '@common/base/base-editor.resolver'; @@ -27,45 +28,45 @@ export class ReferenceTypeEditorResolver extends BaseEditorResolver { [nameof(x => x.definition), nameof(x => x.fields), nameof(x => x.description)].join('.'), [nameof(x => x.definition), nameof(x => x.fields), nameof(x => x.dataType)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.type)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.key)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.label)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.ordinal)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.referenceTypeDependencies),nameof(x => x.id)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.referenceTypeDependencies),nameof(x => x.name)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.type)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.key)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.label)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.ordinal)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.referenceTypeDependencies),nameof(x => x.id)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.referenceTypeDependencies),nameof(x => x.name)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.url)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.results), nameof(x => x.resultsArrayPath)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.url)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.results), nameof(x => x.resultsArrayPath)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.results), nameof(x => x.fieldsMapping), nameof(x => x.code)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.results), nameof(x => x.fieldsMapping), nameof(x => x.responsePath)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.results), nameof(x => x.fieldsMapping), nameof(x => x.code)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.results), nameof(x => x.fieldsMapping), nameof(x => x.responsePath)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.paginationPath)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.contentType)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.firstPage)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.httpMethod)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.requestBody)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.filterType)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.paginationPath)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.contentType)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.firstPage)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.httpMethod)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.requestBody)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.filterType)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.auth),nameof(x => x.enabled)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.auth),nameof(x => x.authUrl)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.auth),nameof(x => x.authMethod)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.auth),nameof(x => x.authTokenPath)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.auth),nameof(x => x.authRequestBody)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.auth),nameof(x => x.type)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.auth),nameof(x => x.enabled)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.auth),nameof(x => x.authUrl)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.auth),nameof(x => x.authMethod)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.auth),nameof(x => x.authTokenPath)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.auth),nameof(x => x.authRequestBody)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.auth),nameof(x => x.type)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.name)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.defaultValue)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.likePattern)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.separator)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.value)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.referenceType)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.referenceType),nameof(x => x.id)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.referenceType),nameof(x => x.name)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.referenceTypeSourceKey)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.name)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.defaultValue)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.likePattern)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.separator)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.value)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.referenceType)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.referenceType),nameof(x => x.id)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.referenceType),nameof(x => x.name)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.queries),nameof(x => x.cases),nameof(x => x.referenceTypeSourceKey)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.options),nameof(x => x.code)].join('.'), - [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.options),nameof(x => x.value)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.options),nameof(x => x.code)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.options),nameof(x => x.value)].join('.'), nameof(x => x.createdAt), nameof(x => x.updatedAt), diff --git a/dmp-frontend/src/app/ui/admin/reference-type/reference-type.module.ts b/dmp-frontend/src/app/ui/admin/reference-type/reference-type.module.ts index 57eca9e06..b160fbb8d 100644 --- a/dmp-frontend/src/app/ui/admin/reference-type/reference-type.module.ts +++ b/dmp-frontend/src/app/ui/admin/reference-type/reference-type.module.ts @@ -15,6 +15,7 @@ import { DragDropModule } from '@angular/cdk/drag-drop'; import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module'; import { CommonFormattingModule } from '@common/formatting/common-formatting.module'; import { ReferenceTypeListingComponent } from './listing/reference-type-listing.component'; +import { ExternalFetcherSourceModule } from '@app/ui/external-fetcher/external-fetcher-source.module'; @NgModule({ @@ -36,7 +37,8 @@ import { ReferenceTypeListingComponent } from './listing/reference-type-listing. NgxDropzoneModule, DragDropModule, AutoCompleteModule, - CommonFormattingModule + CommonFormattingModule, + ExternalFetcherSourceModule ] }) export class ReferenceTypeModule { } diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html index 72761e31c..6b08a1e55 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html @@ -162,7 +162,7 @@ -

{{ 'DMP-OVERVIEW.OVERVIEW.NEW-VERSION' | translate }} +

{{ 'DMP-OVERVIEW.ACTIONS.NEW-VERSION' | translate }}

diff --git a/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source-editor.model.ts b/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source-editor.model.ts new file mode 100644 index 000000000..550c097e9 --- /dev/null +++ b/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source-editor.model.ts @@ -0,0 +1,697 @@ +import { FormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; +import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model"; +import { Validation, ValidationContext } from "@common/forms/validation/validation-context"; +import { BackendErrorValidator } from "@common/forms/validation/custom-validator"; +import { ExternalFetcherApiHTTPMethodType } from "@app/core/common/enum/external-fetcher-api-http-method-type"; +import { ExternalFetcherSourceType } from "@app/core/common/enum/external-fetcher-source-type"; +import { AuthenticationConfiguration, AuthenticationConfigurationPersist, ExternalFetcherBaseSourceConfiguration, ExternalFetcherBaseSourceConfigurationPersist, QueryCaseConfig, QueryCaseConfigPersist, QueryConfig, QueryConfigPersist, ResultFieldsMappingConfiguration, ResultFieldsMappingConfigurationPersist, ResultsConfiguration, ResultsConfigurationPersist, StaticOption, StaticOptionPersist } from "@app/core/model/external-fetcher/external-fetcher"; +import { Guid } from "@common/types/guid"; + +export class ExternalFetcherBaseSourceConfigurationEditorModel implements ExternalFetcherBaseSourceConfigurationPersist { + type: ExternalFetcherSourceType = ExternalFetcherSourceType.API; + key: string; + label: string; + ordinal: number; + + url: string; + results: ResultsConfigurationEditorModel = new ResultsConfigurationEditorModel(this.validationErrorModel); + paginationPath: string; + contentType: string; + firstPage: string; + httpMethod: ExternalFetcherApiHTTPMethodType; + requestBody?: string; + filterType?: string; + auth: AuthenticationConfigurationEditorModel = new AuthenticationConfigurationEditorModel(this.validationErrorModel); + queries?: QueryConfigEditorModel[] = []; + + options: StaticOptionEditorModel[] = []; + + referenceTypeDependencyIds: Guid[]; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + public fromModel(item: ExternalFetcherBaseSourceConfiguration): ExternalFetcherBaseSourceConfigurationEditorModel { + if (item) { + this.type = item.type; + this.key = item.key; + this.label = item.label; + this.ordinal = item.ordinal; + + if (item.url) this.url = item.url; + if (item.results) this.results = new ResultsConfigurationEditorModel(this.validationErrorModel).fromModel(item.results); + if (item.paginationPath) this.paginationPath = item.paginationPath; + if (item.contentType) this.contentType = item.contentType; + if (item.firstPage) this.firstPage = item.firstPage; + if (item.httpMethod != null) this.httpMethod = item.httpMethod; + if (item.requestBody) this.requestBody = item.requestBody; + if (item.filterType) this.filterType = item.filterType; + if (item.auth) this.auth = new AuthenticationConfigurationEditorModel(this.validationErrorModel).fromModel(item.auth); + if (item.queries) { item.queries.map(x => this.queries.push(new QueryConfigEditorModel(this.validationErrorModel).fromModel(x))); } + + if (item.options) { + item.options.map(x => this.options.push(new StaticOptionEditorModel(this.validationErrorModel).fromModel(x))); + } else { + this.options.push(new StaticOptionEditorModel().fromModel({ code: 'reference_id', value: undefined })); + this.options.push(new StaticOptionEditorModel().fromModel({ code: 'label', value: undefined })); + this.options.push(new StaticOptionEditorModel().fromModel({ code: 'description', value: undefined })); + } + + if (item.referenceTypeDependencies) { this.referenceTypeDependencyIds = item.referenceTypeDependencies.map(x => x.id)} + } + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = ExternalFetcherBaseSourceConfigurationEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + type: [{ value: this.type, disabled: disabled }, context.getValidation('type').validators], + key: [{ value: this.key, disabled: disabled }, context.getValidation('key').validators], + label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators], + ordinal: [{ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal').validators], + + url: [{ value: this.url, disabled: disabled }, context.getValidation('url').validators], + results: this.results.buildForm({ + rootPath: `${rootPath}results.`, + }), + paginationPath: [{ value: this.paginationPath, disabled: disabled }, context.getValidation('paginationPath').validators], + contentType: [{ value: this.contentType, disabled: disabled }, context.getValidation('contentType').validators], + firstPage: [{ value: this.firstPage, disabled: disabled }, context.getValidation('firstPage').validators], + httpMethod: [{ value: this.httpMethod, disabled: disabled }, context.getValidation('httpMethod').validators], + requestBody: [{ value: this.requestBody, disabled: disabled }, context.getValidation('requestBody').validators], + filterType: [{ value: this.filterType, disabled: disabled }, context.getValidation('filterType').validators], + auth: this.auth.buildForm({ + rootPath: `${rootPath}auth.` + }), + queries: this.formBuilder.array( + (this.queries ?? []).map( + (item, index) => item.buildForm({ + rootPath: `${rootPath}queries[${index}].` + }) + ), context.getValidation('queries').validators + ), + options: this.formBuilder.array( + (this.options ?? []).map( + (item, index) => new StaticOptionEditorModel( + this.validationErrorModel + ).fromModel(item).buildForm({ + rootPath: `${rootPath}options[${index}].` + }) + ), context.getValidation('options').validators + ), + referenceTypeDependencyIds: [{ value: this.referenceTypeDependencyIds, disabled: disabled }, context.getValidation('referenceTypeDependencyIds').validators], + + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'type', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}type`)] }); + baseValidationArray.push({ key: 'key', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}key`)] }); + baseValidationArray.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}label`)] }); + baseValidationArray.push({ key: 'ordinal', validators: [Validators.required, Validators.pattern("^[0-9]*$"), BackendErrorValidator(validationErrorModel, `${rootPath}ordinal`)] }); + + baseValidationArray.push({ key: 'url', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}url`)] }); + baseValidationArray.push({ key: 'paginationPath', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}paginationPath`)] }); + baseValidationArray.push({ key: 'contentType', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}contentType`)] }); + baseValidationArray.push({ key: 'firstPage', validators: [Validators.pattern("^[0-9]*$"), BackendErrorValidator(validationErrorModel, `${rootPath}firstPage`)] }); + baseValidationArray.push({ key: 'httpMethod', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}httpMethod`)] }); + baseValidationArray.push({ key: 'requestBody', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}requestBody`)] }); + baseValidationArray.push({ key: 'filterType', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}filterType`)] }); + baseValidationArray.push({ key: 'results', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}results`)] }); + baseValidationArray.push({ key: 'queries', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}queries`)] }); + + baseValidationArray.push({ key: 'options', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}options`)] }); + + baseValidationArray.push({ key: 'referenceTypeDependencyIds', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}referenceTypeDependencyIds`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = ExternalFetcherBaseSourceConfigurationEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['type', 'key', 'label', 'ordinal', 'url', 'paginationPath', 'contentType', 'firstPage', 'httpMethod', 'requestBody','filterType', 'referenceTypeDependencyIds'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }); + + AuthenticationConfigurationEditorModel.reapplyAuthValidators({ + formGroup: formGroup?.get('auth') as UntypedFormGroup, + rootPath: `${rootPath}auth.`, + validationErrorModel: validationErrorModel + }); + + ResultsConfigurationEditorModel.reapplyValidators({ + formGroup: formGroup?.get('results') as UntypedFormGroup, + rootPath: `${rootPath}results.`, + validationErrorModel: validationErrorModel + }); + + (formGroup.get('options') as FormArray).controls?.forEach( + (control, index) => StaticOptionEditorModel.reapplyStaticOptionsValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}options[${index}].`, + validationErrorModel: validationErrorModel + } + ) + ); + + (formGroup.get('queries') as FormArray).controls?.forEach( + (control, index) => QueryConfigEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}queries[${index}].`, + validationErrorModel: validationErrorModel + }) + ); + + } +} + +export class ResultsConfigurationEditorModel implements ResultsConfigurationPersist { + public resultsArrayPath: string; + public fieldsMapping: ResultFieldsMappingConfigurationEditorModel[] = []; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + fromModel(item: ResultsConfiguration): ResultsConfigurationEditorModel { + this.resultsArrayPath = item.resultsArrayPath; + if (item.fieldsMapping) { item.fieldsMapping.map(x => this.fieldsMapping.push(new ResultFieldsMappingConfigurationEditorModel(this.validationErrorModel).fromModel(x))); } + else { + this.fieldsMapping.push(new ResultFieldsMappingConfigurationEditorModel(this.validationErrorModel).fromModel({ code: 'reference_id', responsePath: undefined })); + this.fieldsMapping.push(new ResultFieldsMappingConfigurationEditorModel(this.validationErrorModel).fromModel({ code: 'label', responsePath: undefined })); + this.fieldsMapping.push(new ResultFieldsMappingConfigurationEditorModel(this.validationErrorModel).fromModel({ code: 'description', responsePath: undefined })); + } + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = ResultsConfigurationEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + resultsArrayPath: [{ value: this.resultsArrayPath, disabled: disabled }, context.getValidation('resultsArrayPath').validators], + fieldsMapping: this.formBuilder.array( + (this.fieldsMapping ?? []).map( + (item, index) => new ResultFieldsMappingConfigurationEditorModel( + this.validationErrorModel + ).fromModel(item).buildForm({ + rootPath: `${rootPath}fieldsMapping[${index}].` + }) + ), context.getValidation('fieldsMapping').validators + ) + + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'resultsArrayPath', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}resultsArrayPath`)] }); + baseValidationArray.push({ key: 'fieldsMapping', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}fieldsMapping`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = ResultsConfigurationEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['resultsArrayPath'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }); + + (formGroup.get('fieldsMapping') as FormArray).controls?.forEach( + (control, index) => ResultFieldsMappingConfigurationEditorModel.reapplyFieldsMappingValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}fieldsMapping[${index}].`, + validationErrorModel: validationErrorModel + } + ) + ); + } +} + +export class ResultFieldsMappingConfigurationEditorModel implements ResultFieldsMappingConfigurationPersist { + public code: string; + public responsePath: string; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + fromModel(item: ResultFieldsMappingConfiguration): ResultFieldsMappingConfigurationEditorModel { + this.code = item.code; + this.responsePath = item.responsePath; + + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = ResultFieldsMappingConfigurationEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + code: [{ value: this.code, disabled: disabled }, context.getValidation('code').validators], + responsePath: [{ value: this.responsePath, disabled: disabled }, context.getValidation('responsePath').validators], + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'code', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}code`)] }); + baseValidationArray.push({ key: 'responsePath', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}responsePath`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + + static reapplyFieldsMappingValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = ResultFieldsMappingConfigurationEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['code', 'responsePath'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }); + } +} + +export class AuthenticationConfigurationEditorModel implements AuthenticationConfigurationPersist { + public enabled: boolean = false; + public authUrl: string; + public authMethod: ExternalFetcherApiHTTPMethodType; + public authTokenPath: string; + public authRequestBody: string; + public type: string; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + fromModel(item: AuthenticationConfiguration): AuthenticationConfigurationEditorModel { + this.enabled = item.enabled; + this.authUrl = item.authUrl; + this.authMethod = item.authMethod; + this.authTokenPath = item.authTokenPath; + this.authRequestBody = item.authRequestBody; + this.type = item.type; + + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = AuthenticationConfigurationEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + enabled: [{ value: this.enabled, disabled: disabled }, context.getValidation('enabled').validators], + authUrl: [{ value: this.authUrl, disabled: disabled }, context.getValidation('authUrl').validators], + authMethod: [{ value: this.authMethod, disabled: disabled }, context.getValidation('authMethod').validators], + authTokenPath: [{ value: this.authTokenPath, disabled: disabled }, context.getValidation('authTokenPath').validators], + authRequestBody: [{ value: this.authRequestBody, disabled: disabled }, context.getValidation('authRequestBody').validators], + type: [{ value: this.type, disabled: disabled }, context.getValidation('type').validators], + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'enabled', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}enabled`)] }); + baseValidationArray.push({ key: 'authUrl', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}authUrl`)] }); + baseValidationArray.push({ key: 'authMethod', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}authMethod`)] }); + baseValidationArray.push({ key: 'authTokenPath', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}authTokenPath`)] }); + baseValidationArray.push({ key: 'authRequestBody', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}authRequestBody`)] }); + baseValidationArray.push({ key: 'type', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}type`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + + static reapplyAuthValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = AuthenticationConfigurationEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['enabled', 'authUrl', 'authMethod', 'authTokenPath', 'authRequestBody', 'type'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } +} + +export class QueryConfigEditorModel implements QueryConfigPersist { + public name: string; + public defaultValue: string; + public cases: QueryCaseConfigEditorModel[] = []; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + fromModel(item: QueryConfig): QueryConfigEditorModel { + this.name = item.name; + this.defaultValue = item.defaultValue; + if (item.cases) { item.cases.map(x => this.cases.push(new QueryCaseConfigEditorModel(this.validationErrorModel).fromModel(x))); } + + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = QueryConfigEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + name: [{ value: this.name, disabled: disabled }, context.getValidation('name').validators], + defaultValue: [{ value: this.defaultValue, disabled: disabled }, context.getValidation('defaultValue').validators], + cases: this.formBuilder.array( + (this.cases ?? []).map( + (item, index) => item.buildForm({ + rootPath: `${rootPath}cases[${index}].` + }) + ), context.getValidation('cases').validators + ) + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'name', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}name`)] }); + baseValidationArray.push({ key: 'defaultValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}defaultValue`)] }); + baseValidationArray.push({ key: 'cases', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}cases`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = QueryConfigEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['name', 'defaultValue'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }); + + (formGroup.get('cases') as FormArray).controls?.forEach( + (control, index) => QueryCaseConfigEditorModel.reapplyValidators({ + formGroup: control as UntypedFormGroup, + rootPath: `${rootPath}cases[${index}].`, + validationErrorModel: validationErrorModel + } + ) + ); + } +} + +export class QueryCaseConfigEditorModel implements QueryCaseConfigPersist { + public likePattern: string; + public separator: string; + public value: string; + public referenceTypeId: Guid; + public referenceTypeSourceKey: string; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + fromModel(item: QueryCaseConfig): QueryCaseConfigEditorModel { + this.likePattern = item.likePattern; + this.separator = item.separator; + this.value = item.value; + if(item?.referenceType?.id) this.referenceTypeId = item.referenceType.id; + this.referenceTypeSourceKey = item.referenceTypeSourceKey; + + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = QueryCaseConfigEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + likePattern: [{ value: this.likePattern, disabled: disabled }, context.getValidation('likePattern').validators], + separator: [{ value: this.separator, disabled: disabled }, context.getValidation('separator').validators], + value: [{ value: this.value, disabled: disabled }, context.getValidation('value').validators], + referenceTypeId: [{ value: this.referenceTypeId, disabled: disabled }, context.getValidation('referenceTypeId').validators], + referenceTypeSourceKey: [{ value: this.referenceTypeSourceKey, disabled: disabled }, context.getValidation('referenceTypeSourceKey').validators], + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'likePattern', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}likePattern`)] }); + baseValidationArray.push({ key: 'separator', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}separator`)] }); + baseValidationArray.push({ key: 'value', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}value`)] }); + baseValidationArray.push({ key: 'referenceTypeId', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}referenceTypeId`)] }); + baseValidationArray.push({ key: 'referenceTypeSourceKey', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}referenceTypeSourceKey`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = QueryCaseConfigEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['likePattern', 'separator', 'value', 'referenceTypeId', 'referenceTypeSourceKey'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } +} + +export class StaticOptionEditorModel implements StaticOptionPersist { + public code: string; + public value: string; + + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + fromModel(item: StaticOption): StaticOptionEditorModel { + this.code = item.code; + this.value = item.value; + + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = StaticOptionEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + code: [{ value: this.code, disabled: true }, context.getValidation('code').validators], + value: [{ value: this.value, disabled: disabled }, context.getValidation('value').validators], + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'code', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}code`)] }); + baseValidationArray.push({ key: 'value', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}value`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + + static reapplyStaticOptionsValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = StaticOptionEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['code', 'value'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }); + + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.html b/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.html new file mode 100644 index 000000000..87ab361d9 --- /dev/null +++ b/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.html @@ -0,0 +1,359 @@ +
+
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.KEY' | translate}} + + {{formGroup.get('key').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.LABEL' | translate}} + + {{formGroup.get('label').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.ORDINAL' | translate}} + + {{formGroup.get('ordinal').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.DEPENDENCIES' | translate}} + + {{referenceType.name}} + + {{formGroup.get('referenceTypeDependencyIds').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.SOURCE-TYPE' | translate}} + + + {{enumUtils.toExternalFetcherSourceTypeString(sourceType)}} + + + {{formGroup.get('type').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+ +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.URL' | translate}} + + {{formGroup.get('url').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.PAGINATION-PATH' | translate}} + + {{formGroup.get('paginationPath').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.CONTENT-TYPE' | translate}} + + {{formGroup.get('contentType').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.FIRST-PAGE' | translate}} + + {{formGroup.get('firstPage').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.HTTP-METHOD' | translate}} + + + {{enumUtils.toExternalFetcherApiHTTPMethodTypeString(httpMethod)}} + + + {{formGroup.get('httpMethod').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.REQUEST-BODY' | translate}} + + {{formGroup.get('requestBody').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.FILTER-TYPE' | translate}} + + {{formGroup.get('filterType').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+ +

{{'REFERENCE-TYPE-EDITOR.FIELDS.RESULTS' | translate}}

+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.RESULTS-PATH' | translate}} + + {{formGroup.get('results').get('resultsArrayPath').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+ +
+
+
+ +
+
+

{{'REFERENCE-TYPE-EDITOR.FIELDS.FIELD-MAPPING' | translate}} {{fieldMappingIndex + 1}}

+
+
+
+ +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.CODE' | translate}} + + {{field.get('code').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.RESPONSE-PATH' | translate}} + + {{field.get('responsePath').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+
+
+
+
+ +

{{'REFERENCE-TYPE-EDITOR.FIELDS.AUTHENTICATION' | translate}} + +

+
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.URL' | translate}} + + {{formGroup.get('auth').get('authUrl').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.HTTP-METHOD' | translate}} + + + {{enumUtils.toExternalFetcherApiHTTPMethodTypeString(httpMethod)}} + + + {{formGroup.get('auth').get('authMethod').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.TOKEN-PATH' | translate}} + + {{formGroup.get('auth').get('authTokenPath').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.REQUEST-BODY' | translate}} + + {{formGroup.get('auth').get('authRequestBody').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.TYPE' | translate}} + + {{formGroup.get('auth').get('type').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ +

{{'REFERENCE-TYPE-EDITOR.FIELDS.QUERIES' | translate}} + +

+
+
+
+ +
+
+

{{'REFERENCE-TYPE-EDITOR.FIELDS.QUERY' | translate}} {{queryIndex + 1}}

+
+
+ +
+
+ +
+
+
+ +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.NAME' | translate}} + + {{query.get('name').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.DEFAULT-VALUE' | translate}} + + {{query.get('defaultValue').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+
+
+ +
+
+ +
+
+

{{'REFERENCE-TYPE-EDITOR.FIELDS.CASE' | translate}} {{caseIndex + 1}}

+
+
+ +
+
+
+ +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.LIKE-PATTERN' | translate}} + + {{case.get('likePattern').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.SEPARATOR' | translate}} + + {{case.get('separator').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.VALUE' | translate}} + + {{case.get('value').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.REFERENCE-TYPE' | translate}} + + + {{referenceType.code}} + + + {{case.get('referenceTypeId').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.SOURCE-KEY' | translate}} + + + {{sourceKey}} + + + {{case.get('referenceTypeSourceKey').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+
+
+
+
+
+
+ +
+
+

{{'REFERENCE-TYPE-EDITOR.FIELDS.OPTIONS' | translate}}

+
+
+ +
+
+

{{'REFERENCE-TYPE-EDITOR.FIELDS.OPTION' | translate}} {{optionsIndex + 1}}

+
+
+
+ +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.CODE' | translate}} + + {{option.get('code').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.VALUE' | translate}} + + {{option.get('value').getError('backendError').message}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+
+
+
+
+
+
+ {{formGroup.value | json}} +
\ No newline at end of file diff --git a/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.scss b/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.ts b/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.ts new file mode 100644 index 000000000..6f3174d06 --- /dev/null +++ b/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.ts @@ -0,0 +1,103 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { FormArray, UntypedFormGroup } from '@angular/forms'; +import { ExternalFetcherApiHTTPMethodType } from '@app/core/common/enum/external-fetcher-api-http-method-type'; +import { ExternalFetcherSourceType } from '@app/core/common/enum/external-fetcher-source-type'; +import { ReferenceType } from '@app/core/model/reference-type/reference-type'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; +import { BaseComponent } from '@common/base/base.component'; +import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; +import { QueryCaseConfigEditorModel, QueryConfigEditorModel, StaticOptionEditorModel } from './external-fetcher-source-editor.model'; +import { Guid } from '@common/types/guid'; + +@Component({ + selector: 'app-external-fetcher-source-component', + templateUrl: 'external-fetcher-source.component.html', + styleUrls: ['./external-fetcher-source.component.scss'] +}) +export class ExternalFetcherSourceComponent extends BaseComponent implements OnInit { + + @Input() formGroup: UntypedFormGroup = null; + @Input() validationErrorModel: ValidationErrorModel = null; + @Input() validationRootPath: string = null; + @Input() referenceTypeSourceIndex: number = null; + @Input() referenceTypes: ReferenceType[] = null; + @Input() sourceKeysMap: Map = new Map(); + + externalFetcherSourceType = ExternalFetcherSourceType; + externalFetcherApiHTTPMethodType = ExternalFetcherApiHTTPMethodType; + externalFetcherSourceTypeEnum = this.enumUtils.getEnumValues(ExternalFetcherSourceType); + externalFetcherApiHTTPMethodTypeEnum = this.enumUtils.getEnumValues(ExternalFetcherApiHTTPMethodType); + referenceTypeDependenciesMap: Map = new Map(); + + constructor( + public enumUtils: EnumUtils, + ) { super(); } + + ngOnInit() { + console.log(this.referenceTypeSourceIndex); + } + + // + // + // queries + // + // + addQuery(): void { + const formArray= this.formGroup.get('queries') as FormArray; + const query: QueryConfigEditorModel = new QueryConfigEditorModel(this.validationErrorModel); + formArray.push(query.buildForm({rootPath: this.validationRootPath + 'queries[' + formArray.length + '].'})); + } + + removeQuery(queryIndex: number): void { + const formArray = (this.formGroup.get('queries') as FormArray); + formArray.removeAt(queryIndex); + } + + // cases + + addCase(queryIndex: number): void { + const formArray = (this.formGroup.get('queries') as FormArray).at(queryIndex).get('cases') as FormArray; + const queryCase: QueryCaseConfigEditorModel = new QueryCaseConfigEditorModel(this.validationErrorModel); + formArray.push(queryCase.buildForm({rootPath: this.validationRootPath + 'queries[' + queryIndex + '].cases[' + formArray.length + '].'})); + + } + + removeCase(queryIndex: number, index: number): void { + const formArray = (this.formGroup.get('queries') as FormArray).at(queryIndex).get('cases') as FormArray; + formArray.removeAt(index); + } + + // Options + + addOption(code: string): void { + const optionsSize = (this.formGroup.get('options') as FormArray).length; + + if (optionsSize > 0) { + for (let i = 0; i < optionsSize; i++) { + if ((this.formGroup.get('options') as FormArray).at(i).get('code').getRawValue() == code) { + return; + } + } + } + + const option = new StaticOptionEditorModel(this.validationErrorModel); + (this.formGroup.get('options') as FormArray).push(option.buildForm()); + (this.formGroup.get('options') as FormArray).at(optionsSize).get('code').patchValue(code); + } + + removeOption(optionIndex: number): void { + const formArray = (this.formGroup.get('options') as FormArray); + formArray.removeAt(optionIndex); + } + + setReferenceTypeDependenciesMap(ids: Guid[], index: number){ + let mapValues :ReferenceType[] = []; + this.referenceTypes.forEach(x => { + if(ids.includes(x.id)){ + mapValues.push(x); + } + }) + this.referenceTypeDependenciesMap.set(index, mapValues); + } + +} diff --git a/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.module.ts b/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.module.ts new file mode 100644 index 000000000..15c83f1b4 --- /dev/null +++ b/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.module.ts @@ -0,0 +1,24 @@ +import { NgModule } from '@angular/core'; +import { FormattingModule } from '@app/core/formatting.module'; +import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module'; +import { DescriptionRoutingModule } from '@app/ui/description/description.routing'; +import { CommonFormsModule } from '@common/forms/common-forms.module'; +import { CommonUiModule } from '@common/ui/common-ui.module'; +import { ExternalFetcherSourceComponent } from './external-fetcher-source.component'; + +@NgModule({ + imports: [ + CommonUiModule, + CommonFormsModule, + FormattingModule, + DescriptionRoutingModule, + AutoCompleteModule + ], + declarations: [ + ExternalFetcherSourceComponent + ], + exports: [ + ExternalFetcherSourceComponent + ] +}) +export class ExternalFetcherSourceModule { } diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts index 6dbf6d10c..819df99fc 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts +++ b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts @@ -53,6 +53,7 @@ export const ADMIN_ROUTES: RouteInfo[] = [ { path: '/description-template-type', title: 'SIDE-BAR.DESCRIPTION-TEMPLATE-TYPES', icon: 'stack' }, { path: '/references', title: 'SIDE-BAR.REFERENCES', icon: 'dataset_linked' }, { path: '/reference-type', title: 'SIDE-BAR.REFERENCE-TYPES', icon: 'add_link' }, + { path: '/prefilling-sources', title: 'SIDE-BAR.PREFILLING-SOURCES', icon: 'add_link' }, { path: '/tenants', title: 'SIDE-BAR.TENANTS', icon: 'tenancy' }, { path: '/users', title: 'SIDE-BAR.USERS', icon: 'people' }, { path: '/languages', title: 'SIDE-BAR.LANGUAGES', icon: 'language' }, diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index babe55052..b0c119da6 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -256,7 +256,10 @@ "EDIT-LANGUAGE": "Edit", "NOTIFICATION-TEMPLATES": "Notification Templates", "INAPP-NOTIFICATIONS":"Notifications", - "NOTIFICATIONS": "Notifications" + "NOTIFICATIONS": "Notifications", + "PREFILLING-SOURCES": "Prefilling Sources", + "NEW-PREFILLING-SOURCE": "New", + "EDIT-PREFILLING-SOURCE": "Edit" }, "COOKIE": { "MESSAGE": "This website uses cookies to enhance the user experience.", @@ -359,7 +362,8 @@ "LANGUAGES": "Languages", "MAINTENANCE": "Maintenance", "NOTIFICATION-TEMPLATES": "Notification Templates", - "NOTIFICATIONS":"Notifications" + "NOTIFICATIONS":"Notifications", + "PREFILLING-SOURCES":"Prefilling Sources" }, "DESCRIPTION-TEMPLATE-EDITOR": { "TITLE": { @@ -1196,6 +1200,33 @@ "SUCCESSFUL-DELETE": "Successful Delete", "UNSUCCESSFUL-DELETE": "This item could not be deleted." }, + "PREFILLING-SOURCE-LISTING": { + "TITLE": "Prefilling Sources", + "CREATE": "Create Prefilling Source", + "FIELDS": { + "LABEL": "Label", + "UPDATED-AT": "Updated", + "CREATED-AT": "Created", + "IS-ACTIVE": "Is Active" + }, + "FILTER": { + "TITLE": "Filters", + "IS-ACTIVE": "Is Active", + "CANCEL": "Cancel", + "APPLY-FILTERS": "Apply filters" + }, + "CONFIRM-DELETE-DIALOG": { + "MESSAGE": "Would you like to delete this Preffiling Source?", + "CONFIRM-BUTTON": "Yes, delete", + "CANCEL-BUTTON": "No" + }, + "ACTIONS": { + "DELETE": "Delete", + "EDIT": "Edit" + }, + "SUCCESSFUL-DELETE": "Successful Delete", + "UNSUCCESSFUL-DELETE": "This item could not be deleted." + }, "REFERENCE-LISTING": { "TITLE": "References", "CREATE": "Create Reference", @@ -1515,7 +1546,8 @@ "ADD-QUERY": "Add Query", "REMOVE-QUERY": "Remove Query", "ADD-CASE": "Add Case", - "REMOVE-CASE": "Remove Case" + "REMOVE-CASE": "Remove Case", + "SUBMIT-FIELDS": "Submit" }, "CONFIRM-DELETE-DIALOG": { "MESSAGE": "Would you like to delete this Reference type?", @@ -1556,6 +1588,32 @@ "CANCEL-BUTTON": "No" } }, + "PREFILLING-SOURCE-EDITOR": { + "NEW": "New Prefilling Source", + "FIELDS": { + "LABEL": "Label", + "FIELD": "Field", + "CODE": "Code", + "TARGET": "Target", + "SYSTEM-TARGET": "System Target", + "SEMANTIC-TARGET": "Semantic Target", + "TRIM-REGEX": "Trim Regex", + "FIXED-VALUE": "Fixed Value" + }, + "ACTIONS": { + "SAVE": "Save", + "CANCEL": "Cancel", + "DELETE": "Delete", + "ADD-FIELD": "Add Field", + "REMOVE-FIELD": "Remove Field", + "SUBMIT-FIELDS": "Submit" + }, + "CONFIRM-DELETE-DIALOG": { + "MESSAGE": "Would you like to delete this Prefilling Source?", + "CONFIRM-BUTTON": "Yes, delete", + "CANCEL-BUTTON": "No" + } + }, "REFERENCE-EDITOR": { "NEW": "New Reference", "FIELDS": { From 57908f342be87b6278584bde032823d46aebe9cc Mon Sep 17 00:00:00 2001 From: amentis Date: Mon, 26 Feb 2024 19:47:20 +0200 Subject: [PATCH 2/9] refactor reference type enums to prefilling source and ui code clean up --- ... => ExternalFetcherApiHTTPMethodType.java} | 8 +- ...pe.java => ExternalFetcherSourceType.java} | 9 +- .../AuthenticationConfigurationEntity.java | 8 +- ...alFetcherApiSourceConfigurationEntity.java | 10 +- ...lFetcherBaseSourceConfigurationEntity.java | 8 +- .../ReferenceTypeDefinitionEntity.java | 6 +- .../eu/eudat/data/PrefillingSourceEntity.java | 5 +- .../PrefillingSourceDefinitionBuilder.java | 7 + .../ReferenceTypeDefinitionBuilder.java | 6 +- .../AuthenticationConfiguration.java | 8 +- ...ExternalFetcherApiSourceConfiguration.java | 8 +- ...xternalFetcherBaseSourceConfiguration.java | 8 +- .../AuthenticationConfigurationPersist.java | 8 +- ...lFetcherApiSourceConfigurationPersist.java | 20 +- ...FetcherBaseSourceConfigurationPersist.java | 12 +- ...taticOptionSourceConfigurationPersist.java | 8 +- .../PrefillingSourceDefinitionPersist.java | 12 +- .../ReferenceTypeDefinitionPersist.java | 4 +- .../ExternalFetcherServiceImpl.java | 6 +- .../config/UrlConfiguration.java | 8 +- .../entities/AuthenticationConfiguration.java | 4 +- .../entities/SourceBaseConfiguration.java | 4 +- .../SourceExternalApiConfiguration.java | 4 +- .../PrefillingSourceServiceImpl.java | 11 + .../ReferenceTypeServiceImpl.java | 4 +- .../reference-type-editor.component.html | 358 ------------------ 26 files changed, 108 insertions(+), 446 deletions(-) rename dmp-backend/core/src/main/java/eu/eudat/commons/enums/{ReferenceTypeExternalApiHTTPMethodType.java => ExternalFetcherApiHTTPMethodType.java} (55%) rename dmp-backend/core/src/main/java/eu/eudat/commons/enums/{ReferenceTypeSourceType.java => ExternalFetcherSourceType.java} (63%) diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ReferenceTypeExternalApiHTTPMethodType.java b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ExternalFetcherApiHTTPMethodType.java similarity index 55% rename from dmp-backend/core/src/main/java/eu/eudat/commons/enums/ReferenceTypeExternalApiHTTPMethodType.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/enums/ExternalFetcherApiHTTPMethodType.java index 5aed17828..ce9b24c81 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ReferenceTypeExternalApiHTTPMethodType.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ExternalFetcherApiHTTPMethodType.java @@ -6,14 +6,14 @@ import jakarta.xml.bind.annotation.XmlEnumValue; import java.util.Map; -public enum ReferenceTypeExternalApiHTTPMethodType implements DatabaseEnum { +public enum ExternalFetcherApiHTTPMethodType implements DatabaseEnum { @XmlEnumValue(value = "0") GET((short) 0), @XmlEnumValue(value = "1") POST((short) 1); private final Short value; - ReferenceTypeExternalApiHTTPMethodType(Short value) { + ExternalFetcherApiHTTPMethodType(Short value) { this.value = value; } @@ -22,9 +22,9 @@ public enum ReferenceTypeExternalApiHTTPMethodType implements DatabaseEnum map = EnumUtils.getEnumValueMap(ReferenceTypeExternalApiHTTPMethodType.class); + private static final Map map = EnumUtils.getEnumValueMap(ExternalFetcherApiHTTPMethodType.class); - public static ReferenceTypeExternalApiHTTPMethodType of(Short i) { + public static ExternalFetcherApiHTTPMethodType of(Short i) { return map.get(i); } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ReferenceTypeSourceType.java b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ExternalFetcherSourceType.java similarity index 63% rename from dmp-backend/core/src/main/java/eu/eudat/commons/enums/ReferenceTypeSourceType.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/enums/ExternalFetcherSourceType.java index 3b6ff61f5..04240db3c 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ReferenceTypeSourceType.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ExternalFetcherSourceType.java @@ -3,11 +3,10 @@ package eu.eudat.commons.enums; import com.fasterxml.jackson.annotation.JsonValue; import eu.eudat.data.converters.enums.DatabaseEnum; import jakarta.xml.bind.annotation.XmlEnumValue; -import jakarta.xml.bind.annotation.XmlValue; import java.util.Map; -public enum ReferenceTypeSourceType implements DatabaseEnum { +public enum ExternalFetcherSourceType implements DatabaseEnum { @XmlEnumValue(value = "0") API((short) 0), @XmlEnumValue(value = "1") @@ -19,7 +18,7 @@ public enum ReferenceTypeSourceType implements DatabaseEnum { public static final String STATIC = "static"; } - ReferenceTypeSourceType(Short value) { + ExternalFetcherSourceType(Short value) { this.value = value; } @@ -28,9 +27,9 @@ public enum ReferenceTypeSourceType implements DatabaseEnum { return value; } - private static final Map map = EnumUtils.getEnumValueMap(ReferenceTypeSourceType.class); + private static final Map map = EnumUtils.getEnumValueMap(ExternalFetcherSourceType.class); - public static ReferenceTypeSourceType of(Short i) { + public static ExternalFetcherSourceType of(Short i) { return map.get(i); } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/externalfetcher/AuthenticationConfigurationEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/externalfetcher/AuthenticationConfigurationEntity.java index 2a40ec173..9b54d5244 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/externalfetcher/AuthenticationConfigurationEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/externalfetcher/AuthenticationConfigurationEntity.java @@ -1,6 +1,6 @@ package eu.eudat.commons.types.externalfetcher; -import eu.eudat.commons.enums.ReferenceTypeExternalApiHTTPMethodType; +import eu.eudat.commons.enums.ExternalFetcherApiHTTPMethodType; import eu.eudat.service.externalfetcher.config.entities.AuthenticationConfiguration; import jakarta.xml.bind.annotation.XmlElement; @@ -8,7 +8,7 @@ public class AuthenticationConfigurationEntity implements AuthenticationConfigur private Boolean enabled; private String authUrl; - private ReferenceTypeExternalApiHTTPMethodType authMethod; + private ExternalFetcherApiHTTPMethodType authMethod; private String authTokenPath; private String authRequestBody; private String type; @@ -31,12 +31,12 @@ public class AuthenticationConfigurationEntity implements AuthenticationConfigur this.authUrl = authUrl; } - public ReferenceTypeExternalApiHTTPMethodType getAuthMethod() { + public ExternalFetcherApiHTTPMethodType getAuthMethod() { return authMethod; } @XmlElement(name = "authUrlMethod") - public void setAuthMethod(ReferenceTypeExternalApiHTTPMethodType authMethod) { + public void setAuthMethod(ExternalFetcherApiHTTPMethodType authMethod) { this.authMethod = authMethod; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/externalfetcher/ExternalFetcherApiSourceConfigurationEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/externalfetcher/ExternalFetcherApiSourceConfigurationEntity.java index 1c59b1cc5..1b6b9df09 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/externalfetcher/ExternalFetcherApiSourceConfigurationEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/externalfetcher/ExternalFetcherApiSourceConfigurationEntity.java @@ -1,7 +1,7 @@ package eu.eudat.commons.types.externalfetcher; -import eu.eudat.commons.enums.ReferenceTypeExternalApiHTTPMethodType; +import eu.eudat.commons.enums.ExternalFetcherApiHTTPMethodType; import eu.eudat.service.externalfetcher.config.entities.SourceExternalApiConfiguration; import jakarta.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlElementWrapper; @@ -14,7 +14,7 @@ public class ExternalFetcherApiSourceConfigurationEntity extends ExternalFetcher private String paginationPath; private String contentType; private String firstPage; - private ReferenceTypeExternalApiHTTPMethodType httpMethod; + private ExternalFetcherApiHTTPMethodType httpMethod; private String requestBody = ""; private String filterType = "remote"; private AuthenticationConfigurationEntity auth; @@ -62,12 +62,12 @@ public class ExternalFetcherApiSourceConfigurationEntity extends ExternalFetcher this.firstPage = firstPage; } - public ReferenceTypeExternalApiHTTPMethodType getHttpMethod() { + public ExternalFetcherApiHTTPMethodType getHttpMethod() { return httpMethod; } @XmlElement(name = "requestHttpMethod") - public void setHttpMethod(ReferenceTypeExternalApiHTTPMethodType httpMethod) { - this.httpMethod = httpMethod != null ? httpMethod : ReferenceTypeExternalApiHTTPMethodType.GET; + public void setHttpMethod(ExternalFetcherApiHTTPMethodType httpMethod) { + this.httpMethod = httpMethod != null ? httpMethod : ExternalFetcherApiHTTPMethodType.GET; } public String getRequestBody() { return requestBody; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/externalfetcher/ExternalFetcherBaseSourceConfigurationEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/externalfetcher/ExternalFetcherBaseSourceConfigurationEntity.java index 3c86c9a0f..d5d7810b7 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/externalfetcher/ExternalFetcherBaseSourceConfigurationEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/externalfetcher/ExternalFetcherBaseSourceConfigurationEntity.java @@ -1,6 +1,6 @@ package eu.eudat.commons.types.externalfetcher; -import eu.eudat.commons.enums.ReferenceTypeSourceType; +import eu.eudat.commons.enums.ExternalFetcherSourceType; import eu.eudat.service.externalfetcher.config.entities.SourceBaseConfiguration; import jakarta.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlElementWrapper; @@ -15,10 +15,10 @@ public abstract class ExternalFetcherBaseSourceConfigurationEntity implements So private String label; private Integer ordinal; - private ReferenceTypeSourceType type; + private ExternalFetcherSourceType type; private List referenceTypeDependencyIds; - public ReferenceTypeSourceType getType() { + public ExternalFetcherSourceType getType() { return type; } @@ -50,7 +50,7 @@ public abstract class ExternalFetcherBaseSourceConfigurationEntity implements So } @XmlElement(name = "type") - public void setType(ReferenceTypeSourceType type) { + public void setType(ExternalFetcherSourceType type) { this.type = type; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/ReferenceTypeDefinitionEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/ReferenceTypeDefinitionEntity.java index 90c1cd765..8bc96b6ce 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/ReferenceTypeDefinitionEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/ReferenceTypeDefinitionEntity.java @@ -1,6 +1,6 @@ package eu.eudat.commons.types.referencetype; -import eu.eudat.commons.enums.ReferenceTypeSourceType; +import eu.eudat.commons.enums.ExternalFetcherSourceType; import eu.eudat.commons.types.externalfetcher.ExternalFetcherBaseSourceConfigurationEntity; import eu.eudat.commons.types.externalfetcher.ExternalFetcherApiSourceConfigurationEntity; import eu.eudat.commons.types.externalfetcher.ExternalFetcherStaticOptionSourceConfigurationEntity; @@ -17,8 +17,8 @@ public class ReferenceTypeDefinitionEntity { @XmlElementWrapper(name = "sources") @XmlElements({ - @XmlElement(name = ReferenceTypeSourceType.Names.API, type = ExternalFetcherApiSourceConfigurationEntity.class), - @XmlElement(name = ReferenceTypeSourceType.Names.STATIC, type = ExternalFetcherStaticOptionSourceConfigurationEntity.class), + @XmlElement(name = ExternalFetcherSourceType.Names.API, type = ExternalFetcherApiSourceConfigurationEntity.class), + @XmlElement(name = ExternalFetcherSourceType.Names.STATIC, type = ExternalFetcherStaticOptionSourceConfigurationEntity.class), }) private List sources; diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/PrefillingSourceEntity.java b/dmp-backend/core/src/main/java/eu/eudat/data/PrefillingSourceEntity.java index 72d0e7235..f6afb774f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/data/PrefillingSourceEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/PrefillingSourceEntity.java @@ -3,7 +3,9 @@ package eu.eudat.data; import eu.eudat.commons.enums.IsActive; import eu.eudat.data.converters.enums.IsActiveConverter; import eu.eudat.data.tenant.TenantScopedBaseEntity; +import eu.eudat.data.types.SQLXMLType; import jakarta.persistence.*; +import org.hibernate.annotations.Type; import java.time.Instant; import java.util.UUID; @@ -22,7 +24,8 @@ public class PrefillingSourceEntity extends TenantScopedBaseEntity { public static final String _label = "label"; public static final int _labelLength = 250; - @Column(name = "definition") + @Type(value = SQLXMLType.class) + @Column(name = "definition", nullable = false, columnDefinition = "xml") private String definition; public static final String _definition = "definition"; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionBuilder.java index d9c299777..95ba37811 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionBuilder.java @@ -5,6 +5,7 @@ import eu.eudat.commons.types.prefillingsource.PrefillingSourceDefinitionEntity; import eu.eudat.convention.ConventionService; import eu.eudat.model.builder.BaseBuilder; import eu.eudat.model.builder.externalfetcher.ExternalFetcherApiSourceConfigurationBuilder; +import eu.eudat.model.externalfetcher.ExternalFetcherApiSourceConfiguration; import eu.eudat.model.prefillingsourcedefinition.PrefillingSourceDefinition; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.exception.MyApplicationException; @@ -53,6 +54,12 @@ public class PrefillingSourceDefinitionBuilder extends BaseBuilder externalApiConfigEntities = d.getSources().stream().filter(x-> ReferenceTypeSourceType.API.equals(x.getType())).map(x-> (ExternalFetcherApiSourceConfigurationEntity)x).toList(); - List staticOptionConfigEntities = d.getSources().stream().filter(x-> ReferenceTypeSourceType.STATIC.equals(x.getType())).map(x-> (ExternalFetcherStaticOptionSourceConfigurationEntity)x).toList(); + List externalApiConfigEntities = d.getSources().stream().filter(x-> ExternalFetcherSourceType.API.equals(x.getType())).map(x-> (ExternalFetcherApiSourceConfigurationEntity)x).toList(); + List staticOptionConfigEntities = d.getSources().stream().filter(x-> ExternalFetcherSourceType.STATIC.equals(x.getType())).map(x-> (ExternalFetcherStaticOptionSourceConfigurationEntity)x).toList(); m.setSources(new ArrayList<>()); m.getSources().addAll(this.builderFactory.builder(ExternalFetcherApiSourceConfigurationBuilder.class).authorize(this.authorize).build(sourcesFields, externalApiConfigEntities)); m.getSources().addAll(this.builderFactory.builder(ExternalFetcherStaticOptionSourceConfigurationBuilder.class).authorize(this.authorize).build(sourcesFields, staticOptionConfigEntities)); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/externalfetcher/AuthenticationConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/model/externalfetcher/AuthenticationConfiguration.java index b4cf575f7..9f93f7498 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/externalfetcher/AuthenticationConfiguration.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/externalfetcher/AuthenticationConfiguration.java @@ -1,6 +1,6 @@ package eu.eudat.model.externalfetcher; -import eu.eudat.commons.enums.ReferenceTypeExternalApiHTTPMethodType; +import eu.eudat.commons.enums.ExternalFetcherApiHTTPMethodType; public class AuthenticationConfiguration { @@ -11,7 +11,7 @@ public class AuthenticationConfiguration { private String authUrl; public final static String _authMethod = "authMethod"; - private ReferenceTypeExternalApiHTTPMethodType authMethod; + private ExternalFetcherApiHTTPMethodType authMethod; public final static String _authTokenPath = "authTokenPath"; private String authTokenPath; @@ -39,12 +39,12 @@ public class AuthenticationConfiguration { this.authUrl = authUrl; } - public ReferenceTypeExternalApiHTTPMethodType getAuthMethod() { + public ExternalFetcherApiHTTPMethodType getAuthMethod() { return authMethod; } - public void setAuthMethod(ReferenceTypeExternalApiHTTPMethodType authMethod) { + public void setAuthMethod(ExternalFetcherApiHTTPMethodType authMethod) { this.authMethod = authMethod; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/externalfetcher/ExternalFetcherApiSourceConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/model/externalfetcher/ExternalFetcherApiSourceConfiguration.java index 6e4a3ad64..db16a350a 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/externalfetcher/ExternalFetcherApiSourceConfiguration.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/externalfetcher/ExternalFetcherApiSourceConfiguration.java @@ -1,7 +1,7 @@ package eu.eudat.model.externalfetcher; -import eu.eudat.commons.enums.ReferenceTypeExternalApiHTTPMethodType; +import eu.eudat.commons.enums.ExternalFetcherApiHTTPMethodType; import java.util.List; public class ExternalFetcherApiSourceConfiguration extends ExternalFetcherBaseSourceConfiguration { @@ -23,7 +23,7 @@ public class ExternalFetcherApiSourceConfiguration extends ExternalFetcherBaseSo private String firstPage; public final static String _httpMethod = "httpMethod"; - private ReferenceTypeExternalApiHTTPMethodType httpMethod; + private ExternalFetcherApiHTTPMethodType httpMethod; public final static String _requestBody = "requestBody"; private String requestBody = ""; @@ -78,11 +78,11 @@ public class ExternalFetcherApiSourceConfiguration extends ExternalFetcherBaseSo this.firstPage = firstPage; } - public ReferenceTypeExternalApiHTTPMethodType getHttpMethod() { + public ExternalFetcherApiHTTPMethodType getHttpMethod() { return httpMethod; } - public void setHttpMethod(ReferenceTypeExternalApiHTTPMethodType httpMethod) { + public void setHttpMethod(ExternalFetcherApiHTTPMethodType httpMethod) { this.httpMethod = httpMethod; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/externalfetcher/ExternalFetcherBaseSourceConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/model/externalfetcher/ExternalFetcherBaseSourceConfiguration.java index 4f06b3f99..6daf6ad69 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/externalfetcher/ExternalFetcherBaseSourceConfiguration.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/externalfetcher/ExternalFetcherBaseSourceConfiguration.java @@ -1,6 +1,6 @@ package eu.eudat.model.externalfetcher; -import eu.eudat.commons.enums.ReferenceTypeSourceType; +import eu.eudat.commons.enums.ExternalFetcherSourceType; import eu.eudat.model.ReferenceType; import java.util.List; @@ -18,16 +18,16 @@ public abstract class ExternalFetcherBaseSourceConfiguration { private Integer ordinal; public final static String _type = "type"; - private ReferenceTypeSourceType type; + private ExternalFetcherSourceType type; public final static String _referenceTypeDependencies = "referenceTypeDependencies"; private List referenceTypeDependencies; - public ReferenceTypeSourceType getType() { + public ExternalFetcherSourceType getType() { return type; } - public void setType(ReferenceTypeSourceType type) { + public void setType(ExternalFetcherSourceType type) { this.type = type; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/AuthenticationConfigurationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/AuthenticationConfigurationPersist.java index 0c26032d0..92f023293 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/AuthenticationConfigurationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/AuthenticationConfigurationPersist.java @@ -1,6 +1,6 @@ package eu.eudat.model.persist.externalfetcher; -import eu.eudat.commons.enums.ReferenceTypeExternalApiHTTPMethodType; +import eu.eudat.commons.enums.ExternalFetcherApiHTTPMethodType; import eu.eudat.commons.validation.BaseValidator; import gr.cite.tools.validation.specification.Specification; import eu.eudat.convention.ConventionService; @@ -24,7 +24,7 @@ public class AuthenticationConfigurationPersist { public static final String _authUrl = "authUrl"; - private ReferenceTypeExternalApiHTTPMethodType authMethod; + private ExternalFetcherApiHTTPMethodType authMethod; public static final String _authMethod = "authMethod"; @@ -56,11 +56,11 @@ public class AuthenticationConfigurationPersist { this.authUrl = authUrl; } - public ReferenceTypeExternalApiHTTPMethodType getAuthMethod() { + public ExternalFetcherApiHTTPMethodType getAuthMethod() { return authMethod; } - public void setAuthMethod(ReferenceTypeExternalApiHTTPMethodType authMethod) { + public void setAuthMethod(ExternalFetcherApiHTTPMethodType authMethod) { this.authMethod = authMethod; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherApiSourceConfigurationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherApiSourceConfigurationPersist.java index 8fe4faa4d..dc71ab873 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherApiSourceConfigurationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherApiSourceConfigurationPersist.java @@ -1,6 +1,6 @@ package eu.eudat.model.persist.externalfetcher; -import eu.eudat.commons.enums.ReferenceTypeExternalApiHTTPMethodType; +import eu.eudat.commons.enums.ExternalFetcherApiHTTPMethodType; import eu.eudat.convention.ConventionService; import eu.eudat.errorcode.ErrorThesaurusProperties; import gr.cite.tools.validation.ValidatorFactory; @@ -36,13 +36,13 @@ public class ExternalFetcherApiSourceConfigurationPersist extends ExternalFetche public static final String _firstPage = "firstPage"; - private ReferenceTypeExternalApiHTTPMethodType httpMethod; + private ExternalFetcherApiHTTPMethodType httpMethod; public static final String _httpMethod = "httpMethod"; - private String requestBody = ""; + private String requestBody; - private String filterType = "remote"; + private String filterType; private AuthenticationConfigurationPersist auth; @@ -92,11 +92,11 @@ public class ExternalFetcherApiSourceConfigurationPersist extends ExternalFetche this.firstPage = firstPage; } - public ReferenceTypeExternalApiHTTPMethodType getHttpMethod() { + public ExternalFetcherApiHTTPMethodType getHttpMethod() { return httpMethod; } - public void setHttpMethod(ReferenceTypeExternalApiHTTPMethodType httpMethod) { + public void setHttpMethod(ExternalFetcherApiHTTPMethodType httpMethod) { this.httpMethod = httpMethod; } @@ -132,13 +132,13 @@ public class ExternalFetcherApiSourceConfigurationPersist extends ExternalFetche this.queries = queries; } - @Component(ReferenceTypeSourceExternalApiConfigurationPersistValidator.ValidatorName) + @Component(ExternalFetcherApiSourceConfigurationPersistValidator.ValidatorName) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public static class ReferenceTypeSourceExternalApiConfigurationPersistValidator extends ReferenceTypeSourceBaseConfigurationPersistValidator { + public static class ExternalFetcherApiSourceConfigurationPersistValidator extends ExternalFetcherBaseSourceConfigurationPersistValidator { - public static final String ValidatorName = "ReferenceTypeSourceExternalApiConfigurationPersistValidator"; + public static final String ValidatorName = "ExternalFetcherApiSourceConfigurationPersistValidator"; - protected ReferenceTypeSourceExternalApiConfigurationPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { + protected ExternalFetcherApiSourceConfigurationPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { super(conventionService, errors, messageSource, validatorFactory); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherBaseSourceConfigurationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherBaseSourceConfigurationPersist.java index 9ef910fbe..f21d77784 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherBaseSourceConfigurationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherBaseSourceConfigurationPersist.java @@ -2,7 +2,7 @@ package eu.eudat.model.persist.externalfetcher; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import eu.eudat.commons.enums.ReferenceTypeSourceType; +import eu.eudat.commons.enums.ExternalFetcherSourceType; import eu.eudat.commons.validation.BaseValidator; import eu.eudat.convention.ConventionService; import eu.eudat.errorcode.ErrorThesaurusProperties; @@ -39,7 +39,7 @@ public abstract class ExternalFetcherBaseSourceConfigurationPersist { public static final String _ordinal = "ordinal"; - private ReferenceTypeSourceType type; + private ExternalFetcherSourceType type; public static final String _type = "type"; @@ -71,11 +71,11 @@ public abstract class ExternalFetcherBaseSourceConfigurationPersist { this.ordinal = ordinal; } - public ReferenceTypeSourceType getType() { + public ExternalFetcherSourceType getType() { return type; } - public void setType(ReferenceTypeSourceType type) { + public void setType(ExternalFetcherSourceType type) { this.type = type; } @@ -87,13 +87,13 @@ public abstract class ExternalFetcherBaseSourceConfigurationPersist { this.referenceTypeDependencyIds = referenceTypeDependencyIds; } - public static abstract class ReferenceTypeSourceBaseConfigurationPersistValidator extends BaseValidator { + public static abstract class ExternalFetcherBaseSourceConfigurationPersistValidator extends BaseValidator { protected final MessageSource messageSource; protected final ValidatorFactory validatorFactory; - protected ReferenceTypeSourceBaseConfigurationPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { + protected ExternalFetcherBaseSourceConfigurationPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { super(conventionService, errors); this.messageSource = messageSource; this.validatorFactory = validatorFactory; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherStaticOptionSourceConfigurationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherStaticOptionSourceConfigurationPersist.java index 340a63724..de1e85e55 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherStaticOptionSourceConfigurationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherStaticOptionSourceConfigurationPersist.java @@ -25,13 +25,13 @@ public class ExternalFetcherStaticOptionSourceConfigurationPersist extends Exter this.options = options; } - @Component(ReferenceTypeSourceStaticOptionConfigurationPersistValidator.ValidatorName) + @Component(ExternalFetcherStaticOptionSourceConfigurationPersistValidator.ValidatorName) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public static class ReferenceTypeSourceStaticOptionConfigurationPersistValidator extends ReferenceTypeSourceBaseConfigurationPersistValidator { + public static class ExternalFetcherStaticOptionSourceConfigurationPersistValidator extends ExternalFetcherBaseSourceConfigurationPersistValidator { - public static final String ValidatorName = "ReferenceTypeSourceStaticOptionConfigurationPersistValidator"; + public static final String ValidatorName = "ExternalFetcherStaticOptionSourceConfigurationPersistValidator"; - protected ReferenceTypeSourceStaticOptionConfigurationPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { + protected ExternalFetcherStaticOptionSourceConfigurationPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { super(conventionService, errors, messageSource, validatorFactory); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionPersist.java index 007866ba5..ec8e8e503 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionPersist.java @@ -81,12 +81,12 @@ public class PrefillingSourceDefinitionPersist { .iff(() -> !this.isNull(item.getSearchConfiguration())) .on(PrefillingSourceDefinitionPersist._searchConfiguration) .over(item.getSearchConfiguration()) - .using(() -> this.validatorFactory.validator(PrefillingSourceDefinitionPersist.PrefillingSourceDefinitionPersistValidator.class)), - this.refSpec() - .iff(() -> !this.isNull(item.getGetConfiguration())) - .on(PrefillingSourceDefinitionPersist._getConfiguration) - .over(item.getGetConfiguration()) - .using(() -> this.validatorFactory.validator(PrefillingSourceDefinitionPersist.PrefillingSourceDefinitionPersistValidator.class)), + .using(() -> this.validatorFactory.validator(ExternalFetcherApiSourceConfigurationPersist.ExternalFetcherApiSourceConfigurationPersistValidator.class)), +// this.refSpec() TODO +// .iff(() -> !this.isNull(item.getGetConfiguration())) +// .on(PrefillingSourceDefinitionPersist._getConfiguration) +// .over(item.getGetConfiguration()) +// .using(() -> this.validatorFactory.validator(ExternalFetcherApiSourceConfigurationPersist.ExternalFetcherApiSourceConfigurationPersistValidator.class)), this.navSpec() .iff(() -> !this.isListNullOrEmpty(item.getFields())) .on(PrefillingSourceDefinitionPersist._fields) diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeDefinitionPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeDefinitionPersist.java index 74dc03446..39c167b2c 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeDefinitionPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeDefinitionPersist.java @@ -1,6 +1,6 @@ package eu.eudat.model.persist.referencetypedefinition; -import eu.eudat.commons.enums.ReferenceTypeSourceType; +import eu.eudat.commons.enums.ExternalFetcherSourceType; import eu.eudat.commons.validation.BaseValidator; import eu.eudat.model.persist.externalfetcher.ExternalFetcherBaseSourceConfigurationPersist; import eu.eudat.model.persist.externalfetcher.ExternalFetcherApiSourceConfigurationPersist; @@ -80,7 +80,7 @@ public class ReferenceTypeDefinitionPersist { .iff(() -> !this.isListNullOrEmpty(item.getSources())) .on(ReferenceTypeDefinitionPersist._sources) .over(item.getSources()) - .using((itm) -> ((ExternalFetcherBaseSourceConfigurationPersist) itm).getType() == ReferenceTypeSourceType.STATIC? this.validatorFactory.validator(ExternalFetcherStaticOptionSourceConfigurationPersist.ReferenceTypeSourceStaticOptionConfigurationPersistValidator.class): this.validatorFactory.validator(ExternalFetcherApiSourceConfigurationPersist.ReferenceTypeSourceExternalApiConfigurationPersistValidator.class)) + .using((itm) -> ((ExternalFetcherBaseSourceConfigurationPersist) itm).getType() == ExternalFetcherSourceType.STATIC? this.validatorFactory.validator(ExternalFetcherStaticOptionSourceConfigurationPersist.ExternalFetcherStaticOptionSourceConfigurationPersistValidator.class): this.validatorFactory.validator(ExternalFetcherApiSourceConfigurationPersist.ExternalFetcherApiSourceConfigurationPersistValidator.class)) ); } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/ExternalFetcherServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/ExternalFetcherServiceImpl.java index 03c550be8..3f412db29 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/ExternalFetcherServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/ExternalFetcherServiceImpl.java @@ -6,7 +6,7 @@ import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.PathNotFoundException; import eu.eudat.commons.JsonHandlingService; -import eu.eudat.commons.enums.ReferenceTypeSourceType; +import eu.eudat.commons.enums.ExternalFetcherSourceType; import eu.eudat.convention.ConventionService; import eu.eudat.data.ReferenceEntity; import eu.eudat.model.Reference; @@ -81,7 +81,7 @@ public class ExternalFetcherServiceImpl implements ExternalFetcherService { if (this.conventionService.isListNullOrEmpty(sources)) return new ExternalDataResult(); for (SourceBaseConfiguration source : sources) { - if (source.getType() == null || source.getType().equals(ReferenceTypeSourceType.API)) { + if (source.getType() == null || source.getType().equals(ExternalFetcherSourceType.API)) { try { SourceExternalApiConfiguration, AuthenticationConfiguration, QueryConfig> apiSource = (SourceExternalApiConfiguration)source; // this.applyFunderToQuery(apiSource, externalReferenceCriteria); @@ -94,7 +94,7 @@ public class ExternalFetcherServiceImpl implements ExternalFetcherService { } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); } - } else if (source.getType() != null && source.getType().equals(ReferenceTypeSourceType.STATIC)) { + } else if (source.getType() != null && source.getType().equals(ExternalFetcherSourceType.STATIC)) { SourceStaticOptionConfiguration staticSource = (SourceStaticOptionConfiguration)source; results.addAll(queryStaticData(staticSource, externalReferenceCriteria)); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/UrlConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/UrlConfiguration.java index 575a2d1ac..53602665b 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/UrlConfiguration.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/UrlConfiguration.java @@ -1,7 +1,7 @@ package eu.eudat.service.externalfetcher.config; -import eu.eudat.commons.enums.ReferenceTypeSourceType; +import eu.eudat.commons.enums.ExternalFetcherSourceType; import eu.eudat.service.externalfetcher.config.entities.SourceBaseConfiguration; public class UrlConfiguration implements SourceBaseConfiguration { @@ -9,7 +9,7 @@ public class UrlConfiguration implements SourceBaseConfiguration { private String key; private String label; private Integer ordinal; - private ReferenceTypeSourceType type; + private ExternalFetcherSourceType type; public String getKey() { return key; @@ -35,11 +35,11 @@ public class UrlConfiguration implements SourceBaseConfiguration { this.ordinal = ordinal; } - public ReferenceTypeSourceType getType() { + public ExternalFetcherSourceType getType() { return type; } - public void setType(ReferenceTypeSourceType type) { + public void setType(ExternalFetcherSourceType type) { this.type = type; } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/entities/AuthenticationConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/entities/AuthenticationConfiguration.java index c698b6bae..33fdd650e 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/entities/AuthenticationConfiguration.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/entities/AuthenticationConfiguration.java @@ -1,6 +1,6 @@ package eu.eudat.service.externalfetcher.config.entities; -import eu.eudat.commons.enums.ReferenceTypeExternalApiHTTPMethodType; +import eu.eudat.commons.enums.ExternalFetcherApiHTTPMethodType; public interface AuthenticationConfiguration { @@ -8,7 +8,7 @@ public interface AuthenticationConfiguration { String getAuthUrl(); - ReferenceTypeExternalApiHTTPMethodType getAuthMethod(); + ExternalFetcherApiHTTPMethodType getAuthMethod(); String getAuthTokenPath(); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/entities/SourceBaseConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/entities/SourceBaseConfiguration.java index 7dd7939da..eba1d420e 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/entities/SourceBaseConfiguration.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/entities/SourceBaseConfiguration.java @@ -1,10 +1,10 @@ package eu.eudat.service.externalfetcher.config.entities; -import eu.eudat.commons.enums.ReferenceTypeSourceType; +import eu.eudat.commons.enums.ExternalFetcherSourceType; public interface SourceBaseConfiguration { String getKey(); String getLabel(); Integer getOrdinal(); - ReferenceTypeSourceType getType(); + ExternalFetcherSourceType getType(); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/entities/SourceExternalApiConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/entities/SourceExternalApiConfiguration.java index 2f4271512..b65df2fd4 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/entities/SourceExternalApiConfiguration.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/entities/SourceExternalApiConfiguration.java @@ -1,6 +1,6 @@ package eu.eudat.service.externalfetcher.config.entities; -import eu.eudat.commons.enums.ReferenceTypeExternalApiHTTPMethodType; +import eu.eudat.commons.enums.ExternalFetcherApiHTTPMethodType; import java.util.List; @@ -15,7 +15,7 @@ public interface SourceExternalApiConfiguration - - - - - From 90bcc40ddefb287d877ea6007edb4e3608867390 Mon Sep 17 00:00:00 2001 From: Diamantis Tziotzios Date: Tue, 27 Feb 2024 10:01:45 +0200 Subject: [PATCH 3/9] no message --- .../editor/prefilling-source-editor.model.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.model.ts b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.model.ts index 3807b7f69..31f38095f 100644 --- a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.model.ts +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.model.ts @@ -74,7 +74,7 @@ export class PrefillingSourceEditorModel extends BaseEditorModel implements Pref export class PrefillingSourceDefinitionEditorModel implements PrefillingSourceDefinitionPersist { fields: PrefillingSourceDefinitionFieldEditorModel[] = []; searchConfiguration: ExternalFetcherBaseSourceConfigurationEditorModel = new ExternalFetcherBaseSourceConfigurationEditorModel(); - getConfiguration: ExternalFetcherBaseSourceConfigurationEditorModel = new ExternalFetcherBaseSourceConfigurationEditorModel(); + getConfiguration: ExternalFetcherBaseSourceConfigurationEditorModel; getEnabled = false; protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); @@ -108,7 +108,7 @@ export class PrefillingSourceDefinitionEditorModel implements PrefillingSourceDe }); } - return this.formBuilder.group({ + const form: UntypedFormGroup = this.formBuilder.group({ fields: this.formBuilder.array( (this.fields ?? []).map( (item, index) => item.buildForm({ @@ -119,11 +119,15 @@ export class PrefillingSourceDefinitionEditorModel implements PrefillingSourceDe searchConfiguration: this.searchConfiguration.buildForm({ rootPath: `${rootPath}searchConfiguration.` }), - getConfiguration: this.getConfiguration.buildForm({ - rootPath: `${rootPath}getConfiguration.` - }), getEnabled: [{ value: this.getEnabled, disabled: disabled }, context.getValidation('getEnabled').validators], }); + + if (this.getConfiguration != null) { + form.addControl('getConfiguration', this.getConfiguration.buildForm({ + rootPath: `${rootPath}getConfiguration.` + })); + } + return form; } static createValidationContext(params: { From 141d6346fb03b5b8854f76b50c448e89e0b49e39 Mon Sep 17 00:00:00 2001 From: Thomas Georgios Giannos Date: Tue, 27 Feb 2024 13:44:50 +0200 Subject: [PATCH 4/9] Small fixes on annotation service client --- .../src/annotation-service/core/query/annotation.lookup.ts | 1 + .../annotation-service/services/http/annotation.service.ts | 2 +- .../app/core/services/configuration/configuration.service.ts | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dmp-frontend/src/annotation-service/core/query/annotation.lookup.ts b/dmp-frontend/src/annotation-service/core/query/annotation.lookup.ts index e58171e5b..eda82fa6f 100644 --- a/dmp-frontend/src/annotation-service/core/query/annotation.lookup.ts +++ b/dmp-frontend/src/annotation-service/core/query/annotation.lookup.ts @@ -25,4 +25,5 @@ export interface AnnotationFilter { isActive: IsActive; entityIds: Guid[]; entityTypes: string[]; + anchors: string[]; } \ No newline at end of file diff --git a/dmp-frontend/src/annotation-service/services/http/annotation.service.ts b/dmp-frontend/src/annotation-service/services/http/annotation.service.ts index d89f5d059..4062eeca4 100644 --- a/dmp-frontend/src/annotation-service/services/http/annotation.service.ts +++ b/dmp-frontend/src/annotation-service/services/http/annotation.service.ts @@ -10,7 +10,7 @@ import { catchError } from "rxjs/operators"; @Injectable() export class AnnotationService { - private get apiBase(): string { return `${this.installationConfiguration.annotationServiceAddress}api/annotation`; } + private get apiBase(): string { return `${this.installationConfiguration.annotationServiceAddress}/annotation`; } constructor( private installationConfiguration: ConfigurationService, diff --git a/dmp-frontend/src/app/core/services/configuration/configuration.service.ts b/dmp-frontend/src/app/core/services/configuration/configuration.service.ts index d23787420..4e955766e 100644 --- a/dmp-frontend/src/app/core/services/configuration/configuration.service.ts +++ b/dmp-frontend/src/app/core/services/configuration/configuration.service.ts @@ -120,12 +120,12 @@ export class ConfigurationService extends BaseComponent { private _annotationServiceAddress: string; get annotationServiceAddress(): string { - return this._notificationServiceAddress || './'; + return this._annotationServiceAddress || './'; } private _annotationServiceEnabled: boolean; get annotationServiceEnabled(): boolean { - return this._notificationServiceEnabled; + return this._annotationServiceEnabled; } private _inAppNotificationsCountInterval: number; From dad32207e3c3007fc3d4156d8c8fe373fbbaa45e Mon Sep 17 00:00:00 2001 From: amentis Date: Tue, 27 Feb 2024 16:27:26 +0200 Subject: [PATCH 5/9] add dmp blueprint prefilling source and validation prefilling source fixes --- .../types/dmpblueprint/SectionEntity.java | 12 ++++++ .../SectionBuilder.java | 13 +++++- .../model/dmpblueprintdefinition/Section.java | 13 ++++++ .../SectionPersist.java | 12 ++++++ ...refillingSourceDefinitionFieldPersist.java | 6 ++- .../PrefillingSourceDefinitionPersist.java | 21 +++++++--- .../dmpblueprint/DmpBlueprintServiceImpl.java | 1 + .../PrefillingSourceServiceImpl.java | 2 +- .../core/model/dmp-blueprint/dmp-blueprint.ts | 3 ++ .../services/utilities/enum-utils.service.ts | 8 ++-- .../dmp-blueprint-editor.component.html | 7 ++++ .../editor/dmp-blueprint-editor.component.ts | 5 ++- .../editor/dmp-blueprint-editor.model.ts | 8 +++- .../editor/dmp-blueprint-editor.resolver.ts | 5 +++ .../prefilling-source-editor.component.html | 2 +- .../prefilling-source-editor.component.ts | 28 ++++++++++--- .../editor/prefilling-source-editor.model.ts | 41 +++++++++++++++---- .../external-fetcher-source.component.ts | 21 ++++++++-- dmp-frontend/src/assets/i18n/en.json | 7 ++-- 19 files changed, 178 insertions(+), 37 deletions(-) diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/dmpblueprint/SectionEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/dmpblueprint/SectionEntity.java index 39767a2cb..400fa58f7 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/dmpblueprint/SectionEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/dmpblueprint/SectionEntity.java @@ -37,6 +37,10 @@ public class SectionEntity { @XmlElement(name = "descriptionTemplate") private List descriptionTemplates; + @XmlElementWrapper(name = "prefillingSourcesIds") + @XmlElement(name = "id") + private List prefillingSourcesIds; + public UUID getId() { return id; } @@ -86,6 +90,14 @@ public class SectionEntity { this.descriptionTemplates = descriptionTemplates; } + public List getPrefillingSourcesIds() { + return prefillingSourcesIds; + } + + public void setPrefillingSourcesIds(List prefillingSourcesIds) { + this.prefillingSourcesIds = prefillingSourcesIds; + } + public List getAllField(){ return this.getFields() != null ? this.getFields() : new ArrayList<>(); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/dmpblueprintdefinition/SectionBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/dmpblueprintdefinition/SectionBuilder.java index 0c3e20314..a47cbe12d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/dmpblueprintdefinition/SectionBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/dmpblueprintdefinition/SectionBuilder.java @@ -4,9 +4,13 @@ import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.commons.enums.DmpBlueprintFieldCategory; import eu.eudat.commons.types.dmpblueprint.*; import eu.eudat.convention.ConventionService; +import eu.eudat.data.PrefillingSourceEntity; import eu.eudat.model.builder.BaseBuilder; +import eu.eudat.model.builder.PrefillingSourceBuilder; import eu.eudat.model.dmpblueprintdefinition.Section; +import eu.eudat.query.PrefillingSourceQuery; import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.DataLogEntry; @@ -24,13 +28,15 @@ import java.util.*; public class SectionBuilder extends BaseBuilder { private final BuilderFactory builderFactory; + private final QueryFactory queryFactory; private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); @Autowired public SectionBuilder( - ConventionService conventionService, BuilderFactory builderFactory) { + ConventionService conventionService, BuilderFactory builderFactory, QueryFactory queryFactory) { super(conventionService, new LoggerService(LoggerFactory.getLogger(SectionBuilder.class))); this.builderFactory = builderFactory; + this.queryFactory = queryFactory; } public SectionBuilder authorize(EnumSet values) { @@ -48,6 +54,7 @@ public class SectionBuilder extends BaseBuilder { //Not Bulk Build because is XML no interaction with db FieldSet descriptionTemplatesFields = fields.extractPrefixed(this.asPrefix(Section._descriptionTemplates)); FieldSet fieldsFields = fields.extractPrefixed(this.asPrefix(Section._fields)); + FieldSet prefillingSourcesFields = fields.extractPrefixed(this.asPrefix(Section._prefillingSources)); List
models = new ArrayList<>(); for (SectionEntity d : data) { @@ -67,6 +74,10 @@ public class SectionBuilder extends BaseBuilder { List referenceFieldEntities = d.getFields().stream().filter(x-> DmpBlueprintFieldCategory.ReferenceType.equals(x.getCategory())).map(x-> (ReferenceTypeFieldEntity)x).toList(); m.getFields().addAll(this.builderFactory.builder(ReferenceFieldBuilder.class).authorize(this.authorize).build(fieldsFields, referenceFieldEntities)); } + if (!prefillingSourcesFields.isEmpty() && d.getPrefillingSourcesIds() != null) { + List prefillingSourceEntities = this.queryFactory.query(PrefillingSourceQuery.class).authorize(this.authorize).ids(d.getPrefillingSourcesIds()).collectAs(prefillingSourcesFields); + m.setPrefillingSources(this.builderFactory.builder(PrefillingSourceBuilder.class).authorize(this.authorize).build(prefillingSourcesFields, prefillingSourceEntities)); + } models.add(m); } this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/dmpblueprintdefinition/Section.java b/dmp-backend/core/src/main/java/eu/eudat/model/dmpblueprintdefinition/Section.java index 844f2912c..65b64acdf 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/dmpblueprintdefinition/Section.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/dmpblueprintdefinition/Section.java @@ -1,6 +1,8 @@ package eu.eudat.model.dmpblueprintdefinition; +import eu.eudat.model.PrefillingSource; + import java.util.List; import java.util.UUID; @@ -27,6 +29,9 @@ public class Section { public final static String _descriptionTemplates = "descriptionTemplates"; private List descriptionTemplates; + public final static String _prefillingSources = "prefillingSources"; + private List prefillingSources; + public UUID getId() { return id; } @@ -82,6 +87,14 @@ public class Section { public void setDescriptionTemplates(List descriptionTemplates) { this.descriptionTemplates = descriptionTemplates; } + + public List getPrefillingSources() { + return prefillingSources; + } + + public void setPrefillingSources(List prefillingSources) { + this.prefillingSources = prefillingSources; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/SectionPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/SectionPersist.java index 4a6eee0bc..46ae7a356 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/SectionPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/SectionPersist.java @@ -45,6 +45,10 @@ public class SectionPersist { public static final String _descriptionTemplates = "descriptionTemplates"; + private List prefillingSourcesIds= null; + + public static final String _prefillingSourcesIds = "prefillingSourcesIds"; + public UUID getId() { return id; } @@ -101,6 +105,14 @@ public class SectionPersist { this.descriptionTemplates = descriptionTemplates; } + public List getPrefillingSourcesIds() { + return prefillingSourcesIds; + } + + public void setPrefillingSourcesIds(List prefillingSourcesIds) { + this.prefillingSourcesIds = prefillingSourcesIds; + } + @Component(SectionPersistValidator.ValidatorName) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public static class SectionPersistValidator extends BaseValidator { diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionFieldPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionFieldPersist.java index 4a525a625..1288ea9dc 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionFieldPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionFieldPersist.java @@ -91,7 +91,11 @@ public class PrefillingSourceDefinitionFieldPersist { @Override protected List specifications(PrefillingSourceDefinitionFieldPersist item) { - return Arrays.asList(); + return Arrays.asList( + this.spec() + .must(() -> !this.isEmpty(item.getCode())) + .failOn(PrefillingSourceDefinitionFieldPersist._code).failWith(messageSource.getMessage("Validation_Required", new Object[]{PrefillingSourceDefinitionFieldPersist._code}, LocaleContextHolder.getLocale())) + ); } } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionPersist.java index ec8e8e503..ed6f4c5ee 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionPersist.java @@ -23,6 +23,9 @@ public class PrefillingSourceDefinitionPersist { private ExternalFetcherApiSourceConfigurationPersist getConfiguration; public static final String _getConfiguration = "getConfiguration"; + private Boolean getEnabled; + public static final String _getEnabled = "getEnabled"; + private List fields; public static final String _fields = "fields"; @@ -42,6 +45,14 @@ public class PrefillingSourceDefinitionPersist { this.getConfiguration = getConfiguration; } + public Boolean getGetEnabled() { + return getEnabled; + } + + public void setGetEnabled(Boolean getEnabled) { + this.getEnabled = getEnabled; + } + public List getFields() { return fields; } @@ -82,11 +93,11 @@ public class PrefillingSourceDefinitionPersist { .on(PrefillingSourceDefinitionPersist._searchConfiguration) .over(item.getSearchConfiguration()) .using(() -> this.validatorFactory.validator(ExternalFetcherApiSourceConfigurationPersist.ExternalFetcherApiSourceConfigurationPersistValidator.class)), -// this.refSpec() TODO -// .iff(() -> !this.isNull(item.getGetConfiguration())) -// .on(PrefillingSourceDefinitionPersist._getConfiguration) -// .over(item.getGetConfiguration()) -// .using(() -> this.validatorFactory.validator(ExternalFetcherApiSourceConfigurationPersist.ExternalFetcherApiSourceConfigurationPersistValidator.class)), + this.refSpec() + .iff(() -> !this.isNull(item.getGetConfiguration()) && item.getGetEnabled()) + .on(PrefillingSourceDefinitionPersist._getConfiguration) + .over(item.getGetConfiguration()) + .using(() -> this.validatorFactory.validator(ExternalFetcherApiSourceConfigurationPersist.ExternalFetcherApiSourceConfigurationPersistValidator.class)), this.navSpec() .iff(() -> !this.isListNullOrEmpty(item.getFields())) .on(PrefillingSourceDefinitionPersist._fields) diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dmpblueprint/DmpBlueprintServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/dmpblueprint/DmpBlueprintServiceImpl.java index 33fc249db..79cb450e1 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/dmpblueprint/DmpBlueprintServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dmpblueprint/DmpBlueprintServiceImpl.java @@ -216,6 +216,7 @@ public class DmpBlueprintServiceImpl implements DmpBlueprintService { data.setLabel(persist.getLabel()); data.setOrdinal(persist.getOrdinal()); data.setHasTemplates(persist.getHasTemplates()); + data.setPrefillingSourcesIds(persist.getPrefillingSourcesIds()); if (!this.conventionService.isListNullOrEmpty(persist.getFields())) { data.setFields(new ArrayList<>()); for (FieldPersist fieldPersist : persist.getFields()) { diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceServiceImpl.java index 4d6fc29ab..a8c36a34e 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceServiceImpl.java @@ -117,7 +117,7 @@ public class PrefillingSourceServiceImpl implements PrefillingSourceService { if (persist.getSearchConfiguration() != null ) { data.setSearchConfiguration(this.buildExternalFetcherApiConfigEntity(persist.getSearchConfiguration())); } - if (persist.getGetConfiguration() != null ) { + if (persist.getGetConfiguration() != null && persist.getGetEnabled()) { data.setGetConfiguration(this.buildExternalFetcherApiConfigEntity(persist.getGetConfiguration())); } diff --git a/dmp-frontend/src/app/core/model/dmp-blueprint/dmp-blueprint.ts b/dmp-frontend/src/app/core/model/dmp-blueprint/dmp-blueprint.ts index 7398dcbff..abe85a36b 100644 --- a/dmp-frontend/src/app/core/model/dmp-blueprint/dmp-blueprint.ts +++ b/dmp-frontend/src/app/core/model/dmp-blueprint/dmp-blueprint.ts @@ -5,6 +5,7 @@ import { DmpBlueprintSystemFieldType } from "@app/core/common/enum/dmp-blueprint import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model"; import { Guid } from "@common/types/guid"; import { ReferenceType } from "../reference-type/reference-type"; +import { PrefillingSource } from "../prefilling-source/prefilling-source"; export interface DmpBlueprint extends BaseEntity { @@ -28,6 +29,7 @@ export interface DmpBlueprintDefinitionSection { fields: FieldInSection[]; hasTemplates: boolean; descriptionTemplates?: DescriptionTemplatesInSection[]; + prefillingSources: PrefillingSource[]; } export interface DescriptionTemplatesInSection { @@ -87,6 +89,7 @@ export interface DmpBlueprintDefinitionSectionPersist { fields: FieldInSectionPersist[]; hasTemplates: boolean; descriptionTemplates?: DescriptionTemplatesInSectionPersist[]; + prefillingSourcesIds: Guid[]; } export interface DescriptionTemplatesInSectionPersist { diff --git a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts index 19d7510b5..018897aad 100644 --- a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts +++ b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts @@ -176,8 +176,8 @@ export class EnumUtils { toExternalFetcherSourceTypeString(status: ExternalFetcherSourceType): string { switch (status) { - case ExternalFetcherSourceType.API: return this.language.instant('TYPES.REFERENCE-TYPE-SOURCE-TYPE.API'); - case ExternalFetcherSourceType.STATIC: return this.language.instant('TYPES.REFERENCE-TYPE-SOURCE-TYPE.STATIC'); + case ExternalFetcherSourceType.API: return this.language.instant('TYPES.EXTERNAL-FETCHER-SOURCE-TYPE.API'); + case ExternalFetcherSourceType.STATIC: return this.language.instant('TYPES.EXTERNAL-FETCHER-SOURCE-TYPE.STATIC'); } } @@ -191,8 +191,8 @@ export class EnumUtils { toExternalFetcherApiHTTPMethodTypeString(status: ExternalFetcherApiHTTPMethodType): string { switch (status) { - case ExternalFetcherApiHTTPMethodType.GET: return this.language.instant('TYPES.REFERENCE-TYPE-EXTERNAL-API-HTTP-METHOD-TYPE.GET'); - case ExternalFetcherApiHTTPMethodType.POST: return this.language.instant('TYPES.REFERENCE-TYPE-EXTERNAL-API-HTTP-METHOD-TYPE.POST'); + case ExternalFetcherApiHTTPMethodType.GET: return this.language.instant('TYPES.EXTERNAL-FETCHER-API-HTTP-METHOD-TYPE.GET'); + case ExternalFetcherApiHTTPMethodType.POST: return this.language.instant('TYPES.EXTERNAL-FETCHER-API-HTTP-METHOD-TYPE.POST'); } } diff --git a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.html b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.html index 47c1cbcce..e68cf2a99 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.html @@ -247,6 +247,13 @@ {{section.get('descriptionTemplates').getError('backendError').message}} +
+ + {{'DMP-BLUEPRINT-EDITOR.FIELDS.PREFILLING-SOURCES' | translate}} + + {{section.get('prefillingSourcesIds').getError('backendError').message}} + +
diff --git a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.ts b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.ts index 8a46c19a2..d0b3ee603 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.ts @@ -42,6 +42,7 @@ import { DmpBlueprintEditorResolver } from './dmp-blueprint-editor.resolver'; import { DmpBlueprintEditorService } from './dmp-blueprint-editor.service'; import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service'; import { SemanticsService } from '@app/core/services/semantic/semantics.service'; +import { PrefillingSourceService } from '@app/core/services/prefilling-source/prefilling-source.service'; @Component({ @@ -124,7 +125,8 @@ export class DmpBlueprintEditorComponent extends BaseEditor this.fields.push(new FieldInSectionEditorModel(this.validationErrorModel).fromModel(x))); } if (item.descriptionTemplates) { item.descriptionTemplates.map(x => this.descriptionTemplates.push(new DescriptionTemplatesInSectionEditorModel(this.validationErrorModel).fromModel(x))); } + if (item.prefillingSources) this.prefillingSourcesIds = item.prefillingSources.map(x => x.id); } return this; } @@ -227,7 +229,8 @@ export class DmpBlueprintDefinitionSectionEditorModel implements DmpBlueprintDef disabled: disabled }) ), context.getValidation('descriptionTemplates').validators - ) + ), + prefillingSourcesIds: [{ value: this.prefillingSourcesIds, disabled: disabled }, context.getValidation('prefillingSourcesIds').validators], }); } @@ -246,6 +249,7 @@ export class DmpBlueprintDefinitionSectionEditorModel implements DmpBlueprintDef baseValidationArray.push({ key: 'hasTemplates', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}hasTemplates`)] }); baseValidationArray.push({ key: 'fields', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}fields`)] }); baseValidationArray.push({ key: 'descriptionTemplates', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}descriptionTemplates`)] }); + baseValidationArray.push({ key: 'prefillingSourcesIds', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}prefillingSourcesIds`)] }); baseValidationArray.push({ key: 'hash', validators: [] }); baseContext.validation = baseValidationArray; @@ -263,7 +267,7 @@ export class DmpBlueprintDefinitionSectionEditorModel implements DmpBlueprintDef validationErrorModel }); - ['id', 'label', 'ordinal', 'description', 'hasTemplates', 'hash'].forEach(keyField => { + ['id', 'label', 'ordinal', 'description', 'hasTemplates', 'prefillingSourcesIds', 'hash'].forEach(keyField => { const control = formGroup?.get(keyField); control?.clearValidators(); control?.addValidators(context.getValidation(keyField).validators); diff --git a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.resolver.ts b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.resolver.ts index f80098b14..d778d6235 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.resolver.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection, ExtraFieldInSection, FieldInSection, ReferenceTypeFieldInSection, SystemFieldInSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; +import { PrefillingSource } from '@app/core/model/prefilling-source/prefilling-source'; import { ReferenceType } from '@app/core/model/reference-type/reference-type'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; @@ -46,6 +47,10 @@ export class DmpBlueprintEditorResolver extends BaseEditorResolver { [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.label)].join('.'), [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.minMultiplicity)].join('.'), [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.maxMultiplicity)].join('.'), + + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.prefillingSources), nameof(x => x.id)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.prefillingSources), nameof(x => x.label)].join('.'), + nameof(x => x.createdAt), nameof(x => x.hash), nameof(x => x.isActive) diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.html b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.html index 369a7f40a..0621f41eb 100644 --- a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.html @@ -113,7 +113,7 @@
- + {{'PREFILLING-SOURCE-EDITOR.FIELDS.GET-SOURCE-CONFIGURATION' | translate}} {{formGroup.get('definition').get('getEnabled').getError('backendError').message}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts index 7687535f4..3ce89ed69 100644 --- a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts @@ -25,9 +25,10 @@ import { TranslateService } from '@ngx-translate/core'; import { map, takeUntil } from 'rxjs/operators'; import { PrefillingSourceEditorResolver } from './prefilling-source-editor.resolver'; import { PrefillingSourceEditorService } from './prefilling-source-editor.service'; -import { PrefillingSourceEditorModel } from './prefilling-source-editor.model'; +import { PrefillingSourceDefinitionEditorModel, PrefillingSourceEditorModel } from './prefilling-source-editor.model'; import { ResultFieldsMappingConfigurationEditorModel } from '@app/ui/external-fetcher/external-fetcher-source-editor.model'; import { SemanticsService } from '@app/core/services/semantic/semantics.service'; +import { MatCheckboxChange } from '@angular/material/checkbox'; @Component({ selector: 'app-prefilling-source-editor-component', @@ -110,9 +111,6 @@ export class PrefillingSourceEditorComponent extends BaseEditor PrefillingSourceDefinitionFieldEditorModel.reapplyValidators({ formGroup: control as UntypedFormGroup, rootPath: `${rootPath}fields[${index}].`, validationErrorModel: validationErrorModel }) ); + + ExternalFetcherBaseSourceConfigurationEditorModel.reapplyValidators({ + formGroup: formGroup.get('searchConfiguration') as UntypedFormGroup, + rootPath: `${rootPath}searchConfiguration.`, + validationErrorModel: validationErrorModel + }); + + if(formGroup.get('getEnabled').value == true){ + ExternalFetcherBaseSourceConfigurationEditorModel.reapplyValidators({ + formGroup: formGroup.get('getConfiguration') as UntypedFormGroup, + rootPath: `${rootPath}getConfiguration.`, + validationErrorModel: validationErrorModel + }); + } } } diff --git a/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.ts b/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.ts index 6f3174d06..54eed58e1 100644 --- a/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.ts +++ b/dmp-frontend/src/app/ui/external-fetcher/external-fetcher-source.component.ts @@ -6,7 +6,7 @@ import { ReferenceType } from '@app/core/model/reference-type/reference-type'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { BaseComponent } from '@common/base/base.component'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; -import { QueryCaseConfigEditorModel, QueryConfigEditorModel, StaticOptionEditorModel } from './external-fetcher-source-editor.model'; +import { ExternalFetcherBaseSourceConfigurationEditorModel, QueryCaseConfigEditorModel, QueryConfigEditorModel, StaticOptionEditorModel } from './external-fetcher-source-editor.model'; import { Guid } from '@common/types/guid'; @Component({ @@ -34,7 +34,16 @@ export class ExternalFetcherSourceComponent extends BaseComponent implements OnI ) { super(); } ngOnInit() { - console.log(this.referenceTypeSourceIndex); + } + + private reApplyValidators(){ + ExternalFetcherBaseSourceConfigurationEditorModel.reapplyValidators( + { + formGroup: this.formGroup, + validationErrorModel: this.validationErrorModel, + rootPath: this.validationRootPath + } + ) } // @@ -50,7 +59,9 @@ export class ExternalFetcherSourceComponent extends BaseComponent implements OnI removeQuery(queryIndex: number): void { const formArray = (this.formGroup.get('queries') as FormArray); - formArray.removeAt(queryIndex); + formArray.removeAt(queryIndex); + this.reApplyValidators(); + formArray.markAsDirty(); } // cases @@ -65,6 +76,8 @@ export class ExternalFetcherSourceComponent extends BaseComponent implements OnI removeCase(queryIndex: number, index: number): void { const formArray = (this.formGroup.get('queries') as FormArray).at(queryIndex).get('cases') as FormArray; formArray.removeAt(index); + this.reApplyValidators(); + formArray.markAsDirty(); } // Options @@ -88,6 +101,8 @@ export class ExternalFetcherSourceComponent extends BaseComponent implements OnI removeOption(optionIndex: number): void { const formArray = (this.formGroup.get('options') as FormArray); formArray.removeAt(optionIndex); + this.reApplyValidators(); + formArray.markAsDirty(); } setReferenceTypeDependenciesMap(ids: Guid[], index: number){ diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index b0c119da6..2e831445e 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -1681,7 +1681,8 @@ "OPTIONS-ROOT": "Options Root", "LABEL": "Label", "VALUE": "Value" - } + }, + "PREFILLING-SOURCES":"Prefilling Sources" }, "ACTIONS": { "ADD-FIELD": "Add Field", @@ -2364,11 +2365,11 @@ "TEXT": "Text", "DATE": "Date" }, - "REFERENCE-TYPE-SOURCE-TYPE": { + "EXTERNAL-FETCHER-SOURCE-TYPE": { "API": "API", "STATIC": "Static" }, - "REFERENCE-TYPE-EXTERNAL-API-HTTP-METHOD-TYPE": { + "EXTERNAL-FETCHER-API-HTTP-METHOD-TYPE": { "GET": "GET", "POST": "POST" }, From 9989f5ca6961f4028fdf8da79718af66d44d58d8 Mon Sep 17 00:00:00 2001 From: amentis Date: Wed, 28 Feb 2024 13:29:53 +0200 Subject: [PATCH 6/9] prefilling sources ui changes --- ...xternalFetcherApiSourceConfigurationPersist.java | 3 --- .../core/services/utilities/enum-utils.service.ts | 9 +++++++++ .../editor/prefilling-source-editor.component.html | 13 ++++++------- .../editor/prefilling-source-editor.component.ts | 9 ++++----- .../external-fetcher-source.component.html | 5 ++--- dmp-frontend/src/assets/i18n/en.json | 10 +++++++++- 6 files changed, 30 insertions(+), 19 deletions(-) diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherApiSourceConfigurationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherApiSourceConfigurationPersist.java index dc71ab873..b78da406e 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherApiSourceConfigurationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/externalfetcher/ExternalFetcherApiSourceConfigurationPersist.java @@ -160,9 +160,6 @@ public class ExternalFetcherApiSourceConfigurationPersist extends ExternalFetche this.spec() .must(() -> !this.isEmpty(item.getContentType())) .failOn(ExternalFetcherApiSourceConfigurationPersist._contentType).failWith(messageSource.getMessage("Validation_Required", new Object[]{ExternalFetcherApiSourceConfigurationPersist._contentType}, LocaleContextHolder.getLocale())), - this.spec() - .must(() -> !this.isEmpty(item.getFirstPage())) - .failOn(ExternalFetcherApiSourceConfigurationPersist._firstPage).failWith(messageSource.getMessage("Validation_Required", new Object[]{ExternalFetcherApiSourceConfigurationPersist._firstPage}, LocaleContextHolder.getLocale())), this.spec() .must(() -> !this.isNull(item.getHttpMethod())) .failOn(ExternalFetcherApiSourceConfigurationPersist._httpMethod).failWith(messageSource.getMessage("Validation_Required", new Object[]{ExternalFetcherApiSourceConfigurationPersist._httpMethod}, LocaleContextHolder.getLocale())), diff --git a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts index 018897aad..2d90dfa50 100644 --- a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts +++ b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts @@ -38,6 +38,7 @@ import { ValidationType } from '../../common/enum/validation-type'; import { DescriptionTemplateExternalSelectAuthType } from '@app/core/common/enum/description-template-external-select-auth-type'; import { DmpBlueprintFieldCategory } from '@app/core/common/enum/dmp-blueprint-field-category'; import { DmpUserType } from '@app/core/common/enum/dmp-user-type'; +import { PrefillingSourceSystemTargetType } from '@app/core/common/enum/prefilling-source-system-target-type'; @Injectable() export class EnumUtils { @@ -398,5 +399,13 @@ export class EnumUtils { } } + public toPrefillingSourceSystemTargetTypeString(value: PrefillingSourceSystemTargetType): string { + switch (value) { + case PrefillingSourceSystemTargetType.Label: return this.language.instant('TYPES.PREFILLING-SOURCE-SYSTEM-TARGET-TYPE.LABEL'); + case PrefillingSourceSystemTargetType.Description: return this.language.instant('TYPES.PREFILLING-SOURCE-SYSTEM-TARGET-TYPE.DESCRIPTION'); + case PrefillingSourceSystemTargetType.Tags: return this.language.instant('TYPES.PREFILLING-SOURCE-SYSTEM-TARGET-TYPE.TAGS'); + } + } + } diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.html b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.html index 0621f41eb..c07270810 100644 --- a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.html @@ -40,9 +40,6 @@
-

- -

@@ -67,12 +64,13 @@
{{'PREFILLING-SOURCE-EDITOR.FIELDS.SYSTEM-TARGET' | translate}} - - {{field.get('systemFieldTarget').getError('backendError').message}} + + {{enumUtils.toPrefillingSourceSystemTargetTypeString(systemFieldTarget)}} + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
-
+
{{'PREFILLING-SOURCE-EDITOR.FIELDS.SEMANTIC-TARGET' | translate}} @@ -99,8 +97,9 @@
+ + type="button" (click)="submitFields()" [disabled]="!formGroup.get('definition').get('fields').valid">{{'PREFILLING-SOURCE-EDITOR.ACTIONS.SUBMIT-FIELDS' | translate}}
diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts index 3ce89ed69..c5c6ebeba 100644 --- a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts @@ -29,6 +29,7 @@ import { PrefillingSourceDefinitionEditorModel, PrefillingSourceEditorModel } fr import { ResultFieldsMappingConfigurationEditorModel } from '@app/ui/external-fetcher/external-fetcher-source-editor.model'; import { SemanticsService } from '@app/core/services/semantic/semantics.service'; import { MatCheckboxChange } from '@angular/material/checkbox'; +import { PrefillingSourceSystemTargetType } from '@app/core/common/enum/prefilling-source-system-target-type'; @Component({ selector: 'app-prefilling-source-editor-component', @@ -42,6 +43,7 @@ export class PrefillingSourceEditorComponent extends BaseEditor(PrefillingSourceSystemTargetType); protected get canDelete(): boolean { return !this.isDeleted && !this.isNew && this.hasPermission(this.authService.permissionEnum.DeletePrefillingSource); @@ -190,9 +192,6 @@ export class PrefillingSourceEditorComponent extends BaseEditor{{'GENERAL.VALIDATION.REQUIRED' | translate}}
-
+
{{'REFERENCE-TYPE-EDITOR.FIELDS.SOURCE-TYPE' | translate}} @@ -288,7 +288,7 @@
- {{'REFERENCE-TYPE-EDITOR.FIELDS.REFERENCE-TYPE' | translate}} + {{'REFERENCE-TYPE-EDITOR.FIELDS.DEPENDENCY' | translate}} {{referenceType.code}} @@ -355,5 +355,4 @@
- {{formGroup.value | json}} \ No newline at end of file diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 2e831445e..ec587ef85 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -1529,6 +1529,7 @@ "TYPE": "Type", "SEPARATOR": "Separator", "DEPENDENCIES": "Dependencies", + "DEPENDENCY": "Dependency", "REQUIRED": "Required", "DEFAULT-VALUE": "Default Value", "CASE": "Case", @@ -1591,6 +1592,8 @@ "PREFILLING-SOURCE-EDITOR": { "NEW": "New Prefilling Source", "FIELDS": { + "SOURCE-CONFIGURATION":"Search Source Configuration", + "GET-SOURCE-CONFIGURATION": "Get Source Configuration", "LABEL": "Label", "FIELD": "Field", "CODE": "Code", @@ -1606,7 +1609,7 @@ "DELETE": "Delete", "ADD-FIELD": "Add Field", "REMOVE-FIELD": "Remove Field", - "SUBMIT-FIELDS": "Submit" + "SUBMIT-FIELDS": "Submit Fields" }, "CONFIRM-DELETE-DIALOG": { "MESSAGE": "Would you like to delete this Prefilling Source?", @@ -2489,6 +2492,11 @@ "SYSTEM": "System", "EXTRA": "Custom", "REFERENCE-TYPE": "External Reference" + }, + "PREFILLING-SOURCE-SYSTEM-TARGET-TYPE": { + "LABEL": "Label", + "DESCRIPTION": "Description", + "TAGS": "Tags" } }, "ADDRESEARCHERS-EDITOR": { From be796bc68f15941baf9d36f89556754694658654 Mon Sep 17 00:00:00 2001 From: amentis Date: Wed, 28 Feb 2024 13:30:12 +0200 Subject: [PATCH 7/9] prefilling sources ui changes --- .../core/common/enum/prefilling-source-system-target-type.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 dmp-frontend/src/app/core/common/enum/prefilling-source-system-target-type.ts diff --git a/dmp-frontend/src/app/core/common/enum/prefilling-source-system-target-type.ts b/dmp-frontend/src/app/core/common/enum/prefilling-source-system-target-type.ts new file mode 100644 index 000000000..beb6ae686 --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/prefilling-source-system-target-type.ts @@ -0,0 +1,5 @@ +export enum PrefillingSourceSystemTargetType { + Label = "label", + Description = "description", + Tags= "tags" +} \ No newline at end of file From 067e81207f9b9f632aefec197b073d3bcb007bb8 Mon Sep 17 00:00:00 2001 From: Diamantis Tziotzios Date: Wed, 28 Feb 2024 15:41:36 +0200 Subject: [PATCH 8/9] prefill popup refactor --- .../core/model/annotation.model.ts | 38 ++- .../common/enum/annotation-entity-type.ts | 4 + .../enum/annotation-protection-type.enum.ts | 4 + .../annotation-dialog.component.html | 149 +++++++++ .../annotation-dialog.component.scss | 68 ++++ .../annotation-dialog.component.ts | 197 +++++++++++ .../annotation-dialog.module.ts | 20 ++ .../editor/description-editor.component.ts | 56 +++- .../editor/description-editor.module.ts | 6 +- .../field-set-title.component.html | 2 +- .../field-set-title.component.ts | 1 - .../form-field-set.component.html | 3 + .../form-field-set.component.scss | 6 + .../form-field-set.component.ts | 25 ++ .../description-form.module.ts | 4 +- .../prefill-description.component.html | 42 +-- .../prefill-description.component.scss | 2 +- .../prefill-description.component.ts | 306 +++++++++--------- dmp-frontend/src/assets/i18n/en.json | 13 + 19 files changed, 738 insertions(+), 208 deletions(-) create mode 100644 dmp-frontend/src/app/core/common/enum/annotation-entity-type.ts create mode 100644 dmp-frontend/src/app/core/common/enum/annotation-protection-type.enum.ts create mode 100644 dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.html create mode 100644 dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.scss create mode 100644 dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.ts create mode 100644 dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.module.ts diff --git a/dmp-frontend/src/annotation-service/core/model/annotation.model.ts b/dmp-frontend/src/annotation-service/core/model/annotation.model.ts index 7974172e5..f61a3763a 100644 --- a/dmp-frontend/src/annotation-service/core/model/annotation.model.ts +++ b/dmp-frontend/src/annotation-service/core/model/annotation.model.ts @@ -1,21 +1,27 @@ -import { IsActive } from "@app/core/common/enum/is-active.enum"; +import { AnnotationProtectionType } from "@app/core/common/enum/annotation-protection-type.enum"; +import { User } from "@app/core/model/user/user"; +import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model"; import { Guid } from "@common/types/guid"; -export interface Annotation { - id: Guid; - entityId: Guid; - entityType: string; - anchor?: string; - payload: string; - createdAt: Date; - updatedAt: Date; - isActive: IsActive; +export interface Annotation extends BaseEntity { + entityId: Guid; + entityType: string; + anchor?: string; + payload: string; + timeStamp: Date; + author: User; + threadId: Guid; + parent: Annotation; + protection: AnnotationProtectionType; } -export interface AnnotationPersist { - subjectId: Guid; - entityId: Guid; - entityType: string; - anchor: string; - payload: string; +export interface AnnotationPersist extends BaseEntityPersist { + subjectId: Guid; + entityId: Guid; + entityType: string; + anchor: string; + payload: string; + threadId?: Guid; + parentId?: Guid; + protection: AnnotationProtectionType; } \ No newline at end of file diff --git a/dmp-frontend/src/app/core/common/enum/annotation-entity-type.ts b/dmp-frontend/src/app/core/common/enum/annotation-entity-type.ts new file mode 100644 index 000000000..ae1df923f --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/annotation-entity-type.ts @@ -0,0 +1,4 @@ +export enum AnnotationEntityType { + Description = "description", + Dmp = "dmp" +} diff --git a/dmp-frontend/src/app/core/common/enum/annotation-protection-type.enum.ts b/dmp-frontend/src/app/core/common/enum/annotation-protection-type.enum.ts new file mode 100644 index 000000000..109de1ff3 --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/annotation-protection-type.enum.ts @@ -0,0 +1,4 @@ +export enum AnnotationProtectionType { + Private = 0, + EntityAccessors = 1 +} diff --git a/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.html b/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.html new file mode 100644 index 000000000..c0ba38570 --- /dev/null +++ b/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.html @@ -0,0 +1,149 @@ +
+
+ + +
+
+ + + {{threadFormGroup.get('text').getError('backendError')?.message}} + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + + +
+ +
+
+
+
{{'APP.ANNOTATION.TITLE' | translate}}
+
+
+ +
+
+
+
+
+
+
+
+
+
{{thread.timeStamp | date:'EEEE, MMMM d, y, h:mm a'}}
+
{{getAnnotationProtectionType(thread)}}
+
{{getAnnotationProtectionType(thread)}}
+
{{getAnnotationProtectionType(thread)}}
+
{{thread.text}}
+
+ {{'APP.ANNOTATION.THREADS.FROM-USER' | translate}} {{thread.author.name}} + + +
+
+
+
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
{{annotation.timeStamp | date:'EEEE, MMMM d, y, h:mm a'}}
+
{{annotation.text}}
+
+ {{'APP.ANNOTATION.THREADS.FROM-USER' | translate}} + {{annotation.author.name}} + +
+
+
+
+
+
+
+ + +
+
+ + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+ +
+
+
+
+
+
+
+
+
+ close +
+
+
+ +
+

{{'NAV-BAR.START-NEW-DMP' | translate}}

+
+
+

{{'NAV-BAR.START-NEW-DMP-TXT' | translate}}

+
+
+
+
+ +
+
+

{{ 'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.FIRST-STEP.OR' | translate }}

+
+
+ +
+
+
+
+
+
+ info +
+ + {{'GENERAL.START-NEW-DMP-DIALOG.IMPORT' | translate }} {{'GENERAL.START-NEW-DMP-DIALOG.FUNCTION-SUPPORTS' | translate }} + {{'GENERAL.START-NEW-DMP-DIALOG.JSON-FILES' | translate }} {{'GENERAL.START-NEW-DMP-DIALOG.PRODUCED' | translate }} + {{'GENERAL.START-NEW-DMP-DIALOG.RDA-SPECIFICATIONS' | translate }} + {{'GENERAL.START-NEW-DMP-DIALOG.MACHINE-ACTIONABLE' | translate }} + +
+
\ No newline at end of file diff --git a/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.scss b/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.scss new file mode 100644 index 000000000..d59032e36 --- /dev/null +++ b/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.scss @@ -0,0 +1,68 @@ +::ng-deep .mat-dialog-container { + border-radius: 8px; +} + +.form-container { + width: 33rem; + min-height: 14rem; + padding: 0.28rem 0.34rem 0.875rem 0.625rem; +} + +.logo { + width: 8.44rem; +} + +.close-icon { + cursor: pointer; + // margin-right: 20px; + padding: .4rem; + width: auto !important; + height: auto !important; +} + +.close-icon:hover { + background-color: #ECECED !important; + border-radius: 50%; +} + +.content { + margin: 2.17rem 2.304rem 1.1875rem 3.065rem; +} + +.title, +.text { + font-size: 1.25rem; + font-weight: lighter; + color: #000000; + opacity: 0.8; +} + +.title { + font-size: 2.375rem; + margin-bottom: 1.1875rem; +} + +.text { + margin-bottom: 2.9375rem; + line-height: 1.9rem; +} + +.upload-btn { + background-color: white; + color: #212121; + font-weight: bold; + box-shadow: 0px 3px 6px #1e202029; + border: 2px solid #212121; +} + +.actions { + width: 26.667rem; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; +} + +.warn { + color: #f16868; +} diff --git a/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.ts b/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.ts new file mode 100644 index 000000000..725d65c87 --- /dev/null +++ b/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.ts @@ -0,0 +1,197 @@ +import { HttpClient } from '@angular/common/http'; +import { Component, Inject } from '@angular/core'; +import { FormBuilder, FormControl, UntypedFormGroup, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { Router } from '@angular/router'; +import { Annotation, AnnotationPersist } from '@annotation-service/core/model/annotation.model'; +import { AnnotationLookup } from '@annotation-service/core/query/annotation.lookup'; +import { AnnotationService } from '@annotation-service/services/http/annotation.service'; +import { AnnotationProtectionType } from '@app/core/common/enum/annotation-protection-type.enum'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { BaseComponent } from '@common/base/base.component'; +import { FormService } from '@common/forms/form-service'; +import { Guid } from '@common/types/guid'; +import { TranslateService } from '@ngx-translate/core'; +import { takeUntil } from 'rxjs/operators'; +import { nameof } from 'ts-simple-nameof'; + +@Component({ + selector: 'app-start-new-dmp', + templateUrl: './annotation-dialog.component.html', + styleUrls: ['./annotation-dialog.component.scss'] +}) +export class AnnotationDialogComponent extends BaseComponent { + + private entityId: Guid; + private anchor: string; + private entityType: string; + // public annotations: Array = []; + + public threads = new Array(); + public annotationsPerThread = {}; + threadReplyTextsFG: Array; + threadFormGroup: UntypedFormGroup; + private formBuilder: FormBuilder = new FormBuilder(); + + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + private router: Router, + public dialog: MatDialog, + private uiNotificationService: UiNotificationService, + private language: TranslateService, + private annotationService: AnnotationService, + private formService: FormService + ) { + super(); + this.entityId = data.entityId; + this.anchor = data.anchor; + this.entityType = data.entityType; + } + + ngOnInit(): void { + // this.threadFormGroup = new UntypedFormGroup({ + // text: new FormControl(null, [Validators.required]), + // annotationProtectionType: new FormControl(AnnotationProtectionType.Public, [Validators.required]) + // }); + // if (this.entityId != null) { + // this.loadThreads(); + // } + } + + createThread() { + // this.formService.removeAllBackEndErrors(this.threadFormGroup); + // this.formService.touchAllFormFields(this.threadFormGroup); + // if (!this.isFormValid(this.threadFormGroup)) { + // return; + // } + // const threadToCreate: AnnotationPersist = { + // payload: this.threadFormGroup.get('text').value, + // protection: this.threadFormGroup.get('annotationProtectionType').value, + // referenceId: this.referenceId + // }; + // this.annotationService.persist(threadToCreate).pipe(takeUntil(this._destroyed)) + // .subscribe( + // complete => this.onCallbackSuccess(), + // error => this.onCallbackError(error) + // ); + } + + replyThread(threadId: Guid, threadProtection: AnnotationProtectionType) { + // // if (!this.threadReplyTexts[threadId.toString()] || this.threadReplyTexts[threadId.toString()].length === 0) { return; } + // this.formService.removeAllBackEndErrors(this.threadReplyTextsFG[threadId.toString()]); + // this.formService.touchAllFormFields(this.threadReplyTextsFG[threadId.toString()]); + // if (!this.isFormValid(this.threadReplyTextsFG[threadId.toString()])) { + // return; + // } + // const replyToCreate: AnnotationPersist = { + // threadId: threadId, + // text: this.threadReplyTextsFG[threadId.toString()].get('replyText').value, + // protection: threadProtection, + // referenceId: this.referenceId + // }; + // this.annotationService.persist(replyToCreate).pipe(takeUntil(this._destroyed)) + // .subscribe( + // complete => this.onCallbackSuccess(), + // error => this.onCallbackError(error) + // ); + } + + private refreshAnnotations() { + // this.threadReplyTextsFG.forEach(element => { + // element.reset(); + // }); + this.loadThreads(); + } + + private loadThreads() { + const lookup: AnnotationLookup = new AnnotationLookup(); + lookup.entityIds = [this.entityId]; + // lookup.anchors = [this.anchor]; + lookup.entityTypes = [this.entityType]; + lookup.project = { + fields: [ + nameof(x => x.id), + // nameof(x => x.threadId), + // nameof(x => x.threadId), + // nameof(x => x.timeStamp), + // nameof(x => x.author.name), + nameof(x => x.payload), + // nameof(x => x.protection), + ] + }; + + this.annotationService.query(lookup) + .pipe(takeUntil(this._destroyed)) + .subscribe( + data => { + // this.annotationsPerThread = {}; + // this.threadReplyTextsFG = new Array(); + // this.resetFormGroup(); + // this.threads = data.items.filter(item => item.id === item.threadId).sort((a1, a2) => new Date(a2.timeStamp).getTime() - new Date(a1.timeStamp).getTime()); + // this.threads.forEach(element => { + // // this.threadReplyTextsFG.addControl(element.id.toString(), new FormControl(null)); + // this.threadReplyTextsFG[element.id.toString()] = this.fb.group({ replyText: new FormControl(null, [Validators.required]) }); + // this.annotationsPerThread[element.id.toString()] = data.items.filter(x => x.threadId === element.id && x.id !== element.id).sort((a1, a2) => new Date(a1.timeStamp).getTime() - new Date(a2.timeStamp).getTime()); + // }); + // // this.annotationsChanged.emit(this.threads); + }, + error => this.onCallbackError(error), + ); + } + + resetFormGroup() { + this.threadFormGroup.reset(); + this.threadFormGroup.get('annotationProtectionType').setValue(AnnotationProtectionType.EntityAccessors); + } + + isValidText(text: string): boolean { + return !isNullOrUndefined(text) && text.length !== 0 && text !== ''; + } + + // ngOnInit() { + // const lookup: AnnotationLookup = new AnnotationLookup(); + // lookup.entityIds = [this.entityId]; + // // lookup.anchors = [this.anchor]; + // lookup.entityTypes = [this.entityType]; + + // this.annotationService.query(lookup).pipe(takeUntil(this._destroyed)) + // .subscribe( + // data => { + // this.annotations = data.items; + // }, + // error => this.onCallbackError(error) + // ); + // } + + + private onCallbackSuccess() { + this.uiNotificationService.snackBarNotification(this.language.instant('DMP-UPLOAD.UPLOAD-SUCCESS'), SnackBarNotificationLevel.Success); + this.router.navigate(['/reload']).then(() => this.router.navigate(['/plans'])); + // this.router.navigate(['/reload']).then(() => this.isPublic ? this.router.navigate(['/explore-plans']) : this.router.navigate(['/plans'])); + } + + private onCallbackError(error: any) { + this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error); + } + + + cancel() { + this.dialogRef.close(); + } + + send() { + this.dialogRef.close(this.data); + } + + close() { + this.dialogRef.close(false); + } + + startWizard() { + this.router.navigate(['/plans/new']); + this.close(); + } +} diff --git a/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.module.ts b/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.module.ts new file mode 100644 index 000000000..92b80ffb6 --- /dev/null +++ b/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { FormattingModule } from '@app/core/formatting.module'; +import { CommonFormsModule } from '@common/forms/common-forms.module'; +import { CommonUiModule } from '@common/ui/common-ui.module'; +import { AnnotationDialogComponent } from './annotation-dialog.component'; + +@NgModule({ + imports: [ + CommonUiModule, + CommonFormsModule, + FormattingModule, + ], + declarations: [ + AnnotationDialogComponent, + ], + exports: [ + AnnotationDialogComponent, + ] +}) +export class AnnotationDialogModule { } diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts index ae4398e90..925f5837e 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts @@ -1,26 +1,27 @@ +import { DatePipe } from '@angular/common'; import { Component, OnInit, ViewChild } from '@angular/core'; -import { UntypedFormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { DescriptionStatus } from '@app/core/common/enum/description-status'; import { DmpStatus } from '@app/core/common/enum/dmp-status'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { AppPermission } from '@app/core/common/enum/permission.enum'; +import { Description, DescriptionPersist } from '@app/core/model/description/description'; import { AuthService } from '@app/core/services/auth/auth.service'; +import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service'; +import { DescriptionService } from '@app/core/services/description/description.service'; +import { DmpService } from '@app/core/services/dmp/dmp.service'; import { LockService } from '@app/core/services/lock/lock.service'; +import { LoggingService } from '@app/core/services/logging/logging-service'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; -import { FileUtils } from '@app/core/services/utilities/file-utils.service'; -import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; -import { DatePipe } from '@angular/common'; -import { IsActive } from '@app/core/common/enum/is-active.enum'; -import { AppPermission } from '@app/core/common/enum/permission.enum'; -import { Description, DescriptionPersist } from '@app/core/model/description/description'; -import { DescriptionService } from '@app/core/services/description/description.service'; -import { LoggingService } from '@app/core/services/logging/logging-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; +import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; +import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; import { VisibilityRulesService } from '@app/ui/description/editor/description-form/visibility-rules/visibility-rules.service'; import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; import { BaseEditor } from '@common/base/base-editor'; @@ -34,12 +35,10 @@ import { map, takeUntil } from 'rxjs/operators'; import { DescriptionEditorModel, DescriptionPropertyDefinitionEditorModel } from './description-editor.model'; import { DescriptionEditorResolver } from './description-editor.resolver'; import { DescriptionEditorService } from './description-editor.service'; +import { PrefillDescriptionDialogComponent } from './prefill-description/prefill-description.component'; import { ToCEntry } from './table-of-contents/models/toc-entry'; -import { TableOfContentsComponent } from './table-of-contents/table-of-contents.component'; import { ToCEntryType } from './table-of-contents/models/toc-entry-type.enum'; -import { DmpService } from '@app/core/services/dmp/dmp.service'; -import { DescriptionTemplateSection } from '@app/core/model/description-template/description-template'; -import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service'; +import { TableOfContentsComponent } from './table-of-contents/table-of-contents.component'; @Component({ selector: 'app-description-editor-component', @@ -140,12 +139,18 @@ export class DescriptionEditorComponent extends BaseEditor { - const isPublicDescription = params['public']; + const itemId = params['id']; + const dmpId = params['dmpId']; + const dmpSectionId = params['dmpSectionId']; + + const isPublicDescription = params['public']; const newDmpId = params['newDmpId']; + + // const publicId = params['publicId']; // this.dmpId = params['dmpId']; // this.dmpSectionIndex = parseInt(params['dmpSectionIndex']); @@ -237,6 +242,29 @@ export class DescriptionEditorComponent extends BaseEditor { + if (result) { + // this.descriptionModel = this.descriptionModel.fromModel(result); + // this.descriptionModel.dmp = data; + // this.descriptionModel.dmpSectionIndex = this.dmpSectionIndex; + // this.formGroup = this.descriptionModel.buildForm(); + // this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue())); + // this.formGroup.get('dmp').disable(); + // this.loadDescriptionProfiles(); + // this.registerFormListeners(); + } + }) } // if (this.itemId != null && this.newDmpId == null) { diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.module.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.module.ts index 350589979..23a6ecdd5 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.module.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.module.ts @@ -12,6 +12,7 @@ import { DescriptionFormProgressIndicationModule } from './form-progress-indicat import { TableOfContentsModule } from './table-of-contents/table-of-contents.module'; import { RichTextEditorModule } from '@app/library/rich-text-editor/rich-text-editor.module'; import { TagsFieldModule } from '@app/ui/tag/tags-field/tags-field.module'; +import { PrefillDescriptionDialogComponent } from './prefill-description/prefill-description.component'; @NgModule({ imports: [ @@ -28,12 +29,13 @@ import { TagsFieldModule } from '@app/ui/tag/tags-field/tags-field.module'; ], declarations: [ DescriptionEditorComponent, - DescriptionBaseFieldsEditorComponent + DescriptionBaseFieldsEditorComponent, + PrefillDescriptionDialogComponent ], exports: [ ], providers: [ - VisibilityRulesService + VisibilityRulesService, ] }) export class DescriptionEditorModule { } diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/field-set-title/field-set-title.component.html b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/field-set-title/field-set-title.component.html index a4ff6dc86..bd01cfe40 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/field-set-title/field-set-title.component.html +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/field-set-title/field-set-title.component.html @@ -21,4 +21,4 @@ {{'DATASET-EDITOR.QUESTION.EXTENDED-DESCRIPTION.VIEW-LESS' | translate}} - + \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/field-set-title/field-set-title.component.ts b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/field-set-title/field-set-title.component.ts index 1efc1733a..a237e2229 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/field-set-title/field-set-title.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/field-set-title/field-set-title.component.ts @@ -18,5 +18,4 @@ export class DescriptionFormFieldSetTitleComponent implements OnInit { ngOnInit() { } - } diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.html b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.html index 8e3faf1b5..84b84ee64 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.html +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.html @@ -1,6 +1,9 @@
+
diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.scss b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.scss index 20b9e2f82..2fddd967e 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.scss +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.scss @@ -6,3 +6,9 @@ width: 110px; display: flex; } + +.annotation-icon{ + margin-top: 1.625rem; + width: auto; + height: auto; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.ts b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.ts index d3ed1c9fc..68d735d1e 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.ts @@ -10,6 +10,9 @@ import { DescriptionPropertyDefinitionEditorModel, DescriptionPropertyDefinition import { FormFieldSetEditorDialogComponent } from './dialog-editor/form-fieldset-editor-dialog.component'; import { cloneAbstractControl } from '@app/utilities/enhancers/utils'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; +import { Guid } from '@common/types/guid'; +import { AnnotationDialogComponent } from '@app/ui/annotations/annotation-dialog-component/annotation-dialog.component'; +import { AnnotationEntityType } from '@app/core/common/enum/annotation-entity-type'; @Component({ selector: 'app-description-form-field-set', @@ -21,6 +24,7 @@ export class DescriptionFormFieldSetComponent extends BaseComponent { @Input() fieldSet: DescriptionTemplateFieldSet; @Input() propertiesFormGroup: UntypedFormGroup; + @Input() descriptionId: Guid; get isMultiplicityEnabled() { return this.fieldSet.multiplicity != null && this.fieldSet.multiplicity.min != 0 && this.fieldSet.multiplicity.max != 0; @@ -114,6 +118,27 @@ export class DescriptionFormFieldSetComponent extends BaseComponent { }); } + // + // + // Annotations + // + // + showAnnotations(fieldSetId: string) { + const dialogRef = this.dialog.open(AnnotationDialogComponent, { + width: '528px', + data: { + entityId: this.descriptionId, + anchor: fieldSetId, + entityType: AnnotationEntityType.Description + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result && result.success) { + //TODO refactor + } + }); + } + // deleteCompositeFieldFormGroup() { diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/description-form.module.ts b/dmp-frontend/src/app/ui/description/editor/description-form/description-form.module.ts index bab54aee1..a9d4deb9c 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/description-form.module.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-form/description-form.module.ts @@ -2,6 +2,7 @@ import { NgModule } from '@angular/core'; import { FormattingModule } from "@app/core/formatting.module"; import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module'; import { RichTextEditorModule } from "@app/library/rich-text-editor/rich-text-editor.module"; +import { AnnotationDialogModule } from '@app/ui/annotations/annotation-dialog-component/annotation-dialog.module'; import { ReferenceFieldModule } from '@app/ui/reference/reference-field/reference-field.module'; import { CommonFormsModule } from '@common/forms/common-forms.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; @@ -22,7 +23,8 @@ import { DescriptionFormComponent } from './description-form.component'; RichTextEditorModule, NgxDropzoneModule, FormattingModule, - ReferenceFieldModule + ReferenceFieldModule, + AnnotationDialogModule ], declarations: [ DescriptionFormComponent, diff --git a/dmp-frontend/src/app/ui/description/editor/prefill-description/prefill-description.component.html b/dmp-frontend/src/app/ui/description/editor/prefill-description/prefill-description.component.html index b6d159d7b..8e416f9c2 100644 --- a/dmp-frontend/src/app/ui/description/editor/prefill-description/prefill-description.component.html +++ b/dmp-frontend/src/app/ui/description/editor/prefill-description/prefill-description.component.html @@ -1,7 +1,7 @@
-
- {{'DATASET-CREATE-WIZARD.PREFILL-STEP.TITLE' | translate}} - + {{'PREFILL-DESCRIPTION-DIALOG.TITLE' | translate}} + close
@@ -10,48 +10,48 @@
- {{'DATASET-CREATE-WIZARD.PREFILL-STEP.HINT' | translate}} + {{'PREFILL-DESCRIPTION-DIALOG.HINT' | translate}}
-
+
-
{{'DATASET-CREATE-WIZARD.PREFILL-STEP.OR' | translate}}
+ (click)="closeDialog()">{{'PREFILL-DESCRIPTION-DIALOG.ACTIONS.MANUALLY' | translate}} +
{{'PREFILL-DESCRIPTION-DIALOG.OR' | translate}}
+ (click)="prefillSelected = true">{{'PREFILL-DESCRIPTION-DIALOG.ACTIONS.PREFILL' | translate}}
-
+
-

{{'DATASET-CREATE-WIZARD.PREFILL-STEP.PROFILE' | translate}}

+

{{'PREFILL-DESCRIPTION-DIALOG.DESCRIPTION-TEMPLATE' | translate}}

- - -
- {{profile.label}} + + +
+ {{descriptionTempalte.label}}
- {{prefillForm.get('profile').getError('backendError').message}} + {{prefillForm.get('descriptionTempalte').getError('backendError').message}}
-
+
-
+
+ (click)="next()">{{'PREFILL-DESCRIPTION-DIALOG.ACTIONS.NEXT' | translate}}
diff --git a/dmp-frontend/src/app/ui/description/editor/prefill-description/prefill-description.component.scss b/dmp-frontend/src/app/ui/description/editor/prefill-description/prefill-description.component.scss index 7a892e68b..db6af9d12 100644 --- a/dmp-frontend/src/app/ui/description/editor/prefill-description/prefill-description.component.scss +++ b/dmp-frontend/src/app/ui/description/editor/prefill-description/prefill-description.component.scss @@ -9,7 +9,7 @@ } .template-title { - margin-left: 37px; + margin-left: 1em; white-space: nowrap; width: 480px; overflow: hidden; diff --git a/dmp-frontend/src/app/ui/description/editor/prefill-description/prefill-description.component.ts b/dmp-frontend/src/app/ui/description/editor/prefill-description/prefill-description.component.ts index 08bdc21d1..029f96224 100644 --- a/dmp-frontend/src/app/ui/description/editor/prefill-description/prefill-description.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/prefill-description/prefill-description.component.ts @@ -1,42 +1,46 @@ import { Component, Inject, OnInit } from "@angular/core"; import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from "@angular/material/dialog"; -import { DatasetProfileModel } from "@app/core/model/dataset/dataset-profile"; -import { Prefilling } from "@app/core/model/dataset/prefilling"; -import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection, FieldInSection } from "@app/core/model/dmp-blueprint/dmp-blueprint"; +import { DescriptionTemplate } from "@app/core/model/description-template/description-template"; +import { Dmp } from "@app/core/model/dmp/dmp"; import { DmpBlueprintService } from "@app/core/services/dmp/dmp-blueprint.service"; import { PrefillingService } from "@app/core/services/prefilling.service"; import { ProgressIndicationService } from "@app/core/services/progress-indication/progress-indication-service"; -import { SingleAutoCompleteConfiguration } from "@app/library/auto-complete/single/single-auto-complete-configuration"; -import { PopupNotificationDialogComponent } from "@app/library/notification/popup/popup-notification.component"; import { BaseComponent } from "@common/base/base.component"; import { Guid } from "@common/types/guid"; import { TranslateService } from "@ngx-translate/core"; -import { Observable } from "rxjs"; -import { map, takeUntil } from "rxjs/operators"; -import { nameof } from "ts-simple-nameof"; +import { UUID } from "crypto"; +import { takeUntil } from "rxjs/operators"; @Component({ - selector: 'prefill-dataset-component', - templateUrl: 'prefill-dataset.component.html', - styleUrls: ['prefill-dataset.component.scss'] + selector: 'prefill-description-component', + templateUrl: 'prefill-description.component.html', + styleUrls: ['prefill-description.component.scss'] }) -export class PrefillDatasetComponent extends BaseComponent implements OnInit { +export class PrefillDescriptionDialogComponent extends BaseComponent implements OnInit { progressIndication = false; - prefillAutoCompleteConfiguration: SingleAutoCompleteConfiguration; - isPrefilled: boolean = false; + // prefillAutoCompleteConfiguration: SingleAutoCompleteConfiguration; + prefillSelected: boolean = false; prefillForm: UntypedFormGroup; - constructor(public dialogRef: MatDialogRef, - private prefillingService: PrefillingService, - private dmpBlueprintService: DmpBlueprintService, - private dialog: MatDialog, - private language: TranslateService, + dmp: Dmp; + dmpSectionId: Guid; + availableDescriptionTempaltes: DescriptionTemplate[] = []; + + constructor(public dialogRef: MatDialogRef, + // private prefillingService: PrefillingService, + // private dmpBlueprintService: DmpBlueprintService, + // private dialog: MatDialog, + // private language: TranslateService, private progressIndicationService: ProgressIndicationService, private fb: UntypedFormBuilder, @Inject(MAT_DIALOG_DATA) public data: any) { super(); + + this.dmp = data.dmp; + this.dmpSectionId = data.dmpSectionId; + this.availableDescriptionTempaltes = this.dmp.dmpDescriptionTemplates.filter(x => x.sectionId == this.dmpSectionId).map(x => x.currentDescriptionTemplate); } ngOnInit() { @@ -45,153 +49,153 @@ export class PrefillDatasetComponent extends BaseComponent implements OnInit { }); this.prefillForm = this.fb.group({ type: this.fb.control(false), - profile: this.fb.control('', Validators.required), + descriptionTempalte: this.fb.control('', Validators.required), prefill: this.fb.control(null, Validators.required) }) - if (this.data.availableProfiles && this.data.availableProfiles.length === 1) { - this.addProfileIfUsedLessThanMax(this.data.availableProfiles[0]); - } - this.prefillAutoCompleteConfiguration = { - filterFn: this.searchDatasets.bind(this), - loadDataOnStart: false, - displayFn: (item) => (item['name'].length > 60) ? (item['name'].substr(0, 60) + "...") : item['name'], - titleFn: (item) => item['name'], - subtitleFn: (item) => item['pid'] - }; + // if (this.data.availableProfiles && this.data.availableProfiles.length === 1) { + // this.addProfileIfUsedLessThanMax(this.data.availableProfiles[0]); + // } + // this.prefillAutoCompleteConfiguration = { + // filterFn: this.searchDescriptions.bind(this), + // loadDataOnStart: false, + // displayFn: (item) => (item['name'].length > 60) ? (item['name'].substr(0, 60) + "...") : item['name'], + // titleFn: (item) => item['name'], + // subtitleFn: (item) => item['pid'] + // }; } - addProfileIfUsedLessThanMax(profile: DatasetProfileModel) { - const dmpSectionIndex = this.data.datasetFormGroup.get('dmpSectionIndex').value; - const blueprintId = this.data.datasetFormGroup.get('dmp').value.profile.id; - this.dmpBlueprintService.getSingle(blueprintId, this.getBlueprintDefinitionFields()) - .pipe(takeUntil(this._destroyed)) - .subscribe(result => { - const section = result.definition.sections[dmpSectionIndex]; - if (section.hasTemplates) { - const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === Guid.parse(profile.id)); - if (foundTemplate !== undefined) { - let count = 0; - if (this.data.datasetFormGroup.get('dmp').value.datasets != null) { - for (let dataset of this.data.datasetFormGroup.get('dmp').value.datasets) { - if (dataset.dmpSectionIndex === dmpSectionIndex && dataset.profile.id === foundTemplate.descriptionTemplateId) { - count++; - } - } - if (count < foundTemplate.maxMultiplicity) { - this.prefillForm.get('profile').patchValue(profile); - } - } - } - else { - this.prefillForm.get('profile').patchValue(profile); - } - } - else { - this.prefillForm.get('profile').patchValue(profile); - } - }); - } + // addProfileIfUsedLessThanMax(profile: DescriptionProfileModel) { + // const dmpSectionIndex = this.data.datasetFormGroup.get('dmpSectionIndex').value; + // const blueprintId = this.data.datasetFormGroup.get('dmp').value.profile.id; + // this.dmpBlueprintService.getSingle(blueprintId, this.getBlueprintDefinitionFields()) + // .pipe(takeUntil(this._destroyed)) + // .subscribe(result => { + // const section = result.definition.sections[dmpSectionIndex]; + // if (section.hasTemplates) { + // const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === Guid.parse(profile.id)); + // if (foundTemplate !== undefined) { + // let count = 0; + // if (this.data.datasetFormGroup.get('dmp').value.datasets != null) { + // for (let dataset of this.data.datasetFormGroup.get('dmp').value.datasets) { + // if (dataset.dmpSectionIndex === dmpSectionIndex && dataset.profile.id === foundTemplate.descriptionTemplateId) { + // count++; + // } + // } + // if (count < foundTemplate.maxMultiplicity) { + // this.prefillForm.get('profile').patchValue(profile); + // } + // } + // } + // else { + // this.prefillForm.get('profile').patchValue(profile); + // } + // } + // else { + // this.prefillForm.get('profile').patchValue(profile); + // } + // }); + // } - checkMinMax(event, profile: DatasetProfileModel) { - event.stopPropagation(); - const dmpSectionIndex = this.data.datasetFormGroup.get('dmpSectionIndex').value; - const blueprintId = this.data.datasetFormGroup.get('dmp').value.profile.id; - this.dmpBlueprintService.getSingle(blueprintId, this.getBlueprintDefinitionFields()) - .pipe(takeUntil(this._destroyed)) - .subscribe(result => { - const section = result.definition.sections[dmpSectionIndex]; - if (section.hasTemplates) { - const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === Guid.parse(profile.id)); - if (foundTemplate !== undefined) { - let count = 0; - if (this.data.datasetFormGroup.get('dmp').value.datasets != null) { - for (let dataset of this.data.datasetFormGroup.get('dmp').value.datasets) { - if (dataset.dmpSectionIndex === dmpSectionIndex && dataset.profile.id === foundTemplate.descriptionTemplateId) { - count++; - } - } - if (count === foundTemplate.maxMultiplicity) { - this.dialog.open(PopupNotificationDialogComponent, { - data: { - title: this.language.instant('DATASET-EDITOR.MAX-DESCRIPTION-DIALOG.TITLE'), - message: this.language.instant('DATASET-EDITOR.MAX-DESCRIPTION-DIALOG.MESSAGE') - }, maxWidth: '30em' - }); - } - else { - this.prefillForm.get('profile').setValue(profile); - } - } - } - else { - this.prefillForm.get('profile').setValue(profile); - } - } - else { - this.prefillForm.get('profile').setValue(profile); - } - }); - } + // checkMinMax(event, profile: DescriptionProfileModel) { + // event.stopPropagation(); + // const dmpSectionIndex = this.data.datasetFormGroup.get('dmpSectionIndex').value; + // const blueprintId = this.data.datasetFormGroup.get('dmp').value.profile.id; + // this.dmpBlueprintService.getSingle(blueprintId, this.getBlueprintDefinitionFields()) + // .pipe(takeUntil(this._destroyed)) + // .subscribe(result => { + // const section = result.definition.sections[dmpSectionIndex]; + // if (section.hasTemplates) { + // const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === Guid.parse(profile.id)); + // if (foundTemplate !== undefined) { + // let count = 0; + // if (this.data.datasetFormGroup.get('dmp').value.datasets != null) { + // for (let dataset of this.data.datasetFormGroup.get('dmp').value.datasets) { + // if (dataset.dmpSectionIndex === dmpSectionIndex && dataset.profile.id === foundTemplate.descriptionTemplateId) { + // count++; + // } + // } + // if (count === foundTemplate.maxMultiplicity) { + // this.dialog.open(PopupNotificationDialogComponent, { + // data: { + // title: this.language.instant('DATASET-EDITOR.MAX-DESCRIPTION-DIALOG.TITLE'), + // message: this.language.instant('DATASET-EDITOR.MAX-DESCRIPTION-DIALOG.MESSAGE') + // }, maxWidth: '30em' + // }); + // } + // else { + // this.prefillForm.get('profile').setValue(profile); + // } + // } + // } + // else { + // this.prefillForm.get('profile').setValue(profile); + // } + // } + // else { + // this.prefillForm.get('profile').setValue(profile); + // } + // }); + // } - private getBlueprintDefinitionFields() { - return [ - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.id)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.label)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.description)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.ordinal)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.hasTemplates)].join('.'), + // private getBlueprintDefinitionFields() { + // return [ + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.id)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.label)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.description)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.ordinal)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.hasTemplates)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.id)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.category)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.dataType)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.systemFieldType)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.label)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.placeholder)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.description)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.required)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.ordinal)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.id)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.category)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.dataType)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.systemFieldType)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.label)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.placeholder)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.description)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.required)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.ordinal)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.id)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.descriptionTemplateId)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.label)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.minMultiplicity)].join('.'), - [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.maxMultiplicity)].join('.'), - ] - } + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.id)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.descriptionTemplateId)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.label)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.minMultiplicity)].join('.'), + // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.maxMultiplicity)].join('.'), + // ] + // } public compareWith(object1: any, object2: any) { return object1 && object2 && object1.id === object2.id; } - searchDatasets(query: string): Observable { - return this.prefillingService.getPrefillingList(query).pipe(map(prefilling => prefilling.sort((a, b) => { - if (a.name > b.name) { - return 1; - } else if (a.name < b.name) { - return -1; - } else { - return 0; - } - }))); - } + // searchDescriptions(query: string): Observable { + // return this.prefillingService.getPrefillingList(query).pipe(map(prefilling => prefilling.sort((a, b) => { + // if (a.name > b.name) { + // return 1; + // } else if (a.name < b.name) { + // return -1; + // } else { + // return 0; + // } + // }))); + // } next() { - if (this.isPrefilled) { - if (this.prefillForm.get('prefill').value.data == null) { - this.prefillingService.getPrefillingDataset(this.prefillForm.get('prefill').value.pid, this.prefillForm.get('profile').value.id, this.prefillForm.get('prefill').value.key).subscribe(wizard => { - wizard.profile = this.prefillForm.get('profile').value; - this.closeDialog(wizard); - }); - } - else { - this.prefillingService.getPrefillingDatasetUsingData(this.prefillForm.get('prefill').value.data, this.prefillForm.get('profile').value.id, this.prefillForm.get('prefill').value.key).subscribe(wizard => { - wizard.profile = this.prefillForm.get('profile').value; - this.closeDialog(wizard); - }); - } - } else { - this.closeDialog(); - } + // if (this.isPrefilled) { + // if (this.prefillForm.get('prefill').value.data == null) { + // this.prefillingService.getPrefillingDescription(this.prefillForm.get('prefill').value.pid, this.prefillForm.get('profile').value.id, this.prefillForm.get('prefill').value.key).subscribe(wizard => { + // wizard.profile = this.prefillForm.get('profile').value; + // this.closeDialog(wizard); + // }); + // } + // else { + // this.prefillingService.getPrefillingDescriptionUsingData(this.prefillForm.get('prefill').value.data, this.prefillForm.get('profile').value.id, this.prefillForm.get('prefill').value.key).subscribe(wizard => { + // wizard.profile = this.prefillForm.get('profile').value; + // this.closeDialog(wizard); + // }); + // } + // } else { + // this.closeDialog(); + // } } closeDialog(result = null): void { diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index ec587ef85..7270c7fb6 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -1061,6 +1061,19 @@ "DISCARD": "Discard" } }, + "PREFILL-DESCRIPTION-DIALOG": { + "TITLE": "Initialize your Dataset", + "OR": "OR", + "HINT": "Select the dataset from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", + "DESCRIPTION-TEMPLATE": "Description Template", + "SEARCH-HEADER": "Prefilled object", + "SEARCH": "Start typing to search for an entity to use for prefilling", + "ACTIONS": { + "NEXT": "Next", + "PREFILL": "Prefill", + "MANUALLY": "Manually" + } + }, "DATASET-PUBLIC-LISTING": { "TITLE": "Published Datasets", "TOOLTIP": { From fd77a44039b2c92bf152ac0aa713a0cd3357f11b Mon Sep 17 00:00:00 2001 From: amentis Date: Wed, 28 Feb 2024 17:37:56 +0200 Subject: [PATCH 9/9] remove ExternalUrlConfigProvider --- .../ExternalUrlConfigProvider.java | 37 ------------------- .../externalfetcher/config/ExternalUrls.java | 31 ---------------- .../prefilling/PrefillingServiceImpl.java | 9 +---- .../service/storage/StorageFileService.java | 2 - .../storage/StorageFileServiceImpl.java | 10 ----- .../prefilling-source-system-target-type.ts | 2 +- 6 files changed, 3 insertions(+), 88 deletions(-) delete mode 100644 dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/ExternalUrlConfigProvider.java delete mode 100644 dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/ExternalUrls.java diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/ExternalUrlConfigProvider.java b/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/ExternalUrlConfigProvider.java deleted file mode 100644 index 993999b7c..000000000 --- a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/ExternalUrlConfigProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -package eu.eudat.service.externalfetcher; - -import eu.eudat.service.externalfetcher.config.ExternalUrls; -import eu.eudat.service.storage.StorageFileService; -import jakarta.xml.bind.JAXBContext; -import jakarta.xml.bind.Unmarshaller; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -import java.io.ByteArrayInputStream; - -@Service -public class ExternalUrlConfigProvider { - private static final Logger logger = LoggerFactory.getLogger(ExternalUrlConfigProvider.class); - - private ExternalUrls externalUrls; - private final StorageFileService storageFileService; - - public ExternalUrlConfigProvider(StorageFileService storageFileService) { - this.storageFileService = storageFileService; - } - - public ExternalUrls getExternalUrls() { - if (externalUrls == null) { - byte[] bytes = this.storageFileService.getExternalUrlsFile(); - try { - JAXBContext jaxbContext = JAXBContext.newInstance(ExternalUrls.class); - Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - externalUrls = (ExternalUrls) jaxbUnmarshaller.unmarshal(new ByteArrayInputStream(bytes)); - } catch (Exception ex) { - logger.error("Cannot find resource", ex); - } - } - return externalUrls; - } -} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/ExternalUrls.java b/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/ExternalUrls.java deleted file mode 100644 index aaa40ca3a..000000000 --- a/dmp-backend/core/src/main/java/eu/eudat/service/externalfetcher/config/ExternalUrls.java +++ /dev/null @@ -1,31 +0,0 @@ -package eu.eudat.service.externalfetcher.config; - - -import eu.eudat.service.externalfetcher.config.prefilling.PrefillingConfigMapAdapter; - -import eu.eudat.service.externalfetcher.config.entities.*; -import jakarta.xml.bind.annotation.XmlElement; -import jakarta.xml.bind.annotation.XmlRootElement; -import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import java.io.Serializable; -import java.util.Map; - -@XmlRootElement -public class ExternalUrls implements Serializable { - - private static final long serialVersionUID = -5076364662014107275L; - - Map prefillings; - - public Map getPrefillings() { - return prefillings; - } - - @XmlJavaTypeAdapter(PrefillingConfigMapAdapter.class) - @XmlElement(name = "prefillings") - public void setPrefillings(Map prefillings) { - this.prefillings = prefillings; - } -} - - diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/prefilling/PrefillingServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/prefilling/PrefillingServiceImpl.java index 6c9276eef..ecb30f663 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/prefilling/PrefillingServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/prefilling/PrefillingServiceImpl.java @@ -18,7 +18,6 @@ import eu.eudat.model.descriptionproperties.PropertyDefinitionFieldSet; import eu.eudat.model.descriptionproperties.PropertyDefinitionFieldSetItem; import eu.eudat.model.persist.DescriptionProfilingRequest; import eu.eudat.model.persist.DescriptionProfilingWithDataRequest; -import eu.eudat.service.externalfetcher.ExternalUrlConfigProvider; import eu.eudat.service.externalfetcher.config.entities.*; import eu.eudat.service.externalfetcher.criteria.ExternalReferenceCriteria; import gr.cite.tools.data.builder.BuilderFactory; @@ -59,7 +58,6 @@ public class PrefillingServiceImpl implements PrefillingService { private final BuilderFactory builderFactory; private final ConventionService conventionService; private final MessageSource messageSource; - private final ExternalUrlConfigProvider externalUrlConfigProvider; private final XmlHandlingService xmlHandlingService; private final ValidatorFactory validatorFactory; @Autowired @@ -68,14 +66,12 @@ public class PrefillingServiceImpl implements PrefillingService { BuilderFactory builderFactory, ConventionService conventionService, MessageSource messageSource, - ExternalUrlConfigProvider externalUrlConfigProvider, XmlHandlingService xmlHandlingService, ValidatorFactory validatorFactory) { this.entityManager = entityManager; this.builderFactory = builderFactory; this.conventionService = conventionService; this.messageSource = messageSource; - this.externalUrlConfigProvider = externalUrlConfigProvider; this.xmlHandlingService = xmlHandlingService; this.validatorFactory = validatorFactory; } @@ -88,7 +84,6 @@ public class PrefillingServiceImpl implements PrefillingService { externalReferenceCriteria.setLike(lookup.getLike()); List prefillings = new ArrayList<>(); List> map; - Map prefillingConfigs = this.externalUrlConfigProvider.getExternalUrls().getPrefillings(); // for (PrefillingConfig prefillingConfig: prefillingConfigs.values()) {//TODO new reference logic // map = remoteFetcherService.getExternalData(prefillingConfig.getPrefillingSearch().getUrls(), externalReferenceCriteria, prefillingConfig.getPrefillingSearch().getFetchMode()); // prefillings.addAll(map.stream().map(submap -> PrefillingEntity.build(submap, this.jsonHandlingService)).toList()); @@ -105,7 +100,7 @@ public class PrefillingServiceImpl implements PrefillingService { @Override public Description getPrefilledDescription(DescriptionProfilingRequest model) throws JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException { - PrefillingConfig prefillingConfig = this.externalUrlConfigProvider.getExternalUrls().getPrefillings().get(model.getConfigId()); + PrefillingConfig prefillingConfig = null; PrefillingGet prefillingGet = prefillingConfig.getPrefillingGet(); Map prefillingEntity = getSinglePrefillingData(prefillingGet.getUrl(), model.getPrefillId()); DescriptionProfilingWithDataRequest descriptionProfilingWithDataRequest = new DescriptionProfilingWithDataRequest(); @@ -129,7 +124,7 @@ public class PrefillingServiceImpl implements PrefillingService { @Override public Description getPrefilledDescriptionUsingData(DescriptionProfilingWithDataRequest model) throws JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException { - PrefillingConfig prefillingConfig = this.externalUrlConfigProvider.getExternalUrls().getPrefillings().get(model.getConfigId()); + PrefillingConfig prefillingConfig = null; PrefillingGet prefillingGet = prefillingConfig.getPrefillingGet(); DescriptionTemplateEntity descriptionTemplateEntity = this.entityManager.find(DescriptionTemplateEntity.class, model.getDescriptionTemplateId()); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/storage/StorageFileService.java b/dmp-backend/core/src/main/java/eu/eudat/service/storage/StorageFileService.java index 35926f360..ad088853e 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/storage/StorageFileService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/storage/StorageFileService.java @@ -33,8 +33,6 @@ public interface StorageFileService extends ApplicationListener