mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
Resolved more caching issues for relationships
This commit is contained in:
@@ -161,7 +161,6 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
findByHref(href: string, options?: HttpOptions): Observable<RemoteData<T>> {
|
findByHref(href: string, options?: HttpOptions): Observable<RemoteData<T>> {
|
||||||
console.log('perform request for:', href)
|
|
||||||
this.requestService.configure(new GetRequest(this.requestService.generateRequestId(), href, null, options), this.forceBypassCache);
|
this.requestService.configure(new GetRequest(this.requestService.generateRequestId(), href, null, options), this.forceBypassCache);
|
||||||
return this.rdbService.buildSingle<T>(href);
|
return this.rdbService.buildSingle<T>(href);
|
||||||
}
|
}
|
||||||
|
@@ -68,7 +68,7 @@ export class RelationshipService extends DataService<Relationship> {
|
|||||||
deleteRelationship(id: string): Observable<RestResponse> {
|
deleteRelationship(id: string): Observable<RestResponse> {
|
||||||
return this.getRelationshipEndpoint(id).pipe(
|
return this.getRelationshipEndpoint(id).pipe(
|
||||||
isNotEmptyOperator(),
|
isNotEmptyOperator(),
|
||||||
distinctUntilChanged(),
|
take(1),
|
||||||
map((endpointURL: string) => new DeleteRequest(this.requestService.generateRequestId(), endpointURL)),
|
map((endpointURL: string) => new DeleteRequest(this.requestService.generateRequestId(), endpointURL)),
|
||||||
configureRequest(this.requestService),
|
configureRequest(this.requestService),
|
||||||
switchMap((restRequest: RestRequest) => this.requestService.getByUUID(restRequest.uuid)),
|
switchMap((restRequest: RestRequest) => this.requestService.getByUUID(restRequest.uuid)),
|
||||||
@@ -84,7 +84,7 @@ export class RelationshipService extends DataService<Relationship> {
|
|||||||
options.headers = headers;
|
options.headers = headers;
|
||||||
return this.halService.getEndpoint(this.linkPath).pipe(
|
return this.halService.getEndpoint(this.linkPath).pipe(
|
||||||
isNotEmptyOperator(),
|
isNotEmptyOperator(),
|
||||||
distinctUntilChanged(),
|
take(1),
|
||||||
map((endpointUrl: string) => `${endpointUrl}?relationshipType=${typeId}`),
|
map((endpointUrl: string) => `${endpointUrl}?relationshipType=${typeId}`),
|
||||||
map((endpointURL: string) => new PostRequest(this.requestService.generateRequestId(), endpointURL, `${item1.self} \n ${item2.self}`, options)),
|
map((endpointURL: string) => new PostRequest(this.requestService.generateRequestId(), endpointURL, `${item1.self} \n ${item2.self}`, options)),
|
||||||
configureRequest(this.requestService),
|
configureRequest(this.requestService),
|
||||||
@@ -267,7 +267,7 @@ export class RelationshipService extends DataService<Relationship> {
|
|||||||
);
|
);
|
||||||
}))
|
}))
|
||||||
}),
|
}),
|
||||||
map((relationships: Relationship[]) => relationships.find((relationship => hasValue(relationship)))),
|
map((relationships: Relationship[]) => relationships.find((relationship => hasValue(relationship))))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -308,6 +308,7 @@ export class RequestService {
|
|||||||
*/
|
*/
|
||||||
hasByHref(href: string): boolean {
|
hasByHref(href: string): boolean {
|
||||||
let result = false;
|
let result = false;
|
||||||
|
/* NB: that this is only a solution because the select method is synchronous, see: https://github.com/ngrx/store/issues/296#issuecomment-269032571*/
|
||||||
this.getByHref(href).pipe(
|
this.getByHref(href).pipe(
|
||||||
take(1)
|
take(1)
|
||||||
).subscribe((requestEntry: RequestEntry) => result = this.isValid(requestEntry));
|
).subscribe((requestEntry: RequestEntry) => result = this.isValid(requestEntry));
|
||||||
|
@@ -48,11 +48,12 @@
|
|||||||
aria-hidden="true"></span>
|
aria-hidden="true"></span>
|
||||||
<span class="sr-only">{{ ('submission.sections.describe.relationship-lookup.loading' | translate) }}</span>
|
<span class="sr-only">{{ ('submission.sections.describe.relationship-lookup.loading' | translate) }}</span>
|
||||||
</button>
|
</button>
|
||||||
<button *ngIf="!selectAllLoading" id="resultdropdown" type="button"
|
<button id="resultdropdown" type="button"
|
||||||
ngbDropdownToggle
|
ngbDropdownToggle
|
||||||
class="btn btn-outline-secondary dropdown-toggle-split"
|
class="btn btn-outline-secondary dropdown-toggle-split"
|
||||||
data-toggle="dropdown" aria-haspopup="true"
|
data-toggle="dropdown" aria-haspopup="true"
|
||||||
aria-expanded="false">
|
aria-expanded="false"
|
||||||
|
[hidden]="selectAllLoading">
|
||||||
<span class="sr-only">{{ ('submission.sections.describe.relationship-lookup.toggle-dropdown' | translate) }}</span>
|
<span class="sr-only">{{ ('submission.sections.describe.relationship-lookup.toggle-dropdown' | translate) }}</span>
|
||||||
</button>
|
</button>
|
||||||
<div ngbDropdownMenu aria-labelledby="resultdropdown">
|
<div ngbDropdownMenu aria-labelledby="resultdropdown">
|
||||||
|
@@ -2,13 +2,13 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
|
|||||||
import { PaginatedList } from '../../../../../core/data/paginated-list';
|
import { PaginatedList } from '../../../../../core/data/paginated-list';
|
||||||
import { SearchResult } from '../../../../search/search-result.model';
|
import { SearchResult } from '../../../../search/search-result.model';
|
||||||
import { RemoteData } from '../../../../../core/data/remote-data';
|
import { RemoteData } from '../../../../../core/data/remote-data';
|
||||||
import { Observable, ReplaySubject } from 'rxjs';
|
import { from, Observable, ReplaySubject } from 'rxjs';
|
||||||
import { SearchService } from '../../../../../core/shared/search/search.service';
|
import { SearchService } from '../../../../../core/shared/search/search.service';
|
||||||
import { PaginatedSearchOptions } from '../../../../search/paginated-search-options.model';
|
import { PaginatedSearchOptions } from '../../../../search/paginated-search-options.model';
|
||||||
import { DSpaceObject } from '../../../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../../../core/shared/dspace-object.model';
|
||||||
import { PaginationComponentOptions } from '../../../../pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../../../../pagination/pagination-component-options.model';
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { hasValue, isNotEmpty } from '../../../../empty.util';
|
import { hasValue, hasValueOperator, isNotEmpty } from '../../../../empty.util';
|
||||||
import { concat, map, mergeMap, multicast, switchMap, take, takeWhile, tap } from 'rxjs/operators';
|
import { concat, map, mergeMap, multicast, switchMap, take, takeWhile, tap } from 'rxjs/operators';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { SEARCH_CONFIG_SERVICE } from '../../../../../+my-dspace-page/my-dspace-page.component';
|
import { SEARCH_CONFIG_SERVICE } from '../../../../../+my-dspace-page/my-dspace-page.component';
|
||||||
@@ -117,12 +117,24 @@ export class DsDynamicLookupRelationModalComponent implements OnInit, OnDestroy
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
selectPage(page: SearchResult<DSpaceObject>[]) {
|
selectPage(page: SearchResult<Item>[]) {
|
||||||
|
this.selection$
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe((selection: SearchResult<Item>[]) => {
|
||||||
|
const filteredPage = page.filter((pageItem) => selection.findIndex((selected) => selected.equals(pageItem)) < 0)
|
||||||
|
this.select(...filteredPage);
|
||||||
|
});
|
||||||
this.selectableListService.select(this.listId, page);
|
this.selectableListService.select(this.listId, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
deselectPage(page: SearchResult<DSpaceObject>[]) {
|
deselectPage(page: SearchResult<Item>[]) {
|
||||||
this.allSelected = false;
|
this.allSelected = false;
|
||||||
|
this.selection$
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe((selection: SearchResult<Item>[]) => {
|
||||||
|
const filteredPage = page.filter((pageItem) => selection.findIndex((selected) => selected.equals(pageItem)) >= 0)
|
||||||
|
this.deselect(...filteredPage);
|
||||||
|
});
|
||||||
this.selectableListService.deselect(this.listId, page);
|
this.selectableListService.deselect(this.listId, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,62 +144,84 @@ export class DsDynamicLookupRelationModalComponent implements OnInit, OnDestroy
|
|||||||
const fullPagination = Object.assign(new PaginationComponentOptions(), {
|
const fullPagination = Object.assign(new PaginationComponentOptions(), {
|
||||||
query: this.searchQuery,
|
query: this.searchQuery,
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: Number.POSITIVE_INFINITY
|
pageSize: 9999
|
||||||
});
|
});
|
||||||
const fullSearchConfig = Object.assign(this.searchConfig, { pagination: fullPagination });
|
const fullSearchConfig = Object.assign(this.searchConfig, { pagination: fullPagination });
|
||||||
const results = this.searchService.search(fullSearchConfig);
|
const results$ = this.searchService.search(fullSearchConfig) as Observable<RemoteData<PaginatedList<SearchResult<Item>>>>;
|
||||||
results.pipe(
|
results$.pipe(
|
||||||
getSucceededRemoteData(),
|
getSucceededRemoteData(),
|
||||||
map((resultsRD) => resultsRD.payload.page),
|
map((resultsRD) => resultsRD.payload.page),
|
||||||
tap(() => this.selectAllLoading = false),
|
tap(() => this.selectAllLoading = false),
|
||||||
).subscribe((results) =>
|
).subscribe((results) => {
|
||||||
this.selectableListService.select(this.listId, results)
|
this.selection$
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe((selection: SearchResult<Item>[]) => {
|
||||||
|
const filteredResults = results.filter((pageItem) => selection.findIndex((selected) => selected.equals(pageItem)) < 0);
|
||||||
|
this.select(...filteredResults);
|
||||||
|
});
|
||||||
|
this.selectableListService.select(this.listId, results);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
deselectAll() {
|
deselectAll() {
|
||||||
this.allSelected = false;
|
this.allSelected = false;
|
||||||
|
this.selection$
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe((selection: SearchResult<Item>[]) => this.deselect(...selection));
|
||||||
this.selectableListService.deselectAll(this.listId);
|
this.selectableListService.deselectAll(this.listId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
select(selectableObject: SearchResult<Item>) {
|
select(...selectableObjects: SearchResult<Item>[]) {
|
||||||
setTimeout(() => this.itemRD$
|
setTimeout(() => this.itemRD$
|
||||||
.pipe(
|
.pipe(
|
||||||
getSucceededRemoteData(),
|
getSucceededRemoteData(),
|
||||||
mergeMap((itemRD: RemoteData<Item>) => {
|
switchMap((itemRD: RemoteData<Item>) => {
|
||||||
const type1: string = itemRD.payload.firstMetadataValue('relationship.type');
|
const type1: string = itemRD.payload.firstMetadataValue('relationship.type');
|
||||||
const type2: string = selectableObject.indexableObject.firstMetadataValue('relationship.type');
|
return from(selectableObjects).pipe(
|
||||||
|
mergeMap((object) => {
|
||||||
|
const type2: string = object.indexableObject.firstMetadataValue('relationship.type');
|
||||||
return this.relationshipTypeService.getRelationshipTypeByLabelAndTypes(this.relationship.relationshipType, type1, type2)
|
return this.relationshipTypeService.getRelationshipTypeByLabelAndTypes(this.relationship.relationshipType, type1, type2)
|
||||||
.pipe(
|
.pipe(
|
||||||
mergeMap((type: RelationshipType) => {
|
mergeMap((type: RelationshipType) => {
|
||||||
const isSwitched = type.rightLabel === this.relationship.relationshipType;
|
const isSwitched = type.rightLabel === this.relationship.relationshipType;
|
||||||
if (isSwitched) {
|
if (isSwitched) {
|
||||||
return this.relationshipService.addRelationship(type.id, selectableObject.indexableObject, itemRD.payload);
|
return this.relationshipService.addRelationship(type.id, object.indexableObject, itemRD.payload);
|
||||||
} else {
|
} else {
|
||||||
return this.relationshipService.addRelationship(type.id, itemRD.payload, selectableObject.indexableObject);
|
return this.relationshipService.addRelationship(type.id, itemRD.payload, object.indexableObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
).pipe(take(1));
|
||||||
|
}));
|
||||||
}),
|
}),
|
||||||
take(1)
|
).subscribe(), 0
|
||||||
)
|
);
|
||||||
.subscribe(), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
deselect(selectableObject: SearchResult<Item>) {
|
deselect(...selectableObjects: SearchResult<Item>[]) {
|
||||||
setTimeout(() => this.itemRD$.pipe(
|
setTimeout(() => this.itemRD$.pipe(
|
||||||
getSucceededRemoteData(),
|
getSucceededRemoteData(),
|
||||||
switchMap((itemRD: RemoteData<Item>) => this.relationshipService.getRelationshipByItemsAndLabel(itemRD.payload, selectableObject.indexableObject, this.relationship.relationshipType)),
|
switchMap((itemRD: RemoteData<Item>) => {
|
||||||
switchMap((relationship: Relationship) => this.relationshipService.deleteRelationship(relationship.id)),
|
return from(selectableObjects).pipe(
|
||||||
|
tap(t => console.log(itemRD)),
|
||||||
|
mergeMap((object) => this.relationshipService.getRelationshipByItemsAndLabel(itemRD.payload, object.indexableObject, this.relationship.relationshipType)),
|
||||||
|
take(1),
|
||||||
|
hasValueOperator(),
|
||||||
|
mergeMap((relationship: Relationship) => this.relationshipService.deleteRelationship(relationship.id))
|
||||||
|
)
|
||||||
|
}),
|
||||||
take(1),
|
take(1),
|
||||||
).subscribe(), 0);
|
).subscribe(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy()
|
||||||
if (hasValue(this.subscription)) {
|
:
|
||||||
|
void {
|
||||||
|
if (hasValue(this.subscription)
|
||||||
|
) {
|
||||||
this.subscription.unsubscribe();
|
this.subscription.unsubscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user