From bfeeeac96f52b6eddab360778a5f22e84693db70 Mon Sep 17 00:00:00 2001 From: gaurav patel <100828173+GauravD2t@users.noreply.github.com> Date: Sat, 24 Feb 2024 03:31:36 +0530 Subject: [PATCH 1/2] only add Display Search Facets to the Homepage (#2275) * Update homepage-config.interface.ts change comment of homepage-config.interface.ts * advance Search add * slove error while unti test * write unit test * Ensures select element has an accessible name * change data pass into url * error resolve * Search.Filters.Applied.F.Title given name as Title * Advanced filters configurable in the User interface (in config.*.yml) * Search Facets on all Home, Community, Collection * should pass accessibility tests error resolve * change label name * unique role or role/label/title * remove same role name * order of headings is semantically correct * semantically correct advance search and global css * URL pattern * headings is semantically correct * Merge branch 'Search-Facets-home-community-collection' of https://github.com/GauravD2t/Advanced-search into Search-Facets-home-community-collection * change update * change update * remove advance search code from here * removing all code relating to Community/Collection pages * resolve code conflict * remove the space * remove commented code * add 'merge' * resolve confilt * remove back file * add lable dynamic * Update search-navbar.component.spec.ts * Update search-filter.component.html * showDiscoverFilters config in yml file * Ensures the order of headings is semantically correct * showDiscoverFilters change default to false * Update homepage-config.interface.ts to use boolean instead of false --------- Co-authored-by: Tim Donohue --- config/config.example.yml | 2 ++ .../collection-page.component.html | 2 +- .../community-page.component.ts | 2 +- src/app/home-page/home-page.component.html | 23 +++++++++++++------ src/app/home-page/home-page.component.ts | 4 +++- src/app/home-page/home-page.module.ts | 3 ++- .../search-filter/search-filter.component.ts | 13 +++++++++-- .../search-filters.component.html | 3 ++- .../search-filters.component.spec.ts | 3 ++- .../search-filters.component.ts | 4 ++++ .../search-sidebar.component.html | 2 +- src/app/shared/search/search.component.html | 13 ++++++----- src/app/shared/search/search.module.ts | 1 - .../sidebar/sidebar-dropdown.component.html | 2 +- src/assets/i18n/en.json5 | 3 +++ src/config/default-app-config.ts | 3 ++- src/config/homepage-config.interface.ts | 6 ++++- src/environments/environment.test.ts | 3 ++- 18 files changed, 65 insertions(+), 27 deletions(-) diff --git a/config/config.example.yml b/config/config.example.yml index feea06f7cb..4fbc98fea2 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -294,6 +294,8 @@ homePage: # No. of communities to list per page on the home page # This will always round to the nearest number from the list of page sizes. e.g. if you set it to 7 it'll use 10 pageSize: 5 + # Enable or disable the Discover filters on the homepage + showDiscoverFilters: false # Item Config item: diff --git a/src/app/collection-page/collection-page.component.html b/src/app/collection-page/collection-page.component.html index 21cc94af68..d5da37c12f 100644 --- a/src/app/collection-page/collection-page.component.html +++ b/src/app/collection-page/collection-page.component.html @@ -58,4 +58,4 @@ - + \ No newline at end of file diff --git a/src/app/community-page/community-page.component.ts b/src/app/community-page/community-page.component.ts index 206aa54cb0..148df02509 100644 --- a/src/app/community-page/community-page.component.ts +++ b/src/app/community-page/community-page.component.ts @@ -7,7 +7,7 @@ import { Bitstream } from '../core/shared/bitstream.model'; import { Community } from '../core/shared/community.model'; import { fadeInOut } from '../shared/animations/fade'; import { hasValue } from '../shared/empty.util'; -import { getAllSucceededRemoteDataPayload} from '../core/shared/operators'; +import { getAllSucceededRemoteDataPayload } from '../core/shared/operators'; import { AuthService } from '../core/auth/auth.service'; import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../core/data/feature-authorization/feature-id'; diff --git a/src/app/home-page/home-page.component.html b/src/app/home-page/home-page.component.html index 49329b3f04..c1d4b8a98c 100644 --- a/src/app/home-page/home-page.component.html +++ b/src/app/home-page/home-page.component.html @@ -1,10 +1,19 @@ -
- - - - - - +
+
+
+ +
+
+ + + + + + +
+
diff --git a/src/app/home-page/home-page.component.ts b/src/app/home-page/home-page.component.ts index c151cbbb16..9adc478b90 100644 --- a/src/app/home-page/home-page.component.ts +++ b/src/app/home-page/home-page.component.ts @@ -1,9 +1,10 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, Inject, OnInit } from '@angular/core'; import { map } from 'rxjs/operators'; import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs'; import { Site } from '../core/shared/site.model'; import { environment } from '../../environments/environment'; +import { APP_CONFIG, AppConfig } from 'src/config/app-config.interface'; @Component({ selector: 'ds-home-page', styleUrls: ['./home-page.component.scss'], @@ -14,6 +15,7 @@ export class HomePageComponent implements OnInit { site$: Observable; recentSubmissionspageSize: number; constructor( + @Inject(APP_CONFIG) protected appConfig: AppConfig, private route: ActivatedRoute, ) { this.recentSubmissionspageSize = environment.homePage.recentSubmissions.pageSize; diff --git a/src/app/home-page/home-page.module.ts b/src/app/home-page/home-page.module.ts index 7b656abd73..e3debef5ca 100644 --- a/src/app/home-page/home-page.module.ts +++ b/src/app/home-page/home-page.module.ts @@ -3,7 +3,6 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../shared/shared.module'; import { HomeNewsComponent } from './home-news/home-news.component'; import { HomePageRoutingModule } from './home-page-routing.module'; - import { HomePageComponent } from './home-page.component'; import { TopLevelCommunityListComponent } from './top-level-community-list/top-level-community-list.component'; import { StatisticsModule } from '../statistics/statistics.module'; @@ -13,6 +12,7 @@ import { RecentItemListComponent } from './recent-item-list/recent-item-list.com import { JournalEntitiesModule } from '../entity-groups/journal-entities/journal-entities.module'; import { ResearchEntitiesModule } from '../entity-groups/research-entities/research-entities.module'; import { ThemedTopLevelCommunityListComponent } from './top-level-community-list/themed-top-level-community-list.component'; +import { SearchModule } from '../shared/search/search.module'; import { NotificationsModule } from '../notifications/notifications.module'; const DECLARATIONS = [ @@ -29,6 +29,7 @@ const DECLARATIONS = [ imports: [ CommonModule, SharedModule.withEntryComponents(), + SearchModule, JournalEntitiesModule.withEntryComponents(), ResearchEntitiesModule.withEntryComponents(), HomePageRoutingModule, diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-filter.component.ts index 67e8906bb5..64b5ba23e2 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-filter.component.ts @@ -157,11 +157,20 @@ export class SearchFilterComponent implements OnInit { } get regionId(): string { - return `search-filter-region-${this.sequenceId}`; + if (this.inPlaceSearch) { + return `search-filter-region-${this.sequenceId}`; + } else { + return `search-filter-region-home-${this.sequenceId}`; + } + } get toggleId(): string { - return `search-filter-toggle-${this.sequenceId}`; + if (this.inPlaceSearch) { + return `search-filter-toggle-${this.sequenceId}`; + } else { + return `search-filter-toggle-home-${this.sequenceId}`; + } } /** diff --git a/src/app/shared/search/search-filters/search-filters.component.html b/src/app/shared/search/search-filters/search-filters.component.html index c006d80c44..b5377f502b 100644 --- a/src/app/shared/search/search-filters/search-filters.component.html +++ b/src/app/shared/search/search-filters/search-filters.component.html @@ -1,4 +1,5 @@ -

