From 151b02aeec81107731f5eadcdf4d4f25e7d34590 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Wed, 17 Feb 2021 16:10:22 +0100 Subject: [PATCH 01/21] [CST-3782] Make changes in order to remove template row in form's repeatable fields --- ...amic-form-control-container.component.html | 7 +- ...ynamic-form-control-container.component.ts | 4 + .../dynamic-form-array.component.html | 61 ++++------ .../dynamic-form-array.component.ts | 7 +- .../form/builder/form-builder.service.ts | 8 +- .../builder/parsers/concat-field-parser.ts | 16 ++- .../form/builder/parsers/field-parser.ts | 37 +++--- .../builder/parsers/onebox-field-parser.ts | 4 +- src/app/shared/form/form.component.html | 107 +++++++++--------- src/app/shared/form/form.component.ts | 47 +------- .../form/section-form-operations.service.ts | 33 +++--- src/assets/i18n/en.json5 | 2 + 12 files changed, 154 insertions(+), 179 deletions(-) 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..0ab69851a5 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 @@ -13,6 +13,11 @@ + +  
{{ message | translate: model.validators }} @@ -32,7 +37,7 @@
-
+
-
-
- - -
-
- -
-
- - - - - - -
-
-
-
- - -
-
+ + + +
+
+ + +
- + +
+
+ +
+
+
+ +
+ + + +
+
+
+
+ + +
+
+
+ +
diff --git a/src/app/shared/form/form.component.ts b/src/app/shared/form/form.component.ts index a4af407a55..f749f4391b 100644 --- a/src/app/shared/form/form.component.ts +++ b/src/app/shared/form/form.component.ts @@ -187,7 +187,6 @@ export class FormComponent implements OnDestroy, OnInit { if (field) { const model: DynamicFormControlModel = this.formBuilderService.findById(fieldId, formModel); this.formService.addErrorToField(field, model, error.message); - // this.formService.validateAllFormFields(formGroup); this.changeDetectorRef.detectChanges(); } @@ -300,55 +299,15 @@ export class FormComponent implements OnDestroy, OnInit { removeItem($event, arrayContext: DynamicFormArrayModel, index: number): void { const formArrayControl = this.formGroup.get(this.formBuilderService.getPath(arrayContext)) as FormArray; - this.removeArrayItem.emit(this.getEvent($event, arrayContext, index - 1, 'remove')); + this.removeArrayItem.emit(this.getEvent($event, arrayContext, index, 'remove')); this.formBuilderService.removeFormArrayGroup(index, formArrayControl, arrayContext); this.formService.changeForm(this.formId, this.formModel); } insertItem($event, arrayContext: DynamicFormArrayModel, index: number): void { const formArrayControl = this.formGroup.get(this.formBuilderService.getPath(arrayContext)) as FormArray; - - // First emit the new value so it can be sent to the server - const value = formArrayControl.controls[0].value; - const event = this.getEvent($event, arrayContext, 0, 'add'); - this.addArrayItem.emit(event); - this.change.emit(event); - - // Next: update the UI so the user sees the changes - // without having to wait for the server's reply - - // add an empty new field at the bottom - this.formBuilderService.addFormArrayGroup(formArrayControl, arrayContext); - - // set that field to the new value - const model = arrayContext.groups[arrayContext.groups.length - 1].group[0] as any; - if (model.hasAuthority) { - model.value = Object.values(value)[0]; - const ctrl = formArrayControl.controls[formArrayControl.length - 1]; - const ctrlValue = ctrl.value; - const ctrlValueKey = Object.keys(ctrlValue)[0]; - ctrl.setValue({ - [ctrlValueKey]: model.value - }); - } else if (this.formBuilderService.isQualdropGroup(model)) { - const ctrl = formArrayControl.controls[formArrayControl.length - 1]; - const ctrlKey = Object.keys(ctrl.value).find((key: string) => isNotEmpty(key.match(QUALDROP_GROUP_REGEX))); - const valueKey = Object.keys(value).find((key: string) => isNotEmpty(key.match(QUALDROP_GROUP_REGEX))); - if (ctrlKey !== valueKey) { - Object.defineProperty(value, ctrlKey, Object.getOwnPropertyDescriptor(value, valueKey)); - delete value[valueKey]; - } - ctrl.setValue(value); - } else { - formArrayControl.controls[formArrayControl.length - 1].setValue(value); - } - - // Clear the topmost field by removing the filled out version and inserting a new, empty version. - // Doing it this way ensures an empty value of the correct type is added without a bunch of ifs here - this.formBuilderService.removeFormArrayGroup(0, formArrayControl, arrayContext); - this.formBuilderService.insertFormArrayGroup(0, formArrayControl, arrayContext); - - // Tell the formService that it should rerender. + this.formBuilderService.insertFormArrayGroup(index, formArrayControl, arrayContext); + this.addArrayItem.emit(this.getEvent($event, arrayContext, index, 'add')); this.formService.changeForm(this.formId, this.formModel); } diff --git a/src/app/submission/sections/form/section-form-operations.service.ts b/src/app/submission/sections/form/section-form-operations.service.ts index d019663d6c..1c372fb06f 100644 --- a/src/app/submission/sections/form/section-form-operations.service.ts +++ b/src/app/submission/sections/form/section-form-operations.service.ts @@ -9,15 +9,7 @@ import { DynamicFormControlModel } from '@ng-dynamic-forms/core'; -import { - hasNoValue, - hasValue, - isNotEmpty, - isNotNull, - isNotUndefined, - isNull, - isUndefined -} from '../../../shared/empty.util'; +import { hasValue, isNotEmpty, isNotNull, isNotUndefined, isNull, isUndefined } from '../../../shared/empty.util'; import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner'; import { FormFieldPreviousValueObject } from '../../../shared/form/builder/models/form-field-previous-value-object'; import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder'; @@ -30,6 +22,7 @@ import { DynamicQualdropModel } from '../../../shared/form/builder/ds-dynamic-fo import { DynamicRelationGroupModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model'; import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; import { deepClone } from 'fast-json-patch'; +import { dateToString, isNgbDateStruct } from '../../../shared/date.util'; /** * The service handling all form section operations @@ -71,9 +64,6 @@ export class SectionFormOperationsService { case 'change': this.dispatchOperationsFromChangeEvent(pathCombiner, event, previousValue, hasStoredValue); break; - case 'add': - this.dispatchOperationsFromAddEvent(pathCombiner, event); - break; default: break; } @@ -245,6 +235,8 @@ export class SectionFormOperationsService { // Language without Authority (input, textArea) fieldValue = new FormFieldMetadataValueObject(value, language); } + } else if (isNgbDateStruct(value)) { + fieldValue = new FormFieldMetadataValueObject(dateToString(value)); } else if (value instanceof FormFieldLanguageValueObject || value instanceof VocabularyEntry || value instanceof VocabularyEntryDetail || isObject(value)) { fieldValue = value; @@ -295,7 +287,7 @@ export class SectionFormOperationsService { const value = this.getFieldValueFromChangeEvent(event); if (this.formBuilder.isQualdropGroup(event.model as DynamicFormControlModel)) { this.dispatchOperationsFromMap(this.getQualdropValueMap(event), pathCombiner, event, previousValue); - } else if (isNotEmpty(value)) { + } else if (isNotEmpty(value) && (value instanceof FormFieldMetadataValueObject && value.hasValue())) { this.operationsBuilder.remove(pathCombiner.getPath(path)); } } @@ -362,7 +354,7 @@ export class SectionFormOperationsService { } else if (this.formBuilder.isRelationGroup(event.model)) { // It's a relation model this.dispatchOperationsFromMap(this.getValueMap(value), pathCombiner, event, previousValue); - } else if (this.formBuilder.hasArrayGroupValue(event.model) && hasNoValue((event.model as any).relationshipConfig)) { + } else if (this.formBuilder.hasArrayGroupValue(event.model)) { // Model has as value an array, so dispatch an add operation with entire block of values this.operationsBuilder.add( pathCombiner.getPath(segmentedPath), @@ -398,13 +390,22 @@ export class SectionFormOperationsService { value); } previousValue.delete(); - } else if (value.hasValue() && (isUndefined(this.getArrayIndexFromEvent(event)) - || this.getArrayIndexFromEvent(event) === 0)) { + } else if (value.hasValue()) { + // Here model has no previous value but a new one + if (isUndefined(this.getArrayIndexFromEvent(event)) + || this.getArrayIndexFromEvent(event) === 0) { // Model is single field or is part of an array model but is the first item, // so dispatch an add operation that initialize the values of a specific metadata this.operationsBuilder.add( pathCombiner.getPath(segmentedPath), value, true); + } else { + // Model is part of an array model but is not the first item, + // so dispatch an add operation that add a value to an existent metadata + this.operationsBuilder.add( + pathCombiner.getPath(path), + value); + } } } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 51a2c0bd35..05d3aa4e49 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1267,6 +1267,8 @@ "form.clear-help": "Click here to remove the selected value", + "form.discard": "Discard", + "form.edit": "Edit", "form.edit-help": "Click here to edit the selected value", From d208cf16fa56bd27b17f1f70b3e1cabcfb8607a8 Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Wed, 17 Feb 2021 17:57:29 +0100 Subject: [PATCH 02/21] [CST-3782] Drag drop restored --- .../dynamic-form-array.component.html | 50 +++++++++++-------- .../dynamic-form-array.component.ts | 12 +++-- src/app/shared/form/form.component.spec.ts | 4 +- .../sections/form/section-form.component.ts | 21 ++++---- 4 files changed, 49 insertions(+), 38 deletions(-) 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 d6cfc57b90..ec007d6ff4 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 @@ -3,29 +3,37 @@ [formArrayName]="model.id" [ngClass]="getClass('element', 'control')"> -
- - - - - - + +
+ +
+ + + + +
+
+ +
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 3c275ddf19..b6c1a6c308 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 @@ -44,9 +44,15 @@ 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 = { @@ -59,7 +65,7 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent { }; this.onChange($event); - } + } } update(event: any, index: number) { diff --git a/src/app/shared/form/form.component.spec.ts b/src/app/shared/form/form.component.spec.ts index aa004b3f87..4dd733a554 100644 --- a/src/app/shared/form/form.component.spec.ts +++ b/src/app/shared/form/form.component.spec.ts @@ -418,7 +418,7 @@ describe('FormComponent test suite', () => { })); it('should dispatch FormChangeAction when an item has been removed from an array', inject([FormBuilderService], (service: FormBuilderService) => { - formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1); + formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 0); expect(store.dispatch).toHaveBeenCalledWith(new FormChangeAction('testFormArray', service.getValueFromModel(formComp.formModel))); })); @@ -426,7 +426,7 @@ describe('FormComponent test suite', () => { it('should emit removeArrayItem Event when an item has been removed from an array', inject([FormBuilderService], (service: FormBuilderService) => { spyOn(formComp.removeArrayItem, 'emit'); - formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1); + formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 0); expect(formComp.removeArrayItem.emit).toHaveBeenCalled(); })); diff --git a/src/app/submission/sections/form/section-form.component.ts b/src/app/submission/sections/form/section-form.component.ts index c3d4575148..bc88323a8c 100644 --- a/src/app/submission/sections/form/section-form.component.ts +++ b/src/app/submission/sections/form/section-form.component.ts @@ -359,19 +359,16 @@ export class SubmissionSectionformComponent extends SectionModelComponent { * the [[DynamicFormControlEvent]] emitted */ onChange(event: DynamicFormControlEvent): void { - // don't handle change events for things with an index < 0, those are template rows. - if (hasNoValue(event.context) || hasNoValue(event.context.index) || event.context.index >= 0) { - this.formOperationsService.dispatchOperationsFromEvent( - this.pathCombiner, - event, - this.previousValue, - this.hasStoredValue(this.formBuilderService.getId(event.model), this.formOperationsService.getArrayIndexFromEvent(event))); - const metadata = this.formOperationsService.getFieldPathSegmentedFromChangeEvent(event); - const value = this.formOperationsService.getFieldValueFromChangeEvent(event); + this.formOperationsService.dispatchOperationsFromEvent( + this.pathCombiner, + event, + this.previousValue, + this.hasStoredValue(this.formBuilderService.getId(event.model), this.formOperationsService.getArrayIndexFromEvent(event))); + const metadata = this.formOperationsService.getFieldPathSegmentedFromChangeEvent(event); + const value = this.formOperationsService.getFieldValueFromChangeEvent(event); - if (environment.submission.autosave.metadata.indexOf(metadata) !== -1 && isNotEmpty(value)) { - this.submissionService.dispatchSave(this.submissionId); - } + if (environment.submission.autosave.metadata.indexOf(metadata) !== -1 && isNotEmpty(value)) { + this.submissionService.dispatchSave(this.submissionId); } } From 1901ace5a6416d12b00bbe70ce2d43aded99ad1d Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Wed, 17 Feb 2021 20:25:46 +0100 Subject: [PATCH 03/21] [CST-3782] Changes in order to display add more and lookup button at the end of the repeatable fields array --- ...amic-form-control-container.component.html | 18 ++---- ...ynamic-form-control-container.component.ts | 51 +--------------- ...sting-metadata-list-element.component.html | 1 + ...ng-metadata-list-element.component.spec.ts | 10 ++++ .../dynamic-form-array.component.html | 2 +- .../dynamic-form-array.component.scss | 3 +- ...namic-lookup-relation-modal.component.html | 3 +- ...ic-lookup-relation-modal.component.spec.ts | 20 +++++++ ...dynamic-lookup-relation-modal.component.ts | 37 +++++++++++- src/app/shared/form/form.component.html | 33 +++++++---- src/app/shared/form/form.component.scss | 5 ++ src/app/shared/form/form.component.ts | 59 ++++++++++++++++--- src/assets/i18n/en.json5 | 2 +- 13 files changed, 160 insertions(+), 84 deletions(-) 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 0ab69851a5..cb00993324 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,13 +11,12 @@ 'd-none': value?.isVirtual && (model.hasSelectableMetadata || context?.index > 0)}">
+ - -   + +
{{ message | translate: model.validators }} @@ -37,14 +36,6 @@
-
- -
@@ -70,6 +61,7 @@ [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 72dd374231..6c080a7f53 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, @@ -83,18 +82,16 @@ import { find, map, startWith, switchMap, take } from 'rxjs/operators'; import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs'; import { SearchResult } from '../../../search/search-result.model'; import { DSpaceObject } from '../../../../core/shared/dspace-object.model'; -import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { RelationshipService } from '../../../../core/data/relationship.service'; import { SelectableListService } from '../../../object-list/selectable-list/selectable-list.service'; import { DsDynamicDisabledComponent } from './models/disabled/dynamic-disabled.component'; import { DYNAMIC_FORM_CONTROL_TYPE_DISABLED } from './models/disabled/dynamic-disabled.model'; -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'; @@ -110,7 +107,6 @@ import { Collection } from '../../../../core/shared/collection.model'; import { MetadataValue, VIRTUAL_METADATA_PREFIX } from '../../../../core/shared/metadata.models'; import { FormService } from '../../form.service'; import { SelectableListState } from '../../../object-list/selectable-list/selectable-list.reducer'; -import { SubmissionService } from '../../../../submission/submission.service'; import { followLink } from '../../../utils/follow-link-config.model'; import { paginatedRelationsToItems } from '../../../../+item-page/simple/item-types/shared/item-relationships-utils'; import { RelationshipOptions } from '../models/relationship-options.model'; @@ -206,7 +202,6 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo @Input() model: any; relationshipValue$: Observable; isRelationship: boolean; - modalRef: NgbModalRef; item: Item; item$: Observable; collection: Collection; @@ -239,7 +234,6 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo protected validationService: DynamicFormValidationService, protected translateService: TranslateService, protected relationService: DynamicFormRelationService, - private modalService: NgbModal, private relationshipService: RelationshipService, private selectableListService: SelectableListService, private itemService: ItemDataService, @@ -249,7 +243,6 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo private ref: ChangeDetectorRef, private formService: FormService, private formBuilderService: FormBuilderService, - private submissionService: SubmissionService ) { super(ref, componentFactoryResolver, layoutService, validationService, dynamicFormComponentService, relationService); } @@ -264,7 +257,6 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo if (this.isRelationship || isWrapperAroundRelationshipList) { const config = this.model.relationshipConfig || this.model.relationship; const relationshipOptions = Object.assign(new RelationshipOptions(), config); - this.listId = `list-${this.model.submissionId}-${relationshipOptions.relationshipType}`; this.setItem(); if (isWrapperAroundRelationshipList || !this.model.repeatable) { @@ -378,45 +370,6 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo return this.model.value.pipe(map((list: SearchResult[]) => isNotEmpty(list))); } - /** - * Open a modal where the user can select relationships to be added to item being submitted - */ - openLookup() { - this.modalRef = this.modalService.open(DsDynamicLookupRelationModalComponent, { - size: 'lg' - }); - const modalComp = this.modalRef.componentInstance; - - if (hasValue(this.model.value) && !this.model.readOnly) { - if (typeof this.model.value === 'string') { - modalComp.query = this.model.value; - } else if (typeof this.model.value.value === 'string') { - modalComp.query = this.model.value.value; - } - } - - 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; - modalComp.label = this.model.relationship.relationshipType; - modalComp.metadataFields = this.model.metadataFields; - modalComp.item = this.item; - modalComp.collection = this.collection; - modalComp.submissionId = this.model.submissionId; - } - /** * Callback for the remove event, * remove the current control from its array 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 ec007d6ff4..d036627345 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 @@ -12,7 +12,7 @@ [ngClass]="[getClass('element', 'group'), getClass('grid', 'group')]" cdkDrag cdkDragHandle> - + From 975ef7ebd2d8c037813757ebbc96413676b5dcb3 Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Wed, 24 Feb 2021 15:34:21 +0100 Subject: [PATCH 07/21] [CST-3782] Style refinements and qualdrop moves fixed --- ...-dynamic-form-control-container.component.html | 15 +++++++-------- .../array-group/dynamic-form-array.component.html | 6 ++++++ .../array-group/dynamic-form-array.component.scss | 14 ++++---------- .../form/section-form-operations.service.ts | 3 ++- src/assets/i18n/en.json5 | 1 + 5 files changed, 20 insertions(+), 19 deletions(-) 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 cb00993324..029ba0b1f8 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,16 +11,15 @@ 'd-none': value?.isVirtual && (model.hasSelectableMetadata || context?.index > 0)}">
- - - -
+ +
-
- {{ message | translate: model.validators }} -
+
+ {{ message | translate: model.validators }} +
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 d036627345..732b5978ac 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 @@ -12,6 +12,12 @@ [ngClass]="[getClass('element', 'group'), getClass('grid', 'group')]" cdkDrag cdkDragHandle> +
+
+ {{ 'form.repeatable.sort.tip' | translate }} +
+
+ Date: Thu, 25 Feb 2021 13:17:47 +0100 Subject: [PATCH 08/21] [CST-3620] fix typo --- src/app/shared/form/builder/parsers/field-parser.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts index b8411ca22c..93f941e344 100644 --- a/src/app/shared/form/builder/parsers/field-parser.ts +++ b/src/app/shared/form/builder/parsers/field-parser.ts @@ -67,11 +67,11 @@ export abstract class FieldParser { model = this.modelFactory(); arrayCounter++; } else { - const fieldArrayOfValueLenght = this.getInitValueCount(arrayCounter - 1); + const fieldArrayOfValueLength = this.getInitValueCount(arrayCounter - 1); let fieldValue = null; - if (fieldArrayOfValueLenght > 0) { + if (fieldArrayOfValueLength > 0) { fieldValue = this.getInitFieldValue(arrayCounter - 1, fieldArrayCounter++); - if (fieldArrayCounter === fieldArrayOfValueLenght) { + if (fieldArrayCounter === fieldArrayOfValueLength) { fieldArrayCounter = 0; arrayCounter++; } From a6effcad34051b058ee63fc33167342eec5a1b1a Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Thu, 25 Feb 2021 17:09:33 +0100 Subject: [PATCH 09/21] [CST-3620] Changes to show lookup button next to the field --- ...amic-form-control-container.component.html | 8 +++ ...ynamic-form-control-container.component.ts | 66 +++++++++++++++++++ ...dynamic-lookup-relation-modal.component.ts | 1 - src/app/shared/form/form.component.html | 10 +-- src/app/shared/form/form.component.ts | 44 +------------ 5 files changed, 77 insertions(+), 52 deletions(-) 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 029ba0b1f8..8ba6489068 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 @@ -35,6 +35,14 @@
+
+ +
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 6c080a7f53..5ab4a7b247 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,6 +37,7 @@ import { DynamicFormControl, DynamicFormControlContainerComponent, DynamicFormControlEvent, + DynamicFormControlEventType, DynamicFormControlModel, DynamicFormLayout, DynamicFormLayoutService, @@ -82,10 +83,12 @@ import { find, map, startWith, switchMap, take } from 'rxjs/operators'; import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs'; import { SearchResult } from '../../../search/search-result.model'; import { DSpaceObject } from '../../../../core/shared/dspace-object.model'; +import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { RelationshipService } from '../../../../core/data/relationship.service'; import { SelectableListService } from '../../../object-list/selectable-list/selectable-list.service'; import { DsDynamicDisabledComponent } from './models/disabled/dynamic-disabled.component'; import { DYNAMIC_FORM_CONTROL_TYPE_DISABLED } from './models/disabled/dynamic-disabled.model'; +import { DsDynamicLookupRelationModalComponent } from './relation-lookup-modal/dynamic-lookup-relation-modal.component'; import { getAllSucceededRemoteData, getFirstSucceededRemoteData, @@ -107,6 +110,7 @@ import { Collection } from '../../../../core/shared/collection.model'; import { MetadataValue, VIRTUAL_METADATA_PREFIX } from '../../../../core/shared/metadata.models'; import { FormService } from '../../form.service'; import { SelectableListState } from '../../../object-list/selectable-list/selectable-list.reducer'; +import { SubmissionService } from '../../../../submission/submission.service'; import { followLink } from '../../../utils/follow-link-config.model'; import { paginatedRelationsToItems } from '../../../../+item-page/simple/item-types/shared/item-relationships-utils'; import { RelationshipOptions } from '../models/relationship-options.model'; @@ -202,6 +206,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo @Input() model: any; relationshipValue$: Observable; isRelationship: boolean; + modalRef: NgbModalRef; item: Item; item$: Observable; collection: Collection; @@ -234,6 +239,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo protected validationService: DynamicFormValidationService, protected translateService: TranslateService, protected relationService: DynamicFormRelationService, + private modalService: NgbModal, private relationshipService: RelationshipService, private selectableListService: SelectableListService, private itemService: ItemDataService, @@ -243,6 +249,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo private ref: ChangeDetectorRef, private formService: FormService, private formBuilderService: FormBuilderService, + private submissionService: SubmissionService ) { super(ref, componentFactoryResolver, layoutService, validationService, dynamicFormComponentService, relationService); } @@ -257,6 +264,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo if (this.isRelationship || isWrapperAroundRelationshipList) { const config = this.model.relationshipConfig || this.model.relationship; const relationshipOptions = Object.assign(new RelationshipOptions(), config); + this.listId = `list-${this.model.submissionId}-${relationshipOptions.relationshipType}`; this.setItem(); if (isWrapperAroundRelationshipList || !this.model.repeatable) { @@ -366,10 +374,68 @@ 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))); } + /** + * Open a modal where the user can select relationships to be added to item being submitted + */ + openLookup() { + this.modalRef = this.modalService.open(DsDynamicLookupRelationModalComponent, { + size: 'lg' + }); + + if (hasValue(this.model.value)) { + this.focus.emit({ + $event: new Event('focus'), + context: this.context, + control: this.control, + model: this.model, + type: DynamicFormControlEventType.Focus + } as DynamicFormControlEvent); + + this.model.value = null; + this.change.emit({ + $event: new Event('change'), + context: this.context, + control: this.control, + model: this.model, + type: DynamicFormControlEventType.Change + } as DynamicFormControlEvent); + + this.submissionService.dispatchSave(this.model.submissionId); + } + + const modalComp = this.modalRef.componentInstance; + + if (hasValue(this.model.value) && !this.model.readOnly) { + if (typeof this.model.value === 'string') { + modalComp.query = this.model.value; + } else if (typeof this.model.value.value === 'string') { + modalComp.query = this.model.value.value; + } + } + + modalComp.repeatable = this.model.repeatable; + modalComp.listId = this.listId; + modalComp.relationshipOptions = this.model.relationship; + modalComp.label = this.model.relationship.relationshipType; + modalComp.metadataFields = this.model.metadataFields; + modalComp.item = this.item; + modalComp.collection = this.collection; + modalComp.submissionId = this.model.submissionId; + } + /** * Callback for the remove event, * remove the current control from its array diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.ts index c7474cb769..4ed972b2fa 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.ts @@ -147,7 +147,6 @@ export class DsDynamicLookupRelationModalComponent implements OnInit, OnDestroy ngOnInit(): void { this.setItem(); - this.submissionService.dispatchSave(this.submissionId); this.selection$ = this.selectableListService .getSelectableList(this.listId) .pipe(map((listState: SelectableListState) => hasValue(listState) && hasValue(listState.selection) ? listState.selection : [])); diff --git a/src/app/shared/form/form.component.html b/src/app/shared/form/form.component.html index 8f5c18a6cf..7f6efc5b9f 100644 --- a/src/app/shared/form/form.component.html +++ b/src/app/shared/form/form.component.html @@ -14,14 +14,12 @@
-
-
@@ -31,13 +29,6 @@ (click)="insertItem($event, group.context, group.context.groups.length)"> {{'form.add' | translate}} -
@@ -54,6 +45,7 @@ + diff --git a/src/app/shared/form/form.component.ts b/src/app/shared/form/form.component.ts index bd742dc9c6..c2b690504a 100644 --- a/src/app/shared/form/form.component.ts +++ b/src/app/shared/form/form.component.ts @@ -10,15 +10,13 @@ import { DynamicFormGroupModel, DynamicFormLayout, } from '@ng-dynamic-forms/core'; -import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { findIndex } from 'lodash'; import { FormBuilderService } from './builder/form-builder.service'; import { hasValue, isNotEmpty, isNotNull, isNull } from '../empty.util'; import { FormService } from './form.service'; import { FormEntry, FormError } from './form.reducer'; -import { DsDynamicLookupRelationModalComponent } from './builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component'; -import { RelationshipOptions } from './builder/models/relationship-options.model'; import { FormFieldMetadataValueObject } from './builder/models/form-field-metadata-value.model'; /** @@ -101,8 +99,7 @@ export class FormComponent implements OnDestroy, OnInit { constructor(private formService: FormService, protected changeDetectorRef: ChangeDetectorRef, - private formBuilderService: FormBuilderService, - private modalService: NgbModal) { + private formBuilderService: FormBuilderService) { } /** @@ -169,7 +166,6 @@ export class FormComponent implements OnDestroy, OnInit { filter((formState: FormEntry) => !!formState && (isNotEmpty(formState.errors) || isNotEmpty(this.formErrors))), map((formState) => formState.errors), distinctUntilChanged()) - // .delay(100) // this terrible delay is here to prevent the detection change error .subscribe((errors: FormError[]) => { const { formGroup, formModel } = this; errors @@ -320,42 +316,6 @@ export class FormComponent implements OnDestroy, OnInit { return isNotEmpty(value) && value.isVirtual; } - hasRelationship(arrayContext: DynamicFormArrayModel, index: number) { - const context = arrayContext.groups[index]; - const model = context.group[0] as any; - return isNotEmpty(model) && model.hasOwnProperty('relationship') && isNotEmpty(model.relationship); - } - - /** - * Open a modal where the user can select relationships to be added to item being submitted - */ - openLookup(arrayContext: DynamicFormArrayModel, index: number) { - const context = arrayContext.groups[index]; - const model = context.group[0] as any; - this.modalRef = this.modalService.open(DsDynamicLookupRelationModalComponent, { - size: 'lg' - }); - const modalComp = this.modalRef.componentInstance; - - if (hasValue(model.value) && !model.readOnly) { - if (typeof model.value === 'string') { - modalComp.query = model.value; - } else if (typeof model.value.value === 'string') { - modalComp.query = model.value.value; - } - } - - const config = model.relationshipConfig || model.relationship; - const relationshipOptions = Object.assign(new RelationshipOptions(), config); - - modalComp.repeatable = model.repeatable; - modalComp.listId = `list-${model.submissionId}-${relationshipOptions.relationshipType}`; - modalComp.relationshipOptions = model.relationship; - modalComp.label = model.relationship.relationshipType; - modalComp.metadataFields = model.metadataFields; - modalComp.submissionId = model.submissionId; - } - protected getEvent($event: any, arrayContext: DynamicFormArrayModel, index: number, type: string): DynamicFormControlEvent { const context = arrayContext.groups[index]; const itemGroupModel = context.context; From a66ec43cccaa63bd8f5b21e244f5c56923828a59 Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Thu, 25 Feb 2021 19:07:51 +0100 Subject: [PATCH 10/21] [CST-3782] Disabled drag when only one value is present --- .../models/array-group/dynamic-form-array.component.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 732b5978ac..1c14c0b994 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 @@ -10,7 +10,9 @@ role="group" [formGroupName]="idx" [ngClass]="[getClass('element', 'group'), getClass('grid', 'group')]" - cdkDrag cdkDragHandle> + cdkDrag + cdkDragHandle + [cdkDragDisabled]="model.groups.length === 1">
From 5eb0a8744f4f85a1040ebdac9232cda498f2a2ff Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Thu, 4 Mar 2021 11:49:28 +0100 Subject: [PATCH 11/21] [CSTPER-3782] custom move events handled correctly --- .../dynamic-form-array.component.ts | 15 ++---- src/app/shared/form/form.component.html | 3 +- src/app/shared/form/form.component.ts | 5 ++ .../form/section-form-operations.service.ts | 46 +++++++++++++++---- .../sections/form/section-form.component.html | 1 + .../sections/form/section-form.component.ts | 13 ++++++ 6 files changed, 62 insertions(+), 21 deletions(-) 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 b6c1a6c308..42a02fee45 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 @@ -6,7 +6,6 @@ import { DynamicFormArrayModel, DynamicFormControlCustomEvent, DynamicFormControlEvent, - DynamicFormControlEventType, DynamicFormControlLayout, DynamicFormLayout, DynamicFormLayoutService, @@ -55,16 +54,12 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent { 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, model: this.model.groups[index].group[0], - type: DynamicFormControlEventType.Change - }; - - this.onChange($event); + control: (this.control as any).controls[index] + }, 'move'); } } diff --git a/src/app/shared/form/form.component.html b/src/app/shared/form/form.component.html index 7f6efc5b9f..10ec8da3b9 100644 --- a/src/app/shared/form/form.component.html +++ b/src/app/shared/form/form.component.html @@ -9,7 +9,8 @@ (change)="$event.stopPropagation();" (dfBlur)="onBlur($event)" (dfChange)="onChange($event)" - (dfFocus)="onFocus($event)"> + (dfFocus)="onFocus($event)" + (ngbEvent)="onCustomEvent($event)">
= 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 */ @Output() addArrayItem: EventEmitter = new EventEmitter(); @Output() removeArrayItem: EventEmitter = new EventEmitter(); @@ -250,6 +251,10 @@ export class FormComponent implements OnDestroy, OnInit { this.blur.emit(event); } + onCustomEvent(event: any) { + this.customEvent.emit(event); + } + onFocus(event: DynamicFormControlEvent): void { this.formService.setTouched(this.formId, this.formModel, event); this.focus.emit(event); diff --git a/src/app/submission/sections/form/section-form-operations.service.ts b/src/app/submission/sections/form/section-form-operations.service.ts index 27e4f73876..136203329f 100644 --- a/src/app/submission/sections/form/section-form-operations.service.ts +++ b/src/app/submission/sections/form/section-form-operations.service.ts @@ -6,7 +6,7 @@ import { DYNAMIC_FORM_CONTROL_TYPE_GROUP, DynamicFormArrayGroupModel, DynamicFormControlEvent, - DynamicFormControlModel + DynamicFormControlModel, isDynamicFormControlEvent } from '@ng-dynamic-forms/core'; import { hasValue, isNotEmpty, isNotNull, isNotUndefined, isNull, isUndefined } from '../../../shared/empty.util'; @@ -64,6 +64,9 @@ export class SectionFormOperationsService { case 'change': this.dispatchOperationsFromChangeEvent(pathCombiner, event, previousValue, hasStoredValue); break; + case 'move': + this.dispatchOperationsFromMoveEvent(pathCombiner, event); + break; default: break; } @@ -73,20 +76,29 @@ export class SectionFormOperationsService { * Return index if specified field is part of fields array * * @param event - * the [[DynamicFormControlEvent]] for the specified operation + * the [[DynamicFormControlEvent]] | CustomEvent for the specified operation * @return number * the array index is part of array, zero otherwise */ - public getArrayIndexFromEvent(event: DynamicFormControlEvent): number { + public getArrayIndexFromEvent(event: DynamicFormControlEvent | any): number { let fieldIndex: number; + if (isNotEmpty(event)) { - if (isNull(event.context)) { - // Check whether model is part of an Array of group - if (this.isPartOfArrayOfGroup(event.model)) { - fieldIndex = (event.model.parent as any).parent.index; + if (isDynamicFormControlEvent(event)) { + // This is the case of a default insertItem/removeItem event + + if (isNull(event.context)) { + // Check whether model is part of an Array of group + if (this.isPartOfArrayOfGroup(event.model)) { + fieldIndex = (event.model.parent as any).parent.index; + } + } else { + fieldIndex = event.context.index; } + } else { - fieldIndex = event.context.index; + // This is the case of a custom event which contains indexes information + fieldIndex = event.index as any; } } @@ -394,8 +406,7 @@ export class SectionFormOperationsService { previousValue.delete(); } else if (value.hasValue()) { // Here model has no previous value but a new one - if (isUndefined(this.getArrayIndexFromEvent(event)) - || this.getArrayIndexFromEvent(event) === 0) { + if (isUndefined(this.getArrayIndexFromEvent(event)) || this.getArrayIndexFromEvent(event) === 0) { // Model is single field or is part of an array model but is the first item, // so dispatch an add operation that initialize the values of a specific metadata this.operationsBuilder.add( @@ -457,4 +468,19 @@ export class SectionFormOperationsService { previousValue.delete(); } + + private dispatchOperationsFromMoveEvent(pathCombiner: JsonPatchOperationPathCombiner, + event: DynamicFormControlEvent) { + const customEvent = event.$event; + const path = this.getFieldPathFromEvent(customEvent); + const segmentedPath = this.getFieldPathSegmentedFromChangeEvent(customEvent); + const moveTo = pathCombiner.getPath(path); + const moveFrom = pathCombiner.getPath(segmentedPath + '/' + customEvent.previousIndex); + if (isNotEmpty(moveFrom.path) && isNotEmpty(moveTo.path) && moveFrom.path !== moveTo.path) { + this.operationsBuilder.move( + moveTo, + moveFrom.path + ); + } + } } diff --git a/src/app/submission/sections/form/section-form.component.html b/src/app/submission/sections/form/section-form.component.html index 166e52675b..64e8a05d80 100644 --- a/src/app/submission/sections/form/section-form.component.html +++ b/src/app/submission/sections/form/section-form.component.html @@ -6,4 +6,5 @@ (dfChange)="onChange($event)" (dfFocus)="onFocus($event)" (remove)="onRemove($event)" + (ngbEvent)="onCustomEvent($event)" (removeArrayItem)="onRemove($event)"> diff --git a/src/app/submission/sections/form/section-form.component.ts b/src/app/submission/sections/form/section-form.component.ts index bc88323a8c..2d1b0ed764 100644 --- a/src/app/submission/sections/form/section-form.component.ts +++ b/src/app/submission/sections/form/section-form.component.ts @@ -448,4 +448,17 @@ export class SubmissionSectionformComponent extends SectionModelComponent { isFieldToRemove(fieldId, index) { return this.fieldsOnTheirWayToBeRemoved.has(fieldId) && this.fieldsOnTheirWayToBeRemoved.get(fieldId).includes(index); } + + /** + * Handle the customEvent (ex. drag-drop move event). + * The customEvent is stored inside event.$event + * @param $event + */ + onCustomEvent(event: any) { + this.formOperationsService.dispatchOperationsFromEvent( + this.pathCombiner, + event, + null, + null); + } } From 5201b4a31d09b9ff2e1f0d449afe021551e06564 Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Thu, 4 Mar 2021 18:25:01 +0100 Subject: [PATCH 12/21] [CST-3782] qualdrop move restored --- .../form/section-form-operations.service.ts | 23 +++++++++++++++++-- .../sections/form/section-form.component.ts | 6 ++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/app/submission/sections/form/section-form-operations.service.ts b/src/app/submission/sections/form/section-form-operations.service.ts index 136203329f..be0e397ddb 100644 --- a/src/app/submission/sections/form/section-form-operations.service.ts +++ b/src/app/submission/sections/form/section-form-operations.service.ts @@ -65,7 +65,7 @@ export class SectionFormOperationsService { this.dispatchOperationsFromChangeEvent(pathCombiner, event, previousValue, hasStoredValue); break; case 'move': - this.dispatchOperationsFromMoveEvent(pathCombiner, event); + this.dispatchOperationsFromMoveEvent(pathCombiner, event, previousValue); break; default: break; @@ -469,9 +469,28 @@ export class SectionFormOperationsService { previousValue.delete(); } + /** + * Handle form move operations + * + * @param pathCombiner + * the [[JsonPatchOperationPathCombiner]] object for the specified operation + * @param event + * the [[DynamicFormControlEvent]] for the specified operation + * @param previousValue + * the [[FormFieldPreviousValueObject]] for the specified operation + */ private dispatchOperationsFromMoveEvent(pathCombiner: JsonPatchOperationPathCombiner, - event: DynamicFormControlEvent) { + event: DynamicFormControlEvent, + previousValue: FormFieldPreviousValueObject) { + const customEvent = event.$event; + + if (this.formBuilder.isQualdropGroup(customEvent.model.parent as DynamicFormControlModel) + || this.formBuilder.isQualdropGroup(customEvent.model as DynamicFormControlModel)) { + // It's a qualdrup model + this.dispatchOperationsFromMap(this.getQualdropValueMap(customEvent), pathCombiner, customEvent, previousValue); + return; + } const path = this.getFieldPathFromEvent(customEvent); const segmentedPath = this.getFieldPathSegmentedFromChangeEvent(customEvent); const moveTo = pathCombiner.getPath(path); diff --git a/src/app/submission/sections/form/section-form.component.ts b/src/app/submission/sections/form/section-form.component.ts index 2d1b0ed764..99a2e12b47 100644 --- a/src/app/submission/sections/form/section-form.component.ts +++ b/src/app/submission/sections/form/section-form.component.ts @@ -19,7 +19,7 @@ import { FormComponent } from '../../../shared/form/form.component'; import { FormService } from '../../../shared/form/form.service'; import { SectionModelComponent } from '../models/section.model'; import { SubmissionFormsConfigService } from '../../../core/config/submission-forms-config.service'; -import { hasNoValue, hasValue, isNotEmpty, isUndefined } from '../../../shared/empty.util'; +import { hasValue, isNotEmpty, isUndefined } from '../../../shared/empty.util'; import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner'; import { SubmissionFormsModel } from '../../../core/config/models/config-submission-forms.model'; import { SubmissionSectionError, SubmissionSectionObject } from '../../objects/submission-objects.reducer'; @@ -454,11 +454,11 @@ export class SubmissionSectionformComponent extends SectionModelComponent { * The customEvent is stored inside event.$event * @param $event */ - onCustomEvent(event: any) { + onCustomEvent(event: DynamicFormControlEvent) { this.formOperationsService.dispatchOperationsFromEvent( this.pathCombiner, event, - null, + this.previousValue, null); } } From 28894f67647bf803ce613bd638c1c3f11168f257 Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Wed, 10 Mar 2021 11:24:42 +0100 Subject: [PATCH 13/21] [CST-3782] lookup search icon --- .../ds-dynamic-form-control-container.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8ba6489068..eb7b5b720f 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 @@ -40,7 +40,7 @@ type="button" ngbTooltip="{{'form.lookup-help' | translate}}" placement="top" - (click)="openLookup(); $event.stopPropagation();">{{'form.lookup' | translate}} + (click)="openLookup(); $event.stopPropagation();">
From 996d54f37e858d01ca06fffb66f271bf9145d399 Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Wed, 10 Mar 2021 17:11:53 +0100 Subject: [PATCH 14/21] [CST-3782] item deletion on lookup disabled --- ...ynamic-form-control-container.component.ts | 21 ------------------- 1 file changed, 21 deletions(-) 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 5ab4a7b247..4fbc29f79d 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 @@ -395,27 +395,6 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo size: 'lg' }); - if (hasValue(this.model.value)) { - this.focus.emit({ - $event: new Event('focus'), - context: this.context, - control: this.control, - model: this.model, - type: DynamicFormControlEventType.Focus - } as DynamicFormControlEvent); - - this.model.value = null; - this.change.emit({ - $event: new Event('change'), - context: this.context, - control: this.control, - model: this.model, - type: DynamicFormControlEventType.Change - } as DynamicFormControlEvent); - - this.submissionService.dispatchSave(this.model.submissionId); - } - const modalComp = this.modalRef.componentInstance; if (hasValue(this.model.value) && !this.model.readOnly) { From d224333a1c014ae4d552d2c156db1322356ead6b Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Wed, 31 Mar 2021 11:47:10 +0200 Subject: [PATCH 15/21] [CST-3782] added hint to the last entity value --- .../ds-dynamic-form-control-container.component.html | 2 ++ 1 file changed, 2 insertions(+) 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 eb7b5b720f..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 @@ -68,6 +68,8 @@ [relationshipOptions]="model.relationship" > +
From d47660b5c29d2ee693c32dba271cde688ad61eb3 Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Wed, 31 Mar 2021 11:56:37 +0200 Subject: [PATCH 16/21] [CST-3782] possibility to configure the isDraggable feature to DynamicRowArrayModel --- .../array-group/dynamic-form-array.component.html | 4 ++-- .../models/array-group/dynamic-form-array.component.ts | 10 +++++++++- .../models/ds-dynamic-row-array-model.ts | 3 +++ .../shared/form/builder/form-builder.service.spec.ts | 1 + src/app/shared/form/builder/parsers/field-parser.ts | 6 ++++++ src/app/shared/mocks/form-models.mock.ts | 1 + 6 files changed, 22 insertions(+), 3 deletions(-) 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 1c14c0b994..09b1331f8b 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 @@ -12,7 +12,7 @@ [ngClass]="[getClass('element', 'group'), getClass('grid', 'group')]" cdkDrag cdkDragHandle - [cdkDragDisabled]="model.groups.length === 1"> + [cdkDragDisabled]="dragDisabled">
@@ -20,7 +20,7 @@
- + | undefined; /* tslint:disable:no-output-rename */ @@ -70,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/form-builder.service.spec.ts b/src/app/shared/form/builder/form-builder.service.spec.ts index b81bb3285b..cea4d7df6e 100644 --- a/src/app/shared/form/builder/form-builder.service.spec.ts +++ b/src/app/shared/form/builder/form-builder.service.spec.ts @@ -295,6 +295,7 @@ describe('FormBuilderService test suite', () => { notRepeatable: false, relationshipConfig: undefined, submissionId: '1234', + isDraggable: true, groupFactory: () => { return [ new DynamicInputModel({ id: 'testFormRowArrayGroupInput' }) diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts index 93f941e344..da304ca267 100644 --- a/src/app/shared/form/builder/parsers/field-parser.ts +++ b/src/app/shared/form/builder/parsers/field-parser.ts @@ -50,6 +50,11 @@ export abstract class FieldParser { if (Array.isArray(this.configData.selectableMetadata) && this.configData.selectableMetadata.length === 1) { metadataKey = this.configData.selectableMetadata[0].metadata; } + + let isDraggable = true; + if (this.configData.input.type === ParserType.Onebox && this.configData?.selectableMetadata?.length > 1) { + isDraggable = false; + } const config = { id: uniqueId() + '_array', label: this.configData.label, @@ -61,6 +66,7 @@ export abstract class FieldParser { metadataKey, metadataFields: this.getAllFieldIds(), hasSelectableMetadata: isNotEmpty(this.configData.selectableMetadata), + isDraggable, groupFactory: () => { let model; if ((arrayCounter === 0)) { diff --git a/src/app/shared/mocks/form-models.mock.ts b/src/app/shared/mocks/form-models.mock.ts index 739de944f0..c43138fa25 100644 --- a/src/app/shared/mocks/form-models.mock.ts +++ b/src/app/shared/mocks/form-models.mock.ts @@ -80,6 +80,7 @@ const rowArrayQualdropConfig = { id: 'row_QUALDROP_GROUP', initialCount: 1, notRepeatable: true, + isDraggable: false, relationshipConfig: undefined, groupFactory: () => { return [MockQualdropModel]; From 8c60bd42802aafda2b939f5dc19007bd17e8342d Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Wed, 31 Mar 2021 11:59:01 +0200 Subject: [PATCH 17/21] [CST-3782] restored submission save after openLookup --- .../ds-dynamic-form-control-container.component.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 4fbc29f79d..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, @@ -395,6 +394,10 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo 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) { From 052dbdaf1e09b1853169a93d5984ce277120670e Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Wed, 31 Mar 2021 12:10:57 +0200 Subject: [PATCH 18/21] [CST-3782] patch add full array in case of DynamicRowArrayModel --- .../dynamic-form-array.component.ts | 2 +- .../form/builder/form-builder.service.ts | 6 +++ .../form/section-form-operations.service.ts | 42 +++++++++++-------- 3 files changed, 32 insertions(+), 18 deletions(-) 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 d349d553a2..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 @@ -3,7 +3,6 @@ import { Component, EventEmitter, Input, Output, QueryList } from '@angular/core import { FormGroup } from '@angular/forms'; import { DynamicFormArrayComponent, - DynamicFormArrayModel, DynamicFormControlCustomEvent, DynamicFormControlEvent, DynamicFormControlLayout, @@ -58,6 +57,7 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent { this.onCustomEvent({ previousIndex: prevIndex, index, + arrayModel: this.model, model: this.model.groups[index].group[0], control: (this.control as any).controls[index] }, 'move'); diff --git a/src/app/shared/form/builder/form-builder.service.ts b/src/app/shared/form/builder/form-builder.service.ts index a7979bde94..85d70f20dc 100644 --- a/src/app/shared/form/builder/form-builder.service.ts +++ b/src/app/shared/form/builder/form-builder.service.ts @@ -31,6 +31,7 @@ import { FormFieldMetadataValueObject } from './models/form-field-metadata-value import { dateToString, isNgbDateStruct } from '../../date.util'; import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from './ds-dynamic-form-ui/ds-dynamic-form-constants'; import { CONCAT_GROUP_SUFFIX, DynamicConcatModel } from './ds-dynamic-form-ui/models/ds-dynamic-concat.model'; +import { VIRTUAL_METADATA_PREFIX } from '../../../core/shared/metadata.models'; @Injectable() export class FormBuilderService extends DynamicFormService { @@ -121,6 +122,11 @@ export class FormBuilderService extends DynamicFormService { const normalizeValue = (controlModel, controlValue, controlModelIndex) => { const controlLanguage = (controlModel as DsDynamicInputModel).hasLanguages ? (controlModel as DsDynamicInputModel).language : null; + + if (controlModel?.metadataValue?.authority?.includes(VIRTUAL_METADATA_PREFIX)) { + return controlModel.metadataValue; + } + if (isString(controlValue)) { return new FormFieldMetadataValueObject(controlValue, controlLanguage, null, null, controlModelIndex); } else if (isNgbDateStruct(controlValue)) { diff --git a/src/app/submission/sections/form/section-form-operations.service.ts b/src/app/submission/sections/form/section-form-operations.service.ts index be0e397ddb..57ac7e1d7e 100644 --- a/src/app/submission/sections/form/section-form-operations.service.ts +++ b/src/app/submission/sections/form/section-form-operations.service.ts @@ -23,6 +23,7 @@ import { DynamicRelationGroupModel } from '../../../shared/form/builder/ds-dynam import { VocabularyEntryDetail } from '../../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; import { deepClone } from 'fast-json-patch'; import { dateToString, isNgbDateStruct } from '../../../shared/date.util'; +import { DynamicRowArrayModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-array-model'; /** * The service handling all form section operations @@ -357,6 +358,13 @@ export class SectionFormOperationsService { event: DynamicFormControlEvent, previousValue: FormFieldPreviousValueObject, hasStoredValue: boolean): void { + + if (event.context && event.context instanceof DynamicFormArrayGroupModel) { + // Model is a DynamicRowArrayModel + this.handleArrayGroupPatch(pathCombiner, event, (event as any).context.context); + return; + } + const path = this.getFieldPathFromEvent(event); const segmentedPath = this.getFieldPathSegmentedFromChangeEvent(event); const value = this.getFieldValueFromChangeEvent(event); @@ -483,23 +491,23 @@ export class SectionFormOperationsService { event: DynamicFormControlEvent, previousValue: FormFieldPreviousValueObject) { - const customEvent = event.$event; + return this.handleArrayGroupPatch(pathCombiner, event.$event, (event as any).$event.arrayModel); + } - if (this.formBuilder.isQualdropGroup(customEvent.model.parent as DynamicFormControlModel) - || this.formBuilder.isQualdropGroup(customEvent.model as DynamicFormControlModel)) { - // It's a qualdrup model - this.dispatchOperationsFromMap(this.getQualdropValueMap(customEvent), pathCombiner, customEvent, previousValue); - return; - } - const path = this.getFieldPathFromEvent(customEvent); - const segmentedPath = this.getFieldPathSegmentedFromChangeEvent(customEvent); - const moveTo = pathCombiner.getPath(path); - const moveFrom = pathCombiner.getPath(segmentedPath + '/' + customEvent.previousIndex); - if (isNotEmpty(moveFrom.path) && isNotEmpty(moveTo.path) && moveFrom.path !== moveTo.path) { - this.operationsBuilder.move( - moveTo, - moveFrom.path - ); - } + /** + * Specific patch handler for a DynamicRowArrayModel. + * Configure a Patch ADD with the current array value. + * @param pathCombiner + * @param event + * @param model + */ + private handleArrayGroupPatch(pathCombiner: JsonPatchOperationPathCombiner, + event, + model: DynamicRowArrayModel) { + const arrayValue = this.formBuilder.getValueFromModel([model]); + const segmentedPath2 = this.getFieldPathSegmentedFromChangeEvent(event); + this.operationsBuilder.add( + pathCombiner.getPath(segmentedPath2), + arrayValue[segmentedPath2], false); } } From f9e80ea2886eba71f0c3553945361153bfeeaa07 Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Wed, 31 Mar 2021 12:27:39 +0200 Subject: [PATCH 19/21] [CST-3782] restored correct drag styles after merge --- .../dynamic-form-array.component.scss | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) 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 36e5fc2131..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,42 +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)); - cursor: grab; - } + 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 { - margin: 0px; - padding: 0px; + margin: 0; + padding: 0; } .cdk-drag-placeholder { - opacity: 0; + opacity: 0; } From 08afa4723b2c28ac9a9d3daeb217d234e2f64aab Mon Sep 17 00:00:00 2001 From: Alessandro Martelli Date: Wed, 31 Mar 2021 14:20:44 +0200 Subject: [PATCH 20/21] [CST-3782] patch add entire array on item remove --- src/app/shared/form/form.component.ts | 3 ++- .../sections/form/section-form-operations.service.ts | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/app/shared/form/form.component.ts b/src/app/shared/form/form.component.ts index 39cc3bdafb..8d7a87c03c 100644 --- a/src/app/shared/form/form.component.ts +++ b/src/app/shared/form/form.component.ts @@ -303,9 +303,10 @@ export class FormComponent implements OnDestroy, OnInit { removeItem($event, arrayContext: DynamicFormArrayModel, index: number): void { const formArrayControl = this.formGroup.get(this.formBuilderService.getPath(arrayContext)) as FormArray; - this.removeArrayItem.emit(this.getEvent($event, arrayContext, index, 'remove')); + const event = this.getEvent($event, arrayContext, index, 'remove'); this.formBuilderService.removeFormArrayGroup(index, formArrayControl, arrayContext); this.formService.changeForm(this.formId, this.formModel); + this.removeArrayItem.emit(event); } insertItem($event, arrayContext: DynamicFormArrayModel, index: number): void { diff --git a/src/app/submission/sections/form/section-form-operations.service.ts b/src/app/submission/sections/form/section-form-operations.service.ts index 57ac7e1d7e..a1bb99e3cd 100644 --- a/src/app/submission/sections/form/section-form-operations.service.ts +++ b/src/app/submission/sections/form/section-form-operations.service.ts @@ -296,6 +296,13 @@ export class SectionFormOperationsService { protected dispatchOperationsFromRemoveEvent(pathCombiner: JsonPatchOperationPathCombiner, event: DynamicFormControlEvent, previousValue: FormFieldPreviousValueObject): void { + + if (event.context && event.context instanceof DynamicFormArrayGroupModel) { + // Model is a DynamicRowArrayModel + this.handleArrayGroupPatch(pathCombiner, event, (event as any).context.context); + return; + } + const path = this.getFieldPathFromEvent(event); const value = this.getFieldValueFromChangeEvent(event); console.log(value); From 94c0af5d861b7ca131aa724552709467b64355fc Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Thu, 1 Apr 2021 20:03:54 +0200 Subject: [PATCH 21/21] [CST-3620] Remove drag and drop placeholder --- .../models/array-group/dynamic-form-array.component.html | 9 ++------- src/styles/_global-styles.scss | 7 +++++++ 2 files changed, 9 insertions(+), 7 deletions(-) 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 09b1331f8b..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 @@ -12,14 +12,9 @@ [ngClass]="[getClass('element', 'group'), getClass('grid', 'group')]" cdkDrag cdkDragHandle - [cdkDragDisabled]="dragDisabled"> + [cdkDragDisabled]="dragDisabled" + [cdkDragPreviewClass]="'ds-submission-reorder-dragging'"> -
-
- {{ 'form.repeatable.sort.tip' | translate }} -
-
-