[CST-3088] Replace use of AuthorityService with new VocabularyService

This commit is contained in:
Giuseppe Digilio
2020-06-25 15:21:44 +02:00
parent 3117916d5b
commit 63cca76b49
59 changed files with 740 additions and 706 deletions

View File

@@ -86,9 +86,6 @@ import { EPersonDataService } from './eperson/eperson-data.service';
import { EpersonResponseParsingService } from './eperson/eperson-response-parsing.service'; import { EpersonResponseParsingService } from './eperson/eperson-response-parsing.service';
import { EPerson } from './eperson/models/eperson.model'; import { EPerson } from './eperson/models/eperson.model';
import { Group } from './eperson/models/group.model'; import { Group } from './eperson/models/group.model';
import { AuthorityService } from './integration/authority.service';
import { IntegrationResponseParsingService } from './integration/integration-response-parsing.service';
import { AuthorityValue } from './integration/models/authority.value';
import { JsonPatchOperationsBuilder } from './json-patch/builder/json-patch-operations-builder'; import { JsonPatchOperationsBuilder } from './json-patch/builder/json-patch-operations-builder';
import { MetadataField } from './metadata/metadata-field.model'; import { MetadataField } from './metadata/metadata-field.model';
import { MetadataSchema } from './metadata/metadata-schema.model'; import { MetadataSchema } from './metadata/metadata-schema.model';
@@ -148,6 +145,8 @@ import { WorkflowAction } from './tasks/models/workflow-action-object.model';
import { VocabularyEntry } from './submission/vocabularies/models/vocabulary-entry.model'; import { VocabularyEntry } from './submission/vocabularies/models/vocabulary-entry.model';
import { Vocabulary } from './submission/vocabularies/models/vocabulary.model'; import { Vocabulary } from './submission/vocabularies/models/vocabulary.model';
import { VocabularyEntriesResponseParsingService } from './submission/vocabularies/vocabulary-entries-response-parsing.service'; import { VocabularyEntriesResponseParsingService } from './submission/vocabularies/vocabulary-entries-response-parsing.service';
import { VocabularyEntryDetail } from './submission/vocabularies/models/vocabulary-entry-detail.model';
import { VocabularyService } from './submission/vocabularies/vocabulary.service';
/** /**
* When not in production, endpoint responses can be mocked for testing purposes * When not in production, endpoint responses can be mocked for testing purposes
@@ -224,8 +223,6 @@ const PROVIDERS = [
SubmissionResponseParsingService, SubmissionResponseParsingService,
SubmissionJsonPatchOperationsService, SubmissionJsonPatchOperationsService,
JsonPatchOperationsBuilder, JsonPatchOperationsBuilder,
AuthorityService,
IntegrationResponseParsingService,
MetadataschemaParsingService, MetadataschemaParsingService,
MetadatafieldParsingService, MetadatafieldParsingService,
UploaderService, UploaderService,
@@ -276,6 +273,7 @@ const PROVIDERS = [
NotificationsService, NotificationsService,
FilteredDiscoveryPageResponseParsingService, FilteredDiscoveryPageResponseParsingService,
{ provide: NativeWindowService, useFactory: NativeWindowFactory }, { provide: NativeWindowService, useFactory: NativeWindowFactory },
VocabularyService,
VocabularyEntriesResponseParsingService VocabularyEntriesResponseParsingService
]; ];
@@ -305,7 +303,6 @@ export const models =
SubmissionSectionModel, SubmissionSectionModel,
SubmissionUploadsModel, SubmissionUploadsModel,
AuthStatus, AuthStatus,
AuthorityValue,
BrowseEntry, BrowseEntry,
BrowseDefinition, BrowseDefinition,
ClaimedTask, ClaimedTask,
@@ -320,7 +317,8 @@ export const models =
VersionHistory, VersionHistory,
WorkflowAction, WorkflowAction,
Vocabulary, Vocabulary,
VocabularyEntry VocabularyEntry,
VocabularyEntryDetail
]; ];
@NgModule({ @NgModule({

View File

@@ -9,7 +9,7 @@ import { JsonPatchOperationPathObject } from './json-patch-operation-path-combin
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { isEmpty, isNotEmpty } from '../../../shared/empty.util'; import { isEmpty, isNotEmpty } from '../../../shared/empty.util';
import { dateToISOFormat } from '../../../shared/date.util'; import { dateToISOFormat } from '../../../shared/date.util';
import { AuthorityValue } from '../../integration/models/authority.value'; import { VocabularyEntry } from '../../submission/vocabularies/models/vocabulary-entry.model';
import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model';
import { FormFieldLanguageValueObject } from '../../../shared/form/builder/models/form-field-language-value.model'; import { FormFieldLanguageValueObject } from '../../../shared/form/builder/models/form-field-language-value.model';
@@ -106,7 +106,7 @@ export class JsonPatchOperationsBuilder {
operationValue = value; operationValue = value;
} else if (value instanceof Date) { } else if (value instanceof Date) {
operationValue = new FormFieldMetadataValueObject(dateToISOFormat(value)); operationValue = new FormFieldMetadataValueObject(dateToISOFormat(value));
} else if (value instanceof AuthorityValue) { } else if (value instanceof VocabularyEntry) {
operationValue = this.prepareAuthorityValue(value); operationValue = this.prepareAuthorityValue(value);
} else if (value instanceof FormFieldLanguageValueObject) { } else if (value instanceof FormFieldLanguageValueObject) {
operationValue = new FormFieldMetadataValueObject(value.value, value.language); operationValue = new FormFieldMetadataValueObject(value.value, value.language);
@@ -127,8 +127,8 @@ export class JsonPatchOperationsBuilder {
protected prepareAuthorityValue(value: any) { protected prepareAuthorityValue(value: any) {
let operationValue: any = null; let operationValue: any = null;
if (isNotEmpty(value.id)) { if (isNotEmpty(value.authority)) {
operationValue = new FormFieldMetadataValueObject(value.value, value.language, value.id); operationValue = new FormFieldMetadataValueObject(value.value, value.language, value.authority);
} else { } else {
operationValue = new FormFieldMetadataValueObject(value.value, value.language); operationValue = new FormFieldMetadataValueObject(value.value, value.language);
} }

View File

@@ -74,9 +74,7 @@ class VocabularyEntryDetailDataServiceImpl extends DataService<VocabularyEntryDe
/** /**
* A service responsible for fetching/sending data from/to the REST API on the vocabularies endpoint * A service responsible for fetching/sending data from/to the REST API on the vocabularies endpoint
*/ */
@Injectable({ @Injectable()
providedIn: 'root'
})
@dataService(VOCABULARY) @dataService(VOCABULARY)
export class VocabularyService { export class VocabularyService {
protected searchByMetadataAndCollectionMethod = 'byMetadataAndCollection'; protected searchByMetadataAndCollectionMethod = 'byMetadataAndCollection';

View File

@@ -13,12 +13,13 @@ import {
import { findIndex } from 'lodash'; import { findIndex } from 'lodash';
import { AuthorityValue } from '../../core/integration/models/authority.value'; import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model';
import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-metadata-value.model';
import { ConfidenceType } from '../../core/integration/models/confidence-type'; import { ConfidenceType } from '../../core/shared/confidence-type';
import { isNotEmpty, isNull } from '../empty.util'; import { isNotEmpty, isNull } from '../empty.util';
import { ConfidenceIconConfig } from '../../../config/submission-config.interface'; import { ConfidenceIconConfig } from '../../../config/submission-config.interface';
import { environment } from '../../../environments/environment'; import { environment } from '../../../environments/environment';
import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
/** /**
* Directive to add to the element a bootstrap utility class based on metadata confidence value * Directive to add to the element a bootstrap utility class based on metadata confidence value
@@ -31,7 +32,7 @@ export class AuthorityConfidenceStateDirective implements OnChanges, AfterViewIn
/** /**
* The metadata value * The metadata value
*/ */
@Input() authorityValue: AuthorityValue | FormFieldMetadataValueObject | string; @Input() authorityValue: VocabularyEntry | FormFieldMetadataValueObject | string;
/** /**
* A boolean representing if to show html icon if authority value is empty * A boolean representing if to show html icon if authority value is empty
@@ -65,7 +66,6 @@ export class AuthorityConfidenceStateDirective implements OnChanges, AfterViewIn
/** /**
* Initialize instance variables * Initialize instance variables
* *
* @param {GlobalConfig} EnvConfig
* @param {ElementRef} elem * @param {ElementRef} elem
* @param {Renderer2} renderer * @param {Renderer2} renderer
*/ */
@@ -114,7 +114,8 @@ export class AuthorityConfidenceStateDirective implements OnChanges, AfterViewIn
private getConfidenceByValue(value: any): ConfidenceType { private getConfidenceByValue(value: any): ConfidenceType {
let confidence: ConfidenceType = ConfidenceType.CF_UNSET; let confidence: ConfidenceType = ConfidenceType.CF_UNSET;
if (isNotEmpty(value) && value instanceof AuthorityValue && value.hasAuthority()) { if (isNotEmpty(value) && (value instanceof VocabularyEntry || value instanceof VocabularyEntryDetail)
&& value.hasAuthority()) {
confidence = ConfidenceType.CF_ACCEPTED; confidence = ConfidenceType.CF_ACCEPTED;
} }

View File

@@ -11,7 +11,7 @@ import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-
import { createTestComponent } from '../testing/utils.test'; import { createTestComponent } from '../testing/utils.test';
import { AuthorityConfidenceStateDirective } from '../authority-confidence/authority-confidence-state.directive'; import { AuthorityConfidenceStateDirective } from '../authority-confidence/authority-confidence-state.directive';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { ConfidenceType } from '../../core/integration/models/confidence-type'; import { ConfidenceType } from '../../core/shared/confidence-type';
import { SortablejsModule } from 'ngx-sortablejs'; import { SortablejsModule } from 'ngx-sortablejs';
import { environment } from '../../../environments/environment'; import { environment } from '../../../environments/environment';

View File

@@ -1,7 +1,7 @@
import { isObject, uniqueId } from 'lodash'; import { isObject, uniqueId } from 'lodash';
import { hasValue, isNotEmpty } from '../../empty.util'; import { hasValue, isNotEmpty } from '../../empty.util';
import { FormFieldMetadataValueObject } from '../../form/builder/models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../form/builder/models/form-field-metadata-value.model';
import { ConfidenceType } from '../../../core/integration/models/confidence-type'; import { ConfidenceType } from '../../../core/shared/confidence-type';
import { PLACEHOLDER_PARENT_METADATA } from '../../form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model'; import { PLACEHOLDER_PARENT_METADATA } from '../../form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
export interface ChipsItemIcon { export interface ChipsItemIcon {

View File

@@ -5,7 +5,7 @@ import { hasValue, isNotEmpty } from '../../empty.util';
import { PLACEHOLDER_PARENT_METADATA } from '../../form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model'; import { PLACEHOLDER_PARENT_METADATA } from '../../form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
import { MetadataIconConfig } from '../../../../config/submission-config.interface'; import { MetadataIconConfig } from '../../../../config/submission-config.interface';
import { FormFieldMetadataValueObject } from '../../form/builder/models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../form/builder/models/form-field-metadata-value.model';
import { AuthorityValue } from '../../../core/integration/models/authority.value'; import { VocabularyEntry } from '../../../core/submission/vocabularies/models/vocabulary-entry.model';
export class Chips { export class Chips {
chipsItems: BehaviorSubject<ChipsItem[]>; chipsItems: BehaviorSubject<ChipsItem[]>;
@@ -102,7 +102,7 @@ export class Chips {
private getChipsIcons(item) { private getChipsIcons(item) {
const icons = []; const icons = [];
if (typeof item === 'string' || item instanceof FormFieldMetadataValueObject || item instanceof AuthorityValue) { if (typeof item === 'string' || item instanceof FormFieldMetadataValueObject || item instanceof VocabularyEntry) {
return icons; return icons;
} }

View File

@@ -44,7 +44,7 @@ import { SharedModule } from '../../../shared.module';
import { DynamicDsDatePickerModel } from './models/date-picker/date-picker.model'; import { DynamicDsDatePickerModel } from './models/date-picker/date-picker.model';
import { DynamicRelationGroupModel } from './models/relation-group/dynamic-relation-group.model'; import { DynamicRelationGroupModel } from './models/relation-group/dynamic-relation-group.model';
import { DynamicListCheckboxGroupModel } from './models/list/dynamic-list-checkbox-group.model'; import { DynamicListCheckboxGroupModel } from './models/list/dynamic-list-checkbox-group.model';
import { AuthorityOptions } from '../../../../core/integration/models/authority-options.model'; import { VocabularyOptions } from '../../../../core/submission/vocabularies/models/vocabulary-options.model';
import { DynamicListRadioGroupModel } from './models/list/dynamic-list-radio-group.model'; import { DynamicListRadioGroupModel } from './models/list/dynamic-list-radio-group.model';
import { DynamicLookupModel } from './models/lookup/dynamic-lookup.model'; import { DynamicLookupModel } from './models/lookup/dynamic-lookup.model';
import { DynamicScrollableDropdownModel } from './models/scrollable-dropdown/dynamic-scrollable-dropdown.model'; import { DynamicScrollableDropdownModel } from './models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
@@ -74,7 +74,7 @@ import { createSuccessfulRemoteDataObject } from '../../../remote-data.utils';
describe('DsDynamicFormControlContainerComponent test suite', () => { describe('DsDynamicFormControlContainerComponent test suite', () => {
const authorityOptions: AuthorityOptions = { const vocabularyOptions: VocabularyOptions = {
closed: false, closed: false,
metadata: 'list', metadata: 'list',
name: 'type_programme', name: 'type_programme',
@@ -104,7 +104,7 @@ describe('DsDynamicFormControlContainerComponent test suite', () => {
new DynamicTypeaheadModel({ id: 'typeahead', metadataFields: [], repeatable: false, submissionId: '1234' }), new DynamicTypeaheadModel({ id: 'typeahead', metadataFields: [], repeatable: false, submissionId: '1234' }),
new DynamicScrollableDropdownModel({ new DynamicScrollableDropdownModel({
id: 'scrollableDropdown', id: 'scrollableDropdown',
authorityOptions: authorityOptions, vocabularyOptions: vocabularyOptions,
metadataFields: [], metadataFields: [],
repeatable: false, repeatable: false,
submissionId: '1234' submissionId: '1234'
@@ -112,12 +112,12 @@ describe('DsDynamicFormControlContainerComponent test suite', () => {
new DynamicTagModel({ id: 'tag', metadataFields: [], repeatable: false, submissionId: '1234' }), new DynamicTagModel({ id: 'tag', metadataFields: [], repeatable: false, submissionId: '1234' }),
new DynamicListCheckboxGroupModel({ new DynamicListCheckboxGroupModel({
id: 'checkboxList', id: 'checkboxList',
authorityOptions: authorityOptions, vocabularyOptions: vocabularyOptions,
repeatable: true repeatable: true
}), }),
new DynamicListRadioGroupModel({ new DynamicListRadioGroupModel({
id: 'radioList', id: 'radioList',
authorityOptions: authorityOptions, vocabularyOptions: vocabularyOptions,
repeatable: false repeatable: false
}), }),
new DynamicRelationGroupModel({ new DynamicRelationGroupModel({

View File

@@ -8,10 +8,6 @@ import { DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dyna
import { DsDatePickerComponent } from './date-picker.component'; import { DsDatePickerComponent } from './date-picker.component';
import { DynamicDsDatePickerModel } from './date-picker.model'; import { DynamicDsDatePickerModel } from './date-picker.model';
import { FormBuilderService } from '../../../form-builder.service';
import { FormComponent } from '../../../../form.component';
import { FormService } from '../../../../form.service';
import { createTestComponent } from '../../../../../testing/utils.test'; import { createTestComponent } from '../../../../../testing/utils.test';
export const DATE_TEST_GROUP = new FormGroup({ export const DATE_TEST_GROUP = new FormGroup({
@@ -20,7 +16,7 @@ export const DATE_TEST_GROUP = new FormGroup({
export const DATE_TEST_MODEL_CONFIG = { export const DATE_TEST_MODEL_CONFIG = {
disabled: false, disabled: false,
errorMessages: {required: 'You must enter at least the year.'}, errorMessages: { required: 'You must enter at least the year.' },
id: 'date', id: 'date',
label: 'Date', label: 'Date',
name: 'date', name: 'date',
@@ -52,8 +48,8 @@ describe('DsDatePickerComponent test suite', () => {
providers: [ providers: [
ChangeDetectorRef, ChangeDetectorRef,
DsDatePickerComponent, DsDatePickerComponent,
{provide: DynamicFormLayoutService, useValue: {}}, { provide: DynamicFormLayoutService, useValue: {} },
{provide: DynamicFormValidationService, useValue: {}} { provide: DynamicFormValidationService, useValue: {} }
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]
}); });

View File

@@ -20,10 +20,6 @@ export class DsDatePickerComponent extends DynamicFormControlComponent implement
@Input() bindId = true; @Input() bindId = true;
@Input() group: FormGroup; @Input() group: FormGroup;
@Input() model: DynamicDsDatePickerModel; @Input() model: DynamicDsDatePickerModel;
// @Input()
// minDate;
// @Input()
// maxDate;
@Output() selected = new EventEmitter<number>(); @Output() selected = new EventEmitter<number>();
@Output() remove = new EventEmitter<number>(); @Output() remove = new EventEmitter<number>();
@@ -65,7 +61,7 @@ export class DsDatePickerComponent extends DynamicFormControlComponent implement
this.initialMonth = now.getMonth() + 1; this.initialMonth = now.getMonth() + 1;
this.initialDay = now.getDate(); this.initialDay = now.getDate();
if (this.model.value && this.model.value !== null) { if (this.model && this.model.value !== null) {
const values = this.model.value.toString().split(DS_DATE_PICKER_SEPARATOR); const values = this.model.value.toString().split(DS_DATE_PICKER_SEPARATOR);
if (values.length > 0) { if (values.length > 0) {
this.initialYear = parseInt(values[0], 10); this.initialYear = parseInt(values[0], 10);

View File

@@ -2,13 +2,13 @@ import { DynamicFormControlLayout, DynamicInputModel, DynamicInputModelConfig, s
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { LanguageCode } from '../../models/form-field-language-value.model'; import { LanguageCode } from '../../models/form-field-language-value.model';
import { AuthorityOptions } from '../../../../../core/integration/models/authority-options.model'; import { VocabularyOptions } from '../../../../../core/submission/vocabularies/models/vocabulary-options.model';
import { hasValue } from '../../../../empty.util'; import { hasValue } from '../../../../empty.util';
import { FormFieldMetadataValueObject } from '../../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../models/form-field-metadata-value.model';
import { RelationshipOptions } from '../../models/relationship-options.model'; import { RelationshipOptions } from '../../models/relationship-options.model';
export interface DsDynamicInputModelConfig extends DynamicInputModelConfig { export interface DsDynamicInputModelConfig extends DynamicInputModelConfig {
authorityOptions?: AuthorityOptions; vocabularyOptions?: VocabularyOptions;
languageCodes?: LanguageCode[]; languageCodes?: LanguageCode[];
language?: string; language?: string;
value?: any; value?: any;
@@ -20,7 +20,7 @@ export interface DsDynamicInputModelConfig extends DynamicInputModelConfig {
export class DsDynamicInputModel extends DynamicInputModel { export class DsDynamicInputModel extends DynamicInputModel {
@serializable() authorityOptions: AuthorityOptions; @serializable() vocabularyOptions: VocabularyOptions;
@serializable() private _languageCodes: LanguageCode[]; @serializable() private _languageCodes: LanguageCode[];
@serializable() private _language: string; @serializable() private _language: string;
@serializable() languageUpdates: Subject<string>; @serializable() languageUpdates: Subject<string>;
@@ -58,11 +58,11 @@ export class DsDynamicInputModel extends DynamicInputModel {
this.language = lang; this.language = lang;
}); });
this.authorityOptions = config.authorityOptions; this.vocabularyOptions = config.vocabularyOptions;
} }
get hasAuthority(): boolean { get hasAuthority(): boolean {
return this.authorityOptions && hasValue(this.authorityOptions.name); return this.vocabularyOptions && hasValue(this.vocabularyOptions.name);
} }
get hasLanguages(): boolean { get hasLanguages(): boolean {
@@ -83,7 +83,7 @@ export class DsDynamicInputModel extends DynamicInputModel {
set languageCodes(languageCodes: LanguageCode[]) { set languageCodes(languageCodes: LanguageCode[]) {
this._languageCodes = languageCodes; this._languageCodes = languageCodes;
if (!this.language || this.language === null || this.language === '') { if (!this.language || this.language === '') {
this.language = this.languageCodes ? this.languageCodes[0].code : null; this.language = this.languageCodes ? this.languageCodes[0].code : null;
} }
} }

View File

@@ -1,16 +1,17 @@
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { import {
DynamicCheckboxGroupModel, DynamicFormControlLayout, DynamicCheckboxGroupModel,
DynamicFormControlLayout,
DynamicFormGroupModelConfig, DynamicFormGroupModelConfig,
serializable serializable
} from '@ng-dynamic-forms/core'; } from '@ng-dynamic-forms/core';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value';
import { AuthorityOptions } from '../../../../../../core/integration/models/authority-options.model'; import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model';
import { VocabularyOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-options.model';
import { hasValue } from '../../../../../empty.util'; import { hasValue } from '../../../../../empty.util';
export interface DynamicListCheckboxGroupModelConfig extends DynamicFormGroupModelConfig { export interface DynamicListCheckboxGroupModelConfig extends DynamicFormGroupModelConfig {
authorityOptions: AuthorityOptions; vocabularyOptions: VocabularyOptions;
groupLength?: number; groupLength?: number;
repeatable: boolean; repeatable: boolean;
value?: any; value?: any;
@@ -18,43 +19,44 @@ export interface DynamicListCheckboxGroupModelConfig extends DynamicFormGroupMod
export class DynamicListCheckboxGroupModel extends DynamicCheckboxGroupModel { export class DynamicListCheckboxGroupModel extends DynamicCheckboxGroupModel {
@serializable() authorityOptions: AuthorityOptions; @serializable() vocabularyOptions: VocabularyOptions;
@serializable() repeatable: boolean; @serializable() repeatable: boolean;
@serializable() groupLength: number; @serializable() groupLength: number;
@serializable() _value: AuthorityValue[];
isListGroup = true; isListGroup = true;
valueUpdates: Subject<any>; valueUpdates: Subject<any>;
constructor(config: DynamicListCheckboxGroupModelConfig, layout?: DynamicFormControlLayout) { constructor(config: DynamicListCheckboxGroupModelConfig, layout?: DynamicFormControlLayout) {
super(config, layout); super(config, layout);
this.authorityOptions = config.authorityOptions; this.vocabularyOptions = config.vocabularyOptions;
this.groupLength = config.groupLength || 5; this.groupLength = config.groupLength || 5;
this._value = []; this._value = [];
this.repeatable = config.repeatable; this.repeatable = config.repeatable;
this.valueUpdates = new Subject<any>(); this.valueUpdates = new Subject<any>();
this.valueUpdates.subscribe((value: AuthorityValue | AuthorityValue[]) => this.value = value); this.valueUpdates.subscribe((value: VocabularyEntry | VocabularyEntry[]) => this.value = value);
this.valueUpdates.next(config.value); this.valueUpdates.next(config.value);
} }
get hasAuthority(): boolean { @serializable() _value: VocabularyEntry[];
return this.authorityOptions && hasValue(this.authorityOptions.name);
}
get value() { get value() {
return this._value; return this._value;
} }
set value(value: AuthorityValue | AuthorityValue[]) { set value(value: VocabularyEntry | VocabularyEntry[]) {
if (value) { if (value) {
if (Array.isArray(value)) { if (Array.isArray(value)) {
this._value = value; this._value = value;
} else { } else {
// _value is non extendible so assign it a new array // _value is non extendible so assign it a new array
const newValue = (this.value as AuthorityValue[]).concat([value]); const newValue = (this.value as VocabularyEntry[]).concat([value]);
this._value = newValue this._value = newValue
} }
} }
} }
get hasAuthority(): boolean {
return this.vocabularyOptions && hasValue(this.vocabularyOptions.name);
}
} }

View File

@@ -4,11 +4,11 @@ import {
DynamicRadioGroupModelConfig, DynamicRadioGroupModelConfig,
serializable serializable
} from '@ng-dynamic-forms/core'; } from '@ng-dynamic-forms/core';
import { AuthorityOptions } from '../../../../../../core/integration/models/authority-options.model'; import { VocabularyOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-options.model';
import { hasValue } from '../../../../../empty.util'; import { hasValue } from '../../../../../empty.util';
export interface DynamicListModelConfig extends DynamicRadioGroupModelConfig<any> { export interface DynamicListModelConfig extends DynamicRadioGroupModelConfig<any> {
authorityOptions: AuthorityOptions; vocabularyOptions: VocabularyOptions;
groupLength?: number; groupLength?: number;
repeatable: boolean; repeatable: boolean;
value?: any; value?: any;
@@ -16,7 +16,7 @@ export interface DynamicListModelConfig extends DynamicRadioGroupModelConfig<any
export class DynamicListRadioGroupModel extends DynamicRadioGroupModel<any> { export class DynamicListRadioGroupModel extends DynamicRadioGroupModel<any> {
@serializable() authorityOptions: AuthorityOptions; @serializable() vocabularyOptions: VocabularyOptions;
@serializable() repeatable: boolean; @serializable() repeatable: boolean;
@serializable() groupLength: number; @serializable() groupLength: number;
isListGroup = true; isListGroup = true;
@@ -24,13 +24,13 @@ export class DynamicListRadioGroupModel extends DynamicRadioGroupModel<any> {
constructor(config: DynamicListModelConfig, layout?: DynamicFormControlLayout) { constructor(config: DynamicListModelConfig, layout?: DynamicFormControlLayout) {
super(config, layout); super(config, layout);
this.authorityOptions = config.authorityOptions; this.vocabularyOptions = config.vocabularyOptions;
this.groupLength = config.groupLength || 5; this.groupLength = config.groupLength || 5;
this.repeatable = config.repeatable; this.repeatable = config.repeatable;
this.valueUpdates.next(config.value); this.valueUpdates.next(config.value);
} }
get hasAuthority(): boolean { get hasAuthority(): boolean {
return this.authorityOptions && hasValue(this.authorityOptions.name); return this.vocabularyOptions && hasValue(this.vocabularyOptions.name);
} }
} }

View File

@@ -2,25 +2,25 @@
import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { async, ComponentFixture, inject, TestBed, } from '@angular/core/testing'; import { async, ComponentFixture, inject, TestBed, } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap';
import { DsDynamicListComponent } from './dynamic-list.component';
import { DynamicListCheckboxGroupModel } from './dynamic-list-checkbox-group.model';
import { AuthorityOptions } from '../../../../../../core/integration/models/authority-options.model';
import { FormBuilderService } from '../../../form-builder.service';
import { import {
DynamicFormControlLayout, DynamicFormControlLayout,
DynamicFormLayoutService, DynamicFormLayoutService,
DynamicFormsCoreModule, DynamicFormsCoreModule,
DynamicFormValidationService DynamicFormValidationService
} from '@ng-dynamic-forms/core'; } from '@ng-dynamic-forms/core';
import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { DsDynamicListComponent } from './dynamic-list.component';
import { AuthorityServiceStub } from '../../../../../testing/authority-service.stub'; import { DynamicListCheckboxGroupModel } from './dynamic-list-checkbox-group.model';
import { VocabularyOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-options.model';
import { FormBuilderService } from '../../../form-builder.service';
import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
import { VocabularyServiceStub } from '../../../../../testing/vocabulary-service.stub';
import { DynamicListRadioGroupModel } from './dynamic-list-radio-group.model'; import { DynamicListRadioGroupModel } from './dynamic-list-radio-group.model';
import { By } from '@angular/platform-browser'; import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value';
import { createTestComponent } from '../../../../../testing/utils.test'; import { createTestComponent } from '../../../../../testing/utils.test';
export const LAYOUT_TEST = { export const LAYOUT_TEST = {
@@ -35,12 +35,12 @@ export const LIST_TEST_GROUP = new FormGroup({
}); });
export const LIST_CHECKBOX_TEST_MODEL_CONFIG = { export const LIST_CHECKBOX_TEST_MODEL_CONFIG = {
authorityOptions: { vocabularyOptions: {
closed: false, closed: false,
metadata: 'listCheckbox', metadata: 'listCheckbox',
name: 'type_programme', name: 'type_programme',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions, } as VocabularyOptions,
disabled: false, disabled: false,
id: 'listCheckbox', id: 'listCheckbox',
label: 'Programme', label: 'Programme',
@@ -52,12 +52,12 @@ export const LIST_CHECKBOX_TEST_MODEL_CONFIG = {
}; };
export const LIST_RADIO_TEST_MODEL_CONFIG = { export const LIST_RADIO_TEST_MODEL_CONFIG = {
authorityOptions: { vocabularyOptions: {
closed: false, closed: false,
metadata: 'listRadio', metadata: 'listRadio',
name: 'type_programme', name: 'type_programme',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions, } as VocabularyOptions,
disabled: false, disabled: false,
id: 'listRadio', id: 'listRadio',
label: 'Programme', label: 'Programme',
@@ -77,7 +77,7 @@ describe('DsDynamicListComponent test suite', () => {
let html; let html;
let modelValue; let modelValue;
const authorityServiceStub = new AuthorityServiceStub(); const vocabularyServiceStub = new VocabularyServiceStub();
// async beforeEach // async beforeEach
beforeEach(async(() => { beforeEach(async(() => {
@@ -99,9 +99,9 @@ describe('DsDynamicListComponent test suite', () => {
DsDynamicListComponent, DsDynamicListComponent,
DynamicFormValidationService, DynamicFormValidationService,
FormBuilderService, FormBuilderService,
{provide: AuthorityService, useValue: authorityServiceStub}, { provide: VocabularyService, useValue: vocabularyServiceStub },
{provide: DynamicFormLayoutService, useValue: {}}, { provide: DynamicFormLayoutService, useValue: {} },
{provide: DynamicFormValidationService, useValue: {}} { provide: DynamicFormValidationService, useValue: {} }
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]
}); });
@@ -147,20 +147,16 @@ describe('DsDynamicListComponent test suite', () => {
}); });
it('should init component properly', () => { it('should init component properly', () => {
const results$ = authorityServiceStub.getEntriesByName({} as any); expect((listComp as any).optionsList).toEqual(vocabularyServiceStub.getList());
expect(listComp.items.length).toBe(1);
results$.subscribe((results) => { expect(listComp.items[0].length).toBe(2);
expect((listComp as any).optionsList).toEqual(results.payload);
expect(listComp.items.length).toBe(1);
expect(listComp.items[0].length).toBe(2);
})
}); });
it('should set model value properly when a checkbox option is selected', () => { it('should set model value properly when a checkbox option is selected', () => {
const de = listFixture.debugElement.queryAll(By.css('div.custom-checkbox')); const de = listFixture.debugElement.queryAll(By.css('div.custom-checkbox'));
const items = de[0].queryAll(By.css('input.custom-control-input')); const items = de[0].queryAll(By.css('input.custom-control-input'));
const item = items[0]; const item = items[0];
modelValue = [Object.assign(new AuthorityValue(), {id: 1, display: 'one', value: 1})]; modelValue = [Object.assign(new VocabularyEntry(), { authority: 1, display: 'one', value: 1 })];
item.nativeElement.click(); item.nativeElement.click();
@@ -187,7 +183,7 @@ describe('DsDynamicListComponent test suite', () => {
listComp = listFixture.componentInstance; // FormComponent test instance listComp = listFixture.componentInstance; // FormComponent test instance
listComp.group = LIST_TEST_GROUP; listComp.group = LIST_TEST_GROUP;
listComp.model = new DynamicListCheckboxGroupModel(LIST_CHECKBOX_TEST_MODEL_CONFIG, LAYOUT_TEST); listComp.model = new DynamicListCheckboxGroupModel(LIST_CHECKBOX_TEST_MODEL_CONFIG, LAYOUT_TEST);
modelValue = [Object.assign(new AuthorityValue(), {id: 1, display: 'one', value: 1})]; modelValue = [Object.assign(new VocabularyEntry(), { authority: 1, display: 'one', value: 1 })];
listComp.model.value = modelValue; listComp.model.value = modelValue;
listFixture.detectChanges(); listFixture.detectChanges();
}); });
@@ -198,13 +194,9 @@ describe('DsDynamicListComponent test suite', () => {
}); });
it('should init component properly', () => { it('should init component properly', () => {
const results$ = authorityServiceStub.getEntriesByName({} as any); expect((listComp as any).optionsList).toEqual(vocabularyServiceStub.getList());
expect(listComp.model.value).toEqual(modelValue);
results$.subscribe((results) => { expect((listComp.model as DynamicListCheckboxGroupModel).group[0].value).toBeTruthy();
expect((listComp as any).optionsList).toEqual(results.payload);
expect(listComp.model.value).toEqual(modelValue);
expect((listComp.model as DynamicListCheckboxGroupModel).group[0].value).toBeTruthy();
})
}); });
it('should set model value properly when a checkbox option is deselected', () => { it('should set model value properly when a checkbox option is deselected', () => {
@@ -237,20 +229,16 @@ describe('DsDynamicListComponent test suite', () => {
}); });
it('should init component properly', () => { it('should init component properly', () => {
const results$ = authorityServiceStub.getEntriesByName({} as any); expect((listComp as any).optionsList).toEqual(vocabularyServiceStub.getList());
expect(listComp.items.length).toBe(1);
results$.subscribe((results) => { expect(listComp.items[0].length).toBe(2);
expect((listComp as any).optionsList).toEqual(results.payload);
expect(listComp.items.length).toBe(1);
expect(listComp.items[0].length).toBe(2);
})
}); });
it('should set model value when a radio option is selected', () => { it('should set model value when a radio option is selected', () => {
const de = listFixture.debugElement.queryAll(By.css('div.custom-radio')); const de = listFixture.debugElement.queryAll(By.css('div.custom-radio'));
const items = de[0].queryAll(By.css('input.custom-control-input')); const items = de[0].queryAll(By.css('input.custom-control-input'));
const item = items[0]; const item = items[0];
modelValue = Object.assign(new AuthorityValue(), {id: 1, display: 'one', value: 1}); modelValue = Object.assign(new VocabularyEntry(), { authority: 1, display: 'one', value: 1 });
item.nativeElement.click(); item.nativeElement.click();
@@ -265,7 +253,7 @@ describe('DsDynamicListComponent test suite', () => {
listComp = listFixture.componentInstance; // FormComponent test instance listComp = listFixture.componentInstance; // FormComponent test instance
listComp.group = LIST_TEST_GROUP; listComp.group = LIST_TEST_GROUP;
listComp.model = new DynamicListRadioGroupModel(LIST_RADIO_TEST_MODEL_CONFIG, LAYOUT_TEST); listComp.model = new DynamicListRadioGroupModel(LIST_RADIO_TEST_MODEL_CONFIG, LAYOUT_TEST);
modelValue = Object.assign(new AuthorityValue(), {id: 1, display: 'one', value: 1}); modelValue = Object.assign(new VocabularyEntry(), { authority: 1, display: 'one', value: 1 });
listComp.model.value = modelValue; listComp.model.value = modelValue;
listFixture.detectChanges(); listFixture.detectChanges();
}); });
@@ -276,13 +264,9 @@ describe('DsDynamicListComponent test suite', () => {
}); });
it('should init component properly', () => { it('should init component properly', () => {
const results$ = authorityServiceStub.getEntriesByName({} as any); expect((listComp as any).optionsList).toEqual(vocabularyServiceStub.getList());
expect(listComp.model.value).toEqual(modelValue);
results$.subscribe((results) => { expect((listComp.model as DynamicListRadioGroupModel).options[0].value).toBeTruthy();
expect((listComp as any).optionsList).toEqual(results.payload);
expect(listComp.model.value).toEqual(modelValue);
expect((listComp.model as DynamicListRadioGroupModel).options[0].value).toBeTruthy();
})
}); });
}); });
}); });

View File

@@ -1,20 +1,23 @@
import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import {
DynamicCheckboxModel,
DynamicFormControlComponent,
DynamicFormLayoutService,
DynamicFormValidationService
} from '@ng-dynamic-forms/core';
import { findKey } from 'lodash'; import { findKey } from 'lodash';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { VocabularyFindOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-find-options.model';
import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model';
import { hasValue, isNotEmpty } from '../../../../../empty.util'; import { hasValue, isNotEmpty } from '../../../../../empty.util';
import { DynamicListCheckboxGroupModel } from './dynamic-list-checkbox-group.model'; import { DynamicListCheckboxGroupModel } from './dynamic-list-checkbox-group.model';
import { FormBuilderService } from '../../../form-builder.service'; import { FormBuilderService } from '../../../form-builder.service';
import {
DynamicCheckboxModel,
DynamicFormControlComponent, DynamicFormLayoutService,
DynamicFormValidationService
} from '@ng-dynamic-forms/core';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value';
import { DynamicListRadioGroupModel } from './dynamic-list-radio-group.model'; import { DynamicListRadioGroupModel } from './dynamic-list-radio-group.model';
import { IntegrationData } from '../../../../../../core/integration/integration-data'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
import { getFirstSucceededRemoteDataPayload } from '../../../../../../core/shared/operators';
import { PaginatedList } from '../../../../../../core/data/paginated-list';
import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model';
export interface ListItem { export interface ListItem {
id: string, id: string,
@@ -39,10 +42,10 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
@Output() focus: EventEmitter<any> = new EventEmitter<any>(); @Output() focus: EventEmitter<any> = new EventEmitter<any>();
public items: ListItem[][] = []; public items: ListItem[][] = [];
protected optionsList: AuthorityValue[]; protected optionsList: VocabularyEntry[];
protected searchOptions: IntegrationSearchOptions; protected searchOptions: VocabularyFindOptions;
constructor(private authorityService: AuthorityService, constructor(private vocabularyService: VocabularyService,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
private formBuilderService: FormBuilderService, private formBuilderService: FormBuilderService,
protected layoutService: DynamicFormLayoutService, protected layoutService: DynamicFormLayoutService,
@@ -54,10 +57,10 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
ngOnInit() { ngOnInit() {
if (this.hasAuthorityOptions()) { if (this.hasAuthorityOptions()) {
// TODO Replace max elements 1000 with a paginated request when pagination bug is resolved // TODO Replace max elements 1000 with a paginated request when pagination bug is resolved
this.searchOptions = new IntegrationSearchOptions( this.searchOptions = new VocabularyFindOptions(
this.model.authorityOptions.scope, this.model.vocabularyOptions.scope,
this.model.authorityOptions.name, this.model.vocabularyOptions.name,
this.model.authorityOptions.metadata, this.model.vocabularyOptions.metadata,
'', '',
1000, // Max elements 1000, // Max elements
1);// Current Page 1);// Current Page
@@ -77,13 +80,13 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
const target = event.target as any; const target = event.target as any;
if (this.model.repeatable) { if (this.model.repeatable) {
// Target tabindex coincide with the array index of the value into the authority list // Target tabindex coincide with the array index of the value into the authority list
const authorityValue: AuthorityValue = this.optionsList[target.tabIndex]; const entry: VocabularyEntry = this.optionsList[target.tabIndex];
if (target.checked) { if (target.checked) {
this.model.valueUpdates.next(authorityValue); this.model.valueUpdates.next(entry);
} else { } else {
const newValue = []; const newValue = [];
this.model.value this.model.value
.filter((item) => item.value !== authorityValue.value) .filter((item) => item.value !== entry.value)
.forEach((item) => newValue.push(item)); .forEach((item) => newValue.push(item));
this.model.valueUpdates.next(newValue); this.model.valueUpdates.next(newValue);
} }
@@ -94,16 +97,18 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
} }
protected setOptionsFromAuthority() { protected setOptionsFromAuthority() {
if (this.model.authorityOptions.name && this.model.authorityOptions.name.length > 0) { if (this.model.vocabularyOptions.name && this.model.vocabularyOptions.name.length > 0) {
const listGroup = this.group.controls[this.model.id] as FormGroup; const listGroup = this.group.controls[this.model.id] as FormGroup;
this.authorityService.getEntriesByName(this.searchOptions).subscribe((authorities: IntegrationData) => { this.vocabularyService.getVocabularyEntries(this.searchOptions).pipe(
getFirstSucceededRemoteDataPayload()
).subscribe((entries: PaginatedList<VocabularyEntry>) => {
let groupCounter = 0; let groupCounter = 0;
let itemsPerGroup = 0; let itemsPerGroup = 0;
let tempList: ListItem[] = []; let tempList: ListItem[] = [];
this.optionsList = authorities.payload as AuthorityValue[]; this.optionsList = entries.page;
// Make a list of available options (checkbox/radio) and split in groups of 'model.groupLength' // Make a list of available options (checkbox/radio) and split in groups of 'model.groupLength'
(authorities.payload as AuthorityValue[]).forEach((option, key) => { entries.page.forEach((option, key) => {
const value = option.id || option.value; const value = option.authority || option.value;
const checked: boolean = isNotEmpty(findKey( const checked: boolean = isNotEmpty(findKey(
this.model.value, this.model.value,
(v) => v.value === option.value)); (v) => v.value === option.value));
@@ -138,8 +143,8 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
} }
protected hasAuthorityOptions() { protected hasAuthorityOptions() {
return (hasValue(this.model.authorityOptions.scope) return (hasValue(this.model.vocabularyOptions.scope)
&& hasValue(this.model.authorityOptions.name) && hasValue(this.model.vocabularyOptions.name)
&& hasValue(this.model.authorityOptions.metadata)); && hasValue(this.model.vocabularyOptions.metadata));
} }
} }

View File

@@ -2,33 +2,33 @@
import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { async, ComponentFixture, fakeAsync, inject, TestBed, tick, } from '@angular/core/testing'; import { async, ComponentFixture, fakeAsync, inject, TestBed, tick, } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core';
import { AuthorityOptions } from '../../../../../../core/integration/models/authority-options.model'; import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormValidationService } from '@ng-dynamic-forms/core';
import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap'; import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormValidationService } from '@ng-dynamic-forms/core';
import { AuthorityServiceStub } from '../../../../../testing/authority-service.stub';
import { VocabularyOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-options.model';
import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
import { VocabularyServiceStub } from '../../../../../testing/vocabulary-service.stub';
import { DsDynamicLookupComponent } from './dynamic-lookup.component'; import { DsDynamicLookupComponent } from './dynamic-lookup.component';
import { DynamicLookupModel } from './dynamic-lookup.model'; import { DynamicLookupModel } from './dynamic-lookup.model';
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { TranslateModule } from '@ngx-translate/core';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { By } from '@angular/platform-browser'; import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value';
import { createTestComponent } from '../../../../../testing/utils.test'; import { createTestComponent } from '../../../../../testing/utils.test';
import { DynamicLookupNameModel } from './dynamic-lookup-name.model'; import { DynamicLookupNameModel } from './dynamic-lookup-name.model';
import { AuthorityConfidenceStateDirective } from '../../../../../authority-confidence/authority-confidence-state.directive'; import { AuthorityConfidenceStateDirective } from '../../../../../authority-confidence/authority-confidence-state.directive';
import { ObjNgFor } from '../../../../../utils/object-ngfor.pipe'; import { ObjNgFor } from '../../../../../utils/object-ngfor.pipe';
let LOOKUP_TEST_MODEL_CONFIG = { let LOOKUP_TEST_MODEL_CONFIG = {
authorityOptions: { vocabularyOptions: {
closed: false, closed: false,
metadata: 'lookup', metadata: 'lookup',
name: 'RPAuthority', name: 'RPAuthority',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions, } as VocabularyOptions,
disabled: false, disabled: false,
errorMessages: { required: 'Required field.' }, errorMessages: { required: 'Required field.' },
id: 'lookup', id: 'lookup',
@@ -47,12 +47,12 @@ let LOOKUP_TEST_MODEL_CONFIG = {
}; };
let LOOKUP_NAME_TEST_MODEL_CONFIG = { let LOOKUP_NAME_TEST_MODEL_CONFIG = {
authorityOptions: { vocabularyOptions: {
closed: false, closed: false,
metadata: 'lookup-name', metadata: 'lookup-name',
name: 'RPAuthority', name: 'RPAuthority',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions, } as VocabularyOptions,
disabled: false, disabled: false,
errorMessages: { required: 'Required field.' }, errorMessages: { required: 'Required field.' },
id: 'lookupName', id: 'lookupName',
@@ -78,12 +78,12 @@ let LOOKUP_TEST_GROUP = new FormGroup({
describe('Dynamic Lookup component', () => { describe('Dynamic Lookup component', () => {
function init() { function init() {
LOOKUP_TEST_MODEL_CONFIG = { LOOKUP_TEST_MODEL_CONFIG = {
authorityOptions: { vocabularyOptions: {
closed: false, closed: false,
metadata: 'lookup', metadata: 'lookup',
name: 'RPAuthority', name: 'RPAuthority',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions, } as VocabularyOptions,
disabled: false, disabled: false,
errorMessages: { required: 'Required field.' }, errorMessages: { required: 'Required field.' },
id: 'lookup', id: 'lookup',
@@ -102,12 +102,12 @@ describe('Dynamic Lookup component', () => {
}; };
LOOKUP_NAME_TEST_MODEL_CONFIG = { LOOKUP_NAME_TEST_MODEL_CONFIG = {
authorityOptions: { vocabularyOptions: {
closed: false, closed: false,
metadata: 'lookup-name', metadata: 'lookup-name',
name: 'RPAuthority', name: 'RPAuthority',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions, } as VocabularyOptions,
disabled: false, disabled: false,
errorMessages: { required: 'Required field.' }, errorMessages: { required: 'Required field.' },
id: 'lookupName', id: 'lookupName',
@@ -137,12 +137,11 @@ describe('Dynamic Lookup component', () => {
let testFixture: ComponentFixture<TestComponent>; let testFixture: ComponentFixture<TestComponent>;
let lookupFixture: ComponentFixture<DsDynamicLookupComponent>; let lookupFixture: ComponentFixture<DsDynamicLookupComponent>;
let html; let html;
let vocabularyServiceStub: VocabularyServiceStub;
let authorityServiceStub;
// async beforeEach // async beforeEach
beforeEach(async(() => { beforeEach(async(() => {
const authorityService = new AuthorityServiceStub(); vocabularyServiceStub = new VocabularyServiceStub();
authorityServiceStub = authorityService;
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
DynamicFormsCoreModule, DynamicFormsCoreModule,
@@ -162,7 +161,7 @@ describe('Dynamic Lookup component', () => {
providers: [ providers: [
ChangeDetectorRef, ChangeDetectorRef,
DsDynamicLookupComponent, DsDynamicLookupComponent,
{ provide: AuthorityService, useValue: authorityService }, { provide: VocabularyService, useValue: vocabularyServiceStub },
{ provide: DynamicFormLayoutService, useValue: {} }, { provide: DynamicFormLayoutService, useValue: {} },
{ provide: DynamicFormValidationService, useValue: {} } { provide: DynamicFormValidationService, useValue: {} }
], ],
@@ -247,7 +246,7 @@ describe('Dynamic Lookup component', () => {
it('should return search results', fakeAsync(() => { it('should return search results', fakeAsync(() => {
const de = lookupFixture.debugElement.queryAll(By.css('button')); const de = lookupFixture.debugElement.queryAll(By.css('button'));
const btnEl = de[0].nativeElement; const btnEl = de[0].nativeElement;
const results$ = authorityServiceStub.getEntriesByName({} as any); const results = vocabularyServiceStub.getList();
lookupComp.firstInputValue = 'test'; lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges(); lookupFixture.detectChanges();
@@ -255,17 +254,15 @@ describe('Dynamic Lookup component', () => {
btnEl.click(); btnEl.click();
tick(); tick();
lookupFixture.detectChanges(); lookupFixture.detectChanges();
results$.subscribe((results) => { expect(lookupComp.optionsList).toEqual(results);
expect(lookupComp.optionsList).toEqual(results.payload);
});
})); }));
it('should select a results entry properly', fakeAsync(() => { it('should select a results entry properly', fakeAsync(() => {
let de = lookupFixture.debugElement.queryAll(By.css('button')); let de = lookupFixture.debugElement.queryAll(By.css('button'));
const btnEl = de[0].nativeElement; const btnEl = de[0].nativeElement;
const selectedValue = Object.assign(new AuthorityValue(), { const selectedValue = Object.assign(new VocabularyEntry(), {
id: 1, authority: 1,
display: 'one', display: 'one',
value: 1 value: 1
}); });
@@ -284,7 +281,7 @@ describe('Dynamic Lookup component', () => {
expect(lookupComp.change.emit).toHaveBeenCalled(); expect(lookupComp.change.emit).toHaveBeenCalled();
})); }));
it('should set model.value on input type when AuthorityOptions.closed is false', fakeAsync(() => { it('should set model.value on input type when VocabularyOptions.closed is false', fakeAsync(() => {
lookupComp.firstInputValue = 'test'; lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges(); lookupFixture.detectChanges();
@@ -293,8 +290,8 @@ describe('Dynamic Lookup component', () => {
})); }));
it('should not set model.value on input type when AuthorityOptions.closed is true', () => { it('should not set model.value on input type when VocabularyOptions.closed is true', () => {
lookupComp.model.authorityOptions.closed = true; lookupComp.model.vocabularyOptions.closed = true;
lookupComp.firstInputValue = 'test'; lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges(); lookupFixture.detectChanges();
@@ -389,26 +386,26 @@ describe('Dynamic Lookup component', () => {
it('should select a results entry properly', fakeAsync(() => { it('should select a results entry properly', fakeAsync(() => {
const payload = [ const payload = [
Object.assign(new AuthorityValue(), { Object.assign(new VocabularyEntry(), {
id: 1, authority: 1,
display: 'Name, Lastname', display: 'Name, Lastname',
value: 1 value: 1
}), }),
Object.assign(new AuthorityValue(), { Object.assign(new VocabularyEntry(), {
id: 2, authority: 2,
display: 'NameTwo, LastnameTwo', display: 'NameTwo, LastnameTwo',
value: 2 value: 2
}), }),
]; ];
let de = lookupFixture.debugElement.queryAll(By.css('button')); let de = lookupFixture.debugElement.queryAll(By.css('button'));
const btnEl = de[0].nativeElement; const btnEl = de[0].nativeElement;
const selectedValue = Object.assign(new AuthorityValue(), { const selectedValue = Object.assign(new VocabularyEntry(), {
id: 1, authority: 1,
display: 'Name, Lastname', display: 'Name, Lastname',
value: 1 value: 1
}); });
spyOn(lookupComp.change, 'emit'); spyOn(lookupComp.change, 'emit');
authorityServiceStub.setNewPayload(payload); vocabularyServiceStub.setNewPayload(payload);
lookupComp.firstInputValue = 'test'; lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges(); lookupFixture.detectChanges();
btnEl.click(); btnEl.click();

View File

@@ -1,8 +1,7 @@
import { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { Subscription } from 'rxjs'; import { of as observableOf, Subscription } from 'rxjs';
import { of as observableOf } from 'rxjs';
import { catchError, distinctUntilChanged } from 'rxjs/operators'; import { catchError, distinctUntilChanged } from 'rxjs/operators';
import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'; import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap';
import { import {
@@ -11,16 +10,16 @@ import {
DynamicFormValidationService DynamicFormValidationService
} from '@ng-dynamic-forms/core'; } from '@ng-dynamic-forms/core';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
import { DynamicLookupModel } from './dynamic-lookup.model'; import { VocabularyFindOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-find-options.model';
import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model';
import { hasValue, isEmpty, isNotEmpty, isNull, isUndefined } from '../../../../../empty.util'; import { hasValue, isEmpty, isNotEmpty, isNull, isUndefined } from '../../../../../empty.util';
import { IntegrationData } from '../../../../../../core/integration/integration-data';
import { PageInfo } from '../../../../../../core/shared/page-info.model'; import { PageInfo } from '../../../../../../core/shared/page-info.model';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value'; import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model';
import { DynamicLookupNameModel } from './dynamic-lookup-name.model'; import { DynamicLookupNameModel } from './dynamic-lookup-name.model';
import { ConfidenceType } from '../../../../../../core/integration/models/confidence-type'; import { ConfidenceType } from '../../../../../../core/shared/confidence-type';
import { PaginatedList } from '../../../../../../core/data/paginated-list';
import { getFirstSucceededRemoteDataPayload } from '../../../../../../core/shared/operators';
@Component({ @Component({
selector: 'ds-dynamic-lookup', selector: 'ds-dynamic-lookup',
@@ -43,10 +42,10 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
public pageInfo: PageInfo; public pageInfo: PageInfo;
public optionsList: any; public optionsList: any;
protected searchOptions: IntegrationSearchOptions; protected searchOptions: VocabularyFindOptions;
protected subs: Subscription[] = []; protected subs: Subscription[] = [];
constructor(private authorityService: AuthorityService, constructor(private vocabularyService: VocabularyService,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
protected layoutService: DynamicFormLayoutService, protected layoutService: DynamicFormLayoutService,
protected validationService: DynamicFormValidationService protected validationService: DynamicFormValidationService
@@ -59,10 +58,10 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
}; };
ngOnInit() { ngOnInit() {
this.searchOptions = new IntegrationSearchOptions( this.searchOptions = new VocabularyFindOptions(
this.model.authorityOptions.scope, this.model.vocabularyOptions.scope,
this.model.authorityOptions.name, this.model.vocabularyOptions.name,
this.model.authorityOptions.metadata, this.model.vocabularyOptions.metadata,
'', '',
this.model.maxOptions, this.model.maxOptions,
1); 1);
@@ -79,6 +78,148 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
})); }));
} }
public formatItemForInput(item: any, field: number): string {
if (isUndefined(item) || isNull(item)) {
return '';
}
return (typeof item === 'string') ? item : this.inputFormatter(item, field);
}
public hasAuthorityValue() {
return hasValue(this.model.value)
&& this.model.value.hasAuthority();
}
public hasEmptyValue() {
return isNotEmpty(this.getCurrentValue());
}
public clearFields() {
// Clear inputs whether there is no results and authority is closed
if (this.model.vocabularyOptions.closed) {
this.resetFields();
}
}
public isEditDisabled() {
return !this.hasAuthorityValue();
}
public isInputDisabled() {
return (this.model.vocabularyOptions.closed && this.hasAuthorityValue() && !this.editMode);
}
public isLookupName() {
return (this.model instanceof DynamicLookupNameModel);
}
public isSearchDisabled() {
return isEmpty(this.firstInputValue) || this.editMode;
}
public onBlurEvent(event: Event) {
this.blur.emit(event);
}
public onFocusEvent(event) {
this.focus.emit(event);
}
public onChange(event) {
event.preventDefault();
if (!this.model.vocabularyOptions.closed) {
if (isNotEmpty(this.getCurrentValue())) {
const currentValue = new FormFieldMetadataValueObject(this.getCurrentValue());
if (!this.editMode) {
this.updateModel(currentValue);
}
} else {
this.remove();
}
}
}
public onScroll() {
if (!this.loading && this.pageInfo.currentPage <= this.pageInfo.totalPages) {
this.searchOptions.currentPage++;
this.search();
}
}
public onSelect(event) {
this.updateModel(event);
}
public openChange(isOpened: boolean) {
if (!isOpened) {
if (this.model.vocabularyOptions.closed && !this.hasAuthorityValue()) {
this.setInputsValue('');
}
}
}
public remove() {
this.group.markAsPristine();
this.model.valueUpdates.next(null);
this.change.emit(null);
}
public saveChanges() {
if (isNotEmpty(this.getCurrentValue())) {
const newValue = Object.assign(new VocabularyEntry(), this.model.value, {
display: this.getCurrentValue(),
value: this.getCurrentValue()
});
this.updateModel(newValue);
} else {
this.remove();
}
this.switchEditMode();
}
public search() {
this.optionsList = null;
this.pageInfo = null;
// Query
this.searchOptions.query = this.getCurrentValue();
this.loading = true;
this.subs.push(this.vocabularyService.getVocabularyEntries(this.searchOptions).pipe(
getFirstSucceededRemoteDataPayload(),
catchError(() =>
observableOf(new PaginatedList(
new PageInfo(),
[]
))
),
distinctUntilChanged())
.subscribe((list: PaginatedList<VocabularyEntry>) => {
console.log(list);
this.optionsList = list.page;
this.pageInfo = list.pageInfo;
this.loading = false;
this.cdr.detectChanges();
}));
}
public switchEditMode() {
this.editMode = !this.editMode;
}
public whenClickOnConfidenceNotAccepted(sdRef: NgbDropdown, confidence: ConfidenceType) {
if (!this.model.readOnly) {
sdRef.open();
this.search();
}
}
ngOnDestroy() {
this.subs
.filter((sub) => hasValue(sub))
.forEach((sub) => sub.unsubscribe());
}
protected getCurrentValue(): string { protected getCurrentValue(): string {
let result = ''; let result = '';
if (!this.isLookupName()) { if (!this.isLookupName()) {
@@ -106,7 +247,7 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
protected setInputsValue(value) { protected setInputsValue(value) {
if (hasValue(value)) { if (hasValue(value)) {
let displayValue = value; let displayValue = value;
if (value instanceof FormFieldMetadataValueObject || value instanceof AuthorityValue) { if (value instanceof FormFieldMetadataValueObject || value instanceof VocabularyEntry) {
displayValue = value.display; displayValue = value.display;
} }
@@ -131,145 +272,4 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
this.optionsList = null; this.optionsList = null;
this.pageInfo = null; this.pageInfo = null;
} }
public formatItemForInput(item: any, field: number): string {
if (isUndefined(item) || isNull(item)) {
return '';
}
return (typeof item === 'string') ? item : this.inputFormatter(item, field);
}
public hasAuthorityValue() {
return hasValue(this.model.value)
&& this.model.value.hasAuthority();
}
public hasEmptyValue() {
return isNotEmpty(this.getCurrentValue());
}
public clearFields() {
// Clear inputs whether there is no results and authority is closed
if (this.model.authorityOptions.closed) {
this.resetFields();
}
}
public isEditDisabled() {
return !this.hasAuthorityValue();
}
public isInputDisabled() {
return (this.model.authorityOptions.closed && this.hasAuthorityValue() && !this.editMode);
}
public isLookupName() {
return (this.model instanceof DynamicLookupNameModel);
}
public isSearchDisabled() {
return isEmpty(this.firstInputValue) || this.editMode;
}
public onBlurEvent(event: Event) {
this.blur.emit(event);
}
public onFocusEvent(event) {
this.focus.emit(event);
}
public onChange(event) {
event.preventDefault();
if (!this.model.authorityOptions.closed) {
if (isNotEmpty(this.getCurrentValue())) {
const currentValue = new FormFieldMetadataValueObject(this.getCurrentValue());
if (!this.editMode) {
this.updateModel(currentValue);
}
} else {
this.remove();
}
}
}
public onScroll() {
if (!this.loading && this.pageInfo.currentPage <= this.pageInfo.totalPages) {
this.searchOptions.currentPage++;
this.search();
}
}
public onSelect(event) {
this.updateModel(event);
}
public openChange(isOpened: boolean) {
if (!isOpened) {
if (this.model.authorityOptions.closed && !this.hasAuthorityValue()) {
this.setInputsValue('');
}
}
}
public remove() {
this.group.markAsPristine();
this.model.valueUpdates.next(null);
this.change.emit(null);
}
public saveChanges() {
if (isNotEmpty(this.getCurrentValue())) {
const newValue = Object.assign(new AuthorityValue(), this.model.value, {
display: this.getCurrentValue(),
value: this.getCurrentValue()
});
this.updateModel(newValue);
} else {
this.remove();
}
this.switchEditMode();
}
public search() {
this.optionsList = null;
this.pageInfo = null;
// Query
this.searchOptions.query = this.getCurrentValue();
this.loading = true;
this.subs.push(this.authorityService.getEntriesByName(this.searchOptions).pipe(
catchError(() => {
const emptyResult = new IntegrationData(
new PageInfo(),
[]
);
return observableOf(emptyResult);
}),
distinctUntilChanged())
.subscribe((object: IntegrationData) => {
this.optionsList = object.payload;
this.pageInfo = object.pageInfo;
this.loading = false;
this.cdr.detectChanges();
}));
}
public switchEditMode() {
this.editMode = !this.editMode;
}
public whenClickOnConfidenceNotAccepted(sdRef: NgbDropdown, confidence: ConfidenceType) {
if (!this.model.readOnly) {
sdRef.open();
this.search();
}
}
ngOnDestroy() {
this.subs
.filter((sub) => hasValue(sub))
.forEach((sub) => sub.unsubscribe());
}
} }

View File

@@ -2,9 +2,12 @@
import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, inject, TestBed, } from '@angular/core/testing'; import { async, ComponentFixture, inject, TestBed, } from '@angular/core/testing';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { Store, StoreModule } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dynamic-forms/core';
import { DsDynamicRelationGroupComponent } from './dynamic-relation-group.components'; import { DsDynamicRelationGroupComponent } from './dynamic-relation-group.components';
import { DynamicRelationGroupModel, DynamicRelationGroupModelConfig } from './dynamic-relation-group.model'; import { DynamicRelationGroupModel, DynamicRelationGroupModelConfig } from './dynamic-relation-group.model';
@@ -13,18 +16,14 @@ import { FormFieldModel } from '../../../models/form-field.model';
import { FormBuilderService } from '../../../form-builder.service'; import { FormBuilderService } from '../../../form-builder.service';
import { FormService } from '../../../../form.service'; import { FormService } from '../../../../form.service';
import { FormComponent } from '../../../../form.component'; import { FormComponent } from '../../../../form.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { Chips } from '../../../../../chips/models/chips.model'; import { Chips } from '../../../../../chips/models/chips.model';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { DsDynamicInputModel } from '../ds-dynamic-input.model'; import { DsDynamicInputModel } from '../ds-dynamic-input.model';
import { createTestComponent } from '../../../../../testing/utils.test'; import { createTestComponent } from '../../../../../testing/utils.test';
import { DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { VocabularyServiceStub } from '../../../../../testing/vocabulary-service.stub';
import { AuthorityServiceStub } from '../../../../../testing/authority-service.stub';
import { Store, StoreModule } from '@ngrx/store';
import { StoreMock } from '../../../../../testing/store.mock'; import { StoreMock } from '../../../../../testing/store.mock';
import { FormRowModel } from '../../../../../../core/config/models/config-submission-form.model'; import { FormRowModel } from '../../../../../../core/config/models/config-submission-form.model';
import { GlobalConfig } from '../../../../../../../config/global-config.interface';
import { storeModuleConfig } from '../../../../../../app.reducer'; import { storeModuleConfig } from '../../../../../../app.reducer';
export let FORM_GROUP_TEST_MODEL_CONFIG; export let FORM_GROUP_TEST_MODEL_CONFIG;
@@ -47,7 +46,7 @@ function init() {
mandatoryMessage: 'Required field!', mandatoryMessage: 'Required field!',
repeatable: false, repeatable: false,
selectableMetadata: [{ selectableMetadata: [{
authority: 'RPAuthority', controlledVocabulary: 'RPAuthority',
closed: false, closed: false,
metadata: 'dc.contributor.author' metadata: 'dc.contributor.author'
}], }],
@@ -61,7 +60,7 @@ function init() {
mandatory: 'false', mandatory: 'false',
repeatable: false, repeatable: false,
selectableMetadata: [{ selectableMetadata: [{
authority: 'OUAuthority', controlledVocabulary: 'OUAuthority',
closed: false, closed: false,
metadata: 'local.contributor.affiliation' metadata: 'local.contributor.affiliation'
}] }]
@@ -128,7 +127,7 @@ describe('DsDynamicRelationGroupComponent test suite', () => {
FormBuilderService, FormBuilderService,
FormComponent, FormComponent,
FormService, FormService,
{ provide: AuthorityService, useValue: new AuthorityServiceStub() }, { provide: VocabularyService, useValue: new VocabularyServiceStub() },
{ provide: Store, useClass: StoreMock } { provide: Store, useClass: StoreMock }
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]

View File

@@ -1,14 +1,4 @@
import { import { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
ChangeDetectorRef,
Component,
EventEmitter,
Inject,
Input,
OnDestroy,
OnInit,
Output,
ViewChild
} from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { combineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; import { combineLatest, Observable, of as observableOf, Subscription } from 'rxjs';
@@ -33,12 +23,12 @@ import { hasValue, isEmpty, isNotEmpty, isNotNull } from '../../../../../empty.u
import { shrinkInOut } from '../../../../../animations/shrink'; import { shrinkInOut } from '../../../../../animations/shrink';
import { ChipsItem } from '../../../../../chips/models/chips-item.model'; import { ChipsItem } from '../../../../../chips/models/chips-item.model';
import { hasOnlyEmptyProperties } from '../../../../../object.util'; import { hasOnlyEmptyProperties } from '../../../../../object.util';
import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model'; import { VocabularyFindOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-find-options.model';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
import { IntegrationData } from '../../../../../../core/integration/integration-data';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value';
import { environment } from '../../../../../../../environments/environment'; import { environment } from '../../../../../../../environments/environment';
import { getFirstSucceededRemoteDataPayload } from '../../../../../../core/shared/operators';
import { VocabularyEntryDetail } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
@Component({ @Component({
selector: 'ds-dynamic-relation-group', selector: 'ds-dynamic-relation-group',
@@ -64,9 +54,9 @@ export class DsDynamicRelationGroupComponent extends DynamicFormControlComponent
private selectedChipItem: ChipsItem; private selectedChipItem: ChipsItem;
private subs: Subscription[] = []; private subs: Subscription[] = [];
@ViewChild('formRef', {static: false}) private formRef: FormComponent; @ViewChild('formRef', { static: false }) private formRef: FormComponent;
constructor(private authorityService: AuthorityService, constructor(private vocabularyService: VocabularyService,
private formBuilderService: FormBuilderService, private formBuilderService: FormBuilderService,
private formService: FormService, private formService: FormService,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
@@ -177,6 +167,12 @@ export class DsDynamicRelationGroupComponent extends DynamicFormControlComponent
this.clear(); this.clear();
} }
ngOnDestroy(): void {
this.subs
.filter((sub) => hasValue(sub))
.forEach((sub) => sub.unsubscribe());
}
private addToChips() { private addToChips() {
if (!this.formRef.formGroup.valid) { if (!this.formRef.formGroup.valid) {
this.formService.validateAllFormFields(this.formRef.formGroup); this.formService.validateAllFormFields(this.formRef.formGroup);
@@ -235,20 +231,16 @@ export class DsDynamicRelationGroupComponent extends DynamicFormControlComponent
if (isObject(valueObj[fieldName]) && valueObj[fieldName].hasAuthority() && isNotEmpty(valueObj[fieldName].authority)) { if (isObject(valueObj[fieldName]) && valueObj[fieldName].hasAuthority() && isNotEmpty(valueObj[fieldName].authority)) {
const fieldId = fieldName.replace(/\./g, '_'); const fieldId = fieldName.replace(/\./g, '_');
const model = this.formBuilderService.findById(fieldId, this.formModel); const model = this.formBuilderService.findById(fieldId, this.formModel);
const searchOptions: IntegrationSearchOptions = new IntegrationSearchOptions( return$ = this.vocabularyService.findEntryDetailByValue(
(model as any).authorityOptions.scope,
(model as any).authorityOptions.name,
(model as any).authorityOptions.metadata,
valueObj[fieldName].authority, valueObj[fieldName].authority,
(model as any).maxOptions, (model as any).vocabularyOptions.name
1); ).pipe(
getFirstSucceededRemoteDataPayload(),
return$ = this.authorityService.getEntryByValue(searchOptions).pipe( map((entryDetail: VocabularyEntryDetail) => Object.assign(
map((result: IntegrationData) => Object.assign(
new FormFieldMetadataValueObject(), new FormFieldMetadataValueObject(),
valueObj[fieldName], valueObj[fieldName],
{ {
otherInformation: (result.payload[0] as AuthorityValue).otherInformation otherInformation: entryDetail.otherInformation
}) })
)); ));
} else { } else {
@@ -315,10 +307,4 @@ export class DsDynamicRelationGroupComponent extends DynamicFormControlComponent
} }
} }
ngOnDestroy(): void {
this.subs
.filter((sub) => hasValue(sub))
.forEach((sub) => sub.unsubscribe());
}
} }

View File

@@ -9,12 +9,12 @@ import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormValidationService } from '@ng-dynamic-forms/core'; import { DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormValidationService } from '@ng-dynamic-forms/core';
import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap'; import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap';
import { AuthorityOptions } from '../../../../../../core/integration/models/authority-options.model'; import { VocabularyOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-options.model';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
import { AuthorityServiceStub } from '../../../../../testing/authority-service.stub'; import { VocabularyServiceStub } from '../../../../../testing/vocabulary-service.stub';
import { DsDynamicScrollableDropdownComponent } from './dynamic-scrollable-dropdown.component'; import { DsDynamicScrollableDropdownComponent } from './dynamic-scrollable-dropdown.component';
import { DynamicScrollableDropdownModel } from './dynamic-scrollable-dropdown.model'; import { DynamicScrollableDropdownModel } from './dynamic-scrollable-dropdown.model';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value'; import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model';
import { createTestComponent, hasClass } from '../../../../../testing/utils.test'; import { createTestComponent, hasClass } from '../../../../../testing/utils.test';
export const SD_TEST_GROUP = new FormGroup({ export const SD_TEST_GROUP = new FormGroup({
@@ -22,14 +22,14 @@ export const SD_TEST_GROUP = new FormGroup({
}); });
export const SD_TEST_MODEL_CONFIG = { export const SD_TEST_MODEL_CONFIG = {
authorityOptions: { vocabularyOptions: {
closed: false, closed: false,
metadata: 'dropdown', metadata: 'dropdown',
name: 'common_iso_languages', name: 'common_iso_languages',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions, } as VocabularyOptions,
disabled: false, disabled: false,
errorMessages: {required: 'Required field.'}, errorMessages: { required: 'Required field.' },
id: 'dropdown', id: 'dropdown',
label: 'Language', label: 'Language',
maxOptions: 10, maxOptions: 10,
@@ -52,7 +52,7 @@ describe('Dynamic Dynamic Scrollable Dropdown component', () => {
let html; let html;
let modelValue; let modelValue;
const authorityServiceStub = new AuthorityServiceStub(); const vocabularyServiceStub = new VocabularyServiceStub();
// async beforeEach // async beforeEach
beforeEach(async(() => { beforeEach(async(() => {
@@ -74,9 +74,9 @@ describe('Dynamic Dynamic Scrollable Dropdown component', () => {
providers: [ providers: [
ChangeDetectorRef, ChangeDetectorRef,
DsDynamicScrollableDropdownComponent, DsDynamicScrollableDropdownComponent,
{provide: AuthorityService, useValue: authorityServiceStub}, { provide: VocabularyService, useValue: vocabularyServiceStub },
{provide: DynamicFormLayoutService, useValue: {}}, { provide: DynamicFormLayoutService, useValue: {} },
{provide: DynamicFormValidationService, useValue: {}} { provide: DynamicFormValidationService, useValue: {} }
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]
}); });
@@ -121,11 +121,8 @@ describe('Dynamic Dynamic Scrollable Dropdown component', () => {
}); });
it('should init component properly', () => { it('should init component properly', () => {
const results$ = authorityServiceStub.getEntriesByName({} as any);
expect(scrollableDropdownComp.optionsList).toBeDefined(); expect(scrollableDropdownComp.optionsList).toBeDefined();
results$.subscribe((results) => { expect(scrollableDropdownComp.optionsList).toEqual(vocabularyServiceStub.getList());
expect(scrollableDropdownComp.optionsList).toEqual(results.payload);
})
}); });
it('should display dropdown menu entries', () => { it('should display dropdown menu entries', () => {
@@ -154,7 +151,7 @@ describe('Dynamic Dynamic Scrollable Dropdown component', () => {
})); }));
it('should select a results entry properly', fakeAsync(() => { it('should select a results entry properly', fakeAsync(() => {
const selectedValue = Object.assign(new AuthorityValue(), {id: 1, display: 'one', value: 1}); const selectedValue = Object.assign(new VocabularyEntry(), { authority: 1, display: 'one', value: 1 });
let de: any = scrollableDropdownFixture.debugElement.query(By.css('button.ds-form-input-btn')); let de: any = scrollableDropdownFixture.debugElement.query(By.css('button.ds-form-input-btn'));
let btnEl = de.nativeElement; let btnEl = de.nativeElement;
@@ -192,7 +189,7 @@ describe('Dynamic Dynamic Scrollable Dropdown component', () => {
scrollableDropdownFixture = TestBed.createComponent(DsDynamicScrollableDropdownComponent); scrollableDropdownFixture = TestBed.createComponent(DsDynamicScrollableDropdownComponent);
scrollableDropdownComp = scrollableDropdownFixture.componentInstance; // FormComponent test instance scrollableDropdownComp = scrollableDropdownFixture.componentInstance; // FormComponent test instance
scrollableDropdownComp.group = SD_TEST_GROUP; scrollableDropdownComp.group = SD_TEST_GROUP;
modelValue = Object.assign(new AuthorityValue(), {id: 1, display: 'one', value: 1}); modelValue = Object.assign(new VocabularyEntry(), { authority: 1, display: 'one', value: 1 });
scrollableDropdownComp.model = new DynamicScrollableDropdownModel(SD_TEST_MODEL_CONFIG); scrollableDropdownComp.model = new DynamicScrollableDropdownModel(SD_TEST_MODEL_CONFIG);
scrollableDropdownComp.model.value = modelValue; scrollableDropdownComp.model.value = modelValue;
scrollableDropdownFixture.detectChanges(); scrollableDropdownFixture.detectChanges();
@@ -204,12 +201,9 @@ describe('Dynamic Dynamic Scrollable Dropdown component', () => {
}); });
it('should init component properly', () => { it('should init component properly', () => {
const results$ = authorityServiceStub.getEntriesByName({} as any);
expect(scrollableDropdownComp.optionsList).toBeDefined(); expect(scrollableDropdownComp.optionsList).toBeDefined();
results$.subscribe((results) => { expect(scrollableDropdownComp.optionsList).toEqual(vocabularyServiceStub.getList());
expect(scrollableDropdownComp.optionsList).toEqual(results.payload); expect(scrollableDropdownComp.model.value).toEqual(modelValue);
expect(scrollableDropdownComp.model.value).toEqual(modelValue);
})
}); });
}); });
}); });

View File

@@ -2,7 +2,7 @@ import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } fro
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { Observable, of as observableOf } from 'rxjs'; import { Observable, of as observableOf } from 'rxjs';
import { catchError, distinctUntilChanged, first, tap } from 'rxjs/operators'; import { catchError, distinctUntilChanged, tap } from 'rxjs/operators';
import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'; import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap';
import { import {
DynamicFormControlComponent, DynamicFormControlComponent,
@@ -10,13 +10,14 @@ import {
DynamicFormValidationService DynamicFormValidationService
} from '@ng-dynamic-forms/core'; } from '@ng-dynamic-forms/core';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value'; import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model';
import { DynamicScrollableDropdownModel } from './dynamic-scrollable-dropdown.model'; import { DynamicScrollableDropdownModel } from './dynamic-scrollable-dropdown.model';
import { PageInfo } from '../../../../../../core/shared/page-info.model'; import { PageInfo } from '../../../../../../core/shared/page-info.model';
import { isNull, isUndefined } from '../../../../../empty.util'; import { isNull, isUndefined } from '../../../../../empty.util';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model'; import { VocabularyFindOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-find-options.model';
import { IntegrationData } from '../../../../../../core/integration/integration-data'; import { getFirstSucceededRemoteDataPayload } from '../../../../../../core/shared/operators';
import { PaginatedList } from '../../../../../../core/data/paginated-list';
@Component({ @Component({
selector: 'ds-dynamic-scrollable-dropdown', selector: 'ds-dynamic-scrollable-dropdown',
@@ -37,9 +38,9 @@ export class DsDynamicScrollableDropdownComponent extends DynamicFormControlComp
public pageInfo: PageInfo; public pageInfo: PageInfo;
public optionsList: any; public optionsList: any;
protected searchOptions: IntegrationSearchOptions; protected searchOptions: VocabularyFindOptions;
constructor(private authorityService: AuthorityService, constructor(private vocabularyService: VocabularyService,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
protected layoutService: DynamicFormLayoutService, protected layoutService: DynamicFormLayoutService,
protected validationService: DynamicFormValidationService protected validationService: DynamicFormValidationService
@@ -48,28 +49,26 @@ export class DsDynamicScrollableDropdownComponent extends DynamicFormControlComp
} }
ngOnInit() { ngOnInit() {
this.searchOptions = new IntegrationSearchOptions( this.searchOptions = new VocabularyFindOptions(
this.model.authorityOptions.scope, this.model.vocabularyOptions.scope,
this.model.authorityOptions.name, this.model.vocabularyOptions.name,
this.model.authorityOptions.metadata, this.model.vocabularyOptions.metadata,
'', '',
this.model.maxOptions, this.model.maxOptions,
1); 1);
this.authorityService.getEntriesByName(this.searchOptions).pipe( this.vocabularyService.getVocabularyEntries(this.searchOptions).pipe(
catchError(() => { getFirstSucceededRemoteDataPayload(),
const emptyResult = new IntegrationData( catchError(() => observableOf(new PaginatedList(
new PageInfo(), new PageInfo(),
[] []
); ))
return observableOf(emptyResult); ))
}), .subscribe((list: PaginatedList<VocabularyEntry>) => {
first()) this.optionsList = list.page;
.subscribe((object: IntegrationData) => {
this.optionsList = object.payload;
if (this.model.value) { if (this.model.value) {
this.setCurrentValue(this.model.value); this.setCurrentValue(this.model.value);
} }
this.pageInfo = object.pageInfo; this.pageInfo = list.pageInfo;
this.cdr.detectChanges(); this.cdr.detectChanges();
}); });
@@ -80,7 +79,7 @@ export class DsDynamicScrollableDropdownComponent extends DynamicFormControlComp
} }
inputFormatter = (x: AuthorityValue): string => x.display || x.value; inputFormatter = (x: VocabularyEntry): string => x.display || x.value;
openDropdown(sdRef: NgbDropdown) { openDropdown(sdRef: NgbDropdown) {
if (!this.model.readOnly) { if (!this.model.readOnly) {
@@ -92,18 +91,17 @@ export class DsDynamicScrollableDropdownComponent extends DynamicFormControlComp
if (!this.loading && this.pageInfo.currentPage <= this.pageInfo.totalPages) { if (!this.loading && this.pageInfo.currentPage <= this.pageInfo.totalPages) {
this.loading = true; this.loading = true;
this.searchOptions.currentPage++; this.searchOptions.currentPage++;
this.authorityService.getEntriesByName(this.searchOptions).pipe( this.vocabularyService.getVocabularyEntries(this.searchOptions).pipe(
catchError(() => { getFirstSucceededRemoteDataPayload(),
const emptyResult = new IntegrationData( catchError(() => observableOf(new PaginatedList(
new PageInfo(), new PageInfo(),
[] []
); ))
return observableOf(emptyResult); ),
}),
tap(() => this.loading = false)) tap(() => this.loading = false))
.subscribe((object: IntegrationData) => { .subscribe((list: PaginatedList<VocabularyEntry>) => {
this.optionsList = this.optionsList.concat(object.payload); this.optionsList = this.optionsList.concat(list.page);
this.pageInfo = object.pageInfo; this.pageInfo = list.pageInfo;
this.cdr.detectChanges(); this.cdr.detectChanges();
}) })
} }

View File

@@ -1,11 +1,11 @@
import { AUTOCOMPLETE_OFF, DynamicFormControlLayout, serializable } from '@ng-dynamic-forms/core'; import { AUTOCOMPLETE_OFF, DynamicFormControlLayout, serializable } from '@ng-dynamic-forms/core';
import { DsDynamicInputModel, DsDynamicInputModelConfig } from '../ds-dynamic-input.model'; import { DsDynamicInputModel, DsDynamicInputModelConfig } from '../ds-dynamic-input.model';
import { AuthorityOptions } from '../../../../../../core/integration/models/authority-options.model'; import { VocabularyOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-options.model';
export const DYNAMIC_FORM_CONTROL_TYPE_SCROLLABLE_DROPDOWN = 'SCROLLABLE_DROPDOWN'; export const DYNAMIC_FORM_CONTROL_TYPE_SCROLLABLE_DROPDOWN = 'SCROLLABLE_DROPDOWN';
export interface DynamicScrollableDropdownModelConfig extends DsDynamicInputModelConfig { export interface DynamicScrollableDropdownModelConfig extends DsDynamicInputModelConfig {
authorityOptions: AuthorityOptions; vocabularyOptions: VocabularyOptions;
maxOptions?: number; maxOptions?: number;
value?: any; value?: any;
} }
@@ -20,7 +20,7 @@ export class DynamicScrollableDropdownModel extends DsDynamicInputModel {
super(config, layout); super(config, layout);
this.autoComplete = AUTOCOMPLETE_OFF; this.autoComplete = AUTOCOMPLETE_OFF;
this.authorityOptions = config.authorityOptions; this.vocabularyOptions = config.vocabularyOptions;
this.maxOptions = config.maxOptions || 10; this.maxOptions = config.maxOptions || 10;
} }

View File

@@ -12,15 +12,14 @@ import {
import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap'; import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap';
import { NgbModule, NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap'; import { NgbModule, NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap';
import { AuthorityOptions } from '../../../../../../core/integration/models/authority-options.model'; import { VocabularyOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-options.model';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
import { AuthorityServiceStub } from '../../../../../testing/authority-service.stub'; import { VocabularyServiceStub } from '../../../../../testing/vocabulary-service.stub';
import { DsDynamicTagComponent } from './dynamic-tag.component'; import { DsDynamicTagComponent } from './dynamic-tag.component';
import { DynamicTagModel } from './dynamic-tag.model'; import { DynamicTagModel } from './dynamic-tag.model';
import { GlobalConfig } from '../../../../../../../config/global-config.interface';
import { Chips } from '../../../../../chips/models/chips.model'; import { Chips } from '../../../../../chips/models/chips.model';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value'; import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model';
import { createTestComponent } from '../../../../../testing/utils.test'; import { createTestComponent } from '../../../../../testing/utils.test';
function createKeyUpEvent(key: number) { function createKeyUpEvent(key: number) {
@@ -45,12 +44,12 @@ function init() {
}); });
TAG_TEST_MODEL_CONFIG = { TAG_TEST_MODEL_CONFIG = {
authorityOptions: { vocabularyOptions: {
closed: false, closed: false,
metadata: 'tag', metadata: 'tag',
name: 'common_iso_languages', name: 'common_iso_languages',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions, } as VocabularyOptions,
disabled: false, disabled: false,
id: 'tag', id: 'tag',
label: 'Keywords', label: 'Keywords',
@@ -75,7 +74,7 @@ describe('DsDynamicTagComponent test suite', () => {
// async beforeEach // async beforeEach
beforeEach(async(() => { beforeEach(async(() => {
const authorityServiceStub = new AuthorityServiceStub(); const vocabularyServiceStub = new VocabularyServiceStub();
init(); init();
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
@@ -92,7 +91,7 @@ describe('DsDynamicTagComponent test suite', () => {
providers: [ providers: [
ChangeDetectorRef, ChangeDetectorRef,
DsDynamicTagComponent, DsDynamicTagComponent,
{ provide: AuthorityService, useValue: authorityServiceStub }, { provide: VocabularyService, useValue: vocabularyServiceStub },
{ provide: DynamicFormLayoutService, useValue: {} }, { provide: DynamicFormLayoutService, useValue: {} },
{ provide: DynamicFormValidationService, useValue: {} } { provide: DynamicFormValidationService, useValue: {} }
], ],
@@ -124,7 +123,7 @@ describe('DsDynamicTagComponent test suite', () => {
})); }));
}); });
describe('when authorityOptions are set', () => { describe('when vocabularyOptions are set', () => {
describe('and init model value is empty', () => { describe('and init model value is empty', () => {
beforeEach(() => { beforeEach(() => {
@@ -148,20 +147,20 @@ describe('DsDynamicTagComponent test suite', () => {
}); });
it('should search when 3+ characters typed', fakeAsync(() => { it('should search when 3+ characters typed', fakeAsync(() => {
spyOn((tagComp as any).authorityService, 'getEntriesByName').and.callThrough(); spyOn((tagComp as any).vocabularyService, 'getVocabularyEntries').and.callThrough();
tagComp.search(observableOf('test')).subscribe(() => { tagComp.search(observableOf('test')).subscribe(() => {
expect((tagComp as any).authorityService.getEntriesByName).toHaveBeenCalled(); expect((tagComp as any).vocabularyService.getVocabularyEntries).toHaveBeenCalled();
}); });
})); }));
it('should select a results entry properly', fakeAsync(() => { it('should select a results entry properly', fakeAsync(() => {
modelValue = [ modelValue = [
Object.assign(new AuthorityValue(), { id: 1, display: 'Name, Lastname', value: 1 }) Object.assign(new VocabularyEntry(), { authority: 1, display: 'Name, Lastname', value: 1 })
]; ];
const event: NgbTypeaheadSelectItemEvent = { const event: NgbTypeaheadSelectItemEvent = {
item: Object.assign(new AuthorityValue(), { item: Object.assign(new VocabularyEntry(), {
id: 1, authority: 1,
display: 'Name, Lastname', display: 'Name, Lastname',
value: 1 value: 1
}), }),
@@ -239,7 +238,7 @@ describe('DsDynamicTagComponent test suite', () => {
}); });
describe('when authorityOptions are not set', () => { describe('when vocabularyOptions are not set', () => {
describe('and init model value is empty', () => { describe('and init model value is empty', () => {
beforeEach(() => { beforeEach(() => {
@@ -247,7 +246,7 @@ describe('DsDynamicTagComponent test suite', () => {
tagComp = tagFixture.componentInstance; // FormComponent test instance tagComp = tagFixture.componentInstance; // FormComponent test instance
tagComp.group = TAG_TEST_GROUP; tagComp.group = TAG_TEST_GROUP;
const config = TAG_TEST_MODEL_CONFIG; const config = TAG_TEST_MODEL_CONFIG;
config.authorityOptions = null; config.vocabularyOptions = null;
tagComp.model = new DynamicTagModel(config); tagComp.model = new DynamicTagModel(config);
tagFixture.detectChanges(); tagFixture.detectChanges();
}); });

View File

@@ -1,4 +1,4 @@
import { ChangeDetectorRef, Component, EventEmitter, Inject, Input, OnInit, Output, ViewChild } from '@angular/core'; import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { import {
@@ -6,17 +6,21 @@ import {
DynamicFormLayoutService, DynamicFormLayoutService,
DynamicFormValidationService DynamicFormValidationService
} from '@ng-dynamic-forms/core'; } from '@ng-dynamic-forms/core';
import { of as observableOf, Observable } from 'rxjs'; import { Observable, of as observableOf } from 'rxjs';
import { catchError, debounceTime, distinctUntilChanged, tap, switchMap, map, merge } from 'rxjs/operators'; import { catchError, debounceTime, distinctUntilChanged, map, merge, switchMap, tap } from 'rxjs/operators';
import { NgbTypeahead, NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap'; import { NgbTypeahead, NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap';
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
import { DynamicTagModel } from './dynamic-tag.model'; import { DynamicTagModel } from './dynamic-tag.model';
import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model'; import { VocabularyFindOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-find-options.model';
import { Chips } from '../../../../../chips/models/chips.model'; import { Chips } from '../../../../../chips/models/chips.model';
import { hasValue, isNotEmpty } from '../../../../../empty.util'; import { hasValue, isNotEmpty } from '../../../../../empty.util';
import { environment } from '../../../../../../../environments/environment'; import { environment } from '../../../../../../../environments/environment';
import { getFirstSucceededRemoteDataPayload } from '../../../../../../core/shared/operators';
import { PaginatedList } from '../../../../../../core/data/paginated-list';
import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model';
import { PageInfo } from '../../../../../../core/shared/page-info.model';
@Component({ @Component({
selector: 'ds-dynamic-tag', selector: 'ds-dynamic-tag',
@@ -32,17 +36,25 @@ export class DsDynamicTagComponent extends DynamicFormControlComponent implement
@Output() change: EventEmitter<any> = new EventEmitter<any>(); @Output() change: EventEmitter<any> = new EventEmitter<any>();
@Output() focus: EventEmitter<any> = new EventEmitter<any>(); @Output() focus: EventEmitter<any> = new EventEmitter<any>();
@ViewChild('instance', {static: false}) instance: NgbTypeahead; @ViewChild('instance', { static: false }) instance: NgbTypeahead;
chips: Chips; chips: Chips;
hasAuthority: boolean; hasAuthority: boolean;
searching = false; searching = false;
searchOptions: IntegrationSearchOptions; searchOptions: VocabularyFindOptions;
searchFailed = false; searchFailed = false;
hideSearchingWhenUnsubscribed = new Observable(() => () => this.changeSearchingStatus(false)); hideSearchingWhenUnsubscribed = new Observable(() => () => this.changeSearchingStatus(false));
currentValue: any; currentValue: any;
constructor(private vocabularyService: VocabularyService,
private cdr: ChangeDetectorRef,
protected layoutService: DynamicFormLayoutService,
protected validationService: DynamicFormValidationService
) {
super(layoutService, validationService);
}
formatter = (x: { display: string }) => x.display; formatter = (x: { display: string }) => x.display;
search = (text$: Observable<string>) => search = (text$: Observable<string>) =>
@@ -52,44 +64,33 @@ export class DsDynamicTagComponent extends DynamicFormControlComponent implement
tap(() => this.changeSearchingStatus(true)), tap(() => this.changeSearchingStatus(true)),
switchMap((term) => { switchMap((term) => {
if (term === '' || term.length < this.model.minChars) { if (term === '' || term.length < this.model.minChars) {
return observableOf({list: []}); return observableOf({ list: [] });
} else { } else {
this.searchOptions.query = term; this.searchOptions.query = term;
return this.authorityService.getEntriesByName(this.searchOptions).pipe( return this.vocabularyService.getVocabularyEntries(this.searchOptions).pipe(
map((authorities) => { getFirstSucceededRemoteDataPayload(),
// @TODO Pagination for authority is not working, to refactor when it will be fixed
return {
list: authorities.payload,
pageInfo: authorities.pageInfo
};
}),
tap(() => this.searchFailed = false), tap(() => this.searchFailed = false),
catchError(() => { catchError(() => {
this.searchFailed = true; this.searchFailed = true;
return observableOf({list: []}); return observableOf(new PaginatedList(
new PageInfo(),
[]
));
})); }));
} }
}), }),
map((results) => results.list), map((list: PaginatedList<VocabularyEntry>) => list.page),
tap(() => this.changeSearchingStatus(false)), tap(() => this.changeSearchingStatus(false)),
merge(this.hideSearchingWhenUnsubscribed)); merge(this.hideSearchingWhenUnsubscribed));
constructor(private authorityService: AuthorityService,
private cdr: ChangeDetectorRef,
protected layoutService: DynamicFormLayoutService,
protected validationService: DynamicFormValidationService
) {
super(layoutService, validationService);
}
ngOnInit() { ngOnInit() {
this.hasAuthority = this.model.authorityOptions && hasValue(this.model.authorityOptions.name); this.hasAuthority = this.model.vocabularyOptions && hasValue(this.model.vocabularyOptions.name);
if (this.hasAuthority) { if (this.hasAuthority) {
this.searchOptions = new IntegrationSearchOptions( this.searchOptions = new VocabularyFindOptions(
this.model.authorityOptions.scope, this.model.vocabularyOptions.scope,
this.model.authorityOptions.name, this.model.vocabularyOptions.name,
this.model.authorityOptions.metadata); this.model.vocabularyOptions.metadata);
} }
this.chips = new Chips( this.chips = new Chips(
@@ -166,7 +167,7 @@ export class DsDynamicTagComponent extends DynamicFormControlComponent implement
} }
private addTagsToChips() { private addTagsToChips() {
if (hasValue(this.currentValue) && (!this.hasAuthority || !this.model.authorityOptions.closed)) { if (hasValue(this.currentValue) && (!this.hasAuthority || !this.model.vocabularyOptions.closed)) {
let res: string[] = []; let res: string[] = [];
res = this.currentValue.split(','); res = this.currentValue.split(',');

View File

@@ -10,10 +10,9 @@ import { DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormValidation
import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap'; import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { AuthorityOptions } from '../../../../../../core/integration/models/authority-options.model'; import { VocabularyOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-options.model';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
import { AuthorityServiceStub } from '../../../../../testing/authority-service.stub'; import { VocabularyServiceStub } from '../../../../../testing/vocabulary-service.stub';
import { GlobalConfig } from '../../../../../../../config/global-config.interface';
import { DsDynamicTypeaheadComponent } from './dynamic-typeahead.component'; import { DsDynamicTypeaheadComponent } from './dynamic-typeahead.component';
import { DynamicTypeaheadModel } from './dynamic-typeahead.model'; import { DynamicTypeaheadModel } from './dynamic-typeahead.model';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
@@ -31,12 +30,12 @@ function init() {
}); });
TYPEAHEAD_TEST_MODEL_CONFIG = { TYPEAHEAD_TEST_MODEL_CONFIG = {
authorityOptions: { vocabularyOptions: {
closed: false, closed: false,
metadata: 'typeahead', metadata: 'typeahead',
name: 'EVENTAuthority', name: 'EVENTAuthority',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions, } as VocabularyOptions,
disabled: false, disabled: false,
id: 'typeahead', id: 'typeahead',
label: 'Conference', label: 'Conference',
@@ -49,6 +48,7 @@ function init() {
value: undefined value: undefined
}; };
} }
describe('DsDynamicTypeaheadComponent test suite', () => { describe('DsDynamicTypeaheadComponent test suite', () => {
let testComp: TestComponent; let testComp: TestComponent;
@@ -59,7 +59,7 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
// async beforeEach // async beforeEach
beforeEach(async(() => { beforeEach(async(() => {
const authorityServiceStub = new AuthorityServiceStub(); const vocabularyServiceStub = new VocabularyServiceStub();
init(); init();
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
@@ -79,7 +79,7 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
providers: [ providers: [
ChangeDetectorRef, ChangeDetectorRef,
DsDynamicTypeaheadComponent, DsDynamicTypeaheadComponent,
{ provide: AuthorityService, useValue: authorityServiceStub }, { provide: VocabularyService, useValue: vocabularyServiceStub },
{ provide: DynamicFormLayoutService, useValue: {} }, { provide: DynamicFormLayoutService, useValue: {} },
{ provide: DynamicFormValidationService, useValue: {} } { provide: DynamicFormValidationService, useValue: {} }
], ],
@@ -134,17 +134,17 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
it('should search when 3+ characters typed', fakeAsync(() => { it('should search when 3+ characters typed', fakeAsync(() => {
spyOn((typeaheadComp as any).authorityService, 'getEntriesByName').and.callThrough(); spyOn((typeaheadComp as any).vocabularyService, 'getVocabularyEntries').and.callThrough();
typeaheadComp.search(observableOf('test')).subscribe(); typeaheadComp.search(observableOf('test')).subscribe();
tick(300); tick(300);
typeaheadFixture.detectChanges(); typeaheadFixture.detectChanges();
expect((typeaheadComp as any).authorityService.getEntriesByName).toHaveBeenCalled(); expect((typeaheadComp as any).vocabularyService.getVocabularyEntries).toHaveBeenCalled();
})); }));
it('should set model.value on input type when AuthorityOptions.closed is false', () => { it('should set model.value on input type when VocabularyOptions.closed is false', () => {
const inputDe = typeaheadFixture.debugElement.query(By.css('input.form-control')); const inputDe = typeaheadFixture.debugElement.query(By.css('input.form-control'));
const inputElement = inputDe.nativeElement; const inputElement = inputDe.nativeElement;
@@ -155,8 +155,8 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
}); });
it('should not set model.value on input type when AuthorityOptions.closed is true', () => { it('should not set model.value on input type when VocabularyOptions.closed is true', () => {
typeaheadComp.model.authorityOptions.closed = true; typeaheadComp.model.vocabularyOptions.closed = true;
typeaheadFixture.detectChanges(); typeaheadFixture.detectChanges();
const inputDe = typeaheadFixture.debugElement.query(By.css('input.form-control')); const inputDe = typeaheadFixture.debugElement.query(By.css('input.form-control'));
const inputElement = inputDe.nativeElement; const inputElement = inputDe.nativeElement;
@@ -184,18 +184,18 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
expect(typeaheadComp.blur.emit).not.toHaveBeenCalled(); expect(typeaheadComp.blur.emit).not.toHaveBeenCalled();
}); });
it('should emit change Event onBlur when AuthorityOptions.closed is false and inputValue is changed', () => { it('should emit change Event onBlur when VocabularyOptions.closed is false and inputValue is changed', () => {
typeaheadComp.inputValue = 'test value'; typeaheadComp.inputValue = 'test value';
typeaheadFixture.detectChanges(); typeaheadFixture.detectChanges();
spyOn(typeaheadComp.blur, 'emit'); spyOn(typeaheadComp.blur, 'emit');
spyOn(typeaheadComp.change, 'emit'); spyOn(typeaheadComp.change, 'emit');
spyOn(typeaheadComp.instance, 'isPopupOpen').and.returnValue(false); spyOn(typeaheadComp.instance, 'isPopupOpen').and.returnValue(false);
typeaheadComp.onBlur(new Event('blur', )); typeaheadComp.onBlur(new Event('blur',));
expect(typeaheadComp.change.emit).toHaveBeenCalled(); expect(typeaheadComp.change.emit).toHaveBeenCalled();
expect(typeaheadComp.blur.emit).toHaveBeenCalled(); expect(typeaheadComp.blur.emit).toHaveBeenCalled();
}); });
it('should not emit change Event onBlur when AuthorityOptions.closed is false and inputValue is not changed', () => { it('should not emit change Event onBlur when VocabularyOptions.closed is false and inputValue is not changed', () => {
typeaheadComp.inputValue = 'test value'; typeaheadComp.inputValue = 'test value';
typeaheadComp.model = new DynamicTypeaheadModel(TYPEAHEAD_TEST_MODEL_CONFIG); typeaheadComp.model = new DynamicTypeaheadModel(TYPEAHEAD_TEST_MODEL_CONFIG);
(typeaheadComp.model as any).value = 'test value'; (typeaheadComp.model as any).value = 'test value';
@@ -203,12 +203,12 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
spyOn(typeaheadComp.blur, 'emit'); spyOn(typeaheadComp.blur, 'emit');
spyOn(typeaheadComp.change, 'emit'); spyOn(typeaheadComp.change, 'emit');
spyOn(typeaheadComp.instance, 'isPopupOpen').and.returnValue(false); spyOn(typeaheadComp.instance, 'isPopupOpen').and.returnValue(false);
typeaheadComp.onBlur(new Event('blur', )); typeaheadComp.onBlur(new Event('blur',));
expect(typeaheadComp.change.emit).not.toHaveBeenCalled(); expect(typeaheadComp.change.emit).not.toHaveBeenCalled();
expect(typeaheadComp.blur.emit).toHaveBeenCalled(); expect(typeaheadComp.blur.emit).toHaveBeenCalled();
}); });
it('should not emit change Event onBlur when AuthorityOptions.closed is false and inputValue is null', () => { it('should not emit change Event onBlur when VocabularyOptions.closed is false and inputValue is null', () => {
typeaheadComp.inputValue = null; typeaheadComp.inputValue = null;
typeaheadComp.model = new DynamicTypeaheadModel(TYPEAHEAD_TEST_MODEL_CONFIG); typeaheadComp.model = new DynamicTypeaheadModel(TYPEAHEAD_TEST_MODEL_CONFIG);
(typeaheadComp.model as any).value = 'test value'; (typeaheadComp.model as any).value = 'test value';
@@ -216,7 +216,7 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
spyOn(typeaheadComp.blur, 'emit'); spyOn(typeaheadComp.blur, 'emit');
spyOn(typeaheadComp.change, 'emit'); spyOn(typeaheadComp.change, 'emit');
spyOn(typeaheadComp.instance, 'isPopupOpen').and.returnValue(false); spyOn(typeaheadComp.instance, 'isPopupOpen').and.returnValue(false);
typeaheadComp.onBlur(new Event('blur', )); typeaheadComp.onBlur(new Event('blur',));
expect(typeaheadComp.change.emit).not.toHaveBeenCalled(); expect(typeaheadComp.change.emit).not.toHaveBeenCalled();
expect(typeaheadComp.blur.emit).toHaveBeenCalled(); expect(typeaheadComp.blur.emit).toHaveBeenCalled();
}); });

View File

@@ -10,12 +10,16 @@ import { catchError, debounceTime, distinctUntilChanged, filter, map, merge, swi
import { Observable, of as observableOf, Subject } from 'rxjs'; import { Observable, of as observableOf, Subject } from 'rxjs';
import { NgbTypeahead, NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap'; import { NgbTypeahead, NgbTypeaheadSelectItemEvent } from '@ng-bootstrap/ng-bootstrap';
import { AuthorityService } from '../../../../../../core/integration/authority.service'; import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
import { DynamicTypeaheadModel } from './dynamic-typeahead.model'; import { DynamicTypeaheadModel } from './dynamic-typeahead.model';
import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model'; import { VocabularyFindOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-find-options.model';
import { isEmpty, isNotEmpty, isNotNull } from '../../../../../empty.util'; import { isEmpty, isNotEmpty, isNotNull } from '../../../../../empty.util';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { ConfidenceType } from '../../../../../../core/integration/models/confidence-type'; import { ConfidenceType } from '../../../../../../core/shared/confidence-type';
import { getFirstSucceededRemoteDataPayload } from '../../../../../../core/shared/operators';
import { PaginatedList } from '../../../../../../core/data/paginated-list';
import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model';
import { PageInfo } from '../../../../../../core/shared/page-info.model';
@Component({ @Component({
selector: 'ds-dynamic-typeahead', selector: 'ds-dynamic-typeahead',
@@ -31,16 +35,24 @@ export class DsDynamicTypeaheadComponent extends DynamicFormControlComponent imp
@Output() change: EventEmitter<any> = new EventEmitter<any>(); @Output() change: EventEmitter<any> = new EventEmitter<any>();
@Output() focus: EventEmitter<any> = new EventEmitter<any>(); @Output() focus: EventEmitter<any> = new EventEmitter<any>();
@ViewChild('instance', {static: false}) instance: NgbTypeahead; @ViewChild('instance', { static: false }) instance: NgbTypeahead;
searching = false; searching = false;
searchOptions: IntegrationSearchOptions; searchOptions: VocabularyFindOptions;
searchFailed = false; searchFailed = false;
hideSearchingWhenUnsubscribed$ = new Observable(() => () => this.changeSearchingStatus(false)); hideSearchingWhenUnsubscribed$ = new Observable(() => () => this.changeSearchingStatus(false));
click$ = new Subject<string>(); click$ = new Subject<string>();
currentValue: any; currentValue: any;
inputValue: any; inputValue: any;
constructor(private vocabularyService: VocabularyService,
private cdr: ChangeDetectorRef,
protected layoutService: DynamicFormLayoutService,
protected validationService: DynamicFormValidationService
) {
super(layoutService, validationService);
}
formatter = (x: { display: string }) => { formatter = (x: { display: string }) => {
return (typeof x === 'object') ? x.display : x return (typeof x === 'object') ? x.display : x
}; };
@@ -53,44 +65,33 @@ export class DsDynamicTypeaheadComponent extends DynamicFormControlComponent imp
tap(() => this.changeSearchingStatus(true)), tap(() => this.changeSearchingStatus(true)),
switchMap((term) => { switchMap((term) => {
if (term === '' || term.length < this.model.minChars) { if (term === '' || term.length < this.model.minChars) {
return observableOf({list: []}); return observableOf({ list: [] });
} else { } else {
this.searchOptions.query = term; this.searchOptions.query = term;
return this.authorityService.getEntriesByName(this.searchOptions).pipe( return this.vocabularyService.getVocabularyEntries(this.searchOptions).pipe(
map((authorities) => { getFirstSucceededRemoteDataPayload(),
// @TODO Pagination for authority is not working, to refactor when it will be fixed
return {
list: authorities.payload,
pageInfo: authorities.pageInfo
};
}),
tap(() => this.searchFailed = false), tap(() => this.searchFailed = false),
catchError(() => { catchError(() => {
this.searchFailed = true; this.searchFailed = true;
return observableOf({list: []}); return observableOf(new PaginatedList(
new PageInfo(),
[]
));
})); }));
} }
}), }),
map((results) => results.list), map((list: PaginatedList<VocabularyEntry>) => list.page),
tap(() => this.changeSearchingStatus(false)), tap(() => this.changeSearchingStatus(false)),
merge(this.hideSearchingWhenUnsubscribed$) merge(this.hideSearchingWhenUnsubscribed$)
) )
}; };
constructor(private authorityService: AuthorityService,
private cdr: ChangeDetectorRef,
protected layoutService: DynamicFormLayoutService,
protected validationService: DynamicFormValidationService
) {
super(layoutService, validationService);
}
ngOnInit() { ngOnInit() {
this.currentValue = this.model.value; this.currentValue = this.model.value;
this.searchOptions = new IntegrationSearchOptions( this.searchOptions = new VocabularyFindOptions(
this.model.authorityOptions.scope, this.model.vocabularyOptions.scope,
this.model.authorityOptions.name, this.model.vocabularyOptions.name,
this.model.authorityOptions.metadata); this.model.vocabularyOptions.metadata);
this.group.get(this.model.id).valueChanges.pipe( this.group.get(this.model.id).valueChanges.pipe(
filter((value) => this.currentValue !== value)) filter((value) => this.currentValue !== value))
.subscribe((value) => { .subscribe((value) => {
@@ -104,14 +105,14 @@ export class DsDynamicTypeaheadComponent extends DynamicFormControlComponent imp
} }
onInput(event) { onInput(event) {
if (!this.model.authorityOptions.closed && isNotEmpty(event.target.value)) { if (!this.model.vocabularyOptions.closed && isNotEmpty(event.target.value)) {
this.inputValue = new FormFieldMetadataValueObject(event.target.value); this.inputValue = new FormFieldMetadataValueObject(event.target.value);
} }
} }
onBlur(event: Event) { onBlur(event: Event) {
if (!this.instance.isPopupOpen()) { if (!this.instance.isPopupOpen()) {
if (!this.model.authorityOptions.closed && isNotEmpty(this.inputValue)) { if (!this.model.vocabularyOptions.closed && isNotEmpty(this.inputValue)) {
if (isNotNull(this.inputValue) && this.model.value !== this.inputValue) { if (isNotNull(this.inputValue) && this.model.value !== this.inputValue) {
this.model.valueUpdates.next(this.inputValue); this.model.valueUpdates.next(this.inputValue);
this.change.emit(this.inputValue); this.change.emit(this.inputValue);

View File

@@ -36,7 +36,7 @@ import { DynamicLookupModel } from './ds-dynamic-form-ui/models/lookup/dynamic-l
import { DynamicDsDatePickerModel } from './ds-dynamic-form-ui/models/date-picker/date-picker.model'; import { DynamicDsDatePickerModel } from './ds-dynamic-form-ui/models/date-picker/date-picker.model';
import { DynamicTypeaheadModel } from './ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.model'; import { DynamicTypeaheadModel } from './ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.model';
import { DynamicListRadioGroupModel } from './ds-dynamic-form-ui/models/list/dynamic-list-radio-group.model'; import { DynamicListRadioGroupModel } from './ds-dynamic-form-ui/models/list/dynamic-list-radio-group.model';
import { AuthorityOptions } from '../../../core/integration/models/authority-options.model'; import { VocabularyOptions } from '../../../core/submission/vocabularies/models/vocabulary-options.model';
import { FormFieldModel } from './models/form-field.model'; import { FormFieldModel } from './models/form-field.model';
import { import {
SubmissionFormsModel SubmissionFormsModel
@@ -78,7 +78,7 @@ describe('FormBuilderService test suite', () => {
] ]
}); });
const authorityOptions: AuthorityOptions = { const vocabularyOptions: VocabularyOptions = {
closed: false, closed: false,
metadata: 'list', metadata: 'list',
name: 'type_programme', name: 'type_programme',
@@ -197,13 +197,13 @@ describe('FormBuilderService test suite', () => {
new DynamicTypeaheadModel({id: 'testTypeahead', repeatable: false, metadataFields: [], submissionId: '1234'}), new DynamicTypeaheadModel({id: 'testTypeahead', repeatable: false, metadataFields: [], submissionId: '1234'}),
new DynamicScrollableDropdownModel({id: 'testScrollableDropdown', authorityOptions: authorityOptions, repeatable: false, metadataFields: [], submissionId: '1234'}), new DynamicScrollableDropdownModel({id: 'testScrollableDropdown', vocabularyOptions: vocabularyOptions, repeatable: false, metadataFields: [], submissionId: '1234'}),
new DynamicTagModel({id: 'testTag', repeatable: false, metadataFields: [], submissionId: '1234'}), new DynamicTagModel({id: 'testTag', repeatable: false, metadataFields: [], submissionId: '1234'}),
new DynamicListCheckboxGroupModel({id: 'testCheckboxList', authorityOptions: authorityOptions, repeatable: true}), new DynamicListCheckboxGroupModel({id: 'testCheckboxList', vocabularyOptions: vocabularyOptions, repeatable: true}),
new DynamicListRadioGroupModel({id: 'testRadioList', authorityOptions: authorityOptions, repeatable: false}), new DynamicListRadioGroupModel({id: 'testRadioList', vocabularyOptions: vocabularyOptions, repeatable: false}),
new DynamicRelationGroupModel({ new DynamicRelationGroupModel({
submissionId, submissionId,
@@ -218,7 +218,7 @@ describe('FormBuilderService test suite', () => {
mandatoryMessage: 'Required field!', mandatoryMessage: 'Required field!',
repeatable: false, repeatable: false,
selectableMetadata: [{ selectableMetadata: [{
authority: 'RPAuthority', controlledVocabulary: 'RPAuthority',
closed: false, closed: false,
metadata: 'dc.contributor.author' metadata: 'dc.contributor.author'
}], }],
@@ -232,7 +232,7 @@ describe('FormBuilderService test suite', () => {
mandatory: 'false', mandatory: 'false',
repeatable: false, repeatable: false,
selectableMetadata: [{ selectableMetadata: [{
authority: 'OUAuthority', controlledVocabulary: 'OUAuthority',
closed: false, closed: false,
metadata: 'local.contributor.affiliation' metadata: 'local.contributor.affiliation'
}] }]
@@ -284,7 +284,7 @@ describe('FormBuilderService test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'journal', metadata: 'journal',
authority: 'JOURNALAuthority', controlledVocabulary: 'JOURNALAuthority',
closed: false closed: false
} }
], ],
@@ -364,7 +364,7 @@ describe('FormBuilderService test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'conference', metadata: 'conference',
authority: 'EVENTAuthority', controlledVocabulary: 'EVENTAuthority',
closed: false closed: false
} }
], ],

View File

@@ -1,5 +1,5 @@
import { isEmpty, isNotEmpty, isNotNull } from '../../../empty.util'; import { isEmpty, isNotEmpty, isNotNull } from '../../../empty.util';
import { ConfidenceType } from '../../../../core/integration/models/confidence-type'; import { ConfidenceType } from '../../../../core/shared/confidence-type';
import { PLACEHOLDER_PARENT_METADATA } from '../ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model'; import { PLACEHOLDER_PARENT_METADATA } from '../ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
import { MetadataValueInterface } from '../../../../core/shared/metadata.models'; import { MetadataValueInterface } from '../../../../core/shared/metadata.models';
@@ -7,15 +7,16 @@ export interface OtherInformation {
[name: string]: string [name: string]: string
} }
/**
* A class representing a specific input-form field's value
*/
export class FormFieldMetadataValueObject implements MetadataValueInterface { export class FormFieldMetadataValueObject implements MetadataValueInterface {
metadata?: string;
value: any; value: any;
display: string; display: string;
language: any; language: any;
authority: string; authority: string;
confidence: ConfidenceType; confidence: ConfidenceType;
place: number; place: number;
closed: boolean;
label: string; label: string;
otherInformation: OtherInformation; otherInformation: OtherInformation;
@@ -42,9 +43,6 @@ export class FormFieldMetadataValueObject implements MetadataValueInterface {
} }
this.place = place; this.place = place;
if (isNotEmpty(metadata)) {
this.metadata = metadata;
}
this.otherInformation = otherInformation; this.otherInformation = otherInformation;
} }

View File

@@ -1,50 +1,121 @@
import { autoserialize } from 'cerialize'; import { autoserialize } from 'cerialize';
import { LanguageCode } from './form-field-language-value.model'; import { LanguageCode } from './form-field-language-value.model';
import { FormFieldMetadataValueObject } from './form-field-metadata-value.model';
import { RelationshipOptions } from './relationship-options.model'; import { RelationshipOptions } from './relationship-options.model';
import { FormRowModel } from '../../../../core/config/models/config-submission-form.model'; import { FormRowModel } from '../../../../core/config/models/config-submission-form.model';
/**
* Representing SelectableMetadata properties
*/
export interface SelectableMetadata {
/**
* The key of the metadata field to use to store the input
*/
metadata: string;
/**
* The label of the metadata field to use to store the input
*/
label: string;
/**
* The name of the controlled vocabulary used to retrieve value for the input see controlled vocabularies
*/
controlledVocabulary: string;
/**
* A boolean representing if value is closely related to the controlled vocabulary entry or not
*/
closed: boolean;
}
/**
* A class representing a specific input-form field
*/
export class FormFieldModel { export class FormFieldModel {
/**
* The hints for this metadata field to display on form
*/
@autoserialize @autoserialize
hints: string; hints: string;
/**
* The label for this metadata field to display on form
*/
@autoserialize @autoserialize
label: string; label: string;
/**
* The languages available for this metadata field to display on form
*/
@autoserialize @autoserialize
languageCodes: LanguageCode[]; languageCodes: LanguageCode[];
/**
* The error message for this metadata field to display on form in case of field is required
*/
@autoserialize @autoserialize
mandatoryMessage: string; mandatoryMessage: string;
/**
* Representing if this metadata field is mandatory or not
*/
@autoserialize @autoserialize
mandatory: string; mandatory: string;
/**
* Representing if this metadata field is repeatable or not
*/
@autoserialize @autoserialize
repeatable: boolean; repeatable: boolean;
/**
* Containing additional properties for this metadata field
*/
@autoserialize @autoserialize
input: { input: {
/**
* Representing the type for this metadata field
*/
type: string; type: string;
/**
* Containing regex to use for field validation
*/
regex?: string; regex?: string;
}; };
/**
* Representing additional vocabulary configuration for this metadata field
*/
@autoserialize @autoserialize
selectableMetadata: FormFieldMetadataValueObject[]; selectableMetadata: SelectableMetadata[];
/**
* Representing additional relationship configuration for this metadata field
*/
@autoserialize @autoserialize
selectableRelationship: RelationshipOptions; selectableRelationship: RelationshipOptions;
@autoserialize @autoserialize
rows: FormRowModel[]; rows: FormRowModel[];
/**
* Representing the scope for this metadata field
*/
@autoserialize @autoserialize
scope: string; scope: string;
/**
* Containing additional css classes for this metadata field to use on form
*/
@autoserialize @autoserialize
style: string; style: string;
/**
* Containing the value for this metadata field
*/
@autoserialize @autoserialize
value: any; value: any;
} }

View File

@@ -12,7 +12,7 @@ describe('DateFieldParser test suite', () => {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: false, readOnly: false,
submissionScope: null, submissionScope: null,
authorityUuid: null collectionUUID: null
}; };
beforeEach(() => { beforeEach(() => {

View File

@@ -12,7 +12,7 @@ describe('DisabledFieldParser test suite', () => {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: false, readOnly: false,
submissionScope: null, submissionScope: null,
authorityUuid: null collectionUUID: null
}; };
beforeEach(() => { beforeEach(() => {

View File

@@ -11,7 +11,7 @@ describe('DropdownFieldParser test suite', () => {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: false, readOnly: false,
submissionScope: 'testScopeUUID', submissionScope: 'testScopeUUID',
authorityUuid: null collectionUUID: null
}; };
beforeEach(() => { beforeEach(() => {
@@ -26,7 +26,7 @@ describe('DropdownFieldParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'type', metadata: 'type',
authority: 'common_types_dataset', controlledVocabulary: 'common_types_dataset',
closed: false closed: false
} }
], ],
@@ -50,7 +50,7 @@ describe('DropdownFieldParser test suite', () => {
}); });
it('should throw when authority is not passed', () => { it('should throw when authority is not passed', () => {
field.selectableMetadata[0].authority = null; field.selectableMetadata[0].controlledVocabulary = null;
const parser = new DropdownFieldParser(submissionId, field, initFormValues, parserOptions); const parser = new DropdownFieldParser(submissionId, field, initFormValues, parserOptions);
expect(() => parser.parse()) expect(() => parser.parse())

View File

@@ -31,8 +31,8 @@ export class DropdownFieldParser extends FieldParser {
const dropdownModelConfig: DynamicScrollableDropdownModelConfig = this.initModel(null, label); const dropdownModelConfig: DynamicScrollableDropdownModelConfig = this.initModel(null, label);
let layout: DynamicFormControlLayout; let layout: DynamicFormControlLayout;
if (isNotEmpty(this.configData.selectableMetadata[0].authority)) { if (isNotEmpty(this.configData.selectableMetadata[0].controlledVocabulary)) {
this.setAuthorityOptions(dropdownModelConfig, this.parserOptions.authorityUuid); this.setVocabularyOptions(dropdownModelConfig, this.parserOptions.collectionUUID);
if (isNotEmpty(fieldValue)) { if (isNotEmpty(fieldValue)) {
dropdownModelConfig.value = fieldValue; dropdownModelConfig.value = fieldValue;
} }
@@ -47,7 +47,7 @@ export class DropdownFieldParser extends FieldParser {
const dropdownModel = new DynamicScrollableDropdownModel(dropdownModelConfig, layout); const dropdownModel = new DynamicScrollableDropdownModel(dropdownModelConfig, layout);
return dropdownModel; return dropdownModel;
} else { } else {
throw Error(`Authority name is not available. Please check the form configuration file.`); throw Error(`Controlled Vocabulary name is not available. Please check the form configuration file.`);
} }
} }
} }

View File

@@ -1,19 +1,20 @@
import { Inject, InjectionToken } from '@angular/core'; import { Inject, InjectionToken } from '@angular/core';
import { hasValue, isNotEmpty, isNotNull, isNotUndefined, isEmpty } from '../../../empty.util';
import { FormFieldModel } from '../models/form-field.model';
import { uniqueId } from 'lodash'; import { uniqueId } from 'lodash';
import { DynamicFormControlLayout } from '@ng-dynamic-forms/core';
import { hasValue, isEmpty, isNotEmpty, isNotNull, isNotUndefined } from '../../../empty.util';
import { FormFieldModel } from '../models/form-field.model';
import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model';
import { import {
DynamicRowArrayModel, DynamicRowArrayModel,
DynamicRowArrayModelConfig DynamicRowArrayModelConfig
} from '../ds-dynamic-form-ui/models/ds-dynamic-row-array-model'; } from '../ds-dynamic-form-ui/models/ds-dynamic-row-array-model';
import { DsDynamicInputModel, DsDynamicInputModelConfig } from '../ds-dynamic-form-ui/models/ds-dynamic-input.model'; import { DsDynamicInputModel, DsDynamicInputModelConfig } from '../ds-dynamic-form-ui/models/ds-dynamic-input.model';
import { DynamicFormControlLayout } from '@ng-dynamic-forms/core';
import { setLayout } from './parser.utils'; import { setLayout } from './parser.utils';
import { AuthorityOptions } from '../../../../core/integration/models/authority-options.model';
import { ParserOptions } from './parser-options'; import { ParserOptions } from './parser-options';
import { RelationshipOptions } from '../models/relationship-options.model'; import { RelationshipOptions } from '../models/relationship-options.model';
import { VocabularyOptions } from '../../../../core/submission/vocabularies/models/vocabulary-options.model';
export const SUBMISSION_ID: InjectionToken<string> = new InjectionToken<string>('submissionId'); export const SUBMISSION_ID: InjectionToken<string> = new InjectionToken<string>('submissionId');
export const CONFIG_DATA: InjectionToken<FormFieldModel> = new InjectionToken<FormFieldModel>('configData'); export const CONFIG_DATA: InjectionToken<FormFieldModel> = new InjectionToken<FormFieldModel>('configData');
@@ -49,7 +50,7 @@ export abstract class FieldParser {
label: this.configData.label, label: this.configData.label,
initialCount: this.getInitArrayIndex(), initialCount: this.getInitArrayIndex(),
notRepeatable: !this.configData.repeatable, notRepeatable: !this.configData.repeatable,
required: JSON.parse( this.configData.mandatory), required: JSON.parse(this.configData.mandatory),
groupFactory: () => { groupFactory: () => {
let model; let model;
if ((arrayCounter === 0)) { if ((arrayCounter === 0)) {
@@ -92,6 +93,52 @@ export abstract class FieldParser {
} }
} }
public setVocabularyOptions(controlModel, scope) {
if (isNotEmpty(this.configData.selectableMetadata) && isNotEmpty(this.configData.selectableMetadata[0].controlledVocabulary)) {
controlModel.vocabularyOptions = new VocabularyOptions(
this.configData.selectableMetadata[0].controlledVocabulary,
this.configData.selectableMetadata[0].metadata,
scope,
this.configData.selectableMetadata[0].closed
)
}
}
public setValues(modelConfig: DsDynamicInputModelConfig, fieldValue: any, forceValueAsObj: boolean = false, groupModel?: boolean) {
if (isNotEmpty(fieldValue)) {
if (groupModel) {
// Array, values is an array
modelConfig.value = this.getInitGroupValues();
if (Array.isArray(modelConfig.value) && modelConfig.value.length > 0 && modelConfig.value[0].language) {
// Array Item has language, ex. AuthorityModel
modelConfig.language = modelConfig.value[0].language;
}
return;
}
if (typeof fieldValue === 'object') {
modelConfig.language = fieldValue.language;
if (forceValueAsObj) {
modelConfig.value = fieldValue;
} else {
modelConfig.value = fieldValue.value;
}
} else {
if (forceValueAsObj) {
// If value isn't an instance of FormFieldMetadataValueObject instantiate it
modelConfig.value = new FormFieldMetadataValueObject(fieldValue);
} else {
if (typeof fieldValue === 'string') {
// Case only string
modelConfig.value = fieldValue;
}
}
}
}
return modelConfig;
}
protected getInitValueCount(index = 0, fieldId?): number { protected getInitValueCount(index = 0, fieldId?): number {
const fieldIds = fieldId || this.getAllFieldIds(); const fieldIds = fieldId || this.getAllFieldIds();
if (isNotEmpty(this.initFormValues) && isNotNull(fieldIds) && fieldIds.length === 1 && this.initFormValues.hasOwnProperty(fieldIds[0])) { if (isNotEmpty(this.initFormValues) && isNotNull(fieldIds) && fieldIds.length === 1 && this.initFormValues.hasOwnProperty(fieldIds[0])) {
@@ -135,7 +182,7 @@ export abstract class FieldParser {
fieldIds.forEach((id) => { fieldIds.forEach((id) => {
if (this.initFormValues.hasOwnProperty(id)) { if (this.initFormValues.hasOwnProperty(id)) {
const valueObj: FormFieldMetadataValueObject = Object.assign(new FormFieldMetadataValueObject(), this.initFormValues[id][innerIndex]); const valueObj: FormFieldMetadataValueObject = Object.assign(new FormFieldMetadataValueObject(), this.initFormValues[id][innerIndex]);
valueObj.metadata = id; // valueObj.metadata = id;
// valueObj.value = this.initFormValues[id][innerIndex]; // valueObj.value = this.initFormValues[id][innerIndex];
values.push(valueObj); values.push(valueObj);
} }
@@ -224,14 +271,6 @@ export abstract class FieldParser {
if (this.configData.languageCodes && this.configData.languageCodes.length > 0) { if (this.configData.languageCodes && this.configData.languageCodes.length > 0) {
(controlModel as DsDynamicInputModel).languageCodes = this.configData.languageCodes; (controlModel as DsDynamicInputModel).languageCodes = this.configData.languageCodes;
} }
/* (controlModel as DsDynamicInputModel).languageCodes = [{
display: 'English',
code: 'en_US'
},
{
display: 'Italian',
code: 'it_IT'
}];*/
return controlModel; return controlModel;
} }
@@ -278,50 +317,4 @@ export abstract class FieldParser {
} }
} }
public setAuthorityOptions(controlModel, authorityUuid) {
if (isNotEmpty(this.configData.selectableMetadata) && isNotEmpty(this.configData.selectableMetadata[0].authority)) {
controlModel.authorityOptions = new AuthorityOptions(
this.configData.selectableMetadata[0].authority,
this.configData.selectableMetadata[0].metadata,
authorityUuid,
this.configData.selectableMetadata[0].closed
)
}
}
public setValues(modelConfig: DsDynamicInputModelConfig, fieldValue: any, forceValueAsObj: boolean = false, groupModel?: boolean) {
if (isNotEmpty(fieldValue)) {
if (groupModel) {
// Array, values is an array
modelConfig.value = this.getInitGroupValues();
if (Array.isArray(modelConfig.value) && modelConfig.value.length > 0 && modelConfig.value[0].language) {
// Array Item has language, ex. AuthorityModel
modelConfig.language = modelConfig.value[0].language;
}
return;
}
if (typeof fieldValue === 'object') {
modelConfig.language = fieldValue.language;
if (forceValueAsObj) {
modelConfig.value = fieldValue;
} else {
modelConfig.value = fieldValue.value;
}
} else {
if (forceValueAsObj) {
// If value isn't an instance of FormFieldMetadataValueObject instantiate it
modelConfig.value = new FormFieldMetadataValueObject(fieldValue);
} else {
if (typeof fieldValue === 'string') {
// Case only string
modelConfig.value = fieldValue;
}
}
}
}
return modelConfig;
}
} }

View File

@@ -13,7 +13,7 @@ describe('ListFieldParser test suite', () => {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: false, readOnly: false,
submissionScope: 'testScopeUUID', submissionScope: 'testScopeUUID',
authorityUuid: null collectionUUID: null
}; };
beforeEach(() => { beforeEach(() => {
@@ -28,7 +28,7 @@ describe('ListFieldParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'type', metadata: 'type',
authority: 'type_programme', controlledVocabulary: 'type_programme',
closed: false closed: false
} }
], ],

View File

@@ -1,19 +1,19 @@
import { FieldParser } from './field-parser'; import { FieldParser } from './field-parser';
import { isNotEmpty } from '../../../empty.util'; import { isNotEmpty } from '../../../empty.util';
import { IntegrationSearchOptions } from '../../../../core/integration/models/integration-options.model'; import { VocabularyFindOptions } from '../../../../core/submission/vocabularies/models/vocabulary-find-options.model';
import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model';
import { DynamicListCheckboxGroupModel } from '../ds-dynamic-form-ui/models/list/dynamic-list-checkbox-group.model'; import { DynamicListCheckboxGroupModel } from '../ds-dynamic-form-ui/models/list/dynamic-list-checkbox-group.model';
import { DynamicListRadioGroupModel } from '../ds-dynamic-form-ui/models/list/dynamic-list-radio-group.model'; import { DynamicListRadioGroupModel } from '../ds-dynamic-form-ui/models/list/dynamic-list-radio-group.model';
export class ListFieldParser extends FieldParser { export class ListFieldParser extends FieldParser {
searchOptions: IntegrationSearchOptions; searchOptions: VocabularyFindOptions;
public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any {
const listModelConfig = this.initModel(null, label); const listModelConfig = this.initModel(null, label);
listModelConfig.repeatable = this.configData.repeatable; listModelConfig.repeatable = this.configData.repeatable;
if (this.configData.selectableMetadata[0].authority if (this.configData.selectableMetadata[0].controlledVocabulary
&& this.configData.selectableMetadata[0].authority.length > 0) { && this.configData.selectableMetadata[0].controlledVocabulary.length > 0) {
if (isNotEmpty(this.getInitGroupValues())) { if (isNotEmpty(this.getInitGroupValues())) {
listModelConfig.value = []; listModelConfig.value = [];
@@ -26,7 +26,7 @@ export class ListFieldParser extends FieldParser {
} }
}); });
} }
this.setAuthorityOptions(listModelConfig, this.parserOptions.authorityUuid); this.setVocabularyOptions(listModelConfig, this.parserOptions.collectionUUID);
} }
let listModel; let listModel;

View File

@@ -12,7 +12,7 @@ describe('LookupFieldParser test suite', () => {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: false, readOnly: false,
submissionScope: 'testScopeUUID', submissionScope: 'testScopeUUID',
authorityUuid: null collectionUUID: null
}; };
beforeEach(() => { beforeEach(() => {
@@ -27,7 +27,7 @@ describe('LookupFieldParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'journal', metadata: 'journal',
authority: 'JOURNALAuthority', controlledVocabulary: 'JOURNALAuthority',
closed: false closed: false
} }
], ],

View File

@@ -5,10 +5,10 @@ import { FormFieldMetadataValueObject } from '../models/form-field-metadata-valu
export class LookupFieldParser extends FieldParser { export class LookupFieldParser extends FieldParser {
public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any {
if (this.configData.selectableMetadata[0].authority) { if (this.configData.selectableMetadata[0].controlledVocabulary) {
const lookupModelConfig: DynamicLookupModelConfig = this.initModel(null, label); const lookupModelConfig: DynamicLookupModelConfig = this.initModel(null, label);
this.setAuthorityOptions(lookupModelConfig, this.parserOptions.authorityUuid); this.setVocabularyOptions(lookupModelConfig, this.parserOptions.collectionUUID);
this.setValues(lookupModelConfig, fieldValue, true); this.setValues(lookupModelConfig, fieldValue, true);

View File

@@ -12,7 +12,7 @@ describe('LookupNameFieldParser test suite', () => {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: false, readOnly: false,
submissionScope: 'testScopeUUID', submissionScope: 'testScopeUUID',
authorityUuid: null collectionUUID: null
}; };
beforeEach(() => { beforeEach(() => {
@@ -27,7 +27,7 @@ describe('LookupNameFieldParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'author', metadata: 'author',
authority: 'RPAuthority', controlledVocabulary: 'RPAuthority',
closed: false closed: false
} }
], ],

View File

@@ -8,10 +8,10 @@ import { FormFieldMetadataValueObject } from '../models/form-field-metadata-valu
export class LookupNameFieldParser extends FieldParser { export class LookupNameFieldParser extends FieldParser {
public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any {
if (this.configData.selectableMetadata[0].authority) { if (this.configData.selectableMetadata[0].controlledVocabulary) {
const lookupModelConfig: DynamicLookupNameModelConfig = this.initModel(null, label); const lookupModelConfig: DynamicLookupNameModelConfig = this.initModel(null, label);
this.setAuthorityOptions(lookupModelConfig, this.parserOptions.authorityUuid); this.setVocabularyOptions(lookupModelConfig, this.parserOptions.collectionUUID);
this.setValues(lookupModelConfig, fieldValue, true); this.setValues(lookupModelConfig, fieldValue, true);

View File

@@ -14,7 +14,7 @@ describe('NameFieldParser test suite', () => {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: false, readOnly: false,
submissionScope: 'testScopeUUID', submissionScope: 'testScopeUUID',
authorityUuid: null collectionUUID: null
}; };
beforeEach(() => { beforeEach(() => {

View File

@@ -15,7 +15,7 @@ describe('OneboxFieldParser test suite', () => {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: false, readOnly: false,
submissionScope: 'testScopeUUID', submissionScope: 'testScopeUUID',
authorityUuid: null collectionUUID: null
}; };
beforeEach(() => { beforeEach(() => {
@@ -28,7 +28,7 @@ describe('OneboxFieldParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'title', metadata: 'title',
authority: 'EVENTAuthority', controlledVocabulary: 'EVENTAuthority',
closed: false closed: false
} }
], ],

View File

@@ -75,9 +75,9 @@ export class OneboxFieldParser extends FieldParser {
inputSelectGroup.group.push(new DsDynamicInputModel(inputModelConfig, clsInput)); inputSelectGroup.group.push(new DsDynamicInputModel(inputModelConfig, clsInput));
return new DynamicQualdropModel(inputSelectGroup, clsGroup); return new DynamicQualdropModel(inputSelectGroup, clsGroup);
} else if (this.configData.selectableMetadata[0].authority) { } else if (this.configData.selectableMetadata[0].controlledVocabulary) {
const typeaheadModelConfig: DsDynamicTypeaheadModelConfig = this.initModel(null, label); const typeaheadModelConfig: DsDynamicTypeaheadModelConfig = this.initModel(null, label);
this.setAuthorityOptions(typeaheadModelConfig, this.parserOptions.authorityUuid); this.setVocabularyOptions(typeaheadModelConfig, this.parserOptions.collectionUUID);
this.setValues(typeaheadModelConfig, fieldValue, true); this.setValues(typeaheadModelConfig, fieldValue, true);
return new DynamicTypeaheadModel(typeaheadModelConfig); return new DynamicTypeaheadModel(typeaheadModelConfig);

View File

@@ -1,5 +1,5 @@
export interface ParserOptions { export interface ParserOptions {
readOnly: boolean; readOnly: boolean;
submissionScope: string; submissionScope: string;
authorityUuid: string collectionUUID: string
} }

View File

@@ -12,7 +12,7 @@ describe('RelationGroupFieldParser test suite', () => {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: false, readOnly: false,
submissionScope: 'testScopeUUID', submissionScope: 'testScopeUUID',
authorityUuid: 'WORKSPACE' collectionUUID: 'WORKSPACE'
}; };
beforeEach(() => { beforeEach(() => {

View File

@@ -16,7 +16,7 @@ export class RelationGroupFieldParser extends FieldParser {
const modelConfiguration: DynamicRelationGroupModelConfig = this.initModel(null, label); const modelConfiguration: DynamicRelationGroupModelConfig = this.initModel(null, label);
modelConfiguration.submissionId = this.submissionId; modelConfiguration.submissionId = this.submissionId;
modelConfiguration.scopeUUID = this.parserOptions.authorityUuid; modelConfiguration.scopeUUID = this.parserOptions.collectionUUID;
modelConfiguration.submissionScope = this.parserOptions.submissionScope; modelConfiguration.submissionScope = this.parserOptions.submissionScope;
if (this.configData && this.configData.rows && this.configData.rows.length > 0) { if (this.configData && this.configData.rows && this.configData.rows.length > 0) {
modelConfiguration.formConfiguration = this.configData.rows; modelConfiguration.formConfiguration = this.configData.rows;

View File

@@ -35,7 +35,7 @@ describe('RowParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'journal', metadata: 'journal',
authority: 'JOURNALAuthority', controlledVocabulary: 'JOURNALAuthority',
closed: false closed: false
} }
], ],
@@ -83,7 +83,7 @@ describe('RowParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'title', metadata: 'title',
authority: 'EVENTAuthority', controlledVocabulary: 'EVENTAuthority',
closed: false closed: false
} }
], ],
@@ -103,7 +103,7 @@ describe('RowParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'title', metadata: 'title',
authority: 'EVENTAuthority', controlledVocabulary: 'EVENTAuthority',
closed: false closed: false
} }
], ],
@@ -119,7 +119,7 @@ describe('RowParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'otherTitle', metadata: 'otherTitle',
authority: 'EVENTAuthority', controlledVocabulary: 'EVENTAuthority',
closed: false closed: false
} }
], ],
@@ -141,7 +141,7 @@ describe('RowParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'type', metadata: 'type',
authority: 'common_types_dataset', controlledVocabulary: 'common_types_dataset',
closed: false closed: false
} }
], ],
@@ -176,7 +176,7 @@ describe('RowParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'author', metadata: 'author',
authority: 'RPAuthority', controlledVocabulary: 'RPAuthority',
closed: false closed: false
} }
], ],
@@ -198,7 +198,7 @@ describe('RowParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'type', metadata: 'type',
authority: 'type_programme', controlledVocabulary: 'type_programme',
closed: false closed: false
} }
], ],
@@ -241,7 +241,7 @@ describe('RowParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'subject', metadata: 'subject',
authority: 'JOURNALAuthority', controlledVocabulary: 'JOURNALAuthority',
closed: false closed: false
} }
], ],

View File

@@ -5,7 +5,7 @@ import {
} from '@ng-dynamic-forms/core'; } from '@ng-dynamic-forms/core';
import { uniqueId } from 'lodash'; import { uniqueId } from 'lodash';
import { IntegrationSearchOptions } from '../../../../core/integration/models/integration-options.model'; import { VocabularyFindOptions } from '../../../../core/submission/vocabularies/models/vocabulary-find-options.model';
import { isEmpty } from '../../../empty.util'; import { isEmpty } from '../../../empty.util';
import { DynamicRowGroupModel } from '../ds-dynamic-form-ui/models/ds-dynamic-row-group-model'; import { DynamicRowGroupModel } from '../ds-dynamic-form-ui/models/ds-dynamic-row-group-model';
import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from '../ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model'; import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from '../ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
@@ -48,7 +48,7 @@ export class RowParser {
group: [], group: [],
}; };
const authorityOptions = new IntegrationSearchOptions(scopeUUID); const vocabularyOptions = new VocabularyFindOptions(scopeUUID);
const scopedFields: FormFieldModel[] = this.filterScopedFields(rowData.fields, submissionScope); const scopedFields: FormFieldModel[] = this.filterScopedFields(rowData.fields, submissionScope);
@@ -58,7 +58,7 @@ export class RowParser {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: readOnly, readOnly: readOnly,
submissionScope: submissionScope, submissionScope: submissionScope,
authorityUuid: authorityOptions.uuid collectionUUID: vocabularyOptions.collection
}; };
// Iterate over row's fields // Iterate over row's fields

View File

@@ -12,7 +12,7 @@ describe('SeriesFieldParser test suite', () => {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: false, readOnly: false,
submissionScope: 'testScopeUUID', submissionScope: 'testScopeUUID',
authorityUuid: null collectionUUID: null
}; };
beforeEach(() => { beforeEach(() => {

View File

@@ -12,7 +12,7 @@ describe('TagFieldParser test suite', () => {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: false, readOnly: false,
submissionScope: 'testScopeUUID', submissionScope: 'testScopeUUID',
authorityUuid: null collectionUUID: null
}; };
beforeEach(() => { beforeEach(() => {
@@ -27,7 +27,7 @@ describe('TagFieldParser test suite', () => {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'subject', metadata: 'subject',
authority: 'JOURNALAuthority', controlledVocabulary: 'JOURNALAuthority',
closed: false closed: false
} }
], ],

View File

@@ -6,9 +6,9 @@ export class TagFieldParser extends FieldParser {
public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any {
const tagModelConfig: DynamicTagModelConfig = this.initModel(null, label); const tagModelConfig: DynamicTagModelConfig = this.initModel(null, label);
if (this.configData.selectableMetadata[0].authority if (this.configData.selectableMetadata[0].controlledVocabulary
&& this.configData.selectableMetadata[0].authority.length > 0) { && this.configData.selectableMetadata[0].controlledVocabulary.length > 0) {
this.setAuthorityOptions(tagModelConfig, this.parserOptions.authorityUuid); this.setVocabularyOptions(tagModelConfig, this.parserOptions.collectionUUID);
} }
this.setValues(tagModelConfig, fieldValue, null, true); this.setValues(tagModelConfig, fieldValue, null, true);

View File

@@ -12,7 +12,7 @@ describe('TextareaFieldParser test suite', () => {
const parserOptions: ParserOptions = { const parserOptions: ParserOptions = {
readOnly: false, readOnly: false,
submissionScope: null, submissionScope: null,
authorityUuid: null collectionUUID: null
}; };
beforeEach(() => { beforeEach(() => {

View File

@@ -1,16 +1,19 @@
import { DynamicSelectModel } from '@ng-dynamic-forms/core';
import { DsDynamicInputModel } from '../form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model'; import { DsDynamicInputModel } from '../form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model';
import { DynamicQualdropModel } from '../form/builder/ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model'; import { DynamicQualdropModel } from '../form/builder/ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model';
import { DynamicRowArrayModel, DynamicRowArrayModelConfig } from '../form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-array-model'; import {
import { DynamicSelectModel } from '@ng-dynamic-forms/core'; DynamicRowArrayModel,
DynamicRowArrayModelConfig
} from '../form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-array-model';
import { SubmissionScopeType } from '../../core/submission/submission-scope-type'; import { SubmissionScopeType } from '../../core/submission/submission-scope-type';
import { DynamicRelationGroupModel } from '../form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model'; import { DynamicRelationGroupModel } from '../form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
import { FormFieldModel } from '../form/builder/models/form-field.model'; import { FormFieldModel } from '../form/builder/models/form-field.model';
import { AuthorityOptions } from '../../core/integration/models/authority-options.model'; import { VocabularyOptions } from '../../core/submission/vocabularies/models/vocabulary-options.model';
import { AuthorityValue } from '../../core/integration/models/authority.value'; import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model';
import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-metadata-value.model';
import { DynamicRowGroupModel } from '../form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-group-model'; import { DynamicRowGroupModel } from '../form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-group-model';
import { FormRowModel } from '../../core/config/models/config-submission-form.model'; import { FormRowModel } from '../../core/config/models/config-submission-form.model';
import { WorkspaceItem } from '../../core/submission/models/workspaceitem.model';
export const qualdropSelectConfig = { export const qualdropSelectConfig = {
name: 'dc.identifier_QUALDROP_METADATA', name: 'dc.identifier_QUALDROP_METADATA',
@@ -87,7 +90,7 @@ export const MockRowArrayQualdropModel: DynamicRowArrayModel = new DynamicRowArr
const mockFormRowModel = { const mockFormRowModel = {
fields: [ fields: [
{ {
input: {type: 'lookup'}, input: { type: 'lookup' },
label: 'Journal', label: 'Journal',
mandatory: 'false', mandatory: 'false',
repeatable: false, repeatable: false,
@@ -95,14 +98,14 @@ const mockFormRowModel = {
selectableMetadata: [ selectableMetadata: [
{ {
metadata: 'journal', metadata: 'journal',
authority: 'JOURNALAuthority', controlledVocabulary: 'JOURNALAuthority',
closed: false closed: false
} }
], ],
languageCodes: [] languageCodes: []
} as FormFieldModel, } as FormFieldModel,
{ {
input: {type: 'onebox'}, input: { type: 'onebox' },
label: 'Issue', label: 'Issue',
mandatory: 'false', mandatory: 'false',
repeatable: false, repeatable: false,
@@ -142,7 +145,7 @@ const relationGroupConfig = {
export const MockRelationModel: DynamicRelationGroupModel = new DynamicRelationGroupModel(relationGroupConfig); export const MockRelationModel: DynamicRelationGroupModel = new DynamicRelationGroupModel(relationGroupConfig);
export const inputWithLanguageAndAuthorityConfig = { export const inputWithLanguageAndAuthorityConfig = {
authorityOptions: new AuthorityOptions('testAuthority', 'testWithAuthority', 'scope'), vocabularyOptions: new VocabularyOptions('testAuthority', 'testWithAuthority', 'scope'),
languageCodes: [ languageCodes: [
{ {
display: 'English', display: 'English',
@@ -159,10 +162,10 @@ export const inputWithLanguageAndAuthorityConfig = {
readOnly: false, readOnly: false,
disabled: false, disabled: false,
repeatable: false, repeatable: false,
value: { value: {
value: 'testWithLanguageAndAuthority', value: 'testWithLanguageAndAuthority',
display: 'testWithLanguageAndAuthority', display: 'testWithLanguageAndAuthority',
id: 'testWithLanguageAndAuthority', authority: 'testWithLanguageAndAuthority',
}, },
submissionId: '1234', submissionId: '1234',
metadataFields: [] metadataFields: []
@@ -195,7 +198,7 @@ export const inputWithLanguageConfig = {
export const mockInputWithLanguageModel = new DsDynamicInputModel(inputWithLanguageConfig); export const mockInputWithLanguageModel = new DsDynamicInputModel(inputWithLanguageConfig);
export const inputWithLanguageAndAuthorityArrayConfig = { export const inputWithLanguageAndAuthorityArrayConfig = {
authorityOptions: new AuthorityOptions('testAuthority', 'testWithAuthority', 'scope'), vocabularyOptions: new VocabularyOptions('testAuthority', 'testWithAuthority', 'scope'),
languageCodes: [ languageCodes: [
{ {
display: 'English', display: 'English',
@@ -215,7 +218,7 @@ export const inputWithLanguageAndAuthorityArrayConfig = {
value: [{ value: [{
value: 'testLanguageAndAuthorityArray', value: 'testLanguageAndAuthorityArray',
display: 'testLanguageAndAuthorityArray', display: 'testLanguageAndAuthorityArray',
id: 'testLanguageAndAuthorityArray', authority: 'testLanguageAndAuthorityArray',
}], }],
submissionId: '1234', submissionId: '1234',
metadataFields: [] metadataFields: []
@@ -242,7 +245,11 @@ export const inputWithAuthorityValueConfig = {
readOnly: false, readOnly: false,
disabled: false, disabled: false,
repeatable: false, repeatable: false,
value: Object.assign({}, new AuthorityValue(), { value: 'testWithAuthorityValue', id: 'testWithAuthorityValue', display: 'testWithAuthorityValue' }), value: Object.assign({}, new VocabularyEntry(), {
value: 'testWithAuthorityValue',
authority: 'testWithAuthorityValue',
display: 'testWithAuthorityValue'
}),
submissionId: '1234', submissionId: '1234',
metadataFields: [] metadataFields: []
}; };
@@ -255,7 +262,7 @@ export const inputWithObjectValueConfig = {
readOnly: false, readOnly: false,
disabled: false, disabled: false,
repeatable: false, repeatable: false,
value: { value: 'testWithObjectValue', id: 'testWithObjectValue', display: 'testWithObjectValue' }, value: { value: 'testWithObjectValue', authority: 'testWithObjectValue', display: 'testWithObjectValue' },
submissionId: '1234', submissionId: '1234',
metadataFields: [] metadataFields: []
}; };

View File

@@ -1254,7 +1254,7 @@ export const mockUploadConfigResponse = {
{ {
metadata: 'dc.title', metadata: 'dc.title',
label: null, label: null,
authority: null, controlledVocabulary: null,
closed: null closed: null
} }
], ],
@@ -1276,7 +1276,7 @@ export const mockUploadConfigResponse = {
{ {
metadata: 'dc.description', metadata: 'dc.description',
label: null, label: null,
authority: null, controlledVocabulary: null,
closed: null closed: null
} }
], ],

View File

@@ -1,21 +0,0 @@
import {of as observableOf, Observable } from 'rxjs';
import { IntegrationSearchOptions } from '../../core/integration/models/integration-options.model';
import { IntegrationData } from '../../core/integration/integration-data';
import { PageInfo } from '../../core/shared/page-info.model';
import { AuthorityValue } from '../../core/integration/models/authority.value';
export class AuthorityServiceStub {
private _payload = [
Object.assign(new AuthorityValue(),{id: 1, display: 'one', value: 1}),
Object.assign(new AuthorityValue(),{id: 2, display: 'two', value: 2}),
];
setNewPayload(payload) {
this._payload = payload;
}
getEntriesByName(options: IntegrationSearchOptions) {
return observableOf(new IntegrationData(new PageInfo(), this._payload));
}
}

View File

@@ -0,0 +1,29 @@
import { Observable } from 'rxjs';
import { VocabularyFindOptions } from '../../core/submission/vocabularies/models/vocabulary-find-options.model';
import { PageInfo } from '../../core/shared/page-info.model';
import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model';
import { PaginatedList } from '../../core/data/paginated-list';
import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils';
import { RemoteData } from '../../core/data/remote-data';
export class VocabularyServiceStub {
private _payload = [
Object.assign(new VocabularyEntry(),{authority: 1, display: 'one', value: 1}),
Object.assign(new VocabularyEntry(),{authority: 2, display: 'two', value: 2}),
];
setNewPayload(payload) {
this._payload = payload;
}
getList() {
return this._payload
}
getVocabularyEntries(options: VocabularyFindOptions): Observable<RemoteData<PaginatedList<VocabularyEntry>>> {
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), this._payload));
}
}

View File

@@ -27,7 +27,7 @@ import {
mockRowGroupModel mockRowGroupModel
} from '../../../shared/mocks/form-models.mock'; } from '../../../shared/mocks/form-models.mock';
import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model';
import { AuthorityValue } from '../../../core/integration/models/authority.value'; import { VocabularyEntry } from '../../../core/submission/vocabularies/models/vocabulary-entry.model';
describe('SectionFormOperationsService test suite', () => { describe('SectionFormOperationsService test suite', () => {
let formBuilderService: any; let formBuilderService: any;
@@ -365,7 +365,7 @@ describe('SectionFormOperationsService test suite', () => {
event = Object.assign({}, dynamicFormControlChangeEvent, { event = Object.assign({}, dynamicFormControlChangeEvent, {
model: mockInputWithLanguageAndAuthorityModel model: mockInputWithLanguageAndAuthorityModel
}); });
expectedValue = Object.assign(new AuthorityValue(), mockInputWithLanguageAndAuthorityModel.value, {language: mockInputWithLanguageAndAuthorityModel.language}); expectedValue = Object.assign(new VocabularyEntry(), mockInputWithLanguageAndAuthorityModel.value, {language: mockInputWithLanguageAndAuthorityModel.language});
expect(service.getFieldValueFromChangeEvent(event)).toEqual(expectedValue); expect(service.getFieldValueFromChangeEvent(event)).toEqual(expectedValue);
@@ -373,7 +373,7 @@ describe('SectionFormOperationsService test suite', () => {
model: mockInputWithLanguageAndAuthorityArrayModel model: mockInputWithLanguageAndAuthorityArrayModel
}); });
expectedValue = [ expectedValue = [
Object.assign(new AuthorityValue(), mockInputWithLanguageAndAuthorityArrayModel.value[0], Object.assign(new VocabularyEntry(), mockInputWithLanguageAndAuthorityArrayModel.value[0],
{ language: mockInputWithLanguageAndAuthorityArrayModel.language } { language: mockInputWithLanguageAndAuthorityArrayModel.language }
) )
]; ];

View File

@@ -15,11 +15,12 @@ import { FormFieldPreviousValueObject } from '../../../shared/form/builder/model
import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder'; import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder';
import { FormFieldLanguageValueObject } from '../../../shared/form/builder/models/form-field-language-value.model'; import { FormFieldLanguageValueObject } from '../../../shared/form/builder/models/form-field-language-value.model';
import { DsDynamicInputModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model'; import { DsDynamicInputModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model';
import { AuthorityValue } from '../../../core/integration/models/authority.value'; import { VocabularyEntry } from '../../../core/submission/vocabularies/models/vocabulary-entry.model';
import { FormBuilderService } from '../../../shared/form/builder/form-builder.service'; import { FormBuilderService } from '../../../shared/form/builder/form-builder.service';
import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model';
import { DynamicQualdropModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model'; import { DynamicQualdropModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model';
import { DynamicRelationGroupModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model'; import { DynamicRelationGroupModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
/** /**
* The service handling all form section operations * The service handling all form section operations
@@ -221,18 +222,19 @@ export class SectionFormOperationsService {
if ((event.model as DsDynamicInputModel).hasAuthority) { if ((event.model as DsDynamicInputModel).hasAuthority) {
if (Array.isArray(value)) { if (Array.isArray(value)) {
value.forEach((authority, index) => { value.forEach((authority, index) => {
authority = Object.assign(new AuthorityValue(), authority, { language }); authority = Object.assign(new VocabularyEntry(), authority, { language });
value[index] = authority; value[index] = authority;
}); });
fieldValue = value; fieldValue = value;
} else { } else {
fieldValue = Object.assign(new AuthorityValue(), value, { language }); fieldValue = Object.assign(new VocabularyEntry(), value, { language });
} }
} else { } else {
// Language without Authority (input, textArea) // Language without Authority (input, textArea)
fieldValue = new FormFieldMetadataValueObject(value, language); fieldValue = new FormFieldMetadataValueObject(value, language);
} }
} else if (value instanceof FormFieldLanguageValueObject || value instanceof AuthorityValue || isObject(value)) { } else if (value instanceof FormFieldLanguageValueObject || value instanceof VocabularyEntry
|| value instanceof VocabularyEntryDetail || isObject(value)) {
fieldValue = value; fieldValue = value;
} else { } else {
fieldValue = new FormFieldMetadataValueObject(value); fieldValue = new FormFieldMetadataValueObject(value);