93219: Simplify DataService feature interfaces

Get rid of optional methods
- createPatchFromCache is useful -> make required
- leave getFindAllHref and getSearchByHref out & use implementation directly or refactor usages
This commit is contained in:
Yury Bondarenko
2022-09-12 17:34:25 +02:00
parent c32e4ad7c7
commit 8b4dbbad55
23 changed files with 86 additions and 192 deletions

View File

@@ -39,17 +39,6 @@ export interface FindAllData<T extends CacheableObject> {
* Return an observable that emits object list * Return an observable that emits object list
*/ */
findAll(options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<PaginatedList<T>>>; findAll(options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<PaginatedList<T>>>;
/**
* Create the HREF with given options object
*
* @param options The [[FindListOptions]] object
* @param linkPath The link path for the object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
getFindAllHref?(options: FindListOptions, linkPath?: string, ...linksToFollow: FollowLinkConfig<T>[]): Observable<string>;
} }
/** /**

View File

@@ -50,7 +50,7 @@ export interface PatchData<T extends CacheableObject> {
* Return a list of operations representing the difference between an object and its latest value in the cache. * Return a list of operations representing the difference between an object and its latest value in the cache.
* @param object the object to resolve to a list of patch operations * @param object the object to resolve to a list of patch operations
*/ */
createPatchFromCache?(object: T): Observable<Operation[]>; createPatchFromCache(object: T): Observable<Operation[]>;
} }
/** /**

View File

@@ -48,17 +48,6 @@ export interface SearchData<T extends CacheableObject> {
* Return an observable that emits response from the server * Return an observable that emits response from the server
*/ */
searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<PaginatedList<T>>>; searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<PaginatedList<T>>>;
/**
* Create the HREF for a specific object's search method with given options object
*
* @param searchMethod The search method for the object
* @param options The [[FindListOptions]] object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
getSearchByHref?(searchMethod: string, options?: FindListOptions, ...linksToFollow: FollowLinkConfig<T>[]): Observable<string>;
} }
/** /**

View File

@@ -33,6 +33,7 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
import { NoContent } from '../shared/NoContent.model'; import { NoContent } from '../shared/NoContent.model';
import { IdentifiableDataService } from './base/identifiable-data.service'; import { IdentifiableDataService } from './base/identifiable-data.service';
import { dataService } from './base/data-service.decorator'; import { dataService } from './base/data-service.decorator';
import { Operation } from 'fast-json-patch';
/** /**
* A service to retrieve {@link Bitstream}s from the REST API * A service to retrieve {@link Bitstream}s from the REST API
@@ -244,6 +245,14 @@ export class BitstreamDataService extends IdentifiableDataService<Bitstream> imp
return this.patchData.update(object); return this.patchData.update(object);
} }
/**
* Return a list of operations representing the difference between an object and its latest value in the cache.
* @param object the object to resolve to a list of patch operations
*/
public createPatchFromCache(object: Bitstream): Observable<Operation[]> {
return this.patchData.createPatchFromCache(object);
}
/** /**
* Delete an existing object on the server * Delete an existing object on the server
* @param objectId The id of the object to be removed * @param objectId The id of the object to be removed

View File

@@ -167,4 +167,12 @@ export class BundleDataService extends IdentifiableDataService<Bundle> implement
public update(object: Bundle): Observable<RemoteData<Bundle>> { public update(object: Bundle): Observable<RemoteData<Bundle>> {
return this.patchData.update(object); return this.patchData.update(object);
} }
/**
* Return a list of operations representing the difference between an object and its latest value in the cache.
* @param object the object to resolve to a list of patch operations
*/
public createPatchFromCache(object: Bundle): Observable<Operation[]> {
return this.patchData.createPatchFromCache(object);
}
} }

View File