{{"search.filters.head" | translate}}

+

{{filterLabel+'.filters.head' | translate}}

+

{{filterLabel+'.filters.head' | translate}}

diff --git a/src/app/shared/search/search-filters/search-filters.component.spec.ts b/src/app/shared/search/search-filters/search-filters.component.spec.ts index 522459b603..85fd8e09a1 100644 --- a/src/app/shared/search/search-filters/search-filters.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filters.component.spec.ts @@ -20,7 +20,8 @@ describe('SearchFiltersComponent', () => { getClearFiltersQueryParams: () => { }, getSearchLink: () => { - } + }, + getConfigurationSearchConfig: () => { }, /* eslint-enable no-empty, @typescript-eslint/no-empty-function */ }; diff --git a/src/app/shared/search/search-filters/search-filters.component.ts b/src/app/shared/search/search-filters/search-filters.component.ts index 766939226d..57cce61788 100644 --- a/src/app/shared/search/search-filters/search-filters.component.ts +++ b/src/app/shared/search/search-filters/search-filters.component.ts @@ -61,6 +61,7 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { searchLink: string; subs = []; + filterLabel = 'search'; /** * Initialize instance variables @@ -77,6 +78,9 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { } ngOnInit(): void { + if (!this.inPlaceSearch) { + this.filterLabel = 'discover'; + } this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe(map((filters) => { Object.keys(filters).forEach((f) => filters[f] = null); return filters; diff --git a/src/app/shared/search/search-sidebar/search-sidebar.component.html b/src/app/shared/search/search-sidebar/search-sidebar.component.html index 529f1de887..f14854593e 100644 --- a/src/app/shared/search/search-sidebar/search-sidebar.component.html +++ b/src/app/shared/search/search-sidebar/search-sidebar.component.html @@ -23,7 +23,7 @@ [filters]="filters" [refreshFilters]="refreshFilters" [inPlaceSearch]="inPlaceSearch"> -
diff --git a/src/app/shared/search/search.component.html b/src/app/shared/search/search.component.html index acd60f2616..6ee0bb3cb0 100644 --- a/src/app/shared/search/search.component.html +++ b/src/app/shared/search/search.component.html @@ -10,8 +10,9 @@
- - + + @@ -22,15 +23,15 @@
- -
- -
+ \ No newline at end of file diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index a8632ee999..57ed7d3067 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -5630,6 +5630,8 @@ "admin.system-wide-alert.title": "System-wide Alerts", + "discover.filters.head": "Discover", + "item-access-control-title": "This form allows you to perform changes to the access conditions of the item's metadata or its bitstreams.", "collection-access-control-title": "This form allows you to perform changes to the access conditions of all the items owned by this collection. Changes may be performed to either all Item metadata or all content (bitstreams).", @@ -5698,3 +5700,4 @@ "admin.notifications.publicationclaim.page.title": "Publication Claim", } + diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index b7c026be89..ae5c6c1d00 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -306,7 +306,8 @@ export class DefaultAppConfig implements AppConfig { }, topLevelCommunityList: { pageSize: 5 - } + }, + showDiscoverFilters: false }; // Item Config diff --git a/src/config/homepage-config.interface.ts b/src/config/homepage-config.interface.ts index df5d29cfe0..48fd9077a9 100644 --- a/src/config/homepage-config.interface.ts +++ b/src/config/homepage-config.interface.ts @@ -1,7 +1,7 @@ import { Config } from './config.interface'; /** - * Config that determines how the dropdown list of years are created for browse-by-date components + * Config that determines how the recentSubmissions list showing at home page */ export interface HomeConfig extends Config { recentSubmissions: { @@ -19,4 +19,8 @@ export interface HomeConfig extends Config { topLevelCommunityList: { pageSize: number; }; + /* + * Enable or disable the Discover filters on the homepage + */ + showDiscoverFilters: boolean; } diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index 7324cf4d13..e0cf1eb207 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -246,7 +246,8 @@ export const environment: BuildConfig = { }, topLevelCommunityList: { pageSize: 5 - } + }, + showDiscoverFilters: false }, item: { edit: { From 91a419fb0f17bb85501ef66bf25b8fc2c359de2e Mon Sep 17 00:00:00 2001 From: gaurav patel <100828173+GauravD2t@users.noreply.github.com> Date: Tue, 27 Feb 2024 01:41:28 +0530 Subject: [PATCH 2/2] Advance search search page (#2608) * Update homepage-config.interface.ts change comment of homepage-config.interface.ts * advance Search add * slove error while unti test * write unit test * Ensures select element has an accessible name * change data pass into url * error resolve * Search.Filters.Applied.F.Title given name as Title * Advanced filters configurable in the User interface (in config.*.yml) * turn on/off and add filters as a list * remove currenturl * resolve * change envierment config and url pass data * set enabled: false ,and remove debugger ,remove searchConfig * expect clauses add * reslove conflict * merge added * remove commented and design change advance search * moving the "add" button to its own col-lg-12 * resolve conflict * reslove error * merge en.json5 file * remove trailing spaces * resolve Conflicts * Fix typo. property is filter not filters --------- Co-authored-by: Tim Donohue --- config/config.example.yml | 9 ++ .../advanced-search.component.html | 51 ++++++++ .../advanced-search.component.scss | 1 + .../advanced-search.component.spec.ts | 74 +++++++++++ .../advanced-search.component.ts | 115 ++++++++++++++++++ .../search-filters.component.html | 2 + .../search-filters.component.spec.ts | 3 + .../search-filters.component.ts | 6 +- src/app/shared/search/search.module.ts | 2 + src/app/shared/search/search.utils.ts | 2 +- src/assets/i18n/en.json5 | 29 ++++- src/config/advance-search-config.interface.ts | 4 + src/config/app-config.interface.ts | 3 +- src/config/default-app-config.ts | 12 +- src/config/search-page-config.interface.ts | 11 ++ src/environments/environment.test.ts | 10 +- 16 files changed, 326 insertions(+), 8 deletions(-) create mode 100644 src/app/shared/search/advanced-search/advanced-search.component.html create mode 100644 src/app/shared/search/advanced-search/advanced-search.component.scss create mode 100644 src/app/shared/search/advanced-search/advanced-search.component.spec.ts create mode 100644 src/app/shared/search/advanced-search/advanced-search.component.ts create mode 100644 src/config/advance-search-config.interface.ts create mode 100644 src/config/search-page-config.interface.ts diff --git a/config/config.example.yml b/config/config.example.yml index 4fbc98fea2..8b010ba6ea 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -424,3 +424,12 @@ comcolSelectionSort: # suggestion: # - collectionId: 8f7df5ca-f9c2-47a4-81ec-8a6393d6e5af # source: "openaire" + + +# Search settings +search: + # Settings to enable/disable or configure advanced search filters. + advancedFilters: + enabled: false + # List of filters to enable in "Advanced Search" dropdown + filter: [ 'title', 'author', 'subject', 'entityType' ] diff --git a/src/app/shared/search/advanced-search/advanced-search.component.html b/src/app/shared/search/advanced-search/advanced-search.component.html new file mode 100644 index 0000000000..e03fb40532 --- /dev/null +++ b/src/app/shared/search/advanced-search/advanced-search.component.html @@ -0,0 +1,51 @@ +
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/src/app/shared/search/advanced-search/advanced-search.component.scss b/src/app/shared/search/advanced-search/advanced-search.component.scss new file mode 100644 index 0000000000..13ca767b2b --- /dev/null +++ b/src/app/shared/search/advanced-search/advanced-search.component.scss @@ -0,0 +1 @@ +@import '../search-filters/search-filter/search-filter.component.scss'; \ No newline at end of file diff --git a/src/app/shared/search/advanced-search/advanced-search.component.spec.ts b/src/app/shared/search/advanced-search/advanced-search.component.spec.ts new file mode 100644 index 0000000000..a6a7f46491 --- /dev/null +++ b/src/app/shared/search/advanced-search/advanced-search.component.spec.ts @@ -0,0 +1,74 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormBuilderService } from '../../../shared/form/builder/form-builder.service'; +import { AdvancedSearchComponent } from './advanced-search.component'; +import { getMockFormBuilderService } from '../../../shared/mocks/form-builder-service.mock'; +import { SearchService } from '../../../core/shared/search/search.service'; +import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component'; +import { SearchConfigurationServiceStub } from '../../testing/search-configuration-service.stub'; +import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data-build.service'; +import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { APP_CONFIG } from '../../../../config/app-config.interface'; +import { environment } from '../../../../environments/environment'; +import { RouterStub } from '../../testing/router.stub'; +import { Router } from '@angular/router'; +import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; +import { BrowserOnlyMockPipe } from '../../testing/browser-only-mock.pipe'; +import { RouterTestingModule } from '@angular/router/testing'; +import { TranslateModule } from '@ngx-translate/core'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +describe('AdvancedSearchComponent', () => { + let component: AdvancedSearchComponent; + let fixture: ComponentFixture; + let builderService: FormBuilderService = getMockFormBuilderService(); + let searchService: SearchService; + let router; + const searchServiceStub = { + /* eslint-disable no-empty,@typescript-eslint/no-empty-function */ + getClearFiltersQueryParams: () => { + }, + getSearchLink: () => { + }, + getConfigurationSearchConfig: () => { }, + /* eslint-enable no-empty, @typescript-eslint/no-empty-function */ + }; + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [AdvancedSearchComponent, BrowserOnlyMockPipe], + imports: [FormsModule, RouterTestingModule, TranslateModule.forRoot(), BrowserAnimationsModule, ReactiveFormsModule], + providers: [ + FormBuilder, + { provide: APP_CONFIG, useValue: environment }, + { provide: FormBuilderService, useValue: builderService }, + { provide: Router, useValue: new RouterStub() }, + { provide: SEARCH_CONFIG_SERVICE, useValue: new SearchConfigurationServiceStub() }, + { provide: RemoteDataBuildService, useValue: {} }, + { provide: SearchService, useValue: searchServiceStub }, + ], + schemas: [NO_ERRORS_SCHEMA] + }).overrideComponent(AdvancedSearchComponent, { + set: { changeDetection: ChangeDetectionStrategy.Default } + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AdvancedSearchComponent); + component = fixture.componentInstance; + router = TestBed.inject(Router); + fixture.detectChanges(); + }); + describe('when the getSearchLink method is called', () => { + const data = { filter: 'title', textsearch: 'demo', operator: 'equals' }; + it('should call navigate on the router with the right searchlink and parameters when the filter is provided with a valid operator', () => { + component.advSearchForm.get('textsearch').patchValue('1'); + component.advSearchForm.get('filter').patchValue('1'); + component.advSearchForm.get('operator').patchValue('1'); + + component.onSubmit(data); + expect(router.navigate).toHaveBeenCalledWith([undefined], { + queryParams: { ['f.' + data.filter]: data.textsearch + ',' + data.operator }, + queryParamsHandling: 'merge' + }); + + }); + }); +}); diff --git a/src/app/shared/search/advanced-search/advanced-search.component.ts b/src/app/shared/search/advanced-search/advanced-search.component.ts new file mode 100644 index 0000000000..ca6a7c9e28 --- /dev/null +++ b/src/app/shared/search/advanced-search/advanced-search.component.ts @@ -0,0 +1,115 @@ +import { Component, Inject, Input, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { slide } from '../../animations/slide'; +import { FormBuilder } from '@angular/forms'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { SearchService } from '../../../core/shared/search/search.service'; +import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service'; +import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component'; +import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface'; +@Component({ + selector: 'ds-advanced-search', + templateUrl: './advanced-search.component.html', + styleUrls: ['./advanced-search.component.scss'], + animations: [slide], +}) + /** + * This component represents the part of the search sidebar that contains advanced filters. + */ +export class AdvancedSearchComponent implements OnInit { + /** + * True when the search component should show results on the current page + */ + @Input() inPlaceSearch; + + + /** + * Link to the search page + */ + notab: boolean; + + closed: boolean; + collapsedSearch = false; + focusBox = false; + + advSearchForm: FormGroup; + constructor( + @Inject(APP_CONFIG) protected appConfig: AppConfig, + private formBuilder: FormBuilder, + protected searchService: SearchService, + protected router: Router, + @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService) { + } + + ngOnInit(): void { + + this.advSearchForm = this.formBuilder.group({ + textsearch: new FormControl('', { + validators: [Validators.required], + }), + filter: new FormControl('title', { + validators: [Validators.required], + }), + operator: new FormControl('equals', + { validators: [Validators.required], }), + + }); + this.collapsedSearch = this.isCollapsed(); + + } + + get textsearch() { + return this.advSearchForm.get('textsearch'); + } + + get filter() { + return this.advSearchForm.get('filter'); + } + + get operator() { + return this.advSearchForm.get('operator'); + } + paramName(filter) { + return 'f.' + filter; + } + onSubmit(data) { + if (this.advSearchForm.valid) { + let queryParams = { [this.paramName(data.filter)]: data.textsearch + ',' + data.operator }; + if (!this.inPlaceSearch) { + this.router.navigate([this.searchService.getSearchLink()], { queryParams: queryParams, queryParamsHandling: 'merge' }); + } else { + if (!this.router.url.includes('?')) { + this.router.navigateByUrl(this.router.url + '?f.' + data.filter + '=' + data.textsearch + ',' + data.operator); + } else { + this.router.navigateByUrl(this.router.url + '&f.' + data.filter + '=' + data.textsearch + ',' + data.operator); + } + } + + this.advSearchForm.reset({ operator: data.operator, filter: data.filter, textsearch: '' }); + } + } + startSlide(event: any): void { + if (event.toState === 'collapsed') { + this.closed = true; + } + if (event.fromState === 'collapsed') { + this.notab = false; + } + } + finishSlide(event: any): void { + if (event.fromState === 'collapsed') { + this.closed = false; + } + if (event.toState === 'collapsed') { + this.notab = true; + } + } + toggle() { + this.collapsedSearch = !this.collapsedSearch; + } + private isCollapsed(): boolean { + return !this.collapsedSearch; + } + +} + diff --git a/src/app/shared/search/search-filters/search-filters.component.html b/src/app/shared/search/search-filters/search-filters.component.html index b5377f502b..3f70a759bc 100644 --- a/src/app/shared/search/search-filters/search-filters.component.html +++ b/src/app/shared/search/search-filters/search-filters.component.html @@ -5,4 +5,6 @@ + {{"search.filters.reset" | translate}} diff --git a/src/app/shared/search/search-filters/search-filters.component.spec.ts b/src/app/shared/search/search-filters/search-filters.component.spec.ts index 85fd8e09a1..246b9fb8b7 100644 --- a/src/app/shared/search/search-filters/search-filters.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filters.component.spec.ts @@ -9,6 +9,8 @@ import { SearchFiltersComponent } from './search-filters.component'; import { SearchService } from '../../../core/shared/search/search.service'; import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component'; import { SearchConfigurationServiceStub } from '../../testing/search-configuration-service.stub'; +import { APP_CONFIG } from 'src/config/app-config.interface'; +import { environment } from 'src/environments/environment'; describe('SearchFiltersComponent', () => { let comp: SearchFiltersComponent; @@ -38,6 +40,7 @@ describe('SearchFiltersComponent', () => { { provide: SearchService, useValue: searchServiceStub }, { provide: SEARCH_CONFIG_SERVICE, useValue: new SearchConfigurationServiceStub() }, { provide: SearchFilterService, useValue: searchFiltersStub }, + { provide: APP_CONFIG, useValue: environment }, ], schemas: [NO_ERRORS_SCHEMA] diff --git a/src/app/shared/search/search-filters/search-filters.component.ts b/src/app/shared/search/search-filters/search-filters.component.ts index 57cce61788..51065f827f 100644 --- a/src/app/shared/search/search-filters/search-filters.component.ts +++ b/src/app/shared/search/search-filters/search-filters.component.ts @@ -3,7 +3,7 @@ import { Router } from '@angular/router'; import { BehaviorSubject, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; - +import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface'; import { SearchService } from '../../../core/shared/search/search.service'; import { RemoteData } from '../../../core/data/remote-data'; import { SearchFilterConfig } from '../models/search-filter-config.model'; @@ -12,6 +12,7 @@ import { SearchFilterService } from '../../../core/shared/search/search-filter.s import { SEARCH_CONFIG_SERVICE } from '../../../my-dspace-page/my-dspace-page.component'; import { currentPath } from '../../utils/route.utils'; import { hasValue } from '../../empty.util'; +import { PaginatedSearchOptions } from '../models/paginated-search-options.model'; @Component({ selector: 'ds-search-filters', @@ -28,7 +29,7 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { * An observable containing configuration about which filters are shown and how they are shown */ @Input() filters: Observable>; - + @Input() searchOptions: PaginatedSearchOptions; /** * List of all filters that are currently active with their value set to null. * Used to reset all filters at once @@ -71,6 +72,7 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { * @param {SearchConfigurationService} searchConfigService */ constructor( + @Inject(APP_CONFIG) protected appConfig: AppConfig, private searchService: SearchService, private filterService: SearchFilterService, private router: Router, diff --git a/src/app/shared/search/search.module.ts b/src/app/shared/search/search.module.ts index d8474a5ea3..efb1a12581 100644 --- a/src/app/shared/search/search.module.ts +++ b/src/app/shared/search/search.module.ts @@ -32,6 +32,7 @@ import { ThemedSearchComponent } from './themed-search.component'; import { ThemedSearchResultsComponent } from './search-results/themed-search-results.component'; import { ThemedSearchSettingsComponent } from './search-settings/themed-search-settings.component'; import { NouisliderModule } from 'ng2-nouislider'; +import { AdvancedSearchComponent } from './advanced-search/advanced-search.component'; import { ThemedSearchFiltersComponent } from './search-filters/themed-search-filters.component'; import { ThemedSearchSidebarComponent } from './search-sidebar/themed-search-sidebar.component'; const COMPONENTS = [ @@ -59,6 +60,7 @@ const COMPONENTS = [ ThemedConfigurationSearchPageComponent, ThemedSearchResultsComponent, ThemedSearchSettingsComponent, + AdvancedSearchComponent, ThemedSearchFiltersComponent, ThemedSearchSidebarComponent, ]; diff --git a/src/app/shared/search/search.utils.ts b/src/app/shared/search/search.utils.ts index cfb96a5285..d5891f2b4e 100644 --- a/src/app/shared/search/search.utils.ts +++ b/src/app/shared/search/search.utils.ts @@ -49,7 +49,7 @@ export function stripOperatorFromFilterValue(value: string) { * @param operator */ export function addOperatorToFilterValue(value: string, operator: string) { - if (!value.match(new RegExp(`^.+,(equals|query|authority)$`))) { + if (!value.match(new RegExp(`^.+,(equals|query|authority|contains|notcontains|notequals)$`))) { return `${value},${operator}`; } return value; diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 57ed7d3067..a133cf5a3e 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -5699,5 +5699,32 @@ "admin.notifications.publicationclaim.breadcrumbs": "Publication Claim", "admin.notifications.publicationclaim.page.title": "Publication Claim", -} + "filter.search.operator.placeholder": "Operator", + + "search.filters.filter.entityType.text": "Item Type", + + "search.filters.operator.equals.text": "Equals", + + "search.filters.operator.notequals.text": "Not Equals", + + "search.filters.operator.notcontains.text": "Not Contains", + + "search.filters.operator.contains.text": "Contains", + + "search.filters.filter.title.text": "Title", + + "search.filters.applied.f.title": "Title", + + "search.filters.filter.author.text": "Author", + + "search.filters.filter.subject.text": "Subject", + + "search.advanced.filters.head": "Advanced Search", + + "filter.search.operator.placeholder": "Operator", + + "filter.search.text.placeholder": "Search text", + + "advancesearch.form.submit": "Add", +} \ No newline at end of file diff --git a/src/config/advance-search-config.interface.ts b/src/config/advance-search-config.interface.ts new file mode 100644 index 0000000000..092dc008fc --- /dev/null +++ b/src/config/advance-search-config.interface.ts @@ -0,0 +1,4 @@ +export interface AdvancedSearchConfig { + enabled: boolean; + filter: string[]; +} diff --git a/src/config/app-config.interface.ts b/src/config/app-config.interface.ts index 51a116fa70..3f432bfcad 100644 --- a/src/config/app-config.interface.ts +++ b/src/config/app-config.interface.ts @@ -25,7 +25,7 @@ import { MarkdownConfig } from './markdown-config.interface'; import { FilterVocabularyConfig } from './filter-vocabulary-config'; import { DiscoverySortConfig } from './discovery-sort.config'; import { QualityAssuranceConfig } from './quality-assurance.config'; - +import { SearchConfig } from './search-page-config.interface'; interface AppConfig extends Config { ui: UIServerConfig; rest: ServerConfig; @@ -54,6 +54,7 @@ interface AppConfig extends Config { vocabularies: FilterVocabularyConfig[]; comcolSelectionSort: DiscoverySortConfig; qualityAssuranceConfig: QualityAssuranceConfig; + search: SearchConfig; } /** diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index ae5c6c1d00..9ba5ee9a35 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -24,8 +24,8 @@ import { MarkdownConfig } from './markdown-config.interface'; import { FilterVocabularyConfig } from './filter-vocabulary-config'; import { DiscoverySortConfig } from './discovery-sort.config'; import { CommunityPageConfig } from './community-page-config.interface'; -import {QualityAssuranceConfig} from './quality-assurance.config'; - +import { QualityAssuranceConfig } from './quality-assurance.config'; +import { SearchConfig } from './search-page-config.interface'; export class DefaultAppConfig implements AppConfig { production = false; @@ -498,4 +498,12 @@ export class DefaultAppConfig implements AppConfig { }, pageSize: 5, }; + + + search: SearchConfig = { + advancedFilters: { + enabled: false, + filter: ['title', 'author', 'subject', 'entityType'] + } + }; } diff --git a/src/config/search-page-config.interface.ts b/src/config/search-page-config.interface.ts new file mode 100644 index 0000000000..70575c0601 --- /dev/null +++ b/src/config/search-page-config.interface.ts @@ -0,0 +1,11 @@ +import { Config } from './config.interface'; +import { AdvancedSearchConfig } from './advance-search-config.interface'; +export interface SearchConfig extends Config { + + /** + * List of standard filter to select in adding advanced Search + * Used by {@link UploadBitstreamComponent}. + */ + advancedFilters: AdvancedSearchConfig; + +} diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index e0cf1eb207..6f3ab32fa9 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -334,5 +334,13 @@ export const environment: BuildConfig = { } ], - suggestion: [] + suggestion: [], + + search: { + advancedFilters: { + enabled: false, + filter: ['title', 'author', 'subject', 'entityType'] + } + } + };