mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
fix issue where the first relationship of a type wouldn't be added
This commit is contained in:
@@ -105,6 +105,7 @@ export class ServerSyncBufferEffects {
|
|||||||
if (isNotEmpty(entry.patches)) {
|
if (isNotEmpty(entry.patches)) {
|
||||||
const flatPatch: Operation[] = [].concat(...entry.patches.map((patch) => patch.operations));
|
const flatPatch: Operation[] = [].concat(...entry.patches.map((patch) => patch.operations));
|
||||||
if (isNotEmpty(flatPatch)) {
|
if (isNotEmpty(flatPatch)) {
|
||||||
|
// if (href.match(/https://dspace7-ben.atmire.com/server/api/core/relationships/\d+/))
|
||||||
this.requestService.configure(new PatchRequest(this.requestService.generateRequestId(), href, flatPatch));
|
this.requestService.configure(new PatchRequest(this.requestService.generateRequestId(), href, flatPatch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -509,7 +509,15 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
this.requestService.commit(method);
|
this.requestService.commit(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
getLinkPath() {
|
/**
|
||||||
|
* Return the links to traverse from the root of the api to the
|
||||||
|
* endpoint this DataService represents
|
||||||
|
*
|
||||||
|
* e.g. if the api root links to 'foo', and the endpoint at 'foo'
|
||||||
|
* links to 'bar' the linkPath for the BarDataService would be
|
||||||
|
* 'foo/bar'
|
||||||
|
*/
|
||||||
|
getLinkPath(): string {
|
||||||
return this.linkPath;
|
return this.linkPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,9 +3,9 @@ import { Injectable } from '@angular/core';
|
|||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { combineLatest as observableCombineLatest } from 'rxjs';
|
import { combineLatest as observableCombineLatest } from 'rxjs';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { filter, find, map, switchMap } from 'rxjs/operators';
|
import { filter, find, map, switchMap, tap, mergeMap } from 'rxjs/operators';
|
||||||
import { AppState } from '../../app.reducer';
|
import { AppState } from '../../app.reducer';
|
||||||
import { isNotUndefined } from '../../shared/empty.util';
|
import { isNotUndefined, hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { followLink } from '../../shared/utils/follow-link-config.model';
|
import { followLink } from '../../shared/utils/follow-link-config.model';
|
||||||
import { dataService } from '../cache/builders/build-decorators';
|
import { dataService } from '../cache/builders/build-decorators';
|
||||||
@@ -76,7 +76,7 @@ export class RelationshipTypeService extends DataService<RelationshipType> {
|
|||||||
getSucceededRemoteData(),
|
getSucceededRemoteData(),
|
||||||
/* Flatten the page so we can treat it like an observable */
|
/* Flatten the page so we can treat it like an observable */
|
||||||
switchMap((typeListRD: RemoteData<PaginatedList<RelationshipType>>) => typeListRD.payload.page),
|
switchMap((typeListRD: RemoteData<PaginatedList<RelationshipType>>) => typeListRD.payload.page),
|
||||||
switchMap((type: RelationshipType) => {
|
mergeMap((type: RelationshipType) => {
|
||||||
if (type.leftwardType === label) {
|
if (type.leftwardType === label) {
|
||||||
return this.checkType(type, firstType, secondType);
|
return this.checkType(type, firstType, secondType);
|
||||||
} else if (type.rightwardType === label) {
|
} else if (type.rightwardType === label) {
|
||||||
@@ -92,7 +92,7 @@ export class RelationshipTypeService extends DataService<RelationshipType> {
|
|||||||
// returns a void observable if there's not match
|
// returns a void observable if there's not match
|
||||||
// returns an observable that emits the relationship type when there is a match
|
// returns an observable that emits the relationship type when there is a match
|
||||||
private checkType(type: RelationshipType, firstType: string, secondType: string): Observable<RelationshipType> {
|
private checkType(type: RelationshipType, firstType: string, secondType: string): Observable<RelationshipType> {
|
||||||
const entityTypes = observableCombineLatest(type.leftType.pipe(getSucceededRemoteData()), type.rightType.pipe(getSucceededRemoteData()));
|
const entityTypes = observableCombineLatest([type.leftType.pipe(getSucceededRemoteData()), type.rightType.pipe(getSucceededRemoteData())]);
|
||||||
return entityTypes.pipe(
|
return entityTypes.pipe(
|
||||||
find(([leftTypeRD, rightTypeRD]: [RemoteData<ItemType>, RemoteData<ItemType>]) => leftTypeRD.payload.label === firstType && rightTypeRD.payload.label === secondType),
|
find(([leftTypeRD, rightTypeRD]: [RemoteData<ItemType>, RemoteData<ItemType>]) => leftTypeRD.payload.label === firstType && rightTypeRD.payload.label === secondType),
|
||||||
filter((types) => isNotUndefined(types)),
|
filter((types) => isNotUndefined(types)),
|
||||||
|
@@ -114,6 +114,7 @@ export class RelationshipService extends DataService<Relationship> {
|
|||||||
* @param rightwardValue The rightward value of the relationship
|
* @param rightwardValue The rightward value of the relationship
|
||||||
*/
|
*/
|
||||||
addRelationship(typeId: string, item1: Item, item2: Item, leftwardValue?: string, rightwardValue?: string): Observable<RestResponse> {
|
addRelationship(typeId: string, item1: Item, item2: Item, leftwardValue?: string, rightwardValue?: string): Observable<RestResponse> {
|
||||||
|
console.log('addRelationship', typeId, item1, item2, leftwardValue, rightwardValue);
|
||||||
const options: HttpOptions = Object.create({});
|
const options: HttpOptions = Object.create({});
|
||||||
let headers = new HttpHeaders();
|
let headers = new HttpHeaders();
|
||||||
headers = headers.append('Content-Type', 'text/uri-list');
|
headers = headers.append('Content-Type', 'text/uri-list');
|
||||||
|
@@ -65,6 +65,14 @@ export class JsonPatchOperationsBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new NewPatchMoveOperationAction
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* the new path tho move to
|
||||||
|
* @param prevPath
|
||||||
|
* the original path to move from
|
||||||
|
*/
|
||||||
move(path: JsonPatchOperationPathObject, prevPath: string) {
|
move(path: JsonPatchOperationPathObject, prevPath: string) {
|
||||||
this.store.dispatch(
|
this.store.dispatch(
|
||||||
new NewPatchMoveOperationAction(
|
new NewPatchMoveOperationAction(
|
||||||
|
@@ -294,6 +294,20 @@ function flushOperation(state: JsonPatchOperationsState, action: FlushPatchOpera
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new operation to a patch
|
||||||
|
*
|
||||||
|
* @param body
|
||||||
|
* The current patch
|
||||||
|
* @param actionType
|
||||||
|
* The type of operation to add
|
||||||
|
* @param targetPath
|
||||||
|
* The path for the operation
|
||||||
|
* @param value
|
||||||
|
* The new value
|
||||||
|
* @param fromPath
|
||||||
|
* The previous path (in case of a move operation)
|
||||||
|
*/
|
||||||
function addOperationToList(body: JsonPatchOperationObject[], actionType, targetPath, value?, fromPath?) {
|
function addOperationToList(body: JsonPatchOperationObject[], actionType, targetPath, value?, fromPath?) {
|
||||||
const newBody = Array.from(body);
|
const newBody = Array.from(body);
|
||||||
switch (actionType) {
|
switch (actionType) {
|
||||||
|
@@ -358,6 +358,9 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
|
|||||||
.forEach((sub) => sub.unsubscribe());
|
.forEach((sub) => sub.unsubscribe());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize this.item$ based on this.model.submissionId
|
||||||
|
*/
|
||||||
private setItem() {
|
private setItem() {
|
||||||
const submissionObject$ = this.submissionObjectService
|
const submissionObject$ = this.submissionObjectService
|
||||||
.findById(this.model.submissionId, followLink('item'), followLink('collection')).pipe(
|
.findById(this.model.submissionId, followLink('item'), followLink('collection')).pipe(
|
||||||
|
@@ -35,17 +35,33 @@ export abstract class Reorderable {
|
|||||||
constructor(public oldIndex?: number, public newIndex?: number) {
|
constructor(public oldIndex?: number, public newIndex?: number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the id for this Reorderable
|
||||||
|
*/
|
||||||
abstract getId(): string;
|
abstract getId(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the place metadata for this Reorderable
|
||||||
|
*/
|
||||||
abstract getPlace(): number;
|
abstract getPlace(): number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the Reorderable
|
||||||
|
*/
|
||||||
abstract update(): Observable<any>;
|
abstract update(): Observable<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the oldIndex of this Reorderable
|
||||||
|
* differs from the newIndex
|
||||||
|
*/
|
||||||
get hasMoved(): boolean {
|
get hasMoved(): boolean {
|
||||||
return this.oldIndex !== this.newIndex
|
return this.oldIndex !== this.newIndex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Reorderable representation of a FormFieldMetadataValue
|
||||||
|
*/
|
||||||
export class ReorderableFormFieldMetadataValue extends Reorderable {
|
export class ReorderableFormFieldMetadataValue extends Reorderable {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -60,6 +76,9 @@ export class ReorderableFormFieldMetadataValue extends Reorderable {
|
|||||||
this.metadataValue = metadataValue;
|
this.metadataValue = metadataValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the id for this Reorderable
|
||||||
|
*/
|
||||||
getId(): string {
|
getId(): string {
|
||||||
if (hasValue(this.metadataValue.authority)) {
|
if (hasValue(this.metadataValue.authority)) {
|
||||||
return this.metadataValue.authority;
|
return this.metadataValue.authority;
|
||||||
@@ -69,10 +88,16 @@ export class ReorderableFormFieldMetadataValue extends Reorderable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the place metadata for this Reorderable
|
||||||
|
*/
|
||||||
getPlace(): number {
|
getPlace(): number {
|
||||||
return this.metadataValue.place;
|
return this.metadataValue.place;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the Reorderable
|
||||||
|
*/
|
||||||
update(): Observable<FormFieldMetadataValueObject> {
|
update(): Observable<FormFieldMetadataValueObject> {
|
||||||
this.oldIndex = this.newIndex;
|
this.oldIndex = this.newIndex;
|
||||||
return observableOf(this.metadataValue);
|
return observableOf(this.metadataValue);
|
||||||
@@ -98,10 +123,16 @@ export class ReorderableRelationship extends Reorderable {
|
|||||||
this.useLeftItem = useLeftItem;
|
this.useLeftItem = useLeftItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the id for this Reorderable
|
||||||
|
*/
|
||||||
getId(): string {
|
getId(): string {
|
||||||
return this.relationship.id;
|
return this.relationship.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the place metadata for this Reorderable
|
||||||
|
*/
|
||||||
getPlace(): number {
|
getPlace(): number {
|
||||||
if (this.useLeftItem) {
|
if (this.useLeftItem) {
|
||||||
return this.relationship.rightPlace
|
return this.relationship.rightPlace
|
||||||
@@ -110,6 +141,9 @@ export class ReorderableRelationship extends Reorderable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the Reorderable
|
||||||
|
*/
|
||||||
update(): Observable<RemoteData<Relationship>> {
|
update(): Observable<RemoteData<Relationship>> {
|
||||||
this.store.dispatch(new UpdateRelationshipAction(this.relationship, this.submissionID))
|
this.store.dispatch(new UpdateRelationshipAction(this.relationship, this.submissionID))
|
||||||
const updatedRelationship$ = this.relationshipService.updatePlace(this).pipe(
|
const updatedRelationship$ = this.relationshipService.updatePlace(this).pipe(
|
||||||
@@ -154,6 +188,9 @@ export class ExistingMetadataListElementComponent implements OnChanges, OnDestro
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change callback for the component
|
||||||
|
*/
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
if (hasValue(this.reoRel)) {
|
if (hasValue(this.reoRel)) {
|
||||||
const item$ = this.reoRel.useLeftItem ?
|
const item$ = this.reoRel.useLeftItem ?
|
||||||
|
@@ -144,6 +144,7 @@ export class DsDynamicLookupRelationModalComponent implements OnInit, OnDestroy
|
|||||||
* @param selectableObjects
|
* @param selectableObjects
|
||||||
*/
|
*/
|
||||||
select(...selectableObjects: Array<SearchResult<Item>>) {
|
select(...selectableObjects: Array<SearchResult<Item>>) {
|
||||||
|
console.log('selectableObjects', selectableObjects);
|
||||||
this.zone.runOutsideAngular(
|
this.zone.runOutsideAngular(
|
||||||
() => {
|
() => {
|
||||||
const obs: Observable<any[]> = combineLatest(...selectableObjects.map((sri: SearchResult<Item>) => {
|
const obs: Observable<any[]> = combineLatest(...selectableObjects.map((sri: SearchResult<Item>) => {
|
||||||
@@ -163,7 +164,9 @@ export class DsDynamicLookupRelationModalComponent implements OnInit, OnDestroy
|
|||||||
obs
|
obs
|
||||||
.subscribe((arr: any[]) => {
|
.subscribe((arr: any[]) => {
|
||||||
return arr.forEach((object: any) => {
|
return arr.forEach((object: any) => {
|
||||||
this.store.dispatch(new AddRelationshipAction(this.item, object.item, this.relationshipOptions.relationshipType, this.submissionId, object.nameVariant));
|
const addRelationshipAction = new AddRelationshipAction(this.item, object.item, this.relationshipOptions.relationshipType, this.submissionId, object.nameVariant);
|
||||||
|
console.log('addRelationshipAction', addRelationshipAction);
|
||||||
|
this.store.dispatch(addRelationshipAction);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
@@ -21,7 +21,7 @@ import { ServerSyncBufferActionTypes } from '../../../../../core/cache/server-sy
|
|||||||
import { CommitPatchOperationsAction, JsonPatchOperationsActionTypes, PatchOperationsActions } from '../../../../../core/json-patch/json-patch-operations.actions';
|
import { CommitPatchOperationsAction, JsonPatchOperationsActionTypes, PatchOperationsActions } from '../../../../../core/json-patch/json-patch-operations.actions';
|
||||||
import { followLink } from '../../../../utils/follow-link-config.model';
|
import { followLink } from '../../../../utils/follow-link-config.model';
|
||||||
|
|
||||||
const DEBOUNCE_TIME = 5000;
|
const DEBOUNCE_TIME = 500;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NGRX effects for RelationshipEffects
|
* NGRX effects for RelationshipEffects
|
||||||
|
Reference in New Issue
Block a user