@@ -28,6 +28,7 @@ import { RequestService } from './request.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
import { Operation } from 'fast-json-patch';
export abstract class ComColDataService<T extends Community | Collection> extends IdentifiableDataService<T> implements CreateData<T>, FindAllData<T>, SearchData<T>, PatchData<T>, DeleteData<T> { export abstract class ComColDataService<T extends Community | Collection> extends IdentifiableDataService<T> implements CreateData<T>, FindAllData<T>, SearchData<T>, PatchData<T>, DeleteData<T> {
private createData: CreateData<T>; private createData: CreateData<T>;
@@ -191,32 +192,6 @@ export abstract class ComColDataService<T extends Community | Collection> extend
return this.findAllData.findAll(options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); return this.findAllData.findAll(options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
} }
/**
* Create the HREF with given options object
*
* @param options The [[FindListOptions]] object
* @param linkPath The link path for the object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getFindAllHref(options?: FindListOptions, linkPath?: string, ...linksToFollow: FollowLinkConfig<T>[]): Observable<string> {
return this.findAllData.getFindAllHref(options, linkPath, ...linksToFollow);
}
/**
* Create the HREF for a specific object's search method with given options object
*
* @param searchMethod The search method for the object
* @param options The [[FindListOptions]] object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getSearchByHref(searchMethod: string, options?: FindListOptions, ...linksToFollow: FollowLinkConfig<T>[]): Observable<string> {
return this.searchData.getSearchByHref(searchMethod, options, ...linksToFollow);
}
/** /**
* Make a new FindListRequest with given search method * Make a new FindListRequest with given search method
* *
@@ -261,6 +236,14 @@ export abstract class ComColDataService<T extends Community | Collection> extend
return this.patchData.update(object); return this.patchData.update(object);
} }
/**
* Return a list of operations representing the difference between an object and its latest value in the cache.
* @param object the object to resolve to a list of patch operations
*/
public createPatchFromCache(object: T): Observable<Operation[]> {
return this.patchData.createPatchFromCache(object);
}
/** /**
* Delete an existing object on the server * Delete an existing object on the server
* @param objectId The id of the object to be removed * @param objectId The id of the object to be removed

View File

@@ -36,13 +36,16 @@ export class CommunityDataService extends ComColDataService<Community> {
super('communities', requestService, rdbService, objectCache, halService, comparator, notificationsService, bitstreamDataService); super('communities', requestService, rdbService, objectCache, halService, comparator, notificationsService, bitstreamDataService);
} }
// this method is overridden in order to make it public
getEndpoint() { getEndpoint() {
return this.halService.getEndpoint(this.linkPath); return this.halService.getEndpoint(this.linkPath);
} }
findTop(options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig<Community>[]): Observable<RemoteData<PaginatedList<Community>>> { findTop(options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig<Community>[]): Observable<RemoteData<PaginatedList<Community>>> {
const hrefObs = this.getFindAllHref(options, this.topLinkPath); return this.getEndpoint().pipe(
return this.findListByHref(hrefObs, undefined, true, true, ...linksToFollow); map(href => `${href}/search/top`),
switchMap(href => this.findListByHref(href, options, true, true, ...linksToFollow))
);
} }
protected getFindByParentHref(parentUUID: string): Observable<string> { protected getFindByParentHref(parentUUID: string): Observable<string> {

View File

@@ -345,6 +345,14 @@ export abstract class BaseItemDataService extends IdentifiableDataService<Item>
return this.patchData.update(object); return this.patchData.update(object);
} }
/**
* Return a list of operations representing the difference between an object and its latest value in the cache.
* @param object the object to resolve to a list of patch operations
*/
public createPatchFromCache(object: Item): Observable<Operation[]> {
return this.patchData.createPatchFromCache(object);
}
/** /**
* Delete an existing object on the server * Delete an existing object on the server
* @param objectId The id of the object to be removed * @param objectId The id of the object to be removed

View File

@@ -165,19 +165,6 @@ export class MetadataFieldDataService extends IdentifiableDataService<MetadataFi
return this.createData.create(object, ...params); return this.createData.create(object, ...params);
} }
/**
* Create the HREF for a specific object's search method with given options object
*
* @param searchMethod The search method for the object
* @param options The [[FindListOptions]] object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getSearchByHref(searchMethod: string, options?: FindListOptions, ...linksToFollow: FollowLinkConfig<MetadataField>[]): Observable<string> {
return this.searchData.getSearchByHref(searchMethod, options, ...linksToFollow);
}
/** /**
* Make a new FindListRequest with given search method * Make a new FindListRequest with given search method
* *

View File

@@ -546,17 +546,4 @@ export class RelationshipDataService extends IdentifiableDataService<Relationshi
searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<Relationship>[]): Observable<RemoteData<PaginatedList<Relationship>>> { searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<Relationship>[]): Observable<RemoteData<PaginatedList<Relationship>>> {
return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
} }
/**
* Create the HREF for a specific object's search method with given options object
*
* @param searchMethod The search method for the object
* @param options The [[FindListOptions]] object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
getSearchByHref(searchMethod: string, options: FindListOptions, ...linksToFollow: FollowLinkConfig<Relationship>[]): Observable<string> {
return this.searchData.getSearchByHref(searchMethod, options, ...linksToFollow);
}
} }

View File

@@ -17,6 +17,7 @@ import { RestRequestMethod } from './rest-request-method';
import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
import { IdentifiableDataService } from './base/identifiable-data.service'; import { IdentifiableDataService } from './base/identifiable-data.service';
import { dataService } from './base/data-service.decorator'; import { dataService } from './base/data-service.decorator';
import { Operation } from 'fast-json-patch';
/** /**
* Service responsible for handling requests related to the Version object * Service responsible for handling requests related to the Version object
@@ -89,4 +90,13 @@ export class VersionDataService extends IdentifiableDataService<Version> impleme
public commitUpdates(method?: RestRequestMethod): void { public commitUpdates(method?: RestRequestMethod): void {
this.patchData.commitUpdates(method); this.patchData.commitUpdates(method);
} }
/**
* Return a list of operations representing the difference between an object and its latest value in the cache.
* @param object the object to resolve to a list of patch operations
*/
public createPatchFromCache(object: Version): Observable<Operation[]> {
return this.patchData.createPatchFromCache(object);
}
} }

