diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-vocabulary.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-vocabulary.component.ts index 2b0d815dd8b..09ad4157801 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-vocabulary.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-vocabulary.component.ts @@ -55,6 +55,12 @@ export abstract class DsDynamicVocabularyComponent extends DynamicFormControlCom */ public abstract pageInfo: PageInfo; + protected otherInfoValue: string; + protected otherName: string; + protected otherInfoKey: string; + public otherInfoValues: string[] = []; + public otherInfoValuesUnformatted: string[] = []; + protected constructor(protected vocabularyService: VocabularyService, protected layoutService: DynamicFormLayoutService, protected validationService: DynamicFormValidationService, @@ -202,11 +208,11 @@ export abstract class DsDynamicVocabularyComponent extends DynamicFormControlCom * @param authority */ updateAuthority(authority: string) { - const currentValue: string = (this.model.value instanceof FormFieldMetadataValueObject + const currentValue: string = (this.model.value instanceof FormFieldMetadataValueObject || this.model.value instanceof VocabularyEntry) ? this.model.value.value : this.model.value; let security = null; if ( this.model.value instanceof VocabularyEntry) { - security = this.model.value.securityLevel; + security = this.model.value.securityLevel; } else { if (this.model.metadataValue) { security = this.model.metadataValue.securityLevel; @@ -250,7 +256,7 @@ export abstract class DsDynamicVocabularyComponent extends DynamicFormControlCom for (const key in otherInformation) { if (otherInformation.hasOwnProperty(key) && key.startsWith('data-')) { const fieldId = key.replace('data-', ''); - const newValue: FormFieldMetadataValueObject = this.getOtherInformationValue(otherInformation[key]); + const newValue: FormFieldMetadataValueObject = this.getOtherInformationValue(otherInformation[key], key); if (isNotEmpty(newValue)) { const updatedModel = this.formBuilderService.updateModelValue(fieldId, newValue); if (isNotEmpty(updatedModel)) { @@ -270,23 +276,42 @@ export abstract class DsDynamicVocabularyComponent extends DynamicFormControlCom } } - getOtherInformationValue(value: string): FormFieldMetadataValueObject { - if (isEmpty(value)) { + getOtherInformationValue(value: string, key: string): FormFieldMetadataValueObject { + if (isEmpty(value) || key === 'alternative-names' ) { return null; } let returnValue; if (value.indexOf('::') === -1) { returnValue = new FormFieldMetadataValueObject(value); - } else { + } else if (value.indexOf('|||') === -1) { returnValue = new FormFieldMetadataValueObject( value.substring(0, value.lastIndexOf('::')), null, null, value.substring(value.lastIndexOf('::') + 2) ); + } else if (value.indexOf('|||') !== -1 && this.otherInfoValue) { + const unformattedValue = this.otherInfoValuesUnformatted.find(otherInfoValue => otherInfoValue.includes(this.otherInfoValue || this.otherName)); + const authorityValue = hasValue(unformattedValue) ? unformattedValue.substring(unformattedValue.lastIndexOf('::') + 2) : null; + let otherInfo = {}; + let alternativeValue; + otherInfo[key] = value; + if (hasValue(this.otherName)) { + const otherValues = value.split('|||'); + alternativeValue = otherValues[0].substring(0, otherValues[0].lastIndexOf('::')); + } + returnValue = new FormFieldMetadataValueObject( + hasValue(alternativeValue) ? alternativeValue : this.otherInfoValue, + null, + null, + authorityValue, + null, + null, + null, + otherInfo + ); } - return returnValue; } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.html index fe59791e6b9..da5cfcc26af 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.html @@ -10,7 +10,7 @@
  • {{entry.value}}
  • - {{ 'form.other-information.' + item.key | translate }} : {{item.value !== '' ? getOtherInfoValue(item.value) : ('form.other-information.not-available' | translate)}} + {{ 'form.other-information.' + item.key | translate }} : {{item.value !== '' ? getOtherInfoValue(item.value, item.key) : ('form.other-information.not-available' | translate)}}
  • @@ -31,9 +31,14 @@ aria-hidden="true" [authorityValue]="currentValue" (whenClickOnConfidenceNotAccepted)="whenClickOnConfidenceNotAccepted($event)"> + + + + +
    + {{'form.other-information.selection.' + otherInfoKey | translate}} + +
    diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.scss b/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.scss index 6e9b796bb90..1f8188fc9ff 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.scss +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.scss @@ -40,3 +40,20 @@ background-color: #fff; cursor: pointer; } + +.additional-items-icon { + padding-right: 5rem !important; + cursor: pointer; +} +.additional-info-selection { + z-index: 9999; + width: calc(100% - 10px); + border-radius: 4px; + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.175); + .list-item { + cursor: pointer; + } + .list-item:hover { + background-color: var(--bs-dropdown-link-hover-bg); + } +} diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.ts index 1e7e0e14290..c98ceb272a1 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.ts @@ -1,4 +1,12 @@ -import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + EventEmitter, + Input, + OnInit, + Output, + ViewChild +} from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { @@ -67,6 +75,9 @@ export class DsDynamicOneboxComponent extends DsDynamicVocabularyComponent imple previousValue: any; inputValue: any; preloadLevel: number; + additionalInfoSelectIsOpen = false; + alternativeNamesKey = 'alternative-names'; + private isHierarchicalVocabulary$: Observable; private subs: Subscription[] = []; @@ -94,6 +105,7 @@ export class DsDynamicOneboxComponent extends DsDynamicVocabularyComponent imple * to display in the onebox popup. */ search = (text$: Observable) => { + this.additionalInfoSelectIsOpen = false; return text$.pipe( merge(this.click$), debounceTime(300), @@ -167,7 +179,7 @@ export class DsDynamicOneboxComponent extends DsDynamicVocabularyComponent imple * @param event */ onInput(event) { - if (!this.model.vocabularyOptions.closed && isNotEmpty(event.target.value)) { + if (!this.model.vocabularyOptions.closed && isNotEmpty(event.target.value)) { this.inputValue = new FormFieldMetadataValueObject(event.target.value); if (this.model.value) { if ((this.model.value as any).securityLevel != null) { @@ -187,7 +199,7 @@ export class DsDynamicOneboxComponent extends DsDynamicVocabularyComponent imple if (isNotNull(this.inputValue) && this.model.value !== this.inputValue) { this.dispatchUpdate(this.inputValue); } - this.inputValue = null; + this.inputValue = null; } this.blur.emit(event); } else { @@ -221,8 +233,23 @@ export class DsDynamicOneboxComponent extends DsDynamicVocabularyComponent imple */ onSelectItem(event: NgbTypeaheadSelectItemEvent) { this.inputValue = null; - this.setCurrentValue(event.item); - this.dispatchUpdate(event.item); + const item = event.item; + + if ( hasValue(item.otherInformation)) { + const otherInfoKeys = Object.keys(item.otherInformation).filter((key) => !key.startsWith('data')); + const hasMultipleValues = otherInfoKeys.some(key => hasValue(item.otherInformation[key]) && item.otherInformation[key].includes('|||')); + + if (hasMultipleValues) { + this.setMultipleValuesForOtherInfo(otherInfoKeys, item); + } else { + this.resetMultipleValuesForOtherInfo(); + } + } else { + this.resetMultipleValuesForOtherInfo(); + } + + this.setCurrentValue(item); + this.dispatchUpdate(item); } /** @@ -287,22 +314,37 @@ export class DsDynamicOneboxComponent extends DsDynamicVocabularyComponent imple } else { result = value; } + this.currentValue = null; + this.cdr.detectChanges(); this.currentValue = result; this.previousValue = result; this.cdr.detectChanges(); } - + if (hasValue(this.currentValue.otherInformation)) { + const infoKeys = Object.keys(this.currentValue.otherInformation); + this.setMultipleValuesForOtherInfo(infoKeys, this.currentValue); + } } /** * Get the other information value removing the authority section (after the last ::) * @param itemValue the initial item value + * @param itemKey */ - getOtherInfoValue(itemValue: string): string { + getOtherInfoValue(itemValue: string, itemKey: string): string { if (!itemValue || !itemValue.includes('::')) { return itemValue; } + + if (itemValue.includes('|||')) { + let result = ''; + const values = itemValue.split('|||').map(item => item.substring(0, item.lastIndexOf('::'))); + const lastIndex = values.length - 1; + values.forEach((value, i) => result += i === lastIndex ? value : value + ' ยท '); + return result; + } + return itemValue.substring(0, itemValue.lastIndexOf('::')); } @@ -311,4 +353,64 @@ export class DsDynamicOneboxComponent extends DsDynamicVocabularyComponent imple .filter((sub) => hasValue(sub)) .forEach((sub) => sub.unsubscribe()); } + + toggleOtherInfoSelection() { + this.additionalInfoSelectIsOpen = !this.additionalInfoSelectIsOpen; + } + + selectAlternativeInfo(info: string) { + this.searching = true; + + if (this.otherInfoKey !== this.alternativeNamesKey) { + this.otherInfoValue = info; + } else { + this.otherName = info; + } + + const temp = this.createVocabularyObject(info, info, this.currentValue.otherInformation); + this.currentValue = null; + this.currentValue = temp; + + const event = { + item: this.currentValue + } as any; + + this.onSelectItem(event); + this.searching = false; + this.toggleOtherInfoSelection(); + } + + + setMultipleValuesForOtherInfo(keys: string[], item: any) { + const hasAlternativeNames = keys.includes(this.alternativeNamesKey); + + this.otherInfoKey = hasAlternativeNames ? this.alternativeNamesKey : keys.find(key => hasValue(item.otherInformation[key]) && item.otherInformation[key].includes('|||')); + this.otherInfoValuesUnformatted = item.otherInformation[this.otherInfoKey] ? item.otherInformation[this.otherInfoKey].split('|||') : []; + this.otherInfoValues = this.otherInfoValuesUnformatted.map(unformattedItem => unformattedItem.substring(0, unformattedItem.lastIndexOf('::'))); + + if (hasAlternativeNames) { + this.otherName = hasValue(this.otherName) ? this.otherName : this.otherInfoValues[0]; + } + + if (keys.length > 1) { + this.otherInfoValue = hasValue(this.otherInfoValue) ? this.otherInfoValue : this.otherInfoValues[0]; + } + } + + resetMultipleValuesForOtherInfo() { + this.otherInfoKey = undefined; + this.otherInfoValuesUnformatted = []; + this.otherInfoValues = []; + this.otherInfoValue = undefined; + this.otherName = undefined; + } + + createVocabularyObject(display, value, otherInformation) { + return Object.assign(new VocabularyEntry(), this.model.value, { + display: display, + value: value, + otherInformation: otherInformation, + type: 'vocabularyEntry' + }); + } } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.html index 887e0f00588..669de36ad6c 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.html @@ -6,7 +6,7 @@ + [wrapperClass]="'border-bottom'"> 0) { this.setVocabularyOptions(tagModelConfig, this.parserOptions.collectionUUID); } - this.setValues(tagModelConfig, fieldValue, null, true); - - const tagModel = new DynamicTagModel(tagModelConfig); - + tagModelConfig.placeholder = 'Enter the Keywords'; + const tagModel = new DynamicTagModel(tagModelConfig, clsTag); return tagModel; } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 2cb67480df6..ffdb3155c18 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3269,11 +3269,25 @@ "item.preview.dc.identifier.arxiv": "arXiv ID", - "item.preview.dc.identifier.patentno": "Patent Number", + "item.preview.crispatent.document.description": "Document description:", + + "item.preview.crispatent.document.issueDate": "Publication date:", + + "item.preview.crispatent.document.kind": "Document Kind code:", + + "item.preview.crispatent.document.title": "Document title:", + + "item.preview.crispatent.kind": "Kind code:", + + "item.preview.dc.contributor": "Applicants:", + + "item.preview.dc.identifier.applicationnumber": "Application number:", + + "item.preview.dc.identifier.patentno": "Patent number:", "item.preview.dc.subject.ipc": "Subject IPC", - "item.preview.dcterms.dateSubmitted": "Registration Date", + "item.preview.dcterms.dateSubmitted": "Registration date:", "item.preview.dc.identifier.isi": "ISI", @@ -7344,4 +7358,14 @@ "third-party-metrics-cookies.consent-settings": "consent settings", "third-party-metrics-blocked": "Some of the metrics are blocked by your", + + "form.other-information.alternative-names": "Alternative names", + + "form.other-information.selection.data-oairecerif_author_affiliation": "Select alternative affiliation", + + "form.other-information.data-oairecerif_author_affiliation": "Affiliation", + + "form.other-information.selection.data-crispj_coinvestigator_affiliation": "Affiliation", + + "form.other-information.selection.alternative-names": "Select alternative name", }