Skip to content

Commit

Permalink
[DURACOM-304] refactor, fix dynamic-list.component loading
Browse files Browse the repository at this point in the history
  • Loading branch information
FrancescoMolinaro committed Jan 17, 2025
1 parent c79affd commit 9570cd9
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 91 deletions.
46 changes: 4 additions & 42 deletions src/app/core/data/bundle-data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ export class BundleDataService extends IdentifiableDataService<Bundle> implement
*/
// TODO should be implemented rest side
findByItemAndName(item: Item, bundleName: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, options?: FindListOptions, ...linksToFollow: FollowLinkConfig<Bundle>[]): Observable<RemoteData<Bundle>> {
return this.findAllByItem(item, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow).pipe(
//Since we filter by bundleName where the pagination options are not indicated we need to load all the possible bundles.
// This is a workaround, in substitution of the previously recursive call with expand
const paginationOptions = options ?? { elementsPerPage: 9999 };
return this.findAllByItem(item, paginationOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow).pipe(
map((rd: RemoteData<PaginatedList<Bundle>>) => {
if (hasValue(rd.payload) && hasValue(rd.payload.page)) {
const matchingBundle = rd.payload.page.find((bundle: Bundle) =>
Expand Down Expand Up @@ -115,47 +118,6 @@ export class BundleDataService extends IdentifiableDataService<Bundle> implement
);
}

// findByItemAndName(item: Item, bundleName: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<Bundle>[]): Observable<RemoteData<Bundle>> {
// return this.findAllByItem(item, { elementsPerPage: 1, currentPage: 1 }, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow).pipe(
// expand((rd: RemoteData<PaginatedList<Bundle>>) => {
// if (rd.hasSucceeded && hasValue(rd.payload) && hasValue(rd.payload.page) && rd.payload.currentPage < rd.payload.totalPages) {
// const nextPageOptions = { elementsPerPage: 1, currentPage: rd.payload.currentPage + 1 };
// return this.findAllByItem(item, nextPageOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
// } else {
// return EMPTY;
// }
// }),
// map((rd: RemoteData<PaginatedList<Bundle>>) => {
// if (hasValue(rd.payload) && hasValue(rd.payload.page)) {
// const matchingBundle = rd.payload.page.find((bundle: Bundle) => bundle.name === bundleName);
// if (hasValue(matchingBundle)) {
// return new RemoteData(
// rd.timeCompleted,
// rd.msToLive,
// rd.lastUpdated,
// RequestEntryState.Success,
// null,
// matchingBundle,
// 200
// );
// } else {
// return new RemoteData(
// rd.timeCompleted,
// rd.msToLive,
// rd.lastUpdated,
// RequestEntryState.Error,
// `The bundle with name ${bundleName} was not found.`,
// null,
// 404
// );
// }
// } else {
// return rd as any;
// }
// })
// );
// }

/**
* Get the bitstreams endpoint for a bundle
* @param bundleId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
aria-describedby="reorder-description">
</ds-item-edit-bitstream-bundle>
<div class="d-flex justify-content-center" *ngIf="showLoadMoreLink$ | async">
<div class="btn btn-link py-3" (click)="loadBundles()"> {{'item.edit.bitstreams.load-more.link' | translate}}</div>
<button class="btn btn-link my-3" (click)="loadBundles()"> {{'item.edit.bitstreams.load-more.link' | translate}}</button>
</div>
</div>
<div *ngIf="bundles?.length === 0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@
</div>
</div>

<div class="d-flex justify-content-center" *ngIf="(showLoadMore$ | async)">
<div *ngIf="(showLoadMore$ | async)" class="btn btn-link py-3" (click)="loadEntries()">{{'dynamic-list.load-more' | translate}}</div>
<div class="d-flex justify-content-center" *ngIf="(isLoading$ | async)">
<ds-loading></ds-loading>
</div>

</div>
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Component,
EventEmitter,
Input,
OnDestroy,
OnInit,
Output,
} from '@angular/core';
Expand All @@ -28,7 +29,10 @@ import {
} from '@ng-dynamic-forms/core';
import { TranslateModule } from '@ngx-translate/core';
import findKey from 'lodash/findKey';
import { BehaviorSubject } from 'rxjs';
import {
BehaviorSubject,
Subscription,
} from 'rxjs';
import {
map,
tap,
Expand All @@ -43,6 +47,7 @@ import {
hasValue,
isNotEmpty,
} from '../../../../../empty.util';
import { ThemedLoadingComponent } from '../../../../../loading/themed-loading.component';
import { FormBuilderService } from '../../../form-builder.service';
import { DynamicListCheckboxGroupModel } from './dynamic-list-checkbox-group.model';
import { DynamicListRadioGroupModel } from './dynamic-list-radio-group.model';
Expand All @@ -69,10 +74,11 @@ export interface ListItem {
ReactiveFormsModule,
AsyncPipe,
TranslateModule,
ThemedLoadingComponent,
],
standalone: true,
})
export class DsDynamicListComponent extends DynamicFormControlComponent implements OnInit {
export class DsDynamicListComponent extends DynamicFormControlComponent implements OnInit, OnDestroy {

@Input() group: UntypedFormGroup;
@Input() model: any;
Expand All @@ -82,9 +88,10 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
@Output() focus: EventEmitter<any> = new EventEmitter<any>();

public items: ListItem[][] = [];
public showLoadMore$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
public isLoading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
protected optionsList: VocabularyEntry[] = [];
private nextPageInfo: PageInfo;
private subs: Subscription[] = [];

constructor(private vocabularyService: VocabularyService,
private cdr: ChangeDetectorRef,
Expand All @@ -104,6 +111,12 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
}
}

ngOnDestroy() {
if (this.subs.length > 0) {
this.subs.forEach(sub => sub.unsubscribe());
}
}

/**
* Emits a blur event containing a given value.
* @param event The value to emit.
Expand Down Expand Up @@ -178,9 +191,9 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
setPaginationInfo(response: PaginatedList<VocabularyEntry>) {
if (response.pageInfo.currentPage < response.pageInfo.totalPages) {
this.nextPageInfo = Object.assign(new PageInfo(), response.pageInfo, { currentPage: response.currentPage + 1 });
this.showLoadMore$.next(true);
this.isLoading$.next(true);

Check warning on line 194 in src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts#L193-L194

Added lines #L193 - L194 were not covered by tests
} else {
this.showLoadMore$.next(false);
this.isLoading$.next(false);
}
}

Expand All @@ -194,47 +207,53 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
listGroup = this.group.controls[this.model.id] as UntypedFormGroup;

Check warning on line 207 in src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts#L207

Added line #L207 was not covered by tests
}

this.vocabularyService.getVocabularyEntries(this.model.vocabularyOptions, this.nextPageInfo).pipe(
getFirstSucceededRemoteDataPayload(),
tap((response) => this.setPaginationInfo(response)),
map(entries => entries.page),
).subscribe((allEntries: VocabularyEntry[]) => {
this.optionsList = [...this.optionsList, ...allEntries];
let groupCounter = (this.items.length > 0) ? (this.items.length - 1) : 0;
let itemsPerGroup = 0;
let tempList: ListItem[] = [];

// Make a list of available options (checkbox/radio) and split in groups of 'model.groupLength'
allEntries.forEach((option: VocabularyEntry, key: number) => {
const value = option.authority || option.value;
const checked: boolean = isNotEmpty(findKey(
this.model.value,
(v) => v?.value === option.value));

const item: ListItem = {
id: `${this.model.id}_${value}`,
label: option.display,
value: checked,
index: key,
};
if (this.model.repeatable) {
this.formBuilderService.addFormGroupControl(listGroup, (this.model as DynamicListCheckboxGroupModel), new DynamicCheckboxModel(item));
} else {
(this.model as DynamicListRadioGroupModel).options.push({
label: item.label,
value: option,
});
}
tempList.push(item);
itemsPerGroup++;
this.items[groupCounter] = tempList;
if (itemsPerGroup === this.model.groupLength) {
groupCounter++;
itemsPerGroup = 0;
tempList = [];
this.subs.push(
this.vocabularyService.getVocabularyEntries(this.model.vocabularyOptions, this.nextPageInfo).pipe(
getFirstSucceededRemoteDataPayload(),
tap((response) => this.setPaginationInfo(response)),
map(entries => entries.page),
).subscribe((allEntries: VocabularyEntry[]) => {
this.optionsList = [...this.optionsList, ...allEntries];
let groupCounter = this.items.length;
let itemsPerGroup = 0;
let tempList: ListItem[] = [];

// Make a list of available options (checkbox/radio) and split in groups of 'model.groupLength'
allEntries.forEach((option: VocabularyEntry) => {
const value = option.authority || option.value;
const checked: boolean = isNotEmpty(findKey(
this.model.value,
(v) => v?.value === option.value));

const item: ListItem = {
id: `${this.model.id}_${value}`,
label: option.display,
value: checked,
index: this.optionsList.indexOf(option),
};
if (this.model.repeatable) {
this.formBuilderService.addFormGroupControl(listGroup, (this.model as DynamicListCheckboxGroupModel), new DynamicCheckboxModel(item));
} else {
(this.model as DynamicListRadioGroupModel).options.push({
label: item.label,
value: option,
});
}
tempList.push(item);
itemsPerGroup++;
this.items[groupCounter] = tempList;
if (itemsPerGroup === this.model.groupLength) {
groupCounter++;
itemsPerGroup = 0;
tempList = [];
}
});
this.cdr.markForCheck();
// If the paginated request did not reach the end keep loading the entries in the background
if (this.isLoading$.value) {
this.loadEntries();

Check warning on line 254 in src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts#L254

Added line #L254 was not covered by tests
}
});
this.cdr.markForCheck();
});
}),
);
}
}

0 comments on commit 9570cd9

Please sign in to comment.