mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Merge branch 'advanced-search_contribute-7.6' into advanced-search_contribute-main
# Conflicts: # src/app/core/shared/search/search-configuration.service.ts # src/app/shared/search/advanced-search/advanced-search.component.ts # src/app/shared/search/search-sidebar/search-sidebar.component.html # src/app/shared/search/search-sidebar/search-sidebar.component.spec.ts # src/app/shared/search/search-sidebar/search-sidebar.component.ts # src/app/shared/testing/search-configuration-service.stub.ts
This commit is contained in:
@@ -56,6 +56,11 @@ import {
|
|||||||
getFirstSucceededRemoteData,
|
getFirstSucceededRemoteData,
|
||||||
} from '../operators';
|
} from '../operators';
|
||||||
import { ViewMode } from '../view-mode.model';
|
import { ViewMode } from '../view-mode.model';
|
||||||
|
import { SearchFilterConfig } from '../../../shared/search/models/search-filter-config.model';
|
||||||
|
import { FacetConfigResponse } from '../../../shared/search/models/facet-config-response.model';
|
||||||
|
import { addOperatorToFilterValue } from '../../../shared/search/search.utils';
|
||||||
|
import { FilterConfig } from './search-filters/search-config.model';
|
||||||
|
import { FilterType } from '../../../shared/search/models/filter-type.model';
|
||||||
import {
|
import {
|
||||||
SearchConfig,
|
SearchConfig,
|
||||||
SortConfig,
|
SortConfig,
|
||||||
@@ -282,6 +287,21 @@ export class SearchConfigurationService implements OnDestroy {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link FilterConfig}s of the filters that should be displayed for the current configuration/scope
|
||||||
|
*
|
||||||
|
* @param configuration The search configuration
|
||||||
|
* @param scope The scope if exists
|
||||||
|
*/
|
||||||
|
public getConfigurationAdvancedSearchFilters(configuration: string, scope?: string): Observable<FilterConfig[]> {
|
||||||
|
return this.getConfigurationSearchConfig(configuration, scope).pipe(
|
||||||
|
map((searchConfiguration: SearchConfig) => {
|
||||||
|
return searchConfiguration.filters
|
||||||
|
.filter((filterConfig: FilterConfig) => filterConfig.type !== FilterType.range);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
setPaginationId(paginationId): void {
|
setPaginationId(paginationId): void {
|
||||||
if (isNotEmpty(paginationId)) {
|
if (isNotEmpty(paginationId)) {
|
||||||
const currentValue: PaginatedSearchOptions = this.paginatedSearchOptions.getValue();
|
const currentValue: PaginatedSearchOptions = this.paginatedSearchOptions.getValue();
|
||||||
|
@@ -17,7 +17,6 @@ import {
|
|||||||
} from '@angular/router';
|
} from '@angular/router';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import {
|
import {
|
||||||
map,
|
|
||||||
Observable,
|
Observable,
|
||||||
of as observableOf,
|
of as observableOf,
|
||||||
Subscription,
|
Subscription,
|
||||||
@@ -31,10 +30,7 @@ import {
|
|||||||
import { SearchService } from '../../../core/shared/search/search.service';
|
import { SearchService } from '../../../core/shared/search/search.service';
|
||||||
import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
|
import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
|
||||||
import { SearchFilterService } from '../../../core/shared/search/search-filter.service';
|
import { SearchFilterService } from '../../../core/shared/search/search-filter.service';
|
||||||
import {
|
import { FilterConfig } from '../../../core/shared/search/search-filters/search-config.model';
|
||||||
FilterConfig,
|
|
||||||
SearchConfig,
|
|
||||||
} from '../../../core/shared/search/search-filters/search-config.model';
|
|
||||||
import {
|
import {
|
||||||
hasValue,
|
hasValue,
|
||||||
isNotEmpty,
|
isNotEmpty,
|
||||||
@@ -44,6 +40,9 @@ import { InputSuggestion } from '../../input-suggestions/input-suggestions.model
|
|||||||
import { FilterType } from '../models/filter-type.model';
|
import { FilterType } from '../models/filter-type.model';
|
||||||
import { SearchFilterConfig } from '../models/search-filter-config.model';
|
import { SearchFilterConfig } from '../models/search-filter-config.model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component represents the advanced search in the search sidebar.
|
||||||
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-advanced-search',
|
selector: 'ds-advanced-search',
|
||||||
templateUrl: './advanced-search.component.html',
|
templateUrl: './advanced-search.component.html',
|
||||||
@@ -60,10 +59,21 @@ import { SearchFilterConfig } from '../models/search-filter-config.model';
|
|||||||
})
|
})
|
||||||
export class AdvancedSearchComponent implements OnInit, OnDestroy {
|
export class AdvancedSearchComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current search configuration
|
||||||
|
*/
|
||||||
@Input() configuration: string;
|
@Input() configuration: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The facet configurations, used to determine if suggestions should be retrieved for the selected search filter
|
||||||
|
*/
|
||||||
@Input() filtersConfig: SearchFilterConfig[];
|
@Input() filtersConfig: SearchFilterConfig[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current search scope
|
||||||
|
*/
|
||||||
|
@Input() scope: string;
|
||||||
|
|
||||||
advancedFilters$: Observable<FilterConfig[]>;
|
advancedFilters$: Observable<FilterConfig[]>;
|
||||||
|
|
||||||
advancedFilterMap: Map<string, FilterConfig> = new Map();
|
advancedFilterMap: Map<string, FilterConfig> = new Map();
|
||||||
@@ -94,13 +104,7 @@ export class AdvancedSearchComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.advancedFilters$ = this.searchConfigurationService.getConfigurationSearchConfig(this.configuration).pipe(
|
this.advancedFilters$ = this.searchConfigurationService.getConfigurationAdvancedSearchFilters(this.configuration, this.scope);
|
||||||
map((searchConfiguration: SearchConfig) => {
|
|
||||||
return searchConfiguration.filters
|
|
||||||
.filter((filter: FilterConfig) => this.appConfig.search.advancedFilters.filter.includes(filter.filter))
|
|
||||||
.filter((filter: FilterConfig) => filter.type !== FilterType.range);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
this.subs.push(this.advancedFilters$.subscribe((filters: FilterConfig[]) => {
|
this.subs.push(this.advancedFilters$.subscribe((filters: FilterConfig[]) => {
|
||||||
const filterMap: Map<string, FilterConfig> = new Map();
|
const filterMap: Map<string, FilterConfig> = new Map();
|
||||||
if (filters.length > 0) {
|
if (filters.length > 0) {
|
||||||
|
@@ -24,9 +24,10 @@
|
|||||||
[refreshFilters]="refreshFilters"
|
[refreshFilters]="refreshFilters"
|
||||||
[inPlaceSearch]="inPlaceSearch">
|
[inPlaceSearch]="inPlaceSearch">
|
||||||
</ds-search-filters>
|
</ds-search-filters>
|
||||||
<ds-advanced-search *ngIf="inPlaceSearch && appConfig.search.advancedFilters.enabled"
|
<ds-advanced-search *ngIf="inPlaceSearch && (this.showAdvancedSearch$ | async) === true"
|
||||||
[configuration]="configuration"
|
[configuration]="configuration"
|
||||||
[filtersConfig]="(filters | async)?.payload">
|
[filtersConfig]="(filters | async)?.payload"
|
||||||
|
[scope]="currentScope">
|
||||||
</ds-advanced-search>
|
</ds-advanced-search>
|
||||||
<ds-search-settings *ngIf="inPlaceSearch"
|
<ds-search-settings *ngIf="inPlaceSearch"
|
||||||
[currentSortOption]="currentSortOption"
|
[currentSortOption]="currentSortOption"
|
||||||
|
@@ -17,12 +17,21 @@ import { AdvancedSearchComponent } from '../advanced-search/advanced-search.comp
|
|||||||
import { ThemedSearchFiltersComponent } from '../search-filters/themed-search-filters.component';
|
import { ThemedSearchFiltersComponent } from '../search-filters/themed-search-filters.component';
|
||||||
import { ThemedSearchSettingsComponent } from '../search-settings/themed-search-settings.component';
|
import { ThemedSearchSettingsComponent } from '../search-settings/themed-search-settings.component';
|
||||||
import { SearchSidebarComponent } from './search-sidebar.component';
|
import { SearchSidebarComponent } from './search-sidebar.component';
|
||||||
|
import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { SearchConfigurationServiceStub } from '../../testing/search-configuration-service.stub';
|
||||||
|
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
|
import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
|
||||||
|
|
||||||
describe('SearchSidebarComponent', () => {
|
describe('SearchSidebarComponent', () => {
|
||||||
let comp: SearchSidebarComponent;
|
let comp: SearchSidebarComponent;
|
||||||
let fixture: ComponentFixture<SearchSidebarComponent>;
|
let fixture: ComponentFixture<SearchSidebarComponent>;
|
||||||
// waitForAsync beforeEach
|
|
||||||
|
let searchConfigurationService: SearchConfigurationServiceStub;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
|
searchConfigurationService = new SearchConfigurationServiceStub();
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule.forRoot(),
|
TranslateModule.forRoot(),
|
||||||
|
@@ -7,6 +7,7 @@ import {
|
|||||||
EventEmitter,
|
EventEmitter,
|
||||||
Inject,
|
Inject,
|
||||||
Input,
|
Input,
|
||||||
|
OnInit,
|
||||||
Output,
|
Output,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
@@ -14,6 +15,7 @@ import {
|
|||||||
BehaviorSubject,
|
BehaviorSubject,
|
||||||
Observable,
|
Observable,
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
APP_CONFIG,
|
APP_CONFIG,
|
||||||
@@ -21,6 +23,8 @@ import {
|
|||||||
} from '../../../../config/app-config.interface';
|
} from '../../../../config/app-config.interface';
|
||||||
import { SortOptions } from '../../../core/cache/models/sort-options.model';
|
import { SortOptions } from '../../../core/cache/models/sort-options.model';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
|
import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
|
||||||
|
import { FilterConfig } from '../../../core/shared/search/search-filters/search-config.model';
|
||||||
import { ViewMode } from '../../../core/shared/view-mode.model';
|
import { ViewMode } from '../../../core/shared/view-mode.model';
|
||||||
import { ViewModeSwitchComponent } from '../../view-mode-switch/view-mode-switch.component';
|
import { ViewModeSwitchComponent } from '../../view-mode-switch/view-mode-switch.component';
|
||||||
import { AdvancedSearchComponent } from '../advanced-search/advanced-search.component';
|
import { AdvancedSearchComponent } from '../advanced-search/advanced-search.component';
|
||||||
@@ -48,7 +52,7 @@ import { SearchSwitchConfigurationComponent } from '../search-switch-configurati
|
|||||||
/**
|
/**
|
||||||
* Component representing the sidebar on the search page
|
* Component representing the sidebar on the search page
|
||||||
*/
|
*/
|
||||||
export class SearchSidebarComponent {
|
export class SearchSidebarComponent implements OnInit {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The configuration to use for the search options
|
* The configuration to use for the search options
|
||||||
@@ -125,9 +129,18 @@ export class SearchSidebarComponent {
|
|||||||
*/
|
*/
|
||||||
@Output() changeViewMode: EventEmitter<ViewMode> = new EventEmitter<ViewMode>();
|
@Output() changeViewMode: EventEmitter<ViewMode> = new EventEmitter<ViewMode>();
|
||||||
|
|
||||||
|
showAdvancedSearch$: Observable<boolean>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(APP_CONFIG) protected appConfig: AppConfig,
|
@Inject(APP_CONFIG) protected appConfig: AppConfig,
|
||||||
|
protected searchConfigurationService: SearchConfigurationService,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.showAdvancedSearch$ = this.searchConfigurationService.getConfigurationAdvancedSearchFilters(this.configuration, this.currentScope).pipe(
|
||||||
|
map((advancedFilters: FilterConfig[]) => this.appConfig.search.advancedFilters.enabled && advancedFilters.length > 0),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -5,8 +5,14 @@ import {
|
|||||||
of as observableOf,
|
of as observableOf,
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
|
|
||||||
import { SearchConfig } from '../../core/shared/search/search-filters/search-config.model';
|
import {
|
||||||
|
FilterConfig,
|
||||||
|
SearchConfig,
|
||||||
|
} from '../../core/shared/search/search-filters/search-config.model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stub class of {@link SearchConfigurationService}
|
||||||
|
*/
|
||||||
export class SearchConfigurationServiceStub {
|
export class SearchConfigurationServiceStub {
|
||||||
|
|
||||||
public paginationID = 'test-id';
|
public paginationID = 'test-id';
|
||||||
@@ -30,6 +36,10 @@ export class SearchConfigurationServiceStub {
|
|||||||
return observableOf(a);
|
return observableOf(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getConfigurationAdvancedSearchFilters(_configuration: string, _scope?: string): Observable<FilterConfig[]> {
|
||||||
|
return observableOf([]);
|
||||||
|
}
|
||||||
|
|
||||||
getConfig () {
|
getConfig () {
|
||||||
return observableOf({ hasSucceeded: true, payload: [] });
|
return observableOf({ hasSucceeded: true, payload: [] });
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user