mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
[TLC-674] Refactor duplicates from item link to searchBy
This commit is contained in:
@@ -46,6 +46,9 @@ import { RestRequestMethod } from './rest-request-method';
|
||||
import { CreateData, CreateDataImpl } from './base/create-data';
|
||||
import { RequestParam } from '../cache/models/request-param.model';
|
||||
import { dataService } from './base/data-service.decorator';
|
||||
import { Duplicate } from '../../shared/object-list/duplicate-data/duplicate.model';
|
||||
import { SearchDataImpl } from './base/search-data';
|
||||
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||
|
||||
/**
|
||||
* An abstract service for CRUD operations on Items
|
||||
@@ -56,6 +59,7 @@ export abstract class BaseItemDataService extends IdentifiableDataService<Item>
|
||||
private createData: CreateData<Item>;
|
||||
private patchData: PatchData<Item>;
|
||||
private deleteData: DeleteData<Item>;
|
||||
private searchData: SearchDataImpl<Duplicate>;
|
||||
|
||||
protected constructor(
|
||||
protected linkPath,
|
||||
@@ -74,6 +78,7 @@ export abstract class BaseItemDataService extends IdentifiableDataService<Item>
|
||||
this.createData = new CreateDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService, this.responseMsToLive);
|
||||
this.patchData = new PatchDataImpl<Item>(this.linkPath, requestService, rdbService, objectCache, halService, comparator, this.responseMsToLive, this.constructIdEndpoint);
|
||||
this.deleteData = new DeleteDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService, this.responseMsToLive, this.constructIdEndpoint);
|
||||
this.searchData = new SearchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,24 +247,18 @@ export abstract class BaseItemDataService extends IdentifiableDataService<Item>
|
||||
);
|
||||
}
|
||||
|
||||
public getDuplicatesEndpoint(itemId: string): Observable<string> {
|
||||
return this.halService.getEndpoint(this.linkPath).pipe(
|
||||
switchMap((url: string) => this.halService.getEndpoint('duplicates', `${url}/${itemId}`))
|
||||
);
|
||||
public findDuplicates(uuid: string, options?: FindListOptions, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<Duplicate>[]): Observable<RemoteData<PaginatedList<Duplicate>>> {
|
||||
const searchParams = [new RequestParam('uuid', uuid)];
|
||||
let findListOptions = new FindListOptions();
|
||||
if (options) {
|
||||
findListOptions = Object.assign(new FindListOptions(), options);
|
||||
}
|
||||
|
||||
public getDuplicates(itemId: string, searchOptions?: PaginatedSearchOptions): Observable<RemoteData<PaginatedList<Item>>> {
|
||||
const hrefObs = this.getDuplicatesEndpoint(itemId).pipe(
|
||||
map((href) => searchOptions ? searchOptions.toRestUrl(href) : href)
|
||||
);
|
||||
hrefObs.pipe(
|
||||
take(1)
|
||||
).subscribe((href) => {
|
||||
const request = new GetRequest(this.requestService.generateRequestId(), href);
|
||||
this.requestService.send(request);
|
||||
});
|
||||
|
||||
return this.rdbService.buildList<Item>(hrefObs);
|
||||
if (findListOptions.searchParams) {
|
||||
findListOptions.searchParams = [...findListOptions.searchParams, ...searchParams];
|
||||
} else {
|
||||
findListOptions.searchParams = searchParams;
|
||||
}
|
||||
return this.searchData.searchBy('findDuplicates', findListOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -26,7 +26,6 @@ import { AccessStatusObject } from 'src/app/shared/object-collection/shared/badg
|
||||
import { HandleObject } from './handle-object.model';
|
||||
import { IDENTIFIERS } from '../../shared/object-list/identifier-data/identifier-data.resource-type';
|
||||
import { IdentifierData } from '../../shared/object-list/identifier-data/identifier-data.model';
|
||||
import { Duplicate } from '../../shared/object-list/duplicate-data/duplicate.model';
|
||||
|
||||
/**
|
||||
* Class representing a DSpace Item
|
||||
@@ -80,7 +79,6 @@ export class Item extends DSpaceObject implements ChildHALResource, HandleObject
|
||||
thumbnail: HALLink;
|
||||
accessStatus: HALLink;
|
||||
identifiers: HALLink;
|
||||
duplicates: HALLink;
|
||||
self: HALLink;
|
||||
};
|
||||
|
||||
@@ -133,9 +131,6 @@ export class Item extends DSpaceObject implements ChildHALResource, HandleObject
|
||||
@link(IDENTIFIERS, false, 'identifiers')
|
||||
identifiers?: Observable<RemoteData<IdentifierData>>;
|
||||
|
||||
@link(ITEM, true, 'duplicates')
|
||||
duplicates?: Observable<RemoteData<PaginatedList<Duplicate>>>;
|
||||
|
||||
/**
|
||||
* Method that returns as which type of object this object should be rendered
|
||||
*/
|
||||
|
@@ -1,7 +1,14 @@
|
||||
import { autoserialize } from 'cerialize';
|
||||
import {autoserialize, deserialize} from 'cerialize';
|
||||
import { MetadataMap } from '../../../core/shared/metadata.models';
|
||||
import { HALLink} from '../../../core/shared/hal-link.model';
|
||||
import { CacheableObject } from '../../../core/cache/cacheable-object.model';
|
||||
import { DUPLICATE } from './duplicate.resource-type';
|
||||
import { ResourceType } from '../../../core/shared/resource-type';
|
||||
|
||||
export class Duplicate implements CacheableObject {
|
||||
|
||||
static type = DUPLICATE;
|
||||
|
||||
export class Duplicate {
|
||||
/**
|
||||
* The item title
|
||||
*/
|
||||
@@ -23,5 +30,13 @@ export class Duplicate {
|
||||
metadata: MetadataMap;
|
||||
|
||||
@autoserialize
|
||||
type: string;
|
||||
type: ResourceType;
|
||||
|
||||
/**
|
||||
* The {@link HALLink}s for this Bitstream
|
||||
*/
|
||||
@deserialize
|
||||
_links: {
|
||||
self: HALLink;
|
||||
};
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ import { Item } from '../../../../core/shared/item.model';
|
||||
import { ClaimedSearchResultListElementComponent } from './claimed-search-result-list-element.component';
|
||||
import { ClaimedTask } from '../../../../core/tasks/models/claimed-task-object.model';
|
||||
import { WorkflowItem } from '../../../../core/submission/models/workflowitem.model';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../remote-data.utils';
|
||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../remote-data.utils';
|
||||
import { ClaimedTaskSearchResult } from '../../../object-collection/shared/claimed-task-search-result.model';
|
||||
import { TruncatableService } from '../../../truncatable/truncatable.service';
|
||||
import { VarDirective } from '../../../utils/var.directive';
|
||||
@@ -28,6 +28,8 @@ import { APP_CONFIG } from '../../../../../config/app-config.interface';
|
||||
import { environment } from '../../../../../environments/environment';
|
||||
import { ObjectCacheService } from '../../../../core/cache/object-cache.service';
|
||||
import { Context } from '../../../../core/shared/context.model';
|
||||
import { createPaginatedList } from '../../../testing/utils.test';
|
||||
import { ItemDataService } from '../../../../core/data/item-data.service';
|
||||
|
||||
let component: ClaimedSearchResultListElementComponent;
|
||||
let fixture: ComponentFixture<ClaimedSearchResultListElementComponent>;
|
||||
@@ -35,6 +37,12 @@ let fixture: ComponentFixture<ClaimedSearchResultListElementComponent>;
|
||||
const mockResultObject: ClaimedTaskSearchResult = new ClaimedTaskSearchResult();
|
||||
mockResultObject.hitHighlights = {};
|
||||
|
||||
const emptyList = createSuccessfulRemoteDataObject(createPaginatedList([]));
|
||||
const itemDataServiceStub = {
|
||||
findDuplicates: () => createSuccessfulRemoteDataObject$({}),
|
||||
findListByHref: () => observableOf(emptyList),
|
||||
};
|
||||
|
||||
const item = Object.assign(new Item(), {
|
||||
bundles: observableOf({}),
|
||||
metadata: {
|
||||
@@ -83,7 +91,8 @@ describe('ClaimedSearchResultListElementComponent', () => {
|
||||
{ provide: LinkService, useValue: linkService },
|
||||
{ provide: DSONameService, useClass: DSONameServiceMock },
|
||||
{ provide: APP_CONFIG, useValue: environment },
|
||||
{ provide: ObjectCacheService, useValue: objectCacheServiceMock }
|
||||
{ provide: ObjectCacheService, useValue: objectCacheServiceMock },
|
||||
{ provide: ItemDataService, useValue: itemDataServiceStub },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(ClaimedSearchResultListElementComponent, {
|
||||
|
@@ -23,6 +23,7 @@ import { isNotEmpty, hasValue } from '../../../empty.util';
|
||||
import { Context } from '../../../../core/shared/context.model';
|
||||
import { Duplicate } from '../../duplicate-data/duplicate.model';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list.model';
|
||||
import { ItemDataService } from '../../../../core/data/item-data.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-claimed-search-result-list-element',
|
||||
@@ -67,6 +68,7 @@ export class ClaimedSearchResultListElementComponent extends SearchResultListEle
|
||||
protected truncatableService: TruncatableService,
|
||||
public dsoNameService: DSONameService,
|
||||
protected objectCache: ObjectCacheService,
|
||||
protected itemDataService: ItemDataService,
|
||||
@Inject(APP_CONFIG) protected appConfig: AppConfig
|
||||
) {
|
||||
super(truncatableService, dsoNameService, appConfig);
|
||||
@@ -97,7 +99,7 @@ export class ClaimedSearchResultListElementComponent extends SearchResultListEle
|
||||
tap((itemRD: RemoteData<Item>) => {
|
||||
if (isNotEmpty(itemRD) && itemRD.hasSucceeded) {
|
||||
this.item$.next(itemRD.payload);
|
||||
this.duplicates$ = itemRD.payload.duplicates.pipe(
|
||||
this.duplicates$ = this.itemDataService.findDuplicates(itemRD.payload.uuid).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((remoteData: RemoteData<PaginatedList<Duplicate>>) => {
|
||||
if (remoteData.hasSucceeded) {
|
||||
|
@@ -15,7 +15,7 @@ import { Item } from '../../../../core/shared/item.model';
|
||||
import { PoolSearchResultListElementComponent } from './pool-search-result-list-element.component';
|
||||
import { PoolTask } from '../../../../core/tasks/models/pool-task-object.model';
|
||||
import { WorkflowItem } from '../../../../core/submission/models/workflowitem.model';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../remote-data.utils';
|
||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../remote-data.utils';
|
||||
import { PoolTaskSearchResult } from '../../../object-collection/shared/pool-task-search-result.model';
|
||||
import { TruncatableService } from '../../../truncatable/truncatable.service';
|
||||
import { VarDirective } from '../../../utils/var.directive';
|
||||
@@ -27,6 +27,8 @@ import { DSONameServiceMock } from '../../../mocks/dso-name.service.mock';
|
||||
import { APP_CONFIG } from '../../../../../config/app-config.interface';
|
||||
import { ObjectCacheService } from '../../../../core/cache/object-cache.service';
|
||||
import { Context } from '../../../../core/shared/context.model';
|
||||
import { createPaginatedList } from '../../../testing/utils.test';
|
||||
import { ItemDataService } from '../../../../core/data/item-data.service';
|
||||
|
||||
let component: PoolSearchResultListElementComponent;
|
||||
let fixture: ComponentFixture<PoolSearchResultListElementComponent>;
|
||||
@@ -34,6 +36,12 @@ let fixture: ComponentFixture<PoolSearchResultListElementComponent>;
|
||||
const mockResultObject: PoolTaskSearchResult = new PoolTaskSearchResult();
|
||||
mockResultObject.hitHighlights = {};
|
||||
|
||||
const emptyList = createSuccessfulRemoteDataObject(createPaginatedList([]));
|
||||
const itemDataServiceStub = {
|
||||
findDuplicates: () => createSuccessfulRemoteDataObject$({}),
|
||||
findListByHref: () => observableOf(emptyList),
|
||||
};
|
||||
|
||||
const item = Object.assign(new Item(), {
|
||||
duplicates: observableOf([]),
|
||||
bundles: observableOf({}),
|
||||
@@ -90,7 +98,8 @@ describe('PoolSearchResultListElementComponent', () => {
|
||||
{ provide: LinkService, useValue: linkService },
|
||||
{ provide: DSONameService, useClass: DSONameServiceMock },
|
||||
{ provide: APP_CONFIG, useValue: environmentUseThumbs },
|
||||
{ provide: ObjectCacheService, useValue: objectCacheServiceMock }
|
||||
{ provide: ObjectCacheService, useValue: objectCacheServiceMock },
|
||||
{ provide: ItemDataService, useValue: itemDataServiceStub },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(PoolSearchResultListElementComponent, {
|
||||
|
@@ -24,6 +24,7 @@ import { isNotEmpty, hasValue } from '../../../empty.util';
|
||||
import { Context } from '../../../../core/shared/context.model';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list.model';
|
||||
import { Duplicate } from '../../duplicate-data/duplicate.model';
|
||||
import { ItemDataService } from '../../../../core/data/item-data.service';
|
||||
|
||||
/**
|
||||
* This component renders pool task object for the search result in the list view.
|
||||
@@ -77,6 +78,7 @@ export class PoolSearchResultListElementComponent extends SearchResultListElemen
|
||||
protected truncatableService: TruncatableService,
|
||||
public dsoNameService: DSONameService,
|
||||
protected objectCache: ObjectCacheService,
|
||||
protected itemDataService: ItemDataService,
|
||||
@Inject(APP_CONFIG) protected appConfig: AppConfig
|
||||
) {
|
||||
super(truncatableService, dsoNameService, appConfig);
|
||||
@@ -88,7 +90,7 @@ export class PoolSearchResultListElementComponent extends SearchResultListElemen
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
this.linkService.resolveLinks(this.dso, followLink('workflowitem', {},
|
||||
followLink('item', {}, followLink('bundles'), followLink('duplicates')),
|
||||
followLink('item', {}, followLink('bundles')),
|
||||
followLink('submitter')
|
||||
), followLink('action'));
|
||||
|
||||
@@ -107,7 +109,7 @@ export class PoolSearchResultListElementComponent extends SearchResultListElemen
|
||||
tap((itemRD: RemoteData<Item>) => {
|
||||
if (isNotEmpty(itemRD) && itemRD.hasSucceeded) {
|
||||
this.item$.next(itemRD.payload);
|
||||
this.duplicates$ = itemRD.payload.duplicates.pipe(
|
||||
this.duplicates$ = this.itemDataService.findDuplicates(itemRD.payload.uuid).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((remoteData: RemoteData<PaginatedList<Duplicate>>) => {
|
||||
if (remoteData.hasSucceeded) {
|
||||
|
Reference in New Issue
Block a user