import { Component, EventEmitter, Input, OnInit, Output, ViewChild, ViewContainerRef } from '@angular/core'; import { Bundle } from '../../../../core/shared/bundle.model'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { Observable } from 'rxjs/internal/Observable'; import { FieldUpdates } from '../../../../core/data/object-updates/object-updates.reducer'; import { toBitstreamsArray } from '../../../../core/shared/item-bitstreams-utils'; import { map, switchMap, tap } from 'rxjs/operators'; import { Bitstream } from '../../../../core/shared/bitstream.model'; import { Item } from '../../../../core/shared/item.model'; import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { RemoteData } from '../../../../core/data/remote-data'; import { PaginatedList } from '../../../../core/data/paginated-list'; import { BundleDataService } from '../../../../core/data/bundle-data.service'; import { PaginatedSearchOptions } from '../../../../+search-page/paginated-search-options.model'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { combineLatest as observableCombineLatest } from 'rxjs'; @Component({ selector: 'ds-item-edit-bitstream-bundle', styleUrls: ['../item-bitstreams.component.scss'], templateUrl: './item-edit-bitstream-bundle.component.html', }) /** * Component that displays a single bundle of an item on the item bitstreams edit page */ export class ItemEditBitstreamBundleComponent implements OnInit { /** * The view on the bundle information and bitstreams */ @ViewChild('bundleView') bundleView; /** * The bundle to display bitstreams for */ @Input() bundle: Bundle; /** * The item the bundle belongs to */ @Input() item: Item; /** * The bitstreams within this bundle retrieved from the REST API */ bitstreamsRD$: Observable<RemoteData<PaginatedList<Bitstream>>>; /** * The updates to the current bundle */ updates$: Observable<FieldUpdates>; /** * The amount of one bitstreams one "batch" resembles * The user is able to increase the amount of bitstreams displayed per bundle by this batch size until all are shown */ batchSize = 10; /** * The page options to use for fetching the bitstreams */ bitstreamsOptions = { id: 'bitstreams-pagination-options', currentPage: 1, pageSize: this.batchSize } as any; /** * The current amount of bitstreams to display for this bundle * Starts off with just one batch */ currentSize$ = new BehaviorSubject<number>(this.batchSize); /** * Are we currently loading more bitstreams? */ isLoadingMore$: Observable<boolean>; constructor(private objectUpdatesService: ObjectUpdatesService, private bundleService: BundleDataService, private viewContainerRef: ViewContainerRef) { } ngOnInit(): void { this.bitstreamsRD$ = this.currentSize$.pipe( switchMap((size: number) => this.bundleService.getBitstreams(this.bundle.id, new PaginatedSearchOptions({pagination: Object.assign({}, this.bitstreamsOptions, { pageSize: size })}))) ); this.updates$ = this.bitstreamsRD$.pipe( toBitstreamsArray(), tap((bitstreams: Bitstream[]) => this.objectUpdatesService.initialize(this.bundle.self, bitstreams, new Date(), true)), switchMap((bitstreams: Bitstream[]) => this.objectUpdatesService.getFieldUpdatesByCustomOrder(this.bundle.self, bitstreams)) ); this.isLoadingMore$ = observableCombineLatest(this.currentSize$, this.bitstreamsRD$).pipe( map(([size, bitstreamsRD]: [number, RemoteData<PaginatedList<Bitstream>>]) => size > bitstreamsRD.payload.page.length) ); this.viewContainerRef.createEmbeddedView(this.bundleView); } /** * A bitstream was moved, send updates to the store * @param event */ drop(event: CdkDragDrop<any>) { this.objectUpdatesService.saveMoveFieldUpdate(this.bundle.self, event.previousIndex, event.currentIndex); } /** * Load more bitstreams (current size + batchSize) */ loadMore() { this.currentSize$.next(this.currentSize$.value + this.batchSize); } /** * Load all bitstreams */ loadAll() { this.currentSize$.next(9999); } }