mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-14 13:33:03 +00:00
Merge pull request #407 from atmire/Fixed-filtered-search-page
Fixed filtered search page
This commit is contained in:
@@ -18,9 +18,6 @@ cache:
|
|||||||
|
|
||||||
bundler_args: --retry 5
|
bundler_args: --retry 5
|
||||||
|
|
||||||
before_install:
|
|
||||||
- travis_retry yarn run global
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- travis_retry yarn install
|
- travis_retry yarn install
|
||||||
|
|
||||||
|
@@ -597,6 +597,18 @@
|
|||||||
"objectpeople": {
|
"objectpeople": {
|
||||||
"placeholder": "People",
|
"placeholder": "People",
|
||||||
"head": "People"
|
"head": "People"
|
||||||
|
},
|
||||||
|
"jobTitle": {
|
||||||
|
"placeholder": "Job Title",
|
||||||
|
"head": "Job Title"
|
||||||
|
},
|
||||||
|
"knowsLanguage": {
|
||||||
|
"placeholder": "Known language",
|
||||||
|
"head": "Known language"
|
||||||
|
},
|
||||||
|
"birthDate": {
|
||||||
|
"placeholder": "Birth Date",
|
||||||
|
"head": "Birth Date"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,20 +18,4 @@ describe('FilteredSearchPageComponent', () => {
|
|||||||
searchConfigService = (comp as any).searchConfigService;
|
searchConfigService = (comp as any).searchConfigService;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when fixedFilterQuery is defined', () => {
|
|
||||||
const fixedFilterQuery = 'fixedFilterQuery';
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
spyOn(searchConfigService, 'updateFixedFilter').and.callThrough();
|
|
||||||
comp.fixedFilterQuery = fixedFilterQuery;
|
|
||||||
comp.ngOnInit();
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update the paginated search options', () => {
|
|
||||||
expect(searchConfigService.updateFixedFilter).toHaveBeenCalledWith(fixedFilterQuery);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -2,20 +2,22 @@ import { HostWindowService } from '../shared/host-window.service';
|
|||||||
import { SearchService } from './search-service/search.service';
|
import { SearchService } from './search-service/search.service';
|
||||||
import { SearchSidebarService } from './search-sidebar/search-sidebar.service';
|
import { SearchSidebarService } from './search-sidebar/search-sidebar.service';
|
||||||
import { SearchPageComponent } from './search-page.component';
|
import { SearchPageComponent } from './search-page.component';
|
||||||
import { ChangeDetectionStrategy, Component, Inject, Input } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, Inject, Input, OnInit } from '@angular/core';
|
||||||
import { pushInOut } from '../shared/animations/push';
|
import { pushInOut } from '../shared/animations/push';
|
||||||
import { RouteService } from '../shared/services/route.service';
|
import { RouteService } from '../shared/services/route.service';
|
||||||
import { SearchConfigurationService } from './search-service/search-configuration.service';
|
import { SearchConfigurationService } from './search-service/search-configuration.service';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { PaginatedSearchOptions } from './paginated-search-options.model';
|
import { PaginatedSearchOptions } from './paginated-search-options.model';
|
||||||
import { SEARCH_CONFIG_SERVICE } from '../+my-dspace-page/my-dspace-page.component';
|
import { SEARCH_CONFIG_SERVICE } from '../+my-dspace-page/my-dspace-page.component';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component renders a simple item page.
|
* This component renders a simple item page.
|
||||||
* The route parameter 'id' is used to request the item it represents.
|
* The route parameter 'id' is used to request the item it represents.
|
||||||
* All fields of the item that should be displayed, are defined in its template.
|
* All fields of the item that should be displayed, are defined in its template.
|
||||||
*/
|
*/
|
||||||
@Component({selector: 'ds-filtered-search-page',
|
@Component({
|
||||||
|
selector: 'ds-filtered-search-page',
|
||||||
styleUrls: ['./search-page.component.scss'],
|
styleUrls: ['./search-page.component.scss'],
|
||||||
templateUrl: './search-page.component.html',
|
templateUrl: './search-page.component.html',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
@@ -28,8 +30,7 @@ import { SEARCH_CONFIG_SERVICE } from '../+my-dspace-page/my-dspace-page.compone
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
export class FilteredSearchPageComponent extends SearchPageComponent {
|
export class FilteredSearchPageComponent extends SearchPageComponent implements OnInit {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual query for the fixed filter.
|
* The actual query for the fixed filter.
|
||||||
* If empty, the query will be determined by the route parameter called 'filter'
|
* If empty, the query will be determined by the route parameter called 'filter'
|
||||||
@@ -44,6 +45,17 @@ export class FilteredSearchPageComponent extends SearchPageComponent {
|
|||||||
super(service, sidebarService, windowService, searchConfigService, routeService);
|
super(service, sidebarService, windowService, searchConfigService, routeService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listening to changes in the paginated search options
|
||||||
|
* If something changes, update the search results
|
||||||
|
*
|
||||||
|
* Listen to changes in the scope
|
||||||
|
* If something changes, update the list of scopes for the dropdown
|
||||||
|
*/
|
||||||
|
ngOnInit(): void {
|
||||||
|
super.ngOnInit();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current paginated search options after updating the fixed filter using the fixedFilterQuery input
|
* Get the current paginated search options after updating the fixed filter using the fixedFilterQuery input
|
||||||
* This is to make sure the fixed filter is included in the paginated search options, as it is not part of any
|
* This is to make sure the fixed filter is included in the paginated search options, as it is not part of any
|
||||||
@@ -51,8 +63,11 @@ export class FilteredSearchPageComponent extends SearchPageComponent {
|
|||||||
* @returns {Observable<PaginatedSearchOptions>}
|
* @returns {Observable<PaginatedSearchOptions>}
|
||||||
*/
|
*/
|
||||||
protected getSearchOptions(): Observable<PaginatedSearchOptions> {
|
protected getSearchOptions(): Observable<PaginatedSearchOptions> {
|
||||||
this.searchConfigService.updateFixedFilter(this.fixedFilterQuery);
|
return this.searchConfigService.paginatedSearchOptions.pipe(
|
||||||
return this.searchConfigService.paginatedSearchOptions;
|
map((options: PaginatedSearchOptions) => {
|
||||||
|
const filter = this.fixedFilterQuery || options.fixedFilter;
|
||||||
|
return Object.assign(options, { fixedFilter: filter });
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,7 @@ describe('SearchFixedFilterService', () => {
|
|||||||
configure: () => {},
|
configure: () => {},
|
||||||
/* tslint:enable:no-empty */
|
/* tslint:enable:no-empty */
|
||||||
generateRequestId: () => 'fake-id',
|
generateRequestId: () => 'fake-id',
|
||||||
getByUUID: () => observableOf(Object.assign(new RequestEntry(), {
|
getByHref: () => observableOf(Object.assign(new RequestEntry(), {
|
||||||
response: new FilteredDiscoveryQueryResponse(filterQuery, 200, 'OK')
|
response: new FilteredDiscoveryQueryResponse(filterQuery, 200, 'OK')
|
||||||
}))
|
}))
|
||||||
}) as RequestService;
|
}) as RequestService;
|
||||||
@@ -56,5 +56,4 @@ describe('SearchFixedFilterService', () => {
|
|||||||
expect(query).toContain(itemUUID);
|
expect(query).toContain(itemUUID);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { flatMap, map } from 'rxjs/operators';
|
import { flatMap, map, switchMap, tap } from 'rxjs/operators';
|
||||||
import { Observable , of as observableOf } from 'rxjs';
|
import { Observable, of as observableOf } from 'rxjs';
|
||||||
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
|
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
|
||||||
import { GetRequest, RestRequest } from '../../../core/data/request.models';
|
import { GetRequest, RestRequest } from '../../../core/data/request.models';
|
||||||
import { RequestService } from '../../../core/data/request.service';
|
import { RequestService } from '../../../core/data/request.service';
|
||||||
@@ -33,7 +33,7 @@ export class SearchFixedFilterService {
|
|||||||
getQueryByFilterName(filterName: string): Observable<string> {
|
getQueryByFilterName(filterName: string): Observable<string> {
|
||||||
if (hasValue(filterName)) {
|
if (hasValue(filterName)) {
|
||||||
const requestUuid = this.requestService.generateRequestId();
|
const requestUuid = this.requestService.generateRequestId();
|
||||||
this.halService.getEndpoint(this.queryByFilterPath).pipe(
|
const requestObs = this.halService.getEndpoint(this.queryByFilterPath).pipe(
|
||||||
map((url: string) => {
|
map((url: string) => {
|
||||||
url += ('/' + filterName);
|
url += ('/' + filterName);
|
||||||
const request = new GetRequest(requestUuid, url);
|
const request = new GetRequest(requestUuid, url);
|
||||||
@@ -44,10 +44,12 @@ export class SearchFixedFilterService {
|
|||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
configureRequest(this.requestService)
|
configureRequest(this.requestService)
|
||||||
).subscribe();
|
);
|
||||||
|
|
||||||
// get search results from response cache
|
const requestEntryObs = requestObs.pipe(
|
||||||
const filterQuery: Observable<string> = this.requestService.getByUUID(requestUuid).pipe(
|
switchMap((request: RestRequest) => this.requestService.getByHref(request.href)),
|
||||||
|
);
|
||||||
|
const filterQuery = requestEntryObs.pipe(
|
||||||
getResponseFromEntry(),
|
getResponseFromEntry(),
|
||||||
map((response: FilteredDiscoveryQueryResponse) =>
|
map((response: FilteredDiscoveryQueryResponse) =>
|
||||||
response.filterQuery
|
response.filterQuery
|
||||||
@@ -75,5 +77,4 @@ export class SearchFixedFilterService {
|
|||||||
getFilterByRelation(relationType: string, itemUUID: string): string {
|
getFilterByRelation(relationType: string, itemUUID: string): string {
|
||||||
return `f.${relationType}=${itemUUID}`;
|
return `f.${relationType}=${itemUUID}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
<div class="search-page row">
|
<div class="search-page row">
|
||||||
<ds-search-sidebar *ngIf="!(isXsOrSm$ | async)" class="col-{{sideBarWidth}} sidebar-md-sticky"
|
<ds-search-sidebar *ngIf="!(isXsOrSm$ | async)" class="col-{{sideBarWidth}} sidebar-md-sticky"
|
||||||
id="search-sidebar"
|
id="search-sidebar"
|
||||||
[resultCount]="(resultsRD$ | async)?.payload.totalElements" [inPlaceSearch]="inPlaceSearch"></ds-search-sidebar>
|
[resultCount]="(resultsRD$ | async)?.payload?.totalElements" [inPlaceSearch]="inPlaceSearch"></ds-search-sidebar>
|
||||||
<div class="col-12 col-md-{{12 - sideBarWidth}}">
|
<div class="col-12 col-md-{{12 - sideBarWidth}}">
|
||||||
<ds-search-form *ngIf="searchEnabled" id="search-form"
|
<ds-search-form *ngIf="searchEnabled" id="search-form"
|
||||||
[query]="(searchOptions$ | async)?.query"
|
[query]="(searchOptions$ | async)?.query"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { ChangeDetectionStrategy, Component, Inject, Input, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, Inject, Input, OnInit } from '@angular/core';
|
||||||
import { Observable , Subscription , BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject, Observable, of as observableOf, Subscription } from 'rxjs';
|
||||||
import { switchMap, } from 'rxjs/operators';
|
import { startWith, switchMap, } from 'rxjs/operators';
|
||||||
import { PaginatedList } from '../core/data/paginated-list';
|
import { PaginatedList } from '../core/data/paginated-list';
|
||||||
import { RemoteData } from '../core/data/remote-data';
|
import { RemoteData } from '../core/data/remote-data';
|
||||||
import { DSpaceObject } from '../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../core/shared/dspace-object.model';
|
||||||
@@ -43,7 +43,6 @@ export const SEARCH_ROUTE = '/search';
|
|||||||
* It renders search results depending on the current search options
|
* It renders search results depending on the current search options
|
||||||
*/
|
*/
|
||||||
export class SearchPageComponent implements OnInit {
|
export class SearchPageComponent implements OnInit {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current search results
|
* The current search results
|
||||||
*/
|
*/
|
||||||
@@ -110,7 +109,7 @@ export class SearchPageComponent implements OnInit {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.searchOptions$ = this.getSearchOptions();
|
this.searchOptions$ = this.getSearchOptions();
|
||||||
this.sub = this.searchOptions$.pipe(
|
this.sub = this.searchOptions$.pipe(
|
||||||
switchMap((options) => this.service.search(options).pipe(getSucceededRemoteData())))
|
switchMap((options) => this.service.search(options).pipe(getSucceededRemoteData(), startWith(observableOf(undefined)))))
|
||||||
.subscribe((results) => {
|
.subscribe((results) => {
|
||||||
this.resultsRD$.next(results);
|
this.resultsRD$.next(results);
|
||||||
});
|
});
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
[objects]="searchResults"
|
[objects]="searchResults"
|
||||||
[hideGear]="true">
|
[hideGear]="true">
|
||||||
</ds-viewable-collection></div>
|
</ds-viewable-collection></div>
|
||||||
<ds-loading *ngIf="!searchResults || searchResults?.isLoading" message="{{'loading.search-results' | translate}}"></ds-loading>
|
<ds-loading *ngIf="hasNoValue(searchResults) || hasNoValue(searchResults.payload) || searchResults.isLoading" message="{{'loading.search-results' | translate}}"></ds-loading>
|
||||||
<ds-error *ngIf="searchResults?.hasFailed && (!searchResults?.error || searchResults?.error?.statusCode != 400)" message="{{'error.search-results' | translate}}"></ds-error>
|
<ds-error *ngIf="searchResults?.hasFailed && (!searchResults?.error || searchResults?.error?.statusCode != 400)" message="{{'error.search-results' | translate}}"></ds-error>
|
||||||
<div *ngIf="searchResults?.payload?.page.length == 0 || searchResults?.error?.statusCode == 400">
|
<div *ngIf="searchResults?.payload?.page.length == 0 || searchResults?.error?.statusCode == 400">
|
||||||
{{ 'search.results.no-results' | translate }}
|
{{ 'search.results.no-results' | translate }}
|
||||||
|
@@ -6,7 +6,7 @@ import { SetViewMode } from '../../shared/view-mode';
|
|||||||
import { SearchOptions } from '../search-options.model';
|
import { SearchOptions } from '../search-options.model';
|
||||||
import { SearchResult } from '../search-result.model';
|
import { SearchResult } from '../search-result.model';
|
||||||
import { PaginatedList } from '../../core/data/paginated-list';
|
import { PaginatedList } from '../../core/data/paginated-list';
|
||||||
import { isNotEmpty } from '../../shared/empty.util';
|
import { hasNoValue, isNotEmpty } from '../../shared/empty.util';
|
||||||
import { SortOptions } from '../../core/cache/models/sort-options.model';
|
import { SortOptions } from '../../core/cache/models/sort-options.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -22,6 +22,8 @@ import { SortOptions } from '../../core/cache/models/sort-options.model';
|
|||||||
* Component that represents all results from a search
|
* Component that represents all results from a search
|
||||||
*/
|
*/
|
||||||
export class SearchResultsComponent {
|
export class SearchResultsComponent {
|
||||||
|
hasNoValue = hasNoValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual search result objects
|
* The actual search result objects
|
||||||
*/
|
*/
|
||||||
|
@@ -171,20 +171,4 @@ describe('SearchConfigurationService', () => {
|
|||||||
expect((service as any).routeService.getRouteParameterValue).toHaveBeenCalledWith('filter');
|
expect((service as any).routeService.getRouteParameterValue).toHaveBeenCalledWith('filter');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when updateFixedFilter is called', () => {
|
|
||||||
const filter = 'filter';
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
service.updateFixedFilter(filter);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update the paginated search options with the correct fixed filter', () => {
|
|
||||||
expect(service.paginatedSearchOptions.getValue().fixedFilter).toEqual(filter);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update the search options with the correct fixed filter', () => {
|
|
||||||
expect(service.searchOptions.getValue().fixedFilter).toEqual(filter);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@@ -9,7 +9,7 @@ import {
|
|||||||
of as observableOf,
|
of as observableOf,
|
||||||
Subscription
|
Subscription
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
import { filter, flatMap, map } from 'rxjs/operators';
|
import { filter, flatMap, map, switchMap, tap } from 'rxjs/operators';
|
||||||
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||||
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||||
import { SearchOptions } from '../search-options.model';
|
import { SearchOptions } from '../search-options.model';
|
||||||
@@ -44,7 +44,7 @@ export class SearchConfigurationService implements OnDestroy {
|
|||||||
/**
|
/**
|
||||||
* Default configuration parameter setting
|
* Default configuration parameter setting
|
||||||
*/
|
*/
|
||||||
protected defaultConfiguration = 'default';
|
protected defaultConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default scope setting
|
* Default scope setting
|
||||||
@@ -99,10 +99,8 @@ export class SearchConfigurationService implements OnDestroy {
|
|||||||
const defs = defRD.payload;
|
const defs = defRD.payload;
|
||||||
this.paginatedSearchOptions = new BehaviorSubject<PaginatedSearchOptions>(defs);
|
this.paginatedSearchOptions = new BehaviorSubject<PaginatedSearchOptions>(defs);
|
||||||
this.searchOptions = new BehaviorSubject<SearchOptions>(defs);
|
this.searchOptions = new BehaviorSubject<SearchOptions>(defs);
|
||||||
|
|
||||||
this.subs.push(this.subscribeToSearchOptions(defs));
|
this.subs.push(this.subscribeToSearchOptions(defs));
|
||||||
this.subs.push(this.subscribeToPaginatedSearchOptions(defs));
|
this.subs.push(this.subscribeToPaginatedSearchOptions(defs));
|
||||||
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -206,7 +204,7 @@ export class SearchConfigurationService implements OnDestroy {
|
|||||||
*/
|
*/
|
||||||
getCurrentFixedFilter(): Observable<string> {
|
getCurrentFixedFilter(): Observable<string> {
|
||||||
return this.routeService.getRouteParameterValue('filter').pipe(
|
return this.routeService.getRouteParameterValue('filter').pipe(
|
||||||
flatMap((f) => this.fixedFilterService.getQueryByFilterName(f))
|
switchMap((f) => this.fixedFilterService.getQueryByFilterName(f))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,21 +355,7 @@ export class SearchConfigurationService implements OnDestroy {
|
|||||||
isNotEmptyOperator(),
|
isNotEmptyOperator(),
|
||||||
map((fixedFilter) => {
|
map((fixedFilter) => {
|
||||||
return { fixedFilter }
|
return { fixedFilter }
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the fixed filter in paginated and non-paginated search options with a given value
|
|
||||||
* @param {string} fixedFilter
|
|
||||||
*/
|
|
||||||
public updateFixedFilter(fixedFilter: string) {
|
|
||||||
const currentPaginatedValue: PaginatedSearchOptions = this.paginatedSearchOptions.getValue();
|
|
||||||
const updatedPaginatedValue: PaginatedSearchOptions = Object.assign(currentPaginatedValue, { fixedFilter: fixedFilter });
|
|
||||||
this.paginatedSearchOptions.next(updatedPaginatedValue);
|
|
||||||
|
|
||||||
const currentValue: SearchOptions = this.searchOptions.getValue();
|
|
||||||
const updatedValue: SearchOptions = Object.assign(currentValue, { fixedFilter: fixedFilter });
|
|
||||||
this.searchOptions.next(updatedValue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
<script src="../search-switch-configuration/search-switch-configuration.component.ts"></script>
|
||||||
<ng-container *ngVar="(searchOptions$ | async) as config">
|
<ng-container *ngVar="(searchOptions$ | async) as config">
|
||||||
<h3>{{ 'search.sidebar.settings.title' | translate}}</h3>
|
<h3>{{ 'search.sidebar.settings.title' | translate}}</h3>
|
||||||
<div *ngIf="config?.sort" class="setting-option result-order-settings mb-3 p-3">
|
<div *ngIf="config?.sort" class="setting-option result-order-settings mb-3 p-3">
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
<div id="search-sidebar-content">
|
<div id="search-sidebar-content">
|
||||||
<ds-view-mode-switch [viewModeList]="viewModeList" class="d-none d-md-block"></ds-view-mode-switch>
|
<ds-view-mode-switch [viewModeList]="viewModeList" class="d-none d-md-block"></ds-view-mode-switch>
|
||||||
<div class="sidebar-content">
|
<div class="sidebar-content">
|
||||||
<ds-search-switch-configuration *ngIf="configurationList" [configurationList]="configurationList"></ds-search-switch-configuration>
|
<ds-search-switch-configuration [inPlaceSearch]="inPlaceSearch" *ngIf="configurationList" [configurationList]="configurationList"></ds-search-switch-configuration>
|
||||||
<ds-search-filters [inPlaceSearch]="inPlaceSearch"></ds-search-filters>
|
<ds-search-filters [inPlaceSearch]="inPlaceSearch"></ds-search-filters>
|
||||||
<ds-search-settings [inPlaceSearch]="inPlaceSearch"></ds-search-settings>
|
<ds-search-settings [inPlaceSearch]="inPlaceSearch"></ds-search-settings>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -94,7 +94,7 @@ describe('SearchSwitchConfigurationComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should navigate to the route when selecting an option', () => {
|
it('should navigate to the route when selecting an option', () => {
|
||||||
(comp as any).searchService.getSearchLink.and.returnValue(MYDSPACE_ROUTE);
|
spyOn((comp as any), 'getSearchLinkParts').and.returnValue([MYDSPACE_ROUTE]);
|
||||||
comp.selectedOption = MyDSpaceConfigurationValueType.Workflow;
|
comp.selectedOption = MyDSpaceConfigurationValueType.Workflow;
|
||||||
const navigationExtras: NavigationExtras = {
|
const navigationExtras: NavigationExtras = {
|
||||||
queryParams: {configuration: MyDSpaceConfigurationValueType.Workflow},
|
queryParams: {configuration: MyDSpaceConfigurationValueType.Workflow},
|
||||||
|
@@ -20,6 +20,10 @@ import { SearchService } from '../search-service/search.service';
|
|||||||
*/
|
*/
|
||||||
export class SearchSwitchConfigurationComponent implements OnDestroy, OnInit {
|
export class SearchSwitchConfigurationComponent implements OnDestroy, OnInit {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True when the search component should show results on the current page
|
||||||
|
*/
|
||||||
|
@Input() inPlaceSearch;
|
||||||
/**
|
/**
|
||||||
* The list of available configuration options
|
* The list of available configuration options
|
||||||
*/
|
*/
|
||||||
@@ -56,7 +60,7 @@ export class SearchSwitchConfigurationComponent implements OnDestroy, OnInit {
|
|||||||
queryParams: {configuration: this.selectedOption},
|
queryParams: {configuration: this.selectedOption},
|
||||||
};
|
};
|
||||||
|
|
||||||
this.router.navigate([this.searchService.getSearchLink()], navigationExtras);
|
this.router.navigate(this.getSearchLinkParts(), navigationExtras);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -77,4 +81,24 @@ export class SearchSwitchConfigurationComponent implements OnDestroy, OnInit {
|
|||||||
this.sub.unsubscribe();
|
this.sub.unsubscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string} The base path to the search page, or the current page when inPlaceSearch is true
|
||||||
|
*/
|
||||||
|
public getSearchLink(): string {
|
||||||
|
if (this.inPlaceSearch) {
|
||||||
|
return './';
|
||||||
|
}
|
||||||
|
return this.searchService.getSearchLink();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string[]} The base path to the search page, or the current page when inPlaceSearch is true, split in separate pieces
|
||||||
|
*/
|
||||||
|
public getSearchLinkParts(): string[] {
|
||||||
|
if (this.searchService) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return this.getSearchLink().split('/');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,7 +57,6 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||||||
private angulartics2GoogleAnalytics: Angulartics2GoogleAnalytics,
|
private angulartics2GoogleAnalytics: Angulartics2GoogleAnalytics,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private routeService: RouteService,
|
|
||||||
private cssService: CSSVariableService,
|
private cssService: CSSVariableService,
|
||||||
private menuService: MenuService,
|
private menuService: MenuService,
|
||||||
private windowService: HostWindowService
|
private windowService: HostWindowService
|
||||||
@@ -77,13 +76,10 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||||||
|
|
||||||
metadata.listenForRouteChange();
|
metadata.listenForRouteChange();
|
||||||
|
|
||||||
routeService.saveRouting();
|
|
||||||
|
|
||||||
if (config.debug) {
|
if (config.debug) {
|
||||||
console.info(config);
|
console.info(config);
|
||||||
}
|
}
|
||||||
this.storeCSSVariables();
|
this.storeCSSVariables();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
@@ -6,6 +6,7 @@ import { AuthEffects } from './auth/auth.effects';
|
|||||||
import { JsonPatchOperationsEffects } from './json-patch/json-patch-operations.effects';
|
import { JsonPatchOperationsEffects } from './json-patch/json-patch-operations.effects';
|
||||||
import { ServerSyncBufferEffects } from './cache/server-sync-buffer.effects';
|
import { ServerSyncBufferEffects } from './cache/server-sync-buffer.effects';
|
||||||
import { ObjectUpdatesEffects } from './data/object-updates/object-updates.effects';
|
import { ObjectUpdatesEffects } from './data/object-updates/object-updates.effects';
|
||||||
|
import { RouteEffects } from '../shared/services/route.effects';
|
||||||
|
|
||||||
export const coreEffects = [
|
export const coreEffects = [
|
||||||
RequestEffects,
|
RequestEffects,
|
||||||
@@ -14,5 +15,6 @@ export const coreEffects = [
|
|||||||
AuthEffects,
|
AuthEffects,
|
||||||
JsonPatchOperationsEffects,
|
JsonPatchOperationsEffects,
|
||||||
ServerSyncBufferEffects,
|
ServerSyncBufferEffects,
|
||||||
ObjectUpdatesEffects
|
ObjectUpdatesEffects,
|
||||||
|
RouteEffects
|
||||||
];
|
];
|
||||||
|
@@ -13,6 +13,7 @@ import {
|
|||||||
objectUpdatesReducer,
|
objectUpdatesReducer,
|
||||||
ObjectUpdatesState
|
ObjectUpdatesState
|
||||||
} from './data/object-updates/object-updates.reducer';
|
} from './data/object-updates/object-updates.reducer';
|
||||||
|
import { routeReducer, RouteState } from '../shared/services/route.reducer';
|
||||||
|
|
||||||
export interface CoreState {
|
export interface CoreState {
|
||||||
'cache/object': ObjectCacheState,
|
'cache/object': ObjectCacheState,
|
||||||
@@ -21,7 +22,8 @@ export interface CoreState {
|
|||||||
'data/request': RequestState,
|
'data/request': RequestState,
|
||||||
'index': MetaIndexState,
|
'index': MetaIndexState,
|
||||||
'auth': AuthState,
|
'auth': AuthState,
|
||||||
'json/patch': JsonPatchOperationsState
|
'json/patch': JsonPatchOperationsState,
|
||||||
|
'route': RouteState
|
||||||
}
|
}
|
||||||
|
|
||||||
export const coreReducers: ActionReducerMap<CoreState> = {
|
export const coreReducers: ActionReducerMap<CoreState> = {
|
||||||
@@ -31,5 +33,6 @@ export const coreReducers: ActionReducerMap<CoreState> = {
|
|||||||
'data/request': requestReducer,
|
'data/request': requestReducer,
|
||||||
'index': indexReducer,
|
'index': indexReducer,
|
||||||
'auth': authReducer,
|
'auth': authReducer,
|
||||||
'json/patch': jsonPatchOperationsReducer
|
'json/patch': jsonPatchOperationsReducer,
|
||||||
|
'route': routeReducer
|
||||||
};
|
};
|
||||||
|
@@ -14,7 +14,7 @@ export const IndexActionTypes = {
|
|||||||
|
|
||||||
/* tslint:disable:max-classes-per-file */
|
/* tslint:disable:max-classes-per-file */
|
||||||
/**
|
/**
|
||||||
* An ngrx action to add an value to the index
|
* An ngrx action to add a value to the index
|
||||||
*/
|
*/
|
||||||
export class AddToIndexAction implements Action {
|
export class AddToIndexAction implements Action {
|
||||||
type = IndexActionTypes.ADD;
|
type = IndexActionTypes.ADD;
|
||||||
@@ -40,7 +40,7 @@ export class AddToIndexAction implements Action {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An ngrx action to remove an value from the index
|
* An ngrx action to remove a value from the index
|
||||||
*/
|
*/
|
||||||
export class RemoveFromIndexByValueAction implements Action {
|
export class RemoveFromIndexByValueAction implements Action {
|
||||||
type = IndexActionTypes.REMOVE_BY_VALUE;
|
type = IndexActionTypes.REMOVE_BY_VALUE;
|
||||||
|
@@ -75,7 +75,6 @@ describe('ItemSearchResultListElementComponent', () => {
|
|||||||
|
|
||||||
it('should show the relationship type badge', () => {
|
it('should show the relationship type badge', () => {
|
||||||
const badge = fixture.debugElement.query(By.css('span.badge'));
|
const badge = fixture.debugElement.query(By.css('span.badge'));
|
||||||
console.log(itemSearchResultListElementComponent.dso);
|
|
||||||
expect(badge.nativeElement.textContent).toContain(type.toLowerCase());
|
expect(badge.nativeElement.textContent).toContain(type.toLowerCase());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
116
src/app/shared/services/route.actions.ts
Normal file
116
src/app/shared/services/route.actions.ts
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
import { Action } from '@ngrx/store';
|
||||||
|
import { type } from '../../shared/ngrx/type';
|
||||||
|
import { Params } from '@angular/router';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of HrefIndexAction type definitions
|
||||||
|
*/
|
||||||
|
export const RouteActionTypes = {
|
||||||
|
SET_QUERY_PARAMETERS: type('dspace/core/route/SET_QUERY_PARAMETERS'),
|
||||||
|
SET_PARAMETERS: type('dspace/core/route/SET_PARAMETERS'),
|
||||||
|
ADD_QUERY_PARAMETER: type('dspace/core/route/ADD_QUERY_PARAMETER'),
|
||||||
|
ADD_PARAMETER: type('dspace/core/route/ADD_PARAMETER'),
|
||||||
|
RESET: type('dspace/core/route/RESET'),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* tslint:disable:max-classes-per-file */
|
||||||
|
/**
|
||||||
|
* An ngrx action to set the query parameters
|
||||||
|
*/
|
||||||
|
export class SetQueryParametersAction implements Action {
|
||||||
|
type = RouteActionTypes.SET_QUERY_PARAMETERS;
|
||||||
|
payload: Params;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new SetQueryParametersAction
|
||||||
|
*
|
||||||
|
* @param parameters
|
||||||
|
* the query parameters
|
||||||
|
*/
|
||||||
|
constructor(parameters: Params) {
|
||||||
|
this.payload = parameters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ngrx action to set the parameters
|
||||||
|
*/
|
||||||
|
export class SetParametersAction implements Action {
|
||||||
|
type = RouteActionTypes.SET_PARAMETERS;
|
||||||
|
payload: Params;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new SetParametersAction
|
||||||
|
*
|
||||||
|
* @param parameters
|
||||||
|
* the parameters
|
||||||
|
*/
|
||||||
|
constructor(parameters: Params) {
|
||||||
|
this.payload = parameters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ngrx action to add a query parameter
|
||||||
|
*/
|
||||||
|
export class AddQueryParameterAction implements Action {
|
||||||
|
type = RouteActionTypes.ADD_QUERY_PARAMETER;
|
||||||
|
payload: {
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new AddQueryParameterAction
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* the key to add
|
||||||
|
* @param value
|
||||||
|
* the value of this key
|
||||||
|
*/
|
||||||
|
constructor(key: string, value: string) {
|
||||||
|
this.payload = { key, value };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ngrx action to add a parameter
|
||||||
|
*/
|
||||||
|
export class AddParameterAction implements Action {
|
||||||
|
type = RouteActionTypes.ADD_PARAMETER;
|
||||||
|
payload: {
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new AddParameterAction
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* the key to add
|
||||||
|
* @param value
|
||||||
|
* the value of this key
|
||||||
|
*/
|
||||||
|
constructor(key: string, value: string) {
|
||||||
|
this.payload = { key, value };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ngrx action to reset the route state
|
||||||
|
*/
|
||||||
|
export class ResetRouteStateAction implements Action {
|
||||||
|
type = RouteActionTypes.RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tslint:enable:max-classes-per-file */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type to encompass all RouteActions
|
||||||
|
*/
|
||||||
|
export type RouteActions =
|
||||||
|
SetQueryParametersAction
|
||||||
|
| SetParametersAction
|
||||||
|
| AddQueryParameterAction
|
||||||
|
| AddParameterAction
|
||||||
|
| ResetRouteStateAction;
|
23
src/app/shared/services/route.effects.ts
Normal file
23
src/app/shared/services/route.effects.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Actions, Effect, ofType } from '@ngrx/effects'
|
||||||
|
import * as fromRouter from '@ngrx/router-store';
|
||||||
|
import { ResetRouteStateAction } from './route.actions';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RouteEffects {
|
||||||
|
/**
|
||||||
|
* Effect that resets the route state on reroute
|
||||||
|
* @type {Observable<ResetRouteStateAction>}
|
||||||
|
*/
|
||||||
|
@Effect() routeChange$ = this.actions$
|
||||||
|
.pipe(
|
||||||
|
ofType(fromRouter.ROUTER_NAVIGATION),
|
||||||
|
map(() => new ResetRouteStateAction())
|
||||||
|
);
|
||||||
|
|
||||||
|
constructor(private actions$: Actions) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
74
src/app/shared/services/route.reducer.ts
Normal file
74
src/app/shared/services/route.reducer.ts
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import { Params } from '@angular/router';
|
||||||
|
import {
|
||||||
|
AddParameterAction,
|
||||||
|
AddQueryParameterAction,
|
||||||
|
RouteActions,
|
||||||
|
RouteActionTypes, SetParametersAction, SetQueryParametersAction
|
||||||
|
} from './route.actions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to represent the parameter state of a current route in the store
|
||||||
|
*/
|
||||||
|
export interface RouteState {
|
||||||
|
queryParams: Params;
|
||||||
|
params: Params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The initial route state
|
||||||
|
*/
|
||||||
|
const initialState: RouteState = {
|
||||||
|
queryParams: {},
|
||||||
|
params: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reducer function to save the current route parameters and query parameters in the store
|
||||||
|
* @param state The current or initial state
|
||||||
|
* @param action The action to perform on the state
|
||||||
|
*/
|
||||||
|
export function routeReducer(state = initialState, action: RouteActions): RouteState {
|
||||||
|
switch (action.type) {
|
||||||
|
case RouteActionTypes.RESET: {
|
||||||
|
return initialState
|
||||||
|
}
|
||||||
|
case RouteActionTypes.SET_PARAMETERS: {
|
||||||
|
return setParameters(state, action as SetParametersAction, 'params');
|
||||||
|
}
|
||||||
|
case RouteActionTypes.SET_QUERY_PARAMETERS: {
|
||||||
|
return setParameters(state, action as SetQueryParametersAction, 'queryParams');
|
||||||
|
}
|
||||||
|
case RouteActionTypes.ADD_PARAMETER: {
|
||||||
|
return addParameter(state, action as AddParameterAction, 'params');
|
||||||
|
}
|
||||||
|
case RouteActionTypes.ADD_QUERY_PARAMETER: {
|
||||||
|
return addParameter(state, action as AddQueryParameterAction, 'queryParams');
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a route or query parameter in the store
|
||||||
|
* @param state The current state
|
||||||
|
* @param action The add action to perform on the current state
|
||||||
|
* @param paramType The type of parameter to add: route or query parameter
|
||||||
|
*/
|
||||||
|
function addParameter(state: RouteState, action: AddParameterAction | AddQueryParameterAction, paramType: string): RouteState {
|
||||||
|
const subState = state[paramType];
|
||||||
|
const existingValues = subState[action.payload.key] || [];
|
||||||
|
const newValues = [...existingValues, action.payload.value];
|
||||||
|
const newSubstate = Object.assign(subState, { [action.payload.key]: newValues });
|
||||||
|
return Object.assign({}, state, { [paramType]: newSubstate });
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set a route or query parameter in the store
|
||||||
|
* @param state The current state
|
||||||
|
* @param action The set action to perform on the current state
|
||||||
|
* @param paramType The type of parameter to set: route or query parameter
|
||||||
|
*/
|
||||||
|
function setParameters(state: RouteState, action: SetParametersAction | SetQueryParametersAction, paramType: string): RouteState {
|
||||||
|
return Object.assign({}, state, { [paramType]: action.payload });
|
||||||
|
}
|
@@ -42,6 +42,7 @@ describe('RouteService', () => {
|
|||||||
provide: ActivatedRoute,
|
provide: ActivatedRoute,
|
||||||
useValue: {
|
useValue: {
|
||||||
queryParams: observableOf(paramObject),
|
queryParams: observableOf(paramObject),
|
||||||
|
params: observableOf(paramObject),
|
||||||
queryParamMap: observableOf(convertToParamMap(paramObject))
|
queryParamMap: observableOf(convertToParamMap(paramObject))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { distinctUntilChanged, filter, map, mergeMap } from 'rxjs/operators';
|
import { distinctUntilChanged, filter, map, tap } from 'rxjs/operators';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
ActivatedRoute,
|
ActivatedRoute,
|
||||||
@@ -8,24 +8,67 @@ import {
|
|||||||
RouterStateSnapshot,
|
RouterStateSnapshot,
|
||||||
} from '@angular/router';
|
} from '@angular/router';
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { combineLatest, Observable } from 'rxjs';
|
||||||
import { select, Store } from '@ngrx/store';
|
import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
|
|
||||||
import { AppState } from '../../app.reducer';
|
|
||||||
import { AddUrlToHistoryAction } from '../history/history.actions';
|
import { AddUrlToHistoryAction } from '../history/history.actions';
|
||||||
import { historySelector } from '../history/selectors';
|
import { historySelector } from '../history/selectors';
|
||||||
|
import { SetParametersAction, SetQueryParametersAction } from './route.actions';
|
||||||
|
import { CoreState } from '../../core/core.reducers';
|
||||||
|
import { hasValue } from '../empty.util';
|
||||||
|
import { coreSelector } from '../../core/core.selectors';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector to select all route parameters from the store
|
||||||
|
*/
|
||||||
|
export const routeParametersSelector = createSelector(
|
||||||
|
coreSelector,
|
||||||
|
(state: CoreState) => state.route.params
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector to select all query parameters from the store
|
||||||
|
*/
|
||||||
|
export const queryParametersSelector = createSelector(
|
||||||
|
coreSelector,
|
||||||
|
(state: CoreState) => state.route.queryParams
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector to select a specific route parameter from the store
|
||||||
|
* @param key The key of the parameter
|
||||||
|
*/
|
||||||
|
export const routeParameterSelector = (key: string) => parameterSelector(key, routeParametersSelector);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector to select a specific query parameter from the store
|
||||||
|
* @param key The key of the parameter
|
||||||
|
*/
|
||||||
|
export const queryParameterSelector = (key: string) => parameterSelector(key, queryParametersSelector);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to select a specific parameter from the store
|
||||||
|
* @param key The key to look for
|
||||||
|
* @param paramsSelector The selector that selects the parameters to search in
|
||||||
|
*/
|
||||||
|
export function parameterSelector(key: string, paramsSelector: (state: CoreState) => Params): MemoizedSelector<CoreState, string> {
|
||||||
|
return createSelector(paramsSelector, (state: Params) => {
|
||||||
|
if (hasValue(state)) {
|
||||||
|
return state[key];
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service to keep track of the current query parameters
|
* Service to keep track of the current query parameters
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RouteService {
|
export class RouteService {
|
||||||
params: Observable<Params>;
|
constructor(private route: ActivatedRoute, private router: Router, private store: Store<CoreState>) {
|
||||||
|
this.saveRouting();
|
||||||
constructor(private route: ActivatedRoute, private router: Router, private store: Store<AppState>) {
|
|
||||||
this.subscribeToRouterParams();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,11 +117,11 @@ export class RouteService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getRouteParameterValue(paramName: string): Observable<string> {
|
getRouteParameterValue(paramName: string): Observable<string> {
|
||||||
return this.params.pipe(map((params) => params[paramName]),distinctUntilChanged(),);
|
return this.store.pipe(select(routeParameterSelector(paramName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
getRouteDataValue(datafield: string): Observable<any> {
|
getRouteDataValue(datafield: string): Observable<any> {
|
||||||
return this.route.data.pipe(map((data) => data[datafield]),distinctUntilChanged(),);
|
return this.route.data.pipe(map((data) => data[datafield]), distinctUntilChanged(),);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,23 +157,21 @@ export class RouteService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public saveRouting(): void {
|
public saveRouting(): void {
|
||||||
this.router.events
|
combineLatest(this.router.events, this.getRouteParams(), this.route.queryParams)
|
||||||
.pipe(filter((event) => event instanceof NavigationEnd))
|
.pipe(filter(([event, params, queryParams]) => event instanceof NavigationEnd))
|
||||||
.subscribe(({ urlAfterRedirects }: NavigationEnd) => {
|
.subscribe(([event, params, queryParams]: [NavigationEnd, Params, Params]) => {
|
||||||
this.store.dispatch(new AddUrlToHistoryAction(urlAfterRedirects))
|
this.store.dispatch(new SetParametersAction(params));
|
||||||
|
this.store.dispatch(new SetQueryParametersAction(queryParams));
|
||||||
|
this.store.dispatch(new AddUrlToHistoryAction(event.urlAfterRedirects));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribeToRouterParams() {
|
private getRouteParams(): Observable<Params> {
|
||||||
this.params = this.router.events.pipe(
|
let active = this.route;
|
||||||
mergeMap((event) => {
|
while (active.firstChild) {
|
||||||
let active = this.route;
|
active = active.firstChild;
|
||||||
while (active.firstChild) {
|
}
|
||||||
active = active.firstChild;
|
return active.params;
|
||||||
}
|
|
||||||
return active.params;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getHistory(): Observable<string[]> {
|
public getHistory(): Observable<string[]> {
|
||||||
|
@@ -38,7 +38,7 @@
|
|||||||
title="{{ listItem.collection.name }}"
|
title="{{ listItem.collection.name }}"
|
||||||
(click)="onSelect(listItem)">
|
(click)="onSelect(listItem)">
|
||||||
<ul class="list-unstyled mb-0">
|
<ul class="list-unstyled mb-0">
|
||||||
<li class="list-item text-truncate text-secondary" *ngFor="let item of listItem.communities" >
|
<li class="list-item text-truncate text-secondary" *ngFor="let item of listItem.communities">
|
||||||
{{ item.name}} <i class="fa fa-level-down" aria-hidden="true"></i>
|
{{ item.name}} <i class="fa fa-level-down" aria-hidden="true"></i>
|
||||||
</li>
|
</li>
|
||||||
<li class="list-item text-truncate text-primary font-weight-bold">{{ listItem.collection.name}}</li>
|
<li class="list-item text-truncate text-primary font-weight-bold">{{ listItem.collection.name}}</li>
|
||||||
|
@@ -237,7 +237,7 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit {
|
|||||||
if (isEmpty(searchTerm)) {
|
if (isEmpty(searchTerm)) {
|
||||||
return listCollection;
|
return listCollection;
|
||||||
} else {
|
} else {
|
||||||
return listCollection.filter((v) => v.collection.name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1).slice(0, 5)
|
return listCollection.filter((v) => v.collection.name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1).slice(0, 5);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user