diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html index d315c081d..6f265f232 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html @@ -188,12 +188,18 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - - {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }} + + + {{tag.name}} + cancel + + +
@@ -201,11 +207,9 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - + + {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }}
@@ -214,11 +218,9 @@
- - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - + + {{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }}
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts index ace677192..89743d093 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts @@ -1,6 +1,6 @@ import { Component, Input, OnInit } from '@angular/core'; -import { FormGroup } from '@angular/forms'; +import { FormGroup, FormArray } from '@angular/forms'; import { DatasetProfileComboBoxType } from '@app/core/common/enum/dataset-profile-combo-box-type'; import { DatasetProfileFieldViewStyle } from '@app/core/common/enum/dataset-profile-field-view-style'; import { DatasetProfileInternalDmpEntitiesType } from '@app/core/common/enum/dataset-profile-internal-dmp-entities-type'; @@ -27,6 +27,10 @@ import { DataRepositoryCriteria } from '@app/core/query/data-repository/data-rep import { RegistryCriteria } from '@app/core/query/registry/registry-criteria'; import { ServiceCriteria } from '@app/core/query/service/service-criteria'; import { TagCriteria } from '@app/core/query/tag/tag-criteria'; +import { isNullOrUndefined } from 'util'; +import { ExternalTagEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model'; +import { MatChipInputEvent } from '@angular/material'; +import { ENTER, COMMA } from '@angular/cdk/keycodes'; @Component({ selector: 'app-form-field', @@ -48,6 +52,17 @@ export class FormFieldComponent extends BaseComponent implements OnInit { datasetProfileFieldViewStyleEnum = DatasetProfileFieldViewStyle; datasetProfileComboBoxTypeEnum = DatasetProfileComboBoxType; datasetProfileInternalDmpEntitiesTypeEnum = DatasetProfileInternalDmpEntitiesType; + externalDatasetAutoCompleteConfiguration: SingleAutoCompleteConfiguration; + dataRepositoriesAutoCompleteConfiguration: SingleAutoCompleteConfiguration; + registriesAutoCompleteConfiguration: SingleAutoCompleteConfiguration; + servicesAutoCompleteConfiguration: SingleAutoCompleteConfiguration; + tagsAutoCompleteConfiguration: SingleAutoCompleteConfiguration; + researchersAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; + organisationsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; + + readonly separatorKeysCodes: number[] = [ENTER, COMMA]; + + tags: ExternalTagEditorModel[] = []; constructor( public visibilityRulesService: VisibilityRulesService, @@ -58,46 +73,6 @@ export class FormFieldComponent extends BaseComponent implements OnInit { private dmpService: DmpService ) { super(); } - externalDatasetAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { - filterFn: this.searchDatasetExternalDatasets.bind(this), - initialItems: (type) => this.searchDatasetExternalDatasets('', type),//.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1), - displayFn: (item) => item ? item.name : null, - titleFn: (item) => item ? item.name : null, - subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : item.tag ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.tag : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE') - }; - - registriesAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { - filterFn: this.searchDatasetExternalRegistries.bind(this), - initialItems: (type) => this.searchDatasetExternalRegistries('', type), - displayFn: (item) => item ? item.name : null, - titleFn: (item) => item ? item.name : null, - subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE') - }; - - dataRepositoriesAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { - filterFn: this.searchDatasetExternalDataRepositories.bind(this), - initialItems: (type) => this.searchDatasetExternalDataRepositories('', type), - displayFn: (item) => item ? item.name : null, - titleFn: (item) => item ? item.name : null, - subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE') - }; - - servicesAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { - filterFn: this.searchDatasetExternalServices.bind(this), - initialItems: (type) => this.searchDatasetExternalServices('', type), - displayFn: (item) => item ? item.label : null, - titleFn: (item) => item ? item.label : null, - subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE') - }; - - tagsAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { - filterFn: this.searchDatasetTags.bind(this), - initialItems: (type) => this.searchDatasetTags('', type), - displayFn: (item) => item ? item.name : null, - titleFn: (item) => item ? item.name : null, - subtitleFn: (item) => item.tag ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.tag : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE') - }; - ngOnInit() { if (this.form.get('value').value) { this.visibilityRulesService.updateValueAndVisibility(this.form.get('id').value, this.form.get('value').value); @@ -127,6 +102,72 @@ export class FormFieldComponent extends BaseComponent implements OnInit { } } + switch (this.form.get('viewStyle').value.renderStyle) { + case DatasetProfileFieldViewStyle.ExternalDatasets: + this.externalDatasetAutoCompleteConfiguration = { + filterFn: this.searchDatasetExternalDatasets.bind(this), + initialItems: () => this.searchDatasetExternalDatasets(''),//.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1), + displayFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + titleFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : item.tag ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.tag : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE'), + valueAssign: (item) => typeof (item) == 'string' ? item : JSON.stringify(item) + }; + break; + case DatasetProfileFieldViewStyle.DataRepositories: + this.dataRepositoriesAutoCompleteConfiguration = { + filterFn: this.searchDatasetExternalDataRepositories.bind(this), + initialItems: () => this.searchDatasetExternalDataRepositories(''), + displayFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + titleFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE'), + valueAssign: (item) => typeof (item) == 'string' ? item : JSON.stringify(item) + }; + break; + case DatasetProfileFieldViewStyle.Registries: + this.registriesAutoCompleteConfiguration = { + filterFn: this.searchDatasetExternalRegistries.bind(this), + initialItems: () => this.searchDatasetExternalRegistries(''), + displayFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + titleFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE'), + valueAssign: (item) => typeof (item) == 'string' ? item : JSON.stringify(item) + }; + break; + case DatasetProfileFieldViewStyle.Services: + this.servicesAutoCompleteConfiguration = { + filterFn: this.searchDatasetExternalServices.bind(this), + initialItems: () => this.searchDatasetExternalServices(''), + displayFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + titleFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE'), + valueAssign: (item) => typeof (item) == 'string' ? item : JSON.stringify(item) + }; + break; + case DatasetProfileFieldViewStyle.Tags: + this.setupTags(); + break; + case DatasetProfileFieldViewStyle.Researchers: + this.researchersAutoCompleteConfiguration = { + filterFn: this.filterResearchers.bind(this), + initialItems: (excludedItems: any[]) => this.filterResearchers('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + titleFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + subtitleFn: (item) => item['tag'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['tag'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE')), + valueAssign: (item) => typeof (item) == 'string' ? item : JSON.stringify(item) + }; + break; + case DatasetProfileFieldViewStyle.Organizations: + this.organisationsAutoCompleteConfiguration = { + filterFn: this.filterOrganisations.bind(this), + initialItems: (excludedItems: any[]) => this.filterOrganisations('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + titleFn: (item) => typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name, + subtitleFn: (item) => item['tag'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['tag'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE')), + valueAssign: (item) => typeof (item) == 'string' ? item : JSON.stringify(item) + }; + break; + } + if (this.form.get('viewStyle').value.renderStyle === DatasetProfileFieldViewStyle.InternalDmpEntities) { if (this.form.get('data').value.type === DatasetProfileInternalDmpEntitiesType.Researchers) { this.makeAutocompleteConfiguration(this.searchResearchers.bind(this), "name", "tag"); @@ -214,43 +255,75 @@ export class FormFieldComponent extends BaseComponent implements OnInit { } } - searchDatasetExternalDatasets(query: string, type: string): Observable { + searchDatasetExternalDatasets(query: string): Observable { const requestItem: RequestItem = new RequestItem(); requestItem.criteria = new ExternalDatasetCriteria(); requestItem.criteria.like = query; - requestItem.criteria.type = type; + requestItem.criteria.type = ''; return this.externalSourcesService.searchDatasetSExternalDatasetservice(requestItem); } - searchDatasetExternalDataRepositories(query: string, type: string): Observable { + searchDatasetExternalDataRepositories(query: string): Observable { const requestItem: RequestItem = new RequestItem(); requestItem.criteria = new DataRepositoryCriteria(); requestItem.criteria.like = query; - requestItem.criteria.type = type; + requestItem.criteria.type = ''; return this.externalSourcesService.searchDatasetRepository(requestItem); } - searchDatasetExternalRegistries(query: string, type: string): Observable { + searchDatasetExternalRegistries(query: string): Observable { const requestItem: RequestItem = new RequestItem(); requestItem.criteria = new RegistryCriteria(); requestItem.criteria.like = query; - requestItem.criteria.type = type; + requestItem.criteria.type = ''; return this.externalSourcesService.searchDatasetRegistry(requestItem); } - searchDatasetExternalServices(query: string, type: string): Observable { + searchDatasetExternalServices(query: string): Observable { const requestItem: RequestItem = new RequestItem(); requestItem.criteria = new ServiceCriteria(); requestItem.criteria.like = query; - requestItem.criteria.type = type; + requestItem.criteria.type = ''; return this.externalSourcesService.searchDatasetService(requestItem); } - searchDatasetTags(query: string, type: string): Observable { + searchDatasetTags(query: string): Observable { const requestItem: RequestItem = new RequestItem(); requestItem.criteria = new TagCriteria(); requestItem.criteria.like = query; - requestItem.criteria.type = type; + requestItem.criteria.type = ''; return this.externalSourcesService.searchDatasetTags(requestItem); } + + private setupTags() { + this.tags = (this.form.get('value').value as string[]).map(string => JSON.parse(string)); + if (this.tags === null) { + this.tags = []; + } + } + + getTags() { + return this.tags; + } + + removeTag(tag: any) { + this.tags.splice(this.tags.indexOf(tag), 1); + this.form.patchValue({ 'value': JSON.stringify(this.tags) }); + } + + addTag(ev: MatChipInputEvent) { + if (ev.value !== '' && isNullOrUndefined((this.tags.find(tag => tag.name === ev.value)))) { + this.tags.push(new ExternalTagEditorModel('', ev.value)); + } + this.form.patchValue({ 'value': JSON.stringify(this.tags) }); + ev.input.value = ''; + } + + filterOrganisations(value: string): Observable { + return this.externalSourcesService.searchDMPOrganizations(value); + } + + filterResearchers(value: string): Observable { + return this.externalSourcesService.searchDMPResearchers({ criteria: { name: value, like: null } }); + } } diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description-form.module.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description-form.module.ts index 21a4eba2e..97f52ca21 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description-form.module.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description-form.module.ts @@ -10,12 +10,14 @@ import { VisibilityRulesService } from '@app/ui/misc/dataset-description-form/vi import { CommonFormsModule } from '@common/forms/common-forms.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; import { FormCompositeTitleComponent } from './components/form-composite-title/form-composite-title.component'; +import { ExternalSourcesModule } from '../external-sources/external-sources.module'; @NgModule({ imports: [ CommonUiModule, CommonFormsModule, - AutoCompleteModule + AutoCompleteModule, + ExternalSourcesModule ], declarations: [ DatasetDescriptionFormComponent,