Skip to content

Commit b614224

Browse files
atarix83vins01-4science
authored andcommitted
Merged in task/dspace-cris-2024_02_x/DSC-2397 (pull request DSpace#3307)
Add support for multiple value with metadata enrichment Approved-by: Andrea Barbasso
2 parents ebe8d78 + 7dbeb14 commit b614224

4 files changed

Lines changed: 120 additions & 33 deletions

File tree

bitbucket-pipelines.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ options:
22
runs-on: self.hosted
33

44
definitions:
5+
caches:
6+
node-cris8: ./node_modules
7+
58
steps:
69
- step: &unittest-code-checks
710
name: test-code-checks
@@ -10,7 +13,7 @@ definitions:
1013
run-as-user: 1000
1114
size: 4x
1215
caches:
13-
- node
16+
- node-cris8
1417
script:
1518
- yarn install --frozen-lockfile
1619
- yarn run lint --quiet

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ export class Vocabulary implements CacheableObject {
7474
@autoserialize
7575
externalSource: VocabularyExternalSourceMap;
7676

77+
78+
/**
79+
* A boolean variable that indicates whether the functionality of
80+
* multiple value generation is enabled within a generator context.
81+
*/
82+
@autoserialize
83+
multiValueOnGenerator: boolean;
84+
7785
/**
7886
* A string representing the kind of Vocabulary model
7987
*/

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

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
filter,
2323
map,
2424
take,
25+
tap,
2526
} from 'rxjs/operators';
2627

2728
import { Metadata } from '../../../../../core/shared/metadata.utils';
@@ -76,6 +77,8 @@ export abstract class DsDynamicVocabularyComponent extends DynamicFormControlCom
7677
public otherInfoValues: string[] = [];
7778
public otherInfoValuesUnformatted: string[] = [];
7879

80+
multiValueOnGenerator: boolean;
81+
7982
protected constructor(protected vocabularyService: VocabularyService,
8083
protected layoutService: DynamicFormLayoutService,
8184
protected validationService: DynamicFormValidationService,
@@ -195,6 +198,7 @@ export abstract class DsDynamicVocabularyComponent extends DynamicFormControlCom
195198
this.vocabulary$ = this.vocabularyService.findVocabularyById(this.model.vocabularyOptions.name).pipe(
196199
getFirstSucceededRemoteDataPayload(),
197200
distinctUntilChanged(),
201+
tap((vocabulary: Vocabulary) => this.multiValueOnGenerator = vocabulary.multiValueOnGenerator),
198202
);
199203
}
200204

@@ -277,12 +281,14 @@ export abstract class DsDynamicVocabularyComponent extends DynamicFormControlCom
277281
for (const key in otherInformation) {
278282
if (otherInformation.hasOwnProperty(key) && key.startsWith('data-')) {
279283
const fieldId = key.replace('data-', '');
280-
const newValue: FormFieldMetadataValueObject = this.getOtherInformationValue(otherInformation[key], key);
281-
if (isNotEmpty(newValue)) {
282-
const updatedModel = this.formBuilderService.updateModelValue(fieldId, newValue);
283-
if (isNotEmpty(updatedModel)) {
284-
updatedModels.push(updatedModel);
285-
}
284+
const newValues: FormFieldMetadataValueObject[] = this.getOtherInformationValue(otherInformation[key], key);
285+
if (isNotEmpty(newValues)) {
286+
newValues.forEach((newValue) => {
287+
const updatedModel = this.formBuilderService.updateModelValue(fieldId, newValue);
288+
if (isNotEmpty(updatedModel)) {
289+
updatedModels.push(updatedModel);
290+
}
291+
});
286292
}
287293
}
288294
}
@@ -297,43 +303,53 @@ export abstract class DsDynamicVocabularyComponent extends DynamicFormControlCom
297303
}
298304
}
299305

