mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
refactor followlinks to use a single object for all params and add an isOptional param. Also add support for embedding links to search service
This commit is contained in:
@@ -35,7 +35,7 @@ export class BitstreamPageResolver implements Resolve<RemoteData<Bitstream>> {
|
||||
*/
|
||||
get followLinks(): FollowLinkConfig<Bitstream>[] {
|
||||
return [
|
||||
followLink('bundle', undefined, true, true, true, followLink('item')),
|
||||
followLink('bundle', {}, followLink('item')),
|
||||
followLink('format')
|
||||
];
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ import { ResolvedAction } from '../core/resolving/resolver.actions';
|
||||
* Requesting them as embeds will limit the number of requests
|
||||
*/
|
||||
export const COLLECTION_PAGE_LINKS_TO_FOLLOW: FollowLinkConfig<Collection>[] = [
|
||||
followLink('parentCommunity', undefined, true, true, true,
|
||||
followLink('parentCommunity', {},
|
||||
followLink('parentCommunity')
|
||||
),
|
||||
followLink('logo')
|
||||
|
@@ -79,7 +79,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
|
||||
getFirstSucceededRemoteDataWithNotEmptyPayload(),
|
||||
map((item: Item) => this.linkService.resolveLink(
|
||||
item,
|
||||
followLink('bundles', new FindListOptions(), true, true, true, followLink('bitstreams'))
|
||||
followLink('bundles', {}, followLink('bitstreams'))
|
||||
))
|
||||
) as Observable<Item>;
|
||||
|
||||
|
@@ -323,7 +323,7 @@ export class EditRelationshipListComponent implements OnInit {
|
||||
|
||||
private getItemRelationships() {
|
||||
this.linkService.resolveLink(this.item,
|
||||
followLink('relationships', undefined, true, true, true,
|
||||
followLink('relationships', {},
|
||||
followLink('relationshipType'),
|
||||
followLink('leftItem'),
|
||||
followLink('rightItem'),
|
||||
|
@@ -15,13 +15,13 @@ import { ResolvedAction } from '../core/resolving/resolver.actions';
|
||||
* Requesting them as embeds will limit the number of requests
|
||||
*/
|
||||
export const ITEM_PAGE_LINKS_TO_FOLLOW: FollowLinkConfig<Item>[] = [
|
||||
followLink('owningCollection', undefined, true, true, true,
|
||||
followLink('parentCommunity', undefined, true, true, true,
|
||||
followLink('owningCollection', {},
|
||||
followLink('parentCommunity', {},
|
||||
followLink('parentCommunity'))
|
||||
),
|
||||
followLink('bundles', new FindListOptions(), true, true, true, followLink('bitstreams')),
|
||||
followLink('bundles', {}, followLink('bitstreams')),
|
||||
followLink('relationships'),
|
||||
followLink('version', undefined, true, true, true, followLink('versionhistory')),
|
||||
followLink('version', {}, followLink('versionhistory')),
|
||||
];
|
||||
|
||||
/**
|
||||
|
@@ -19,6 +19,8 @@ import { currentPath } from '../shared/utils/route.utils';
|
||||
import { Router } from '@angular/router';
|
||||
import { Context } from '../core/shared/context.model';
|
||||
import { SortOptions } from '../core/cache/models/sort-options.model';
|
||||
import { followLink } from '../shared/utils/follow-link-config.model';
|
||||
import { Item } from '../core/shared/item.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-search',
|
||||
|
@@ -174,8 +174,8 @@ export class CommunityListService {
|
||||
direction: options.sort.direction
|
||||
}
|
||||
},
|
||||
followLink('subcommunities', this.configOnePage, true, true),
|
||||
followLink('collections', this.configOnePage, true, true))
|
||||
followLink('subcommunities', { findListOptions: this.configOnePage }),
|
||||
followLink('collections', { findListOptions: this.configOnePage }))
|
||||
.pipe(
|
||||
getFirstSucceededRemoteData(),
|
||||
map((results) => results.payload),
|
||||
@@ -242,8 +242,8 @@ export class CommunityListService {
|
||||
elementsPerPage: MAX_COMCOLS_PER_PAGE,
|
||||
currentPage: i
|
||||
},
|
||||
followLink('subcommunities', this.configOnePage, true, true),
|
||||
followLink('collections', this.configOnePage, true, true))
|
||||
followLink('subcommunities', { findListOptions: this.configOnePage }),
|
||||
followLink('collections', { findListOptions: this.configOnePage }))
|
||||
.pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
switchMap((rd: RemoteData<PaginatedList<Community>>) => {
|
||||
|
10
src/app/core/cache/builders/link.service.spec.ts
vendored
10
src/app/core/cache/builders/link.service.spec.ts
vendored
@@ -102,7 +102,7 @@ describe('LinkService', () => {
|
||||
describe('resolveLink', () => {
|
||||
describe(`when the linkdefinition concerns a single object`, () => {
|
||||
beforeEach(() => {
|
||||
service.resolveLink(testModel, followLink('predecessor', {}, true, true, true, followLink('successor')));
|
||||
service.resolveLink(testModel, followLink('predecessor', {}, followLink('successor')));
|
||||
});
|
||||
it('should call dataservice.findByHref with the correct href and nested links', () => {
|
||||
expect(testDataService.findByHref).toHaveBeenCalledWith(testModel._links.predecessor.href, true, true, followLink('successor'));
|
||||
@@ -116,7 +116,7 @@ describe('LinkService', () => {
|
||||
propertyName: 'predecessor',
|
||||
isList: true
|
||||
});
|
||||
service.resolveLink(testModel, followLink('predecessor', { some: 'options ' } as any, true, true, true, followLink('successor')));
|
||||
service.resolveLink(testModel, followLink('predecessor', { findListOptions: { some: 'options ' } as any }, followLink('successor')));
|
||||
});
|
||||
it('should call dataservice.findAllByHref with the correct href, findListOptions, and nested links', () => {
|
||||
expect(testDataService.findAllByHref).toHaveBeenCalledWith(testModel._links.predecessor.href, { some: 'options ' } as any, true, true, followLink('successor'));
|
||||
@@ -124,7 +124,7 @@ describe('LinkService', () => {
|
||||
});
|
||||
describe('either way', () => {
|
||||
beforeEach(() => {
|
||||
result = service.resolveLink(testModel, followLink('predecessor', {}, true, true, true, followLink('successor')));
|
||||
result = service.resolveLink(testModel, followLink('predecessor', {}, followLink('successor')));
|
||||
});
|
||||
|
||||
it('should call getLinkDefinition with the correct model and link', () => {
|
||||
@@ -149,7 +149,7 @@ describe('LinkService', () => {
|
||||
});
|
||||
it('should throw an error', () => {
|
||||
expect(() => {
|
||||
service.resolveLink(testModel, followLink('predecessor', {}, true, true, true, followLink('successor')));
|
||||
service.resolveLink(testModel, followLink('predecessor', {}, followLink('successor')));
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
@@ -160,7 +160,7 @@ describe('LinkService', () => {
|
||||
});
|
||||
it('should throw an error', () => {
|
||||
expect(() => {
|
||||
service.resolveLink(testModel, followLink('predecessor', {}, true, true, true, followLink('successor')));
|
||||
service.resolveLink(testModel, followLink('predecessor', {}, followLink('successor')));
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
|
7
src/app/core/cache/builders/link.service.ts
vendored
7
src/app/core/cache/builders/link.service.ts
vendored
@@ -55,9 +55,7 @@ export class LinkService {
|
||||
public resolveLinkWithoutAttaching<T extends HALResource, U extends HALResource>(model, linkToFollow: FollowLinkConfig<T>): Observable<RemoteData<U>> {
|
||||
const matchingLinkDef = this.getLinkDefinition(model.constructor, linkToFollow.name);
|
||||
|
||||
if (hasNoValue(matchingLinkDef)) {
|
||||
throw new Error(`followLink('${linkToFollow.name}') was used for a ${model.constructor.name}, but there is no property on ${model.constructor.name} models with an @link() for ${linkToFollow.name}`);
|
||||
} else {
|
||||
if (hasValue(matchingLinkDef)) {
|
||||
const provider = this.getDataServiceFor(matchingLinkDef.resourceType);
|
||||
|
||||
if (hasNoValue(provider)) {
|
||||
@@ -84,7 +82,10 @@ export class LinkService {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else if (!linkToFollow.isOptional) {
|
||||
throw new Error(`followLink('${linkToFollow.name}') was used as a required link for a ${model.constructor.name}, but there is no property on ${model.constructor.name} models with an @link() for ${linkToFollow.name}`);
|
||||
}
|
||||
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
|
@@ -523,7 +523,7 @@ describe('RemoteDataBuildService', () => {
|
||||
let paginatedLinksToFollow;
|
||||
beforeEach(() => {
|
||||
paginatedLinksToFollow = [
|
||||
followLink('page', undefined, true, true, true, ...linksToFollow),
|
||||
followLink('page', {}, ...linksToFollow),
|
||||
...linksToFollow
|
||||
];
|
||||
});
|
||||
|
@@ -271,7 +271,7 @@ export class RemoteDataBuildService {
|
||||
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||
*/
|
||||
buildList<T extends HALResource>(href$: string | Observable<string>, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<PaginatedList<T>>> {
|
||||
return this.buildFromHref<PaginatedList<T>>(href$, followLink('page', undefined, false, true, true, ...linksToFollow));
|
||||
return this.buildFromHref<PaginatedList<T>>(href$, followLink('page', { shouldEmbed: false }, ...linksToFollow));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -233,7 +233,7 @@ describe('DataService', () => {
|
||||
const config: FindListOptions = Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: 5
|
||||
});
|
||||
(service as any).getFindAllHref({}, null, followLink('bundles', config, true, true, true)).subscribe((value) => {
|
||||
(service as any).getFindAllHref({}, null, followLink('bundles', { findListOptions: config })).subscribe((value) => {
|
||||
expect(value).toBe(expected);
|
||||
});
|
||||
});
|
||||
@@ -253,7 +253,7 @@ describe('DataService', () => {
|
||||
elementsPerPage: 2
|
||||
});
|
||||
|
||||
(service as any).getFindAllHref({}, null, followLink('bundles'), followLink('owningCollection', config, true, true, true), followLink('templateItemOf')).subscribe((value) => {
|
||||
(service as any).getFindAllHref({}, null, followLink('bundles'), followLink('owningCollection', { findListOptions: config }), followLink('templateItemOf')).subscribe((value) => {
|
||||
expect(value).toBe(expected);
|
||||
});
|
||||
});
|
||||
@@ -261,7 +261,13 @@ describe('DataService', () => {
|
||||
it('should not include linksToFollow with shouldEmbed = false', () => {
|
||||
const expected = `${endpoint}?embed=templateItemOf`;
|
||||
|
||||
(service as any).getFindAllHref({}, null, followLink('bundles', undefined, false), followLink('owningCollection', undefined, false), followLink('templateItemOf')).subscribe((value) => {
|
||||
(service as any).getFindAllHref(
|
||||
{},
|
||||
null,
|
||||
followLink('bundles', { shouldEmbed: false }),
|
||||
followLink('owningCollection', { shouldEmbed: false }),
|
||||
followLink('templateItemOf')
|
||||
).subscribe((value) => {
|
||||
expect(value).toBe(expected);
|
||||
});
|
||||
});
|
||||
@@ -269,7 +275,7 @@ describe('DataService', () => {
|
||||
it('should include nested linksToFollow 3lvl', () => {
|
||||
const expected = `${endpoint}?embed=owningCollection/itemtemplate/relationships`;
|
||||
|
||||
(service as any).getFindAllHref({}, null, followLink('owningCollection', undefined, true, true, true, followLink('itemtemplate', undefined, true, true, true, followLink('relationships')))).subscribe((value) => {
|
||||
(service as any).getFindAllHref({}, null, followLink('owningCollection', {}, followLink('itemtemplate', {}, followLink('relationships')))).subscribe((value) => {
|
||||
expect(value).toBe(expected);
|
||||
});
|
||||
});
|
||||
@@ -279,7 +285,7 @@ describe('DataService', () => {
|
||||
const config: FindListOptions = Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: 4
|
||||
});
|
||||
(service as any).getFindAllHref({}, null, followLink('owningCollection', undefined, true, true, true, followLink('itemtemplate', config, true, true, true))).subscribe((value) => {
|
||||
(service as any).getFindAllHref({}, null, followLink('owningCollection', {}, followLink('itemtemplate', { findListOptions: config }))).subscribe((value) => {
|
||||
expect(value).toBe(expected);
|
||||
});
|
||||
});
|
||||
@@ -308,13 +314,19 @@ describe('DataService', () => {
|
||||
|
||||
it('should not include linksToFollow with shouldEmbed = false', () => {
|
||||
const expected = `${endpointMock}/${resourceIdMock}?embed=templateItemOf`;
|
||||
const result = (service as any).getIDHref(endpointMock, resourceIdMock, followLink('bundles', undefined, false), followLink('owningCollection', undefined, false), followLink('templateItemOf'));
|
||||
const result = (service as any).getIDHref(
|
||||
endpointMock,
|
||||
resourceIdMock,
|
||||
followLink('bundles', { shouldEmbed: false }),
|
||||
followLink('owningCollection', { shouldEmbed: false }),
|
||||
followLink('templateItemOf')
|
||||
);
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should include nested linksToFollow 3lvl', () => {
|
||||
const expected = `${endpointMock}/${resourceIdMock}?embed=owningCollection/itemtemplate/relationships`;
|
||||
const result = (service as any).getIDHref(endpointMock, resourceIdMock, followLink('owningCollection', undefined, true, true, true,followLink('itemtemplate', undefined, true, true, true, followLink('relationships'))));
|
||||
const result = (service as any).getIDHref(endpointMock, resourceIdMock, followLink('owningCollection', {}, followLink('itemtemplate', {}, followLink('relationships'))));
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
@@ -174,13 +174,29 @@ describe('DsoRedirectDataService', () => {
|
||||
|
||||
it('should not include linksToFollow with shouldEmbed = false', () => {
|
||||
const expected = `${requestUUIDURL}&embed=templateItemOf`;
|
||||
const result = (service as any).getIDHref(pidLink, dsoUUID, followLink('bundles', undefined, false), followLink('owningCollection', undefined, false), followLink('templateItemOf'));
|
||||
const result = (service as any).getIDHref(
|
||||
pidLink,
|
||||
dsoUUID,
|
||||
followLink('bundles', { shouldEmbed: false }),
|
||||
followLink('owningCollection', { shouldEmbed: false }),
|
||||
followLink('templateItemOf')
|
||||
);
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should include nested linksToFollow 3lvl', () => {
|
||||
const expected = `${requestUUIDURL}&embed=owningCollection/itemtemplate/relationships`;
|
||||
const result = (service as any).getIDHref(pidLink, dsoUUID, followLink('owningCollection', undefined, true, true, true, followLink('itemtemplate', undefined, true, true, true, followLink('relationships'))));
|
||||
const result = (service as any).getIDHref(
|
||||
pidLink,
|
||||
dsoUUID,
|
||||
followLink('owningCollection',
|
||||
{},
|
||||
followLink('itemtemplate',
|
||||
{},
|
||||
followLink('relationships')
|
||||
)
|
||||
)
|
||||
);
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
@@ -41,6 +41,43 @@ import { SearchConfig } from './search-filters/search-config.model';
|
||||
import { PaginationService } from '../../pagination/pagination.service';
|
||||
import { SearchConfigurationService } from './search-configuration.service';
|
||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||
import { DataService } from '../../data/data.service';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { CoreState } from '../../core.reducers';
|
||||
import { ObjectCacheService } from '../../cache/object-cache.service';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { DSOChangeAnalyzer } from '../../data/dso-change-analyzer.service';
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
/**
|
||||
* A class that lets us delegate some methods to DataService
|
||||
*/
|
||||
class DataServiceImpl extends DataService<any> {
|
||||
protected linkPath = 'discover';
|
||||
|
||||
constructor(
|
||||
protected requestService: RequestService,
|
||||
protected rdbService: RemoteDataBuildService,
|
||||
protected store: Store<CoreState>,
|
||||
protected objectCache: ObjectCacheService,
|
||||
protected halService: HALEndpointService,
|
||||
protected notificationsService: NotificationsService,
|
||||
protected http: HttpClient,
|
||||
protected comparator: DSOChangeAnalyzer<any>) {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the embed options to the link for the request
|
||||
* @param href The href the params are to be added to
|
||||
* @param args params for the query string
|
||||
* @param linksToFollow links we want to embed in query string if shouldEmbed is true
|
||||
*/
|
||||
public addEmbedParams(href: string, args: string[], ...linksToFollow: FollowLinkConfig<any>[]) {
|
||||
return super.addEmbedParams(href, args, ...linksToFollow);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Service that performs all general actions that have to do with the search page
|
||||
@@ -78,6 +115,11 @@ export class SearchService implements OnDestroy {
|
||||
*/
|
||||
private sub;
|
||||
|
||||
/**
|
||||
* Instance of DataServiceImpl that lets us delegate some methods to DataService
|
||||
*/
|
||||
private searchDataService: DataServiceImpl;
|
||||
|
||||
constructor(private router: Router,
|
||||
private routeService: RouteService,
|
||||
protected requestService: RequestService,
|
||||
@@ -89,6 +131,16 @@ export class SearchService implements OnDestroy {
|
||||
private paginationService: PaginationService,
|
||||
private searchConfigurationService: SearchConfigurationService
|
||||
) {
|
||||
this.searchDataService = new DataServiceImpl(
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,7 +183,17 @@ export class SearchService implements OnDestroy {
|
||||
search<T extends DSpaceObject>(searchOptions?: PaginatedSearchOptions, responseMsToLive?: number, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<SearchObjects<T>>> {
|
||||
const href$ = this.getEndpoint(searchOptions);
|
||||
|
||||
href$.pipe(take(1)).subscribe((url: string) => {
|
||||
href$.pipe(
|
||||
take(1),
|
||||
map((href: string) => {
|
||||
const args = this.searchDataService.addEmbedParams(href, [], ...linksToFollow);
|
||||
if (isNotEmpty(args)) {
|
||||
return new URLCombiner(href, `?${args.join('&')}`).toString();
|
||||
} else {
|
||||
return href;
|
||||
}
|
||||
})
|
||||
).subscribe((url: string) => {
|
||||
const request = new this.request(this.requestService.generateRequestId(), url);
|
||||
|
||||
const getResponseParserFn: () => GenericConstructor<ResponseParsingService> = () => {
|
||||
|
@@ -173,7 +173,7 @@ export class VocabularyService {
|
||||
);
|
||||
|
||||
// TODO remove false for the entries embed when https://github.com/DSpace/DSpace/issues/3096 is solved
|
||||
return this.findVocabularyById(vocabularyOptions.name, true, true, followLink('entries', options, false)).pipe(
|
||||
return this.findVocabularyById(vocabularyOptions.name, true, true, followLink('entries', { findListOptions: options, shouldEmbed: false })).pipe(
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
switchMap((vocabulary: Vocabulary) => vocabulary.entries),
|
||||
);
|
||||
@@ -200,7 +200,7 @@ export class VocabularyService {
|
||||
);
|
||||
|
||||
// TODO remove false for the entries embed when https://github.com/DSpace/DSpace/issues/3096 is solved
|
||||
return this.findVocabularyById(vocabularyOptions.name, true, true, followLink('entries', options, false)).pipe(
|
||||
return this.findVocabularyById(vocabularyOptions.name, true, true, followLink('entries', { findListOptions: options, shouldEmbed: false })).pipe(
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
switchMap((vocabulary: Vocabulary) => vocabulary.entries),
|
||||
);
|
||||
@@ -249,7 +249,7 @@ export class VocabularyService {
|
||||
);
|
||||
|
||||
// TODO remove false for the entries embed when https://github.com/DSpace/DSpace/issues/3096 is solved
|
||||
return this.findVocabularyById(vocabularyOptions.name, true, true, followLink('entries', options, false)).pipe(
|
||||
return this.findVocabularyById(vocabularyOptions.name, true, true, followLink('entries', { findListOptions: options, shouldEmbed: false })).pipe(
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
switchMap((vocabulary: Vocabulary) => vocabulary.entries),
|
||||
getFirstSucceededRemoteListPayload(),
|
||||
|
@@ -49,8 +49,8 @@ export class ClaimedTaskSearchResultDetailElementComponent extends SearchResultD
|
||||
*/
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
this.linkService.resolveLinks(this.dso, followLink('workflowitem', null, true, true, true,
|
||||
followLink('item', null, true, true, true, followLink('bundles')),
|
||||
this.linkService.resolveLinks(this.dso, followLink('workflowitem', {},
|
||||
followLink('item', {}, followLink('bundles')),
|
||||
followLink('submitter')
|
||||
), followLink('action'));
|
||||
this.workflowitemRD$ = this.dso.workflowitem as Observable<RemoteData<WorkflowItem>>;
|
||||
|
@@ -48,8 +48,8 @@ export class PoolSearchResultDetailElementComponent extends SearchResultDetailEl
|
||||
*/
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
this.linkService.resolveLinks(this.dso, followLink('workflowitem', null, true, true, true,
|
||||
followLink('item', null, true, true, true, followLink('bundles')),
|
||||
this.linkService.resolveLinks(this.dso, followLink('workflowitem', {},
|
||||
followLink('item', {}, followLink('bundles')),
|
||||
followLink('submitter')
|
||||
), followLink('action'));
|
||||
this.workflowitemRD$ = this.dso.workflowitem as Observable<RemoteData<WorkflowItem>>;
|
||||
|
@@ -55,10 +55,7 @@ export class ClaimedApprovedSearchResultListElementComponent extends SearchResul
|
||||
super.ngOnInit();
|
||||
this.linkService.resolveLinks(this.dso,
|
||||
followLink('workflowitem',
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
{ useCachedVersionIfAvailable: false },
|
||||
followLink('item'),
|
||||
followLink('submitter')
|
||||
),
|
||||
|
@@ -56,10 +56,7 @@ export class ClaimedDeclinedSearchResultListElementComponent extends SearchResul
|
||||
super.ngOnInit();
|
||||
this.linkService.resolveLinks(this.dso,
|
||||
followLink('workflowitem',
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
{ useCachedVersionIfAvailable: false },
|
||||
followLink('item'),
|
||||
followLink('submitter')
|
||||
),
|
||||
|
@@ -50,7 +50,7 @@ export class ClaimedSearchResultListElementComponent extends SearchResultListEle
|
||||
*/
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
this.linkService.resolveLinks(this.dso, followLink('workflowitem', null, true, true, true,
|
||||
this.linkService.resolveLinks(this.dso, followLink('workflowitem', {},
|
||||
followLink('item'), followLink('submitter')
|
||||
), followLink('action'));
|
||||
this.workflowitemRD$ = this.dso.workflowitem as Observable<RemoteData<WorkflowItem>>;
|
||||
|
@@ -60,7 +60,7 @@ export class PoolSearchResultListElementComponent extends SearchResultListElemen
|
||||
*/
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
this.linkService.resolveLinks(this.dso, followLink('workflowitem', null, true, true, true,
|
||||
this.linkService.resolveLinks(this.dso, followLink('workflowitem', {},
|
||||
followLink('item'), followLink('submitter')
|
||||
), followLink('action'));
|
||||
this.workflowitemRD$ = this.dso.workflowitem as Observable<RemoteData<WorkflowItem>>;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { FindListOptions } from '../../core/data/request.models';
|
||||
import { HALResource } from '../../core/shared/hal-resource.model';
|
||||
import { hasValue } from '../empty.util';
|
||||
|
||||
/**
|
||||
* A class to send the retrieval of a {@link HALLink}
|
||||
@@ -40,6 +41,12 @@ export class FollowLinkConfig<R extends HALResource> {
|
||||
* Defaults to true
|
||||
*/
|
||||
reRequestOnStale? = true;
|
||||
|
||||
/**
|
||||
* If this is false an error will be thrown if the link doesn't exist on the model it is used on
|
||||
* Defaults to false
|
||||
*/
|
||||
isOptional? = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,23 +64,35 @@ export class FollowLinkConfig<R extends HALResource> {
|
||||
* no valid cached version. Defaults
|
||||
* @param reRequestOnStale: Whether or not the link should automatically be re-requested after the
|
||||
* response becomes stale
|
||||
* @param isOptional: Whether or not to fail if the link doesn't exist
|
||||
* @param linksToFollow: a list of {@link FollowLinkConfig}s to
|
||||
* use on the retrieved object.
|
||||
*/
|
||||
export const followLink = <R extends HALResource>(
|
||||
linkName: keyof R['_links'],
|
||||
findListOptions?: FindListOptions,
|
||||
shouldEmbed = true,
|
||||
useCachedVersionIfAvailable = true,
|
||||
reRequestOnStale = true,
|
||||
...linksToFollow: FollowLinkConfig<any>[]
|
||||
): FollowLinkConfig<R> => {
|
||||
return {
|
||||
name: linkName,
|
||||
{
|
||||
findListOptions,
|
||||
shouldEmbed,
|
||||
useCachedVersionIfAvailable,
|
||||
reRequestOnStale,
|
||||
isOptional
|
||||
}: {
|
||||
findListOptions?: FindListOptions,
|
||||
shouldEmbed?: boolean,
|
||||
useCachedVersionIfAvailable?: boolean,
|
||||
reRequestOnStale?: boolean,
|
||||
isOptional?: boolean,
|
||||
} = {},
|
||||
...linksToFollow: FollowLinkConfig<any>[]
|
||||
): FollowLinkConfig<R> => {
|
||||
const followLinkConfig = {
|
||||
name: linkName,
|
||||
findListOptions: hasValue(findListOptions) ? findListOptions : new FindListOptions(),
|
||||
shouldEmbed: hasValue(shouldEmbed) ? shouldEmbed : true,
|
||||
useCachedVersionIfAvailable: hasValue(useCachedVersionIfAvailable) ? useCachedVersionIfAvailable : true,
|
||||
reRequestOnStale: hasValue(reRequestOnStale) ? reRequestOnStale : true,
|
||||
isOptional: hasValue(isOptional) ? isOptional : false,
|
||||
linksToFollow
|
||||
};
|
||||
return followLinkConfig;
|
||||
};
|
||||
|
Reference in New Issue
Block a user