diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html index 7473f894fa..bfa9c214e9 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html @@ -11,12 +11,15 @@ 'd-none': value?.isVirtual && (model.hasSelectableMetadata || context?.index > 0)}">
- + + +
-
- {{ message | translate: model.validators }} -
+
+ {{ message | translate: model.validators }} +
@@ -32,12 +35,12 @@
-
+
@@ -65,6 +68,9 @@ [relationshipOptions]="model.relationship" > + +
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts index 014c25e189..fd403561e9 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts @@ -37,7 +37,6 @@ import { DynamicFormControl, DynamicFormControlContainerComponent, DynamicFormControlEvent, - DynamicFormControlEventType, DynamicFormControlModel, DynamicFormLayout, DynamicFormLayoutService, @@ -91,10 +90,10 @@ import { DYNAMIC_FORM_CONTROL_TYPE_DISABLED } from './models/disabled/dynamic-di import { DsDynamicLookupRelationModalComponent } from './relation-lookup-modal/dynamic-lookup-relation-modal.component'; import { getAllSucceededRemoteData, + getFirstSucceededRemoteData, getFirstSucceededRemoteDataPayload, getPaginatedListPayload, - getRemoteDataPayload, - getFirstSucceededRemoteData + getRemoteDataPayload } from '../../../../core/shared/operators'; import { RemoteData } from '../../../../core/data/remote-data'; import { Item } from '../../../../core/shared/item.model'; @@ -374,6 +373,15 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo } } + hasRelationship() { + return isNotEmpty(this.model) && this.model.hasOwnProperty('relationship') && isNotEmpty(this.model.relationship); + } + + isVirtual() { + const value: FormFieldMetadataValueObject = this.model.metadataValue; + return isNotEmpty(value) && value.isVirtual; + } + public hasResultsSelected(): Observable { return this.model.value.pipe(map((list: SearchResult[]) => isNotEmpty(list))); } @@ -385,6 +393,11 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo this.modalRef = this.modalService.open(DsDynamicLookupRelationModalComponent, { size: 'lg' }); + + if (hasValue(this.model.value)) { + this.submissionService.dispatchSave(this.model.submissionId); + } + const modalComp = this.modalRef.componentInstance; if (hasValue(this.model.value) && !this.model.readOnly) { @@ -395,18 +408,6 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo } } - if (hasValue(this.model.value)) { - this.model.value = ''; - this.onChange({ - $event: { previousIndex: 0 }, - context: { index: 0 }, - control: this.control, - model: this.model, - type: DynamicFormControlEventType.Change - }); - } - this.submissionService.dispatchSave(this.model.submissionId); - modalComp.repeatable = this.model.repeatable; modalComp.listId = this.listId; modalComp.relationshipOptions = this.model.relationship; @@ -437,6 +438,10 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo .forEach((sub) => sub.unsubscribe()); } + get hasHint(): boolean { + return isNotEmpty(this.model.hint) && this.model.hint !== ' '; + } + /** * Initialize this.item$ based on this.model.submissionId */ diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.html index 57ab7d66d8..07ea131a00 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.html @@ -8,6 +8,7 @@ diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.spec.ts index c606145c03..3a5623cfdd 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.spec.ts @@ -14,6 +14,8 @@ import { createSuccessfulRemoteDataObject$ } from '../../../../remote-data.utils import { RemoveRelationshipAction } from '../relation-lookup-modal/relationship.actions'; import { ItemSearchResult } from '../../../../object-collection/shared/item-search-result.model'; import { of as observableOf } from 'rxjs'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateLoaderMock } from '../../../../testing/translate-loader.mock'; describe('ExistingMetadataListElementComponent', () => { let component: ExistingMetadataListElementComponent; @@ -65,6 +67,14 @@ describe('ExistingMetadataListElementComponent', () => { beforeEach(waitForAsync(() => { init(); TestBed.configureTestingModule({ + imports: [ + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }) + ], declarations: [ExistingMetadataListElementComponent], providers: [ { provide: SelectableListService, useValue: selectionService }, 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 index 7cd153ef5c..fe0c65ea73 100644 --- 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 @@ -2,44 +2,42 @@
-
- - - -
-
-
-
- - - - - - -
-
+ + +
+ +
+ + + + + +
+
+ + +
+ - - - - - diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.scss b/src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.scss index 8fb13f9c55..634a197123 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.scss +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.scss @@ -5,48 +5,41 @@ } .cdk-drag { - margin-left: calc(-2 * var(--bs-spacer)); - margin-right: calc(-0.5 * var(--bs-spacer)); - padding-right: calc(0.5 * var(--bs-spacer)); - .drag-icon { - visibility: hidden; - width: calc(2 * var(--bs-spacer)); - color: var(--bs-gray-600); - margin: var(--bs-btn-padding-y) 0; - line-height: var(--bs-btn-line-height); - text-indent: calc(0.5 * var(--bs-spacer)) - } + margin-left: calc(-2.3 * var(--bs-spacer)); + margin-right: calc(-0.5 * var(--bs-spacer)); + padding-right: calc(0.5 * var(--bs-spacer)); + .drag-icon { + visibility: hidden; + width: calc(2 * var(--bs-spacer)); + color: var(--bs-gray-600); + margin: var(--bs-btn-padding-y) 0; + line-height: var(--bs-btn-line-height); + text-indent: calc(0.5 * var(--bs-spacer)) + } - &:hover, &:focus { - cursor: grab; - .drag-icon { - visibility: visible; - } + &:hover, &:focus { + cursor: grab; + .drag-icon { + visibility: visible; } + } } .cdk-drop-list-dragging { - .cdk-drag { - cursor: grabbing; - .drag-icon { - visibility: hidden; - } + .cdk-drag { + cursor: grabbing; + .drag-icon { + visibility: hidden; } + } } .cdk-drag-preview { - background-color: white; - border-radius: var(--bs-border-radius-sm); - margin-left: 0; - box-shadow: 0 5px 5px 0px rgba(0, 0, 0, 0.2), - 0 8px 10px 1px rgba(0, 0, 0, 0.14), - 0 3px 14px 2px rgba(0, 0, 0, 0.12); - .drag-icon { - visibility: visible; - } + margin: 0; + padding: 0; } .cdk-drag-placeholder { - opacity: 0; + opacity: 0; } 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 index 80b6e000b8..8ab38454a7 100644 --- 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 @@ -5,15 +5,15 @@ import { DynamicFormArrayComponent, DynamicFormControlCustomEvent, DynamicFormControlEvent, - DynamicFormControlEventType, - DynamicFormControlLayout, DynamicFormLayout, + DynamicFormControlLayout, + DynamicFormLayout, DynamicFormLayoutService, DynamicFormValidationService, DynamicTemplateDirective } from '@ng-dynamic-forms/core'; import { Relationship } from '../../../../../../core/shared/item-relationships/relationship.model'; -import { DynamicRowArrayModel } from '../ds-dynamic-row-array-model'; import { hasValue } from '../../../../../empty.util'; +import { DynamicRowArrayModel } from '../ds-dynamic-row-array-model'; @Component({ selector: 'ds-dynamic-form-array', @@ -25,7 +25,7 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent { @Input() formLayout: DynamicFormLayout; @Input() group: FormGroup; @Input() layout: DynamicFormControlLayout; - @Input() model: DynamicRowArrayModel; + @Input() model: DynamicRowArrayModel;// DynamicRow? @Input() templates: QueryList | undefined; /* tslint:disable:no-output-rename */ @@ -43,22 +43,25 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent { } moveSelection(event: CdkDragDrop) { + + // prevent propagating events generated releasing on the same position + if (event.previousIndex === event.currentIndex) { + return; + } + this.model.moveGroup(event.previousIndex, event.currentIndex - event.previousIndex); - const prevIndex = event.previousIndex - 1; - const index = event.currentIndex - 1; + const prevIndex = event.previousIndex; + const index = event.currentIndex; if (hasValue(this.model.groups[index]) && hasValue((this.control as any).controls[index])) { - const $event = { - $event: { previousIndex: prevIndex }, - context: { index }, - control: (this.control as any).controls[index], - group: this.group, + this.onCustomEvent({ + previousIndex: prevIndex, + index, + arrayModel: this.model, model: this.model.groups[index].group[0], - type: DynamicFormControlEventType.Change - }; - - this.onChange($event); - } + control: (this.control as any).controls[index] + }, 'move'); + } } update(event: any, index: number) { @@ -68,4 +71,11 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent { this.onChange($event); } + + /** + * If the drag feature is disabled for this DynamicRowArrayModel. + */ + get dragDisabled(): boolean { + return this.model.groups.length === 1 || !this.model.isDraggable; + } } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-array-model.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-array-model.ts index 8925d8fd87..d0b07de885 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-array-model.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-array-model.ts @@ -9,6 +9,7 @@ export interface DynamicRowArrayModelConfig extends DynamicFormArrayModelConfig metadataKey: string; metadataFields: string[]; hasSelectableMetadata: boolean; + isDraggable: boolean; } export class DynamicRowArrayModel extends DynamicFormArrayModel { @@ -19,6 +20,7 @@ export class DynamicRowArrayModel extends DynamicFormArrayModel { @serializable() metadataKey: string; @serializable() metadataFields: string[]; @serializable() hasSelectableMetadata: boolean; + @serializable() isDraggable: boolean; isRowArray = true; constructor(config: DynamicRowArrayModelConfig, layout?: DynamicFormControlLayout) { @@ -30,5 +32,6 @@ export class DynamicRowArrayModel extends DynamicFormArrayModel { this.metadataKey = config.metadataKey; this.metadataFields = config.metadataFields; this.hasSelectableMetadata = config.hasSelectableMetadata; + this.isDraggable = config.isDraggable; } } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.html index 3442ddb1ba..339f6f278d 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.html @@ -6,7 +6,8 @@