Skip to content

Commit 3623641

Browse files
[DURACOM-304] add support for findAll method in dynamic-scrollable-dropdown.component.ts
1 parent b892b13 commit 3623641

6 files changed

Lines changed: 136 additions & 102 deletions

File tree

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: 57 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
expand,
99
Observable,
1010
of as observableOf, reduce,
11-
Subscription
11+
Subscription, take
1212
} from 'rxjs';
1313
import { DynamicFormControlModel, DynamicFormGroupModel, DynamicFormLayout, DynamicFormService, DynamicInputModel, DynamicSelectModel } from '@ng-dynamic-forms/core';
1414
import { UntypedFormGroup } from '@angular/forms';
@@ -33,6 +33,8 @@ import { Item } from '../../core/shared/item.model';
3333
import { DsDynamicInputModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model';
3434
import { DsDynamicTextAreaModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-textarea.model';
3535
import { PrimaryBitstreamService } from '../../core/data/primary-bitstream.service';
36+
import { DynamicScrollableDropdownModel } from 'src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
37+
import { FindAllDataImpl } from "../../core/data/base/find-all-data";
3638

3739
@Component({
3840
selector: 'ds-edit-bitstream-page',
@@ -51,12 +53,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
5153
*/
5254
bitstreamRD$: Observable<RemoteData<Bitstream>>;
5355

54-
/**
55-
* The formats their remote data observable
56-
* Tracks changes and updates the view
57-
*/
58-
bitstreamFormatsRD$: Observable<RemoteData<PaginatedList<BitstreamFormat>>>;
59-
6056
/**
6157
* The UUID of the primary bitstream for this bundle
6258
*/
@@ -72,11 +68,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
7268
*/
7369
originalFormat: BitstreamFormat;
7470

75-
/**
76-
* A list of all available bitstream formats
77-
*/
78-
formats: BitstreamFormat[];
79-
8071
/**
8172
* @type {string} Key prefix used to generate form messages
8273
*/
@@ -163,9 +154,22 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
163154
/**
164155
* The Dynamic Input Model for the selected format
165156
*/
166-
selectedFormatModel = new DynamicSelectModel({
157+
selectedFormatModel = new DynamicScrollableDropdownModel({
167158
id: 'selectedFormat',
168-
name: 'selectedFormat'
159+
name: 'selectedFormat',
160+
displayKey: 'shortDescription',
161+
repeatable: false,
162+
metadataFields: [],
163+
submissionId: '',
164+
hasSelectableMetadata: false,
165+
findAllFactory: this.findAllFormatsServiceFactory(),
166+
formatFunction: (format: BitstreamFormat | string) => {
167+
if (format instanceof BitstreamFormat) {
168+
return hasValue(format) && format.supportLevel === BitstreamFormatSupportLevel.Unknown ? this.translate.instant(this.KEY_PREFIX + 'selectedFormat.unknown') : format.shortDescription;
169+
} else {
170+
return format;
171+
}
172+
},
169173
});
170174

171175
/**
@@ -380,6 +384,11 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
380384
* @private
381385
*/
382386
private bundle: Bundle;
387+
/**
388+
* The currently selected format
389+
* @private
390+
*/
391+
private selectedFormat: BitstreamFormat;
383392

384393
constructor(private route: ActivatedRoute,
385394
private router: Router,
@@ -407,25 +416,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
407416
this.entityType = this.route.snapshot.queryParams.entityType;
408417
this.bitstreamRD$ = this.route.data.pipe(map((data: any) => data.bitstream));
409418

410-
this.bitstreamFormatsRD$ = this.bitstreamFormatService.findAll(this.findAllOptions).pipe(
411-
getFirstSucceededRemoteData(),
412-
expand((response: RemoteData<PaginatedList<BitstreamFormat>>) => {
413-
const pageInfo = response.payload.pageInfo;
414-
if (pageInfo.currentPage < pageInfo.totalPages) {
415-
const nextPageOptions = { ...this.findAllOptions, currentPage: pageInfo.currentPage + 1 };
416-
return this.bitstreamFormatService.findAll(nextPageOptions).pipe(getFirstSucceededRemoteData());
417-
} else {
418-
return EMPTY;
419-
}
420-
}),
421-
);
422-
423-
const bitstreamFormats$ = this.bitstreamFormatsRD$.pipe(
424-
reduce((acc: BitstreamFormat[], response: RemoteData<PaginatedList<BitstreamFormat>>) => {
425-
return acc.concat(response.payload.page);
426-
}, [])
427-
)
428-
429419
const bitstream$ = this.bitstreamRD$.pipe(
430420
getFirstSucceededRemoteData(),
431421
getRemoteDataPayload(),
@@ -446,24 +436,31 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
446436
switchMap((bundle: Bundle) => bundle.item),
447437
getFirstSucceededRemoteDataPayload(),
448438
);
439+
const format$ = bitstream$.pipe(
440+
switchMap(bitstream => bitstream.format),
441+
getFirstSucceededRemoteDataPayload(),
442+
);
443+
449444
this.subs.push(
450445
observableCombineLatest(
451446
bitstream$,
452-
bitstreamFormats$,
453447
bundle$,
454448
primaryBitstream$,
455449
item$,
456-
).pipe()
457-
.subscribe(([bitstream, allFormats, bundle, primaryBitstream, item]) => {
458-
this.bitstream = bitstream as Bitstream;
459-
this.formats = allFormats;
460-
this.bundle = bundle;
461-
// hasValue(primaryBitstream) because if there's no primaryBitstream on the bundle it will
462-
// be a success response, but empty
463-
this.primaryBitstreamUUID = hasValue(primaryBitstream) ? primaryBitstream.uuid : null;
464-
this.itemId = item.uuid;
465-
this.setIiifStatus(this.bitstream);
466-
})
450+
format$,
451+
).subscribe(([bitstream, bundle, primaryBitstream, item, format]) => {
452+
this.bitstream = bitstream as Bitstream;
453+
this.bundle = bundle;
454+
this.selectedFormat = format;
455+
// hasValue(primaryBitstream) because if there's no primaryBitstream on the bundle it will
456+
// be a success response, but empty
457+
this.primaryBitstreamUUID = hasValue(primaryBitstream) ? primaryBitstream.uuid : null;
458+
this.itemId = item.uuid;
459+
this.setIiifStatus(this.bitstream);
460+
}),
461+
format$.pipe(take(1)).subscribe(
462+
(format) => this.originalFormat = format,
463+
),
467464
);
468465

469466
this.subs.push(
@@ -479,7 +476,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
479476
*/
480477
setForm() {
481478
this.formGroup = this.formService.createFormGroup(this.formModel);
482-
this.updateFormatModel();
483479
this.updateForm(this.bitstream);
484480
this.updateFieldTranslations();
485481
}
@@ -498,8 +494,9 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
498494
description: bitstream.firstMetadataValue('dc.description')
499495
},
500496
formatContainer: {
501-
newFormat: hasValue(bitstream.firstMetadata('dc.format')) ? bitstream.firstMetadata('dc.format').value : undefined
502-
}
497+
selectedFormat: this.selectedFormat.shortDescription,
498+
newFormat: hasValue(bitstream.firstMetadata('dc.format')) ? bitstream.firstMetadata('dc.format').value : undefined,
499+
},
503500
});
504501
if (this.isIIIF) {
505502
this.formGroup.patchValue({
@@ -517,36 +514,16 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
517514
}
518515
});
519516
}
520-
this.bitstream.format.pipe(
521-
getAllSucceededRemoteDataPayload()
522-
).subscribe((format: BitstreamFormat) => {
523-
this.originalFormat = format;
524-
this.formGroup.patchValue({
525-
formatContainer: {
526-
selectedFormat: format.id
527-
}
528-
});
529-
this.updateNewFormatLayout(format.id);
530-
});
517+
this.updateNewFormatLayout();
531518
}
532519

533-
/**
534-
* Create the list of unknown format IDs an add options to the selectedFormatModel
535-
*/
536-
updateFormatModel() {
537-
this.selectedFormatModel.options = this.formats.map((format: BitstreamFormat) =>
538-
Object.assign({
539-
value: format.id,
540-
label: this.isUnknownFormat(format.id) ? this.translate.instant(this.KEY_PREFIX + 'selectedFormat.unknown') : format.shortDescription
541-
}));
542-
}
543520

544521
/**
545522
* Update the layout of the "Other Format" input depending on the selected format
546523
* @param selectedId
547524
*/
548-
updateNewFormatLayout(selectedId: string) {
549-
if (this.isUnknownFormat(selectedId)) {
525+
updateNewFormatLayout() {
526+
if (this.isUnknownFormat()) {
550527
this.formLayout.newFormat.grid.host = this.newFormatBaseLayout;
551528
} else {
552529
this.formLayout.newFormat.grid.host = this.newFormatBaseLayout + ' invisible';
@@ -557,9 +534,8 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
557534
* Is the provided format (id) part of the list of unknown formats?
558535
* @param id
559536
*/
560-
isUnknownFormat(id: string): boolean {
561-
const format = this.formats.find((f: BitstreamFormat) => f.id === id);
562-
return hasValue(format) && format.supportLevel === BitstreamFormatSupportLevel.Unknown;
537+
isUnknownFormat(): boolean {
538+
return hasValue(this.selectedFormat) && this.selectedFormat.supportLevel === BitstreamFormatSupportLevel.Unknown;
563539
}
564540

565541
/**
@@ -591,7 +567,8 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
591567
onChange(event) {
592568
const model = event.model;
593569
if (model.id === this.selectedFormatModel.id) {
594-
this.updateNewFormatLayout(model.value);
570+
this.selectedFormat = model.value;
571+
this.updateNewFormatLayout();
595572
}
596573
}
597574

@@ -601,8 +578,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
601578
onSubmit() {
602579
const updatedValues = this.formGroup.getRawValue();
603580
const updatedBitstream = this.formToBitstream(updatedValues);
604-
const selectedFormat = this.formats.find((f: BitstreamFormat) => f.id === updatedValues.formatContainer.selectedFormat);
605-
const isNewFormat = selectedFormat.id !== this.originalFormat.id;
581+
const isNewFormat = this.selectedFormat.id !== this.originalFormat.id;
606582
const isPrimary = updatedValues.fileNamePrimaryContainer.primaryBitstream;
607583
const wasPrimary = this.primaryBitstreamUUID === this.bitstream.uuid;
608584

@@ -654,7 +630,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
654630
bundle$ = observableOf(this.bundle);
655631
}
656632
if (isNewFormat) {
657-
bitstream$ = this.bitstreamService.updateFormat(this.bitstream, selectedFormat).pipe(
633+
bitstream$ = this.bitstreamService.updateFormat(this.bitstream, this.selectedFormat).pipe(
658634
getFirstCompletedRemoteData(),
659635
map((formatResponse: RemoteData<Bitstream>) => {
660636
if (hasValue(formatResponse) && formatResponse.hasFailed) {
@@ -812,4 +788,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
812788
.forEach((subscription) => subscription.unsubscribe());
813789
}
814790

791+
findAllFormatsServiceFactory() {
792+
return () => this.bitstreamFormatService as any as FindAllDataImpl<BitstreamFormat>;
793+
}
815794
}

src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.html

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,18 @@
4040
(scrolled)="onScroll()"
4141
[scrollWindow]="false">
4242

43-
<button class="dropdown-item disabled" type="button" *ngIf="optionsList && optionsList.length === 0">
44-
{{ 'form.no-results' | translate }}
45-
</button>
43+
<button class="dropdown-item disabled" *ngIf="optionsList && optionsList.length === 0">{{'form.no-results' | translate}}</button>
4644
<button class="dropdown-item collection-item text-truncate"
4745
(click)="onSelect(undefined); sdRef.close()" (mousedown)="onSelect(undefined); sdRef.close()"
4846
title="{{ 'dropdown.clear.tooltip' | translate }}" role="option"
49-
type="button">
47+
>
5048
<i>{{ 'dropdown.clear' | translate }}</i>
5149
</button>
5250
<button class="dropdown-item collection-item text-truncate" *ngFor="let listEntry of optionsList; let i = index"
5351
[class.active]="i === selectedIndex"
5452
(keydown.enter)="onSelect(listEntry); sdRef.close()" (mousedown)="onSelect(listEntry); sdRef.close()"
55-
title="{{ listEntry.display }}" role="option" type="button"
56-
[attr.id]="listEntry.display === (currentValue|async) ? ('combobox_' + id + '_selected') : null">
53+
title="{{ inputFormatter(listEntry) }}" role="option"
54+
[attr.id]="inputFormatter(listEntry) === (currentValue|async) ? ('combobox_' + id + '_selected') : null">
5755
{{inputFormatter(listEntry)}}
5856
</button>
5957
<div class="scrollable-dropdown-loading text-center" *ngIf="loading"><p>{{'form.loading' | translate}}</p></div>

0 commit comments

Comments
 (0)