View File

@@ -118,24 +118,24 @@ describe('EPersonDataService', () => {
}); });
it('search email scope and no query', () => { it('search email scope and no query', () => {
spyOn(service, 'getSearchByHref').and.returnValue(epersonsEndpoint); spyOn((service as any).searchData, 'getSearchByHref').and.returnValue(epersonsEndpoint);
spyOn(service, 'findByHref').and.returnValue(createSuccessfulRemoteDataObject$(null)); spyOn(service, 'findByHref').and.returnValue(createSuccessfulRemoteDataObject$(null));
service.searchByScope('email', ''); service.searchByScope('email', '');
const options = Object.assign(new FindListOptions(), { const options = Object.assign(new FindListOptions(), {
searchParams: [Object.assign(new RequestParam('email', encodeURIComponent('')))] searchParams: [Object.assign(new RequestParam('email', encodeURIComponent('')))]
}); });
expect(service.getSearchByHref).toHaveBeenCalledWith('byEmail', options); expect((service as any).searchData.getSearchByHref).toHaveBeenCalledWith('byEmail', options);
expect(service.findByHref).toHaveBeenCalledWith(epersonsEndpoint, true, true); expect(service.findByHref).toHaveBeenCalledWith(epersonsEndpoint, true, true);
}); });
it('search email scope with a query', () => { it('search email scope with a query', () => {
spyOn(service, 'getSearchByHref').and.returnValue(epersonsEndpoint); spyOn((service as any).searchData, 'getSearchByHref').and.returnValue(epersonsEndpoint);
spyOn(service, 'findByHref').and.returnValue(createSuccessfulRemoteDataObject$(EPersonMock)); spyOn(service, 'findByHref').and.returnValue(createSuccessfulRemoteDataObject$(EPersonMock));
service.searchByScope('email', EPersonMock.email); service.searchByScope('email', EPersonMock.email);
const options = Object.assign(new FindListOptions(), { const options = Object.assign(new FindListOptions(), {
searchParams: [Object.assign(new RequestParam('email', encodeURIComponent(EPersonMock.email)))] searchParams: [Object.assign(new RequestParam('email', encodeURIComponent(EPersonMock.email)))]
}); });
expect(service.getSearchByHref).toHaveBeenCalledWith('byEmail', options); expect((service as any).searchData.getSearchByHref).toHaveBeenCalledWith('byEmail', options);
expect(service.findByHref).toHaveBeenCalledWith(epersonsEndpoint, true, true); expect(service.findByHref).toHaveBeenCalledWith(epersonsEndpoint, true, true);
}); });
}); });

View File

