Skip to content

Commit ff304f3

Browse files
FrancescoMolinaroalisaismailati
authored andcommitted
Prevent request with page size of 9999 (#3694)
* [DURACOM-304] Refactored item-bitstreams.component by removing page size of 9999 * [DURACOM-304] Refactored edit-bitstream-page.component by removing page size of 9999 * [DURACOM-304] Refactored scripts-select.component by using infinite scroll instead of page size 9999 * [DURACOM-304] Refactored dynamic-list.component.ts by removing page size of 9999 * [DURACOM-304] Refactored relationship-type-data.service.ts by removing page size of 9999 * [DURACOM-304] removed unneeded selectAll method (dynamic-lookup-relation-search-tab.component) * [DURACOM-304] Refactored submission-section-cc-licenses.component.ts by removing page size of 9999 * [DURACOM-304] lint fix * [DURACOM-304] test fix * [DURACOM-304] fix accessibility issue on scripts-select * [DURACOM-304] Refactor of bundle-data.service.ts by removing page size of 9999 * [DURACOM-304] other fix related to accessibility * [DURACOM-304] lint fix * [DURACOM-304] resolve conflicts * [DURACOM-304] fix lint * [DURACOM-304] add support for findAll method in dynamic-scrollable-dropdown.component.ts * [DURACOM-304] refactor to use lazy data provider * [DURACOM-304] improve loading logic for cc-licenses section and dynamic-list * [DURACOM-304] refactor, fix dynamic-list.component loading * [DURACOM-304] remove br --------- Co-authored-by: Alisa Ismailati <[email protected]>
1 parent 204062c commit ff304f3

25 files changed

+640
-296
lines changed

src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<ng-container *ngVar="(bitstreamRD$ | async) as bitstreamRD">
2-
<div class="container" *ngVar="(bitstreamFormatsRD$ | async) as formatsRD">
3-
<div class="row" *ngIf="bitstreamRD?.hasSucceeded && formatsRD?.hasSucceeded">
2+
<div class="container">
3+
<div class="row" *ngIf="bitstreamRD?.hasSucceeded">
44
<div class="col-md-2">
55
<ds-thumbnail [thumbnail]="bitstreamRD?.payload"></ds-thumbnail>
66
</div>
@@ -27,7 +27,7 @@ <h1 class="h2">{{dsoNameService.getName(bitstreamRD?.payload)}} <span class="tex
2727
</div>
2828
</div>
2929
<ds-error *ngIf="bitstreamRD?.hasFailed" message="{{'error.bitstream' | translate}}"></ds-error>
30-
<ds-loading *ngIf="!bitstreamRD || !formatsRD || bitstreamRD?.isLoading || formatsRD?.isLoading"
30+
<ds-loading *ngIf="!bitstreamRD || bitstreamRD?.isLoading"
3131
message="{{'loading.bitstream' | translate}}"></ds-loading>
3232
</div>
3333
</ng-container>

src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.spec.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ describe('EditBitstreamPageComponent', () => {
261261
});
262262

263263
it('should select the correct format', () => {
264-
expect(rawForm.formatContainer.selectedFormat).toEqual(selectedFormat.id);
264+
expect(rawForm.formatContainer.selectedFormat).toEqual(selectedFormat.shortDescription);
265265
});
266266

267267
it('should put the \"New Format\" input on invisible', () => {
@@ -292,7 +292,13 @@ describe('EditBitstreamPageComponent', () => {
292292

293293
describe('when an unknown format is selected', () => {
294294
beforeEach(() => {
295-
comp.updateNewFormatLayout(allFormats[0].id);
295+
comp.onChange({
296+
model: {
297+
id: 'selectedFormat',
298+
value: allFormats[0],
299+
},
300+
});
301+
comp.updateNewFormatLayout();
296302
});
297303

298304
it('should remove the invisible class from the \"New Format\" input', () => {
@@ -394,9 +400,10 @@ describe('EditBitstreamPageComponent', () => {
394400

395401
describe('when selected format has changed', () => {
396402
beforeEach(() => {
397-
comp.formGroup.patchValue({
398-
formatContainer: {
399-
selectedFormat: allFormats[2].id,
403+
comp.onChange({
404+
model: {
405+
id: 'selectedFormat',
406+
value: allFormats[2],
400407
},
401408
});
402409
fixture.detectChanges();

src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts

Lines changed: 59 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import {
2121
DynamicFormLayout,
2222
DynamicFormService,
2323
DynamicInputModel,
24-
DynamicSelectModel,
2524
} from '@ng-dynamic-forms/core';
2625
import {
2726
TranslateModule,
@@ -39,23 +38,24 @@ import {
3938
filter,
4039
map,
4140
switchMap,
41+
take,
4242
tap,
4343
} from 'rxjs/operators';
4444

4545
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
46+
import { FindAllDataImpl } from '../../core/data/base/find-all-data';
4647
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
4748
import { BitstreamFormatDataService } from '../../core/data/bitstream-format-data.service';
48-
import { PaginatedList } from '../../core/data/paginated-list.model';
4949
import { PrimaryBitstreamService } from '../../core/data/primary-bitstream.service';
5050
import { RemoteData } from '../../core/data/remote-data';
5151
import { Bitstream } from '../../core/shared/bitstream.model';
5252
import { BitstreamFormat } from '../../core/shared/bitstream-format.model';
53+
import { BITSTREAM_FORMAT } from '../../core/shared/bitstream-format.resource-type';
5354
import { BitstreamFormatSupportLevel } from '../../core/shared/bitstream-format-support-level';
5455
import { Bundle } from '../../core/shared/bundle.model';
5556
import { Item } from '../../core/shared/item.model';
5657
import { Metadata } from '../../core/shared/metadata.utils';
5758
import {
58-
getAllSucceededRemoteDataPayload,
5959
getFirstCompletedRemoteData,
6060
getFirstSucceededRemoteData,
6161
getFirstSucceededRemoteDataPayload,
@@ -72,6 +72,7 @@ import { ErrorComponent } from '../../shared/error/error.component';
7272
import { DynamicCustomSwitchModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/custom-switch/custom-switch.model';
7373
import { DsDynamicInputModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model';
7474
import { DsDynamicTextAreaModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-textarea.model';
75+
import { DynamicScrollableDropdownModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
7576
import { FormComponent } from '../../shared/form/form.component';
7677
import { ThemedLoadingComponent } from '../../shared/loading/themed-loading.component';
7778
import { NotificationsService } from '../../shared/notifications/notifications.service';
@@ -109,12 +110,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
109110
*/
110111
bitstreamRD$: Observable<RemoteData<Bitstream>>;
111112

112-
/**
113-
* The formats their remote data observable
114-
* Tracks changes and updates the view
115-
*/
116-
bitstreamFormatsRD$: Observable<RemoteData<PaginatedList<BitstreamFormat>>>;
117-
118113
/**
119114
* The UUID of the primary bitstream for this bundle
120115
*/
@@ -130,11 +125,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
130125
*/
131126
originalFormat: BitstreamFormat;
132127

133-
/**
134-
* A list of all available bitstream formats
135-
*/
136-
formats: BitstreamFormat[];
137-
138128
/**
139129
* @type {string} Key prefix used to generate form messages
140130
*/
@@ -178,7 +168,10 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
178168
/**
179169
* Options for fetching all bitstream formats
180170
*/
181-
findAllOptions = { elementsPerPage: 9999 };
171+
findAllOptions = {
172+
elementsPerPage: 20,
173+
currentPage: 1,
174+
};
182175

183176
/**
184177
* The Dynamic Input Model for the file's name
@@ -218,9 +211,22 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
218211
/**
219212
* The Dynamic Input Model for the selected format
220213
*/
221-
selectedFormatModel = new DynamicSelectModel({
214+
selectedFormatModel = new DynamicScrollableDropdownModel({
222215
id: 'selectedFormat',
223216
name: 'selectedFormat',
217+
displayKey: 'shortDescription',
218+
repeatable: false,
219+
metadataFields: [],
220+
submissionId: '',
221+
hasSelectableMetadata: false,
222+
resourceType: BITSTREAM_FORMAT,
223+
formatFunction: (format: BitstreamFormat | string) => {
224+
if (format instanceof BitstreamFormat) {
225+
return hasValue(format) && format.supportLevel === BitstreamFormatSupportLevel.Unknown ? this.translate.instant(this.KEY_PREFIX + 'selectedFormat.unknown') : format.shortDescription;
226+
} else {
227+
return format;
228+
}
229+
},
224230
});
225231

226232
/**
@@ -438,6 +444,11 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
438444
* @private
439445
*/
440446
private bundle: Bundle;
447+
/**
448+
* The currently selected format
449+
* @private
450+
*/
451+
private selectedFormat: BitstreamFormat;
441452

442453
constructor(private route: ActivatedRoute,
443454
private router: Router,
@@ -463,18 +474,12 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
463474
this.itemId = this.route.snapshot.queryParams.itemId;
464475
this.entityType = this.route.snapshot.queryParams.entityType;
465476
this.bitstreamRD$ = this.route.data.pipe(map((data: any) => data.bitstream));
466-
this.bitstreamFormatsRD$ = this.bitstreamFormatService.findAll(this.findAllOptions);
467477

468478
const bitstream$ = this.bitstreamRD$.pipe(
469479
getFirstSucceededRemoteData(),
470480
getRemoteDataPayload(),
471481
);
472482

473-
const allFormats$ = this.bitstreamFormatsRD$.pipe(
474-
getFirstSucceededRemoteData(),
475-
getRemoteDataPayload(),
476-
);
477-
478483
const bundle$ = bitstream$.pipe(
479484
switchMap((bitstream: Bitstream) => bitstream.bundle),
480485
getFirstSucceededRemoteDataPayload(),
@@ -490,24 +495,31 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
490495
switchMap((bundle: Bundle) => bundle.item),
491496
getFirstSucceededRemoteDataPayload(),
492497
);
498+
const format$ = bitstream$.pipe(
499+
switchMap(bitstream => bitstream.format),
500+
getFirstSucceededRemoteDataPayload(),
501+
);
502+
493503
this.subs.push(
494504
observableCombineLatest(
495505
bitstream$,
496-
allFormats$,
497506
bundle$,
498507
primaryBitstream$,
499508
item$,
500-
).pipe()
501-
.subscribe(([bitstream, allFormats, bundle, primaryBitstream, item]) => {
502-
this.bitstream = bitstream as Bitstream;
503-
this.formats = allFormats.page;
504-
this.bundle = bundle;
505-
// hasValue(primaryBitstream) because if there's no primaryBitstream on the bundle it will
506-
// be a success response, but empty
507-
this.primaryBitstreamUUID = hasValue(primaryBitstream) ? primaryBitstream.uuid : null;
508-
this.itemId = item.uuid;
509-
this.setIiifStatus(this.bitstream);
510-
}),
509+
format$,
510+
).subscribe(([bitstream, bundle, primaryBitstream, item, format]) => {
511+
this.bitstream = bitstream as Bitstream;
512+
this.bundle = bundle;
513+
this.selectedFormat = format;
514+
// hasValue(primaryBitstream) because if there's no primaryBitstream on the bundle it will
515+
// be a success response, but empty
516+
this.primaryBitstreamUUID = hasValue(primaryBitstream) ? primaryBitstream.uuid : null;
517+
this.itemId = item.uuid;
518+
this.setIiifStatus(this.bitstream);
519+
}),
520+
format$.pipe(take(1)).subscribe(
521+
(format) => this.originalFormat = format,
522+
),
511523
);
512524

513525
this.subs.push(
@@ -523,7 +535,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
523535
*/
524536
setForm() {
525537
this.formGroup = this.formService.createFormGroup(this.formModel);
526-
this.updateFormatModel();
527538
this.updateForm(this.bitstream);
528539
this.updateFieldTranslations();
529540
}
@@ -542,6 +553,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
542553
description: bitstream.firstMetadataValue('dc.description'),
543554
},
544555
formatContainer: {
556+
selectedFormat: this.selectedFormat.shortDescription,
545557
newFormat: hasValue(bitstream.firstMetadata('dc.format')) ? bitstream.firstMetadata('dc.format').value : undefined,
546558
},
547559
});
@@ -561,36 +573,16 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
561573
},
562574
});
563575
}
564-
this.bitstream.format.pipe(
565-
getAllSucceededRemoteDataPayload(),
566-
).subscribe((format: BitstreamFormat) => {
567-
this.originalFormat = format;
568-
this.formGroup.patchValue({
569-
formatContainer: {
570-
selectedFormat: format.id,
571-
},
572-
});
573-
this.updateNewFormatLayout(format.id);
574-
});
576+
this.updateNewFormatLayout();
575577
}
576578

577-
/**
578-
* Create the list of unknown format IDs an add options to the selectedFormatModel
579-
*/
580-
updateFormatModel() {
581-
this.selectedFormatModel.options = this.formats.map((format: BitstreamFormat) =>
582-
Object.assign({
583-
value: format.id,
584-
label: this.isUnknownFormat(format.id) ? this.translate.instant(this.KEY_PREFIX + 'selectedFormat.unknown') : format.shortDescription,
585-
}));
586-
}
587579

588580
/**
589581
* Update the layout of the "Other Format" input depending on the selected format
590582
* @param selectedId
591583
*/
592-
updateNewFormatLayout(selectedId: string) {
593-
if (this.isUnknownFormat(selectedId)) {
584+
updateNewFormatLayout() {
585+
if (this.isUnknownFormat()) {
594586
this.formLayout.newFormat.grid.host = this.newFormatBaseLayout;
595587
} else {
596588
this.formLayout.newFormat.grid.host = this.newFormatBaseLayout + ' invisible';
@@ -601,9 +593,8 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
601593
* Is the provided format (id) part of the list of unknown formats?
602594
* @param id
603595
*/
604-
isUnknownFormat(id: string): boolean {
605-
const format = this.formats.find((f: BitstreamFormat) => f.id === id);
606-
return hasValue(format) && format.supportLevel === BitstreamFormatSupportLevel.Unknown;
596+
isUnknownFormat(): boolean {
597+
return hasValue(this.selectedFormat) && this.selectedFormat.supportLevel === BitstreamFormatSupportLevel.Unknown;
607598
}
608599

609600
/**
@@ -635,7 +626,8 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
635626
onChange(event) {
636627
const model = event.model;
637628
if (model.id === this.selectedFormatModel.id) {
638-
this.updateNewFormatLayout(model.value);
629+
this.selectedFormat = model.value;
630+
this.updateNewFormatLayout();
639631
}
640632
}
641633

@@ -645,8 +637,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
645637
onSubmit() {
646638
const updatedValues = this.formGroup.getRawValue();
647639
const updatedBitstream = this.formToBitstream(updatedValues);
648-
const selectedFormat = this.formats.find((f: BitstreamFormat) => f.id === updatedValues.formatContainer.selectedFormat);
649-
const isNewFormat = selectedFormat.id !== this.originalFormat.id;
640+
const isNewFormat = this.selectedFormat.id !== this.originalFormat.id;
650641
const isPrimary = updatedValues.fileNamePrimaryContainer.primaryBitstream;
651642
const wasPrimary = this.primaryBitstreamUUID === this.bitstream.uuid;
652643

@@ -698,7 +689,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
698689
bundle$ = observableOf(this.bundle);
699690
}
700691
if (isNewFormat) {
701-
bitstream$ = this.bitstreamService.updateFormat(this.bitstream, selectedFormat).pipe(
692+
bitstream$ = this.bitstreamService.updateFormat(this.bitstream, this.selectedFormat).pipe(
702693
getFirstCompletedRemoteData(),
703694
map((formatResponse: RemoteData<Bitstream>) => {
704695
if (hasValue(formatResponse) && formatResponse.hasFailed) {
@@ -856,4 +847,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
856847
.forEach((subscription) => subscription.unsubscribe());
857848
}
858849

850+
findAllFormatsServiceFactory() {
851+
return () => this.bitstreamFormatService as any as FindAllDataImpl<BitstreamFormat>;
852+
}
859853
}

src/app/core/data/bitstream-data.service.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,12 @@ export class BitstreamDataService extends IdentifiableDataService<Bitstream> imp
241241
* no valid cached version. Defaults to true
242242
* @param reRequestOnStale Whether or not the request should automatically be re-
243243
* requested after the response becomes stale
244+
* @param options the {@link FindListOptions} for the request
244245
* @return {Observable<Bitstream | null>}
245246
* Return an observable that constains primary bitstream information or null
246247
*/
247-
public findPrimaryBitstreamByItemAndName(item: Item, bundleName: string, useCachedVersionIfAvailable = true, reRequestOnStale = true): Observable<Bitstream | null> {
248-
return this.bundleService.findByItemAndName(item, bundleName, useCachedVersionIfAvailable, reRequestOnStale, followLink('primaryBitstream')).pipe(
248+
public findPrimaryBitstreamByItemAndName(item: Item, bundleName: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, options?: FindListOptions): Observable<Bitstream | null> {
249+
return this.bundleService.findByItemAndName(item, bundleName, useCachedVersionIfAvailable, reRequestOnStale, options, followLink('primaryBitstream')).pipe(
249250
getFirstCompletedRemoteData(),
250251
switchMap((rd: RemoteData<Bundle>) => {
251252
if (!rd.hasSucceeded) {

src/app/core/data/bundle-data.service.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,14 @@ export class BundleDataService extends IdentifiableDataService<Bundle> implement
7878
* requested after the response becomes stale
7979
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which
8080
* {@link HALLink}s should be automatically resolved
81+
* @param options the {@link FindListOptions} for the request
8182
*/
8283
// TODO should be implemented rest side
83-
findByItemAndName(item: Item, bundleName: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<Bundle>[]): Observable<RemoteData<Bundle>> {
84-
return this.findAllByItem(item, { elementsPerPage: 9999 }, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow).pipe(
84+
findByItemAndName(item: Item, bundleName: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, options?: FindListOptions, ...linksToFollow: FollowLinkConfig<Bundle>[]): Observable<RemoteData<Bundle>> {
85+
//Since we filter by bundleName where the pagination options are not indicated we need to load all the possible bundles.
86+
// This is a workaround, in substitution of the previously recursive call with expand
87+
const paginationOptions = options ?? { elementsPerPage: 9999 };
88+
return this.findAllByItem(item, paginationOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow).pipe(
8589
map((rd: RemoteData<PaginatedList<Bundle>>) => {
8690
if (hasValue(rd.payload) && hasValue(rd.payload.page)) {
8791
const matchingBundle = rd.payload.page.find((bundle: Bundle) =>

src/app/core/metadata/head-tag.service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import { coreSelector } from '../core.selectors';
5050
import { CoreState } from '../core-state.model';
5151
import { BundleDataService } from '../data/bundle-data.service';
5252
import { AuthorizationDataService } from '../data/feature-authorization/authorization-data.service';
53+
import { FindListOptions } from '../data/find-list-options.model';
5354
import { PaginatedList } from '../data/paginated-list.model';
5455
import { RemoteData } from '../data/remote-data';
5556
import { RootDataService } from '../data/root-data.service';
@@ -331,6 +332,7 @@ export class HeadTagService {
331332
'ORIGINAL',
332333
true,
333334
true,
335+
new FindListOptions(),
334336
followLink('primaryBitstream'),
335337
followLink('bitstreams', {
336338
findListOptions: {

src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
[isFirstTable]="isFirst"
4040
aria-describedby="reorder-description">
4141
</ds-item-edit-bitstream-bundle>
42+
<div class="d-flex justify-content-center" *ngIf="showLoadMoreLink$ | async">
43+
<button class="btn btn-link my-3" (click)="loadBundles()"> {{'item.edit.bitstreams.load-more.link' | translate}}</button>
44+
</div>
4245
</div>
4346
<div *ngIf="bundles?.length === 0"
4447
class="alert alert-info w-100 d-inline-block mt-4" role="alert">

0 commit comments

Comments
 (0)