mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
store reordered relationships to the server
This commit is contained in:
@@ -255,7 +255,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
|
|||||||
getSucceededRemoteData(),
|
getSucceededRemoteData(),
|
||||||
getRemoteDataPayload(),
|
getRemoteDataPayload(),
|
||||||
map((leftItem: Item) => {
|
map((leftItem: Item) => {
|
||||||
return new ReorderableRelationship(relationship, leftItem.uuid !== this.item.uuid)
|
return new ReorderableRelationship(relationship, leftItem.uuid !== this.item.uuid, this.relationshipService)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@@ -1,31 +1,55 @@
|
|||||||
import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core';
|
import { Component, EventEmitter, Input, OnChanges, OnDestroy } from '@angular/core';
|
||||||
import { Item } from '../../../../../core/shared/item.model';
|
import { AbstractControl, FormControl } from '@angular/forms';
|
||||||
import { MetadataRepresentation } from '../../../../../core/shared/metadata-representation/metadata-representation.model';
|
import { DynamicFormControlEvent } from '@ng-dynamic-forms/core';
|
||||||
import { getAllSucceededRemoteData, getRemoteDataPayload } from '../../../../../core/shared/operators';
|
|
||||||
import { hasValue, isNotEmpty } from '../../../../empty.util';
|
|
||||||
import { Subscription } from 'rxjs';
|
|
||||||
import { filter } from 'rxjs/operators';
|
|
||||||
import { Relationship } from '../../../../../core/shared/item-relationships/relationship.model';
|
|
||||||
import { MetadataValue } from '../../../../../core/shared/metadata.models';
|
|
||||||
import { ItemMetadataRepresentation } from '../../../../../core/shared/metadata-representation/item/item-metadata-representation.model';
|
|
||||||
import { RelationshipOptions } from '../../models/relationship-options.model';
|
|
||||||
import { RemoveRelationshipAction } from '../relation-lookup-modal/relationship.actions';
|
|
||||||
import { SelectableListService } from '../../../../object-list/selectable-list/selectable-list.service';
|
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
import { Observable, of as observableOf, Subject, Subscription } from 'rxjs';
|
||||||
|
import { filter } from 'rxjs/operators';
|
||||||
import { AppState } from '../../../../../app.reducer';
|
import { AppState } from '../../../../../app.reducer';
|
||||||
|
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 { ItemMetadataRepresentation } from '../../../../../core/shared/metadata-representation/item/item-metadata-representation.model';
|
||||||
|
import { MetadataRepresentation } from '../../../../../core/shared/metadata-representation/metadata-representation.model';
|
||||||
|
import { MetadataValue } from '../../../../../core/shared/metadata.models';
|
||||||
|
import {
|
||||||
|
getAllSucceededRemoteData,
|
||||||
|
getRemoteDataPayload,
|
||||||
|
getSucceededRemoteData
|
||||||
|
} from '../../../../../core/shared/operators';
|
||||||
|
import { hasValue, isNotEmpty } from '../../../../empty.util';
|
||||||
import { ItemSearchResult } from '../../../../object-collection/shared/item-search-result.model';
|
import { ItemSearchResult } from '../../../../object-collection/shared/item-search-result.model';
|
||||||
|
import { SelectableListService } from '../../../../object-list/selectable-list/selectable-list.service';
|
||||||
|
import { FormFieldMetadataValueObject } from '../../models/form-field-metadata-value.model';
|
||||||
|
import { RelationshipOptions } from '../../models/relationship-options.model';
|
||||||
|
import { DynamicConcatModel } from '../models/ds-dynamic-concat.model';
|
||||||
|
import { RemoveRelationshipAction } from '../relation-lookup-modal/relationship.actions';
|
||||||
|
|
||||||
export abstract class Reorderable {
|
export abstract class Reorderable {
|
||||||
|
|
||||||
constructor(public oldIndex?: number, public newIndex?: number) {
|
constructor(public oldIndex?: number, public newIndex?: number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract getId(): string;
|
abstract getId(): string;
|
||||||
|
|
||||||
abstract getPlace(): number;
|
abstract getPlace(): number;
|
||||||
|
|
||||||
|
abstract update(): Observable<any>;
|
||||||
|
|
||||||
|
get hasMoved(): boolean {
|
||||||
|
return this.oldIndex !== this.newIndex
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ReorderableMetadataValue extends Reorderable {
|
export class ReorderableFormFieldMetadataValue extends Reorderable {
|
||||||
|
|
||||||
constructor(public metadataValue: MetadataValue, oldIndex?: number, newIndex?: number) {
|
constructor(
|
||||||
|
public metadataValue: FormFieldMetadataValueObject,
|
||||||
|
public model: DynamicConcatModel,
|
||||||
|
public control: FormControl,
|
||||||
|
oldIndex?: number,
|
||||||
|
newIndex?: number
|
||||||
|
) {
|
||||||
super(oldIndex, newIndex);
|
super(oldIndex, newIndex);
|
||||||
this.metadataValue = metadataValue;
|
this.metadataValue = metadataValue;
|
||||||
}
|
}
|
||||||
@@ -43,11 +67,19 @@ export class ReorderableMetadataValue extends Reorderable {
|
|||||||
return this.metadataValue.place;
|
return this.metadataValue.place;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update(): Observable<FormFieldMetadataValueObject> {
|
||||||
|
this.metadataValue.place = this.newIndex;
|
||||||
|
this.model.valueUpdates.next(this.metadataValue as any);
|
||||||
|
console.log('this.control.value', this.control.value);
|
||||||
|
this.oldIndex = this.newIndex;
|
||||||
|
return observableOf(this.metadataValue);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ReorderableRelationship extends Reorderable {
|
export class ReorderableRelationship extends Reorderable {
|
||||||
|
|
||||||
constructor(public relationship: Relationship, public useLeftItem: boolean, oldIndex?: number, newIndex?: number) {
|
constructor(public relationship: Relationship, public useLeftItem: boolean, protected relationshipService: RelationshipService, oldIndex?: number, newIndex?: number) {
|
||||||
super(oldIndex, newIndex);
|
super(oldIndex, newIndex);
|
||||||
this.relationship = relationship;
|
this.relationship = relationship;
|
||||||
this.useLeftItem = useLeftItem;
|
this.useLeftItem = useLeftItem;
|
||||||
@@ -64,21 +96,17 @@ export class ReorderableRelationship extends Reorderable {
|
|||||||
return this.relationship.leftPlace
|
return this.relationship.leftPlace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
export class ReorderableMetadata extends Reorderable {
|
|
||||||
metadata: MetadataValue;
|
|
||||||
|
|
||||||
constructor(metadata: MetadataValue, oldIndex?: number, newIndex?: number) {
|
update(): Observable<RemoteData<Relationship>> {
|
||||||
super(oldIndex, newIndex);
|
const updatedRelationship$ = this.relationshipService.updatePlace(this);
|
||||||
this.metadata = metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
getId(): string {
|
updatedRelationship$.pipe(
|
||||||
return this.metadata.uuid;
|
getSucceededRemoteData()
|
||||||
}
|
).subscribe(() => {
|
||||||
|
this.oldIndex = this.newIndex;
|
||||||
|
});
|
||||||
|
|
||||||
getPlace(): number {
|
return updatedRelationship$;
|
||||||
return this.metadata.place
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +148,7 @@ export class ExistingMetadataListElementComponent implements OnChanges, OnDestro
|
|||||||
const relationMD: MetadataValue = this.submissionItem.firstMetadata(this.relationshipOptions.metadataField, { value: this.relatedItem.uuid });
|
const relationMD: MetadataValue = this.submissionItem.firstMetadata(this.relationshipOptions.metadataField, { value: this.relatedItem.uuid });
|
||||||
if (hasValue(relationMD)) {
|
if (hasValue(relationMD)) {
|
||||||
const metadataRepresentationMD: MetadataValue = this.submissionItem.firstMetadata(this.metadataFields, { authority: relationMD.authority });
|
const metadataRepresentationMD: MetadataValue = this.submissionItem.firstMetadata(this.metadataFields, { authority: relationMD.authority });
|
||||||
this.metadataRepresentation = Object.assign(
|
this.metadataRepresentation = Object.assign(
|
||||||
new ItemMetadataRepresentation(metadataRepresentationMD),
|
new ItemMetadataRepresentation(metadataRepresentationMD),
|
||||||
this.relatedItem
|
this.relatedItem
|
||||||
)
|
)
|
||||||
|
@@ -1,12 +1,11 @@
|
|||||||
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
||||||
import { Component, EventEmitter, Input, NgZone, OnInit, Output, QueryList } from '@angular/core';
|
import { Component, EventEmitter, Input, NgZone, OnInit, Output, QueryList } from '@angular/core';
|
||||||
import { FormGroup } from '@angular/forms';
|
import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms';
|
||||||
import {
|
import {
|
||||||
DynamicFormArrayComponent,
|
DynamicFormArrayComponent,
|
||||||
DynamicFormArrayGroupModel,
|
DynamicFormArrayGroupModel,
|
||||||
DynamicFormArrayModel,
|
|
||||||
DynamicFormControlCustomEvent,
|
DynamicFormControlCustomEvent,
|
||||||
DynamicFormControlEvent, DynamicFormControlModel,
|
DynamicFormControlEvent,
|
||||||
DynamicFormLayout,
|
DynamicFormLayout,
|
||||||
DynamicFormLayoutService,
|
DynamicFormLayoutService,
|
||||||
DynamicFormService,
|
DynamicFormService,
|
||||||
@@ -14,22 +13,23 @@ import {
|
|||||||
DynamicTemplateDirective
|
DynamicTemplateDirective
|
||||||
} from '@ng-dynamic-forms/core';
|
} from '@ng-dynamic-forms/core';
|
||||||
import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs';
|
import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs';
|
||||||
import { map, switchMap, take, tap } from 'rxjs/operators';
|
import { map, switchMap, take } from 'rxjs/operators';
|
||||||
import { RelationshipService } from '../../../../../../core/data/relationship.service';
|
import { RelationshipService } from '../../../../../../core/data/relationship.service';
|
||||||
import { RemoteData } from '../../../../../../core/data/remote-data';
|
import { RemoteData } from '../../../../../../core/data/remote-data';
|
||||||
import { Relationship } from '../../../../../../core/shared/item-relationships/relationship.model';
|
import { Relationship } from '../../../../../../core/shared/item-relationships/relationship.model';
|
||||||
import { Item } from '../../../../../../core/shared/item.model';
|
import { Item } from '../../../../../../core/shared/item.model';
|
||||||
import { MetadataValue } from '../../../../../../core/shared/metadata.models';
|
import { MetadataValue } from '../../../../../../core/shared/metadata.models';
|
||||||
import {
|
import {
|
||||||
getAllSucceededRemoteData,
|
getRemoteDataPayload,
|
||||||
getRemoteDataPayload, getSucceededRemoteData
|
getSucceededRemoteData
|
||||||
} from '../../../../../../core/shared/operators';
|
} from '../../../../../../core/shared/operators';
|
||||||
import { SubmissionObject } from '../../../../../../core/submission/models/submission-object.model';
|
import { SubmissionObject } from '../../../../../../core/submission/models/submission-object.model';
|
||||||
import { SubmissionObjectDataService } from '../../../../../../core/submission/submission-object-data.service';
|
import { SubmissionObjectDataService } from '../../../../../../core/submission/submission-object-data.service';
|
||||||
import { hasValue, isNotEmpty } from '../../../../../empty.util';
|
import { hasValue, isNotEmpty } from '../../../../../empty.util';
|
||||||
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
|
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
|
||||||
import {
|
import {
|
||||||
Reorderable, ReorderableMetadataValue,
|
Reorderable,
|
||||||
|
ReorderableFormFieldMetadataValue,
|
||||||
ReorderableRelationship
|
ReorderableRelationship
|
||||||
} from '../../existing-metadata-list-element/existing-metadata-list-element.component';
|
} from '../../existing-metadata-list-element/existing-metadata-list-element.component';
|
||||||
import { DynamicConcatModel } from '../ds-dynamic-concat.model';
|
import { DynamicConcatModel } from '../ds-dynamic-concat.model';
|
||||||
@@ -69,6 +69,7 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent imple
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
console.log('this.group.controls[this.model.id]', this.control);
|
||||||
this.submissionObjectService
|
this.submissionObjectService
|
||||||
.findById(this.model.submissionId).pipe(
|
.findById(this.model.submissionId).pipe(
|
||||||
getSucceededRemoteData(),
|
getSucceededRemoteData(),
|
||||||
@@ -84,81 +85,91 @@ export class DsDynamicFormArrayComponent extends DynamicFormArrayComponent imple
|
|||||||
this.updateReorderables();
|
this.updateReorderables();
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateReorderables(): void {
|
private updateReorderables(): void {
|
||||||
const reorderable$arr: Array<Observable<Reorderable>> = this.model.groups
|
this.zone.runOutsideAngular(() => {
|
||||||
.slice(1) // disregard the first group, it is always empty to ensure the first field remains empty
|
const reorderable$arr: Array<Observable<Reorderable>> = this.model.groups
|
||||||
.map((group: DynamicFormArrayGroupModel, index: number) => {
|
.map((group, index) => [group, (this.control as any).controls[index]])
|
||||||
const formFieldMetadataValue: FormFieldMetadataValueObject = (group.group[0] as DynamicConcatModel).value as FormFieldMetadataValueObject;
|
.slice(1) // disregard the first group, it is always empty to ensure the first field remains empty
|
||||||
if (hasValue(formFieldMetadataValue)) {
|
.map(([group, control]: [DynamicFormArrayGroupModel, AbstractControl], index: number) => {
|
||||||
const value = Object.assign(new MetadataValue(), {
|
const model = group.group[0] as DynamicConcatModel;
|
||||||
value: formFieldMetadataValue.display,
|
let formFieldMetadataValue: FormFieldMetadataValueObject = model.value as FormFieldMetadataValueObject;
|
||||||
language: formFieldMetadataValue.language,
|
if (hasValue(formFieldMetadataValue)) {
|
||||||
place: formFieldMetadataValue.place,
|
const metadataValue = Object.assign(new MetadataValue(), {
|
||||||
authority: formFieldMetadataValue.authority,
|
value: formFieldMetadataValue.display,
|
||||||
confidence: formFieldMetadataValue.confidence
|
language: formFieldMetadataValue.language,
|
||||||
});
|
place: formFieldMetadataValue.place,
|
||||||
if (value.isVirtual) {
|
authority: formFieldMetadataValue.authority,
|
||||||
return this.relationshipService.findById(value.virtualValue)
|
confidence: formFieldMetadataValue.confidence
|
||||||
.pipe(
|
});
|
||||||
getSucceededRemoteData(),
|
if (metadataValue.isVirtual) {
|
||||||
getRemoteDataPayload(),
|
return this.relationshipService.findById(metadataValue.virtualValue)
|
||||||
switchMap((relationship: Relationship) =>
|
.pipe(
|
||||||
relationship.leftItem.pipe(
|
getSucceededRemoteData(),
|
||||||
getSucceededRemoteData(),
|
getRemoteDataPayload(),
|
||||||
getRemoteDataPayload(),
|
switchMap((relationship: Relationship) =>
|
||||||
map((leftItem: Item) => {
|
relationship.leftItem.pipe(
|
||||||
return new ReorderableRelationship(
|
getSucceededRemoteData(),
|
||||||
relationship,
|
getRemoteDataPayload(),
|
||||||
leftItem.uuid !== this.submissionItem.uuid,
|
map((leftItem: Item) => {
|
||||||
index,
|
return new ReorderableRelationship(
|
||||||
index
|
relationship,
|
||||||
);
|
leftItem.uuid !== this.submissionItem.uuid,
|
||||||
}),
|
this.relationshipService,
|
||||||
|
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, index, index));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return observableOf(new ReorderableMetadataValue(value, index, index));
|
formFieldMetadataValue = Object.assign(new FormFieldMetadataValueObject(), {
|
||||||
|
value: '',
|
||||||
|
display: '',
|
||||||
|
place: index,
|
||||||
|
});
|
||||||
|
return observableOf(new ReorderableFormFieldMetadataValue(formFieldMetadataValue, model as any, control as FormControl, index, index));
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
const value = Object.assign(new MetadataValue(), {
|
|
||||||
value: '',
|
|
||||||
place: index,
|
|
||||||
});
|
|
||||||
return observableOf(new ReorderableMetadataValue(value, index, index));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
observableCombineLatest(reorderable$arr)
|
observableCombineLatest(reorderable$arr)
|
||||||
.subscribe((reorderables: Reorderable[]) => {
|
.subscribe((reorderables: Reorderable[]) => {
|
||||||
if (isNotEmpty(this.reorderables)) {
|
if (isNotEmpty(this.reorderables)) {
|
||||||
reorderables.forEach((newReorderable: Reorderable) => {
|
reorderables.forEach((newReorderable: Reorderable) => {
|
||||||
const match = this.reorderables.find((reo: Reorderable) => reo.getId() === newReorderable.getId());
|
const match = this.reorderables.find((reo: Reorderable) => reo.getId() === newReorderable.getId());
|
||||||
if (hasValue(match)) {
|
if (hasValue(match)) {
|
||||||
newReorderable.oldIndex = match.newIndex;
|
newReorderable.oldIndex = match.newIndex;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.reorderables = reorderables;
|
||||||
|
|
||||||
|
this.reorderables.forEach((reorderable: Reorderable) => {
|
||||||
|
if (reorderable.hasMoved) {
|
||||||
|
console.log('reorderable moved', reorderable, reorderable.getPlace());
|
||||||
|
reorderable.update().pipe(take(1)).subscribe((v) => {
|
||||||
|
console.log('reorderable updated', reorderable, reorderable.getPlace());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
});
|
||||||
this.reorderables = reorderables;
|
})
|
||||||
console.log('this.reorderables', this.reorderables);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
moveSelection(event: CdkDragDrop<Relationship>) {
|
moveSelection(event: CdkDragDrop<Relationship>) {
|
||||||
this.model.moveGroup(event.previousIndex,event.currentIndex - event.previousIndex);
|
this.model.moveGroup(event.previousIndex, event.currentIndex - event.previousIndex);
|
||||||
this.updateReorderables();
|
this.updateReorderables();
|
||||||
|
|
||||||
// this.zone.runOutsideAngular(() => {
|
|
||||||
|
|
||||||
// return observableCombineLatest(reorderables.map((rel: ReorderableRelationship) => {
|
|
||||||
// if (rel.oldIndex !== rel.newIndex) {
|
|
||||||
// return this.relationshipService.updatePlace(rel);
|
|
||||||
// } else {
|
|
||||||
// return observableOf(undefined);
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// ).pipe(getSucceededRemoteData()).subscribe();
|
|
||||||
// })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user