@@ -45,7 +45,7 @@ export class EPersonDataService extends IdentifiableDataService<EPerson> impleme
protected searchByMetadataPath = 'byMetadata'; protected searchByMetadataPath = 'byMetadata';
private createData: CreateData<EPerson>; private createData: CreateData<EPerson>;
private searchData: SearchData<EPerson>; private searchData: SearchDataImpl<EPerson>;
private patchData: PatchData<EPerson>; private patchData: PatchData<EPerson>;
private deleteData: DeleteData<EPerson>; private deleteData: DeleteData<EPerson>;
@@ -128,7 +128,7 @@ export class EPersonDataService extends IdentifiableDataService<EPerson> impleme
public getEPersonByEmail(query: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<EPerson>[]): Observable<RemoteData<EPerson | NoContent>> { public getEPersonByEmail(query: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<EPerson>[]): Observable<RemoteData<EPerson | NoContent>> {
const findListOptions = new FindListOptions(); const findListOptions = new FindListOptions();
findListOptions.searchParams = [new RequestParam('email', encodeURIComponent(query))]; findListOptions.searchParams = [new RequestParam('email', encodeURIComponent(query))];
const href$ = this.getSearchByHref(this.searchByEmailPath, findListOptions, ...linksToFollow); const href$ = this.searchData.getSearchByHref(this.searchByEmailPath, findListOptions, ...linksToFollow);
return this.findByHref(href$, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); return this.findByHref(href$, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
} }
@@ -363,19 +363,6 @@ export class EPersonDataService extends IdentifiableDataService<EPerson> impleme
return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
} }
/**
* Create the HREF for a specific object's search method with given options object
*
* @param searchMethod The search method for the object
* @param options The [[FindListOptions]] object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
getSearchByHref(searchMethod: string, options?: FindListOptions, ...linksToFollow: FollowLinkConfig<EPerson>[]): Observable<string> {
return this.searchData.getSearchByHref(searchMethod, options, ...linksToFollow);
}
/** /**
* Return a list of operations representing the difference between an object and its latest value in the cache. * Return a list of operations representing the difference between an object and its latest value in the cache.
* @param object the object to resolve to a list of patch operations * @param object the object to resolve to a list of patch operations
@@ -384,14 +371,28 @@ export class EPersonDataService extends IdentifiableDataService<EPerson> impleme
return this.patchData.createPatchFromCache(object); return this.patchData.createPatchFromCache(object);
} }
/**
* Send a patch request for a specified object
* @param {T} object The object to send a patch request for
* @param {Operation[]} operations The patch operations to be performed
*/
patch(object: EPerson, operations: Operation[]): Observable<RemoteData<EPerson>> { patch(object: EPerson, operations: Operation[]): Observable<RemoteData<EPerson>> {
return this.patchData.patch(object, operations); return this.patchData.patch(object, operations);
} }
/**
* Add a new patch to the object cache
* The patch is derived from the differences between the given object and its version in the object cache
* @param {DSpaceObject} object The given object
*/
update(object: EPerson): Observable<RemoteData<EPerson>> { update(object: EPerson): Observable<RemoteData<EPerson>> {
return this.patchData.update(object); return this.patchData.update(object);
} }
/**
* Commit current object changes to the server
* @param method The RestRequestMethod for which de server sync buffer should be committed
*/
commitUpdates(method?: RestRequestMethod): void { commitUpdates(method?: RestRequestMethod): void {
this.patchData.commitUpdates(method); this.patchData.commitUpdates(method);
} }

View File

@@ -342,15 +342,11 @@ export class GroupDataService extends IdentifiableDataService<Group> {
return this.createData.create(object, ...params); return this.createData.create(object, ...params);
} }
//
searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<Group>[]): Observable<RemoteData<PaginatedList<Group>>> { searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<Group>[]): Observable<RemoteData<PaginatedList<Group>>> {
return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
} }
getSearchByHref(searchMethod: string, options?: FindListOptions, ...linksToFollow: FollowLinkConfig<Group>[]): Observable<string> {
return this.searchData.getSearchByHref(searchMethod, options, ...linksToFollow);
}
public createPatchFromCache(object: Group): Observable<Operation[]> { public createPatchFromCache(object: Group): Observable<Operation[]> {
return this.patchData.createPatchFromCache(object); return this.patchData.createPatchFromCache(object);
} }

View File

