mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-10 11:33:04 +00:00
[TLC-674] Duplicate detection frontend changes as per feedback
This commit is contained in:
@@ -198,7 +198,7 @@ import { NotifyRequestsStatus } from '../item-page/simple/notify-requests-status
|
||||
import { LdnService } from '../admin/admin-ldn-services/ldn-services-model/ldn-services.model';
|
||||
import { Itemfilter } from '../admin/admin-ldn-services/ldn-services-model/ldn-service-itemfilters';
|
||||
import { SubmissionCoarNotifyConfig } from '../submission/sections/section-coar-notify/submission-coar-notify.config';
|
||||
import { DuplicateDataService } from './data/duplicate-search.service';
|
||||
import { SubmissionDuplicateDataService } from './submission/submission-duplicate-data.service';
|
||||
|
||||
/**
|
||||
* When not in production, endpoint responses can be mocked for testing purposes
|
||||
@@ -235,7 +235,7 @@ const PROVIDERS = [
|
||||
HALEndpointService,
|
||||
HostWindowService,
|
||||
ItemDataService,
|
||||
DuplicateDataService,
|
||||
SubmissionDuplicateDataService,
|
||||
MetadataService,
|
||||
ObjectCacheService,
|
||||
PaginationComponentOptions,
|
||||
|
@@ -46,9 +46,6 @@ 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
|
||||
@@ -59,7 +56,6 @@ 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,
|
||||
@@ -78,7 +74,6 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,20 +242,6 @@ export abstract class BaseItemDataService extends IdentifiableDataService<Item>
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if (findListOptions.searchParams) {
|
||||
findListOptions.searchParams = [...findListOptions.searchParams, ...searchParams];
|
||||
} else {
|
||||
findListOptions.searchParams = searchParams;
|
||||
}
|
||||
return this.searchData.searchBy('findDuplicates', findListOptions, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the endpoint to move the item
|
||||
* @param itemId
|
||||
|
@@ -3,28 +3,34 @@ import { Observable } from 'rxjs';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||
import { ResponseParsingService } from './parsing.service';
|
||||
import { RemoteData } from './remote-data';
|
||||
import { GetRequest } from './request.models';
|
||||
import { RequestService } from './request.service';
|
||||
import { ResponseParsingService } from '../data/parsing.service';
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { GetRequest } from '../data/request.models';
|
||||
import { RequestService } from '../data/request.service';
|
||||
import { GenericConstructor } from '../shared/generic-constructor';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
import { SearchResponseParsingService } from './search-response-parsing.service';
|
||||
import { SearchResponseParsingService } from '../data/search-response-parsing.service';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { RestRequest } from './rest-request.model';
|
||||
import { BaseDataService } from './base/base-data.service';
|
||||
import { FindListOptions } from './find-list-options.model';
|
||||
import { RestRequest } from '../data/rest-request.model';
|
||||
import { BaseDataService } from '../data/base/base-data.service';
|
||||
import { FindListOptions } from '../data/find-list-options.model';
|
||||
import { Duplicate } from '../../shared/object-list/duplicate-data/duplicate.model';
|
||||
import { PaginatedList } from './paginated-list.model';
|
||||
import { PaginatedList } from '../data/paginated-list.model';
|
||||
import { RequestParam } from '../cache/models/request-param.model';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
|
||||
|
||||
/**
|
||||
* Service that performs all general actions that have to do with the search page
|
||||
* Service that handles search requests for potential duplicate items.
|
||||
* This uses the /api/submission/duplicates endpoint to look for other archived or in-progress items (if user
|
||||
* has READ permission) that match the item (for the given uuid).
|
||||
* Matching is configured in the backend in dspace/config/modulesduplicate-detection.cfg
|
||||
* The returned results are small preview 'stubs' of items, and displayed in either a submission section
|
||||
* or the workflow pooled/claimed task page.
|
||||
*
|
||||
*/
|
||||
@Injectable()
|
||||
export class DuplicateDataService extends BaseDataService<Duplicate> {
|
||||
export class SubmissionDuplicateDataService extends BaseDataService<Duplicate> {
|
||||
|
||||
/**
|
||||
* The ResponseParsingService constructor name
|
@@ -5,6 +5,10 @@ import { CacheableObject } from '../../../core/cache/cacheable-object.model';
|
||||
import { DUPLICATE } from './duplicate.resource-type';
|
||||
import { ResourceType } from '../../../core/shared/resource-type';
|
||||
|
||||
/**
|
||||
* This implements the model of a duplicate preview stub, to be displayed to submitters or reviewers
|
||||
* if duplicate detection is enabled. The metadata map is configurable in the backend at duplicate-detection.cfg
|
||||
*/
|
||||
export class Duplicate implements CacheableObject {
|
||||
|
||||
static type = DUPLICATE;
|
||||
@@ -14,17 +18,28 @@ export class Duplicate implements CacheableObject {
|
||||
*/
|
||||
@autoserialize
|
||||
title: string;
|
||||
/**
|
||||
* The item uuid
|
||||
*/
|
||||
@autoserialize
|
||||
uuid: string;
|
||||
/**
|
||||
* The workfow item ID, if any
|
||||
*/
|
||||
@autoserialize
|
||||
workflowItemId: number;
|
||||
/**
|
||||
* The workspace item ID, if any
|
||||
*/
|
||||
@autoserialize
|
||||
workspaceItemId: number;
|
||||
/**
|
||||
* The owning collection of the item
|
||||
*/
|
||||
@autoserialize
|
||||
owningCollection: string;
|
||||
|
||||
/**
|
||||
* Metadata for the bitstream (e.g. dc.description)
|
||||
* Metadata for the preview item (e.g. dc.title)
|
||||
*/
|
||||
@autoserialize
|
||||
metadata: MetadataMap;
|
||||
@@ -33,7 +48,7 @@ export class Duplicate implements CacheableObject {
|
||||
type: ResourceType;
|
||||
|
||||
/**
|
||||
* The {@link HALLink}s for this Bitstream
|
||||
* The {@link HALLink}s for the URL that generated this item (in context of search results)
|
||||
*/
|
||||
@deserialize
|
||||
_links: {
|
||||
|
@@ -30,7 +30,9 @@ 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';
|
||||
import { DuplicateDataService } from '../../../../core/data/duplicate-search.service';
|
||||
import { SubmissionDuplicateDataService } from '../../../../core/submission/submission-duplicate-data.service';
|
||||
import { ConfigurationProperty } from '../../../../core/shared/configuration-property.model';
|
||||
import { ConfigurationDataService } from '../../../../core/data/configuration-data.service';
|
||||
|
||||
let component: ClaimedSearchResultListElementComponent;
|
||||
let fixture: ComponentFixture<ClaimedSearchResultListElementComponent>;
|
||||
@@ -41,8 +43,15 @@ mockResultObject.hitHighlights = {};
|
||||
const emptyList = createSuccessfulRemoteDataObject(createPaginatedList([]));
|
||||
const itemDataServiceStub = {
|
||||
findListByHref: () => observableOf(emptyList),
|
||||
|
||||
};
|
||||
const configurationDataService = jasmine.createSpyObj('configurationDataService', {
|
||||
findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), {
|
||||
name: 'duplicate.enable',
|
||||
values: [
|
||||
'true'
|
||||
]
|
||||
}))
|
||||
});
|
||||
const duplicateDataServiceStub = {
|
||||
findListByHref: () => observableOf(emptyList),
|
||||
findDuplicates: () => createSuccessfulRemoteDataObject$({}),
|
||||
@@ -98,7 +107,8 @@ describe('ClaimedSearchResultListElementComponent', () => {
|
||||
{ provide: APP_CONFIG, useValue: environment },
|
||||
{ provide: ObjectCacheService, useValue: objectCacheServiceMock },
|
||||
{ provide: ItemDataService, useValue: itemDataServiceStub },
|
||||
{ provide: DuplicateDataService, useValue: duplicateDataServiceStub },
|
||||
{ provide: ConfigurationDataService, useValue: configurationDataService },
|
||||
{ provide: SubmissionDuplicateDataService, useValue: duplicateDataServiceStub },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(ClaimedSearchResultListElementComponent, {
|
||||
|
@@ -5,7 +5,7 @@ import { listableObjectComponent } from '../../../object-collection/shared/lista
|
||||
import { ClaimedTaskSearchResult } from '../../../object-collection/shared/claimed-task-search-result.model';
|
||||
import { LinkService } from '../../../../core/cache/builders/link.service';
|
||||
import { TruncatableService } from '../../../truncatable/truncatable.service';
|
||||
import { BehaviorSubject, EMPTY, Observable } from 'rxjs';
|
||||
import {BehaviorSubject, combineLatest, EMPTY, Observable} from 'rxjs';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { WorkflowItem } from '../../../../core/submission/models/workflowitem.model';
|
||||
import { followLink } from '../../../utils/follow-link-config.model';
|
||||
@@ -24,7 +24,9 @@ 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';
|
||||
import { DuplicateDataService } from '../../../../core/data/duplicate-search.service';
|
||||
import { SubmissionDuplicateDataService } from '../../../../core/submission/submission-duplicate-data.service';
|
||||
import { ConfigurationProperty } from '../../../../core/shared/configuration-property.model';
|
||||
import { ConfigurationDataService } from '../../../../core/data/configuration-data.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-claimed-search-result-list-element',
|
||||
@@ -57,7 +59,7 @@ export class ClaimedSearchResultListElementComponent extends SearchResultListEle
|
||||
/**
|
||||
* The potential duplicates of this item
|
||||
*/
|
||||
public duplicates$: Observable<Duplicate[]> = new Observable<Duplicate[]>();
|
||||
public duplicates$: Observable<Duplicate[]>;
|
||||
|
||||
/**
|
||||
* Display thumbnails if required by configuration
|
||||
@@ -70,7 +72,8 @@ export class ClaimedSearchResultListElementComponent extends SearchResultListEle
|
||||
public dsoNameService: DSONameService,
|
||||
protected objectCache: ObjectCacheService,
|
||||
protected itemDataService: ItemDataService,
|
||||
protected duplicateDataService: DuplicateDataService,
|
||||
protected configService: ConfigurationDataService,
|
||||
protected duplicateDataService: SubmissionDuplicateDataService,
|
||||
@Inject(APP_CONFIG) protected appConfig: AppConfig
|
||||
) {
|
||||
super(truncatableService, dsoNameService, appConfig);
|
||||
@@ -114,10 +117,45 @@ export class ClaimedSearchResultListElementComponent extends SearchResultListEle
|
||||
}
|
||||
})
|
||||
).subscribe();
|
||||
|
||||
// Initialise duplicates, if enabled
|
||||
this.duplicates$ = this.initializeDuplicateDetectionIfEnabled();
|
||||
this.showThumbnails = this.appConfig.browseBy.showThumbnails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize and set the duplicates observable based on whether the configuration in REST is enabled
|
||||
* and the results returned
|
||||
*/
|
||||
initializeDuplicateDetectionIfEnabled() {
|
||||
return combineLatest([
|
||||
this.configService.findByPropertyName('duplicate.enable').pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((remoteData: RemoteData<ConfigurationProperty>) => {
|
||||
return (remoteData.isSuccess && remoteData.payload && remoteData.payload.values[0] === 'true');
|
||||
})
|
||||
),
|
||||
this.item$.pipe(),
|
||||
]
|
||||
).pipe(
|
||||
map(([enabled, rd]) => {
|
||||
if (enabled) {
|
||||
this.duplicates$ = this.duplicateDataService.findDuplicates(rd.uuid).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((remoteData: RemoteData<PaginatedList<Duplicate>>) => {
|
||||
if (remoteData.hasSucceeded) {
|
||||
if (remoteData.payload.page) {
|
||||
return remoteData.payload.page;
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
} else {
|
||||
return [] as Duplicate[];
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
// This ensures the object is removed from cache, when action is performed on task
|
||||
if (hasValue(this.dso)) {
|
||||
|
@@ -4,6 +4,7 @@
|
||||
[showSubmitter]="showSubmitter"
|
||||
[badgeContext]="badgeContext"
|
||||
[workflowItem]="workflowitem$.value"></ds-themed-item-list-preview>
|
||||
|
||||
<!-- Display duplicate alert, if feature enabled and duplicates detected -->
|
||||
<ng-container *ngVar="(duplicates$|async)?.length as duplicateCount">
|
||||
<div [ngClass]="'row'" *ngIf="duplicateCount > 0">
|
||||
|
@@ -29,7 +29,9 @@ 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';
|
||||
import { DuplicateDataService } from '../../../../core/data/duplicate-search.service';
|
||||
import { SubmissionDuplicateDataService } from '../../../../core/submission/submission-duplicate-data.service';
|
||||
import { ConfigurationProperty } from '../../../../core/shared/configuration-property.model';
|
||||
import { ConfigurationDataService } from '../../../../core/data/configuration-data.service';
|
||||
|
||||
let component: PoolSearchResultListElementComponent;
|
||||
let fixture: ComponentFixture<PoolSearchResultListElementComponent>;
|
||||
@@ -41,6 +43,14 @@ const emptyList = createSuccessfulRemoteDataObject(createPaginatedList([]));
|
||||
const itemDataServiceStub = {
|
||||
findListByHref: () => observableOf(emptyList),
|
||||
};
|
||||
const configurationDataService = jasmine.createSpyObj('configurationDataService', {
|
||||
findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), {
|
||||
name: 'duplicate.enable',
|
||||
values: [
|
||||
'true'
|
||||
]
|
||||
}))
|
||||
});
|
||||
const duplicateDataServiceStub = {
|
||||
findListByHref: () => observableOf(emptyList),
|
||||
findDuplicates: () => createSuccessfulRemoteDataObject$({}),
|
||||
@@ -104,7 +114,8 @@ describe('PoolSearchResultListElementComponent', () => {
|
||||
{ provide: APP_CONFIG, useValue: environmentUseThumbs },
|
||||
{ provide: ObjectCacheService, useValue: objectCacheServiceMock },
|
||||
{ provide: ItemDataService, useValue: itemDataServiceStub },
|
||||
{ provide: DuplicateDataService, useValue: duplicateDataServiceStub }
|
||||
{ provide: ConfigurationDataService, useValue: configurationDataService },
|
||||
{ provide: SubmissionDuplicateDataService, useValue: duplicateDataServiceStub }
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(PoolSearchResultListElementComponent, {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { Component, Inject, OnDestroy, OnInit } from '@angular/core';
|
||||
|
||||
import { BehaviorSubject, EMPTY, Observable } from 'rxjs';
|
||||
import {BehaviorSubject, combineLatest, EMPTY, Observable } from 'rxjs';
|
||||
import { map, mergeMap, tap } from 'rxjs/operators';
|
||||
|
||||
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
||||
@@ -25,7 +25,9 @@ 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';
|
||||
import { DuplicateDataService } from '../../../../core/data/duplicate-search.service';
|
||||
import { SubmissionDuplicateDataService } from '../../../../core/submission/submission-duplicate-data.service';
|
||||
import { ConfigurationDataService } from '../../../../core/data/configuration-data.service';
|
||||
import { ConfigurationProperty } from '../../../../core/shared/configuration-property.model';
|
||||
|
||||
/**
|
||||
* This component renders pool task object for the search result in the list view.
|
||||
@@ -62,7 +64,7 @@ export class PoolSearchResultListElementComponent extends SearchResultListElemen
|
||||
/**
|
||||
* The potential duplicates of this workflow item
|
||||
*/
|
||||
public duplicates$: Observable<Duplicate[]> = new Observable<Duplicate[]>();
|
||||
public duplicates$: Observable<Duplicate[]>;
|
||||
|
||||
/**
|
||||
* The index of this list element
|
||||
@@ -74,13 +76,16 @@ export class PoolSearchResultListElementComponent extends SearchResultListElemen
|
||||
*/
|
||||
showThumbnails: boolean;
|
||||
|
||||
enableDetectDuplicates$: Observable<any>;
|
||||
|
||||
constructor(
|
||||
protected linkService: LinkService,
|
||||
protected truncatableService: TruncatableService,
|
||||
public dsoNameService: DSONameService,
|
||||
protected objectCache: ObjectCacheService,
|
||||
protected itemDataService: ItemDataService,
|
||||
protected duplicateDataService: DuplicateDataService,
|
||||
protected configService: ConfigurationDataService,
|
||||
protected duplicateDataService: SubmissionDuplicateDataService,
|
||||
@Inject(APP_CONFIG) protected appConfig: AppConfig
|
||||
) {
|
||||
super(truncatableService, dsoNameService, appConfig);
|
||||
@@ -96,6 +101,14 @@ export class PoolSearchResultListElementComponent extends SearchResultListElemen
|
||||
followLink('submitter')
|
||||
), followLink('action'));
|
||||
|
||||
// Get configuration for duplicate detection feature
|
||||
this.enableDetectDuplicates$ = this.configService.findByPropertyName('duplicate.enable').pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((rd: RemoteData<ConfigurationProperty>) => {
|
||||
return (rd.hasSucceeded && rd.payload && rd.payload.values[0] === 'true');
|
||||
})
|
||||
);
|
||||
|
||||
(this.dso.workflowitem as Observable<RemoteData<WorkflowItem>>).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
mergeMap((wfiRD: RemoteData<WorkflowItem>) => {
|
||||
@@ -111,8 +124,32 @@ export class PoolSearchResultListElementComponent extends SearchResultListElemen
|
||||
tap((itemRD: RemoteData<Item>) => {
|
||||
if (isNotEmpty(itemRD) && itemRD.hasSucceeded) {
|
||||
this.item$.next(itemRD.payload);
|
||||
// Find duplicates for this item
|
||||
this.duplicates$ = this.duplicateDataService.findDuplicates(itemRD.payload.uuid).pipe(
|
||||
}
|
||||
}),
|
||||
).subscribe();
|
||||
this.showThumbnails = this.appConfig.browseBy.showThumbnails;
|
||||
// Initialise duplicates, if enabled
|
||||
this.duplicates$ = this.initializeDuplicateDetectionIfEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize and set the duplicates observable based on whether the configuration in REST is enabled
|
||||
* and the results returned
|
||||
*/
|
||||
initializeDuplicateDetectionIfEnabled() {
|
||||
return combineLatest([
|
||||
this.configService.findByPropertyName('duplicate.enable').pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((remoteData: RemoteData<ConfigurationProperty>) => {
|
||||
return (remoteData.isSuccess && remoteData.payload && remoteData.payload.values[0] === 'true');
|
||||
})
|
||||
),
|
||||
this.item$.pipe(),
|
||||
]
|
||||
).pipe(
|
||||
map(([enabled, rd]) => {
|
||||
if (enabled) {
|
||||
this.duplicates$ = this.duplicateDataService.findDuplicates(rd.uuid).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((remoteData: RemoteData<PaginatedList<Duplicate>>) => {
|
||||
if (remoteData.hasSucceeded) {
|
||||
@@ -122,12 +159,11 @@ export class PoolSearchResultListElementComponent extends SearchResultListElemen
|
||||
}
|
||||
})
|
||||
);
|
||||
} else {
|
||||
return [] as Duplicate[];
|
||||
}
|
||||
}),
|
||||
).subscribe();
|
||||
|
||||
this.showThumbnails = this.appConfig.browseBy.showThumbnails;
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
@@ -76,7 +76,7 @@ const duplicates: Duplicate[] = [{
|
||||
type: DUPLICATE,
|
||||
_links: {
|
||||
self: {
|
||||
href: 'http://localhost:8080/server/api/core/items/search/findDuplicates?uuid=testid'
|
||||
href: 'http://localhost:8080/server/api/core/submission/duplicates/search?uuid=testid'
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
Reference in New Issue
Block a user