-
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
+
+
+
+ - {{entry.value}}
+ -
+ {{ 'form.other-information.' + item.key | translate }} : {{item.value}}
+
+
+
+
+
+
+
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.scss b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.scss
index 6dec8c1f45b..3e6536110d6 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.scss
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.scss
@@ -4,39 +4,8 @@
display:none
}
-/* enable absolute positioning */
-.spinner-addon {
- position: relative;
-}
-
-/* style fa-spin */
-.spinner-addon .fa-spin {
- color: map-get($theme-colors, primary);
- position: absolute;
- margin-top: 3px;
- padding: 0;
- pointer-events: none;
-}
-
-/* align fa-spin */
-.left-addon .fa-spin {
- left: 0px;
-}
-
-.right-addon .fa-spin {
- right: 0px;
-}
-
-/* add padding */
-.left-addon input {
- padding-left: $spacer * 2;
-}
-
-.right-addon input {
- padding-right: $spacer * 2;
-}
-
:host /deep/ .dropdown-menu {
+ left: 0 !important;
width: 100% !important;
max-height: $dropdown-menu-max-height;
overflow-y: auto !important;
@@ -50,16 +19,11 @@
color: $dropdown-link-hover-color !important;
background-color: $dropdown-link-hover-bg !important;
}
-//
-//.dropdown-menu {
-// margin-top: -($spacer * 0.625);
-//}
div {
overflow: visible;
- //padding-right: 0 !important;
}
-//
-//button {
-// margin-right: $spacer * 0.625;
-//}
+
+.lookup-item {
+ border-bottom: $dropdown-border-width solid $dropdown-border-color;
+}
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 62e9191893e..df2252163dc 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
@@ -20,9 +20,13 @@ import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { TranslateModule } from '@ngx-translate/core';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { By } from '@angular/platform-browser';
-import { AuthorityValueModel } from '../../../../../../core/integration/models/authority-value.model';
+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: {} }
@@ -174,6 +183,7 @@ describe('Dynamic Lookup component', () => {
[bindId]="bindId"
[group]="group"
[model]="model"
+ [showErrorMessages]="showErrorMessages"
(blur)="onBlur($event)"
(change)="onValueChange($event)"
(focus)="onFocus($event)">`;
@@ -249,7 +259,7 @@ describe('Dynamic Lookup component', () => {
it('should select a results entry properly', fakeAsync(() => {
let de = lookupFixture.debugElement.queryAll(By.css('button'));
const btnEl = de[0].nativeElement;
- const selectedValue = Object.assign(new AuthorityValueModel(), {
+ const selectedValue = Object.assign(new AuthorityValue(), {
id: 1,
display: 'one',
value: 1
@@ -353,12 +363,12 @@ describe('Dynamic Lookup component', () => {
it('should select a results entry properly', fakeAsync(() => {
const payload = [
- Object.assign(new AuthorityValueModel(), {
+ Object.assign(new AuthorityValue(), {
id: 1,
display: 'Name, Lastname',
value: 1
}),
- Object.assign(new AuthorityValueModel(), {
+ Object.assign(new AuthorityValue(), {
id: 2,
display: 'NameTwo, LastnameTwo',
value: 2
@@ -366,7 +376,7 @@ describe('Dynamic Lookup component', () => {
];
let de = lookupFixture.debugElement.queryAll(By.css('button'));
const btnEl = de[0].nativeElement;
- const selectedValue = Object.assign(new AuthorityValueModel(), {
+ const selectedValue = Object.assign(new AuthorityValue(), {
id: 1,
display: 'Name, Lastname',
value: 1
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 2a2ee64e9e4..cba352484d8 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
@@ -1,23 +1,26 @@
-
-import {distinctUntilChanged} from 'rxjs/operators';
import { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { FormGroup } from '@angular/forms';
+import { Subscription } from 'rxjs';
+import { of as observableOf } from 'rxjs';
+import { catchError, distinctUntilChanged } from 'rxjs/operators';
+import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap';
+import {
+ DynamicFormControlComponent,
+ DynamicFormLayoutService,
+ DynamicFormValidationService
+} from '@ng-dynamic-forms/core';
+
import { AuthorityService } from '../../../../../../core/integration/authority.service';
import { DynamicLookupModel } from './dynamic-lookup.model';
import { IntegrationSearchOptions } from '../../../../../../core/integration/models/integration-options.model';
import { hasValue, isEmpty, isNotEmpty, isNull, isUndefined } from '../../../../../empty.util';
import { IntegrationData } from '../../../../../../core/integration/integration-data';
import { PageInfo } from '../../../../../../core/shared/page-info.model';
-import { Subscription } from 'rxjs';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
-import { AuthorityValueModel } from '../../../../../../core/integration/models/authority-value.model';
+import { AuthorityValue } from '../../../../../../core/integration/models/authority.value';
import { DynamicLookupNameModel } from './dynamic-lookup-name.model';
-import {
- DynamicFormControlComponent,
- DynamicFormLayoutService,
- DynamicFormValidationService
-} from '@ng-dynamic-forms/core';
+import { ConfidenceType } from '../../../../../../core/integration/models/confidence-type';
@Component({
selector: 'ds-dynamic-lookup',
@@ -33,6 +36,7 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
@Output() change: EventEmitter
= new EventEmitter();
@Output() focus: EventEmitter = new EventEmitter();
+ public editMode = false;
public firstInputValue = '';
public secondInputValue = '';
public loading = false;
@@ -40,7 +44,7 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
public optionsList: any;
protected searchOptions: IntegrationSearchOptions;
- protected sub: Subscription;
+ protected subs: Subscription[] = [];
constructor(private authorityService: AuthorityService,
private cdr: ChangeDetectorRef,
@@ -50,6 +54,10 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
super(layoutService, validationService);
}
+ inputFormatter = (x: { display: string }, y: number) => {
+ return y === 1 ? this.firstInputValue : this.secondInputValue;
+ };
+
ngOnInit() {
this.searchOptions = new IntegrationSearchOptions(
this.model.authorityOptions.scope,
@@ -61,51 +69,44 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
this.setInputsValue(this.model.value);
- this.model.valueUpdates
+ this.subs.push(this.model.valueUpdates
.subscribe((value) => {
if (isEmpty(value)) {
this.resetFields();
- } else {
+ } else if (!this.editMode) {
this.setInputsValue(this.model.value);
}
- });
+ }));
}
- public formatItemForInput(item: any, field: number): string {
- if (isUndefined(item) || isNull(item)) {
- return '';
- }
- return (typeof item === 'string') ? item : this.inputFormatter(item, field);
- }
-
- // inputFormatter = (x: { display: string }) => x.display;
- inputFormatter = (x: { display: string }, y: number) => {
- // this.splitValues();
- return y === 1 ? this.firstInputValue : this.secondInputValue;
- };
-
- onInput(event) {
- if (!this.model.authorityOptions.closed) {
- if (isNotEmpty(this.getCurrentValue())) {
- const currentValue = new FormFieldMetadataValueObject(this.getCurrentValue());
- this.onSelect(currentValue);
- } else {
- this.remove();
+ protected getCurrentValue(): string {
+ let result = '';
+ if (!this.isLookupName()) {
+ result = this.firstInputValue;
+ } else {
+ if (isNotEmpty(this.firstInputValue)) {
+ result = this.firstInputValue;
+ }
+ if (isNotEmpty(this.secondInputValue)) {
+ result = isEmpty(result)
+ ? this.secondInputValue
+ : this.firstInputValue + (this.model as DynamicLookupNameModel).separator + ' ' + this.secondInputValue;
}
}
+ return result;
}
- onScroll() {
- if (!this.loading && this.pageInfo.currentPage <= this.pageInfo.totalPages) {
- this.searchOptions.currentPage++;
- this.search();
+ protected resetFields() {
+ this.firstInputValue = '';
+ if (this.isLookupName()) {
+ this.secondInputValue = '';
}
}
protected setInputsValue(value) {
if (hasValue(value)) {
let displayValue = value;
- if (value instanceof FormFieldMetadataValueObject || value instanceof AuthorityValueModel) {
+ if (value instanceof FormFieldMetadataValueObject || value instanceof AuthorityValue) {
displayValue = value.display;
}
@@ -122,56 +123,74 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
}
}
- protected getCurrentValue(): string {
- let result = '';
- if (!this.isLookupName()) {
- result = this.firstInputValue;
- } else {
- if (isNotEmpty(this.firstInputValue)) {
- result = this.firstInputValue;
- }
- if (isNotEmpty(this.secondInputValue)) {
- result = isEmpty(result)
- ? this.secondInputValue
- : this.firstInputValue + (this.model as DynamicLookupNameModel).separator + ' ' + this.secondInputValue;
- }
+ public formatItemForInput(item: any, field: number): string {
+ if (isUndefined(item) || isNull(item)) {
+ return '';
}
- return result;
+ return (typeof item === 'string') ? item : this.inputFormatter(item, field);
}
- search() {
- this.optionsList = null;
- this.pageInfo = null;
-
- // Query
- this.searchOptions.query = this.getCurrentValue();
+ public hasAuthorityValue() {
+ return hasValue(this.model.value)
+ && this.model.value.hasAuthority();
+ }
- this.loading = true;
- this.authorityService.getEntriesByName(this.searchOptions).pipe(
- distinctUntilChanged())
- .subscribe((object: IntegrationData) => {
- this.optionsList = object.payload;
- this.pageInfo = object.pageInfo;
- this.loading = false;
- this.cdr.detectChanges();
- });
+ public hasEmptyValue() {
+ return isNotEmpty(this.getCurrentValue());
}
- clearFields() {
+ public clearFields() {
// Clear inputs whether there is no results and authority is closed
if (this.model.authorityOptions.closed) {
this.resetFields();
}
}
- protected resetFields() {
- this.firstInputValue = '';
- if (this.isLookupName()) {
- this.secondInputValue = '';
+ public isEditDisabled() {
+ return !this.hasAuthorityValue();
+ }
+
+ public isInputDisabled() {
+ return (this.model.authorityOptions.closed && this.hasAuthorityValue() && !this.editMode);
+ }
+
+ public isLookupName() {
+ return (this.model instanceof DynamicLookupNameModel);
+ }
+
+ public isSearchDisabled() {
+ return isEmpty(this.firstInputValue);
+ }
+
+ public onBlurEvent(event: Event) {
+ this.blur.emit(event);
+ }
+
+ public onFocusEvent(event) {
+ this.focus.emit(event);
+ }
+
+ public onInput(event) {
+ if (!this.model.authorityOptions.closed) {
+ if (isNotEmpty(this.getCurrentValue())) {
+ const currentValue = new FormFieldMetadataValueObject(this.getCurrentValue());
+ if (!this.editMode) {
+ this.onSelect(currentValue);
+ }
+ } else {
+ this.remove();
+ }
+ }
+ }
+
+ public onScroll() {
+ if (!this.loading && this.pageInfo.currentPage <= this.pageInfo.totalPages) {
+ this.searchOptions.currentPage++;
+ this.search();
}
}
- onSelect(event) {
+ public onSelect(event) {
this.group.markAsDirty();
this.model.valueUpdates.next(event);
this.setInputsValue(event);
@@ -180,48 +199,72 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
this.pageInfo = null;
}
- isInputDisabled() {
- return this.model.authorityOptions.closed && hasValue(this.model.value);
- }
-
- isLookupName() {
- return (this.model instanceof DynamicLookupNameModel);
- }
-
- isSearchDisabled() {
- // if (this.firstInputValue === ''
- // && (this.isLookupName ? this.secondInputValue === '' : true)) {
- // return true;
- // }
- // return false;
- return isEmpty(this.firstInputValue);
+ public openChange(isOpened: boolean) {
+ if (!isOpened) {
+ if (this.model.authorityOptions.closed && !this.hasAuthorityValue()) {
+ this.setInputsValue('');
+ }
+ }
}
- remove() {
+ public remove() {
this.group.markAsPristine();
this.model.valueUpdates.next(null);
this.change.emit(null);
}
- openChange(isOpened: boolean) {
- if (!isOpened) {
- if (this.model.authorityOptions.closed) {
- this.setInputsValue('');
- }
+ public saveChanges() {
+ if (isNotEmpty(this.getCurrentValue())) {
+ const newValue = Object.assign(new AuthorityValue(), this.model.value, {
+ display: this.getCurrentValue(),
+ value: this.getCurrentValue()
+ });
+ this.onSelect(newValue);
+ } else {
+ this.remove();
}
+ this.switchEditMode();
}
- onBlurEvent(event: Event) {
- this.blur.emit(event);
+ public search() {
+ this.optionsList = null;
+ this.pageInfo = null;
+
+ // Query
+ this.searchOptions.query = this.getCurrentValue();
+
+ this.loading = true;
+ this.subs.push(this.authorityService.getEntriesByName(this.searchOptions).pipe(
+ catchError(() => {
+ const emptyResult = new IntegrationData(
+ new PageInfo(),
+ []
+ );
+ return observableOf(emptyResult);
+ }),
+ distinctUntilChanged())
+ .subscribe((object: IntegrationData) => {
+ this.optionsList = object.payload;
+ this.pageInfo = object.pageInfo;
+ this.loading = false;
+ this.cdr.detectChanges();
+ }));
}
- onFocusEvent(event) {
- this.focus.emit(event);
+ public switchEditMode() {
+ this.editMode = !this.editMode;
}
- ngOnDestroy() {
- if (hasValue(this.sub)) {
- this.sub.unsubscribe();
+ public whenClickOnConfidenceNotAccepted(sdRef: NgbDropdown, confidence: ConfidenceType) {
+ if (!this.model.readOnly) {
+ sdRef.open();
+ this.search();
}
}
+
+ ngOnDestroy() {
+ this.subs
+ .filter((sub) => hasValue(sub))
+ .forEach((sub) => sub.unsubscribe());
+ }
}
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 93%
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
index 322ea53560d..f584a756111 100644
--- 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
@@ -56,7 +56,8 @@