@@ -20,7 +20,7 @@ import { dataService } from '../data/base/data-service.decorator';
@Injectable() @Injectable()
@dataService(SUBMISSION_CC_LICENSE_URL) @dataService(SUBMISSION_CC_LICENSE_URL)
export class SubmissionCcLicenseUrlDataService extends BaseDataService<SubmissionCcLicenceUrl> implements SearchData<SubmissionCcLicenceUrl> { export class SubmissionCcLicenseUrlDataService extends BaseDataService<SubmissionCcLicenceUrl> implements SearchData<SubmissionCcLicenceUrl> {
private searchData: SearchData<SubmissionCcLicenceUrl>; private searchData: SearchDataImpl<SubmissionCcLicenceUrl>;
constructor( constructor(
protected requestService: RequestService, protected requestService: RequestService,
@@ -40,7 +40,7 @@ export class SubmissionCcLicenseUrlDataService extends BaseDataService<Submissio
*/ */
getCcLicenseLink(ccLicense: SubmissionCcLicence, options: Map<Field, Option>): Observable<string> { getCcLicenseLink(ccLicense: SubmissionCcLicence, options: Map<Field, Option>): Observable<string> {
return this.getSearchByHref( return this.searchData.getSearchByHref(
'rightsByQuestions',{ 'rightsByQuestions',{
searchParams: [ searchParams: [
{ {
@@ -64,19 +64,6 @@ export class SubmissionCcLicenseUrlDataService extends BaseDataService<Submissio
); );
} }
/**
* Create the HREF for a specific object's search method with given options object
*
* @param searchMethod The search method for the object
* @param options The [[FindListOptions]] object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getSearchByHref(searchMethod: string, options?: FindListOptions, ...linksToFollow: FollowLinkConfig<SubmissionCcLicenceUrl>[]): Observable<string> {
return this.searchData.getSearchByHref(searchMethod, options, ...linksToFollow);
}
/** /**
* Make a new FindListRequest with given search method * Make a new FindListRequest with given search method
* *

View File

@@ -43,19 +43,6 @@ export class VocabularyEntryDetailsDataService extends IdentifiableDataService<V
this.searchData = new SearchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive); this.searchData = new SearchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive);
} }
/**
* Create the HREF with given options object
*
* @param options The [[FindListOptions]] object
* @param linkPath The link path for the object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getFindAllHref(options: FindListOptions, linkPath?: string, ...linksToFollow: FollowLinkConfig<VocabularyEntryDetail>[]): Observable<string> {
return this.findAllData.getFindAllHref(options, linkPath, ...linksToFollow);
}
/** /**
* Returns {@link RemoteData} of all object with a list of {@link FollowLinkConfig}, to indicate which embedded * Returns {@link RemoteData} of all object with a list of {@link FollowLinkConfig}, to indicate which embedded
* info should be added to the objects * info should be added to the objects
@@ -91,17 +78,4 @@ export class VocabularyEntryDetailsDataService extends IdentifiableDataService<V
public searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<VocabularyEntryDetail>[]): Observable<RemoteData<PaginatedList<VocabularyEntryDetail>>> { public searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<VocabularyEntryDetail>[]): Observable<RemoteData<PaginatedList<VocabularyEntryDetail>>> {
return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
} }
/**
* Create the HREF for a specific object's search method with given options object
*
* @param searchMethod The search method for the object
* @param options The [[FindListOptions]] object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getSearchByHref(searchMethod: string, options?: FindListOptions, ...linksToFollow): Observable<string> {
return this.searchData.getSearchByHref(searchMethod, options, ...linksToFollow);
}
} }

View File

@@ -40,19 +40,6 @@ export class VocabularyDataService extends IdentifiableDataService<Vocabulary> i
this.findAllData = new FindAllDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive); this.findAllData = new FindAllDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive);
} }
/**
* Create the HREF with given options object
*
* @param options The [[FindListOptions]] object
* @param linkPath The link path for the object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getFindAllHref(options: FindListOptions, linkPath?: string, ...linksToFollow: FollowLinkConfig<Vocabulary>[]): Observable<string> {
return this.findAllData.getFindAllHref(options, linkPath, ...linksToFollow);
}
/** /**
* Returns {@link RemoteData} of all object with a list of {@link FollowLinkConfig}, to indicate which embedded * Returns {@link RemoteData} of all object with a list of {@link FollowLinkConfig}, to indicate which embedded
* info should be added to the objects * info should be added to the objects

View File

@@ -253,7 +253,7 @@ describe('VocabularyService', () => {
spyOn((service as any).vocabularyDataService, 'findById').and.callThrough(); spyOn((service as any).vocabularyDataService, 'findById').and.callThrough();
spyOn((service as any).vocabularyDataService, 'findAll').and.callThrough(); spyOn((service as any).vocabularyDataService, 'findAll').and.callThrough();
spyOn((service as any).vocabularyDataService, 'findByHref').and.callThrough(); spyOn((service as any).vocabularyDataService, 'findByHref').and.callThrough();
spyOn((service as any).vocabularyDataService, 'getFindAllHref').and.returnValue(observableOf(entriesRequestURL)); spyOn((service as any).vocabularyDataService.findAllData, 'getFindAllHref').and.returnValue(observableOf(entriesRequestURL));
}); });
afterEach(() => { afterEach(() => {
@@ -421,8 +421,8 @@ describe('VocabularyService', () => {
spyOn((service as any).vocabularyEntryDetailDataService, 'findByHref').and.callThrough(); spyOn((service as any).vocabularyEntryDetailDataService, 'findByHref').and.callThrough();
spyOn((service as any).vocabularyEntryDetailDataService, 'findListByHref').and.callThrough(); spyOn((service as any).vocabularyEntryDetailDataService, 'findListByHref').and.callThrough();
spyOn((service as any).vocabularyEntryDetailDataService, 'searchBy').and.callThrough(); spyOn((service as any).vocabularyEntryDetailDataService, 'searchBy').and.callThrough();
spyOn((service as any).vocabularyEntryDetailDataService, 'getSearchByHref').and.returnValue(observableOf(searchRequestURL)); spyOn((service as any).vocabularyEntryDetailDataService.searchData, 'getSearchByHref').and.returnValue(observableOf(searchRequestURL));
spyOn((service as any).vocabularyEntryDetailDataService, 'getFindAllHref').and.returnValue(observableOf(entryDetailChildrenRequestURL)); spyOn((service as any).vocabularyEntryDetailDataService.findAllData, 'getFindAllHref').and.returnValue(observableOf(entryDetailChildrenRequestURL));
spyOn((service as any).vocabularyEntryDetailDataService, 'getBrowseEndpoint').and.returnValue(observableOf(entryDetailEndpointURL)); spyOn((service as any).vocabularyEntryDetailDataService, 'getBrowseEndpoint').and.returnValue(observableOf(entryDetailEndpointURL));
}); });

View File

@@ -281,8 +281,10 @@ export class VocabularyService {
pageInfo.elementsPerPage, pageInfo.elementsPerPage,
pageInfo.currentPage pageInfo.currentPage
); );
return this.vocabularyEntryDetailDataService.getFindAllHref(options, linkPath).pipe(
mergeMap((href) => this.vocabularyEntryDetailDataService.findListByHref(href, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow)), return this.vocabularyEntryDetailDataService.getBrowseEndpoint().pipe(
map(href => `${href}/${name}:${value}/children`),
switchMap(href => this.vocabularyEntryDetailDataService.findListByHref(href, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow))
); );
} }

View File

@@ -118,7 +118,7 @@ describe('WorkflowItemDataService test', () => {
service = initTestService(); service = initTestService();
spyOn((service as any), 'findByHref').and.callThrough(); spyOn((service as any), 'findByHref').and.callThrough();
spyOn((service as any), 'getSearchByHref').and.returnValue(searchRequestURL$); spyOn((service as any).searchData, 'getSearchByHref').and.returnValue(searchRequestURL$);
}); });
afterEach(() => { afterEach(() => {

View File

@@ -108,23 +108,10 @@ export class WorkflowItemDataService extends IdentifiableDataService<WorkflowIte
public findByItem(uuid: string, useCachedVersionIfAvailable = false, reRequestOnStale = true, options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig<WorkspaceItem>[]): Observable<RemoteData<WorkspaceItem>> { public findByItem(uuid: string, useCachedVersionIfAvailable = false, reRequestOnStale = true, options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig<WorkspaceItem>[]): Observable<RemoteData<WorkspaceItem>> {
const findListOptions = new FindListOptions(); const findListOptions = new FindListOptions();
findListOptions.searchParams = [new RequestParam('uuid', encodeURIComponent(uuid))]; findListOptions.searchParams = [new RequestParam('uuid', encodeURIComponent(uuid))];
const href$ = this.getSearchByHref(this.searchByItemLinkPath, findListOptions, ...linksToFollow); const href$ = this.searchData.getSearchByHref(this.searchByItemLinkPath, findListOptions, ...linksToFollow);
return this.findByHref(href$, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); return this.findByHref(href$, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
} }
/**
* Create the HREF for a specific object's search method with given options object
*
* @param searchMethod The search method for the object
* @param options The [[FindListOptions]] object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getSearchByHref(searchMethod: string, options?: FindListOptions, ...linksToFollow): Observable<string> {
return this.searchData.getSearchByHref(searchMethod, options, ...linksToFollow);
}
/** /**
* Make a new FindListRequest with given search method * Make a new FindListRequest with given search method
* *

View File

@@ -111,7 +111,7 @@ describe('TasksService', () => {
it('should call findByHref with the href generated by getSearchByHref', () => { it('should call findByHref with the href generated by getSearchByHref', () => {
spyOn(service, 'getSearchByHref').and.returnValue(observableOf('generatedHref')); spyOn((service as any).searchData, 'getSearchByHref').and.returnValue(observableOf('generatedHref'));
spyOn(service, 'findByHref').and.returnValue(observableOf(null)); spyOn(service, 'findByHref').and.returnValue(observableOf(null));
const followLinks = {}; const followLinks = {};
@@ -121,7 +121,7 @@ describe('TasksService', () => {
scheduler.schedule(() => service.searchTask('method', options, followLinks as any).subscribe()); scheduler.schedule(() => service.searchTask('method', options, followLinks as any).subscribe());
scheduler.flush(); scheduler.flush();
expect(service.getSearchByHref).toHaveBeenCalledWith('method', options, followLinks as any); expect((service as any).searchData.getSearchByHref).toHaveBeenCalledWith('method', options, followLinks as any);
expect(service.findByHref).toHaveBeenCalledWith('generatedHref', false, true); expect(service.findByHref).toHaveBeenCalledWith('generatedHref', false, true);
}); });
}); });

View File

@@ -23,7 +23,7 @@ import { IdentifiableDataService } from '../data/base/identifiable-data.service'
* An abstract class that provides methods to handle task requests. todo: data in name * An abstract class that provides methods to handle task requests. todo: data in name
*/ */
export abstract class TasksService<T extends CacheableObject> extends IdentifiableDataService<T> implements SearchData<T> { export abstract class TasksService<T extends CacheableObject> extends IdentifiableDataService<T> implements SearchData<T> {
private searchData: SearchData<T>; private searchData: SearchDataImpl<T>;
protected constructor( protected constructor(
protected linkPath: string, protected linkPath: string,
@@ -119,7 +119,7 @@ export abstract class TasksService<T extends CacheableObject> extends Identifiab
* links to follow * links to follow
*/ */
public searchTask(searchMethod: string, options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<T>> { public searchTask(searchMethod: string, options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<T>> {
const hrefObs = this.getSearchByHref(searchMethod, options, ...linksToFollow); const hrefObs = this.searchData.getSearchByHref(searchMethod, options, ...linksToFollow);
return hrefObs.pipe( return hrefObs.pipe(
find((href: string) => hasValue(href)), find((href: string) => hasValue(href)),
mergeMap((href) => this.findByHref(href, false, true).pipe( mergeMap((href) => this.findByHref(href, false, true).pipe(
@@ -161,19 +161,6 @@ export abstract class TasksService<T extends CacheableObject> extends Identifiab
return options; return options;
} }
/**
* Create the HREF for a specific object's search method with given options object
*
* @param searchMethod The search method for the object
* @param options The [[FindListOptions]] object
* @return {Observable<string>}
* Return an observable that emits created HREF
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getSearchByHref(searchMethod: string, options?: FindListOptions, ...linksToFollow: FollowLinkConfig<T>[]): Observable<string> {
return this.searchData.getSearchByHref(searchMethod, options, ...linksToFollow);
}
/** /**
* Make a new FindListRequest with given search method * Make a new FindListRequest with given search method
* *