Skip to content

Commit 6b73c75

Browse files
authored
Merge pull request DSpace#3925 from 4Science/task/dspace-7_X/DURACOM-304
[Port dspace-7_x] Prevent request with page size of 9999
2 parents f01e49f + d155d77 commit 6b73c75

25 files changed

Lines changed: 610 additions & 313 deletions

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-themed-thumbnail [thumbnail]="bitstreamRD?.payload"></ds-themed-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-themed-loading *ngIf="!bitstreamRD || !formatsRD || bitstreamRD?.isLoading || formatsRD?.isLoading"
30+
<ds-themed-loading *ngIf="!bitstreamRD || bitstreamRD?.isLoading"
3131
message="{{'loading.bitstream' | translate}}"></ds-themed-loading>
3232
</div>
3333
</ng-container>

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ describe('EditBitstreamPageComponent', () => {
239239
});
240240

241241
it('should select the correct format', () => {
242-
expect(rawForm.formatContainer.selectedFormat).toEqual(selectedFormat.id);
242+
expect(rawForm.formatContainer.selectedFormat).toEqual(selectedFormat.shortDescription);
243243
});
244244

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

271271
describe('when an unknown format is selected', () => {
272272
beforeEach(() => {
273-
comp.updateNewFormatLayout(allFormats[0].id);
273+
comp.onChange({
274+
model: {
275+
id: 'selectedFormat',
276+
value: allFormats[0],
277+
},
278+
});
279+
comp.updateNewFormatLayout();
274280
});
275281

276282
it('should remove the invisible class from the \"New Format\" input', () => {
@@ -372,10 +378,11 @@ describe('EditBitstreamPageComponent', () => {
372378

373379
describe('when selected format has changed', () => {
374380
beforeEach(() => {
375-
comp.formGroup.patchValue({
376-
formatContainer: {
377-
selectedFormat: allFormats[2].id
378-
}
381+
comp.onChange({
382+
model: {
383+
id: 'selectedFormat',
384+
value: allFormats[2],
385+
},
379386
});
380387
fixture.detectChanges();
381388
comp.onSubmit();

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

Lines changed: 69 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnIni
22
import { Bitstream } from '../../core/shared/bitstream.model';
33
import { ActivatedRoute, Router } from '@angular/router';
44
import { filter, map, switchMap, tap } from 'rxjs/operators';
5-
import { combineLatest, combineLatest as observableCombineLatest, Observable, of as observableOf, Subscription } from 'rxjs';
6-
import { DynamicFormControlModel, DynamicFormGroupModel, DynamicFormLayout, DynamicFormService, DynamicInputModel, DynamicSelectModel } from '@ng-dynamic-forms/core';
5+
import {
6+
combineLatest,
7+
combineLatest as observableCombineLatest,
8+
Observable,
9+
of as observableOf,
10+
Subscription, take
11+
} from 'rxjs';
12+
import { DynamicFormControlModel, DynamicFormGroupModel, DynamicFormLayout, DynamicFormService, DynamicInputModel } from '@ng-dynamic-forms/core';
713
import { UntypedFormGroup } from '@angular/forms';
814
import { TranslateService } from '@ngx-translate/core';
915
import { DynamicCustomSwitchModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/custom-switch/custom-switch.model';
1016
import cloneDeep from 'lodash/cloneDeep';
1117
import { BitstreamDataService } from '../../core/data/bitstream-data.service';
12-
import { getAllSucceededRemoteDataPayload, getFirstCompletedRemoteData, getFirstSucceededRemoteData, getFirstSucceededRemoteDataPayload, getRemoteDataPayload } from '../../core/shared/operators';
18+
import { getFirstCompletedRemoteData, getFirstSucceededRemoteData, getFirstSucceededRemoteDataPayload, getRemoteDataPayload } from '../../core/shared/operators';
1319
import { NotificationsService } from '../../shared/notifications/notifications.service';
1420
import { BitstreamFormatDataService } from '../../core/data/bitstream-format-data.service';
1521
import { BitstreamFormat } from '../../core/shared/bitstream-format.model';
@@ -18,14 +24,15 @@ import { hasValue, hasValueOperator, isEmpty, isNotEmpty } from '../../shared/em
1824
import { Metadata } from '../../core/shared/metadata.utils';
1925
import { Location } from '@angular/common';
2026
import { RemoteData } from '../../core/data/remote-data';
21-
import { PaginatedList } from '../../core/data/paginated-list.model';
2227
import { getEntityEditRoute } from '../../item-page/item-page-routing-paths';
2328
import { Bundle } from '../../core/shared/bundle.model';
2429
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
2530
import { Item } from '../../core/shared/item.model';
2631
import { DsDynamicInputModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model';
2732
import { DsDynamicTextAreaModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-textarea.model';
2833
import { PrimaryBitstreamService } from '../../core/data/primary-bitstream.service';
34+
import { DynamicScrollableDropdownModel } from 'src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
35+
import { FindAllDataImpl } from '../../core/data/base/find-all-data';
2936

3037
@Component({
3138
selector: 'ds-edit-bitstream-page',
@@ -44,12 +51,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
4451
*/
4552
bitstreamRD$: Observable<RemoteData<Bitstream>>;
4653

47-
/**
48-
* The formats their remote data observable
49-
* Tracks changes and updates the view
50-
*/
51-
bitstreamFormatsRD$: Observable<RemoteData<PaginatedList<BitstreamFormat>>>;
52-
5354
/**
5455
* The UUID of the primary bitstream for this bundle
5556
*/
@@ -65,11 +66,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
6566
*/
6667
originalFormat: BitstreamFormat;
6768

68-
/**
69-
* A list of all available bitstream formats
70-
*/
71-
formats: BitstreamFormat[];
72-
7369
/**
7470
* @type {string} Key prefix used to generate form messages
7571
*/
@@ -113,7 +109,10 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
113109
/**
114110
* Options for fetching all bitstream formats
115111
*/
116-
findAllOptions = { elementsPerPage: 9999 };
112+
findAllOptions = {
113+
elementsPerPage: 20,
114+
currentPage: 1
115+
};
117116

118117
/**
119118
* The Dynamic Input Model for the file's name
@@ -153,9 +152,22 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
153152
/**
154153
* The Dynamic Input Model for the selected format
155154
*/
156-
selectedFormatModel = new DynamicSelectModel({
155+
selectedFormatModel = new DynamicScrollableDropdownModel({
157156
id: 'selectedFormat',
158-
name: 'selectedFormat'
157+
name: 'selectedFormat',
158+
displayKey: 'shortDescription',
159+
repeatable: false,
160+
metadataFields: [],
161+
submissionId: '',
162+
hasSelectableMetadata: false,
163+
findAllFactory: this.findAllFormatsServiceFactory(),
164+
formatFunction: (format: BitstreamFormat | string) => {
165+
if (format instanceof BitstreamFormat) {
166+
return hasValue(format) && format.supportLevel === BitstreamFormatSupportLevel.Unknown ? this.translate.instant(this.KEY_PREFIX + 'selectedFormat.unknown') : format.shortDescription;
167+
} else {
168+
return format;
169+
}
170+
},
159171
});
160172

161173
/**
@@ -370,6 +382,11 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
370382
* @private
371383
*/
372384
private bundle: Bundle;
385+
/**
386+
* The currently selected format
387+
* @private
388+
*/
389+
private selectedFormat: BitstreamFormat;
373390

374391
constructor(private route: ActivatedRoute,
375392
private router: Router,
@@ -396,18 +413,12 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
396413
this.itemId = this.route.snapshot.queryParams.itemId;
397414
this.entityType = this.route.snapshot.queryParams.entityType;
398415
this.bitstreamRD$ = this.route.data.pipe(map((data: any) => data.bitstream));
399-
this.bitstreamFormatsRD$ = this.bitstreamFormatService.findAll(this.findAllOptions);
400416

401417
const bitstream$ = this.bitstreamRD$.pipe(
402418
getFirstSucceededRemoteData(),
403419
getRemoteDataPayload(),
404420
);
405421

406-
const allFormats$ = this.bitstreamFormatsRD$.pipe(
407-
getFirstSucceededRemoteData(),
408-
getRemoteDataPayload(),
409-
);
410-
411422
const bundle$ = bitstream$.pipe(
412423
switchMap((bitstream: Bitstream) => bitstream.bundle),
413424
getFirstSucceededRemoteDataPayload(),
@@ -423,24 +434,31 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
423434
switchMap((bundle: Bundle) => bundle.item),
424435
getFirstSucceededRemoteDataPayload(),
425436
);
437+
const format$ = bitstream$.pipe(
438+
switchMap(bitstream => bitstream.format),
439+
getFirstSucceededRemoteDataPayload(),
440+
);
441+
426442
this.subs.push(
427443
observableCombineLatest(
428444
bitstream$,
429-
allFormats$,
430445
bundle$,
431446
primaryBitstream$,
432447
item$,
433-
).pipe()
434-
.subscribe(([bitstream, allFormats, bundle, primaryBitstream, item]) => {
435-
this.bitstream = bitstream as Bitstream;
436-
this.formats = allFormats.page;
437-
this.bundle = bundle;
438-
// hasValue(primaryBitstream) because if there's no primaryBitstream on the bundle it will
439-
// be a success response, but empty
440-
this.primaryBitstreamUUID = hasValue(primaryBitstream) ? primaryBitstream.uuid : null;
441-
this.itemId = item.uuid;
442-
this.setIiifStatus(this.bitstream);
443-
})
448+
format$,
449+
).subscribe(([bitstream, bundle, primaryBitstream, item, format]) => {
450+
this.bitstream = bitstream as Bitstream;
451+
this.bundle = bundle;
452+
this.selectedFormat = format;
453+
// hasValue(primaryBitstream) because if there's no primaryBitstream on the bundle it will
454+
// be a success response, but empty
455+
this.primaryBitstreamUUID = hasValue(primaryBitstream) ? primaryBitstream.uuid : null;
456+
this.itemId = item.uuid;
457+
this.setIiifStatus(this.bitstream);
458+
}),
459+
format$.pipe(take(1)).subscribe(
460+
(format) => this.originalFormat = format,
461+
),
444462
);
445463

446464
this.subs.push(
@@ -456,7 +474,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
456474
*/
457475
setForm() {
458476
this.formGroup = this.formService.createFormGroup(this.formModel);
459-
this.updateFormatModel();
460477
this.updateForm(this.bitstream);
461478
this.updateFieldTranslations();
462479
}
@@ -475,8 +492,9 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
475492
description: bitstream.firstMetadataValue('dc.description')
476493
},
477494
formatContainer: {
478-
newFormat: hasValue(bitstream.firstMetadata('dc.format')) ? bitstream.firstMetadata('dc.format').value : undefined
479-
}
495+
selectedFormat: this.selectedFormat.shortDescription,
496+
newFormat: hasValue(bitstream.firstMetadata('dc.format')) ? bitstream.firstMetadata('dc.format').value : undefined,
497+
},
480498
});
481499
if (this.isIIIF) {
482500
this.formGroup.patchValue({
@@ -494,36 +512,16 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
494512
}
495513
});
496514
}
497-
this.bitstream.format.pipe(
498-
getAllSucceededRemoteDataPayload()
499-
).subscribe((format: BitstreamFormat) => {
500-
this.originalFormat = format;
501-
this.formGroup.patchValue({
502-
formatContainer: {
503-
selectedFormat: format.id
504-
}
505-
});
506-
this.updateNewFormatLayout(format.id);
507-
});
515+
this.updateNewFormatLayout();
508516
}
509517

510-
/**
511-
* Create the list of unknown format IDs an add options to the selectedFormatModel
512-
*/
513-
updateFormatModel() {
514-
this.selectedFormatModel.options = this.formats.map((format: BitstreamFormat) =>
515-
Object.assign({
516-
value: format.id,
517-
label: this.isUnknownFormat(format.id) ? this.translate.instant(this.KEY_PREFIX + 'selectedFormat.unknown') : format.shortDescription
518-
}));
519-
}
520518

521519
/**
522520
* Update the layout of the "Other Format" input depending on the selected format
523521
* @param selectedId
524522
*/
525-
updateNewFormatLayout(selectedId: string) {
526-
if (this.isUnknownFormat(selectedId)) {
523+
updateNewFormatLayout() {
524+
if (this.isUnknownFormat()) {
527525
this.formLayout.newFormat.grid.host = this.newFormatBaseLayout;
528526
} else {
529527
this.formLayout.newFormat.grid.host = this.newFormatBaseLayout + ' invisible';
@@ -534,9 +532,8 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
534532
* Is the provided format (id) part of the list of unknown formats?
535533
* @param id
536534
*/
537-
isUnknownFormat(id: string): boolean {
538-
const format = this.formats.find((f: BitstreamFormat) => f.id === id);
539-
return hasValue(format) && format.supportLevel === BitstreamFormatSupportLevel.Unknown;
535+
isUnknownFormat(): boolean {
536+
return hasValue(this.selectedFormat) && this.selectedFormat.supportLevel === BitstreamFormatSupportLevel.Unknown;
540537
}
541538

542539
/**
@@ -568,7 +565,8 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
568565
onChange(event) {
569566
const model = event.model;
570567
if (model.id === this.selectedFormatModel.id) {
571-
this.updateNewFormatLayout(model.value);
568+
this.selectedFormat = model.value;
569+
this.updateNewFormatLayout();
572570
}
573571
}
574572

@@ -578,8 +576,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
578576
onSubmit() {
579577
const updatedValues = this.formGroup.getRawValue();
580578
const updatedBitstream = this.formToBitstream(updatedValues);
581-
const selectedFormat = this.formats.find((f: BitstreamFormat) => f.id === updatedValues.formatContainer.selectedFormat);
582-
const isNewFormat = selectedFormat.id !== this.originalFormat.id;
579+
const isNewFormat = this.selectedFormat.id !== this.originalFormat.id;
583580
const isPrimary = updatedValues.fileNamePrimaryContainer.primaryBitstream;
584581
const wasPrimary = this.primaryBitstreamUUID === this.bitstream.uuid;
585582

@@ -631,7 +628,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
631628
bundle$ = observableOf(this.bundle);
632629
}
633630
if (isNewFormat) {
634-
bitstream$ = this.bitstreamService.updateFormat(this.bitstream, selectedFormat).pipe(
631+
bitstream$ = this.bitstreamService.updateFormat(this.bitstream, this.selectedFormat).pipe(
635632
getFirstCompletedRemoteData(),
636633
map((formatResponse: RemoteData<Bitstream>) => {
637634
if (hasValue(formatResponse) && formatResponse.hasFailed) {
@@ -789,4 +786,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
789786
.forEach((subscription) => subscription.unsubscribe());
790787
}
791788

789+
findAllFormatsServiceFactory() {
790+
return () => this.bitstreamFormatService as any as FindAllDataImpl<BitstreamFormat>;
791+
}
792792
}

0 commit comments

Comments
 (0)