mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
50463: use search/facet endpoint to retrieve facet values
This commit is contained in:
@@ -117,7 +117,7 @@
|
||||
"placeholder": "Subject",
|
||||
"head": "Subject"
|
||||
},
|
||||
"date": {
|
||||
"dateIssued": {
|
||||
"placeholder": "Date",
|
||||
"head": "Date"
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import { FacetValue } from '../../search-service/facet-value.model';
|
||||
import { SearchFilterService } from './search-filter.service';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { slide } from '../../../shared/animations/slide';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
|
||||
/**
|
||||
* This component renders a simple item page.
|
||||
@@ -22,13 +23,13 @@ import { slide } from '../../../shared/animations/slide';
|
||||
|
||||
export class SearchFilterComponent implements OnInit {
|
||||
@Input() filter: SearchFilterConfig;
|
||||
filterValues: Observable<RemoteData<FacetValue[]>>;
|
||||
filterValues: Observable<RemoteData<FacetValue[] | PaginatedList<FacetValue>>>;
|
||||
|
||||
constructor(private searchService: SearchService, private filterService: SearchFilterService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.filterValues = this.searchService.getFacetValuesFor(this.filter.name);
|
||||
this.filterValues = this.searchService.getFacetValuesFor(this.filter.name, '', '');
|
||||
const sub = this.filterService.isFilterActive(this.filter.paramName).first().subscribe((isActive) => {
|
||||
if (this.filter.isOpenByDefault || isActive) {
|
||||
this.initialExpand();
|
||||
|
@@ -1,7 +1,13 @@
|
||||
|
||||
import { autoserialize, autoserializeAs } from 'cerialize';
|
||||
|
||||
export class FacetValue {
|
||||
|
||||
@autoserializeAs(String, 'label')
|
||||
value: string;
|
||||
|
||||
@autoserialize
|
||||
count: number;
|
||||
|
||||
@autoserialize
|
||||
search: string;
|
||||
}
|
||||
|
@@ -1,13 +1,14 @@
|
||||
import { Inject, Injectable, OnDestroy } from '@angular/core';
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
import { ActivatedRoute, NavigationExtras, Router } from '@angular/router';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { flatMap, map, tap } from 'rxjs/operators';
|
||||
import { ViewMode } from '../../+search-page/search-options.model';
|
||||
import { GLOBAL_CONFIG } from '../../../config';
|
||||
import { GlobalConfig } from '../../../config/global-config.interface';
|
||||
import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service';
|
||||
import { SortOptions } from '../../core/cache/models/sort-options.model';
|
||||
import { SearchSuccessResponse } from '../../core/cache/response-cache.models';
|
||||
import {
|
||||
FacetValueMapSuccessResponse, FacetValueSuccessResponse,
|
||||
SearchSuccessResponse
|
||||
} from '../../core/cache/response-cache.models';
|
||||
import { ResponseCacheEntry } from '../../core/cache/response-cache.reducer';
|
||||
import { ResponseCacheService } from '../../core/cache/response-cache.service';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
@@ -33,6 +34,7 @@ import { SearchQueryResponse } from './search-query-response.model';
|
||||
import { PageInfo } from '../../core/shared/page-info.model';
|
||||
import { getSearchResultFor } from './search-result-element-decorator';
|
||||
import { ListableObject } from '../../shared/object-collection/shared/listable-object.model';
|
||||
import { FacetResponseParsingService } from '../../core/data/facet-response-parsing.service';
|
||||
|
||||
function shuffle(array: any[]) {
|
||||
let i = 0;
|
||||
@@ -49,20 +51,21 @@ function shuffle(array: any[]) {
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SearchService extends HALEndpointService implements OnDestroy {
|
||||
protected linkPath = 'discover/search/objects';
|
||||
export class SearchService implements OnDestroy {
|
||||
private searchLinkPath = 'discover/search/objects';
|
||||
private facetLinkPath = 'discover/search/facets';
|
||||
|
||||
private sub;
|
||||
uiSearchRoute = '/search';
|
||||
|
||||
config: SearchFilterConfig[] = [
|
||||
Object.assign(new SearchFilterConfig(),
|
||||
{
|
||||
name: 'scope',
|
||||
type: FilterType.hierarchy,
|
||||
hasFacets: true,
|
||||
isOpenByDefault: true
|
||||
}),
|
||||
// Object.assign(new SearchFilterConfig(),
|
||||
// {
|
||||
// name: 'scope',
|
||||
// type: FilterType.hierarchy,
|
||||
// hasFacets: true,
|
||||
// isOpenByDefault: true
|
||||
// }),
|
||||
Object.assign(new SearchFilterConfig(),
|
||||
{
|
||||
name: 'author',
|
||||
@@ -72,7 +75,7 @@ export class SearchService extends HALEndpointService implements OnDestroy {
|
||||
}),
|
||||
Object.assign(new SearchFilterConfig(),
|
||||
{
|
||||
name: 'date',
|
||||
name: 'dateIssued',
|
||||
type: FilterType.range,
|
||||
hasFacets: true,
|
||||
isOpenByDefault: false
|
||||
@@ -92,10 +95,9 @@ export class SearchService extends HALEndpointService implements OnDestroy {
|
||||
private route: ActivatedRoute,
|
||||
protected responseCache: ResponseCacheService,
|
||||
protected requestService: RequestService,
|
||||
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
||||
private routeService: RouteService,
|
||||
private rdb: RemoteDataBuildService,) {
|
||||
super();
|
||||
private rdb: RemoteDataBuildService,
|
||||
private halService: HALEndpointService) {
|
||||
const pagination: PaginationComponentOptions = new PaginationComponentOptions();
|
||||
pagination.id = 'search-results-pagination';
|
||||
pagination.currentPage = 1;
|
||||
@@ -106,7 +108,7 @@ export class SearchService extends HALEndpointService implements OnDestroy {
|
||||
}
|
||||
|
||||
search(query: string, scopeId?: string, searchOptions?: SearchOptions): Observable<RemoteData<Array<SearchResult<DSpaceObject>> | PaginatedList<SearchResult<DSpaceObject>>>> {
|
||||
const requestObs = this.getEndpoint().pipe(
|
||||
const requestObs = this.halService.getEndpoint(this.searchLinkPath).pipe(
|
||||
map((url: string) => {
|
||||
const args: string[] = [];
|
||||
|
||||
@@ -219,35 +221,92 @@ export class SearchService extends HALEndpointService implements OnDestroy {
|
||||
));
|
||||
}
|
||||
|
||||
getFacetValuesFor(searchFilterConfigName: string): Observable<RemoteData<FacetValue[]>> {
|
||||
const filterConfig = this.config.find((config: SearchFilterConfig) => config.name === searchFilterConfigName);
|
||||
return this.routeService.getQueryParameterValues(filterConfig.paramName).map((selectedValues: string[]) => {
|
||||
const payload: FacetValue[] = [];
|
||||
const totalFilters = 13;
|
||||
for (let i = 0; i < totalFilters; i++) {
|
||||
const value = searchFilterConfigName + ' ' + (i + 1);
|
||||
if (!selectedValues.includes(value)) {
|
||||
payload.push({
|
||||
value: value,
|
||||
count: Math.floor(Math.random() * 20) + 20 * (totalFilters - i), // make sure first results have the highest (random) count
|
||||
search: (decodeURI(this.router.url) + (this.router.url.includes('?') ? '&' : '?') + filterConfig.paramName + '=' + value)
|
||||
getFacetValuesFor(searchFilterConfigName: string, query: string, scopeId: string): Observable<RemoteData<FacetValue[] | PaginatedList<FacetValue>>> {
|
||||
const requestObs = this.halService.getEndpoint(this.facetLinkPath).pipe(
|
||||
map((url: string) => {
|
||||
const args: string[] = [];
|
||||
|
||||
if (isNotEmpty(query)) {
|
||||
args.push(`query=${query}`);
|
||||
}
|
||||
|
||||
if (isNotEmpty(scopeId)) {
|
||||
args.push(`scope=${scopeId}`);
|
||||
}
|
||||
|
||||
if (isNotEmpty(args)) {
|
||||
url = new URLCombiner(url, `?${args.join('&')}`).toString();
|
||||
}
|
||||
|
||||
const request = new GetRequest(this.requestService.generateRequestId(), url);
|
||||
return Object.assign(request, {
|
||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
||||
return FacetResponseParsingService;
|
||||
}
|
||||
});
|
||||
}),
|
||||
tap((request: RestRequest) => this.requestService.configure(request)),
|
||||
);
|
||||
|
||||
const requestEntryObs = requestObs.pipe(
|
||||
flatMap((request: RestRequest) => this.requestService.getByHref(request.href))
|
||||
);
|
||||
|
||||
const responseCacheObs = requestObs.pipe(
|
||||
flatMap((request: RestRequest) => this.responseCache.get(request.href))
|
||||
);
|
||||
|
||||
// get search results from response cache
|
||||
const facetValueResponseObs: Observable<FacetValueSuccessResponse> = responseCacheObs.pipe(
|
||||
map((entry: ResponseCacheEntry) => entry.response),
|
||||
map((response: FacetValueMapSuccessResponse) => response.results[searchFilterConfigName])
|
||||
);
|
||||
|
||||
// get search results from response cache
|
||||
const facetValueObs: Observable<FacetValue[]> = facetValueResponseObs.pipe(
|
||||
map((response: FacetValueSuccessResponse) => response.results)
|
||||
);
|
||||
|
||||
const pageInfoObs: Observable<PageInfo> = facetValueResponseObs.pipe(
|
||||
map((response: FacetValueSuccessResponse) => { console.log(response); return response.pageInfo})
|
||||
);
|
||||
const payloadObs = Observable.combineLatest(facetValueObs, pageInfoObs, (facetValue, pageInfo) => {
|
||||
if (hasValue(pageInfo)) {
|
||||
return new PaginatedList(pageInfo, facetValue);
|
||||
} else {
|
||||
return facetValue;
|
||||
}
|
||||
}
|
||||
const requestPending = false;
|
||||
const responsePending = false;
|
||||
const isSuccessful = true;
|
||||
const error = undefined;
|
||||
return new RemoteData(
|
||||
requestPending,
|
||||
responsePending,
|
||||
isSuccessful,
|
||||
error,
|
||||
payload
|
||||
)
|
||||
}
|
||||
)
|
||||
});
|
||||
return this.rdb.toRemoteDataObservable(requestEntryObs, responseCacheObs, payloadObs);
|
||||
|
||||
// const filterConfig = this.config.find((config: SearchFilterConfig) => config.name === searchFilterConfigName);
|
||||
// return this.routeService.getQueryParameterValues(filterConfig.paramName).map((selectedValues: string[]) => {
|
||||
// const payload: FacetValue[] = [];
|
||||
// const totalFilters = 13;
|
||||
// for (let i = 0; i < totalFilters; i++) {
|
||||
// const value = searchFilterConfigName + ' ' + (i + 1);
|
||||
// if (!selectedValues.includes(value)) {
|
||||
// payload.push({
|
||||
// value: value,
|
||||
// count: Math.floor(Math.random() * 20) + 20 * (totalFilters - i), // make sure first results have the highest (random) count
|
||||
// search: (decodeURI(this.router.url) + (this.router.url.includes('?') ? '&' : '?') + filterConfig.paramName + '=' + value)
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// const requestPending = false;
|
||||
// const responsePending = false;
|
||||
// const isSuccessful = true;
|
||||
// const error = undefined;
|
||||
// return new RemoteData(
|
||||
// requestPending,
|
||||
// responsePending,
|
||||
// isSuccessful,
|
||||
// error,
|
||||
// payload
|
||||
// )
|
||||
// }
|
||||
// )
|
||||
}
|
||||
|
||||
getViewMode(): Observable<ViewMode> {
|
||||
|
@@ -12,7 +12,7 @@ import { BrowseDefinition } from '../shared/browse-definition.model';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
|
||||
@Injectable()
|
||||
export class BrowseService extends HALEndpointService {
|
||||
export class BrowseService {
|
||||
protected linkPath = 'browses';
|
||||
|
||||
private static toSearchKeyArray(metadatumKey: string): string[] {
|
||||
@@ -31,13 +31,12 @@ export class BrowseService extends HALEndpointService {
|
||||
constructor(
|
||||
protected responseCache: ResponseCacheService,
|
||||
protected requestService: RequestService,
|
||||
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig) {
|
||||
super();
|
||||
protected halService: HALEndpointService) {
|
||||
}
|
||||
|
||||
getBrowseURLFor(metadatumKey: string, linkPath: string): Observable<string> {
|
||||
const searchKeyArray = BrowseService.toSearchKeyArray(metadatumKey);
|
||||
return this.getEndpoint()
|
||||
return this.halService.getEndpoint(linkPath)
|
||||
.filter((href: string) => isNotEmpty(href))
|
||||
.distinctUntilChanged()
|
||||
.map((endpointURL: string) => new BrowseEndpointRequest(this.requestService.generateRequestId(), endpointURL))
|
||||
|
23
src/app/core/cache/response-cache.models.ts
vendored
23
src/app/core/cache/response-cache.models.ts
vendored
@@ -3,6 +3,7 @@ import { RequestError } from '../data/request.models';
|
||||
import { PageInfo } from '../shared/page-info.model';
|
||||
import { BrowseDefinition } from '../shared/browse-definition.model';
|
||||
import { ConfigObject } from '../shared/config/config.model';
|
||||
import { FacetValue } from '../../+search-page/search-service/facet-value.model';
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
export class RestResponse {
|
||||
@@ -32,6 +33,28 @@ export class SearchSuccessResponse extends RestResponse {
|
||||
}
|
||||
}
|
||||
|
||||
export class FacetValueMap {
|
||||
[name: string]: FacetValueSuccessResponse
|
||||
}
|
||||
|
||||
export class FacetValueSuccessResponse extends RestResponse {
|
||||
constructor(
|
||||
public results: FacetValue[],
|
||||
public statusCode: string,
|
||||
public pageInfo?: PageInfo) {
|
||||
super(true, statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
export class FacetValueMapSuccessResponse extends RestResponse {
|
||||
constructor(
|
||||
public results: FacetValueMap,
|
||||
public statusCode: string,
|
||||
) {
|
||||
super(true, statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
export class EndpointMap {
|
||||
[linkPath: string]: string
|
||||
}
|
||||
|
@@ -1,10 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { RequestService } from '../data/request.service';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
import { GlobalConfig } from '../../../config/global-config.interface';
|
||||
import { ConfigSuccessResponse, ErrorResponse, RestResponse } from '../cache/response-cache.models';
|
||||
import { ConfigRequest, FindAllOptions, RestRequest } from '../data/request.models';
|
||||
import { ResponseCacheEntry } from '../cache/response-cache.reducer';
|
||||
@@ -12,13 +9,13 @@ import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
import { ConfigData } from './config-data';
|
||||
|
||||
export abstract class ConfigService extends HALEndpointService {
|
||||
export abstract class ConfigService {
|
||||
protected request: ConfigRequest;
|
||||
protected abstract responseCache: ResponseCacheService;
|
||||
protected abstract requestService: RequestService;
|
||||
protected abstract linkPath: string;
|
||||
protected abstract EnvConfig: GlobalConfig;
|
||||
protected abstract browseEndpoint: string;
|
||||
protected abstract halService: HALEndpointService;
|
||||
|
||||
protected getConfig(request: RestRequest): Observable<ConfigData> {
|
||||
const [successResponse, errorResponse] = this.responseCache.get(request.href)
|
||||
@@ -68,7 +65,7 @@ export abstract class ConfigService extends HALEndpointService {
|
||||
}
|
||||
|
||||
public getConfigAll(): Observable<ConfigData> {
|
||||
return this.getEndpoint()
|
||||
return this.halService.getEndpoint(this.linkPath)
|
||||
.filter((href: string) => isNotEmpty(href))
|
||||
.distinctUntilChanged()
|
||||
.map((endpointURL: string) => new ConfigRequest(this.requestService.generateRequestId(), endpointURL))
|
||||
@@ -85,7 +82,7 @@ export abstract class ConfigService extends HALEndpointService {
|
||||
}
|
||||
|
||||
public getConfigByName(name: string): Observable<ConfigData> {
|
||||
return this.getEndpoint()
|
||||
return this.halService.getEndpoint(this.linkPath)
|
||||
.map((endpoint: string) => this.getConfigByNameHref(endpoint, name))
|
||||
.filter((href: string) => isNotEmpty(href))
|
||||
.distinctUntilChanged()
|
||||
@@ -96,7 +93,7 @@ export abstract class ConfigService extends HALEndpointService {
|
||||
}
|
||||
|
||||
public getConfigBySearch(options: FindAllOptions = {}): Observable<ConfigData> {
|
||||
return this.getEndpoint()
|
||||
return this.halService.getEndpoint(this.linkPath)
|
||||
.map((endpoint: string) => this.getConfigSearchHref(endpoint, options))
|
||||
.filter((href: string) => isNotEmpty(href))
|
||||
.distinctUntilChanged()
|
||||
|
@@ -1,10 +1,9 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { ConfigService } from './config.service';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
import { RequestService } from '../data/request.service';
|
||||
import { GLOBAL_CONFIG } from '../../../config';
|
||||
import { GlobalConfig } from '../../../config/global-config.interface';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
|
||||
@Injectable()
|
||||
export class SubmissionDefinitionsConfigService extends ConfigService {
|
||||
@@ -14,7 +13,7 @@ export class SubmissionDefinitionsConfigService extends ConfigService {
|
||||
constructor(
|
||||
protected responseCache: ResponseCacheService,
|
||||
protected requestService: RequestService,
|
||||
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig) {
|
||||
protected halService: HALEndpointService) {
|
||||
super();
|
||||
}
|
||||
|
||||
|
@@ -1,10 +1,9 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { ConfigService } from './config.service';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
import { RequestService } from '../data/request.service';
|
||||
import { GLOBAL_CONFIG } from '../../../config';
|
||||
import { GlobalConfig } from '../../../config/global-config.interface';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
|
||||
@Injectable()
|
||||
export class SubmissionFormsConfigService extends ConfigService {
|
||||
@@ -14,7 +13,7 @@ export class SubmissionFormsConfigService extends ConfigService {
|
||||
constructor(
|
||||
protected responseCache: ResponseCacheService,
|
||||
protected requestService: RequestService,
|
||||
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig) {
|
||||
protected halService: HALEndpointService) {
|
||||
super();
|
||||
}
|
||||
|
||||
|
@@ -1,10 +1,9 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { ConfigService } from './config.service';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
import { RequestService } from '../data/request.service';
|
||||
import { GLOBAL_CONFIG } from '../../../config';
|
||||
import { GlobalConfig } from '../../../config/global-config.interface';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
|
||||
@Injectable()
|
||||
export class SubmissionSectionsConfigService extends ConfigService {
|
||||
@@ -14,7 +13,7 @@ export class SubmissionSectionsConfigService extends ConfigService {
|
||||
constructor(
|
||||
protected responseCache: ResponseCacheService,
|
||||
protected requestService: RequestService,
|
||||
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig) {
|
||||
protected halService: HALEndpointService) {
|
||||
super();
|
||||
}
|
||||
|
||||
|
@@ -40,6 +40,8 @@ import { SubmissionDefinitionsConfigService } from './config/submission-definiti
|
||||
import { SubmissionFormsConfigService } from './config/submission-forms-config.service';
|
||||
import { SubmissionSectionsConfigService } from './config/submission-sections-config.service';
|
||||
import { UUIDService } from './shared/uuid.service';
|
||||
import { HALEndpointService } from './shared/hal-endpoint.service';
|
||||
import { FacetResponseParsingService } from './data/facet-response-parsing.service';
|
||||
|
||||
const IMPORTS = [
|
||||
CommonModule,
|
||||
@@ -61,6 +63,7 @@ const PROVIDERS = [
|
||||
CollectionDataService,
|
||||
DSOResponseParsingService,
|
||||
DSpaceRESTv2Service,
|
||||
HALEndpointService,
|
||||
HostWindowService,
|
||||
ItemDataService,
|
||||
MetadataService,
|
||||
@@ -70,6 +73,7 @@ const PROVIDERS = [
|
||||
RequestService,
|
||||
ResponseCacheService,
|
||||
EndpointMapResponseParsingService,
|
||||
FacetResponseParsingService,
|
||||
DebugResponseParsingService,
|
||||
SearchResponseParsingService,
|
||||
ServerResponseService,
|
||||
|
@@ -10,6 +10,7 @@ import { Collection } from '../shared/collection.model';
|
||||
import { ComColDataService } from './comcol-data.service';
|
||||
import { CommunityDataService } from './community-data.service';
|
||||
import { RequestService } from './request.service';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
|
||||
@Injectable()
|
||||
export class CollectionDataService extends ComColDataService<NormalizedCollection, Collection> {
|
||||
@@ -20,9 +21,9 @@ export class CollectionDataService extends ComColDataService<NormalizedCollectio
|
||||
protected requestService: RequestService,
|
||||
protected rdbService: RemoteDataBuildService,
|
||||
protected store: Store<CoreState>,
|
||||
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
||||
protected cds: CommunityDataService,
|
||||
protected objectCache: ObjectCacheService
|
||||
protected objectCache: ObjectCacheService,
|
||||
protected halService: HALEndpointService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
@@ -10,10 +10,12 @@ import { CommunityDataService } from './community-data.service';
|
||||
import { DataService } from './data.service';
|
||||
import { FindByIDRequest } from './request.models';
|
||||
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
|
||||
export abstract class ComColDataService<TNormalized extends NormalizedObject, TDomain> extends DataService<TNormalized, TDomain> {
|
||||
protected abstract cds: CommunityDataService;
|
||||
protected abstract objectCache: ObjectCacheService;
|
||||
protected abstract halService: HALEndpointService;
|
||||
|
||||
/**
|
||||
* Get the scoped endpoint URL by fetching the object with
|
||||
@@ -27,7 +29,7 @@ export abstract class ComColDataService<TNormalized extends NormalizedObject, TD
|
||||
*/
|
||||
public getScopedEndpoint(scopeID: string): Observable<string> {
|
||||
if (isEmpty(scopeID)) {
|
||||
return this.getEndpoint();
|
||||
return this.halService.getEndpoint(this.linkPath);
|
||||
} else {
|
||||
const scopeCommunityHrefObs = this.cds.getEndpoint()
|
||||
.flatMap((endpoint: string) => this.cds.getFindByIDHref(endpoint, scopeID))
|
||||
|
@@ -10,6 +10,7 @@ import { CoreState } from '../core.reducers';
|
||||
import { Community } from '../shared/community.model';
|
||||
import { ComColDataService } from './comcol-data.service';
|
||||
import { RequestService } from './request.service';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
|
||||
@Injectable()
|
||||
export class CommunityDataService extends ComColDataService<NormalizedCommunity, Community> {
|
||||
@@ -21,9 +22,13 @@ export class CommunityDataService extends ComColDataService<NormalizedCommunity,
|
||||
protected requestService: RequestService,
|
||||
protected rdbService: RemoteDataBuildService,
|
||||
protected store: Store<CoreState>,
|
||||
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
||||
protected objectCache: ObjectCacheService
|
||||
protected objectCache: ObjectCacheService,
|
||||
protected halService: HALEndpointService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
getEndpoint() {
|
||||
return this.halService.getEndpoint(this.linkPath);
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,9 @@
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { GlobalConfig } from '../../../config';
|
||||
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { GenericConstructor } from '../shared/generic-constructor';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
import { URLCombiner } from '../url-combiner/url-combiner';
|
||||
import { PaginatedList } from './paginated-list';
|
||||
@@ -14,13 +12,13 @@ import { FindAllOptions, FindAllRequest, FindByIDRequest, GetRequest } from './r
|
||||
import { RequestService } from './request.service';
|
||||
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
||||
|
||||
export abstract class DataService<TNormalized extends NormalizedObject, TDomain> extends HALEndpointService {
|
||||
export abstract class DataService<TNormalized extends NormalizedObject, TDomain> {
|
||||
protected abstract responseCache: ResponseCacheService;
|
||||
protected abstract requestService: RequestService;
|
||||
protected abstract rdbService: RemoteDataBuildService;
|
||||
protected abstract store: Store<CoreState>;
|
||||
protected abstract linkPath: string;
|
||||
protected abstract EnvConfig: GlobalConfig;
|
||||
protected abstract halService: HALEndpointService;
|
||||
|
||||
public abstract getScopedEndpoint(scope: string): Observable<string>
|
||||
|
||||
@@ -55,7 +53,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain>
|
||||
}
|
||||
|
||||
findAll(options: FindAllOptions = {}): Observable<RemoteData<PaginatedList<TDomain>>> {
|
||||
const hrefObs = this.getEndpoint().filter((href: string) => isNotEmpty(href))
|
||||
const hrefObs = this.halService.getEndpoint(this.linkPath).filter((href: string) => isNotEmpty(href))
|
||||
.flatMap((endpoint: string) => this.getFindAllHref(endpoint, options));
|
||||
|
||||
hrefObs
|
||||
@@ -74,7 +72,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain>
|
||||
}
|
||||
|
||||
findById(id: string): Observable<RemoteData<TDomain>> {
|
||||
const hrefObs = this.getEndpoint()
|
||||
const hrefObs = this.halService.getEndpoint(this.linkPath)
|
||||
.map((endpoint: string) => this.getFindByIDHref(endpoint, id));
|
||||
|
||||
hrefObs
|
||||
|
41
src/app/core/data/facet-response-parsing.service.ts
Normal file
41
src/app/core/data/facet-response-parsing.service.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
FacetValueMap,
|
||||
FacetValueMapSuccessResponse,
|
||||
FacetValueSuccessResponse,
|
||||
RestResponse
|
||||
} from '../cache/response-cache.models';
|
||||
import { ResponseParsingService } from './parsing.service';
|
||||
import { RestRequest } from './request.models';
|
||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
||||
import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer';
|
||||
import { PageInfo } from '../shared/page-info.model';
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
import { FacetValue } from '../../+search-page/search-service/facet-value.model';
|
||||
|
||||
@Injectable()
|
||||
export class FacetResponseParsingService implements ResponseParsingService {
|
||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
||||
|
||||
const payload = data.payload;
|
||||
const facetMap: FacetValueMap = new FacetValueMap();
|
||||
|
||||
const serializer = new DSpaceRESTv2Serializer(FacetValue);
|
||||
payload._embedded.facets.map((facet) => {
|
||||
const values = facet._embedded.values.map((value) => {value.search = value._links.search.href; return value;});
|
||||
const facetValues = serializer.deserializeArray(values);
|
||||
const valuesResponse = new FacetValueSuccessResponse(facetValues, data.statusCode, this.processPageInfo(data.payload.page));
|
||||
facetMap[facet.name] = valuesResponse;
|
||||
});
|
||||
|
||||
return new FacetValueMapSuccessResponse(facetMap, data.statusCode);
|
||||
}
|
||||
|
||||
protected processPageInfo(pageObj: any): PageInfo {
|
||||
if (isNotEmpty(pageObj)) {
|
||||
return new DSpaceRESTv2Serializer(PageInfo).deserialize(pageObj);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
@@ -14,6 +14,7 @@ import { URLCombiner } from '../url-combiner/url-combiner';
|
||||
|
||||
import { DataService } from './data.service';
|
||||
import { RequestService } from './request.service';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
|
||||
@Injectable()
|
||||
export class ItemDataService extends DataService<NormalizedItem, Item> {
|
||||
@@ -24,15 +25,14 @@ export class ItemDataService extends DataService<NormalizedItem, Item> {
|
||||
protected requestService: RequestService,
|
||||
protected rdbService: RemoteDataBuildService,
|
||||
protected store: Store<CoreState>,
|
||||
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
||||
private bs: BrowseService
|
||||
) {
|
||||
private bs: BrowseService,
|
||||
protected halService: HALEndpointService) {
|
||||
super();
|
||||
}
|
||||
|
||||
public getScopedEndpoint(scopeID: string): Observable<string> {
|
||||
if (isEmpty(scopeID)) {
|
||||
return this.getEndpoint();
|
||||
return this.halService.getEndpoint(this.linkPath);
|
||||
} else {
|
||||
return this.bs.getBrowseURLFor('dc.date.issued', this.linkPath)
|
||||
.filter((href: string) => isNotEmpty(href))
|
||||
|
@@ -8,13 +8,19 @@ import { EndpointMapRequest } from '../data/request.models';
|
||||
import { ResponseCacheEntry } from '../cache/response-cache.reducer';
|
||||
import { isEmpty, isNotEmpty } from '../../shared/empty.util';
|
||||
import { RESTURLCombiner } from '../url-combiner/rest-url-combiner';
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { GLOBAL_CONFIG } from '../../../config';
|
||||
|
||||
export abstract class HALEndpointService {
|
||||
protected abstract responseCache: ResponseCacheService;
|
||||
protected abstract requestService: RequestService;
|
||||
protected abstract linkPath: string;
|
||||
protected abstract EnvConfig: GlobalConfig;
|
||||
@Injectable()
|
||||
export class HALEndpointService {
|
||||
|
||||
protected linkPath: string;
|
||||
|
||||
constructor(private responseCache: ResponseCacheService,
|
||||
private requestService: RequestService,
|
||||
@Inject(GLOBAL_CONFIG) private EnvConfig: GlobalConfig) {
|
||||
|
||||
}
|
||||
protected getRootHref(): string {
|
||||
return new RESTURLCombiner(this.EnvConfig, '/').toString();
|
||||
}
|
||||
@@ -33,8 +39,8 @@ export abstract class HALEndpointService {
|
||||
.distinctUntilChanged();
|
||||
}
|
||||
|
||||
public getEndpoint(): Observable<string> {
|
||||
return this.getEndpointAt(...this.linkPath.split('/'));
|
||||
public getEndpoint(linkPath: string): Observable<string> {
|
||||
return this.getEndpointAt(...linkPath.split('/'));
|
||||
}
|
||||
|
||||
private getEndpointAt(...path: string[]): Observable<string> {
|
||||
@@ -50,10 +56,10 @@ export abstract class HALEndpointService {
|
||||
return Observable.of(this.getRootHref()).pipe(...pipeArguments, distinctUntilChanged());
|
||||
}
|
||||
|
||||
public isEnabledOnRestApi(): Observable<boolean> {
|
||||
public isEnabledOnRestApi(linkPath: string): Observable<boolean> {
|
||||
return this.getRootEndpointMap().pipe(
|
||||
// TODO this only works when there's no / in linkPath
|
||||
map((endpointMap: EndpointMap) => isNotEmpty(endpointMap[this.linkPath])),
|
||||
map((endpointMap: EndpointMap) => isNotEmpty(endpointMap[linkPath])),
|
||||
startWith(undefined),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
|
Reference in New Issue
Block a user