add submissionId to fieldparser, and refactor to create fieldparsers using DI

This commit is contained in:
Art Lowel
2019-11-05 15:53:41 +01:00
parent 82367ea778
commit d255838265
29 changed files with 352 additions and 167 deletions

View File

@@ -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);

View File

@@ -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,
{},

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();

View File

@@ -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();

View File

@@ -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;

View File

@@ -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<string> = new InjectionToken<string>('submissionId');
export const CONFIG_DATA: InjectionToken<FormFieldModel> = new InjectionToken<FormFieldModel>('configData');
export const INIT_FORM_VALUES:InjectionToken<any> = new InjectionToken<any>('initFormValues');
export const PARSER_OPTIONS: InjectionToken<ParserOptions> = new InjectionToken<ParserOptions>('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;

View File

@@ -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();

View File

@@ -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();

View File

@@ -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();

View File

@@ -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();

View File

@@ -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');
}
}

View File

@@ -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();

View File

@@ -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<FieldParser> {
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: {

View File

@@ -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 = [{

View File

@@ -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) {

View File

@@ -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);
});
describe('parse', () => {
it('should return a DynamicRowGroupModel object', () => {
const parser = new RowParser(row1, scopeUUID, initFormValues, submissionScope, readOnly);
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);
});
it('should return a row with three fields', () => {
const parser = new RowParser(row1, scopeUUID, initFormValues, submissionScope, readOnly);
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);
});
it('should return a DynamicRowArrayModel object', () => {
const parser = new RowParser(row2, scopeUUID, initFormValues, submissionScope, readOnly);
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);
});
it('should return a row that contains only scoped fields', () => {
const parser = new RowParser(row3, scopeUUID, initFormValues, submissionScope, readOnly);
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);
});
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();
});
});
});

View File

@@ -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);
}
});

View File

@@ -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();

View File

@@ -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, ';');
}
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -115,6 +115,7 @@ const mockFormRowModel = {
} as FormRowModel;
const relationGroupConfig = {
submissionId: '1234',
id: 'relationGroup',
formConfiguration: [mockFormRowModel],
mandatoryField: 'false',

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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,