diff --git a/src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.ts b/src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.ts index c4d3f07167..61494c983a 100644 --- a/src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.ts +++ b/src/app/+collection-page/collection-item-mapper/collection-item-mapper.component.ts @@ -7,11 +7,12 @@ import { ActivatedRoute, Router } from '@angular/router'; import { RemoteData } from '../../core/data/remote-data'; import { Collection } from '../../core/shared/collection.model'; import { PaginatedList } from '../../core/data/paginated-list.model'; -import { filter, map, startWith, switchMap, take } from 'rxjs/operators'; +import { map, startWith, switchMap, take } from 'rxjs/operators'; import { - getRemoteDataPayload, - getFirstSucceededRemoteData, - toDSpaceObjectListRD + getRemoteDataPayload, + getFirstSucceededRemoteData, + toDSpaceObjectListRD, + getFirstCompletedRemoteData, getAllSucceededRemoteData } from '../../core/shared/operators'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model'; @@ -20,7 +21,7 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { ItemDataService } from '../../core/data/item-data.service'; import { TranslateService } from '@ngx-translate/core'; import { CollectionDataService } from '../../core/data/collection-data.service'; -import { hasValue, isNotEmpty } from '../../shared/empty.util'; +import { isNotEmpty } from '../../shared/empty.util'; import { SEARCH_CONFIG_SERVICE } from '../../+my-dspace-page/my-dspace-page.component'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model'; @@ -53,7 +54,7 @@ export class CollectionItemMapperComponent implements OnInit { * A view on the tabset element * Used to switch tabs programmatically */ - @ViewChild('tabs') tabs; + @ViewChild('tabs', {static: false}) tabs; /** * The collection to map items to @@ -108,13 +109,12 @@ export class CollectionItemMapperComponent implements OnInit { } ngOnInit(): void { - this.collectionRD$ = this.route.data.pipe( - take(1), - map((data) => data.dso), + this.collectionRD$ = this.route.parent.data.pipe( + map((data) => data.dso as RemoteData), + getFirstSucceededRemoteData() ); this.collectionName$ = this.collectionRD$.pipe( - filter((rd: RemoteData) => hasValue(rd)), map((rd: RemoteData) => { return this.dsoNameService.getName(rd.payload); }) @@ -136,27 +136,27 @@ export class CollectionItemMapperComponent implements OnInit { ); this.collectionItemsRD$ = collectionAndOptions$.pipe( switchMap(([collectionRD, options, shouldUpdate]) => { - if (shouldUpdate) { + if (shouldUpdate === true) { this.shouldUpdate$.next(false); } return this.itemDataService.findAllByHref(collectionRD.payload._links.mappedItems.href, Object.assign(options, { sort: this.defaultSortOptions - }),!shouldUpdate, true, followLink('owningCollection')); + }),!shouldUpdate, false, followLink('owningCollection')).pipe( + getAllSucceededRemoteData() + ) }) ); this.mappedItemsRD$ = collectionAndOptions$.pipe( switchMap(([collectionRD, options, shouldUpdate]) => { - if (shouldUpdate) { - return this.searchService.search(Object.assign(new PaginatedSearchOptions(options), { - query: this.buildQuery(collectionRD.payload.id, options.query), - scope: undefined, - dsoTypes: [DSpaceObjectType.ITEM], - sort: this.defaultSortOptions - }), 10000).pipe( - toDSpaceObjectListRD(), - startWith(undefined) - ); - } + return this.searchService.search(Object.assign(new PaginatedSearchOptions(options), { + query: this.buildQuery(collectionRD.payload.id, options.query), + scope: undefined, + dsoTypes: [DSpaceObjectType.ITEM], + sort: this.defaultSortOptions + }), 10000).pipe( + toDSpaceObjectListRD(), + startWith(undefined) + ); }) ); } @@ -171,8 +171,17 @@ export class CollectionItemMapperComponent implements OnInit { getFirstSucceededRemoteData(), map((collectionRD: RemoteData) => collectionRD.payload), switchMap((collection: Collection) => - observableCombineLatest(ids.map((id: string) => - remove ? this.itemDataService.removeMappingFromCollection(id, collection.id) : this.itemDataService.mapToCollection(id, collection._links.self.href) + observableCombineLatest(ids.map((id: string) => { + if (remove) { + return this.itemDataService.removeMappingFromCollection(id, collection.id).pipe( + getFirstCompletedRemoteData() + ); + } else { + return this.itemDataService.mapToCollection(id, collection._links.self.href).pipe( + getFirstCompletedRemoteData() + ); + } + } )) ) ); @@ -200,6 +209,7 @@ export class CollectionItemMapperComponent implements OnInit { successMessages.subscribe(([head, content]) => { this.notificationsService.success(head, content); }); + this.shouldUpdate$.next(true); } if (unsuccessful.length > 0) { const unsuccessMessages = observableCombineLatest( @@ -211,8 +221,6 @@ export class CollectionItemMapperComponent implements OnInit { this.notificationsService.error(head, content); }); } - // Force an update on all lists and switch back to the first tab - this.shouldUpdate$.next(true); this.switchToFirstTab(); }); } diff --git a/src/app/+collection-page/collection-page-routing.module.ts b/src/app/+collection-page/collection-page-routing.module.ts index 9d1df9b95d..7e44883a53 100644 --- a/src/app/+collection-page/collection-page-routing.module.ts +++ b/src/app/+collection-page/collection-page-routing.module.ts @@ -9,7 +9,6 @@ import { CreateCollectionPageGuard } from './create-collection-page/create-colle import { DeleteCollectionPageComponent } from './delete-collection-page/delete-collection-page.component'; import { EditItemTemplatePageComponent } from './edit-item-template-page/edit-item-template-page.component'; import { ItemTemplatePageResolver } from './edit-item-template-page/item-template-page.resolver'; -import { CollectionItemMapperComponent } from './collection-item-mapper/collection-item-mapper.component'; import { CollectionBreadcrumbResolver } from '../core/breadcrumbs/collection-breadcrumb.resolver'; import { DSOBreadcrumbsService } from '../core/breadcrumbs/dso-breadcrumbs.service'; import { LinkService } from '../core/cache/builders/link.service'; @@ -65,12 +64,6 @@ import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; path: '', component: CollectionPageComponent, pathMatch: 'full', - }, - { - path: '/edit/mapper', - component: CollectionItemMapperComponent, - pathMatch: 'full', - canActivate: [AuthenticatedGuard] } ], data: { diff --git a/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts b/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts index 6f55c6e9c3..e712ff2e35 100644 --- a/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts +++ b/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts @@ -13,7 +13,7 @@ import { getRemoteDataPayload, getFirstSucceededRemoteData, toDSpaceObjectListRD, - getAllSucceededRemoteData + getAllSucceededRemoteData, getFirstCompletedRemoteData } from '../../../core/shared/operators'; import { ActivatedRoute, Router } from '@angular/router'; import { filter, map, startWith, switchMap, take } from 'rxjs/operators'; @@ -135,7 +135,8 @@ export class ItemCollectionMapperComponent implements OnInit { const owningCollectionRD$ = this.itemRD$.pipe( getFirstSucceededRemoteDataPayload(), - switchMap((item: Item) => this.collectionDataService.findOwningCollectionFor(item)) + switchMap((item: Item) => this.collectionDataService.findOwningCollectionFor(item)), + getAllSucceededRemoteData(), ); const itemCollectionsAndOptions$ = observableCombineLatest( this.itemCollectionsRD$, @@ -175,7 +176,12 @@ export class ItemCollectionMapperComponent implements OnInit { // Map the item to the collections found in ids, excluding the collections the item is already mapped to const responses$ = itemIdAndExcludingIds$.pipe( - switchMap(([itemId, excludingIds]) => observableCombineLatest(this.filterIds(ids, excludingIds).map((id: string) => this.itemDataService.mapToCollection(itemId, id)))) + switchMap(([itemId, excludingIds]) => + observableCombineLatest( + this.filterIds(ids, excludingIds).map((id: string) => + this.itemDataService.mapToCollection(itemId, id).pipe(getFirstCompletedRemoteData()) + )) + ) ); this.showNotifications(responses$, 'item.edit.item-mapper.notifications.add'); @@ -189,7 +195,11 @@ export class ItemCollectionMapperComponent implements OnInit { const responses$ = this.itemRD$.pipe( getFirstSucceededRemoteData(), map((itemRD: RemoteData) => itemRD.payload.id), - switchMap((itemId: string) => observableCombineLatest(ids.map((id: string) => this.itemDataService.removeMappingFromCollection(itemId, id)))) + switchMap((itemId: string) => observableCombineLatest( + ids.map((id: string) => + this.itemDataService.removeMappingFromCollection(itemId, id).pipe(getFirstCompletedRemoteData()) + )) + ) ); this.showNotifications(responses$, 'item.edit.item-mapper.notifications.remove');