diff --git a/src/app/core/shared/form/models/form-field.model.ts b/src/app/core/shared/form/models/form-field.model.ts index d5cd65106fe..8e541de449b 100644 --- a/src/app/core/shared/form/models/form-field.model.ts +++ b/src/app/core/shared/form/models/form-field.model.ts @@ -120,6 +120,12 @@ export class FormFieldModel { @autoserialize typeBind: string[]; + /** + * Contains field name to type-bind to + */ + @autoserialize + typeBindToField: string; + /** * Containing the value for this metadata field */ diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts index 3bdd5d67f44..ee16911a4b6 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts @@ -184,6 +184,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo listId: string; searchConfig: string; value: MetadataValue; + /** * List of subscriptions to unsubscribe from */ @@ -355,8 +356,20 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo if (this.model && this.model.placeholder) { this.model.placeholder = this.translateService.instant(this.model.placeholder); } + + // Handle typeBind relations if (this.model.typeBindRelations && this.model.typeBindRelations.length > 0) { - this.subscriptions.push(...this.typeBindRelationService.subscribeRelations(this.model, this.control)); + const fieldKey = this.model.metadataKey ?? this.model.name; + if (!this.typeBindRelationService.activatedSubscriptionsByMetadataKey.has(fieldKey)) { + this.subscriptions.push(...this.typeBindRelationService.subscribeRelations( + this.model, + this.control, + this.formGroup ? this.formGroup : this.group, + this.ref, + )); + this.typeBindRelationService.activatedSubscriptionsByMetadataKey.add(fieldKey); + } + } } } @@ -519,6 +532,16 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo this.subs .filter((sub) => hasValue(sub)) .forEach((sub) => sub.unsubscribe()); + + this.clearListOfTypeBindRelationSubscriptions(); + } + + private clearListOfTypeBindRelationSubscriptions() { + const fieldKey = this.model.metadataKey ?? this.model.name; + + if (this.typeBindRelationService.activatedSubscriptionsByMetadataKey.has(fieldKey)) { + this.typeBindRelationService.activatedSubscriptionsByMetadataKey.delete(fieldKey); + } } get hasHint(): boolean { diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.spec.ts index 029aea63647..e696aca2d19 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.spec.ts @@ -1,4 +1,7 @@ -import { Injector } from '@angular/core'; +import { + ChangeDetectorRef, + Injector, +} from '@angular/core'; import { inject, TestBed, @@ -78,13 +81,13 @@ describe('DSDynamicTypeBindRelationService test suite', () => { describe('Test getRelatedFormModel method', () => { it('Should get 0 related form models for simple type bind mock data', () => { const testModel = MockRelationModel; - const relatedModels = service.getRelatedFormModel(testModel); + const relatedModels = service.getRelatedFormModel(testModel, undefined); expect(relatedModels).toHaveSize(0); }); it('Should get 1 related form models for mock relation model data', () => { const testModel = mockInputWithTypeBindModel; testModel.typeBindRelations = getTypeBindRelations(['boundType'], 'dc.type'); - const relatedModels = service.getRelatedFormModel(testModel); + const relatedModels = service.getRelatedFormModel(testModel, undefined); expect(relatedModels).toHaveSize(1); }); }); @@ -95,7 +98,8 @@ describe('DSDynamicTypeBindRelationService test suite', () => { testModel.typeBindRelations = getTypeBindRelations(['boundType'], 'dc.type'); const dcTypeControl = new UntypedFormControl(); dcTypeControl.setValue('boundType'); - let subscriptions = service.subscribeRelations(testModel, dcTypeControl); + const compRef = jasmine.createSpyObj('ChangeDetectorRef', ['markForCheck']); + let subscriptions = service.subscribeRelations(testModel, dcTypeControl, dcTypeControl.parent as any, compRef); expect(subscriptions).toHaveSize(1); }); @@ -108,7 +112,7 @@ describe('DSDynamicTypeBindRelationService test suite', () => { const relation = dynamicFormRelationService.findRelationByMatcher((testModel as any).typeBindRelations, HIDDEN_MATCHER); const matcher = HIDDEN_MATCHER; if (relation !== undefined) { - const hasMatch = service.matchesCondition(relation, matcher); + const hasMatch = service.matchesCondition(relation, matcher,[{ 'dc.type': 'boundType' }]); matcher.onChange(hasMatch, testModel, dcTypeControl, injector); expect(hasMatch).toBeTruthy(); } @@ -123,7 +127,7 @@ describe('DSDynamicTypeBindRelationService test suite', () => { const relation = dynamicFormRelationService.findRelationByMatcher((testModel as any).typeBindRelations, HIDDEN_MATCHER); const matcher = HIDDEN_MATCHER; if (relation !== undefined) { - const hasMatch = service.matchesCondition(relation, matcher); + const hasMatch = service.matchesCondition(relation, matcher, [{ 'dc.type': 'boundType' }]); matcher.onChange(hasMatch, testModel, dcTypeControl, injector); expect(hasMatch).toBeFalsy(); } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts index 68a77c8f9ad..51e86716717 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts @@ -1,18 +1,25 @@ import { + ChangeDetectorRef, Inject, Injectable, Injector, Optional, } from '@angular/core'; -import { UntypedFormControl } from '@angular/forms'; +import { + FormArray, + UntypedFormControl, + UntypedFormGroup, +} from '@angular/forms'; import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from '@dspace/core/shared/form/ds-dynamic-form-constants'; import { FormFieldMetadataValueObject } from '@dspace/core/shared/form/models/form-field-metadata-value.model'; import { hasNoValue, hasValue, + isNotNull, } from '@dspace/shared/utils/empty.util'; import { AND_OPERATOR, + DYNAMIC_FORM_CONTROL_TYPE_ARRAY, DYNAMIC_MATCHERS, DynamicFormControlCondition, DynamicFormControlMatcher, @@ -22,7 +29,11 @@ import { OR_OPERATOR, } from '@ng-dynamic-forms/core'; import { Subscription } from 'rxjs'; -import { startWith } from 'rxjs/operators'; +import { + debounceTime, + distinctUntilChanged, + startWith, +} from 'rxjs/operators'; import { FormBuilderService } from '../form-builder.service'; @@ -32,6 +43,7 @@ import { FormBuilderService } from '../form-builder.service'; */ @Injectable({ providedIn: 'root' }) export class DsDynamicTypeBindRelationService { + activatedSubscriptionsByMetadataKey = new Set(); constructor(@Optional() @Inject(DYNAMIC_MATCHERS) private dynamicMatchers: DynamicFormControlMatcher[], protected dynamicFormRelationService: DynamicFormRelationService, @@ -60,12 +72,15 @@ export class DsDynamicTypeBindRelationService { /** - * Get models for this bind type + * Get models or (parent array-)controls for a model with type bind + * * @param model + * @param formGroup */ - public getRelatedFormModel(model: DynamicFormControlModel): DynamicFormControlModel[] { + public getRelatedFormModel(model: DynamicFormControlModel, formGroup: UntypedFormGroup): Array { - const models: DynamicFormControlModel[] = []; + const models: Array = []; + let parentControl: any; (model as any).typeBindRelations.forEach((relGroup) => relGroup.when.forEach((rel) => { @@ -73,13 +88,23 @@ export class DsDynamicTypeBindRelationService { throw new Error(`FormControl ${model.id} cannot depend on itself`); } - const bindModel: DynamicFormControlModel = this.formBuilderService.getTypeBindModel(); + const bindModel: DynamicFormControlModel = this.formBuilderService.getTypeBindModels(rel.id); + + if (!parentControl && formGroup && bindModel && this.isPartOfArrayWithRepeatableItems(bindModel)) { + parentControl = this.formBuilderService.findControlByModel((bindModel.parent as any).context, formGroup); + } - if (model && !models.some((modelElement) => modelElement === bindModel)) { - models.push(bindModel); + if (!parentControl) { + if (model && !models.some((modelElement) => modelElement === bindModel)) { + models.push(bindModel); + } } })); + if (parentControl && !models.some((modelElement) => modelElement === parentControl)) { + models.push(parentControl); + } + return models; } @@ -89,20 +114,20 @@ export class DsDynamicTypeBindRelationService { * component, the negation of the comparison is returned. * @param relation type bind relation (eg. {MATCH_VISIBLE, OR, ['book', 'book part']}) * @param matcher contains 'match' value and an onChange() event listener + * @param latestChanges */ - public matchesCondition(relation: DynamicFormControlRelation, matcher: DynamicFormControlMatcher): boolean { + public matchesCondition(relation: DynamicFormControlRelation, matcher: DynamicFormControlMatcher, latestChanges?: any): boolean { // Default to OR for operator (OR is explicitly set in field-parser.ts anyway) const operator = relation.operator || OR_OPERATOR; - return relation.when.reduce((hasAlreadyMatched: boolean, condition: DynamicFormControlCondition, index: number) => { // Get the DynamicFormControlModel (typeBindModel) from the form builder service, set in the form builder // in the form model at init time in formBuilderService.modelFromConfiguration (called by other form components // like relation group component and submission section form component). // This model (DynamicRelationGroupModel) contains eg. mandatory field, formConfiguration, relationFields, // submission scope, form/section type and other high level properties - const bindModel: any = this.formBuilderService.getTypeBindModel(); + const bindModel: any = this.formBuilderService.getTypeBindModels(condition.id); let values: string[]; let bindModelValue = bindModel.value; @@ -112,8 +137,17 @@ export class DsDynamicTypeBindRelationService { if (bindModel.type === DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP) { bindModelValue = bindModel.value.map((entry) => entry[bindModel.mandatoryField]); } + // Support multiple bind models - if (Array.isArray(bindModelValue)) { + if (latestChanges && Array.isArray(latestChanges)) { + values = latestChanges.map((entry) => { + if (entry[condition.id]) { + return this.getTypeBindValue(entry[condition.id]); + } else { + return this.getTypeBindValue(entry); + } + }); + } else if (Array.isArray(bindModelValue)) { values = [...bindModelValue.map((entry) => this.getTypeBindValue(entry))]; } else { values = [this.getTypeBindValue(bindModelValue)]; @@ -177,42 +211,68 @@ export class DsDynamicTypeBindRelationService { * Return an array of subscriptions to a calling component * @param model * @param control + * @param formGroup + * @param compRef */ - subscribeRelations(model: DynamicFormControlModel, control: UntypedFormControl): Subscription[] { - - const relatedModels = this.getRelatedFormModel(model); - const subscriptions: Subscription[] = []; - - Object.values(relatedModels).forEach((relatedModel: any) => { - - if (hasValue(relatedModel)) { - const initValue = (hasNoValue(relatedModel.value) || typeof relatedModel.value === 'string') ? relatedModel.value : - (Array.isArray(relatedModel.value) ? relatedModel.value : relatedModel.value.value); - - const updateSubject = (relatedModel.type === 'CHECKBOX_GROUP' ? relatedModel.valueUpdates : relatedModel.valueChanges); - const valueChanges = updateSubject.pipe( - startWith(initValue), - ); - - // Build up the subscriptions to watch for changes; - subscriptions.push(valueChanges.subscribe(() => { - // Iterate each matcher - if (hasValue(this.dynamicMatchers)) { - this.dynamicMatchers.forEach((matcher) => { - // Find the relation - const relation = this.dynamicFormRelationService.findRelationByMatcher((model as any).typeBindRelations, matcher); - // If the relation is defined, get matchesCondition result and pass it to the onChange event listener - if (relation !== undefined) { - const hasMatch = this.matchesCondition(relation, matcher); - matcher.onChange(hasMatch, model, control, this.injector); - } - }); - } - })); + subscribeRelations(model: DynamicFormControlModel, control: UntypedFormControl, formGroup: UntypedFormGroup, compRef: ChangeDetectorRef): Subscription[] { + const relatedControlsOrModels: Array = this.getRelatedFormModel(model, formGroup); + + return Object.values(relatedControlsOrModels).filter((relatedModel) => hasValue(relatedModel)).map((relatedModel) => { + const isFormArray = relatedModel instanceof FormArray; + + const initialValue = this.getInitialRelatedModelValue(relatedModel); + let valueUpdates$; + + if (isFormArray) { + valueUpdates$ = relatedModel.valueChanges; + } else if ((relatedModel as any).type === 'CHECKBOX_GROUP') { + valueUpdates$ = (relatedModel as any).valueUpdates; + } else { + valueUpdates$ = (relatedModel as any).valueChanges; } + + return valueUpdates$.pipe( + startWith(initialValue), + distinctUntilChanged(), + debounceTime(150), + ).subscribe((changedValues: any) => { + this.applyMatcher(model, control, compRef, isFormArray ? changedValues : undefined); + }); }); + } + + private getInitialRelatedModelValue(relatedModel: DynamicFormControlModel | FormArray) { + const value = (relatedModel as any).value; + + if (hasNoValue(value) || typeof value === 'string' || Array.isArray(value)) { + return value; + } + + return value.value; + } - return subscriptions; + private applyMatcher(model: DynamicFormControlModel, control: UntypedFormControl, compRef: ChangeDetectorRef, latestChanges: any) { + if (!hasValue(this.dynamicMatchers)) { + return; + } + + this.dynamicMatchers.forEach((matcher) => { + const relation = this.dynamicFormRelationService.findRelationByMatcher((model as any).typeBindRelations, matcher); + + if (relation === undefined) { + return; + } + + const hasMatch = this.matchesCondition(relation, matcher, latestChanges); + matcher.onChange(hasMatch, model, control, this.injector); + compRef.markForCheck(); + }); } + private isPartOfArrayWithRepeatableItems(model: DynamicFormControlModel): boolean { + return (isNotNull(model.parent) && + (model.parent as any).context && + (model.parent as any).context.type === DYNAMIC_FORM_CONTROL_TYPE_ARRAY && + (model.parent as any).context.notRepeatable === false); + } } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts index 838c67767cc..5bad65712bb 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts @@ -278,7 +278,6 @@ export class DsDynamicRelationGroupComponent extends DynamicFormControlComponent {}, // @Input model.value this.model.submissionScope, this.model.readOnly, - null, true); const fieldId = fieldName.replace(/\./g, '_'); const model = this.formBuilderService.findById(fieldId, formModel); diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/modal/dynamic-relation-group-modal.components.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/modal/dynamic-relation-group-modal.components.ts index 1d0d6fe1214..b61a0ad6ea9 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/modal/dynamic-relation-group-modal.components.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/modal/dynamic-relation-group-modal.components.ts @@ -202,7 +202,6 @@ export class DsDynamicRelationGroupModalComponent extends DynamicFormControlComp {}, this.model.submissionScope, this.model.readOnly, - null, true, this.metadataSecurityConfiguration); this.formBuilderService.addFormModel(this.formId, this.formModel); diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-inline-group/dynamic-relation-inline-group.components.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-inline-group/dynamic-relation-inline-group.components.ts index b6ce313ee3d..62b241501c5 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-inline-group/dynamic-relation-inline-group.components.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-inline-group/dynamic-relation-inline-group.components.ts @@ -133,7 +133,6 @@ export class DsDynamicRelationInlineGroupComponent extends DynamicFormControlCom initValues, this.model.submissionScope, this.model.readOnly, - this.formBuilderService.getTypeBindModel(), true, this.metadataSecurityConfiguration)[0]; diff --git a/src/app/shared/form/builder/form-builder.service.ts b/src/app/shared/form/builder/form-builder.service.ts index ef5ec96fd53..47f5965cd57 100644 --- a/src/app/shared/form/builder/form-builder.service.ts +++ b/src/app/shared/form/builder/form-builder.service.ts @@ -67,7 +67,7 @@ import { RowParser } from './parsers/row-parser'; @Injectable({ providedIn: 'root' }) export class FormBuilderService extends DynamicFormService { - private typeBindModel: DynamicFormControlModel; + private typeBindModels: { [key: string]: DynamicFormControlModel } = {}; /** * This map contains the active forms model @@ -110,12 +110,16 @@ export class FormBuilderService extends DynamicFormService { return { $event, context, control: control, group: group, model: model, type }; } - getTypeBindModel() { - return this.typeBindModel; + getTypeBindModels(key: string) { + if (!this.typeBindModels[key]) { + return; + } + + return this.typeBindModels[key]; } - setTypeBindModel(model: DynamicFormControlModel) { - this.typeBindModel = model; + setTypeBindModels(model: DynamicFormControlModel, key: string) { + this.typeBindModels[key] = model; } findById(id: string, groupModel: DynamicFormControlModel[], arrayIndex = null): DynamicFormControlModel | null { @@ -383,8 +387,8 @@ export class FormBuilderService extends DynamicFormService { } modelFromConfiguration(submissionId: string, json: string | SubmissionFormsModel, scopeUUID: string, sectionData: any = {}, - submissionScope?: string, readOnly = false, typeBindModel = null, - isInnerForm = false, securityConfig: any = null, setTypeBind: boolean = true): DynamicFormControlModel[] | never { + submissionScope?: string, readOnly = false, isInnerForm = false, securityConfig: any = null): DynamicFormControlModel[] | never { + const typeBindToFieldList: string[] = ['dc_type']; let rows: DynamicFormControlModel[] = []; const rawData = typeof json === 'string' ? JSON.parse(json, parseReviver) : json; if (rawData.rows && !isEmpty(rawData.rows)) { @@ -398,16 +402,31 @@ export class FormBuilderService extends DynamicFormService { rows.push(rowParsed); } } + + // Collect all type-bind keys + if (currentRow.fields && currentRow.fields.length > 0) { + currentRow.fields.forEach((field) => { + if (field.typeBindToField) { + const typeBindToField = field.typeBindToField.replace(/\./g, '_'); + if (!typeBindToFieldList.includes(typeBindToField)) { + typeBindToFieldList.push(typeBindToField); + } + } + }); + } }); } - if (hasNoValue(typeBindModel)) { - typeBindModel = this.findById(this.typeField, rows); + // If type-bind exists, set their corresponding models for later use in value changes subscription + if (typeBindToFieldList.length > 0) { + typeBindToFieldList.forEach((typeBindToField) => { + const foundTypeBindModel = this.findById(typeBindToField, rows); + if (hasValue(foundTypeBindModel)) { + this.setTypeBindModels(foundTypeBindModel, typeBindToField); + } + }); } - if (hasValue(typeBindModel)) { - this.setTypeBindModel(typeBindModel); - } return rows; } diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts index 5c31eafff77..c29b5c595f8 100644 --- a/src/app/shared/form/builder/parsers/field-parser.ts +++ b/src/app/shared/form/builder/parsers/field-parser.ts @@ -89,6 +89,14 @@ export abstract class FieldParser { if (this.configData.input.type === ParserType.Onebox.valueOf() && this.configData?.selectableMetadata?.length > 1) { isDraggable = false; } + + let typeBindRelations = null; + if (isNotEmpty(this.configData.typeBind)) { + const typeBindToField = this.configData.typeBindToField ? this.configData.typeBindToField.replace(/\./g, '_') : undefined; + const typeField = typeBindToField ? typeBindToField : this.parserOptions.typeField; + typeBindRelations = getTypeBindRelations(this.configData.typeBind, typeField); + } + const config = { id: uniqueId() + '_array', label: this.configData.label, @@ -101,8 +109,7 @@ export abstract class FieldParser { metadataFields: this.getAllFieldIds(), hasSelectableMetadata: isNotEmpty(this.configData.selectableMetadata), isDraggable, - typeBindRelations: isNotEmpty(this.configData.typeBind) ? getTypeBindRelations(this.configData.typeBind, - this.parserOptions.typeField) : null, + typeBindRelations: typeBindRelations, groupFactory: () => { let model; if ((arrayCounter === 0)) { @@ -358,8 +365,10 @@ export abstract class FieldParser { // If typeBind is configured if (isNotEmpty(this.configData.typeBind)) { - (controlModel as DsDynamicInputModel).typeBindRelations = getTypeBindRelations(this.configData.typeBind, - this.parserOptions.typeField); + const typeBindToField = this.configData.typeBindToField ? this.configData.typeBindToField.replace(/\./g, '_') : undefined; + const typeField = typeBindToField ? typeBindToField : this.parserOptions.typeField; + + (controlModel as DsDynamicInputModel).typeBindRelations = getTypeBindRelations(this.configData.typeBind, typeField); } controlModel.securityConfigLevel = this.mapBetweenMetadataRowAndSecurityMetadataLevels(this.getFieldId()); diff --git a/src/app/shared/form/builder/parsers/row-parser.ts b/src/app/shared/form/builder/parsers/row-parser.ts index 56a6117f902..14d632c25da 100644 --- a/src/app/shared/form/builder/parsers/row-parser.ts +++ b/src/app/shared/form/builder/parsers/row-parser.ts @@ -61,16 +61,20 @@ export class RowParser { const layoutDefaultGridClass = ' col-sm-' + Math.trunc(12 / scopedFields.length); const layoutClass = ' d-flex flex-column justify-content-start'; - const parserOptions: ParserOptions = { - readOnly: readOnly, - submissionScope: submissionScope, - collectionUUID: scopeUUID, - typeField: typeField, - isInnerForm: isInnerForm, - }; - // Iterate over row's fields scopedFields.forEach((fieldData: FormFieldModel) => { + let parserOptionsTypeField = typeField; + if (fieldData.typeBindToField) { + parserOptionsTypeField = fieldData.typeBindToField.replace(/\./g, '_'); + } + + const parserOptions: ParserOptions = { + readOnly: readOnly, + submissionScope: submissionScope, + collectionUUID: scopeUUID, + typeField: parserOptionsTypeField, + isInnerForm: isInnerForm, + }; const layoutFieldClass = (fieldData.style || layoutDefaultGridClass) + layoutClass; const parserProvider = ParserFactory.getProvider(fieldData.input.type as ParserType); diff --git a/src/app/shared/form/testing/form-builder-service.mock.ts b/src/app/shared/form/testing/form-builder-service.mock.ts index 087bd7a5199..51678b94871 100644 --- a/src/app/shared/form/testing/form-builder-service.mock.ts +++ b/src/app/shared/form/testing/form-builder-service.mock.ts @@ -26,7 +26,7 @@ export function getMockFormBuilderService(): FormBuilderService { isRelationGroup: true, isConcatGroup: false, hasArrayGroupValue: true, - getTypeBindModel: new DsDynamicInputModel({ + getTypeBindModels: new DsDynamicInputModel({ name: 'dc.type', id: 'dc_type', readOnly: false, diff --git a/src/app/shared/form/testing/form-models.mock.ts b/src/app/shared/form/testing/form-models.mock.ts index a1621f0e453..122b81633c2 100644 --- a/src/app/shared/form/testing/form-models.mock.ts +++ b/src/app/shared/form/testing/form-models.mock.ts @@ -323,7 +323,7 @@ export const inputWithTypeBindConfig = { submissionId: '1234', metadataFields: [], hasSelectableMetadata: false, - getTypeBindModel: new DsDynamicInputModel({ + getTypeBindModels: new DsDynamicInputModel({ name: 'testWithTypeBind', id: 'testWithTypeBind', readOnly: false, diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts index df00af09f21..ab3f3403517 100644 --- a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts @@ -1,7 +1,4 @@ -import { - AsyncPipe, - NgClass, -} from '@angular/common'; +import { AsyncPipe } from '@angular/common'; import { Component, Input, @@ -28,7 +25,6 @@ import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators' imports: [ AsyncPipe, NgbTooltip, - NgClass, ], templateUrl: './orcid-badge-and-tooltip.component.html', styleUrl: './orcid-badge-and-tooltip.component.scss', diff --git a/src/app/submission/sections/form/section-form.component.ts b/src/app/submission/sections/form/section-form.component.ts index b4f1fc399cc..a75ed80422a 100644 --- a/src/app/submission/sections/form/section-form.component.ts +++ b/src/app/submission/sections/form/section-form.component.ts @@ -338,7 +338,6 @@ export class SubmissionSectionFormComponent extends SectionModelComponent implem sectionData, this.submissionService.getSubmissionScope(), SubmissionVisibility.isReadOnly(this.sectionData.sectionVisibility, this.submissionService.getSubmissionScope()), - null, false, this.metadataSecurityConfiguration, ); diff --git a/src/app/submission/sections/license/section-license.component.spec.ts b/src/app/submission/sections/license/section-license.component.spec.ts index 557247b01b6..88a4fb158d2 100644 --- a/src/app/submission/sections/license/section-license.component.spec.ts +++ b/src/app/submission/sections/license/section-license.component.spec.ts @@ -74,11 +74,15 @@ import { SectionsService } from '../sections.service'; import { SubmissionSectionLicenseComponent } from './section-license.component'; function getMockDsDynamicTypeBindRelationService(): DsDynamicTypeBindRelationService { - return jasmine.createSpyObj('DsDynamicTypeBindRelationService', { + const service = jasmine.createSpyObj('DsDynamicTypeBindRelationService', { getRelatedFormModel: jasmine.createSpy('getRelatedFormModel'), matchesCondition: jasmine.createSpy('matchesCondition'), subscribeRelations: jasmine.createSpy('subscribeRelations'), }); + + service.activatedSubscriptionsByMetadataKey = new Set(); + + return service; } const collectionId = mockSubmissionCollectionId; diff --git a/src/themes/custom/app/submission/sections/upload/file/section-upload-file.component.ts b/src/themes/custom/app/submission/sections/upload/file/section-upload-file.component.ts index a6a39ba657a..9304628e006 100644 --- a/src/themes/custom/app/submission/sections/upload/file/section-upload-file.component.ts +++ b/src/themes/custom/app/submission/sections/upload/file/section-upload-file.component.ts @@ -4,7 +4,6 @@ import { TranslateModule } from '@ngx-translate/core'; import { SubmissionSectionUploadFileComponent as BaseComponent } from 'src/app/submission/sections/upload/file/section-upload-file.component'; import { BtnDisabledDirective } from '../../../../../../../app/shared/btn-disabled.directive'; -import { ThemedFileDownloadLinkComponent } from '../../../../../../../app/shared/file-download-link/themed-file-download-link.component'; import { SubmissionSectionUploadFileViewComponent } from '../../../../../../../app/submission/sections/upload/file/view/section-upload-file-view.component'; @Component({ @@ -17,7 +16,6 @@ import { SubmissionSectionUploadFileViewComponent } from '../../../../../../../a AsyncPipe, BtnDisabledDirective, SubmissionSectionUploadFileViewComponent, - ThemedFileDownloadLinkComponent, TranslateModule, ], })