diff --git a/package.json b/package.json
index 88672dfe10..c91d99109c 100644
--- a/package.json
+++ b/package.json
@@ -74,9 +74,9 @@
"@angular/platform-server": "^6.1.4",
"@angular/router": "^6.1.4",
"@angularclass/bootloader": "1.0.1",
- "@ng-bootstrap/ng-bootstrap": "^2.0.0",
- "@ng-dynamic-forms/core": "6.0.9",
- "@ng-dynamic-forms/ui-ng-bootstrap": "6.0.9",
+ "@ng-bootstrap/ng-bootstrap": "3.3.1",
+ "@ng-dynamic-forms/core": "6.2.0",
+ "@ng-dynamic-forms/ui-ng-bootstrap": "6.2.0",
"@ngrx/effects": "^6.1.0",
"@ngrx/router-store": "^6.1.0",
"@ngrx/store": "^6.1.0",
diff --git a/src/app/+home-page/home-page.component.html b/src/app/+home-page/home-page.component.html
index 6a3e20ca9d..b6e55932a2 100644
--- a/src/app/+home-page/home-page.component.html
+++ b/src/app/+home-page/home-page.component.html
@@ -1,5 +1,6 @@
-
-
-
-
-
+
diff --git a/src/app/+home-page/home-page.component.ts b/src/app/+home-page/home-page.component.ts
index 902a0e820d..d766c606a0 100644
--- a/src/app/+home-page/home-page.component.ts
+++ b/src/app/+home-page/home-page.component.ts
@@ -1,4 +1,43 @@
-import { Component } from '@angular/core';
+import { ChangeDetectorRef, Component, Inject, ViewChild } from '@angular/core';
+import { DynamicFormControlModel, DynamicFormGroupModel, DynamicFormLayout } from '@ng-dynamic-forms/core';
+import { FormComponent } from '../shared/form/form.component';
+import { FormBuilderService } from '../shared/form/builder/form-builder.service';
+import { SubmissionFormsConfigService } from '../core/config/submission-forms-config.service';
+import { FormService } from '../shared/form/form.service';
+import { Store } from '@ngrx/store';
+import { AppState } from '../app.reducer';
+import { AuthorityOptions } from '../core/integration/models/authority-options.model';
+import { DynamicScrollableDropdownModel } from '../shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
+import { FormFieldMetadataValueObject } from '../shared/form/builder/models/form-field-metadata-value.model';
+import { ConfidenceType } from '../core/integration/models/confidence-type';
+import { Chips } from '../shared/chips/models/chips.model';
+import { ChipsItem } from '../shared/chips/models/chips-item.model';
+import { GLOBAL_CONFIG, GlobalConfig } from '../../config';
+
+export const NG_BOOTSTRAP_SAMPLE_FORM_MODEL: DynamicFormControlModel[] = [
+
+ new DynamicFormGroupModel({
+
+ id: 'typeGroup',
+ group: [
+ new DynamicScrollableDropdownModel({
+
+ id: 'type',
+ label: 'type',
+ placeholder: 'Type',
+ authorityOptions: new AuthorityOptions( 'type', 'dc.type', 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23')
+ })
+ ]
+ }),
+
+ new DynamicScrollableDropdownModel({
+
+ id: 'dc_type',
+ label: 'type',
+ placeholder: 'Type',
+ authorityOptions: new AuthorityOptions( 'type', 'dc.type', 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23')
+ })
+];
@Component({
selector: 'ds-home-page',
@@ -6,4 +45,40 @@ import { Component } from '@angular/core';
templateUrl: './home-page.component.html'
})
export class HomePageComponent {
+ public formId;
+ public formLayout: DynamicFormLayout = {};
+ public formModel: DynamicFormControlModel[];
+ public displaySubmit = false;
+ public chips: Chips;
+
+ @ViewChild('formRef') private formRef: FormComponent;
+ @ViewChild('formRefTwo') private formRefTwo: FormComponent;
+
+ constructor(@Inject(GLOBAL_CONFIG) public envConfig: GlobalConfig,
+ protected cdr: ChangeDetectorRef,
+ protected formBuilderService: FormBuilderService,
+ protected formConfigService: SubmissionFormsConfigService,
+ protected formService: FormService,
+ protected store: Store) {
+
+ }
+
+ ngOnInit() {
+
+ // const collectionId = '1c11f3f1-ba1f-4f36-908a-3f1ea9a557eb';
+ const collectionId = 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23';
+ const formId = 'traditionalpageone';
+
+ this.formId = this.formService.getUniqueId('test');
+ this.formModel = NG_BOOTSTRAP_SAMPLE_FORM_MODEL;
+
+ const item = {
+ mainField: new FormFieldMetadataValueObject('main test', null, 'test001', 'main test', 0, ConfidenceType.CF_ACCEPTED),
+ relatedField: new FormFieldMetadataValueObject('related test', null, 'test002', 'related test', 0, ConfidenceType.CF_ACCEPTED),
+ otherRelatedField: new FormFieldMetadataValueObject('other related test')
+ };
+
+ this.chips = new Chips([item], 'display', 'mainField', this.envConfig.submission.icons.metadata);
+
+ }
}
diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts
index 1c353920e0..7582c29233 100644
--- a/src/app/core/cache/builders/remote-data-build.service.ts
+++ b/src/app/core/cache/builders/remote-data-build.service.ts
@@ -6,7 +6,7 @@ import {
} from 'rxjs';
import { Injectable } from '@angular/core';
import { distinctUntilChanged, flatMap, map, startWith } from 'rxjs/operators';
-import { hasValue, hasValueOperator, isEmpty, isNotEmpty } from '../../../shared/empty.util';
+import { hasValue, hasValueOperator, isEmpty, isNotEmpty, isNotUndefined } from '../../../shared/empty.util';
import { PaginatedList } from '../../data/paginated-list';
import { RemoteData } from '../../data/remote-data';
import { RemoteDataError } from '../../data/remote-data-error';
@@ -266,8 +266,10 @@ export class RemoteDataBuildService {
map((rd: RemoteData>) => {
if (Array.isArray(rd.payload)) {
return Object.assign(rd, { payload: new PaginatedList(pageInfo, rd.payload) })
- } else {
+ } else if (isNotUndefined(rd.payload)) {
return Object.assign(rd, { payload: new PaginatedList(pageInfo, rd.payload.page) });
+ } else {
+ return Object.assign(rd, { payload: new PaginatedList(pageInfo, []) });
}
})
);
diff --git a/src/app/core/integration/models/authority.value.ts b/src/app/core/integration/models/authority.value.ts
index 5d23b51dd5..269407d2c5 100644
--- a/src/app/core/integration/models/authority.value.ts
+++ b/src/app/core/integration/models/authority.value.ts
@@ -1,7 +1,7 @@
import { IntegrationModel } from './integration.model';
import { autoserialize } from 'cerialize';
import { isNotEmpty } from '../../../shared/empty.util';
-import { PLACEHOLDER_PARENT_METADATA } from '../../../shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model';
+import { PLACEHOLDER_PARENT_METADATA } from '../../../shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
export class AuthorityValue extends IntegrationModel {
diff --git a/src/app/shared/chips/chips.component.spec.ts b/src/app/shared/chips/chips.component.spec.ts
index 5ac1a2131e..d11ce7a639 100644
--- a/src/app/shared/chips/chips.component.spec.ts
+++ b/src/app/shared/chips/chips.component.spec.ts
@@ -10,6 +10,12 @@ import { SortablejsModule } from 'angular-sortablejs';
import { By } from '@angular/platform-browser';
import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-metadata-value.model';
import { createTestComponent, hasClass } from '../testing/utils';
+import { AuthorityConfidenceStateDirective } from '../authority-confidence/authority-confidence-state.directive';
+import { TranslateModule } from '@ngx-translate/core';
+import { GlobalConfig } from '../../../config/global-config.interface';
+import { GLOBAL_CONFIG } from '../../../config';
+import { MOCK_SUBMISSION_CONFIG } from '../testing/mock-submission-config';
+import { ConfidenceType } from '../../core/integration/models/confidence-type';
describe('ChipsComponent test suite', () => {
@@ -20,6 +26,7 @@ describe('ChipsComponent test suite', () => {
let html;
let chips: Chips;
+ const envConfig: GlobalConfig = MOCK_SUBMISSION_CONFIG;
// async beforeEach
beforeEach(async(() => {
@@ -27,12 +34,15 @@ describe('ChipsComponent test suite', () => {
imports: [
NgbModule.forRoot(),
SortablejsModule.forRoot({animation: 150}),
+ TranslateModule.forRoot()
],
declarations: [
ChipsComponent,
TestComponent,
+ AuthorityConfidenceStateDirective
], // declare the test component
providers: [
+ { provide: GLOBAL_CONFIG, useValue: envConfig },
ChangeDetectorRef,
ChipsComponent,
UploaderService
@@ -139,33 +149,16 @@ describe('ChipsComponent test suite', () => {
describe('when has items as object', () => {
beforeEach(() => {
const item = {
- mainField: new FormFieldMetadataValueObject('main test', null, 'test001'),
- relatedField: new FormFieldMetadataValueObject('related test', null, 'test002'),
+ mainField: new FormFieldMetadataValueObject('main test', null, 'test001', 'main test', 0, ConfidenceType.CF_ACCEPTED),
+ relatedField: new FormFieldMetadataValueObject('related test', null, 'test002', 'related test', 0, ConfidenceType.CF_ACCEPTED),
otherRelatedField: new FormFieldMetadataValueObject('other related test')
};
- const iconsConfig = [
- {
- name: 'mainField',
- style: 'fa-user'
- },
- {
- name: 'relatedField',
- style: 'fa-user-alt'
- },
- {
- name: 'otherRelatedField',
- style: 'fa-user-alt'
- },
- {
- name: 'default',
- style: ''
- }
- ];
- chips = new Chips([item], 'display', 'mainField', iconsConfig);
+ chips = new Chips([item], 'display', 'mainField', envConfig.submission.icons.metadata);
chipsFixture = TestBed.createComponent(ChipsComponent);
chipsComp = chipsFixture.componentInstance; // TruncatableComponent test instance
chipsComp.editable = true;
+ chipsComp.showIcons = true;
chipsComp.chips = chips;
chipsFixture.detectChanges();
});
@@ -178,20 +171,13 @@ describe('ChipsComponent test suite', () => {
});
- it('should has text-muted on icon style when field value had not authority', () => {
- const de = chipsFixture.debugElement.query(By.css('li.nav-item'));
- const icons = de.queryAll(By.css('i.fa'));
-
- expect(hasClass(icons[2].nativeElement, 'text-muted')).toBeTruthy();
- });
-
it('should show tooltip on mouse over an icon', () => {
const de = chipsFixture.debugElement.query(By.css('li.nav-item'));
const icons = de.queryAll(By.css('i.fa'));
icons[0].triggerEventHandler('mouseover', null);
- expect(chipsComp.tipText).toBe('main test')
+ expect(chipsComp.tipText).toEqual(['main test'])
});
});
});
diff --git a/src/app/shared/chips/models/chips.model.ts b/src/app/shared/chips/models/chips.model.ts
index a688dc2fc9..25754361cb 100644
--- a/src/app/shared/chips/models/chips.model.ts
+++ b/src/app/shared/chips/models/chips.model.ts
@@ -2,7 +2,7 @@ import { findIndex, isEqual, isObject } from 'lodash';
import { BehaviorSubject } from 'rxjs';
import { ChipsItem, ChipsItemIcon } from './chips-item.model';
import { hasValue, isNotEmpty } from '../../empty.util';
-import { PLACEHOLDER_PARENT_METADATA } from '../../form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model';
+import { PLACEHOLDER_PARENT_METADATA } from '../../form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
import { MetadataIconConfig } from '../../../../config/submission-config.interface';
import { FormFieldMetadataValueObject } from '../../form/builder/models/form-field-metadata-value.model';
import { AuthorityValue } from '../../../core/integration/models/authority.value';
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html
similarity index 64%
rename from src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.html
rename to src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html
index 750ef721c2..6b4d1c6562 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.html
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html
@@ -1,19 +1,25 @@
-
-
+
+
+
+
+ {{ message | translate:model.validators }}
+
+
0" class="col-xs-2">
@@ -32,8 +38,8 @@
-
+
-
+
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.spec.ts
similarity index 93%
rename from src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.spec.ts
rename to src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.spec.ts
index ca12a7a4b4..d5dfce2575 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.spec.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.spec.ts
@@ -25,11 +25,14 @@ import {
DynamicTextAreaModel,
DynamicTimePickerModel
} from '@ng-dynamic-forms/core';
-import { DsDynamicFormControlComponent } from './ds-dynamic-form-control.component';
+import {
+ DsDynamicFormControlContainerComponent,
+ dsDynamicFormControlMapFn
+} from './ds-dynamic-form-control-container.component';
import { TranslateModule } from '@ngx-translate/core';
import { SharedModule } from '../../../shared.module';
import { DynamicDsDatePickerModel } from './models/date-picker/date-picker.model';
-import { DynamicGroupModel } from './models/dynamic-group/dynamic-group.model';
+import { DynamicRelationGroupModel } from './models/relation-group/dynamic-relation-group.model';
import { DynamicListCheckboxGroupModel } from './models/list/dynamic-list-checkbox-group.model';
import { AuthorityOptions } from '../../../../core/integration/models/authority-options.model';
import { DynamicListRadioGroupModel } from './models/list/dynamic-list-radio-group.model';
@@ -57,11 +60,11 @@ import { DsDynamicTypeaheadComponent } from './models/typeahead/dynamic-typeahea
import { DsDynamicScrollableDropdownComponent } from './models/scrollable-dropdown/dynamic-scrollable-dropdown.component';
import { DsDynamicTagComponent } from './models/tag/dynamic-tag.component';
import { DsDynamicListComponent } from './models/list/dynamic-list.component';
-import { DsDynamicGroupComponent } from './models/dynamic-group/dynamic-group.components';
+
import { DsDatePickerComponent } from './models/date-picker/date-picker.component';
import { DsDynamicLookupComponent } from './models/lookup/dynamic-lookup.component';
-describe('DsDynamicFormControlComponent test suite', () => {
+describe('DsDynamicFormControlContainerComponent test suite', () => {
const authorityOptions: AuthorityOptions = {
closed: false,
@@ -106,7 +109,7 @@ describe('DsDynamicFormControlComponent test suite', () => {
authorityOptions: authorityOptions,
repeatable: false
}),
- new DynamicGroupModel({
+ new DynamicRelationGroupModel({
id: 'relationGroup',
formConfiguration: [],
mandatoryField: '',
@@ -122,8 +125,8 @@ describe('DsDynamicFormControlComponent test suite', () => {
];
const testModel = formModel[8];
let formGroup: FormGroup;
- let fixture: ComponentFixture;
- let component: DsDynamicFormControlComponent;
+ let fixture: ComponentFixture;
+ let component: DsDynamicFormControlContainerComponent;
let debugElement: DebugElement;
let testElement: DebugElement;
@@ -147,11 +150,11 @@ describe('DsDynamicFormControlComponent test suite', () => {
TranslateModule.forRoot(),
TextMaskModule
],
- providers: [DsDynamicFormControlComponent, DynamicFormService],
+ providers: [DsDynamicFormControlContainerComponent, DynamicFormService],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents().then(() => {
- fixture = TestBed.createComponent(DsDynamicFormControlComponent);
+ fixture = TestBed.createComponent(DsDynamicFormControlContainerComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
@@ -254,7 +257,7 @@ describe('DsDynamicFormControlComponent test suite', () => {
});
it('should map a form control model to a form control component', () => {
- const testFn = DsDynamicFormControlComponent.getFormControlType;
+ const testFn = dsDynamicFormControlMapFn;
expect(testFn(formModel[0])).toBe(DynamicNGBootstrapCheckboxComponent);
expect(testFn(formModel[1])).toBe(DynamicNGBootstrapCheckboxGroupComponent);
expect(testFn(formModel[2])).toBeNull();
@@ -278,7 +281,7 @@ describe('DsDynamicFormControlComponent test suite', () => {
expect(testFn(formModel[18])).toBe(DsDynamicTagComponent);
expect(testFn(formModel[19])).toBe(DsDynamicListComponent);
expect(testFn(formModel[20])).toBe(DsDynamicListComponent);
- expect(testFn(formModel[21])).toBe(DsDynamicGroupComponent);
+ expect(testFn(formModel[21])).toBe(DynamicRelationGroupModel);
expect(testFn(formModel[22])).toBe(DsDatePickerComponent);
expect(testFn(formModel[23])).toBe(DsDynamicLookupComponent);
expect(testFn(formModel[24])).toBe(DsDynamicLookupComponent);
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts
similarity index 50%
rename from src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.ts
rename to src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts
index 3544bce280..703e2fceb0 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts
@@ -1,4 +1,5 @@
import {
+ ChangeDetectionStrategy,
Component,
ComponentFactoryResolver,
ContentChildren,
@@ -7,12 +8,15 @@ import {
OnChanges,
Output,
QueryList,
+ Renderer2,
SimpleChanges,
Type,
ViewChild,
- ViewContainerRef
+ ViewContainerRef,
+ ViewEncapsulation
} from '@angular/core';
import { FormGroup } from '@angular/forms';
+
import {
DYNAMIC_FORM_CONTROL_TYPE_ARRAY,
DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX,
@@ -28,48 +32,112 @@ import {
DynamicFormControl,
DynamicFormControlContainerComponent,
DynamicFormControlEvent,
- DynamicFormControlModel, DynamicFormLayout,
+ DynamicFormControlModel,
+ DynamicFormLayout,
DynamicFormLayoutService,
DynamicFormValidationService,
DynamicTemplateDirective,
} from '@ng-dynamic-forms/core';
-import { DYNAMIC_FORM_CONTROL_TYPE_TYPEAHEAD } from './models/typeahead/dynamic-typeahead.model';
-import { DYNAMIC_FORM_CONTROL_TYPE_SCROLLABLE_DROPDOWN } from './models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
-import { DYNAMIC_FORM_CONTROL_TYPE_TAG } from './models/tag/dynamic-tag.model';
-import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from './models/dynamic-group/dynamic-group.model';
-import { DYNAMIC_FORM_CONTROL_TYPE_DSDATEPICKER } from './models/date-picker/date-picker.model';
-import { DYNAMIC_FORM_CONTROL_TYPE_LOOKUP } from './models/lookup/dynamic-lookup.model';
-import { DynamicListCheckboxGroupModel } from './models/list/dynamic-list-checkbox-group.model';
-import { DynamicListRadioGroupModel } from './models/list/dynamic-list-radio-group.model';
-import { isNotEmpty } from '../../../empty.util';
-import { DYNAMIC_FORM_CONTROL_TYPE_LOOKUP_NAME } from './models/lookup/dynamic-lookup-name.model';
-import { DsDynamicTagComponent } from './models/tag/dynamic-tag.component';
import {
DynamicNGBootstrapCalendarComponent,
DynamicNGBootstrapCheckboxComponent,
DynamicNGBootstrapCheckboxGroupComponent,
DynamicNGBootstrapDatePickerComponent,
- DynamicNGBootstrapFormArrayComponent,
- DynamicNGBootstrapFormGroupComponent,
DynamicNGBootstrapInputComponent,
DynamicNGBootstrapRadioGroupComponent,
DynamicNGBootstrapSelectComponent,
DynamicNGBootstrapTextAreaComponent,
DynamicNGBootstrapTimePickerComponent
} from '@ng-dynamic-forms/ui-ng-bootstrap';
+
+import { DYNAMIC_FORM_CONTROL_TYPE_TYPEAHEAD } from './models/typeahead/dynamic-typeahead.model';
+import { DYNAMIC_FORM_CONTROL_TYPE_SCROLLABLE_DROPDOWN } from './models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
+import { DYNAMIC_FORM_CONTROL_TYPE_TAG } from './models/tag/dynamic-tag.model';
+import { DYNAMIC_FORM_CONTROL_TYPE_DSDATEPICKER } from './models/date-picker/date-picker.model';
+import { DYNAMIC_FORM_CONTROL_TYPE_LOOKUP } from './models/lookup/dynamic-lookup.model';
+import { DynamicListCheckboxGroupModel } from './models/list/dynamic-list-checkbox-group.model';
+import { DynamicListRadioGroupModel } from './models/list/dynamic-list-radio-group.model';
+import { isNotEmpty, isNotUndefined } from '../../../empty.util';
+import { DYNAMIC_FORM_CONTROL_TYPE_LOOKUP_NAME } from './models/lookup/dynamic-lookup-name.model';
+import { DsDynamicTagComponent } from './models/tag/dynamic-tag.component';
import { DsDatePickerComponent } from './models/date-picker/date-picker.component';
import { DsDynamicListComponent } from './models/list/dynamic-list.component';
import { DsDynamicTypeaheadComponent } from './models/typeahead/dynamic-typeahead.component';
import { DsDynamicScrollableDropdownComponent } from './models/scrollable-dropdown/dynamic-scrollable-dropdown.component';
-import { DsDynamicGroupComponent } from './models/dynamic-group/dynamic-group.components';
import { DsDynamicLookupComponent } from './models/lookup/dynamic-lookup.component';
+import { DsDynamicFormGroupComponent } from './models/form-group/dynamic-form-group.component';
+import { DsDynamicFormArrayComponent } from './models/array-group/dynamic-form-array.component';
+import { DsDynamicRelationGroupComponent } from './models/relation-group/dynamic-relation-group.components';
+import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from './models/relation-group/dynamic-relation-group.model';
+
+export function dsDynamicFormControlMapFn(model: DynamicFormControlModel): Type | null {
+ switch (model.type) {
+
+ case DYNAMIC_FORM_CONTROL_TYPE_ARRAY:
+ return DsDynamicFormArrayComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX:
+ return DynamicNGBootstrapCheckboxComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX_GROUP:
+ return (model instanceof DynamicListCheckboxGroupModel) ? DsDynamicListComponent : DynamicNGBootstrapCheckboxGroupComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_DATEPICKER:
+ const datepickerModel = model as DynamicDatePickerModel;
+
+ return datepickerModel.inline ? DynamicNGBootstrapCalendarComponent : DynamicNGBootstrapDatePickerComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_GROUP:
+ return DsDynamicFormGroupComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_INPUT:
+ return DynamicNGBootstrapInputComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_RADIO_GROUP:
+ return (model instanceof DynamicListRadioGroupModel) ? DsDynamicListComponent : DynamicNGBootstrapRadioGroupComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_SELECT:
+ return DynamicNGBootstrapSelectComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_TEXTAREA:
+ return DynamicNGBootstrapTextAreaComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_TIMEPICKER:
+ return DynamicNGBootstrapTimePickerComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_TYPEAHEAD:
+ return DsDynamicTypeaheadComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_SCROLLABLE_DROPDOWN:
+ return DsDynamicScrollableDropdownComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_TAG:
+ return DsDynamicTagComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP:
+ return DsDynamicRelationGroupComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_DSDATEPICKER:
+ return DsDatePickerComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_LOOKUP:
+ return DsDynamicLookupComponent;
+
+ case DYNAMIC_FORM_CONTROL_TYPE_LOOKUP_NAME:
+ return DsDynamicLookupComponent;
+
+ default:
+ return null;
+ }
+}
@Component({
selector: 'ds-dynamic-form-control',
- styleUrls: ['../../form.component.scss', './ds-dynamic-form.component.scss'],
- templateUrl: './ds-dynamic-form-control.component.html'
+ styleUrls: ['./ds-dynamic-form.component.scss', '../../form.component.scss'],
+ templateUrl: './ds-dynamic-form-control-container.component.html',
+ changeDetection: ChangeDetectionStrategy.Default
})
-export class DsDynamicFormControlComponent extends DynamicFormControlContainerComponent implements OnChanges {
+export class DsDynamicFormControlContainerComponent extends DynamicFormControlContainerComponent implements OnChanges {
@ContentChildren(DynamicTemplateDirective) contentTemplateList: QueryList;
// tslint:disable-next-line:no-input-rename
@@ -82,83 +150,29 @@ export class DsDynamicFormControlComponent extends DynamicFormControlContainerCo
@Input() group: FormGroup;
@Input() hasErrorMessaging = false;
@Input() layout = null as DynamicFormLayout;
- @Input() model: any;
+ @Input() model: DynamicFormControlModel;
/* tslint:disable:no-output-rename */
@Output('dfBlur') blur: EventEmitter = new EventEmitter();
@Output('dfChange') change: EventEmitter = new EventEmitter();
@Output('dfFocus') focus: EventEmitter = new EventEmitter();
+ @Output('ngbEvent') customEvent: EventEmitter = new EventEmitter();
/* tslint:enable:no-output-rename */
@ViewChild('componentViewContainer', {read: ViewContainerRef}) componentViewContainerRef: ViewContainerRef;
+ private showErrorMessagesPreviousStage: boolean;
+
get componentType(): Type | null {
- return this.layoutService.getCustomComponentType(this.model) || DsDynamicFormControlComponent.getFormControlType(this.model);
+ return this.layoutService.getCustomComponentType(this.model) || dsDynamicFormControlMapFn(this.model);
}
- static getFormControlType(model: DynamicFormControlModel): Type | null {
-
- switch (model.type) {
-
- case DYNAMIC_FORM_CONTROL_TYPE_ARRAY:
- return DynamicNGBootstrapFormArrayComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX:
- return DynamicNGBootstrapCheckboxComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX_GROUP:
- return (model instanceof DynamicListCheckboxGroupModel) ? DsDynamicListComponent : DynamicNGBootstrapCheckboxGroupComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_DATEPICKER:
- const datepickerModel = model as DynamicDatePickerModel;
-
- return datepickerModel.inline ? DynamicNGBootstrapCalendarComponent : DynamicNGBootstrapDatePickerComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_GROUP:
- return DynamicNGBootstrapFormGroupComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_INPUT:
- return DynamicNGBootstrapInputComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_RADIO_GROUP:
- return (model instanceof DynamicListRadioGroupModel) ? DsDynamicListComponent : DynamicNGBootstrapRadioGroupComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_SELECT:
- return DynamicNGBootstrapSelectComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_TEXTAREA:
- return DynamicNGBootstrapTextAreaComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_TIMEPICKER:
- return DynamicNGBootstrapTimePickerComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_TYPEAHEAD:
- return DsDynamicTypeaheadComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_SCROLLABLE_DROPDOWN:
- return DsDynamicScrollableDropdownComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_TAG:
- return DsDynamicTagComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP:
- return DsDynamicGroupComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_DSDATEPICKER:
- return DsDatePickerComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_LOOKUP:
- return DsDynamicLookupComponent;
-
- case DYNAMIC_FORM_CONTROL_TYPE_LOOKUP_NAME:
- return DsDynamicLookupComponent;
-
- default:
- return null;
- }
- }
-
- constructor(protected componentFactoryResolver: ComponentFactoryResolver, protected layoutService: DynamicFormLayoutService,
- protected validationService: DynamicFormValidationService) {
+ protected test: boolean;
+ constructor(
+ protected componentFactoryResolver: ComponentFactoryResolver,
+ protected layoutService: DynamicFormLayoutService,
+ protected validationService: DynamicFormValidationService,
+ protected renderer: Renderer2
+ ) {
super(componentFactoryResolver, layoutService, validationService);
}
@@ -169,6 +183,28 @@ export class DsDynamicFormControlComponent extends DynamicFormControlContainerCo
}
}
+ ngDoCheck() {
+ if (isNotUndefined(this.showErrorMessagesPreviousStage) && this.showErrorMessagesPreviousStage !== this.showErrorMessages) {
+ this.showErrorMessagesPreviousStage = this.showErrorMessages;
+ this.forceShowErrorDetection();
+ }
+ }
+
+ ngAfterViewInit() {
+ this.showErrorMessagesPreviousStage = this.showErrorMessages
+ }
+
+ /**
+ * Since Form Control Components created dynamically have 'OnPush' change detection strategy,
+ * changes are not propagated. So use this method to force an update
+ */
+ protected forceShowErrorDetection() {
+ if (this.showErrorMessages) {
+ this.destroyFormControlComponent();
+ this.createFormControlComponent();
+ }
+ }
+
onChangeLanguage(event) {
if (isNotEmpty((this.model as any).value)) {
this.onChange(event);
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form.component.ts
index c1b4ca71c8..ccf9e6d292 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form.component.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form.component.ts
@@ -17,11 +17,12 @@ import {
DynamicFormService,
DynamicTemplateDirective,
} from '@ng-dynamic-forms/core';
-import { DsDynamicFormControlComponent } from './ds-dynamic-form-control.component';
+import { DsDynamicFormControlContainerComponent } from './ds-dynamic-form-control-container.component';
import { FormBuilderService } from '../form-builder.service';
@Component({
selector: 'ds-dynamic-form',
+ styleUrls: ['../../form.component.scss'],
templateUrl: './ds-dynamic-form.component.html'
})
export class DsDynamicFormComponent extends DynamicFormComponent {
@@ -35,11 +36,12 @@ export class DsDynamicFormComponent extends DynamicFormComponent {
@Output('dfBlur') blur: EventEmitter = new EventEmitter();
@Output('dfChange') change: EventEmitter = new EventEmitter();
@Output('dfFocus') focus: EventEmitter = new EventEmitter();
+ @Output('ngbEvent') customEvent: EventEmitter = new EventEmitter();
/* tslint:enable:no-output-rename */
@ContentChildren(DynamicTemplateDirective) templates: QueryList;
- @ViewChildren(DsDynamicFormControlComponent) components: QueryList;
+ @ViewChildren(DsDynamicFormControlContainerComponent) components: QueryList;
constructor(protected formService: FormBuilderService, protected layoutService: DynamicFormLayoutService) {
super(formService, layoutService);
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.html
new file mode 100644
index 0000000000..56524523d1
--- /dev/null
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.html
@@ -0,0 +1,32 @@
+
+
+
+
+
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.ts
new file mode 100644
index 0000000000..1e8fd3b55e
--- /dev/null
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.ts
@@ -0,0 +1,38 @@
+import { Component, EventEmitter, Input, Output, QueryList } from '@angular/core';
+import { FormGroup } from '@angular/forms';
+import {
+ DynamicFormArrayComponent,
+ DynamicFormArrayModel,
+ DynamicFormControlCustomEvent, DynamicFormControlEvent,
+ DynamicFormLayout,
+ DynamicFormLayoutService,
+ DynamicFormValidationService,
+ DynamicTemplateDirective
+} from '@ng-dynamic-forms/core';
+
+@Component({
+ selector: 'ds-dynamic-form-array',
+ templateUrl: './dynamic-form-array.component.html'
+})
+export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent {
+
+ @Input() bindId = true;
+ @Input() group: FormGroup;
+ @Input() layout: DynamicFormLayout;
+ @Input() model: DynamicFormArrayModel;
+ @Input() templates: QueryList | undefined;
+
+ /* tslint:disable:no-output-rename */
+ @Output('dfBlur') blur: EventEmitter = new EventEmitter();
+ @Output('dfChange') change: EventEmitter = new EventEmitter();
+ @Output('dfFocus') focus: EventEmitter = new EventEmitter();
+ @Output('ngbEvent') customEvent: EventEmitter = new EventEmitter();
+ /* tslint:enable:no-output-rename */
+
+ constructor(protected layoutService: DynamicFormLayoutService,
+ protected validationService: DynamicFormValidationService) {
+
+ super(layoutService, validationService);
+ }
+
+}
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/form-group/dynamic-form-group.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/form-group/dynamic-form-group.component.html
new file mode 100644
index 0000000000..c8443c640d
--- /dev/null
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/form-group/dynamic-form-group.component.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/form-group/dynamic-form-group.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/form-group/dynamic-form-group.component.ts
new file mode 100644
index 0000000000..fb11ea4cfa
--- /dev/null
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/form-group/dynamic-form-group.component.ts
@@ -0,0 +1,61 @@
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, QueryList } from '@angular/core';
+import { FormGroup } from '@angular/forms';
+import {
+ DynamicFormControlComponent,
+ DynamicFormControlCustomEvent, DynamicFormControlEvent,
+ DynamicFormGroupModel,
+ DynamicFormLayout,
+ DynamicFormLayoutService,
+ DynamicFormValidationService,
+ DynamicTemplateDirective
+} from '@ng-dynamic-forms/core';
+import { filter, tap } from 'rxjs/operators';
+
+@Component({
+ selector: 'ds-dynamic-form-group',
+ templateUrl: './dynamic-form-group.component.html',
+ changeDetection: ChangeDetectionStrategy.Default
+})
+export class DsDynamicFormGroupComponent extends DynamicFormControlComponent {
+
+ @Input() bindId = true;
+ @Input() group: FormGroup;
+ @Input() layout: DynamicFormLayout;
+ @Input() model: DynamicFormGroupModel;
+ @Input() templates: QueryList | DynamicTemplateDirective[] | undefined;
+
+ /* tslint:disable:no-output-rename */
+ @Output('dfBlur') blur: EventEmitter = new EventEmitter();
+ @Output('dfChange') change: EventEmitter = new EventEmitter();
+ @Output('dfFocus') focus: EventEmitter = new EventEmitter();
+ @Output('ngbEvent') customEvent: EventEmitter = new EventEmitter();
+ /* tslint:enable:no-output-rename */
+
+ constructor(protected layoutService: DynamicFormLayoutService,
+ protected validationService: DynamicFormValidationService) {
+
+ super(layoutService, validationService);
+ }
+
+/* ngAfterViewInit() {
+ if (this.control) {
+ this.control.statusChanges.pipe(
+ tap((state) => console.log(this.model.id, state)),
+ filter((state) => state === 'INVALID'),
+ // filter(() => this.control.touched),
+ )
+ .subscribe((state) => {
+ // const instance: DynamicFormControlComponent = this.componentRef.instance as any;
+ console.log('group', this.model.id, state);
+ // console.log(this.model.hasErrorMessages, this.control.touched, this.hasFocus, this.isInvalid);
+ // instance.control.markAsTouched();
+ console.log('showErrorMessages ', this.showErrorMessages);
+ console.log('hasErrorMessages ', this.model.hasErrorMessages);
+ console.log('touched ', this.control.touched);
+ console.log('hasFocus ', this.hasFocus);
+ console.log('isInvalid ', this.isInvalid);
+ });
+ }
+ }*/
+
+}
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts
index 6693eb4d66..186d359dd0 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts
@@ -33,7 +33,6 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
@Input() bindId = true;
@Input() group: FormGroup;
@Input() model: DynamicListCheckboxGroupModel | DynamicListRadioGroupModel;
- @Input() showErrorMessages = false;
@Output() blur: EventEmitter = new EventEmitter();
@Output() change: EventEmitter = new EventEmitter();
@@ -132,7 +131,7 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
tempList = [];
}
});
- this.cdr.detectChanges();
+ this.cdr.markForCheck();
});
}
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts
index 210cb1855d..df2252163d 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts
@@ -23,6 +23,10 @@ import { By } from '@angular/platform-browser';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value';
import { createTestComponent } from '../../../../../testing/utils';
import { DynamicLookupNameModel } from './dynamic-lookup-name.model';
+import { AuthorityConfidenceStateDirective } from '../../../../../authority-confidence/authority-confidence-state.directive';
+import { ObjNgFor } from '../../../../../utils/object-ngfor.pipe';
+import { GLOBAL_CONFIG, GlobalConfig } from '../../../../../../../config';
+import { MOCK_SUBMISSION_CONFIG } from '../../../../../testing/mock-submission-config';
let LOOKUP_TEST_MODEL_CONFIG = {
authorityOptions: {
@@ -73,6 +77,8 @@ let LOOKUP_TEST_GROUP = new FormGroup({
lookupName: new FormControl()
});
+const envConfig: GlobalConfig = MOCK_SUBMISSION_CONFIG;
+
describe('Dynamic Lookup component', () => {
function init() {
LOOKUP_TEST_MODEL_CONFIG = {
@@ -150,10 +156,13 @@ describe('Dynamic Lookup component', () => {
declarations: [
DsDynamicLookupComponent,
TestComponent,
+ AuthorityConfidenceStateDirective,
+ ObjNgFor
], // declare the test component
providers: [
ChangeDetectorRef,
DsDynamicLookupComponent,
+ { provide: GLOBAL_CONFIG, useValue: envConfig },
{ provide: AuthorityService, useValue: authorityService },
{ provide: DynamicFormLayoutService, useValue: {} },
{ provide: DynamicFormValidationService, useValue: {} }
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.ts
index 66697cab61..34202e68b3 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.ts
@@ -30,7 +30,6 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
@Input() bindId = true;
@Input() group: FormGroup;
@Input() model: DynamicLookupModel | DynamicLookupNameModel;
- @Input() showErrorMessages = false;
@Output() blur: EventEmitter = new EventEmitter();
@Output() change: EventEmitter = new EventEmitter();
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html
similarity index 100%
rename from src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.html
rename to src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.scss b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.scss
similarity index 100%
rename from src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.scss
rename to src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.scss
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.spec.ts
similarity index 84%
rename from src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.spec.ts
rename to src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.spec.ts
index bd8d79dd42..20547d6b5b 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.spec.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.spec.ts
@@ -6,16 +6,13 @@ import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angul
import { TranslateModule } from '@ngx-translate/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
-import { DsDynamicGroupComponent } from './dynamic-group.components';
-import { DynamicGroupModel, DynamicGroupModelConfig } from './dynamic-group.model';
-import {
- FormRowModel,
- SubmissionFormsModel
-} from '../../../../../../core/config/models/config-submission-forms.model';
+import { DsDynamicRelationGroupComponent } from './dynamic-relation-group.components';
+import { DynamicRelationGroupModel, DynamicRelationGroupModelConfig } from './dynamic-relation-group.model';
+import { FormRowModel, SubmissionFormsModel } from '../../../../../../core/config/models/config-submission-forms.model';
import { FormFieldModel } from '../../../models/form-field.model';
import { FormBuilderService } from '../../../form-builder.service';
import { FormService } from '../../../../form.service';
-import { GLOBAL_CONFIG } from '../../../../../../../config';
+import { GLOBAL_CONFIG, GlobalConfig } from '../../../../../../../config';
import { FormComponent } from '../../../../form.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { Chips } from '../../../../../chips/models/chips.model';
@@ -26,12 +23,17 @@ import { DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dyna
import { MockStore } from '../../../../../testing/mock-store';
import { Store } from '@ngrx/store';
import { AppState } from '../../../../../../app.reducer';
+import { AuthService } from '../../../../../../core/auth/auth.service';
+import { AuthServiceStub } from '../../../../../testing/auth-service-stub';
+import { AuthorityService } from '../../../../../../core/integration/authority.service';
+import { AuthorityServiceStub } from '../../../../../testing/authority-service-stub';
+import { MOCK_SUBMISSION_CONFIG } from '../../../../../testing/mock-submission-config';
export let FORM_GROUP_TEST_MODEL_CONFIG;
export let FORM_GROUP_TEST_GROUP;
-let config;
+const config: GlobalConfig = MOCK_SUBMISSION_CONFIG;
function init() {
FORM_GROUP_TEST_MODEL_CONFIG = {
@@ -78,38 +80,19 @@ function init() {
scopeUUID: '43fe1f8c-09a6-4fcf-9c78-5d4fed8f2c8f',
submissionScope: undefined,
validators: { required: null }
- } as DynamicGroupModelConfig;
+ } as DynamicRelationGroupModelConfig;
FORM_GROUP_TEST_GROUP = new FormGroup({
dc_contributor_author: new FormControl(),
});
- config = {
- form: {
- validatorMap: {
- required: 'required',
- regex: 'pattern'
- }
- },
- submission: {
- metadata: {
- icons: [
- {
- name: 'default',
- config: {}
- }
- ]
- }
- }
- } as any;
-
}
-describe('DsDynamicGroupComponent test suite', () => {
+describe('DsDynamicRelationGroupComponent test suite', () => {
let testComp: TestComponent;
- let groupComp: DsDynamicGroupComponent;
+ let groupComp: DsDynamicRelationGroupComponent;
let testFixture: ComponentFixture;
- let groupFixture: ComponentFixture;
+ let groupFixture: ComponentFixture;
let modelValue: any;
let html;
let control1: FormControl;
@@ -132,19 +115,20 @@ describe('DsDynamicGroupComponent test suite', () => {
],
declarations: [
FormComponent,
- DsDynamicGroupComponent,
+ DsDynamicRelationGroupComponent,
TestComponent,
], // declare the test component
providers: [
ChangeDetectorRef,
- DsDynamicGroupComponent,
+ DsDynamicRelationGroupComponent,
DynamicFormValidationService,
DynamicFormLayoutService,
FormBuilderService,
FormComponent,
FormService,
+ { provide: AuthorityService, useValue: new AuthorityServiceStub() },
{ provide: GLOBAL_CONFIG, useValue: config },
- {provide: Store, useValue: store},
+ { provide: Store, useValue: store },
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});
@@ -154,13 +138,12 @@ describe('DsDynamicGroupComponent test suite', () => {
describe('', () => {
// synchronous beforeEach
beforeEach(() => {
- html = `
- `;
+ (focus)="onFocus($event)">`;
testFixture = createTestComponent(html, TestComponent) as ComponentFixture;
testComp = testFixture.componentInstance;
@@ -171,7 +154,7 @@ describe('DsDynamicGroupComponent test suite', () => {
testComp = null;
});
- it('should create DsDynamicGroupComponent', inject([DsDynamicGroupComponent], (app: DsDynamicGroupComponent) => {
+ it('should create DsDynamicRelationGroupComponent', inject([DsDynamicRelationGroupComponent], (app: DsDynamicRelationGroupComponent) => {
expect(app).toBeDefined();
}));
@@ -180,11 +163,11 @@ describe('DsDynamicGroupComponent test suite', () => {
describe('when init model value is empty', () => {
beforeEach(inject([FormBuilderService], (service: FormBuilderService) => {
- groupFixture = TestBed.createComponent(DsDynamicGroupComponent);
+ groupFixture = TestBed.createComponent(DsDynamicRelationGroupComponent);
groupComp = groupFixture.componentInstance; // FormComponent test instance
groupComp.formId = 'testForm';
groupComp.group = FORM_GROUP_TEST_GROUP;
- groupComp.model = new DynamicGroupModel(FORM_GROUP_TEST_MODEL_CONFIG);
+ groupComp.model = new DynamicRelationGroupModel(FORM_GROUP_TEST_MODEL_CONFIG);
groupFixture.detectChanges();
control1 = service.getFormControlById('dc_contributor_author', (groupComp as any).formRef.formGroup, groupComp.formModel) as FormControl;
model1 = service.findById('dc_contributor_author', groupComp.formModel) as DsDynamicInputModel;
@@ -254,11 +237,11 @@ describe('DsDynamicGroupComponent test suite', () => {
describe('when init model value is not empty', () => {
beforeEach(() => {
- groupFixture = TestBed.createComponent(DsDynamicGroupComponent);
+ groupFixture = TestBed.createComponent(DsDynamicRelationGroupComponent);
groupComp = groupFixture.componentInstance; // FormComponent test instance
groupComp.formId = 'testForm';
groupComp.group = FORM_GROUP_TEST_GROUP;
- groupComp.model = new DynamicGroupModel(FORM_GROUP_TEST_MODEL_CONFIG);
+ groupComp.model = new DynamicRelationGroupModel(FORM_GROUP_TEST_MODEL_CONFIG);
modelValue = [{
'dc.contributor.author': new FormFieldMetadataValueObject('test author'),
'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation')
@@ -339,7 +322,7 @@ class TestComponent {
groupModelConfig = FORM_GROUP_TEST_MODEL_CONFIG;
- model = new DynamicGroupModel(this.groupModelConfig);
+ model = new DynamicRelationGroupModel(this.groupModelConfig);
showErrorMessages = false;
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts
similarity index 96%
rename from src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts
rename to src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts
index 1c119a7223..04b5cf170d 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components.ts
@@ -23,7 +23,7 @@ import {
} from '@ng-dynamic-forms/core';
import { isEqual, isObject } from 'lodash';
-import { DynamicGroupModel, PLACEHOLDER_PARENT_METADATA } from './dynamic-group.model';
+import { DynamicRelationGroupModel, PLACEHOLDER_PARENT_METADATA } from './dynamic-relation-group.model';
import { FormBuilderService } from '../../../form-builder.service';
import { SubmissionFormsModel } from '../../../../../../core/config/models/config-submission-forms.model';
import { FormService } from '../../../../form.service';
@@ -42,17 +42,16 @@ import { FormFieldMetadataValueObject } from '../../../models/form-field-metadat
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value';
@Component({
- selector: 'ds-dynamic-group',
- styleUrls: ['./dynamic-group.component.scss'],
- templateUrl: './dynamic-group.component.html',
+ selector: 'ds-dynamic-relation-group',
+ styleUrls: ['./dynamic-relation-group.component.scss'],
+ templateUrl: './dynamic-relation-group.component.html',
animations: [shrinkInOut]
})
-export class DsDynamicGroupComponent extends DynamicFormControlComponent implements OnDestroy, OnInit {
+export class DsDynamicRelationGroupComponent extends DynamicFormControlComponent implements OnDestroy, OnInit {
@Input() formId: string;
@Input() group: FormGroup;
- @Input() model: DynamicGroupModel;
- @Input() showErrorMessages = false;
+ @Input() model: DynamicRelationGroupModel;
@Output() blur: EventEmitter = new EventEmitter();
@Output() change: EventEmitter = new EventEmitter();
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model.ts
similarity index 87%
rename from src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model.ts
rename to src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model.ts
index bccbcabfc1..7a357dfc31 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model.ts
@@ -1,7 +1,6 @@
import { DynamicFormControlLayout, serializable } from '@ng-dynamic-forms/core';
import { FormRowModel } from '../../../../../../core/config/models/config-submission-forms.model';
import { DsDynamicInputModel, DsDynamicInputModelConfig } from '../ds-dynamic-input.model';
-import { AuthorityValue } from '../../../../../../core/integration/models/authority.value';
import { isEmpty, isNull } from '../../../../../empty.util';
export const DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP = 'RELATION';
@@ -10,7 +9,7 @@ export const PLACEHOLDER_PARENT_METADATA = '#PLACEHOLDER_PARENT_METADATA_VALUE#'
/**
* Dynamic Group Model configuration interface
*/
-export interface DynamicGroupModelConfig extends DsDynamicInputModelConfig {
+export interface DynamicRelationGroupModelConfig extends DsDynamicInputModelConfig {
formConfiguration: FormRowModel[],
mandatoryField: string,
relationFields: string[],
@@ -21,7 +20,7 @@ export interface DynamicGroupModelConfig extends DsDynamicInputModelConfig {
/**
* Dynamic Group Model class
*/
-export class DynamicGroupModel extends DsDynamicInputModel {
+export class DynamicRelationGroupModel extends DsDynamicInputModel {
@serializable() formConfiguration: FormRowModel[];
@serializable() mandatoryField: string;
@serializable() relationFields: string[];
@@ -30,7 +29,7 @@ export class DynamicGroupModel extends DsDynamicInputModel {
@serializable() _value: any[];
@serializable() readonly type: string = DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP;
- constructor(config: DynamicGroupModelConfig, layout?: DynamicFormControlLayout) {
+ constructor(config: DynamicRelationGroupModelConfig, layout?: DynamicFormControlLayout) {
super(config, layout);
this.formConfiguration = config.formConfiguration;
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts
index 3b54226654..de39dacb55 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts
@@ -27,7 +27,6 @@ export class DsDynamicScrollableDropdownComponent extends DynamicFormControlComp
@Input() bindId = true;
@Input() group: FormGroup;
@Input() model: DynamicScrollableDropdownModel;
- @Input() showErrorMessages = false;
@Output() blur: EventEmitter = new EventEmitter();
@Output() change: EventEmitter = new EventEmitter();
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.spec.ts
index a5b0f48a4f..9aeada5032 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.spec.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.spec.ts
@@ -23,6 +23,7 @@ import { Chips } from '../../../../../chips/models/chips.model';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { AuthorityValue } from '../../../../../../core/integration/models/authority.value';
import { createTestComponent } from '../../../../../testing/utils';
+import { MOCK_SUBMISSION_CONFIG } from '../../../../../testing/mock-submission-config';
function createKeyUpEvent(key: number) {
/* tslint:disable:no-empty */
@@ -39,6 +40,7 @@ function createKeyUpEvent(key: number) {
let TAG_TEST_GROUP;
let TAG_TEST_MODEL_CONFIG;
+const envConfig: GlobalConfig = MOCK_SUBMISSION_CONFIG;
function init() {
TAG_TEST_GROUP = new FormGroup({
@@ -94,7 +96,7 @@ describe('DsDynamicTagComponent test suite', () => {
ChangeDetectorRef,
DsDynamicTagComponent,
{ provide: AuthorityService, useValue: authorityServiceStub },
- { provide: GLOBAL_CONFIG, useValue: {} as GlobalConfig },
+ { provide: GLOBAL_CONFIG, useValue: envConfig },
{ provide: DynamicFormLayoutService, useValue: {} },
{ provide: DynamicFormValidationService, useValue: {} }
],
@@ -110,7 +112,6 @@ describe('DsDynamicTagComponent test suite', () => {
`;
@@ -161,7 +162,6 @@ describe('DsDynamicTagComponent test suite', () => {
it('should select a results entry properly', fakeAsync(() => {
modelValue = [
Object.assign(new AuthorityValue(), { id: 1, display: 'Name, Lastname', value: 1 })
- Object.assign(new AuthorityValue(), {id: 1, display: 'Name, Lastname', value: 1})
];
const event: NgbTypeaheadSelectItemEvent = {
item: Object.assign(new AuthorityValue(), {
@@ -169,7 +169,6 @@ describe('DsDynamicTagComponent test suite', () => {
display: 'Name, Lastname',
value: 1
}),
- item: Object.assign(new AuthorityValue(), {id: 1, display: 'Name, Lastname', value: 1}),
preventDefault: () => {
return;
}
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts
index 4370986870..35bb6e1e31 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts
@@ -29,7 +29,6 @@ export class DsDynamicTagComponent extends DynamicFormControlComponent implement
@Input() bindId = true;
@Input() group: FormGroup;
@Input() model: DynamicTagModel;
- @Input() showErrorMessages = false;
@Output() blur: EventEmitter = new EventEmitter();
@Output() change: EventEmitter = new EventEmitter();
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.spec.ts
index c950f8f4ef..18797b69f7 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.spec.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.spec.ts
@@ -1,31 +1,34 @@
// Load the implementations that should be tested
import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
-import { async, ComponentFixture, fakeAsync, inject, TestBed, } from '@angular/core/testing';
+import { async, ComponentFixture, fakeAsync, inject, TestBed, tick, } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
+
import { of as observableOf } from 'rxjs';
+import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
+import { DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormValidationService } from '@ng-dynamic-forms/core';
+import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap';
+import { TranslateModule } from '@ngx-translate/core';
import { AuthorityOptions } from '../../../../../../core/integration/models/authority-options.model';
-import {
- DynamicFormLayoutService,
- DynamicFormsCoreModule,
- DynamicFormValidationService
-} from '@ng-dynamic-forms/core';
-import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap';
import { AuthorityService } from '../../../../../../core/integration/authority.service';
import { AuthorityServiceStub } from '../../../../../testing/authority-service-stub';
import { GlobalConfig } from '../../../../../../../config/global-config.interface';
import { GLOBAL_CONFIG } from '../../../../../../../config';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { DsDynamicTypeaheadComponent } from './dynamic-typeahead.component';
import { DynamicTypeaheadModel } from './dynamic-typeahead.model';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { createTestComponent } from '../../../../../testing/utils';
+import { AuthorityConfidenceStateDirective } from '../../../../../authority-confidence/authority-confidence-state.directive';
+import { MOCK_SUBMISSION_CONFIG } from '../../../../../testing/mock-submission-config';
+import { ObjNgFor } from '../../../../../utils/object-ngfor.pipe';
export let TYPEAHEAD_TEST_GROUP;
export let TYPEAHEAD_TEST_MODEL_CONFIG;
+const envConfig: GlobalConfig = MOCK_SUBMISSION_CONFIG;
+
function init() {
TYPEAHEAD_TEST_GROUP = new FormGroup({
typeahead: new FormControl(),
@@ -61,7 +64,7 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
// async beforeEach
beforeEach(async(() => {
const authorityServiceStub = new AuthorityServiceStub();
- init()
+ init();
TestBed.configureTestingModule({
imports: [
DynamicFormsCoreModule,
@@ -69,14 +72,18 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
FormsModule,
NgbModule.forRoot(),
ReactiveFormsModule,
+ TranslateModule.forRoot()
],
declarations: [
DsDynamicTypeaheadComponent,
TestComponent,
+ AuthorityConfidenceStateDirective,
+ ObjNgFor
], // declare the test component
providers: [
ChangeDetectorRef,
DsDynamicTypeaheadComponent,
+ { provide: GLOBAL_CONFIG, useValue: envConfig },
{ provide: AuthorityService, useValue: authorityServiceStub },
{ provide: DynamicFormLayoutService, useValue: {} },
{ provide: DynamicFormValidationService, useValue: {} }
@@ -130,13 +137,16 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
expect(typeaheadComp.currentValue).not.toBeDefined();
});
- it('should search when 3+ characters typed', fakeAsync(() => {
+ it('should search when 3+ characters typed', fakeAsync((done) => {
+
spyOn((typeaheadComp as any).authorityService, 'getEntriesByName').and.callThrough();
- typeaheadComp.search(observableOf('test')).subscribe(() => {
- expect((typeaheadComp as any).authorityService.getEntriesByName).toHaveBeenCalled();
- });
+ typeaheadComp.search(observableOf('test')).subscribe();
+ tick(300);
+ typeaheadFixture.detectChanges();
+
+ expect((typeaheadComp as any).authorityService.getEntriesByName).toHaveBeenCalled();
}));
it('should set model.value on input type when AuthorityOptions.closed is false', () => {
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts
index 142fbb0b86..ace6812858 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts
@@ -27,7 +27,6 @@ export class DsDynamicTypeaheadComponent extends DynamicFormControlComponent imp
@Input() bindId = true;
@Input() group: FormGroup;
@Input() model: DynamicTypeaheadModel;
- @Input() showErrorMessages = false;
@Output() blur: EventEmitter = new EventEmitter();
@Output() change: EventEmitter = new EventEmitter();
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 80a4497dd6..b092b87a5a 100644
--- a/src/app/shared/form/builder/form-builder.service.spec.ts
+++ b/src/app/shared/form/builder/form-builder.service.spec.ts
@@ -31,7 +31,7 @@ import { DynamicTagModel } from './ds-dynamic-form-ui/models/tag/dynamic-tag.mod
import { DynamicListCheckboxGroupModel } from './ds-dynamic-form-ui/models/list/dynamic-list-checkbox-group.model';
import { DynamicQualdropModel } from './ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model';
import { DynamicScrollableDropdownModel } from './ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
-import { DynamicGroupModel } from './ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model';
+import { DynamicRelationGroupModel } from './ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
import { DynamicLookupModel } from './ds-dynamic-form-ui/models/lookup/dynamic-lookup.model';
import { DynamicDsDatePickerModel } from './ds-dynamic-form-ui/models/date-picker/date-picker.model';
import { DynamicTypeaheadModel } from './ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.model';
@@ -203,7 +203,7 @@ describe('FormBuilderService test suite', () => {
new DynamicListRadioGroupModel({id: 'testRadioList', authorityOptions: authorityOptions, repeatable: false}),
- new DynamicGroupModel({
+ new DynamicRelationGroupModel({
id: 'testRelationGroup',
formConfiguration: [{
fields: [{
diff --git a/src/app/shared/form/builder/form-builder.service.ts b/src/app/shared/form/builder/form-builder.service.ts
index 918515a984..630e9280ff 100644
--- a/src/app/shared/form/builder/form-builder.service.ts
+++ b/src/app/shared/form/builder/form-builder.service.ts
@@ -4,7 +4,8 @@ import { AbstractControl, FormGroup } from '@angular/forms';
import {
DYNAMIC_FORM_CONTROL_TYPE_ARRAY,
DYNAMIC_FORM_CONTROL_TYPE_CHECKBOX_GROUP,
- DYNAMIC_FORM_CONTROL_TYPE_GROUP, DYNAMIC_FORM_CONTROL_TYPE_INPUT,
+ DYNAMIC_FORM_CONTROL_TYPE_GROUP,
+ DYNAMIC_FORM_CONTROL_TYPE_INPUT,
DYNAMIC_FORM_CONTROL_TYPE_RADIO_GROUP,
DynamicFormArrayModel,
DynamicFormControlModel,
@@ -18,13 +19,12 @@ import { isObject, isString, mergeWith } from 'lodash';
import { hasValue, isEmpty, isNotEmpty, isNotNull, isNotUndefined, isNull } from '../../empty.util';
import { DynamicQualdropModel } from './ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model';
import { SubmissionFormsModel } from '../../../core/config/models/config-submission-forms.model';
-import {
- DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP,
- DynamicGroupModel
-} from './ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model';
import { DYNAMIC_FORM_CONTROL_TYPE_TAG } from './ds-dynamic-form-ui/models/tag/dynamic-tag.model';
import { RowParser } from './parsers/row-parser';
-
+import {
+ DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP,
+ DynamicRelationGroupModel
+} from './ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
import { DynamicRowArrayModel } from './ds-dynamic-form-ui/models/ds-dynamic-row-array-model';
import { DsDynamicInputModel } from './ds-dynamic-form-ui/models/ds-dynamic-input.model';
import { FormFieldMetadataValueObject } from './models/form-field-metadata-value.model';
@@ -158,7 +158,7 @@ export class FormBuilderService extends DynamicFormService {
}
if (this.isRelationGroup(controlModel)) {
- const values = (controlModel as DynamicGroupModel).getGroupValue();
+ const values = (controlModel as DynamicRelationGroupModel).getGroupValue();
values.forEach((groupValue, groupIndex) => {
const newGroupValue = Object.create({});
Object.keys(groupValue)
diff --git a/src/app/shared/form/builder/models/form-field-metadata-value.model.ts b/src/app/shared/form/builder/models/form-field-metadata-value.model.ts
index a189ff95a0..10b3667676 100644
--- a/src/app/shared/form/builder/models/form-field-metadata-value.model.ts
+++ b/src/app/shared/form/builder/models/form-field-metadata-value.model.ts
@@ -1,6 +1,6 @@
import { isEmpty, isNotEmpty, isNotNull } from '../../../empty.util';
import { ConfidenceType } from '../../../../core/integration/models/confidence-type';
-import { PLACEHOLDER_PARENT_METADATA } from '../ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model';
+import { PLACEHOLDER_PARENT_METADATA } from '../ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
export class FormFieldMetadataValueObject {
metadata?: string;
diff --git a/src/app/shared/form/builder/models/form-field-unexpected-object.model.ts b/src/app/shared/form/builder/models/form-field-unexpected-object.model.ts
deleted file mode 100644
index 1b37498a64..0000000000
--- a/src/app/shared/form/builder/models/form-field-unexpected-object.model.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export interface FormFieldChangedObject {
- string: any
-}
diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts
index 3286b3fdbb..28e3fb8fb5 100644
--- a/src/app/shared/form/builder/parsers/field-parser.ts
+++ b/src/app/shared/form/builder/parsers/field-parser.ts
@@ -202,6 +202,14 @@ export abstract class FieldParser {
if (this.configData.languageCodes && this.configData.languageCodes.length > 0) {
(controlModel as DsDynamicInputModel).languageCodes = this.configData.languageCodes;
}
+/* (controlModel as DsDynamicInputModel).languageCodes = [{
+ display: 'English',
+ code: 'en_US'
+ },
+ {
+ display: 'Italian',
+ code: 'it_IT'
+ }];*/
return controlModel;
}
@@ -278,16 +286,6 @@ export abstract class FieldParser {
} else {
modelConfig.value = fieldValue.value;
}
- // if (hasValue(fieldValue.language)) {
- // // Instance of FormFieldLanguageValueObject
- // modelConfig.value = fieldValue.value;
- // } else if (hasValue(fieldValue.metadata)) {
- // // Is a combobox field's value
- // modelConfig.value = fieldValue.value;
- // } else {
- // // Instance of FormFieldMetadataValueObject
- // modelConfig.value = fieldValue;
- // }
} else {
if (forceValueAsObj) {
// If value isn't an instance of FormFieldMetadataValueObject instantiate it
diff --git a/src/app/shared/form/builder/parsers/onebox-field-parser.ts b/src/app/shared/form/builder/parsers/onebox-field-parser.ts
index 8949972918..e1c5f40039 100644
--- a/src/app/shared/form/builder/parsers/onebox-field-parser.ts
+++ b/src/app/shared/form/builder/parsers/onebox-field-parser.ts
@@ -29,7 +29,7 @@ export class OneboxFieldParser extends FieldParser {
const clsSelect = {
element: {
- control: 'input-group-addon ds-form-input-addon',
+ control: 'ds-form-input-addon custom-select',
},
grid: {
host: 'col-sm-4 pr-0'
@@ -74,11 +74,27 @@ export class OneboxFieldParser extends FieldParser {
this.setAuthorityOptions(typeaheadModelConfig, this.parserOptions.authorityUuid);
this.setValues(typeaheadModelConfig, fieldValue, true);
const typeaheadModel = new DynamicTypeaheadModel(typeaheadModelConfig);
+/* typeaheadModel.languageCodes = [{
+ display: 'English',
+ code: 'en_US'
+ },
+ {
+ display: 'Italian',
+ code: 'it_IT'
+ }];*/
return typeaheadModel;
} else {
const inputModelConfig: DsDynamicInputModelConfig = this.initModel(null, label);
this.setValues(inputModelConfig, fieldValue);
const inputModel = new DsDynamicInputModel(inputModelConfig);
+/* inputModel.languageCodes = [{
+ display: 'English',
+ code: 'en_US'
+ },
+ {
+ display: 'Italian',
+ code: 'it_IT'
+ }];*/
return inputModel;
}
}
diff --git a/src/app/shared/form/builder/parsers/parser-factory.ts b/src/app/shared/form/builder/parsers/parser-factory.ts
index da5bee0be2..2cbee18783 100644
--- a/src/app/shared/form/builder/parsers/parser-factory.ts
+++ b/src/app/shared/form/builder/parsers/parser-factory.ts
@@ -3,7 +3,7 @@ import { GenericConstructor } from '../../../../core/shared/generic-constructor'
import { FieldParser } from './field-parser';
import { DateFieldParser } from './date-field-parser';
import { DropdownFieldParser } from './dropdown-field-parser';
-import { GroupFieldParser } from './group-field-parser';
+import { RelationGroupFieldParser } from './relation-group-field-parser';
import { ListFieldParser } from './list-field-parser';
import { LookupFieldParser } from './lookup-field-parser';
import { LookupNameFieldParser } from './lookup-name-field-parser';
@@ -22,8 +22,8 @@ export class ParserFactory {
case ParserType.Dropdown: {
return DropdownFieldParser
}
- case ParserType.Group: {
- return GroupFieldParser
+ case ParserType.RelationGroup: {
+ return RelationGroupFieldParser
}
case ParserType.List: {
return ListFieldParser
diff --git a/src/app/shared/form/builder/parsers/parser-type.ts b/src/app/shared/form/builder/parsers/parser-type.ts
index d6bddf867c..a9af87d73f 100644
--- a/src/app/shared/form/builder/parsers/parser-type.ts
+++ b/src/app/shared/form/builder/parsers/parser-type.ts
@@ -1,7 +1,7 @@
export enum ParserType {
Date = 'date',
Dropdown = 'dropdown',
- Group = 'group',
+ RelationGroup = 'group',
List = 'list',
Lookup = 'lookup',
LookupName = 'lookup-name',
diff --git a/src/app/shared/form/builder/parsers/group-field-parser.spec.ts b/src/app/shared/form/builder/parsers/relation-group-field-parser.spec.ts
similarity index 75%
rename from src/app/shared/form/builder/parsers/group-field-parser.spec.ts
rename to src/app/shared/form/builder/parsers/relation-group-field-parser.spec.ts
index abda8d7169..e6bf0dc2c8 100644
--- a/src/app/shared/form/builder/parsers/group-field-parser.spec.ts
+++ b/src/app/shared/form/builder/parsers/relation-group-field-parser.spec.ts
@@ -1,10 +1,10 @@
import { FormFieldModel } from '../models/form-field.model';
-import { GroupFieldParser } from './group-field-parser';
-import { DynamicGroupModel } from '../ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model';
+import { RelationGroupFieldParser } from './relation-group-field-parser';
+import { DynamicRelationGroupModel } from '../ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model';
import { ParserOptions } from './parser-options';
-describe('GroupFieldParser test suite', () => {
+describe('RelationGroupFieldParser test suite', () => {
let field: FormFieldModel;
let initFormValues = {};
@@ -71,22 +71,22 @@ describe('GroupFieldParser test suite', () => {
});
it('should init parser properly', () => {
- const parser = new GroupFieldParser(field, initFormValues, parserOptions);
+ const parser = new RelationGroupFieldParser(field, initFormValues, parserOptions);
- expect(parser instanceof GroupFieldParser).toBe(true);
+ expect(parser instanceof RelationGroupFieldParser).toBe(true);
});
- it('should return a DynamicGroupModel object', () => {
- const parser = new GroupFieldParser(field, initFormValues, parserOptions);
+ it('should return a DynamicRelationGroupModel object', () => {
+ const parser = new RelationGroupFieldParser(field, initFormValues, parserOptions);
const fieldModel = parser.parse();
- expect(fieldModel instanceof DynamicGroupModel).toBe(true);
+ expect(fieldModel instanceof DynamicRelationGroupModel).toBe(true);
});
it('should throw when rows configuration is empty', () => {
field.rows = null;
- const parser = new GroupFieldParser(field, initFormValues, parserOptions);
+ const parser = new RelationGroupFieldParser(field, initFormValues, parserOptions);
expect(() => parser.parse())
.toThrow();
@@ -97,7 +97,7 @@ describe('GroupFieldParser test suite', () => {
author: [new FormFieldMetadataValueObject('test author')],
affiliation: [new FormFieldMetadataValueObject('test affiliation')]
};
- const parser = new GroupFieldParser(field, initFormValues, parserOptions);
+ const parser = new RelationGroupFieldParser(field, initFormValues, parserOptions);
const fieldModel = parser.parse();
const expectedValue = [{
diff --git a/src/app/shared/form/builder/parsers/group-field-parser.ts b/src/app/shared/form/builder/parsers/relation-group-field-parser.ts
similarity index 86%
rename from src/app/shared/form/builder/parsers/group-field-parser.ts
rename to src/app/shared/form/builder/parsers/relation-group-field-parser.ts
index 61edaf7f99..ca0469ef1a 100644
--- a/src/app/shared/form/builder/parsers/group-field-parser.ts
+++ b/src/app/shared/form/builder/parsers/relation-group-field-parser.ts
@@ -1,18 +1,19 @@
import { FieldParser } from './field-parser';
import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model';
import { FormFieldModel } from '../models/form-field.model';
-import {
- DynamicGroupModel,
- DynamicGroupModelConfig,
- PLACEHOLDER_PARENT_METADATA
-} from '../ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model';
+
import { isNotEmpty } from '../../../empty.util';
import { FormRowModel } from '../../../../core/config/models/config-submission-forms.model';
+import {
+ DynamicRelationGroupModel,
+ DynamicRelationGroupModelConfig,
+ PLACEHOLDER_PARENT_METADATA
+} from '../ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
-export class GroupFieldParser extends FieldParser {
+export class RelationGroupFieldParser extends FieldParser {
public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean) {
- const modelConfiguration: DynamicGroupModelConfig = this.initModel(null, label);
+ const modelConfiguration: DynamicRelationGroupModelConfig = this.initModel(null, label);
modelConfiguration.scopeUUID = this.parserOptions.authorityUuid;
modelConfiguration.submissionScope = this.parserOptions.submissionScope;
@@ -54,7 +55,7 @@ export class GroupFieldParser extends FieldParser {
}
};
- const model = new DynamicGroupModel(modelConfiguration, cls);
+ const model = new DynamicRelationGroupModel(modelConfiguration, cls);
model.name = this.getFieldId();
return model;
}
diff --git a/src/app/shared/form/builder/parsers/row-parser.ts b/src/app/shared/form/builder/parsers/row-parser.ts
index a09d84562c..0bb8a0e89a 100644
--- a/src/app/shared/form/builder/parsers/row-parser.ts
+++ b/src/app/shared/form/builder/parsers/row-parser.ts
@@ -2,7 +2,7 @@ import { DYNAMIC_FORM_CONTROL_TYPE_ARRAY, DynamicFormGroupModelConfig } from '@n
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/dynamic-group/dynamic-group.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';
@@ -10,7 +10,6 @@ import { FormFieldModel } from '../models/form-field.model';
import { ParserType } from './parser-type';
import { ParserOptions } from './parser-options';
import { ParserFactory } from './parser-factory';
-import { TranslateService } from '@ngx-translate/core';
export const ROW_ID_PREFIX = 'df-row-group-config-';
diff --git a/src/app/shared/form/form.component.scss b/src/app/shared/form/form.component.scss
index 0f8145f262..8530a2383c 100644
--- a/src/app/shared/form/form.component.scss
+++ b/src/app/shared/form/form.component.scss
@@ -1,9 +1,9 @@
@import "../../../styles/_variables.scss";
.ds-form-input-addon {
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
- border-right: 0;
+ border-top-right-radius: 0 !important;
+ border-bottom-right-radius: 0 !important;
+ border-right: 0 !important;
}
.ds-form-input-btn {
@@ -18,6 +18,6 @@
}
.ds-form-input-value {
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
+ border-top-left-radius: 0 !important;
+ border-bottom-left-radius: 0 !important;
}
diff --git a/src/app/shared/form/form.component.ts b/src/app/shared/form/form.component.ts
index 2d74ddf8d4..69132c29c0 100644
--- a/src/app/shared/form/form.component.ts
+++ b/src/app/shared/form/form.component.ts
@@ -6,7 +6,7 @@ import {
Input,
OnDestroy,
OnInit,
- Output
+ Output, ViewEncapsulation
} from '@angular/core';
import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms';
@@ -32,6 +32,7 @@ import { FormEntry, FormError } from './form.reducer';
selector: 'ds-form',
styleUrls: ['form.component.scss'],
templateUrl: 'form.component.html',
+ encapsulation: ViewEncapsulation.Native
})
export class FormComponent implements OnDestroy, OnInit {
diff --git a/src/app/shared/notifications/notification/notification.component.spec.ts b/src/app/shared/notifications/notification/notification.component.spec.ts
index a0dbfc4afe..72c9d93841 100644
--- a/src/app/shared/notifications/notification/notification.component.spec.ts
+++ b/src/app/shared/notifications/notification/notification.component.spec.ts
@@ -10,7 +10,6 @@ import { NotificationsService } from '../notifications.service';
import { NotificationType } from '../models/notification-type';
import { notificationsReducer } from '../notifications.reducers';
import { NotificationOptions } from '../models/notification-options.model';
-import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { INotificationBoardOptions } from '../../../../config/notifications-config.interfaces';
import { GlobalConfig } from '../../../../config/global-config.interface';
import { Notification } from '../models/notification.model';
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
index eb52041f74..5ae1795247 100644
--- a/src/app/shared/shared.module.ts
+++ b/src/app/shared/shared.module.ts
@@ -4,12 +4,7 @@ import { RouterModule } from '@angular/router';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { NouisliderModule } from 'ng2-nouislider';
-import {
- NgbDatepickerModule,
- NgbModule,
- NgbTimepickerModule,
- NgbTypeaheadModule
-} from '@ng-bootstrap/ng-bootstrap';
+import { NgbDatepickerModule, NgbModule, NgbTimepickerModule, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core';
@@ -56,9 +51,12 @@ import { LogOutComponent } from './log-out/log-out.component';
import { FormComponent } from './form/form.component';
import { DsDynamicTypeaheadComponent } from './form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component';
import { DsDynamicScrollableDropdownComponent } from './form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component';
-import { DsDynamicFormControlComponent } from './form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component';
+import {
+ DsDynamicFormControlContainerComponent,
+ dsDynamicFormControlMapFn
+} from './form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component';
import { DsDynamicFormComponent } from './form/builder/ds-dynamic-form-ui/ds-dynamic-form.component';
-import { DynamicFormsCoreModule } from '@ng-dynamic-forms/core';
+import { DYNAMIC_FORM_CONTROL_MAP_FN, DynamicFormsCoreModule } from '@ng-dynamic-forms/core';
import { DynamicFormsNGBootstrapUIModule } from '@ng-dynamic-forms/ui-ng-bootstrap';
import { TextMaskModule } from 'angular2-text-mask';
import { DragClickDirective } from './utils/drag-click.directive';
@@ -70,7 +68,9 @@ import { UploaderComponent } from './uploader/uploader.component';
import { ChipsComponent } from './chips/chips.component';
import { DsDynamicTagComponent } from './form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component';
import { DsDynamicListComponent } from './form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component';
-import { DsDynamicGroupComponent } from './form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components';
+import { DsDynamicFormGroupComponent } from './form/builder/ds-dynamic-form-ui/models/form-group/dynamic-form-group.component';
+import { DsDynamicFormArrayComponent } from './form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component';
+import { DsDynamicRelationGroupComponent } from './form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.components';
import { SortablejsModule } from 'angular-sortablejs';
import { NumberPickerComponent } from './number-picker/number-picker.component';
import { DsDatePickerComponent } from './form/builder/ds-dynamic-form-ui/models/date-picker/date-picker.component';
@@ -78,7 +78,6 @@ import { DsDynamicLookupComponent } from './form/builder/ds-dynamic-form-ui/mode
import { MockAdminGuard } from './mocks/mock-admin-guard.service';
import { AlertsComponent } from './alerts/alerts.component';
import { ObjNgFor } from './utils/object-ngfor.pipe';
-import { BrowseByModule } from '../+browse-by/browse-by.module';
import { BrowseByComponent } from './browse-by/browse-by.component';
import { BrowseEntryListElementComponent } from './object-list/browse-entry-list-element/browse-entry-list-element.component';
import { DebounceDirective } from './utils/debounce.directive';
@@ -134,14 +133,16 @@ const COMPONENTS = [
ComcolPageHeaderComponent,
ComcolPageLogoComponent,
DsDynamicFormComponent,
- DsDynamicFormControlComponent,
+ DsDynamicFormControlContainerComponent,
DsDynamicListComponent,
DsDynamicLookupComponent,
DsDynamicScrollableDropdownComponent,
DsDynamicTagComponent,
DsDynamicTypeaheadComponent,
- DsDynamicGroupComponent,
+ DsDynamicRelationGroupComponent,
DsDatePickerComponent,
+ DsDynamicFormGroupComponent,
+ DsDynamicFormArrayComponent,
ErrorComponent,
FormComponent,
LoadingComponent,
@@ -177,12 +178,25 @@ const ENTRY_COMPONENTS = [
CollectionGridElementComponent,
CommunityGridElementComponent,
SearchResultGridElementComponent,
- BrowseEntryListElementComponent
+ BrowseEntryListElementComponent,
+ DsDynamicListComponent,
+ DsDynamicLookupComponent,
+ DsDynamicScrollableDropdownComponent,
+ DsDynamicTagComponent,
+ DsDynamicTypeaheadComponent,
+ DsDynamicRelationGroupComponent,
+ DsDatePickerComponent,
+ DsDynamicFormGroupComponent,
+ DsDynamicFormArrayComponent
];
const PROVIDERS = [
TruncatableService,
- MockAdminGuard
+ MockAdminGuard,
+ {
+ provide: DYNAMIC_FORM_CONTROL_MAP_FN,
+ useValue: dsDynamicFormControlMapFn
+ }
];
const DIRECTIVES = [
diff --git a/src/app/shared/testing/mock-submission-config.ts b/src/app/shared/testing/mock-submission-config.ts
new file mode 100644
index 0000000000..212a2fc5f3
--- /dev/null
+++ b/src/app/shared/testing/mock-submission-config.ts
@@ -0,0 +1,54 @@
+import { SubmissionConfig } from '../../../config/submission-config.interface';
+import { GlobalConfig } from '../../../config/global-config.interface';
+
+export const MOCK_SUBMISSION_CONFIG = {
+ submission: {
+ autosave: {
+ // NOTE: which metadata trigger an autosave
+ metadata: ['dc.title', 'dc.identifier.doi', 'dc.identifier.pmid', 'dc.identifier.arxiv'],
+ // NOTE: every how many minutes submission is saved automatically
+ timer: 5
+ },
+ icons: {
+ metadata: [
+ {
+ name: 'mainField',
+ style: 'fa-user'
+ },
+ {
+ name: 'relatedField',
+ style: 'fa-university'
+ },
+ {
+ name: 'otherRelatedField',
+ style: 'fa-circle'
+ },
+ {
+ name: 'default',
+ style: ''
+ }
+ ],
+ authority: {
+ confidence: [
+ {
+ value: 600,
+ style: 'text-success'
+ },
+ {
+ value: 500,
+ style: 'text-info'
+ },
+ {
+ value: 400,
+ style: 'text-warning'
+ },
+ {
+ value: 'default',
+ style: 'text-muted'
+ },
+
+ ]
+ }
+ }
+ } as SubmissionConfig
+} as GlobalConfig;
diff --git a/src/app/submission/sections/form/form-operations.service.ts b/src/app/submission/sections/form/form-operations.service.ts
index f79f824f77..b024f3226d 100644
--- a/src/app/submission/sections/form/form-operations.service.ts
+++ b/src/app/submission/sections/form/form-operations.service.ts
@@ -19,7 +19,7 @@ import { AuthorityValue } from '../../../core/integration/models/authority.value
import { FormBuilderService } from '../../../shared/form/builder/form-builder.service';
import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model';
import { DynamicQualdropModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model';
-import { DynamicGroupModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.model';
+import { DynamicRelationGroupModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
@Injectable()
export class FormOperationsService {
@@ -135,7 +135,7 @@ export class FormOperationsService {
if (this.formBuilder.isModelInCustomGroup(event.model)) {
fieldValue = (event.model.parent as any).value;
} else if (this.formBuilder.isRelationGroup(event.model)) {
- fieldValue = (event.model as DynamicGroupModel).getGroupValue();
+ fieldValue = (event.model as DynamicRelationGroupModel).getGroupValue();
} else if ((event.model as any).hasLanguages) {
const language = (event.model as any).language;
if ((event.model as DsDynamicInputModel).hasAuthority) {