From 19bd36a80f02e3d2684f92a3788a83c79087d215 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Fri, 17 Apr 2020 11:24:10 +0200 Subject: [PATCH] switch to patch for reorderin --- ...xisting-metadata-list-element.component.ts | 29 +-- .../dynamic-form-array.component.html | 4 +- .../dynamic-form-array.component.ts | 217 ++---------------- .../form/section-form-operations.service.ts | 16 +- 4 files changed, 38 insertions(+), 228 deletions(-) diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.ts index e29dc4e3f1..8490d983c4 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.ts @@ -48,7 +48,9 @@ export abstract class Reorderable { /** * Update the Reorderable */ - abstract update(): Observable; + update(): void { + this.oldIndex = this.newIndex; + } /** * Returns true if the oldIndex of this Reorderable @@ -95,14 +97,6 @@ export class ReorderableFormFieldMetadataValue extends Reorderable { return this.metadataValue.place; } - /** - * Update the Reorderable - */ - update(): Observable { - this.oldIndex = this.newIndex; - return observableOf(this.metadataValue); - } - } /** @@ -140,23 +134,6 @@ export class ReorderableRelationship extends Reorderable { return this.relationship.leftPlace } } - - /** - * Update the Reorderable - */ - update(): Observable> { - this.store.dispatch(new UpdateRelationshipAction(this.relationship, this.submissionID)) - const updatedRelationship$ = this.relationshipService.updatePlace(this).pipe( - getSucceededRemoteData(), - ); - - updatedRelationship$.subscribe(() => { - this.oldIndex = this.newIndex; - - }); - - return updatedRelationship$; - } } /** 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 bc411cbd15..6c8537e77f 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 @@ -35,8 +35,8 @@ [model]="_model" [templates]="templates" [ngClass]="[getClass('element', 'host', _model), getClass('grid', 'host', _model)]" - (dfBlur)="update(idx)" - (dfChange)="update(idx)" + (dfBlur)="update($event, idx)" + (dfChange)="update($event, idx)" (dfFocus)="onFocus($event)" (ngbEvent)="onCustomEvent($event, null, true)"> 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 c4ee3a0b79..f43b1cb9cb 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 @@ -1,60 +1,25 @@ import { CdkDragDrop } from '@angular/cdk/drag-drop'; -import { - ChangeDetectorRef, - Component, - EventEmitter, - Input, - NgZone, - OnInit, - Output, - QueryList -} from '@angular/core'; -import { AbstractControl, FormControl, FormGroup } from '@angular/forms'; +import { Component, EventEmitter, Input, Output, QueryList } from '@angular/core'; +import { FormGroup } from '@angular/forms'; import { DynamicFormArrayComponent, - DynamicFormArrayGroupModel, DynamicFormControlCustomEvent, - DynamicFormControlEvent, DynamicFormControlEventType, + DynamicFormControlEvent, + DynamicFormControlEventType, DynamicFormLayout, DynamicFormLayoutService, - DynamicFormService, DynamicFormValidationService, DynamicTemplateDirective } from '@ng-dynamic-forms/core'; -import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; -import { map, switchMap, take, tap, filter } from 'rxjs/operators'; -import { RelationshipService } from '../../../../../../core/data/relationship.service'; -import { RemoteData } from '../../../../../../core/data/remote-data'; import { Relationship } from '../../../../../../core/shared/item-relationships/relationship.model'; -import { Item } from '../../../../../../core/shared/item.model'; -import { MetadataValue } from '../../../../../../core/shared/metadata.models'; -import { - getRemoteDataPayload, - getSucceededRemoteData -} from '../../../../../../core/shared/operators'; -import { SubmissionObject } from '../../../../../../core/submission/models/submission-object.model'; -import { SubmissionObjectDataService } from '../../../../../../core/submission/submission-object-data.service'; -import { hasValue, isNotEmpty } from '../../../../../empty.util'; -import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; -import { - Reorderable, - ReorderableFormFieldMetadataValue, - ReorderableRelationship -} from '../../existing-metadata-list-element/existing-metadata-list-element.component'; -import { DynamicConcatModel } from '../ds-dynamic-concat.model'; import { DynamicRowArrayModel } from '../ds-dynamic-row-array-model'; -import { Store } from '@ngrx/store'; -import { SubmissionService } from '../../../../../../submission/submission.service'; -import { AppState } from '../../../../../../app.reducer'; -import { followLink } from '../../../../../utils/follow-link-config.model'; -import { ObjectCacheService } from '../../../../../../core/cache/object-cache.service'; @Component({ selector: 'ds-dynamic-form-array', templateUrl: './dynamic-form-array.component.html', styleUrls: ['./dynamic-form-array.component.scss'] }) -export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent implements OnInit { +export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent { @Input() bindId = true; @Input() group: FormGroup; @@ -68,169 +33,37 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent imple @Output('dfFocus') focus: EventEmitter = new EventEmitter(); @Output('ngbEvent') customEvent: EventEmitter = new EventEmitter(); - private submissionItem: Item; - private reorderables: Reorderable[] = []; - /* tslint:enable:no-output-rename */ constructor(protected layoutService: DynamicFormLayoutService, protected validationService: DynamicFormValidationService, - protected objectCacheService: ObjectCacheService, - protected relationshipService: RelationshipService, - protected changeDetectorRef: ChangeDetectorRef, - protected submissionObjectService: SubmissionObjectDataService, - protected zone: NgZone, - protected formService: DynamicFormService, - private submissionService: SubmissionService, - private store: Store, ) { super(layoutService, validationService); } - ngOnInit(): void { - this.submissionObjectService - .findById(this.model.submissionId, followLink('item')).pipe( - getSucceededRemoteData(), - getRemoteDataPayload(), - switchMap((submissionObject: SubmissionObject) => (submissionObject.item as Observable>) - .pipe( - getSucceededRemoteData(), - getRemoteDataPayload() - ) - ) - ).subscribe((item) => { - this.submissionItem = item; - this.updateReorderables(false); - }); - - } - - private updateReorderables(shouldPropagateChanges = true): void { - this.zone.runOutsideAngular(() => { - let groups = this.model.groups.map((group, index) => [group, (this.control as any).controls[index]]); - groups = [...groups, groups[0]]; - const reorderable$arr: Array> = groups - .filter(([group, control], index) => index > 0 && hasValue((group.group[0] as any).value)) // disregard the first group, it is always empty to ensure the first field remains empty - .map(([group, control]: [DynamicFormArrayGroupModel, AbstractControl], index: number) => { - const model = group.group[0] as DynamicConcatModel; - let formFieldMetadataValue: FormFieldMetadataValueObject = model.value as FormFieldMetadataValueObject; - if (hasValue(formFieldMetadataValue)) { - const metadataValue = Object.assign(new MetadataValue(), { - value: formFieldMetadataValue.display, - language: formFieldMetadataValue.language, - place: formFieldMetadataValue.place, - authority: formFieldMetadataValue.authority, - confidence: formFieldMetadataValue.confidence - }); - if (metadataValue.isVirtual) { - return this.relationshipService.findById(metadataValue.virtualValue, followLink('leftItem')) - .pipe( - filter((relRD: RemoteData) => hasValue(relRD.payload)), - take(1), - getRemoteDataPayload(), - switchMap((relationship: Relationship) => - relationship.leftItem.pipe( - filter((itemRD: RemoteData) => hasValue(itemRD.payload)), - take(1), - getRemoteDataPayload(), - map((leftItem: Item) => { - return new ReorderableRelationship( - relationship, - leftItem.uuid !== this.submissionItem.uuid, - this.relationshipService, - this.store, - this.model.submissionId, - index, - index - ); - }), - ) - ) - ); - } else { - if (typeof formFieldMetadataValue === 'string') { - formFieldMetadataValue = Object.assign(new FormFieldMetadataValueObject(), { - value: formFieldMetadataValue, - display: formFieldMetadataValue, - place: index, - }); - } - return observableOf(new ReorderableFormFieldMetadataValue(formFieldMetadataValue, model as any, control as FormControl, group, index, index)); - } - } else { - formFieldMetadataValue = Object.assign(new FormFieldMetadataValueObject(), { - value: '', - display: '', - place: index, - }); - return observableOf(new ReorderableFormFieldMetadataValue(formFieldMetadataValue, model as any, control as FormControl, group, index, index)); - } - }); - - observableCombineLatest(reorderable$arr) - .subscribe((reorderables: Reorderable[]) => { - reorderables.forEach((newReorderable: Reorderable) => { - const match = this.reorderables.find((reo: Reorderable) => reo.getId() === newReorderable.getId()); - if (hasValue(match)) { - newReorderable.oldIndex = match.newIndex; - } else { - newReorderable.oldIndex = -1; - } - }); - - this.reorderables = reorderables; - - if (shouldPropagateChanges) { - const movedReoRels: Array = []; - let hasMetadataField = false; - this.reorderables.forEach((reorderable: Reorderable, index: number) => { - if (reorderable.hasMoved) { - if (reorderable instanceof ReorderableFormFieldMetadataValue) { - const prevIndex = reorderable.oldIndex; - hasMetadataField = true; - reorderable.update().pipe(take(1)).subscribe((v) => { - const reoMD = reorderable as ReorderableFormFieldMetadataValue; - reoMD.model.value = reoMD.metadataValue; - this.onChange({ - $event: { previousIndex: prevIndex }, - context: { index }, - control: reoMD.control, - group: this.group, - model: reoMD.model, - type: DynamicFormControlEventType.Change - }); - }); - } else if (reorderable instanceof ReorderableRelationship) { - movedReoRels.push(reorderable) - } - } - }); - - if (isNotEmpty(movedReoRels) && hasMetadataField && hasValue(this.model.relationshipConfig)) { - // if it's a mix between entities and regular metadata fields, - // we need to save, since they use different endpoints and - // otherwise they'll get out of sync. - this.submissionService.dispatchSave(this.model.submissionId); - } - - observableCombineLatest( - movedReoRels.map((movedReoRel) => movedReoRel.update().pipe(take(1))) - ).subscribe(() => { - this.changeDetectorRef.detectChanges(); - }); - } - }); - }) - } - moveSelection(event: CdkDragDrop) { this.model.moveGroup(event.previousIndex, event.currentIndex - event.previousIndex); - this.updateReorderables(); + const prevIndex = event.previousIndex - 1; + const index = event.currentIndex - 1; + const $event = { + $event: { previousIndex: prevIndex }, + context: { index }, + control: (this.control as any).controls[index], + group: this.group, + model: this.model.groups[index].group[0], + type: DynamicFormControlEventType.Change + }; + + this.onChange($event); } - update(index: number) { - if (index > 0) { - this.updateReorderables(); - } + update(event: any, index: number) { + const $event = Object.assign({}, event, { + context: { index: index - 1} + }); + + console.log('$event', $event); + + this.onChange($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 8a6a55715f..ab837522fd 100644 --- a/src/app/submission/sections/form/section-form-operations.service.ts +++ b/src/app/submission/sections/form/section-form-operations.service.ts @@ -366,14 +366,7 @@ export class SectionFormOperationsService { value, true); } else if (previousValue.isPathEqual(this.formBuilder.getPath(event.model)) || hasStoredValue) { // Here model has a previous value changed or stored in the server - if (!value.hasValue()) { - // New value is empty, so dispatch a remove operation - if (this.getArrayIndexFromEvent(event) === 0) { - this.operationsBuilder.remove(pathCombiner.getPath(segmentedPath)); - } else { - this.operationsBuilder.remove(pathCombiner.getPath(path)); - } - } else if (hasValue(event.$event) && hasValue(event.$event.previousIndex)) { + if (hasValue(event.$event) && hasValue(event.$event.previousIndex)) { if (event.$event.previousIndex < 0) { this.operationsBuilder.add( pathCombiner.getPath(segmentedPath), @@ -384,6 +377,13 @@ export class SectionFormOperationsService { pathCombiner.getPath(segmentedPath + '/' + event.$event.previousIndex).path ) } + } else if (!value.hasValue()) { + // New value is empty, so dispatch a remove operation + if (this.getArrayIndexFromEvent(event) === 0) { + this.operationsBuilder.remove(pathCombiner.getPath(segmentedPath)); + } else { + this.operationsBuilder.remove(pathCombiner.getPath(path)); + } } else { // New value is not equal from the previous one, so dispatch a replace operation this.operationsBuilder.replace(