diff --git a/src/app/+item-page/simple/item-types/shared/item-relationships-utils.ts b/src/app/+item-page/simple/item-types/shared/item-relationships-utils.ts index 7baf260c61..7911201df0 100644 --- a/src/app/+item-page/simple/item-types/shared/item-relationships-utils.ts +++ b/src/app/+item-page/simple/item-types/shared/item-relationships-utils.ts @@ -1,8 +1,8 @@ -import { getSucceededRemoteData } from '../../../../core/shared/operators'; +import { getAllSucceededRemoteData, getFinishedRemoteData, getSucceededRemoteData } from '../../../../core/shared/operators'; import { hasValue } from '../../../../shared/empty.util'; import { Observable } from 'rxjs/internal/Observable'; import { Relationship } from '../../../../core/shared/item-relationships/relationship.model'; -import { distinctUntilChanged, flatMap, map, switchMap } from 'rxjs/operators'; +import { distinctUntilChanged, filter, flatMap, map, switchMap } from 'rxjs/operators'; import { combineLatest as observableCombineLatest, zip as observableZip } from 'rxjs'; import { Item } from '../../../../core/shared/item.model'; import { PaginatedList } from '../../../../core/data/paginated-list'; @@ -18,7 +18,7 @@ import { RemoteData } from '../../../../core/data/remote-data'; export const compareArraysUsing = (mapFn: (t: T) => any) => (a: T[], b: T[]): boolean => { if (!Array.isArray(a) || ! Array.isArray(b)) { - return false + return false; } const aIds = a.map(mapFn); @@ -72,10 +72,9 @@ export const relationsToItems = (thisId: string) => export const paginatedRelationsToItems = (thisId: string) => (source: Observable>>): Observable>> => source.pipe( - getSucceededRemoteData(), switchMap((relationshipsRD: RemoteData>) => { - return observableZip( - ...relationshipsRD.payload.page.map((rel: Relationship) => observableCombineLatest(rel.leftItem, rel.rightItem)) + return observableCombineLatest( + ...relationshipsRD.payload.page.map((rel: Relationship) => observableCombineLatest(rel.leftItem.pipe(getFinishedRemoteData()), rel.rightItem.pipe(getFinishedRemoteData()))) ).pipe( map((arr) => arr diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts index 48c5090102..ab24fe16cd 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -23,6 +23,7 @@ import { } from '../../shared/operators'; import { CacheableObject, TypedObject } from '../object-cache.reducer'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils'; +import { deepClone } from 'fast-json-patch'; @Injectable() export class RemoteDataBuildService { @@ -124,7 +125,6 @@ export class RemoteDataBuildService { }); })); }), - startWith([]), distinctUntilChanged(), ); const pageInfo$ = requestEntry$.pipe( diff --git a/src/app/core/data/data.service.ts b/src/app/core/data/data.service.ts index d55b7353eb..a537b49300 100644 --- a/src/app/core/data/data.service.ts +++ b/src/app/core/data/data.service.ts @@ -227,7 +227,7 @@ export abstract class DataService { ), switchMap((href) => this.requestService.getByHref(href)), skipWhile((requestEntry) => hasValue(requestEntry) && requestEntry.completed), - switchMap((href) => + switchMap(() => this.rdbService.buildList(hrefObs) as Observable>> ) ); @@ -348,4 +348,7 @@ export abstract class DataService { this.requestService.commit(method); } + getLinkPath() { + return this.linkPath; + } } diff --git a/src/app/core/submission/submission-object-data.service.ts b/src/app/core/submission/submission-object-data.service.ts index 15ede18cb8..25cc507767 100644 --- a/src/app/core/submission/submission-object-data.service.ts +++ b/src/app/core/submission/submission-object-data.service.ts @@ -7,6 +7,9 @@ import { SubmissionObject } from './models/submission-object.model'; import { SubmissionScopeType } from './submission-scope-type'; import { WorkflowItemDataService } from './workflowitem-data.service'; import { WorkspaceitemDataService } from './workspaceitem-data.service'; +import { DataService } from '../data/data.service'; +import { map } from 'rxjs/operators'; +import { HALEndpointService } from '../shared/hal-endpoint.service'; /** * A service to retrieve submission objects (WorkspaceItem/WorkflowItem) @@ -19,10 +22,22 @@ export class SubmissionObjectDataService { constructor( private workspaceitemDataService: WorkspaceitemDataService, private workflowItemDataService: WorkflowItemDataService, - private submissionService: SubmissionService + private submissionService: SubmissionService, + private halService: HALEndpointService ) { } + /** + * Create the HREF for a specific object based on its identifier + * @param id The identifier for the object + */ + getHrefByID(id): Observable { + const dataService: DataService = this.submissionService.getSubmissionScope() === SubmissionScopeType.WorkspaceItem ? this.workspaceitemDataService : this.workflowItemDataService; + + return this.halService.getEndpoint(dataService.getLinkPath()).pipe( + map((endpoint: string) => dataService.getIDHref(endpoint, encodeURIComponent(id)))); + } + /** * Retrieve a submission object based on its ID. * 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 6f7b476e9f..be3af9c8da 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 @@ -73,7 +73,7 @@ import { DsDynamicFormArrayComponent } from './models/array-group/dynamic-form-a import { DsDynamicRelationGroupComponent } from './models/relation-group/dynamic-relation-group.components'; import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from './models/relation-group/dynamic-relation-group.model'; import { DsDatePickerInlineComponent } from './models/date-picker-inline/dynamic-date-picker-inline.component'; -import { map, startWith, switchMap, find, take } from 'rxjs/operators'; +import { map, startWith, switchMap, find, take, tap } from 'rxjs/operators'; import { combineLatest as observableCombineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; import { SearchResult } from '../../../search/search-result.model'; import { DSpaceObject } from '../../../../core/shared/dspace-object.model'; @@ -96,6 +96,7 @@ import { ItemSearchResult } from '../../../object-collection/shared/item-search- import { Relationship } from '../../../../core/shared/item-relationships/relationship.model'; import { MetadataValue } from '../../../../core/shared/metadata.models'; import { FormService } from '../../form.service'; +import { deepClone } from 'fast-json-patch'; export function dsDynamicFormControlMapFn(model: DynamicFormControlModel): Type | null { switch (model.type) { @@ -253,8 +254,11 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo } } if (this.model.relationshipConfig) { + this.listId = 'list-' + this.model.relationshipConfig.relationshipType; this.setItem(); this.relationService.getRelatedItemsByLabel(this.item, this.model.relationshipConfig.relationshipType).pipe( + tap((t: any) => console.log(deepClone(t))), + getSucceededRemoteData(), map((items: RemoteData>) => items.payload.page.map((item) => Object.assign(new ItemSearchResult(), { indexableObject: item }))), ).subscribe((relatedItems: Array>) => this.selectableListService.select(this.listId, relatedItems)); } 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 9723a6ea74..78316e8c22 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 @@ -9,14 +9,16 @@
-
+
+
+
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 3acf5f7604..ca3316bc6f 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 @@ -1,13 +1,16 @@ @import './../../../../../../../styles/variables'; .cdk-drag { - margin-left: -(1.5 * $spacer); + margin-left: -(2 * $spacer); + margin-right: -(0.5 * $spacer); + padding-right: (0.5 * $spacer); .drag-icon { visibility: hidden; - width: (1.5 * $spacer); + width: (2 * $spacer); color: $gray-600; margin: $btn-padding-y 0; line-height: $btn-line-height; + text-indent: 0.5 * $spacer } &:hover, &:focus { diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/relationship.effects.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/relationship.effects.ts index 6d884210c2..7ea2413ea1 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/relationship.effects.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/relationship.effects.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { Actions, Effect, ofType } from '@ngrx/effects'; -import { debounceTime, map, mergeMap, switchMap, take } from 'rxjs/operators'; -import { BehaviorSubject } from 'rxjs'; +import { debounceTime, filter, map, mergeMap, switchMap, take } from 'rxjs/operators'; +import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { RelationshipService } from '../../../../../core/data/relationship.service'; import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../../core/shared/operators'; import { AddRelationshipAction, RelationshipAction, RelationshipActionTypes, UpdateRelationshipAction } from './relationship.actions'; @@ -15,6 +15,8 @@ import { SaveSubmissionSectionFormSuccessAction } from '../../../../../submissio import { SubmissionObject } from '../../../../../core/submission/models/submission-object.model'; import { SubmissionState } from '../../../../../submission/submission.reducers'; import { Store } from '@ngrx/store'; +import { ObjectCacheService } from '../../../../../core/cache/object-cache.service'; +import { RequestService } from '../../../../../core/data/request.service'; const DEBOUNCE_TIME = 5000; @@ -106,7 +108,9 @@ export class RelationshipEffects { private relationshipService: RelationshipService, private relationshipTypeService: RelationshipTypeService, private submissionObjectService: SubmissionObjectDataService, - private store: Store + private store: Store, + private objectCache: ObjectCacheService, + private requestService: RequestService ) { } @@ -127,8 +131,9 @@ export class RelationshipEffects { return this.relationshipService.addRelationship(type.id, item1, item2, undefined, nameVariant); } } - ) - ).pipe(take(1), switchMap(() => this.submissionObjectService.findById(submissionId).pipe(getSucceededRemoteData(), getRemoteDataPayload())) + ), + take(1), + this.removeWorkspaceItemFromCache(submissionId) ).subscribe((submissionObject: SubmissionObject) => this.store.dispatch(new SaveSubmissionSectionFormSuccessAction(submissionId, [submissionObject], false))); } @@ -138,7 +143,25 @@ export class RelationshipEffects { hasValueOperator(), mergeMap((relationship: Relationship) => this.relationshipService.deleteRelationship(relationship.id)), take(1), - switchMap(() => this.submissionObjectService.findById(submissionId).pipe(getSucceededRemoteData(), getRemoteDataPayload())) - ).subscribe((submissionObject: SubmissionObject) => this.store.dispatch(new SaveSubmissionSectionFormSuccessAction(submissionId, [submissionObject]))); + this.removeWorkspaceItemFromCache(submissionId) + ).subscribe((submissionObject: SubmissionObject) => this.store.dispatch(new SaveSubmissionSectionFormSuccessAction(submissionId, [submissionObject], false))); } + + removeWorkspaceItemFromCache = (submissionId) => + (source: Observable): Observable => + source.pipe( + switchMap(() => this.submissionObjectService.getHrefByID(submissionId).pipe(take(1))), + switchMap((href: string) => { + this.objectCache.remove(href); + this.requestService.removeByHrefSubstring(submissionId); + return combineLatest( + this.objectCache.hasBySelfLinkObservable(href), + this.requestService.hasByHrefObservable(href) + ).pipe( + filter(([existsInOC, existsInRC]) => !existsInOC && !existsInRC), + take(1), + switchMap(() => this.submissionObjectService.findById(submissionId).pipe(getSucceededRemoteData(), getRemoteDataPayload()) as Observable) + ) + } + )); } diff --git a/src/app/shared/form/form.component.scss b/src/app/shared/form/form.component.scss index acdeb792ca..01cf09576f 100644 --- a/src/app/shared/form/form.component.scss +++ b/src/app/shared/form/form.component.scss @@ -42,8 +42,3 @@ .right-addon input { padding-right: $spacer * 2.25; } - -.ds-form-qualdrop-hint { - top: -$spacer; - position: relative; -}