diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.spec.ts index 6d5839f867..e1d12650fe 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.spec.ts @@ -33,6 +33,8 @@ export let FORM_GROUP_TEST_GROUP; const config: GlobalConfig = MOCK_SUBMISSION_CONFIG; +const submissionId = '1234'; + function init() { FORM_GROUP_TEST_MODEL_CONFIG = { disabled: false, @@ -67,6 +69,7 @@ function init() { }] } as FormFieldModel] } as FormRowModel], + submissionId, id: 'dc_contributor_author', label: 'Authors', mandatoryField: 'dc.contributor.author', @@ -183,7 +186,7 @@ describe('DsDynamicRelationGroupComponent test suite', () => { it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => { const formConfig = { rows: groupComp.model.formConfiguration } as SubmissionFormsModel; - const formModel = service.modelFromConfiguration(formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly); + const formModel = service.modelFromConfiguration(submissionId, formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly); const chips = new Chips([], 'value', 'dc.contributor.author'); groupComp.formCollapsed.subscribe((value) => { expect(value).toEqual(false); @@ -257,7 +260,7 @@ describe('DsDynamicRelationGroupComponent test suite', () => { it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => { const formConfig = { rows: groupComp.model.formConfiguration } as SubmissionFormsModel; - const formModel = service.modelFromConfiguration(formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly); + const formModel = service.modelFromConfiguration(submissionId, formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly); const chips = new Chips(modelValue, 'value', 'dc.contributor.author'); groupComp.formCollapsed.subscribe((value) => { expect(value).toEqual(true); 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 62b6b4effa..ea62eeb4ce 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 @@ -93,6 +93,7 @@ export class DsDynamicRelationGroupComponent extends DynamicFormControlComponent this.formId = this.formService.getUniqueId(this.model.id); this.formModel = this.formBuilderService.modelFromConfiguration( + this.model.submissionId, config, this.model.scopeUUID, {}, diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model.ts index e6d2b95afc..c1f76f0431 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model.ts @@ -10,6 +10,7 @@ export const PLACEHOLDER_PARENT_METADATA = '#PLACEHOLDER_PARENT_METADATA_VALUE#' * Dynamic Group Model configuration interface */ export interface DynamicRelationGroupModelConfig extends DsDynamicInputModelConfig { + submissionId: string, formConfiguration: FormRowModel[], mandatoryField: string, relationFields: string[], @@ -21,6 +22,7 @@ export interface DynamicRelationGroupModelConfig extends DsDynamicInputModelConf * Dynamic Group Model class */ export class DynamicRelationGroupModel extends DsDynamicInputModel { + @serializable() submissionId: string; @serializable() formConfiguration: FormRowModel[]; @serializable() mandatoryField: string; @serializable() relationFields: string[]; @@ -32,6 +34,7 @@ export class DynamicRelationGroupModel extends DsDynamicInputModel { constructor(config: DynamicRelationGroupModelConfig, layout?: DynamicFormControlLayout) { super(config, layout); + this.submissionId = config.submissionId; this.formConfiguration = config.formConfiguration; this.mandatoryField = config.mandatoryField; this.relationFields = config.relationFields; diff --git a/src/app/shared/form/builder/form-builder.service.spec.ts b/src/app/shared/form/builder/form-builder.service.spec.ts index 58a1696a92..496c06629a 100644 --- a/src/app/shared/form/builder/form-builder.service.spec.ts +++ b/src/app/shared/form/builder/form-builder.service.spec.ts @@ -56,6 +56,8 @@ describe('FormBuilderService test suite', () => { let testFormConfiguration: SubmissionFormsModel; let service: FormBuilderService; + const submissionId = '1234'; + function testValidator() { return {testValidator: {valid: true}}; } @@ -204,6 +206,7 @@ describe('FormBuilderService test suite', () => { new DynamicListRadioGroupModel({id: 'testRadioList', authorityOptions: authorityOptions, repeatable: false}), new DynamicRelationGroupModel({ + submissionId, id: 'testRelationGroup', formConfiguration: [{ fields: [{ @@ -406,7 +409,7 @@ describe('FormBuilderService test suite', () => { }); it('should create an array of form models', () => { - const formModel = service.modelFromConfiguration(testFormConfiguration, 'testScopeUUID'); + const formModel = service.modelFromConfiguration(submissionId, testFormConfiguration, 'testScopeUUID'); expect(formModel[0] instanceof DynamicRowGroupModel).toBe(true); expect((formModel[0] as DynamicRowGroupModel).group.length).toBe(3); @@ -427,7 +430,7 @@ describe('FormBuilderService test suite', () => { }); it('should return form\'s fields value from form model', () => { - const formModel = service.modelFromConfiguration(testFormConfiguration, 'testScopeUUID'); + const formModel = service.modelFromConfiguration(submissionId, testFormConfiguration, 'testScopeUUID'); let value = {} as any; expect(service.getValueFromModel(formModel)).toEqual(value); @@ -448,7 +451,7 @@ describe('FormBuilderService test suite', () => { }); it('should clear all form\'s fields value', () => { - const formModel = service.modelFromConfiguration(testFormConfiguration, 'testScopeUUID'); + const formModel = service.modelFromConfiguration(submissionId, testFormConfiguration, 'testScopeUUID'); const value = {} as any; ((formModel[0] as DynamicRowGroupModel).get(1) as DsDynamicInputModel).valueUpdates.next('test'); @@ -460,7 +463,7 @@ describe('FormBuilderService test suite', () => { }); it('should return true when model has a custom group model as parent', () => { - const formModel = service.modelFromConfiguration(testFormConfiguration, 'testScopeUUID'); + const formModel = service.modelFromConfiguration(submissionId, testFormConfiguration, 'testScopeUUID'); let model = service.findById('dc_identifier_QUALDROP_VALUE', formModel); let modelParent = service.findById('dc_identifier_QUALDROP_GROUP', formModel); model.parent = modelParent; @@ -489,7 +492,7 @@ describe('FormBuilderService test suite', () => { }); it('should return true when model value is a map', () => { - const formModel = service.modelFromConfiguration(testFormConfiguration, 'testScopeUUID'); + const formModel = service.modelFromConfiguration(submissionId, testFormConfiguration, 'testScopeUUID'); const model = service.findById('dc_identifier_QUALDROP_VALUE', formModel); const modelParent = service.findById('dc_identifier_QUALDROP_GROUP', formModel); model.parent = modelParent; @@ -498,7 +501,7 @@ describe('FormBuilderService test suite', () => { }); it('should return true when model is a Qualdrop Group', () => { - const formModel = service.modelFromConfiguration(testFormConfiguration, 'testScopeUUID'); + const formModel = service.modelFromConfiguration(submissionId, testFormConfiguration, 'testScopeUUID'); let model = service.findById('dc_identifier_QUALDROP_GROUP', formModel); expect(service.isQualdropGroup(model)).toBe(true); @@ -509,7 +512,7 @@ describe('FormBuilderService test suite', () => { }); it('should return true when model is a Custom or List Group', () => { - const formModel = service.modelFromConfiguration(testFormConfiguration, 'testScopeUUID'); + const formModel = service.modelFromConfiguration(submissionId, testFormConfiguration, 'testScopeUUID'); let model = service.findById('dc_identifier_QUALDROP_GROUP', formModel); expect(service.isCustomOrListGroup(model)).toBe(true); @@ -528,7 +531,7 @@ describe('FormBuilderService test suite', () => { }); it('should return true when model is a Custom Group', () => { - const formModel = service.modelFromConfiguration(testFormConfiguration, 'testScopeUUID'); + const formModel = service.modelFromConfiguration(submissionId, testFormConfiguration, 'testScopeUUID'); let model = service.findById('dc_identifier_QUALDROP_GROUP', formModel); expect(service.isCustomGroup(model)).toBe(true); diff --git a/src/app/shared/form/builder/form-builder.service.ts b/src/app/shared/form/builder/form-builder.service.ts index 21e702aabb..f867d1f79c 100644 --- a/src/app/shared/form/builder/form-builder.service.ts +++ b/src/app/shared/form/builder/form-builder.service.ts @@ -10,7 +10,7 @@ import { DynamicFormArrayModel, DynamicFormControlModel, DynamicFormGroupModel, - DynamicFormService, + DynamicFormService, DynamicFormValidationService, DynamicPathable, JSONUtils, } from '@ng-dynamic-forms/core'; @@ -33,6 +33,13 @@ import { isNgbDateStruct } from '../../date.util'; @Injectable() export class FormBuilderService extends DynamicFormService { + constructor( + validationService: DynamicFormValidationService, + protected rowParser: RowParser + ) { + super(validationService); + } + findById(id: string, groupModel: DynamicFormControlModel[], arrayIndex = null): DynamicFormControlModel | null { let result = null; @@ -198,13 +205,13 @@ export class FormBuilderService extends DynamicFormService { return result; } - modelFromConfiguration(json: string | SubmissionFormsModel, scopeUUID: string, initFormValues: any = {}, submissionScope?: string, readOnly = false): DynamicFormControlModel[] | never { + modelFromConfiguration(submissionId: string, json: string | SubmissionFormsModel, scopeUUID: string, sectionData: any = {}, submissionScope?: string, readOnly = false): DynamicFormControlModel[] | never { let rows: DynamicFormControlModel[] = []; const rawData = typeof json === 'string' ? JSON.parse(json, JSONUtils.parseReviver) : json; if (rawData.rows && !isEmpty(rawData.rows)) { rawData.rows.forEach((currentRow) => { - const rowParsed = new RowParser(currentRow, scopeUUID, initFormValues, submissionScope, readOnly).parse(); + const rowParsed = this.rowParser.parse(submissionId, currentRow, scopeUUID, sectionData, submissionScope, readOnly); if (isNotNull(rowParsed)) { if (Array.isArray(rowParsed)) { rows = rows.concat(rowParsed); diff --git a/src/app/shared/form/builder/parsers/concat-field-parser.ts b/src/app/shared/form/builder/parsers/concat-field-parser.ts index 6323905555..449827c56b 100644 --- a/src/app/shared/form/builder/parsers/concat-field-parser.ts +++ b/src/app/shared/form/builder/parsers/concat-field-parser.ts @@ -1,4 +1,11 @@ -import { FieldParser } from './field-parser'; +import { Inject } from '@angular/core'; +import { + CONFIG_DATA, + FieldParser, + INIT_FORM_VALUES, + PARSER_OPTIONS, + SUBMISSION_ID +} from './field-parser'; import { FormFieldModel } from '../models/form-field.model'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; import { DynamicFormControlLayout, DynamicInputModel, DynamicInputModelConfig } from '@ng-dynamic-forms/core'; @@ -14,13 +21,15 @@ import { ParserOptions } from './parser-options'; export class ConcatFieldParser extends FieldParser { - constructor(protected configData: FormFieldModel, - protected initFormValues, - protected parserOptions: ParserOptions, + constructor( + @Inject(SUBMISSION_ID) submissionId: string, + @Inject(CONFIG_DATA) configData: FormFieldModel, + @Inject(INIT_FORM_VALUES) initFormValues, + @Inject(PARSER_OPTIONS) parserOptions: ParserOptions, protected separator: string, protected firstPlaceholder: string = null, protected secondPlaceholder: string = null) { - super(configData, initFormValues, parserOptions); + super(submissionId, configData, initFormValues, parserOptions); this.separator = separator; this.firstPlaceholder = firstPlaceholder; diff --git a/src/app/shared/form/builder/parsers/date-field-parser.spec.ts b/src/app/shared/form/builder/parsers/date-field-parser.spec.ts index bbcfa60621..efa4f3cdb5 100644 --- a/src/app/shared/form/builder/parsers/date-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/date-field-parser.spec.ts @@ -1,6 +1,4 @@ import { FormFieldModel } from '../models/form-field.model'; -import { DynamicConcatModel } from '../ds-dynamic-form-ui/models/ds-dynamic-concat.model'; -import { SeriesFieldParser } from './series-field-parser'; import { DateFieldParser } from './date-field-parser'; import { DynamicDsDatePickerModel } from '../ds-dynamic-form-ui/models/date-picker/date-picker.model'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; @@ -10,6 +8,7 @@ describe('DateFieldParser test suite', () => { let field: FormFieldModel; let initFormValues: any = {}; + const submissionId = '1234'; const parserOptions: ParserOptions = { readOnly: false, submissionScope: null, @@ -37,13 +36,13 @@ describe('DateFieldParser test suite', () => { }); it('should init parser properly', () => { - const parser = new DateFieldParser(field, initFormValues, parserOptions); + const parser = new DateFieldParser(submissionId, field, initFormValues, parserOptions); expect(parser instanceof DateFieldParser).toBe(true); }); it('should return a DynamicDsDatePickerModel object when repeatable option is false', () => { - const parser = new DateFieldParser(field, initFormValues, parserOptions); + const parser = new DateFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -56,7 +55,7 @@ describe('DateFieldParser test suite', () => { }; const expectedValue = '1983-11-18'; - const parser = new DateFieldParser(field, initFormValues, parserOptions); + const parser = new DateFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); diff --git a/src/app/shared/form/builder/parsers/dropdown-field-parser.spec.ts b/src/app/shared/form/builder/parsers/dropdown-field-parser.spec.ts index 5dfdcfa5ce..8dbd68e05a 100644 --- a/src/app/shared/form/builder/parsers/dropdown-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/dropdown-field-parser.spec.ts @@ -6,6 +6,7 @@ import { ParserOptions } from './parser-options'; describe('DropdownFieldParser test suite', () => { let field: FormFieldModel; + const submissionId = '1234'; const initFormValues = {}; const parserOptions: ParserOptions = { readOnly: false, @@ -35,13 +36,13 @@ describe('DropdownFieldParser test suite', () => { }); it('should init parser properly', () => { - const parser = new DropdownFieldParser(field, initFormValues, parserOptions); + const parser = new DropdownFieldParser(submissionId, field, initFormValues, parserOptions); expect(parser instanceof DropdownFieldParser).toBe(true); }); it('should return a DynamicScrollableDropdownModel object when repeatable option is false', () => { - const parser = new DropdownFieldParser(field, initFormValues, parserOptions); + const parser = new DropdownFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -50,7 +51,7 @@ describe('DropdownFieldParser test suite', () => { it('should throw when authority is not passed', () => { field.selectableMetadata[0].authority = null; - const parser = new DropdownFieldParser(field, initFormValues, parserOptions); + const parser = new DropdownFieldParser(submissionId, field, initFormValues, parserOptions); expect(() => parser.parse()) .toThrow(); diff --git a/src/app/shared/form/builder/parsers/dropdown-field-parser.ts b/src/app/shared/form/builder/parsers/dropdown-field-parser.ts index 1623829b15..2de3206742 100644 --- a/src/app/shared/form/builder/parsers/dropdown-field-parser.ts +++ b/src/app/shared/form/builder/parsers/dropdown-field-parser.ts @@ -1,4 +1,12 @@ -import { FieldParser } from './field-parser'; +import { Inject } from '@angular/core'; +import { FormFieldModel } from '../models/form-field.model'; +import { + CONFIG_DATA, + FieldParser, + INIT_FORM_VALUES, + PARSER_OPTIONS, + SUBMISSION_ID +} from './field-parser'; import { DynamicFormControlLayout, } from '@ng-dynamic-forms/core'; import { DynamicScrollableDropdownModel, @@ -6,9 +14,20 @@ import { } from '../ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.model'; import { isNotEmpty } from '../../../empty.util'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; +import { ParserOptions } from './parser-options'; export class DropdownFieldParser extends FieldParser { + constructor( + @Inject(SUBMISSION_ID) submissionId: string, + @Inject(CONFIG_DATA) configData: FormFieldModel, + @Inject(INIT_FORM_VALUES) initFormValues, + @Inject(PARSER_OPTIONS) parserOptions: ParserOptions + ) { + super(submissionId, configData, initFormValues, parserOptions) + } + + public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { const dropdownModelConfig: DynamicScrollableDropdownModelConfig = this.initModel(null, label); let layout: DynamicFormControlLayout; diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts index dd37a45fba..83bdd14e9c 100644 --- a/src/app/shared/form/builder/parsers/field-parser.ts +++ b/src/app/shared/form/builder/parsers/field-parser.ts @@ -1,3 +1,4 @@ +import { Inject, InjectionToken } from '@angular/core'; import { hasValue, isNotEmpty, isNotNull, isNotUndefined } from '../../../empty.util'; import { FormFieldModel } from '../models/form-field.model'; @@ -13,12 +14,21 @@ import { setLayout } from './parser.utils'; import { AuthorityOptions } from '../../../../core/integration/models/authority-options.model'; import { ParserOptions } from './parser-options'; +export const SUBMISSION_ID: InjectionToken = new InjectionToken('submissionId'); +export const CONFIG_DATA: InjectionToken = new InjectionToken('configData'); +export const INIT_FORM_VALUES:InjectionToken = new InjectionToken('initFormValues'); +export const PARSER_OPTIONS: InjectionToken = new InjectionToken('parserOptions'); + export abstract class FieldParser { protected fieldId: string; - constructor(protected configData: FormFieldModel, protected initFormValues, protected parserOptions: ParserOptions) { - } + constructor( + @Inject(SUBMISSION_ID) protected submissionId: string, + @Inject(CONFIG_DATA) protected configData: FormFieldModel, + @Inject(INIT_FORM_VALUES) protected initFormValues: any, + @Inject(PARSER_OPTIONS) protected parserOptions: ParserOptions + ) {} public abstract modelFactory(fieldValue?: FormFieldMetadataValueObject, label?: boolean): any; diff --git a/src/app/shared/form/builder/parsers/list-field-parser.spec.ts b/src/app/shared/form/builder/parsers/list-field-parser.spec.ts index b2fa0b2089..fab5ec3888 100644 --- a/src/app/shared/form/builder/parsers/list-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/list-field-parser.spec.ts @@ -9,6 +9,7 @@ describe('ListFieldParser test suite', () => { let field: FormFieldModel; let initFormValues = {}; + const submissionId = '1234'; const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', @@ -37,13 +38,13 @@ describe('ListFieldParser test suite', () => { }); it('should init parser properly', () => { - const parser = new ListFieldParser(field, initFormValues, parserOptions); + const parser = new ListFieldParser(submissionId, field, initFormValues, parserOptions); expect(parser instanceof ListFieldParser).toBe(true); }); it('should return a DynamicListCheckboxGroupModel object when repeatable option is true', () => { - const parser = new ListFieldParser(field, initFormValues, parserOptions); + const parser = new ListFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -52,7 +53,7 @@ describe('ListFieldParser test suite', () => { it('should return a DynamicListRadioGroupModel object when repeatable option is false', () => { field.repeatable = false; - const parser = new ListFieldParser(field, initFormValues, parserOptions); + const parser = new ListFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -65,7 +66,7 @@ describe('ListFieldParser test suite', () => { }; const expectedValue = [new FormFieldMetadataValueObject('test type')]; - const parser = new ListFieldParser(field, initFormValues, parserOptions); + const parser = new ListFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); diff --git a/src/app/shared/form/builder/parsers/lookup-field-parser.spec.ts b/src/app/shared/form/builder/parsers/lookup-field-parser.spec.ts index c45d39d5bb..5e14e0c013 100644 --- a/src/app/shared/form/builder/parsers/lookup-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/lookup-field-parser.spec.ts @@ -8,6 +8,7 @@ describe('LookupFieldParser test suite', () => { let field: FormFieldModel; let initFormValues = {}; + const submissionId = '1234'; const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', @@ -36,13 +37,13 @@ describe('LookupFieldParser test suite', () => { }); it('should init parser properly', () => { - const parser = new LookupFieldParser(field, initFormValues, parserOptions); + const parser = new LookupFieldParser(submissionId, field, initFormValues, parserOptions); expect(parser instanceof LookupFieldParser).toBe(true); }); it('should return a DynamicLookupModel object when repeatable option is false', () => { - const parser = new LookupFieldParser(field, initFormValues, parserOptions); + const parser = new LookupFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -55,7 +56,7 @@ describe('LookupFieldParser test suite', () => { }; const expectedValue = new FormFieldMetadataValueObject('test journal'); - const parser = new LookupFieldParser(field, initFormValues, parserOptions); + const parser = new LookupFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); diff --git a/src/app/shared/form/builder/parsers/lookup-name-field-parser.spec.ts b/src/app/shared/form/builder/parsers/lookup-name-field-parser.spec.ts index b324ba7a7e..adc1e90166 100644 --- a/src/app/shared/form/builder/parsers/lookup-name-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/lookup-name-field-parser.spec.ts @@ -1,7 +1,5 @@ import { FormFieldModel } from '../models/form-field.model'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; -import { LookupFieldParser } from './lookup-field-parser'; -import { DynamicLookupModel } from '../ds-dynamic-form-ui/models/lookup/dynamic-lookup.model'; import { LookupNameFieldParser } from './lookup-name-field-parser'; import { DynamicLookupNameModel } from '../ds-dynamic-form-ui/models/lookup/dynamic-lookup-name.model'; import { ParserOptions } from './parser-options'; @@ -10,6 +8,7 @@ describe('LookupNameFieldParser test suite', () => { let field: FormFieldModel; let initFormValues = {}; + const submissionId = '1234'; const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', @@ -38,13 +37,13 @@ describe('LookupNameFieldParser test suite', () => { }); it('should init parser properly', () => { - const parser = new LookupNameFieldParser(field, initFormValues, parserOptions); + const parser = new LookupNameFieldParser(submissionId, field, initFormValues, parserOptions); expect(parser instanceof LookupNameFieldParser).toBe(true); }); it('should return a DynamicLookupNameModel object when repeatable option is false', () => { - const parser = new LookupNameFieldParser(field, initFormValues, parserOptions); + const parser = new LookupNameFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -57,7 +56,7 @@ describe('LookupNameFieldParser test suite', () => { }; const expectedValue = new FormFieldMetadataValueObject('test author'); - const parser = new LookupNameFieldParser(field, initFormValues, parserOptions); + const parser = new LookupNameFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); diff --git a/src/app/shared/form/builder/parsers/name-field-parser.spec.ts b/src/app/shared/form/builder/parsers/name-field-parser.spec.ts index 889244e8f2..1b0c637030 100644 --- a/src/app/shared/form/builder/parsers/name-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/name-field-parser.spec.ts @@ -10,6 +10,7 @@ describe('NameFieldParser test suite', () => { let field3: FormFieldModel; let initFormValues: any = {}; + const submissionId = '1234'; const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', @@ -69,13 +70,13 @@ describe('NameFieldParser test suite', () => { }); it('should init parser properly', () => { - const parser = new NameFieldParser(field1, initFormValues, parserOptions); + const parser = new NameFieldParser(submissionId, field1, initFormValues, parserOptions); expect(parser instanceof NameFieldParser).toBe(true); }); it('should return a DynamicConcatModel object when repeatable option is false', () => { - const parser = new NameFieldParser(field2, initFormValues, parserOptions); + const parser = new NameFieldParser(submissionId, field2, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -83,7 +84,7 @@ describe('NameFieldParser test suite', () => { }); it('should return a DynamicConcatModel object with the correct separator', () => { - const parser = new NameFieldParser(field2, initFormValues, parserOptions); + const parser = new NameFieldParser(submissionId, field2, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -96,7 +97,7 @@ describe('NameFieldParser test suite', () => { }; const expectedValue = new FormFieldMetadataValueObject('test, name'); - const parser = new NameFieldParser(field1, initFormValues, parserOptions); + const parser = new NameFieldParser(submissionId, field1, initFormValues, parserOptions); const fieldModel = parser.parse(); diff --git a/src/app/shared/form/builder/parsers/name-field-parser.ts b/src/app/shared/form/builder/parsers/name-field-parser.ts index 896b3cc478..e5ecb034ea 100644 --- a/src/app/shared/form/builder/parsers/name-field-parser.ts +++ b/src/app/shared/form/builder/parsers/name-field-parser.ts @@ -1,10 +1,17 @@ +import { Inject } from '@angular/core'; import { FormFieldModel } from '../models/form-field.model'; import { ConcatFieldParser } from './concat-field-parser'; +import { CONFIG_DATA, INIT_FORM_VALUES, PARSER_OPTIONS, SUBMISSION_ID } from './field-parser'; import { ParserOptions } from './parser-options'; export class NameFieldParser extends ConcatFieldParser { - constructor(protected configData: FormFieldModel, protected initFormValues, protected parserOptions: ParserOptions) { - super(configData, initFormValues, parserOptions, ',', 'form.last-name', 'form.first-name'); + constructor( + @Inject(SUBMISSION_ID) submissionId: string, + @Inject(CONFIG_DATA) configData: FormFieldModel, + @Inject(INIT_FORM_VALUES) initFormValues, + @Inject(PARSER_OPTIONS) parserOptions: ParserOptions + ) { + super(submissionId, configData, initFormValues, parserOptions, ',', 'form.last-name', 'form.first-name'); } } diff --git a/src/app/shared/form/builder/parsers/onebox-field-parser.spec.ts b/src/app/shared/form/builder/parsers/onebox-field-parser.spec.ts index 89c576bf3a..4668b3017d 100644 --- a/src/app/shared/form/builder/parsers/onebox-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/onebox-field-parser.spec.ts @@ -10,6 +10,7 @@ describe('OneboxFieldParser test suite', () => { let field2: FormFieldModel; let field3: FormFieldModel; + const submissionId = '1234'; const initFormValues = {}; const parserOptions: ParserOptions = { readOnly: false, @@ -70,13 +71,13 @@ describe('OneboxFieldParser test suite', () => { }); it('should init parser properly', () => { - const parser = new OneboxFieldParser(field1, initFormValues, parserOptions); + const parser = new OneboxFieldParser(submissionId, field1, initFormValues, parserOptions); expect(parser instanceof OneboxFieldParser).toBe(true); }); it('should return a DynamicQualdropModel object when selectableMetadata is multiple', () => { - const parser = new OneboxFieldParser(field2, initFormValues, parserOptions); + const parser = new OneboxFieldParser(submissionId, field2, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -84,7 +85,7 @@ describe('OneboxFieldParser test suite', () => { }); it('should return a DsDynamicInputModel object when selectableMetadata is not multiple', () => { - const parser = new OneboxFieldParser(field3, initFormValues, parserOptions); + const parser = new OneboxFieldParser(submissionId, field3, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -92,7 +93,7 @@ describe('OneboxFieldParser test suite', () => { }); it('should return a DynamicTypeaheadModel object when selectableMetadata has authority', () => { - const parser = new OneboxFieldParser(field1, initFormValues, parserOptions); + const parser = new OneboxFieldParser(submissionId, field1, initFormValues, parserOptions); const fieldModel = parser.parse(); diff --git a/src/app/shared/form/builder/parsers/parser-factory.ts b/src/app/shared/form/builder/parsers/parser-factory.ts index 2cbee18783..67d8f31740 100644 --- a/src/app/shared/form/builder/parsers/parser-factory.ts +++ b/src/app/shared/form/builder/parsers/parser-factory.ts @@ -1,6 +1,12 @@ +import { StaticProvider } from '@angular/core'; import { ParserType } from './parser-type'; -import { GenericConstructor } from '../../../../core/shared/generic-constructor'; -import { FieldParser } from './field-parser'; +import { + CONFIG_DATA, + FieldParser, + INIT_FORM_VALUES, + PARSER_OPTIONS, + SUBMISSION_ID +} from './field-parser'; import { DateFieldParser } from './date-field-parser'; import { DropdownFieldParser } from './dropdown-field-parser'; import { RelationGroupFieldParser } from './relation-group-field-parser'; @@ -13,41 +19,92 @@ import { SeriesFieldParser } from './series-field-parser'; import { TagFieldParser } from './tag-field-parser'; import { TextareaFieldParser } from './textarea-field-parser'; +const fieldParserDeps = [ + SUBMISSION_ID, + CONFIG_DATA, + INIT_FORM_VALUES, + PARSER_OPTIONS, +]; + export class ParserFactory { - public static getConstructor(type: ParserType): GenericConstructor { + public static getProvider(type: ParserType): StaticProvider { switch (type) { case ParserType.Date: { - return DateFieldParser + return { + provide: FieldParser, + useClass: DateFieldParser, + deps: [...fieldParserDeps] + } } case ParserType.Dropdown: { - return DropdownFieldParser + return { + provide: FieldParser, + useClass: DropdownFieldParser, + deps: [...fieldParserDeps] + } } case ParserType.RelationGroup: { - return RelationGroupFieldParser + return { + provide: FieldParser, + useClass: RelationGroupFieldParser, + deps: [...fieldParserDeps] + } } case ParserType.List: { - return ListFieldParser + return { + provide: FieldParser, + useClass: ListFieldParser, + deps: [...fieldParserDeps] + } } case ParserType.Lookup: { - return LookupFieldParser + return { + provide: FieldParser, + useClass: LookupFieldParser, + deps: [...fieldParserDeps] + } } case ParserType.LookupName: { - return LookupNameFieldParser + return { + provide: FieldParser, + useClass: LookupNameFieldParser, + deps: [...fieldParserDeps] + } } case ParserType.Onebox: { - return OneboxFieldParser + return { + provide: FieldParser, + useClass: OneboxFieldParser, + deps: [...fieldParserDeps] + } } case ParserType.Name: { - return NameFieldParser + return { + provide: FieldParser, + useClass: NameFieldParser, + deps: [...fieldParserDeps] + } } case ParserType.Series: { - return SeriesFieldParser + return { + provide: FieldParser, + useClass: SeriesFieldParser, + deps: [...fieldParserDeps] + } } case ParserType.Tag: { - return TagFieldParser + return { + provide: FieldParser, + useClass: TagFieldParser, + deps: [...fieldParserDeps] + } } case ParserType.Textarea: { - return TextareaFieldParser + return { + provide: FieldParser, + useClass: TextareaFieldParser, + deps: [...fieldParserDeps] + } } default: { diff --git a/src/app/shared/form/builder/parsers/relation-group-field-parser.spec.ts b/src/app/shared/form/builder/parsers/relation-group-field-parser.spec.ts index e6bf0dc2c8..84f3df0365 100644 --- a/src/app/shared/form/builder/parsers/relation-group-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/relation-group-field-parser.spec.ts @@ -8,6 +8,7 @@ describe('RelationGroupFieldParser test suite', () => { let field: FormFieldModel; let initFormValues = {}; + const submissionId = '1234'; const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', @@ -71,13 +72,13 @@ describe('RelationGroupFieldParser test suite', () => { }); it('should init parser properly', () => { - const parser = new RelationGroupFieldParser(field, initFormValues, parserOptions); + const parser = new RelationGroupFieldParser(submissionId, field, initFormValues, parserOptions); expect(parser instanceof RelationGroupFieldParser).toBe(true); }); it('should return a DynamicRelationGroupModel object', () => { - const parser = new RelationGroupFieldParser(field, initFormValues, parserOptions); + const parser = new RelationGroupFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -86,7 +87,7 @@ describe('RelationGroupFieldParser test suite', () => { it('should throw when rows configuration is empty', () => { field.rows = null; - const parser = new RelationGroupFieldParser(field, initFormValues, parserOptions); + const parser = new RelationGroupFieldParser(submissionId, field, initFormValues, parserOptions); expect(() => parser.parse()) .toThrow(); @@ -97,7 +98,7 @@ describe('RelationGroupFieldParser test suite', () => { author: [new FormFieldMetadataValueObject('test author')], affiliation: [new FormFieldMetadataValueObject('test affiliation')] }; - const parser = new RelationGroupFieldParser(field, initFormValues, parserOptions); + const parser = new RelationGroupFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); const expectedValue = [{ diff --git a/src/app/shared/form/builder/parsers/relation-group-field-parser.ts b/src/app/shared/form/builder/parsers/relation-group-field-parser.ts index b3f6e749f3..01699d9e78 100644 --- a/src/app/shared/form/builder/parsers/relation-group-field-parser.ts +++ b/src/app/shared/form/builder/parsers/relation-group-field-parser.ts @@ -15,6 +15,7 @@ export class RelationGroupFieldParser extends FieldParser { public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean) { const modelConfiguration: DynamicRelationGroupModelConfig = this.initModel(null, label); + modelConfiguration.submissionId = this.submissionId; modelConfiguration.scopeUUID = this.parserOptions.authorityUuid; modelConfiguration.submissionScope = this.parserOptions.submissionScope; if (this.configData && this.configData.rows && this.configData.rows.length > 0) { diff --git a/src/app/shared/form/builder/parsers/row-parser.spec.ts b/src/app/shared/form/builder/parsers/row-parser.spec.ts index 58b1d1de99..435c6a6426 100644 --- a/src/app/shared/form/builder/parsers/row-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/row-parser.spec.ts @@ -17,6 +17,7 @@ describe('RowParser test suite', () => { let row9: FormRowModel; let row10: FormRowModel; + const submissionId = '1234'; const scopeUUID = 'testScopeUUID'; const initFormValues = {}; const submissionScope = 'WORKSPACE'; @@ -328,76 +329,98 @@ describe('RowParser test suite', () => { }); it('should init parser properly', () => { - let parser = new RowParser(row1, scopeUUID, initFormValues, submissionScope, readOnly); - - expect(parser instanceof RowParser).toBe(true); - - parser = new RowParser(row2, scopeUUID, initFormValues, submissionScope, readOnly); - - expect(parser instanceof RowParser).toBe(true); - - parser = new RowParser(row3, scopeUUID, initFormValues, submissionScope, readOnly); - - expect(parser instanceof RowParser).toBe(true); - - parser = new RowParser(row4, scopeUUID, initFormValues, submissionScope, readOnly); - - expect(parser instanceof RowParser).toBe(true); - - parser = new RowParser(row5, scopeUUID, initFormValues, submissionScope, readOnly); - - expect(parser instanceof RowParser).toBe(true); - - parser = new RowParser(row6, scopeUUID, initFormValues, submissionScope, readOnly); - - expect(parser instanceof RowParser).toBe(true); - - parser = new RowParser(row7, scopeUUID, initFormValues, submissionScope, readOnly); - - expect(parser instanceof RowParser).toBe(true); - - parser = new RowParser(row8, scopeUUID, initFormValues, submissionScope, readOnly); - - expect(parser instanceof RowParser).toBe(true); - - parser = new RowParser(row9, scopeUUID, initFormValues, submissionScope, readOnly); - - expect(parser instanceof RowParser).toBe(true); - - parser = new RowParser(row10, scopeUUID, initFormValues, submissionScope, readOnly); + const parser = new RowParser(undefined); expect(parser instanceof RowParser).toBe(true); }); - it('should return a DynamicRowGroupModel object', () => { - const parser = new RowParser(row1, scopeUUID, initFormValues, submissionScope, readOnly); + describe('parse', () => { + it('should return a DynamicRowGroupModel object', () => { + const parser = new RowParser(undefined); - const rowModel = parser.parse(); + const rowModel = parser.parse(submissionId, row1, scopeUUID, initFormValues, submissionScope, readOnly); - expect(rowModel instanceof DynamicRowGroupModel).toBe(true); - }); + expect(rowModel instanceof DynamicRowGroupModel).toBe(true); + }); - it('should return a row with three fields', () => { - const parser = new RowParser(row1, scopeUUID, initFormValues, submissionScope, readOnly); + it('should return a row with three fields', () => { + const parser = new RowParser(undefined); - const rowModel = parser.parse(); + const rowModel = parser.parse(submissionId, row1, scopeUUID, initFormValues, submissionScope, readOnly); - expect((rowModel as DynamicRowGroupModel).group.length).toBe(3); - }); + expect((rowModel as DynamicRowGroupModel).group.length).toBe(3); + }); - it('should return a DynamicRowArrayModel object', () => { - const parser = new RowParser(row2, scopeUUID, initFormValues, submissionScope, readOnly); + it('should return a DynamicRowArrayModel object', () => { + const parser = new RowParser(undefined); - const rowModel = parser.parse(); + const rowModel = parser.parse(submissionId, row2, scopeUUID, initFormValues, submissionScope, readOnly); - expect(rowModel instanceof DynamicRowArrayModel).toBe(true); - }); + expect(rowModel instanceof DynamicRowArrayModel).toBe(true); + }); - it('should return a row that contains only scoped fields', () => { - const parser = new RowParser(row3, scopeUUID, initFormValues, submissionScope, readOnly); + it('should return a row that contains only scoped fields', () => { + const parser = new RowParser(undefined); - const rowModel = parser.parse(); + const rowModel = parser.parse(submissionId, row3, scopeUUID, initFormValues, submissionScope, readOnly); - expect((rowModel as DynamicRowGroupModel).group.length).toBe(1); + expect((rowModel as DynamicRowGroupModel).group.length).toBe(1); + }); + + it('should be able to parse a dropdown combo field', () => { + const parser = new RowParser(undefined); + + const rowModel = parser.parse(submissionId, row4, scopeUUID, initFormValues, submissionScope, readOnly); + + expect(rowModel).toBeDefined(); + }); + + it('should be able to parse a lookup-name field', () => { + const parser = new RowParser(undefined); + + const rowModel = parser.parse(submissionId, row5, scopeUUID, initFormValues, submissionScope, readOnly); + + expect(rowModel).toBeDefined(); + }); + + it('should be able to parse a list field', () => { + const parser = new RowParser(undefined); + + const rowModel = parser.parse(submissionId, row6, scopeUUID, initFormValues, submissionScope, readOnly); + + expect(rowModel).toBeDefined(); + }); + + it('should be able to parse a date field', () => { + const parser = new RowParser(undefined); + + const rowModel = parser.parse(submissionId, row7, scopeUUID, initFormValues, submissionScope, readOnly); + + expect(rowModel).toBeDefined(); + }); + + it('should be able to parse a tag field', () => { + const parser = new RowParser(undefined); + + const rowModel = parser.parse(submissionId, row8, scopeUUID, initFormValues, submissionScope, readOnly); + + expect(rowModel).toBeDefined(); + }); + + it('should be able to parse a textarea field', () => { + const parser = new RowParser(undefined); + + const rowModel = parser.parse(submissionId, row9, scopeUUID, initFormValues, submissionScope, readOnly); + + expect(rowModel).toBeDefined(); + }); + + it('should be able to parse a group field', () => { + const parser = new RowParser(undefined); + + const rowModel = parser.parse(submissionId, row10, scopeUUID, initFormValues, submissionScope, readOnly); + + expect(rowModel).toBeDefined(); + }); }); }); diff --git a/src/app/shared/form/builder/parsers/row-parser.ts b/src/app/shared/form/builder/parsers/row-parser.ts index 0bb8a0e89a..72737cfaa9 100644 --- a/src/app/shared/form/builder/parsers/row-parser.ts +++ b/src/app/shared/form/builder/parsers/row-parser.ts @@ -1,30 +1,42 @@ -import { DYNAMIC_FORM_CONTROL_TYPE_ARRAY, DynamicFormGroupModelConfig } from '@ng-dynamic-forms/core'; +import { Injectable, Injector } from '@angular/core'; +import { + DYNAMIC_FORM_CONTROL_TYPE_ARRAY, + DynamicFormGroupModelConfig +} from '@ng-dynamic-forms/core'; import { uniqueId } from 'lodash'; import { IntegrationSearchOptions } from '../../../../core/integration/models/integration-options.model'; -import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from '../ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model'; -import { DynamicRowGroupModel } from '../ds-dynamic-form-ui/models/ds-dynamic-row-group-model'; import { isEmpty } from '../../../empty.util'; -import { setLayout } from './parser.utils'; +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 { FormFieldModel } from '../models/form-field.model'; -import { ParserType } from './parser-type'; -import { ParserOptions } from './parser-options'; +import { + CONFIG_DATA, + FieldParser, + INIT_FORM_VALUES, + PARSER_OPTIONS, + SUBMISSION_ID +} from './field-parser'; import { ParserFactory } from './parser-factory'; +import { ParserOptions } from './parser-options'; +import { ParserType } from './parser-type'; +import { setLayout } from './parser.utils'; export const ROW_ID_PREFIX = 'df-row-group-config-'; +@Injectable({ + providedIn: 'root' +}) export class RowParser { - protected authorityOptions: IntegrationSearchOptions; - - constructor(protected rowData, - protected scopeUUID, - protected initFormValues: any, - protected submissionScope, - protected readOnly: boolean) { - this.authorityOptions = new IntegrationSearchOptions(scopeUUID); + constructor(private parentInjector: Injector) { } - public parse(): DynamicRowGroupModel { + public parse(submissionId: string, + rowData, + scopeUUID, + initFormValues: any, + submissionScope, + readOnly: boolean): DynamicRowGroupModel { let fieldModel: any = null; let parsedResult = null; const config: DynamicFormGroupModelConfig = { @@ -32,31 +44,44 @@ export class RowParser { group: [], }; - const scopedFields: FormFieldModel[] = this.filterScopedFields(this.rowData.fields); + const authorityOptions = new IntegrationSearchOptions(scopeUUID); + + const scopedFields: FormFieldModel[] = this.filterScopedFields(rowData.fields, submissionScope); const layoutDefaultGridClass = ' col-sm-' + Math.trunc(12 / scopedFields.length); const layoutClass = ' d-flex flex-column justify-content-start'; const parserOptions: ParserOptions = { - readOnly: this.readOnly, - submissionScope: this.submissionScope, - authorityUuid: this.authorityOptions.uuid + readOnly: readOnly, + submissionScope: submissionScope, + authorityUuid: authorityOptions.uuid }; // Iterate over row's fields scopedFields.forEach((fieldData: FormFieldModel) => { const layoutFieldClass = (fieldData.style || layoutDefaultGridClass) + layoutClass; - const parserCo = ParserFactory.getConstructor(fieldData.input.type as ParserType); - if (parserCo) { - fieldModel = new parserCo(fieldData, this.initFormValues, parserOptions).parse(); + const parserProvider = ParserFactory.getProvider(fieldData.input.type as ParserType); + if (parserProvider) { + const fieldInjector = Injector.create({ + providers: [ + parserProvider, + { provide: SUBMISSION_ID, useValue: submissionId }, + { provide: CONFIG_DATA, useValue: fieldData }, + { provide: INIT_FORM_VALUES, useValue: initFormValues }, + { provide: PARSER_OPTIONS, useValue: parserOptions } + ], + parent: this.parentInjector + }); + + fieldModel = fieldInjector.get(FieldParser).parse(); } else { - throw new Error(`unknown form control model type "${fieldData.input.type}" defined for Input field with label "${fieldData.label}".`, ); + throw new Error(`unknown form control model type "${fieldData.input.type}" defined for Input field with label "${fieldData.label}".`,); } if (fieldModel) { if (fieldModel.type === DYNAMIC_FORM_CONTROL_TYPE_ARRAY || fieldModel.type === DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP) { - if (this.rowData.fields.length > 1) { + if (rowData.fields.length > 1) { setLayout(fieldModel, 'grid', 'host', layoutFieldClass); config.group.push(fieldModel); // if (isEmpty(parsedResult)) { @@ -98,15 +123,15 @@ export class RowParser { return parsedResult; } - checksFieldScope(fieldScope) { - return (isEmpty(fieldScope) || isEmpty(this.submissionScope) || fieldScope === this.submissionScope); + checksFieldScope(fieldScope, submissionScope) { + return (isEmpty(fieldScope) || isEmpty(submissionScope) || fieldScope === submissionScope); } - filterScopedFields(fields: FormFieldModel[]): FormFieldModel[] { + filterScopedFields(fields: FormFieldModel[], submissionScope): FormFieldModel[] { const filteredFields: FormFieldModel[] = []; fields.forEach((field: FormFieldModel) => { // Whether field scope doesn't match the submission scope, skip it - if (this.checksFieldScope(field.scope)) { + if (this.checksFieldScope(field.scope, submissionScope)) { filteredFields.push(field); } }); diff --git a/src/app/shared/form/builder/parsers/series-field-parser.spec.ts b/src/app/shared/form/builder/parsers/series-field-parser.spec.ts index 95351d027f..ceb4e96320 100644 --- a/src/app/shared/form/builder/parsers/series-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/series-field-parser.spec.ts @@ -8,6 +8,7 @@ describe('SeriesFieldParser test suite', () => { let field: FormFieldModel; let initFormValues: any = {}; + const submissionId = '1234'; const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', @@ -32,13 +33,13 @@ describe('SeriesFieldParser test suite', () => { }); it('should init parser properly', () => { - const parser = new SeriesFieldParser(field, initFormValues, parserOptions); + const parser = new SeriesFieldParser(submissionId, field, initFormValues, parserOptions); expect(parser instanceof SeriesFieldParser).toBe(true); }); it('should return a DynamicConcatModel object when repeatable option is false', () => { - const parser = new SeriesFieldParser(field, initFormValues, parserOptions); + const parser = new SeriesFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -46,7 +47,7 @@ describe('SeriesFieldParser test suite', () => { }); it('should return a DynamicConcatModel object with the correct separator', () => { - const parser = new SeriesFieldParser(field, initFormValues, parserOptions); + const parser = new SeriesFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -59,7 +60,7 @@ describe('SeriesFieldParser test suite', () => { }; const expectedValue = new FormFieldMetadataValueObject('test; series'); - const parser = new SeriesFieldParser(field, initFormValues, parserOptions); + const parser = new SeriesFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); diff --git a/src/app/shared/form/builder/parsers/series-field-parser.ts b/src/app/shared/form/builder/parsers/series-field-parser.ts index 9857b4e993..36ee9c36c1 100644 --- a/src/app/shared/form/builder/parsers/series-field-parser.ts +++ b/src/app/shared/form/builder/parsers/series-field-parser.ts @@ -1,10 +1,17 @@ +import { Inject } from '@angular/core'; import { FormFieldModel } from '../models/form-field.model'; import { ConcatFieldParser } from './concat-field-parser'; +import { CONFIG_DATA, INIT_FORM_VALUES, PARSER_OPTIONS, SUBMISSION_ID } from './field-parser'; import { ParserOptions } from './parser-options'; export class SeriesFieldParser extends ConcatFieldParser { - constructor(protected configData: FormFieldModel, protected initFormValues, protected parserOptions: ParserOptions) { - super(configData, initFormValues, parserOptions, ';'); + constructor( + @Inject(SUBMISSION_ID) submissionId: string, + @Inject(CONFIG_DATA) configData: FormFieldModel, + @Inject(INIT_FORM_VALUES) initFormValues, + @Inject(PARSER_OPTIONS) parserOptions: ParserOptions + ) { + super(submissionId, configData, initFormValues, parserOptions, ';'); } } diff --git a/src/app/shared/form/builder/parsers/tag-field-parser.spec.ts b/src/app/shared/form/builder/parsers/tag-field-parser.spec.ts index 3051dc6395..90449e62e5 100644 --- a/src/app/shared/form/builder/parsers/tag-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/tag-field-parser.spec.ts @@ -8,6 +8,7 @@ describe('TagFieldParser test suite', () => { let field: FormFieldModel; let initFormValues: any = {}; + const submissionId = '1234'; const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', @@ -36,13 +37,13 @@ describe('TagFieldParser test suite', () => { }); it('should init parser properly', () => { - const parser = new TagFieldParser(field, initFormValues, parserOptions); + const parser = new TagFieldParser(submissionId, field, initFormValues, parserOptions); expect(parser instanceof TagFieldParser).toBe(true); }); it('should return a DynamicTagModel object when repeatable option is false', () => { - const parser = new TagFieldParser(field, initFormValues, parserOptions); + const parser = new TagFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -57,7 +58,7 @@ describe('TagFieldParser test suite', () => { ], }; - const parser = new TagFieldParser(field, initFormValues, parserOptions); + const parser = new TagFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); diff --git a/src/app/shared/form/builder/parsers/textarea-field-parser.spec.ts b/src/app/shared/form/builder/parsers/textarea-field-parser.spec.ts index c26d758e48..167f126cf2 100644 --- a/src/app/shared/form/builder/parsers/textarea-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/textarea-field-parser.spec.ts @@ -8,6 +8,7 @@ describe('TextareaFieldParser test suite', () => { let field: FormFieldModel; let initFormValues: any = {}; + const submissionId = '1234'; const parserOptions: ParserOptions = { readOnly: false, submissionScope: null, @@ -34,13 +35,13 @@ describe('TextareaFieldParser test suite', () => { }); it('should init parser properly', () => { - const parser = new TextareaFieldParser(field, initFormValues, parserOptions); + const parser = new TextareaFieldParser(submissionId, field, initFormValues, parserOptions); expect(parser instanceof TextareaFieldParser).toBe(true); }); it('should return a DsDynamicTextAreaModel object when repeatable option is false', () => { - const parser = new TextareaFieldParser(field, initFormValues, parserOptions); + const parser = new TextareaFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); @@ -55,7 +56,7 @@ describe('TextareaFieldParser test suite', () => { }; const expectedValue ='test description'; - const parser = new TextareaFieldParser(field, initFormValues, parserOptions); + const parser = new TextareaFieldParser(submissionId, field, initFormValues, parserOptions); const fieldModel = parser.parse(); diff --git a/src/app/shared/mocks/mock-form-models.ts b/src/app/shared/mocks/mock-form-models.ts index f2fc38c420..74f1581814 100644 --- a/src/app/shared/mocks/mock-form-models.ts +++ b/src/app/shared/mocks/mock-form-models.ts @@ -115,6 +115,7 @@ const mockFormRowModel = { } as FormRowModel; const relationGroupConfig = { + submissionId: '1234', id: 'relationGroup', formConfiguration: [mockFormRowModel], mandatoryField: 'false', diff --git a/src/app/submission/form/submission-form.component.ts b/src/app/submission/form/submission-form.component.ts index b592972839..1732075bf8 100644 --- a/src/app/submission/form/submission-form.component.ts +++ b/src/app/submission/form/submission-form.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core'; import { of as observableOf, Observable, Subscription } from 'rxjs'; -import { distinctUntilChanged, filter, flatMap, map } from 'rxjs/operators'; +import { distinctUntilChanged, filter, flatMap, map, switchMap } from 'rxjs/operators'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { SubmissionObjectEntry } from '../objects/submission-objects.reducer'; @@ -125,7 +125,7 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy { map((submission: SubmissionObjectEntry) => submission.isLoading), map((isLoading: boolean) => isLoading), distinctUntilChanged(), - flatMap((isLoading: boolean) => { + switchMap((isLoading: boolean) => { if (!isLoading) { return this.getSectionsList(); } else { diff --git a/src/app/submission/sections/form/section-form.component.ts b/src/app/submission/sections/form/section-form.component.ts index 2269ccd5f1..c1ca394911 100644 --- a/src/app/submission/sections/form/section-form.component.ts +++ b/src/app/submission/sections/form/section-form.component.ts @@ -215,6 +215,7 @@ export class SubmissionSectionformComponent extends SectionModelComponent { initForm(sectionData: WorkspaceitemSectionFormObject): void { try { this.formModel = this.formBuilderService.modelFromConfiguration( + this.submissionId, this.formConfig, this.collectionId, sectionData, diff --git a/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.ts b/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.ts index b2575d1d58..8cf0d22d20 100644 --- a/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.ts +++ b/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.ts @@ -166,6 +166,7 @@ export class SubmissionSectionUploadFileEditComponent implements OnChanges { const formModel: DynamicFormControlModel[] = []; const metadataGroupModelConfig = Object.assign({}, BITSTREAM_METADATA_FORM_GROUP_CONFIG); metadataGroupModelConfig.group = this.formBuilderService.modelFromConfiguration( + this.submissionId, configForm, this.collectionId, this.fileData.metadata,