Skip to content

Commit 459c237

Browse files
committed
[DSC-2397] Add support for multiple value with metadata enrichment
1 parent 682b900 commit 459c237

3 files changed

Lines changed: 117 additions & 34 deletions

File tree

src/app/core/submission/vocabularies/models/vocabulary.model.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ export class Vocabulary implements CacheableObject {
6565
@autoserialize
6666
externalSource: VocabularyExternalSourceMap;
6767

68+
69+
/**
70+
* A boolean variable that indicates whether the functionality of
71+
* multiple value generation is enabled within a generator context.
72+
*/
73+
@autoserialize
74+
multiValueOnGenerator: boolean;
75+
6876
/**
6977
* A string representing the kind of Vocabulary model
7078
*/

src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-vocabulary.component.ts

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
DynamicFormLayoutService,
99
DynamicFormValidationService
1010
} from '@ng-dynamic-forms/core';
11-
import { distinctUntilChanged, filter, map, take } from 'rxjs/operators';
11+
import { distinctUntilChanged, filter, map, take, tap } from 'rxjs/operators';
1212
import { Observable, of as observableOf } from 'rxjs';
1313
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
1414

@@ -61,6 +61,8 @@ export abstract class DsDynamicVocabularyComponent extends DynamicFormControlCom
6161
public otherInfoValues: string[] = [];
6262
public otherInfoValuesUnformatted: string[] = [];
6363

64+
multiValueOnGenerator: boolean;
65+
6466
protected constructor(protected vocabularyService: VocabularyService,
6567
protected layoutService: DynamicFormLayoutService,
6668
protected validationService: DynamicFormValidationService,
@@ -174,6 +176,7 @@ export abstract class DsDynamicVocabularyComponent extends DynamicFormControlCom
174176
this.vocabulary$ = this.vocabularyService.findVocabularyById(this.model.vocabularyOptions.name).pipe(
175177
getFirstSucceededRemoteDataPayload(),
176178
distinctUntilChanged(),
179+
tap((vocabulary: Vocabulary) => this.multiValueOnGenerator = vocabulary.multiValueOnGenerator),
177180
);
178181
}
179182

@@ -256,12 +259,14 @@ export abstract class DsDynamicVocabularyComponent extends DynamicFormControlCom
256259
for (const key in otherInformation) {
257260
if (otherInformation.hasOwnProperty(key) && key.startsWith('data-')) {
258261
const fieldId = key.replace('data-', '');
259-
const newValue: FormFieldMetadataValueObject = this.getOtherInformationValue(otherInformation[key], key);
260-
if (isNotEmpty(newValue)) {
261-
const updatedModel = this.formBuilderService.updateModelValue(fieldId, newValue);
262-
if (isNotEmpty(updatedModel)) {
263-
updatedModels.push(updatedModel);
264-
}
262+
const newValues: FormFieldMetadataValueObject[] = this.getOtherInformationValue(otherInformation[key], key);
263+
if (isNotEmpty(newValues)) {
264+
newValues.forEach((newValue) => {
265+
const updatedModel = this.formBuilderService.updateModelValue(fieldId, newValue);
266+
if (isNotEmpty(updatedModel)) {
267+
updatedModels.push(updatedModel);
268+
}
269+
});
265270
}
266271
}
267272
}
@@ -276,43 +281,53 @@ export abstract class DsDynamicVocabularyComponent extends DynamicFormControlCom
276281
}
277282
}
278283