300-
getOtherInformationValue(value: string, key: string): FormFieldMetadataValueObject {
306+
getOtherInformationValue(value: string, key: string): FormFieldMetadataValueObject[] {
301307
if (isEmpty(value) || key === 'alternative-names' ) {
302308
return null;
303309
}
304310

305-
let returnValue;
311+
const returnValue = [];
312+
if (value.indexOf('|||') === -1) {
313+
returnValue.push(this.generateFormField(value));
314+
} else if (value.indexOf('|||') !== -1 && this.otherInfoValue) {
315+
const otherValues: string[] = value.split('|||');
316+
if (this.multiValueOnGenerator) {
317+
otherValues.forEach((tmpValue) => returnValue.push(this.generateFormField(tmpValue)));
318+
} else {
319+
const unformattedValue = this.otherInfoValuesUnformatted.find(otherInfoValue => otherInfoValue.includes(this.otherInfoValue || this.otherName));
320+
const authorityValue = hasValue(unformattedValue) ? unformattedValue.substring(unformattedValue.lastIndexOf('::') + 2) : null;
321+
const otherInfo = {};
322+
let alternativeValue: string;
323+
otherInfo[key] = value;
324+
if (hasValue(this.otherName)) {
325+
alternativeValue = otherValues[0].substring(0, otherValues[0].lastIndexOf('::'));
326+
}
327+
returnValue.push(new FormFieldMetadataValueObject(
328+
hasValue(alternativeValue) ? alternativeValue : this.otherInfoValue,
329+
null,
330+
null,
331+
authorityValue,
332+
null,
333+
null,
334+
null,
335+
otherInfo,
336+
));
337+
}
338+
}
339+
return returnValue;
340+
}
341+
342+
private generateFormField(value: string): FormFieldMetadataValueObject {
306343
if (value.indexOf('::') === -1) {
307-
returnValue = new FormFieldMetadataValueObject(value);
308-
} else if (value.indexOf('|||') === -1) {
309-
returnValue = new FormFieldMetadataValueObject(
344+
return new FormFieldMetadataValueObject(value);
345+
} else {
346+
return new FormFieldMetadataValueObject(
310347
value.substring(0, value.lastIndexOf('::')),
311348
null,
312349
null,
313350
value.substring(value.lastIndexOf('::') + 2),
314351
);
315-
} else if (value.indexOf('|||') !== -1 && this.otherInfoValue) {
316-
const unformattedValue = this.otherInfoValuesUnformatted.find(otherInfoValue => otherInfoValue.includes(this.otherInfoValue || this.otherName));
317-
const authorityValue = hasValue(unformattedValue) ? unformattedValue.substring(unformattedValue.lastIndexOf('::') + 2) : null;
318-
const otherInfo = {};
319-
let alternativeValue;
320-
otherInfo[key] = value;
321-
if (hasValue(this.otherName)) {
322-
const otherValues = value.split('|||');
323-
alternativeValue = otherValues[0].substring(0, otherValues[0].lastIndexOf('::'));
324-
}
325-
returnValue = new FormFieldMetadataValueObject(
326-
hasValue(alternativeValue) ? alternativeValue : this.otherInfoValue,
327-
null,
328-
null,
329-
authorityValue,
330-
null,
331-
null,
332-
null,
333-
otherInfo,
334-
);
335352
}
336-
return returnValue;
337353
}
338354

339355
private hasValidAuthority(formMetadataValue: FormFieldMetadataValueObject) {

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

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,66 @@ describe('DsDynamicOneboxComponent test suite', () => {
570570
expect(oneboxComponent.currentValue.authority).toBeUndefined();
571571
});
572572
});
573+
574+
describe('test metadata enrichment', () => {
575+
beforeEach(() => {
576+
oneboxCompFixture = TestBed.createComponent(DsDynamicOneboxComponent);
577+
debugElement = oneboxCompFixture.debugElement;
578+
oneboxComponent = oneboxCompFixture.componentInstance;
579+
oneboxComponent.currentValue = new FormFieldMetadataValueObject('test', null, null, null, 'testDisplay');
580+
oneboxComponent.model = new DynamicOneboxModel(ONEBOX_TEST_MODEL_CONFIG);
581+
582+
spyOn(oneboxComponent, 'onSelectItem').and.returnValue(undefined);
583+
spyOn(oneboxComponent, 'toggleOtherInfoSelection').and.returnValue(undefined);
584+
});
585+
586+
587+
it('should return null if value is empty', () => {
588+
expect(oneboxComponent.getOtherInformationValue('', 'some-key')).toBeNull();
589+
});
590+
591+
it('should return null if key is "alternative-names"', () => {
592+
expect(oneboxComponent.getOtherInformationValue('some-value', 'alternative-names')).toBeNull();
593+
});
594+
595+
it('should return single FormFieldMetadataValueObject if no "|||" in value', () => {
596+
const result = oneboxComponent.getOtherInformationValue('value::authority', 'some-key');
597+
expect(result.length).toBe(1);
598+
expect(result[0]).toEqual(jasmine.any(FormFieldMetadataValueObject));
599+
expect(result[0].value).toBe('value');
600+
expect(result[0].authority).toBe('authority');
601+
});
602+
603+
it('should handle multiple values with multiValueOnGenerator true', () => {
604+
oneboxComponent.multiValueOnGenerator = true;
605+
(oneboxComponent as any).otherInfoValue = 'someValue';
606+
const result = oneboxComponent.getOtherInformationValue('val1::auth1|||val2::auth2', 'some-key');
607+
expect(result.length).toBe(2);
608+
expect(result[0].value).toBe('val1');
609+
expect(result[0].authority).toBe('auth1');
610+
expect(result[1].value).toBe('val2');
611+
expect(result[1].authority).toBe('auth2');
612+
});
613+
614+
it('should handle multiple values with multiValueOnGenerator false', () => {
615+
oneboxComponent.multiValueOnGenerator = false;
616+
(oneboxComponent as any).otherInfoValue = 'val1';
617+
oneboxComponent.otherInfoValuesUnformatted = ['val1::auth1'];
618+
const result = oneboxComponent.getOtherInformationValue('val1::auth1|||val2::auth2', 'data-key');
619+
expect(result.length).toBe(1);
620+
expect(result[0].value).toBe('val1');
621+
expect(result[0].authority).toBe('auth1');
622+
expect(result[0].otherInformation['data-key']).toBe('val1::auth1|||val2::auth2');
623+
});
624+
625+
it('should handle value without "::"', () => {
626+
const result = oneboxComponent.getOtherInformationValue('simpleValue', 'some-key');
627+
expect(result.length).toBe(1);
628+
expect(result[0].value).toBe('simpleValue');
629+
expect(result[0].authority).toBeNull();
630+
});
631+
632+
});
573633
});
574634
});
575635

0 commit comments

Comments
 (0)