import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { BehaviorSubject, Observable, of as observableOf, Subscription } from 'rxjs'; import { catchError, filter, first, flatMap, map, take } from 'rxjs/operators'; import { PaginatedList } from '../../../core/data/paginated-list'; import { getFirstSucceededRemoteDataPayload, getFirstSucceededRemoteDataWithNotEmptyPayload } from '../../../core/shared/operators'; import { Item } from '../../../core/shared/item.model'; import { followLink } from '../../../shared/utils/follow-link-config.model'; import { LinkService } from '../../../core/cache/builders/link.service'; import { Bundle } from '../../../core/shared/bundle.model'; import { hasValue, isNotEmpty } from '../../../shared/empty.util'; import { Bitstream } from '../../../core/shared/bitstream.model'; import { FindListOptions } from '../../../core/data/request.models'; /** * Interface for a bundle's bitstream map entry */ interface BundleBitstreamsMapEntry { id: string; bitstreams: Observable> } @Component({ selector: 'ds-item-authorizations', templateUrl: './item-authorizations.component.html' }) /** * Component that handles the item Authorizations */ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { /** * A map that contains all bitstream of the item's bundles * @type {Observable>>>} */ public bundleBitstreamsMap: Map>> = new Map>>(); /** * The list of bundle for the item * @type {Observable>} */ private bundles$: BehaviorSubject = new BehaviorSubject([]); /** * The target editing item * @type {Observable} */ private item$: Observable; /** * Array to track all subscriptions and unsubscribe them onDestroy * @type {Array} */ private subs: Subscription[] = []; /** * Initialize instance variables * * @param {LinkService} linkService * @param {ActivatedRoute} route */ constructor( private linkService: LinkService, private route: ActivatedRoute ) { } /** * Initialize the component, setting up the bundle and bitstream within the item */ ngOnInit(): void { this.item$ = this.route.data.pipe( map((data) => data.dso), getFirstSucceededRemoteDataWithNotEmptyPayload(), map((item: Item) => this.linkService.resolveLink( item, followLink('bundles', new FindListOptions(), true, followLink('bitstreams')) )) ) as Observable; const bundles$: Observable> = this.item$.pipe( filter((item: Item) => isNotEmpty(item.bundles)), flatMap((item: Item) => item.bundles), getFirstSucceededRemoteDataWithNotEmptyPayload(), catchError((error) => { console.error(error); return observableOf(new PaginatedList(null, [])) }) ); this.subs.push( bundles$.pipe( take(1), map((list: PaginatedList) => list.page) ).subscribe((bundles: Bundle[]) => { this.bundles$.next(bundles); }), bundles$.pipe( take(1), flatMap((list: PaginatedList) => list.page), map((bundle: Bundle) => ({ id: bundle.id, bitstreams: this.getBundleBitstreams(bundle) })) ).subscribe((entry: BundleBitstreamsMapEntry) => { this.bundleBitstreamsMap.set(entry.id, entry.bitstreams) }) ) } /** * Return the item's UUID */ getItemUUID(): Observable { return this.item$.pipe( map((item: Item) => item.id), first((UUID: string) => isNotEmpty(UUID)) ) } /** * Return all item's bundles * * @return an observable that emits all item's bundles */ getItemBundles(): Observable { return this.bundles$.asObservable(); } /** * Return all bundle's bitstreams * * @return an observable that emits all item's bundles */ private getBundleBitstreams(bundle: Bundle): Observable> { return bundle.bitstreams.pipe( getFirstSucceededRemoteDataPayload(), catchError((error) => { console.error(error); return observableOf(new PaginatedList(null, [])) }) ) } /** * Unsubscribe from all subscriptions */ ngOnDestroy(): void { this.subs .filter((subscription) => hasValue(subscription)) .forEach((subscription) => subscription.unsubscribe()) } }