279-
getOtherInformationValue(value: string, key: string): FormFieldMetadataValueObject {
284+
getOtherInformationValue(value: string, key: string): FormFieldMetadataValueObject[] {
280285
if (isEmpty(value) || key === 'alternative-names' ) {
281286
return null;
282287
}
283288

284-
let returnValue;
289+
let returnValue = [];
290+
if (value.indexOf('|||') === -1) {
291+
returnValue.push(this.generateFormField(value));
292+
} else if (value.indexOf('|||') !== -1 && this.otherInfoValue) {
293+
const otherValues: string[] = value.split('|||');
294+
if (this.multiValueOnGenerator) {
295+
otherValues.forEach((tmpValue) => returnValue.push(this.generateFormField(tmpValue)));
296+
} else {
297+
const unformattedValue = this.otherInfoValuesUnformatted.find(otherInfoValue => otherInfoValue.includes(this.otherInfoValue || this.otherName));
298+
const authorityValue = hasValue(unformattedValue) ? unformattedValue.substring(unformattedValue.lastIndexOf('::') + 2) : null;
299+
let otherInfo = {};
300+
let alternativeValue: string;
301+
otherInfo[key] = value;
302+
if (hasValue(this.otherName)) {
303+
alternativeValue = otherValues[0].substring(0, otherValues[0].lastIndexOf('::'));
304+
}
305+
returnValue.push(new FormFieldMetadataValueObject(
306+
hasValue(alternativeValue) ? alternativeValue : this.otherInfoValue,
307+
null,
308+
null,
309+
authorityValue,
310+
null,
311+
null,
312+
null,
313+
otherInfo
314+
));
315+
}
316+
}
317+
return returnValue;
318+
}
319+
320+
private generateFormField(value: string): FormFieldMetadataValueObject {
285321
if (value.indexOf('::') === -1) {
286-
returnValue = new FormFieldMetadataValueObject(value);
287-
} else if (value.indexOf('|||') === -1) {
288-
returnValue = new FormFieldMetadataValueObject(
322+
return new FormFieldMetadataValueObject(value);
323+
} else {
324+
return new FormFieldMetadataValueObject(
289325
value.substring(0, value.lastIndexOf('::')),
290326
null,
291327
null,
292328
value.substring(value.lastIndexOf('::') + 2)
293329
);
294-
} else if (value.indexOf('|||') !== -1 && this.otherInfoValue) {
295-
const unformattedValue = this.otherInfoValuesUnformatted.find(otherInfoValue => otherInfoValue.includes(this.otherInfoValue || this.otherName));
296-
const authorityValue = hasValue(unformattedValue) ? unformattedValue.substring(unformattedValue.lastIndexOf('::') + 2) : null;
297-
let otherInfo = {};
298-
let alternativeValue;
299-
otherInfo[key] = value;
300-
if (hasValue(this.otherName)) {
301-
const otherValues = value.split('|||');
302-
alternativeValue = otherValues[0].substring(0, otherValues[0].lastIndexOf('::'));
303-
}
304-
returnValue = new FormFieldMetadataValueObject(
305-
hasValue(alternativeValue) ? alternativeValue : this.otherInfoValue,
306-
null,
307-
null,
308-
authorityValue,
309-
null,
310-
null,
311-
null,
312-
otherInfo
313-
);
314330
}
315-
return returnValue;
316331
}
317332

318333
private hasValidAuthority(formMetadataValue: FormFieldMetadataValueObject) {

src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.spec.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ describe('DsDynamicOneboxComponent test suite', () => {
8181

8282
let scheduler: TestScheduler;
8383
let testComp: TestComponent;
84-
let oneboxComponent: DsDynamicOneboxComponent;
84+
let oneboxComponent: DsDynamicOneboxComponent|any;
8585
let testFixture: ComponentFixture<TestComponent>;
8686
let debugElement: DebugElement;
8787
let oneboxCompFixture: ComponentFixture<DsDynamicOneboxComponent>;
@@ -549,6 +549,66 @@ describe('DsDynamicOneboxComponent test suite', () => {
549549
expect(oneboxComponent.currentValue.authority).toBeUndefined();
550550
});
551551
});
552+
553+
describe('test metadata enrichment', () => {
554+
beforeEach(() => {
555+
oneboxCompFixture = TestBed.createComponent(DsDynamicOneboxComponent);
556+
debugElement = oneboxCompFixture.debugElement;
557+
oneboxComponent = oneboxCompFixture.componentInstance;
558+
oneboxComponent.currentValue = new FormFieldMetadataValueObject('test', null, null, null, 'testDisplay');
559+
oneboxComponent.model = new DynamicOneboxModel(ONEBOX_TEST_MODEL_CONFIG);
560+
561+
spyOn(oneboxComponent, 'onSelectItem').and.returnValue(undefined);
562+
spyOn(oneboxComponent, 'toggleOtherInfoSelection').and.returnValue(undefined);
563+
});
564+
565+
566+
it('should return null if value is empty', () => {
567+
expect(oneboxComponent.getOtherInformationValue('', 'some-key')).toBeNull();
568+
});
569+
570+
it('should return null if key is "alternative-names"', () => {
571+
expect(oneboxComponent.getOtherInformationValue('some-value', 'alternative-names')).toBeNull();
572+
});
573+
574+
it('should return single FormFieldMetadataValueObject if no "|||" in value', () => {
575+
const result = oneboxComponent.getOtherInformationValue('value::authority', 'some-key');
576+
expect(result.length).toBe(1);
577+
expect(result[0]).toEqual(jasmine.any(FormFieldMetadataValueObject));
578+
expect(result[0].value).toBe('value');
579+
expect(result[0].authority).toBe('authority');
580+
});
581+
582+
it('should handle multiple values with multiValueOnGenerator true', () => {
583+
oneboxComponent.multiValueOnGenerator = true;
584+
oneboxComponent.otherInfoValue = 'someValue';
585+
const result = oneboxComponent.getOtherInformationValue('val1::auth1|||val2::auth2', 'some-key');
586+
expect(result.length).toBe(2);
587+
expect(result[0].value).toBe('val1');
588+
expect(result[0].authority).toBe('auth1');
589+
expect(result[1].value).toBe('val2');
590+
expect(result[1].authority).toBe('auth2');
591+
});
592+
593+
it('should handle multiple values with multiValueOnGenerator false', () => {
594+
oneboxComponent.multiValueOnGenerator = false;
595+
oneboxComponent.otherInfoValue = 'val1';
596+
oneboxComponent.otherInfoValuesUnformatted = ['val1::auth1'];
597+
const result = oneboxComponent.getOtherInformationValue('val1::auth1|||val2::auth2', 'data-key');
598+
expect(result.length).toBe(1);
599+
expect(result[0].value).toBe('val1');
600+
expect(result[0].authority).toBe('auth1');
601+
expect(result[0].otherInformation['data-key']).toBe('val1::auth1|||val2::auth2');
602+
});
603+
604+
it('should handle value without "::"', () => {
605+
const result = oneboxComponent.getOtherInformationValue('simpleValue', 'some-key');
606+
expect(result.length).toBe(1);
607+
expect(result[0].value).toBe('simpleValue');
608+
expect(result[0].authority).toBeNull();
609+
});
610+
611+
});
552612
});
553613
});
554614

0 commit comments

Comments
 (0)