62589: Refactoring mapping endpoint and methods to mapped + collection-list sorting bugfix

This commit is contained in:
Kristof De Langhe
2019-08-19 14:18:10 +02:00
parent 26e25069ad
commit c95fa8fb96
11 changed files with 36 additions and 26 deletions

View File

@@ -34,7 +34,7 @@
<div> <div>
<ds-item-select class="mt-2" <ds-item-select class="mt-2"
[key]="'map'" [key]="'map'"
[dsoRD$]="mappingItemsRD$" [dsoRD$]="mappedItemsRD$"
[paginationOptions]="(searchOptions$ | async)?.pagination" [paginationOptions]="(searchOptions$ | async)?.pagination"
[confirmButton]="'collection.item-mapper.confirm'" [confirmButton]="'collection.item-mapper.confirm'"
(confirm)="mapItems($event)"></ds-item-select> (confirm)="mapItems($event)"></ds-item-select>

View File

@@ -93,7 +93,7 @@ describe('CollectionItemMapperComponent', () => {
const collectionDataServiceStub = { const collectionDataServiceStub = {
getMappedItems: () => of(emptyList), getMappedItems: () => of(emptyList),
/* tslint:disable:no-empty */ /* tslint:disable:no-empty */
clearMappingItemsRequests: () => {} clearMappedItemsRequests: () => {}
/* tslint:enable:no-empty */ /* tslint:enable:no-empty */
}; };
const routeServiceStub = { const routeServiceStub = {

View File

@@ -64,7 +64,7 @@ export class CollectionItemMapperComponent implements OnInit {
* List of items to show under the "Map" tab * List of items to show under the "Map" tab
* Items outside the collection * Items outside the collection
*/ */
mappingItemsRD$: Observable<RemoteData<PaginatedList<DSpaceObject>>>; mappedItemsRD$: Observable<RemoteData<PaginatedList<DSpaceObject>>>;
/** /**
* Sort on title ASC by default * Sort on title ASC by default
@@ -96,7 +96,7 @@ export class CollectionItemMapperComponent implements OnInit {
/** /**
* Load collectionItemsRD$ with a fixed scope to only obtain the items this collection owns * Load collectionItemsRD$ with a fixed scope to only obtain the items this collection owns
* Load mappingItemsRD$ to only obtain items this collection doesn't own * Load mappedItemsRD$ to only obtain items this collection doesn't own
*/ */
loadItemLists() { loadItemLists() {
this.shouldUpdate$ = new BehaviorSubject<boolean>(true); this.shouldUpdate$ = new BehaviorSubject<boolean>(true);
@@ -114,7 +114,7 @@ export class CollectionItemMapperComponent implements OnInit {
} }
}) })
); );
this.mappingItemsRD$ = collectionAndOptions$.pipe( this.mappedItemsRD$ = collectionAndOptions$.pipe(
switchMap(([collectionRD, options, shouldUpdate]) => { switchMap(([collectionRD, options, shouldUpdate]) => {
if (shouldUpdate) { if (shouldUpdate) {
return this.searchService.search(Object.assign(new PaginatedSearchOptions(options), { return this.searchService.search(Object.assign(new PaginatedSearchOptions(options), {
@@ -190,7 +190,7 @@ export class CollectionItemMapperComponent implements OnInit {
*/ */
private clearRequestCache() { private clearRequestCache() {
this.collectionRD$.pipe(take(1)).subscribe((collectionRD: RemoteData<Collection>) => { this.collectionRD$.pipe(take(1)).subscribe((collectionRD: RemoteData<Collection>) => {
this.collectionDataService.clearMappingItemsRequests(collectionRD.payload.id); this.collectionDataService.clearMappedItemsRequests(collectionRD.payload.id);
this.searchService.clearDiscoveryRequests(); this.searchService.clearDiscoveryRequests();
}); });
} }

View File

@@ -32,8 +32,9 @@
<div> <div>
<ds-collection-select class="mt-2" <ds-collection-select class="mt-2"
[key]="'map'" [key]="'map'"
[dsoRD$]="mappingCollectionsRD$" [dsoRD$]="mappedCollectionsRD$"
[paginationOptions]="(searchOptions$ | async)?.pagination" [paginationOptions]="(searchOptions$ | async)?.pagination"
[sortOptions]="(searchOptions$ | async)?.sort"
[confirmButton]="'item.edit.item-mapper.buttons.add'" [confirmButton]="'item.edit.item-mapper.buttons.add'"
(confirm)="mapCollections($event)"></ds-collection-select> (confirm)="mapCollections($event)"></ds-collection-select>
</div> </div>

View File

@@ -54,7 +54,7 @@ export class ItemCollectionMapperComponent implements OnInit {
* List of collections to show under the "Map" tab * List of collections to show under the "Map" tab
* Collections that are not mapped to the item * Collections that are not mapped to the item
*/ */
mappingCollectionsRD$: Observable<RemoteData<PaginatedList<Collection>>>; mappedCollectionsRD$: Observable<RemoteData<PaginatedList<Collection>>>;
/** /**
* Firing this observable (shouldUpdate$.next(true)) forces the two lists to reload themselves * Firing this observable (shouldUpdate$.next(true)) forces the two lists to reload themselves
@@ -79,7 +79,7 @@ export class ItemCollectionMapperComponent implements OnInit {
/** /**
* Load itemCollectionsRD$ with a fixed scope to only obtain the collections that own this item * Load itemCollectionsRD$ with a fixed scope to only obtain the collections that own this item
* Load mappingCollectionsRD$ to only obtain collections that don't own this item * Load mappedCollectionsRD$ to only obtain collections that don't own this item
*/ */
loadCollectionLists() { loadCollectionLists() {
this.shouldUpdate$ = new BehaviorSubject<boolean>(true); this.shouldUpdate$ = new BehaviorSubject<boolean>(true);
@@ -96,7 +96,7 @@ export class ItemCollectionMapperComponent implements OnInit {
this.itemCollectionsRD$, this.itemCollectionsRD$,
this.searchOptions$ this.searchOptions$
); );
this.mappingCollectionsRD$ = itemCollectionsAndOptions$.pipe( this.mappedCollectionsRD$ = itemCollectionsAndOptions$.pipe(
switchMap(([itemCollectionsRD, searchOptions]) => { switchMap(([itemCollectionsRD, searchOptions]) => {
return this.searchService.search(Object.assign(new PaginatedSearchOptions(searchOptions), { return this.searchService.search(Object.assign(new PaginatedSearchOptions(searchOptions), {
query: this.buildQuery(itemCollectionsRD.payload.page, searchOptions.query), query: this.buildQuery(itemCollectionsRD.payload.page, searchOptions.query),

View File

@@ -69,10 +69,10 @@ export class CollectionDataService extends ComColDataService<Collection> {
* Fetches the endpoint used for mapping items to a collection * Fetches the endpoint used for mapping items to a collection
* @param collectionId The id of the collection to map items to * @param collectionId The id of the collection to map items to
*/ */
getMappingItemsEndpoint(collectionId): Observable<string> { getMappedItemsEndpoint(collectionId): Observable<string> {
return this.halService.getEndpoint(this.linkPath).pipe( return this.halService.getEndpoint(this.linkPath).pipe(
map((endpoint: string) => this.getIDHref(endpoint, collectionId)), map((endpoint: string) => this.getIDHref(endpoint, collectionId)),
map((endpoint: string) => `${endpoint}/mappingItems`) map((endpoint: string) => `${endpoint}/mappedItems`)
); );
} }
@@ -84,7 +84,7 @@ export class CollectionDataService extends ComColDataService<Collection> {
getMappedItems(collectionId: string, searchOptions?: PaginatedSearchOptions): Observable<RemoteData<PaginatedList<DSpaceObject>>> { getMappedItems(collectionId: string, searchOptions?: PaginatedSearchOptions): Observable<RemoteData<PaginatedList<DSpaceObject>>> {
const requestUuid = this.requestService.generateRequestId(); const requestUuid = this.requestService.generateRequestId();
const href$ = this.getMappingItemsEndpoint(collectionId).pipe( const href$ = this.getMappedItemsEndpoint(collectionId).pipe(
isNotEmptyOperator(), isNotEmptyOperator(),
distinctUntilChanged(), distinctUntilChanged(),
map((endpoint: string) => hasValue(searchOptions) ? searchOptions.toRestUrl(endpoint) : endpoint) map((endpoint: string) => hasValue(searchOptions) ? searchOptions.toRestUrl(endpoint) : endpoint)
@@ -106,11 +106,11 @@ export class CollectionDataService extends ComColDataService<Collection> {
} }
/** /**
* Clears all requests (from cache) connected to the mappingItems endpoint * Clears all requests (from cache) connected to the mappedItems endpoint
* @param collectionId * @param collectionId
*/ */
clearMappingItemsRequests(collectionId: string) { clearMappedItemsRequests(collectionId: string) {
this.getMappingItemsEndpoint(collectionId).pipe(take(1)).subscribe((href: string) => { this.getMappedItemsEndpoint(collectionId).pipe(take(1)).subscribe((href: string) => {
this.requestService.removeByHrefSubstring(href); this.requestService.removeByHrefSubstring(href);
}); });
} }

View File

@@ -80,7 +80,7 @@ export class ItemDataService extends DataService<Item> {
* @param itemId The item's id * @param itemId The item's id
* @param collectionId The collection's id (optional) * @param collectionId The collection's id (optional)
*/ */
public getMappingCollectionsEndpoint(itemId: string, collectionId?: string): Observable<string> { public getMappedCollectionsEndpoint(itemId: string, collectionId?: string): Observable<string> {
return this.halService.getEndpoint(this.linkPath).pipe( return this.halService.getEndpoint(this.linkPath).pipe(
map((endpoint: string) => this.getIDHref(endpoint, itemId)), map((endpoint: string) => this.getIDHref(endpoint, itemId)),
map((endpoint: string) => `${endpoint}/mappedCollections${collectionId ? `/${collectionId}` : ''}`) map((endpoint: string) => `${endpoint}/mappedCollections${collectionId ? `/${collectionId}` : ''}`)
@@ -93,7 +93,7 @@ export class ItemDataService extends DataService<Item> {
* @param collectionId The collection's id * @param collectionId The collection's id
*/ */
public removeMappingFromCollection(itemId: string, collectionId: string): Observable<RestResponse> { public removeMappingFromCollection(itemId: string, collectionId: string): Observable<RestResponse> {
return this.getMappingCollectionsEndpoint(itemId, collectionId).pipe( return this.getMappedCollectionsEndpoint(itemId, collectionId).pipe(
isNotEmptyOperator(), isNotEmptyOperator(),
distinctUntilChanged(), distinctUntilChanged(),
map((endpointURL: string) => new DeleteRequest(this.requestService.generateRequestId(), endpointURL)), map((endpointURL: string) => new DeleteRequest(this.requestService.generateRequestId(), endpointURL)),
@@ -109,7 +109,7 @@ export class ItemDataService extends DataService<Item> {
* @param collectionHref The collection's self link * @param collectionHref The collection's self link
*/ */
public mapToCollection(itemId: string, collectionHref: string): Observable<RestResponse> { public mapToCollection(itemId: string, collectionHref: string): Observable<RestResponse> {
return this.getMappingCollectionsEndpoint(itemId).pipe( return this.getMappedCollectionsEndpoint(itemId).pipe(
isNotEmptyOperator(), isNotEmptyOperator(),
distinctUntilChanged(), distinctUntilChanged(),
map((endpointURL: string) => { map((endpointURL: string) => {
@@ -130,7 +130,7 @@ export class ItemDataService extends DataService<Item> {
* @param itemId The item's id * @param itemId The item's id
*/ */
public getMappedCollections(itemId: string): Observable<RemoteData<PaginatedList<Collection>>> { public getMappedCollections(itemId: string): Observable<RemoteData<PaginatedList<Collection>>> {
const request$ = this.getMappingCollectionsEndpoint(itemId).pipe( const request$ = this.getMappedCollectionsEndpoint(itemId).pipe(
isNotEmptyOperator(), isNotEmptyOperator(),
distinctUntilChanged(), distinctUntilChanged(),
map((endpointURL: string) => new MappedCollectionsRequest(this.requestService.generateRequestId(), endpointURL)), map((endpointURL: string) => new MappedCollectionsRequest(this.requestService.generateRequestId(), endpointURL)),
@@ -149,11 +149,11 @@ export class ItemDataService extends DataService<Item> {
} }
/** /**
* Clears all requests (from cache) connected to the mappingCollections endpoint * Clears all requests (from cache) connected to the mappedCollections endpoint
* @param itemId * @param itemId
*/ */
public clearMappedCollectionsRequests(itemId: string) { public clearMappedCollectionsRequests(itemId: string) {
this.getMappingCollectionsEndpoint(itemId).pipe(take(1)).subscribe((href: string) => { this.getMappedCollectionsEndpoint(itemId).pipe(take(1)).subscribe((href: string) => {
this.requestService.removeByHrefSubstring(href); this.requestService.removeByHrefSubstring(href);
}); });
} }

View File

@@ -18,18 +18,18 @@ export class MappedCollectionsReponseParsingService implements ResponseParsingSe
if (payload._embedded && payload._embedded.mappedCollections) { if (payload._embedded && payload._embedded.mappedCollections) {
const mappedCollections = payload._embedded.mappedCollections; const mappedCollections = payload._embedded.mappedCollections;
// TODO: When the API supports it, change this to fetch a paginated list, instead of creating static one // TODO: When the API supports it, change this to fetch a paginated list, instead of creating static one
// Reason: Pagination is currently not supported on the mappingCollections endpoint // Reason: Pagination is currently not supported on the mappedCollections endpoint
const paginatedMappingCollections = new PaginatedList(Object.assign(new PageInfo(), { const paginatedMappedCollections = new PaginatedList(Object.assign(new PageInfo(), {
elementsPerPage: mappedCollections.length, elementsPerPage: mappedCollections.length,
totalElements: mappedCollections.length, totalElements: mappedCollections.length,
totalPages: 1, totalPages: 1,
currentPage: 1 currentPage: 1
}), mappedCollections); }), mappedCollections);
return new GenericSuccessResponse(paginatedMappingCollections, data.statusCode, data.statusText); return new GenericSuccessResponse(paginatedMappedCollections, data.statusCode, data.statusText);
} else { } else {
return new ErrorResponse( return new ErrorResponse(
Object.assign( Object.assign(
new Error('Unexpected response from mappingCollections endpoint'), data new Error('Unexpected response from mappedCollections endpoint'), data
) )
); );
} }

View File

@@ -2,6 +2,7 @@
<ds-pagination <ds-pagination
*ngIf="collectionsRD?.payload?.totalElements > 0" *ngIf="collectionsRD?.payload?.totalElements > 0"
[paginationOptions]="paginationOptions" [paginationOptions]="paginationOptions"
[sortOptions]="sortOptions"
[pageInfoState]="collectionsRD?.payload" [pageInfoState]="collectionsRD?.payload"
[collectionSize]="collectionsRD?.payload?.totalElements" [collectionSize]="collectionsRD?.payload?.totalElements"
[hidePagerWhenSinglePage]="true" [hidePagerWhenSinglePage]="true"

View File

@@ -2,6 +2,7 @@
<ds-pagination <ds-pagination
*ngIf="itemsRD?.payload?.totalElements > 0" *ngIf="itemsRD?.payload?.totalElements > 0"
[paginationOptions]="paginationOptions" [paginationOptions]="paginationOptions"
[sortOptions]="sortOptions"
[pageInfoState]="itemsRD?.payload" [pageInfoState]="itemsRD?.payload"
[collectionSize]="itemsRD?.payload?.totalElements" [collectionSize]="itemsRD?.payload?.totalElements"
[hidePagerWhenSinglePage]="true" [hidePagerWhenSinglePage]="true"

View File

@@ -5,6 +5,7 @@ import { RemoteData } from '../../../core/data/remote-data';
import { PaginatedList } from '../../../core/data/paginated-list'; import { PaginatedList } from '../../../core/data/paginated-list';
import { PaginationComponentOptions } from '../../pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../pagination/pagination-component-options.model';
import { ObjectSelectService } from '../object-select.service'; import { ObjectSelectService } from '../object-select.service';
import { SortOptions } from '../../../core/cache/models/sort-options.model';
/** /**
* An abstract component used to select DSpaceObjects from a specific list and returning the UUIDs of the selected DSpaceObjects * An abstract component used to select DSpaceObjects from a specific list and returning the UUIDs of the selected DSpaceObjects
@@ -26,6 +27,12 @@ export abstract class ObjectSelectComponent<TDomain> implements OnInit, OnDestro
@Input() @Input()
paginationOptions: PaginationComponentOptions; paginationOptions: PaginationComponentOptions;
/**
* The sorting options used to display the DSpaceObjects
*/
@Input()
sortOptions: SortOptions;
/** /**
* The message key used for the confirm button * The message key used for the confirm button
* @type {string} * @type {string}