1+ import { isEqual } from 'lodash' ;
2+ import { DSONameService } from '../../../core/breadcrumbs/dso-name.service' ;
13import { Component , OnDestroy , OnInit } from '@angular/core' ;
24import { ActivatedRoute } from '@angular/router' ;
35
@@ -6,7 +8,8 @@ import { catchError, filter, first, map, mergeMap, take } from 'rxjs/operators';
68
79import { buildPaginatedList , PaginatedList } from '../../../core/data/paginated-list.model' ;
810import {
9- getFirstSucceededRemoteDataPayload , getFirstSucceededRemoteDataWithNotEmptyPayload ,
11+ getFirstSucceededRemoteDataPayload ,
12+ getFirstSucceededRemoteDataWithNotEmptyPayload ,
1013} from '../../../core/shared/operators' ;
1114import { Item } from '../../../core/shared/item.model' ;
1215import { followLink } from '../../../shared/utils/follow-link-config.model' ;
@@ -25,7 +28,8 @@ interface BundleBitstreamsMapEntry {
2528
2629@Component ( {
2730 selector : 'ds-item-authorizations' ,
28- templateUrl : './item-authorizations.component.html'
31+ templateUrl : './item-authorizations.component.html' ,
32+ styleUrls :[ './item-authorizations.component.scss' ]
2933} )
3034/**
3135 * Component that handles the item Authorizations
@@ -36,13 +40,13 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
3640 * A map that contains all bitstream of the item's bundles
3741 * @type {Observable<Map<string, Observable<PaginatedList<Bitstream>>>> }
3842 */
39- public bundleBitstreamsMap : Map < string , Observable < PaginatedList < Bitstream > > > = new Map < string , Observable < PaginatedList < Bitstream > > > ( ) ;
43+ public bundleBitstreamsMap : Map < string , BitstreamMapValue > = new Map < string , BitstreamMapValue > ( ) ;
4044
4145 /**
42- * The list of bundle for the item
46+ * The list of all bundles for the item
4347 * @type {Observable<PaginatedList<Bundle>> }
4448 */
45- private bundles$ : BehaviorSubject < Bundle [ ] > = new BehaviorSubject < Bundle [ ] > ( [ ] ) ;
49+ bundles$ : BehaviorSubject < Bundle [ ] > = new BehaviorSubject < Bundle [ ] > ( [ ] ) ;
4650
4751 /**
4852 * The target editing item
@@ -56,32 +60,102 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
5660 */
5761 private subs : Subscription [ ] = [ ] ;
5862
63+ /**
64+ * The size of the bundles to be loaded on demand
65+ * @type {number }
66+ */
67+ bundlesPerPage = 6 ;
68+
69+ /**
70+ * The number of current page
71+ * @type {number }
72+ */
73+ bundlesPageSize = 1 ;
74+
75+ /**
76+ * The flag to show or not the 'Load more' button
77+ * based on the condition if all the bundles are loaded or not
78+ * @type {boolean }
79+ */
80+ allBundlesLoaded = false ;
81+
82+ /**
83+ * Initial size of loaded bitstreams
84+ * The size of incrementation used in bitstream pagination
85+ */
86+ bitstreamSize = 4 ;
87+
88+ /**
89+ * The size of the loaded bitstremas at a certain moment
90+ * @private
91+ */
92+ private bitstreamPageSize = 4 ;
93+
5994 /**
6095 * Initialize instance variables
6196 *
6297 * @param {LinkService } linkService
6398 * @param {ActivatedRoute } route
99+ * @param nameService
64100 */
65101 constructor (
66102 private linkService : LinkService ,
67- private route : ActivatedRoute
103+ private route : ActivatedRoute ,
104+ private nameService : DSONameService
68105 ) {
69106 }
70107
71108 /**
72109 * Initialize the component, setting up the bundle and bitstream within the item
73110 */
74111 ngOnInit ( ) : void {
112+ this . getBundlesPerItem ( ) ;
113+ }
114+
115+ /**
116+ * Return the item's UUID
117+ */
118+ getItemUUID ( ) : Observable < string > {
119+ return this . item$ . pipe (
120+ map ( ( item : Item ) => item . id ) ,
121+ first ( ( UUID : string ) => isNotEmpty ( UUID ) )
122+ ) ;
123+ }
124+
125+ /**
126+ * Return the item's name
127+ */
128+ getItemName ( ) : Observable < string > {
129+ return this . item$ . pipe (
130+ map ( ( item : Item ) => this . nameService . getName ( item ) )
131+ ) ;
132+ }
133+
134+ /**
135+ * Return all item's bundles
136+ *
137+ * @return an observable that emits all item's bundles
138+ */
139+ getItemBundles ( ) : Observable < Bundle [ ] > {
140+ return this . bundles$ . asObservable ( ) ;
141+ }
142+
143+ /**
144+ * Get all bundles per item
145+ * and all the bitstreams per bundle
146+ * @param page number of current page
147+ */
148+ getBundlesPerItem ( page : number = 1 ) {
75149 this . item$ = this . route . data . pipe (
76150 map ( ( data ) => data . dso ) ,
77151 getFirstSucceededRemoteDataWithNotEmptyPayload ( ) ,
78152 map ( ( item : Item ) => this . linkService . resolveLink (
79153 item ,
80- followLink ( 'bundles' , { } , followLink ( 'bitstreams' ) )
154+ followLink ( 'bundles' , { findListOptions : { currentPage : page , elementsPerPage : this . bundlesPerPage } } , followLink ( 'bitstreams' ) )
81155 ) )
82156 ) as Observable < Item > ;
83157
84- const bundles$ : Observable < PaginatedList < Bundle > > = this . item$ . pipe (
158+ const bundles$ : Observable < PaginatedList < Bundle > > = this . item$ . pipe (
85159 filter ( ( item : Item ) => isNotEmpty ( item . bundles ) ) ,
86160 mergeMap ( ( item : Item ) => item . bundles ) ,
87161 getFirstSucceededRemoteDataWithNotEmptyPayload ( ) ,
@@ -96,37 +170,36 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
96170 take ( 1 ) ,
97171 map ( ( list : PaginatedList < Bundle > ) => list . page )
98172 ) . subscribe ( ( bundles : Bundle [ ] ) => {
99- this . bundles$ . next ( bundles ) ;
173+ if ( isEqual ( bundles . length , 0 ) || bundles . length < this . bundlesPerPage ) {
174+ this . allBundlesLoaded = true ;
175+ }
176+ if ( isEqual ( page , 1 ) ) {
177+ this . bundles$ . next ( bundles ) ;
178+ } else {
179+ this . bundles$ . next ( this . bundles$ . getValue ( ) . concat ( bundles ) ) ;
180+ }
100181 } ) ,
101182 bundles$ . pipe (
102183 take ( 1 ) ,
103184 mergeMap ( ( list : PaginatedList < Bundle > ) => list . page ) ,
104185 map ( ( bundle : Bundle ) => ( { id : bundle . id , bitstreams : this . getBundleBitstreams ( bundle ) } ) )
105186 ) . subscribe ( ( entry : BundleBitstreamsMapEntry ) => {
106- this . bundleBitstreamsMap . set ( entry . id , entry . bitstreams ) ;
187+ let bitstreamMapValues : BitstreamMapValue = {
188+ isCollapsed : true ,
189+ allBitstreamsLoaded : false ,
190+ bitstreams : null
191+ } ;
192+ bitstreamMapValues . bitstreams = entry . bitstreams . pipe (
193+ map ( ( b : PaginatedList < Bitstream > ) => {
194+ bitstreamMapValues . allBitstreamsLoaded = b ?. page . length < this . bitstreamSize ;
195+ return [ ...b . page . slice ( 0 , this . bitstreamSize ) ] ;
196+ } )
197+ ) ;
198+ this . bundleBitstreamsMap . set ( entry . id , bitstreamMapValues ) ;
107199 } )
108200 ) ;
109201 }
110202
111- /**
112- * Return the item's UUID
113- */
114- getItemUUID ( ) : Observable < string > {
115- return this . item$ . pipe (
116- map ( ( item : Item ) => item . id ) ,
117- first ( ( UUID : string ) => isNotEmpty ( UUID ) )
118- ) ;
119- }
120-
121- /**
122- * Return all item's bundles
123- *
124- * @return an observable that emits all item's bundles
125- */
126- getItemBundles ( ) : Observable < Bundle [ ] > {
127- return this . bundles$ . asObservable ( ) ;
128- }
129-
130203 /**
131204 * Return all bundle's bitstreams
132205 *
@@ -142,6 +215,46 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
142215 ) ;
143216 }
144217
218+ /**
219+ * Changes the collapsible state of the area that contains the bitstream list
220+ * @param bundleId Id of bundle responsible for the requested bitstreams
221+ */
222+ collapseArea ( bundleId : string ) {
223+ this . bundleBitstreamsMap . get ( bundleId ) . isCollapsed = ! this . bundleBitstreamsMap . get ( bundleId ) . isCollapsed ;
224+ }
225+
226+ /**
227+ * Loads as much bundles as initial value of bundleSize to be displayed
228+ */
229+ onBundleLoad ( ) {
230+ this . bundlesPageSize ++ ;
231+ this . getBundlesPerItem ( this . bundlesPageSize ) ;
232+ }
233+
234+ /**
235+ * Calculates the bitstreams that are going to be loaded on demand,
236+ * based on the number configured on this.bitstreamSize.
237+ * @param bundle parent of bitstreams that are requested to be shown
238+ * @returns Subscription
239+ */
240+ onBitstreamsLoad ( bundle : Bundle ) {
241+ return this . getBundleBitstreams ( bundle ) . subscribe ( ( res : PaginatedList < Bitstream > ) => {
242+ let nextBitstreams = res ?. page . slice ( this . bitstreamPageSize , this . bitstreamPageSize + this . bitstreamSize ) ;
243+ let bitstreamsToShow = this . bundleBitstreamsMap . get ( bundle . id ) . bitstreams . pipe (
244+ map ( ( existingBits : Bitstream [ ] ) => {
245+ return [ ... existingBits , ...nextBitstreams ] ;
246+ } )
247+ ) ;
248+ this . bitstreamPageSize = this . bitstreamPageSize + this . bitstreamSize ;
249+ let bitstreamMapValues : BitstreamMapValue = {
250+ bitstreams : bitstreamsToShow ,
251+ isCollapsed : this . bundleBitstreamsMap . get ( bundle . id ) . isCollapsed ,
252+ allBitstreamsLoaded : res ?. page . length <= this . bitstreamPageSize
253+ } ;
254+ this . bundleBitstreamsMap . set ( bundle . id , bitstreamMapValues ) ;
255+ } ) ;
256+ }
257+
145258 /**
146259 * Unsubscribe from all subscriptions
147260 */
@@ -151,3 +264,9 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
151264 . forEach ( ( subscription ) => subscription . unsubscribe ( ) ) ;
152265 }
153266}
267+
268+ export interface BitstreamMapValue {
269+ bitstreams : Observable < Bitstream [ ] > ;
270+ isCollapsed : boolean ;
271+ allBitstreamsLoaded : boolean ;
272+ }
0 commit comments