mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
[DURACOM-304] add support for findAll method in dynamic-scrollable-dropdown.component.ts
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<ng-container *ngVar="(bitstreamRD$ | async) as bitstreamRD">
|
||||
<div class="container" *ngVar="(bitstreamFormatsRD$ | async) as formatsRD">
|
||||
<div class="row" *ngIf="bitstreamRD?.hasSucceeded && formatsRD?.hasSucceeded">
|
||||
<div class="container">
|
||||
<div class="row" *ngIf="bitstreamRD?.hasSucceeded">
|
||||
<div class="col-md-2">
|
||||
<ds-themed-thumbnail [thumbnail]="bitstreamRD?.payload"></ds-themed-thumbnail>
|
||||
</div>
|
||||
@@ -27,7 +27,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<ds-error *ngIf="bitstreamRD?.hasFailed" message="{{'error.bitstream' | translate}}"></ds-error>
|
||||
<ds-themed-loading *ngIf="!bitstreamRD || !formatsRD || bitstreamRD?.isLoading || formatsRD?.isLoading"
|
||||
<ds-themed-loading *ngIf="!bitstreamRD || bitstreamRD?.isLoading"
|
||||
message="{{'loading.bitstream' | translate}}"></ds-themed-loading>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
@@ -239,7 +239,7 @@ describe('EditBitstreamPageComponent', () => {
|
||||
});
|
||||
|
||||
it('should select the correct format', () => {
|
||||
expect(rawForm.formatContainer.selectedFormat).toEqual(selectedFormat.id);
|
||||
expect(rawForm.formatContainer.selectedFormat).toEqual(selectedFormat.shortDescription);
|
||||
});
|
||||
|
||||
it('should put the \"New Format\" input on invisible', () => {
|
||||
@@ -270,7 +270,13 @@ describe('EditBitstreamPageComponent', () => {
|
||||
|
||||
describe('when an unknown format is selected', () => {
|
||||
beforeEach(() => {
|
||||
comp.updateNewFormatLayout(allFormats[0].id);
|
||||
comp.onChange({
|
||||
model: {
|
||||
id: 'selectedFormat',
|
||||
value: allFormats[0],
|
||||
},
|
||||
});
|
||||
comp.updateNewFormatLayout();
|
||||
});
|
||||
|
||||
it('should remove the invisible class from the \"New Format\" input', () => {
|
||||
@@ -372,10 +378,11 @@ describe('EditBitstreamPageComponent', () => {
|
||||
|
||||
describe('when selected format has changed', () => {
|
||||
beforeEach(() => {
|
||||
comp.formGroup.patchValue({
|
||||
formatContainer: {
|
||||
selectedFormat: allFormats[2].id
|
||||
}
|
||||
comp.onChange({
|
||||
model: {
|
||||
id: 'selectedFormat',
|
||||
value: allFormats[2],
|
||||
},
|
||||
});
|
||||
fixture.detectChanges();
|
||||
comp.onSubmit();
|
||||
|
@@ -8,7 +8,7 @@ import {
|
||||
expand,
|
||||
Observable,
|
||||
of as observableOf, reduce,
|
||||
Subscription
|
||||
Subscription, take
|
||||
} from 'rxjs';
|
||||
import { DynamicFormControlModel, DynamicFormGroupModel, DynamicFormLayout, DynamicFormService, DynamicInputModel, DynamicSelectModel } from '@ng-dynamic-forms/core';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
@@ -33,6 +33,8 @@ import { Item } from '../../core/shared/item.model';
|
||||
import { DsDynamicInputModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model';
|
||||
import { DsDynamicTextAreaModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-textarea.model';
|
||||
import { PrimaryBitstreamService } from '../../core/data/primary-bitstream.service';
|
||||
import { DynamicScrollableDropdownModel } from 'src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
|
||||
import { FindAllDataImpl } from "../../core/data/base/find-all-data";
|
||||
|
||||
@Component({
|
||||
selector: 'ds-edit-bitstream-page',
|
||||
@@ -51,12 +53,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
bitstreamRD$: Observable<RemoteData<Bitstream>>;
|
||||
|
||||
/**
|
||||
* The formats their remote data observable
|
||||
* Tracks changes and updates the view
|
||||
*/
|
||||
bitstreamFormatsRD$: Observable<RemoteData<PaginatedList<BitstreamFormat>>>;
|
||||
|
||||
/**
|
||||
* The UUID of the primary bitstream for this bundle
|
||||
*/
|
||||
@@ -72,11 +68,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
originalFormat: BitstreamFormat;
|
||||
|
||||
/**
|
||||
* A list of all available bitstream formats
|
||||
*/
|
||||
formats: BitstreamFormat[];
|
||||
|
||||
/**
|
||||
* @type {string} Key prefix used to generate form messages
|
||||
*/
|
||||
@@ -163,9 +154,22 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
/**
|
||||
* The Dynamic Input Model for the selected format
|
||||
*/
|
||||
selectedFormatModel = new DynamicSelectModel({
|
||||
selectedFormatModel = new DynamicScrollableDropdownModel({
|
||||
id: 'selectedFormat',
|
||||
name: 'selectedFormat'
|
||||
name: 'selectedFormat',
|
||||
displayKey: 'shortDescription',
|
||||
repeatable: false,
|
||||
metadataFields: [],
|
||||
submissionId: '',
|
||||
hasSelectableMetadata: false,
|
||||
findAllFactory: this.findAllFormatsServiceFactory(),
|
||||
formatFunction: (format: BitstreamFormat | string) => {
|
||||
if (format instanceof BitstreamFormat) {
|
||||
return hasValue(format) && format.supportLevel === BitstreamFormatSupportLevel.Unknown ? this.translate.instant(this.KEY_PREFIX + 'selectedFormat.unknown') : format.shortDescription;
|
||||
} else {
|
||||
return format;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -380,6 +384,11 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
* @private
|
||||
*/
|
||||
private bundle: Bundle;
|
||||
/**
|
||||
* The currently selected format
|
||||
* @private
|
||||
*/
|
||||
private selectedFormat: BitstreamFormat;
|
||||
|
||||
constructor(private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
@@ -407,25 +416,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
this.entityType = this.route.snapshot.queryParams.entityType;
|
||||
this.bitstreamRD$ = this.route.data.pipe(map((data: any) => data.bitstream));
|
||||
|
||||
this.bitstreamFormatsRD$ = this.bitstreamFormatService.findAll(this.findAllOptions).pipe(
|
||||
getFirstSucceededRemoteData(),
|
||||
expand((response: RemoteData<PaginatedList<BitstreamFormat>>) => {
|
||||
const pageInfo = response.payload.pageInfo;
|
||||
if (pageInfo.currentPage < pageInfo.totalPages) {
|
||||
const nextPageOptions = { ...this.findAllOptions, currentPage: pageInfo.currentPage + 1 };
|
||||
return this.bitstreamFormatService.findAll(nextPageOptions).pipe(getFirstSucceededRemoteData());
|
||||
} else {
|
||||
return EMPTY;
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
const bitstreamFormats$ = this.bitstreamFormatsRD$.pipe(
|
||||
reduce((acc: BitstreamFormat[], response: RemoteData<PaginatedList<BitstreamFormat>>) => {
|
||||
return acc.concat(response.payload.page);
|
||||
}, [])
|
||||
)
|
||||
|
||||
const bitstream$ = this.bitstreamRD$.pipe(
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
@@ -446,24 +436,31 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
switchMap((bundle: Bundle) => bundle.item),
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
);
|
||||
const format$ = bitstream$.pipe(
|
||||
switchMap(bitstream => bitstream.format),
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
);
|
||||
|
||||
this.subs.push(
|
||||
observableCombineLatest(
|
||||
bitstream$,
|
||||
bitstreamFormats$,
|
||||
bundle$,
|
||||
primaryBitstream$,
|
||||
item$,
|
||||
).pipe()
|
||||
.subscribe(([bitstream, allFormats, bundle, primaryBitstream, item]) => {
|
||||
format$,
|
||||
).subscribe(([bitstream, bundle, primaryBitstream, item, format]) => {
|
||||
this.bitstream = bitstream as Bitstream;
|
||||
this.formats = allFormats;
|
||||
this.bundle = bundle;
|
||||
this.selectedFormat = format;
|
||||
// hasValue(primaryBitstream) because if there's no primaryBitstream on the bundle it will
|
||||
// be a success response, but empty
|
||||
this.primaryBitstreamUUID = hasValue(primaryBitstream) ? primaryBitstream.uuid : null;
|
||||
this.itemId = item.uuid;
|
||||
this.setIiifStatus(this.bitstream);
|
||||
})
|
||||
}),
|
||||
format$.pipe(take(1)).subscribe(
|
||||
(format) => this.originalFormat = format,
|
||||
),
|
||||
);
|
||||
|
||||
this.subs.push(
|
||||
@@ -479,7 +476,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
setForm() {
|
||||
this.formGroup = this.formService.createFormGroup(this.formModel);
|
||||
this.updateFormatModel();
|
||||
this.updateForm(this.bitstream);
|
||||
this.updateFieldTranslations();
|
||||
}
|
||||
@@ -498,8 +494,9 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
description: bitstream.firstMetadataValue('dc.description')
|
||||
},
|
||||
formatContainer: {
|
||||
newFormat: hasValue(bitstream.firstMetadata('dc.format')) ? bitstream.firstMetadata('dc.format').value : undefined
|
||||
}
|
||||
selectedFormat: this.selectedFormat.shortDescription,
|
||||
newFormat: hasValue(bitstream.firstMetadata('dc.format')) ? bitstream.firstMetadata('dc.format').value : undefined,
|
||||
},
|
||||
});
|
||||
if (this.isIIIF) {
|
||||
this.formGroup.patchValue({
|
||||
@@ -517,36 +514,16 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
});
|
||||
}
|
||||
this.bitstream.format.pipe(
|
||||
getAllSucceededRemoteDataPayload()
|
||||
).subscribe((format: BitstreamFormat) => {
|
||||
this.originalFormat = format;
|
||||
this.formGroup.patchValue({
|
||||
formatContainer: {
|
||||
selectedFormat: format.id
|
||||
}
|
||||
});
|
||||
this.updateNewFormatLayout(format.id);
|
||||
});
|
||||
this.updateNewFormatLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the list of unknown format IDs an add options to the selectedFormatModel
|
||||
*/
|
||||
updateFormatModel() {
|
||||
this.selectedFormatModel.options = this.formats.map((format: BitstreamFormat) =>
|
||||
Object.assign({
|
||||
value: format.id,
|
||||
label: this.isUnknownFormat(format.id) ? this.translate.instant(this.KEY_PREFIX + 'selectedFormat.unknown') : format.shortDescription
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the layout of the "Other Format" input depending on the selected format
|
||||
* @param selectedId
|
||||
*/
|
||||
updateNewFormatLayout(selectedId: string) {
|
||||
if (this.isUnknownFormat(selectedId)) {
|
||||
updateNewFormatLayout() {
|
||||
if (this.isUnknownFormat()) {
|
||||
this.formLayout.newFormat.grid.host = this.newFormatBaseLayout;
|
||||
} else {
|
||||
this.formLayout.newFormat.grid.host = this.newFormatBaseLayout + ' invisible';
|
||||
@@ -557,9 +534,8 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
* Is the provided format (id) part of the list of unknown formats?
|
||||
* @param id
|
||||
*/
|
||||
isUnknownFormat(id: string): boolean {
|
||||
const format = this.formats.find((f: BitstreamFormat) => f.id === id);
|
||||
return hasValue(format) && format.supportLevel === BitstreamFormatSupportLevel.Unknown;
|
||||
isUnknownFormat(): boolean {
|
||||
return hasValue(this.selectedFormat) && this.selectedFormat.supportLevel === BitstreamFormatSupportLevel.Unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -591,7 +567,8 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
onChange(event) {
|
||||
const model = event.model;
|
||||
if (model.id === this.selectedFormatModel.id) {
|
||||
this.updateNewFormatLayout(model.value);
|
||||
this.selectedFormat = model.value;
|
||||
this.updateNewFormatLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -601,8 +578,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
onSubmit() {
|
||||
const updatedValues = this.formGroup.getRawValue();
|
||||
const updatedBitstream = this.formToBitstream(updatedValues);
|
||||
const selectedFormat = this.formats.find((f: BitstreamFormat) => f.id === updatedValues.formatContainer.selectedFormat);
|
||||
const isNewFormat = selectedFormat.id !== this.originalFormat.id;
|
||||
const isNewFormat = this.selectedFormat.id !== this.originalFormat.id;
|
||||
const isPrimary = updatedValues.fileNamePrimaryContainer.primaryBitstream;
|
||||
const wasPrimary = this.primaryBitstreamUUID === this.bitstream.uuid;
|
||||
|
||||
@@ -654,7 +630,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
bundle$ = observableOf(this.bundle);
|
||||
}
|
||||
if (isNewFormat) {
|
||||
bitstream$ = this.bitstreamService.updateFormat(this.bitstream, selectedFormat).pipe(
|
||||
bitstream$ = this.bitstreamService.updateFormat(this.bitstream, this.selectedFormat).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((formatResponse: RemoteData<Bitstream>) => {
|
||||
if (hasValue(formatResponse) && formatResponse.hasFailed) {
|
||||
@@ -812,4 +788,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
.forEach((subscription) => subscription.unsubscribe());
|
||||
}
|
||||
|
||||
findAllFormatsServiceFactory() {
|
||||
return () => this.bitstreamFormatService as any as FindAllDataImpl<BitstreamFormat>;
|
||||
}
|
||||
}
|
||||
|
@@ -40,20 +40,18 @@
|
||||
(scrolled)="onScroll()"
|
||||
[scrollWindow]="false">
|
||||
|
||||
<button class="dropdown-item disabled" type="button" *ngIf="optionsList && optionsList.length === 0">
|
||||
{{ 'form.no-results' | translate }}
|
||||
</button>
|
||||
<button class="dropdown-item disabled" *ngIf="optionsList && optionsList.length === 0">{{'form.no-results' | translate}}</button>
|
||||
<button class="dropdown-item collection-item text-truncate"
|
||||
(click)="onSelect(undefined); sdRef.close()" (mousedown)="onSelect(undefined); sdRef.close()"
|
||||
title="{{ 'dropdown.clear.tooltip' | translate }}" role="option"
|
||||
type="button">
|
||||
>
|
||||
<i>{{ 'dropdown.clear' | translate }}</i>
|
||||
</button>
|
||||
<button class="dropdown-item collection-item text-truncate" *ngFor="let listEntry of optionsList; let i = index"
|
||||
[class.active]="i === selectedIndex"
|
||||
(keydown.enter)="onSelect(listEntry); sdRef.close()" (mousedown)="onSelect(listEntry); sdRef.close()"
|
||||
title="{{ listEntry.display }}" role="option" type="button"
|
||||
[attr.id]="listEntry.display === (currentValue|async) ? ('combobox_' + id + '_selected') : null">
|
||||
title="{{ inputFormatter(listEntry) }}" role="option"
|
||||
[attr.id]="inputFormatter(listEntry) === (currentValue|async) ? ('combobox_' + id + '_selected') : null">
|
||||
{{inputFormatter(listEntry)}}
|
||||
</button>
|
||||
<div class="scrollable-dropdown-loading text-center" *ngIf="loading"><p>{{'form.loading' | translate}}</p></div>
|
||||
|
@@ -18,7 +18,7 @@ import { DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dyna
|
||||
import { VocabularyEntry } from '../../../../../../core/submission/vocabularies/models/vocabulary-entry.model';
|
||||
import { DynamicScrollableDropdownModel } from './dynamic-scrollable-dropdown.model';
|
||||
import { PageInfo } from '../../../../../../core/shared/page-info.model';
|
||||
import { isEmpty } from '../../../../../empty.util';
|
||||
import { hasValue, isEmpty } from '../../../../../empty.util';
|
||||
import { VocabularyService } from '../../../../../../core/submission/vocabularies/vocabulary.service';
|
||||
import { getFirstSucceededRemoteDataPayload } from '../../../../../../core/shared/operators';
|
||||
import {
|
||||
@@ -27,6 +27,8 @@ import {
|
||||
} from '../../../../../../core/data/paginated-list.model';
|
||||
import { DsDynamicVocabularyComponent } from '../dynamic-vocabulary.component';
|
||||
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
|
||||
import { FindAllData } from "../../../../../../core/data/base/find-all-data";
|
||||
import { CacheableObject } from "../../../../../../core/cache/cacheable-object.model";
|
||||
|
||||
/**
|
||||
* Component representing a dropdown input field
|
||||
@@ -55,6 +57,21 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
|
||||
public selectedIndex = 0;
|
||||
public acceptableKeys = ['Space', 'NumpadMultiply', 'NumpadAdd', 'NumpadSubtract', 'NumpadDecimal', 'Semicolon', 'Equal', 'Comma', 'Minus', 'Period', 'Quote', 'Backquote'];
|
||||
|
||||
/**
|
||||
* If true the component can rely on the findAll method for data loading.
|
||||
* This is a behaviour activated by dependency injection through the dropdown config.
|
||||
* If a service that implements findAll is not provided in the config the component falls back on the standard vocabulary service.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private useFindAllService: boolean;
|
||||
/**
|
||||
* A service that implements FindAllData.
|
||||
* If is provided in the config will be used for data loading in stead of the VocabularyService
|
||||
* @private
|
||||
*/
|
||||
private findAllService: FindAllData<CacheableObject>;
|
||||
|
||||
constructor(protected vocabularyService: VocabularyService,
|
||||
protected cdr: ChangeDetectorRef,
|
||||
protected layoutService: DynamicFormLayoutService,
|
||||
@@ -67,6 +84,9 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
|
||||
* Initialize the component, setting up the init form value
|
||||
*/
|
||||
ngOnInit() {
|
||||
this.findAllService = this.model?.findAllFactory();
|
||||
this.useFindAllService = hasValue(this.findAllService?.findAll) && typeof this.findAllService.findAll === 'function';
|
||||
|
||||
this.updatePageInfo(this.model.maxOptions, 1);
|
||||
this.loadOptions(true);
|
||||
this.group.get(this.model.id).valueChanges.pipe(distinctUntilChanged())
|
||||
@@ -75,13 +95,24 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get service and method to use to retrieve dropdown options
|
||||
*/
|
||||
getDataFromService(): Observable<RemoteData<PaginatedList<CacheableObject>>> {
|
||||
if (this.useFindAllService) {
|
||||
return this.findAllService.findAll({ elementsPerPage: this.pageInfo.elementsPerPage, currentPage: this.pageInfo.currentPage });
|
||||
} else {
|
||||
return this.vocabularyService.getVocabularyEntriesByValue(this.inputText, false, this.model.vocabularyOptions, this.pageInfo);
|
||||
}
|
||||
}
|
||||
|
||||
loadOptions(fromInit: boolean) {
|
||||
this.loading = true;
|
||||
this.vocabularyService.getVocabularyEntriesByValue(this.inputText, false, this.model.vocabularyOptions, this.pageInfo).pipe(
|
||||
this.getDataFromService().pipe(
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
catchError(() => observableOf(buildPaginatedList(new PageInfo(), []))),
|
||||
tap(() => this.loading = false)
|
||||
).subscribe((list: PaginatedList<VocabularyEntry>) => {
|
||||
tap(() => this.loading = false),
|
||||
).subscribe((list: PaginatedList<CacheableObject>) => {
|
||||
this.optionsList = list.page;
|
||||
if (fromInit && this.model.value) {
|
||||
this.setCurrentValue(this.model.value, true);
|
||||
@@ -101,7 +132,7 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
|
||||
/**
|
||||
* Converts an item from the result list to a `string` to display in the `<input>` field.
|
||||
*/
|
||||
inputFormatter = (x: VocabularyEntry): string => x.display || x.value;
|
||||
inputFormatter = (x: any): string => (this.model.formatFunction ? this.model.formatFunction(x) : (x.display || x.value));
|
||||
|
||||
/**
|
||||
* Opens dropdown menu
|
||||
@@ -204,7 +235,7 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
|
||||
this.pageInfo.totalElements,
|
||||
this.pageInfo.totalPages
|
||||
);
|
||||
this.vocabularyService.getVocabularyEntriesByValue(this.inputText, false, this.model.vocabularyOptions, this.pageInfo).pipe(
|
||||
this.getDataFromService().pipe(
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
catchError(() => observableOf(buildPaginatedList(
|
||||
new PageInfo(),
|
||||
@@ -212,7 +243,7 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
|
||||
))
|
||||
),
|
||||
tap(() => this.loading = false))
|
||||
.subscribe((list: PaginatedList<VocabularyEntry>) => {
|
||||
.subscribe((list: PaginatedList<any>) => {
|
||||
this.optionsList = this.optionsList.concat(list.page);
|
||||
this.updatePageInfo(
|
||||
list.pageInfo.elementsPerPage,
|
||||
@@ -243,7 +274,7 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
|
||||
setCurrentValue(value: any, init = false): void {
|
||||
let result: Observable<string>;
|
||||
|
||||
if (init) {
|
||||
if (init && !this.useFindAllService) {
|
||||
result = this.getInitValueFromModel().pipe(
|
||||
map((formValue: FormFieldMetadataValueObject) => formValue.display)
|
||||
);
|
||||
@@ -252,6 +283,8 @@ export class DsDynamicScrollableDropdownComponent extends DsDynamicVocabularyCom
|
||||
result = observableOf('');
|
||||
} else if (typeof value === 'string') {
|
||||
result = observableOf(value);
|
||||
} else if (this.useFindAllService) {
|
||||
result = observableOf(value[this.model.displayKey]);
|
||||
} else {
|
||||
result = observableOf(value.display);
|
||||
}
|
||||
|
@@ -1,19 +1,33 @@
|
||||
import { AUTOCOMPLETE_OFF, DynamicFormControlLayout, serializable } from '@ng-dynamic-forms/core';
|
||||
import { DsDynamicInputModel, DsDynamicInputModelConfig } from '../ds-dynamic-input.model';
|
||||
import { VocabularyOptions } from '../../../../../../core/submission/vocabularies/models/vocabulary-options.model';
|
||||
import { FindAllDataImpl } from "../../../../../../core/data/base/find-all-data";
|
||||
import { CacheableObject } from "../../../../../../core/cache/cacheable-object.model";
|
||||
|
||||
export const DYNAMIC_FORM_CONTROL_TYPE_SCROLLABLE_DROPDOWN = 'SCROLLABLE_DROPDOWN';
|
||||
|
||||
export interface DynamicScrollableDropdownModelConfig extends DsDynamicInputModelConfig {
|
||||
vocabularyOptions: VocabularyOptions;
|
||||
vocabularyOptions?: VocabularyOptions;
|
||||
maxOptions?: number;
|
||||
value?: any;
|
||||
displayKey?: string;
|
||||
formatFunction?: (value: any) => string;
|
||||
findAllFactory?: () => FindAllDataImpl<CacheableObject>;
|
||||
}
|
||||
|
||||
export class DynamicScrollableDropdownModel extends DsDynamicInputModel {
|
||||
|
||||
@serializable() maxOptions: number;
|
||||
@serializable() readonly type: string = DYNAMIC_FORM_CONTROL_TYPE_SCROLLABLE_DROPDOWN;
|
||||
@serializable() displayKey: string;
|
||||
/**
|
||||
* Configurable function for display value formatting in input
|
||||
*/
|
||||
formatFunction: (value: any) => string;
|
||||
/**
|
||||
* Factory for a service that implements FindAllData
|
||||
*/
|
||||
findAllFactory: () => FindAllDataImpl<CacheableObject>;
|
||||
|
||||
constructor(config: DynamicScrollableDropdownModelConfig, layout?: DynamicFormControlLayout) {
|
||||
|
||||
@@ -22,6 +36,9 @@ export class DynamicScrollableDropdownModel extends DsDynamicInputModel {
|
||||
this.autoComplete = AUTOCOMPLETE_OFF;
|
||||
this.vocabularyOptions = config.vocabularyOptions;
|
||||
this.maxOptions = config.maxOptions || 10;
|
||||
this.displayKey = config.displayKey || 'display';
|
||||
this.formatFunction = config.formatFunction;
|
||||
this.findAllFactory = config.findAllFactory || (() => null);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user