Skip to content

Commit

Permalink
geocat: add location filter in search & location input in home page
Browse files Browse the repository at this point in the history
  • Loading branch information
jahow committed Nov 28, 2024
1 parent ff3dae2 commit 7547c79
Show file tree
Hide file tree
Showing 32 changed files with 935 additions and 78 deletions.
9 changes: 8 additions & 1 deletion apps/datahub/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {
EXTERNAL_VIEWER_URL_TEMPLATE,
FeatureRecordModule,
GN_UI_VERSION,
WEB_COMPONENT_EMBEDDER_URL,
RecordMetaComponent,
WEB_COMPONENT_EMBEDDER_URL,
} from '@geonetwork-ui/feature/record'
import {
DefaultRouterModule,
Expand All @@ -27,6 +27,7 @@ import {
import {
FeatureSearchModule,
FILTER_GEOMETRY,
LocationSearchComponent,
RECORD_URL_TOKEN,
} from '@geonetwork-ui/feature/search'
import {
Expand Down Expand Up @@ -102,6 +103,7 @@ import {
matStarOutline,
} from '@ng-icons/material-icons/outline'
import { NgIconsModule, provideNgIconsConfig } from '@ng-icons/core'
import { ORGANIZATIONS_STRATEGY } from '@geonetwork-ui/api/repository/gn4'

export const metaReducers: MetaReducer[] = !environment.production ? [] : []

Expand Down Expand Up @@ -173,6 +175,7 @@ export const metaReducers: MetaReducer[] = !environment.production ? [] : []
}),
OrganisationsComponent,
LanguageSwitcherComponent,
LocationSearchComponent,
],
providers: [
provideNgIconsConfig({
Expand Down Expand Up @@ -237,6 +240,10 @@ export const metaReducers: MetaReducer[] = !environment.production ? [] : []
provide: ORGANIZATION_URL_TOKEN,
useValue: `${ROUTER_ROUTE_SEARCH}?${ROUTE_PARAMS.PUBLISHER}=\${name}`,
},
{
provide: ORGANIZATIONS_STRATEGY,
useValue: 'groups',
},
{
provide: DO_NOT_USE_DEFAULT_BASEMAP,
useFactory: () => getOptionalMapConfig()?.DO_NOT_USE_DEFAULT_BASEMAP,
Expand Down
34 changes: 21 additions & 13 deletions apps/datahub/src/app/home/home-header/home-header.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,27 @@
[style.opacity]="expandRatio"
[innerHTML]="'datahub.header.title.html' | translate"
></div>
<gn-ui-fuzzy-search
class="text-[18px] pointer-events-auto"
style="
--gn-ui-text-input-padding: 1.1em;
--gn-ui-text-input-border-size: 0px;
"
(itemSelected)="onFuzzySearchSelection($event)"
[autoFocus]="true"
></gn-ui-fuzzy-search>
<div
class="flex flex-wrap h-0 py-5 gap-3"
[style.opacity]="-0.6 + expandRatio * 2"
>
<div class="flex flex-wrap gap-4">
<gn-ui-fuzzy-search
class="text-[18px] grow pointer-events-auto"
style="
--gn-ui-text-input-padding: 1.1em;
--gn-ui-text-input-border-size: 0px;
"
(itemSelected)="onFuzzySearchSelection($event)"
(inputSubmitted)="updateLocationFilter()"
[autoFocus]="true"
></gn-ui-fuzzy-search>
<gn-ui-location-search
class="text-[18px] grow"
style="
--gn-ui-text-input-padding: 1.1em;
--gn-ui-text-input-border-size: 0px;
"
(inputSubmitted)="updateTextFilter()"
></gn-ui-location-search>
</div>
<div class="flex h-0 py-5 gap-3" [style.opacity]="-0.6 + expandRatio * 2">
<datahub-header-badge-button
[routerLink]="ROUTE_SEARCH"
*ngIf="isAuthenticated$ | async"
Expand Down
22 changes: 21 additions & 1 deletion apps/datahub/src/app/home/home-header/home-header.component.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import {
ChangeDetectionStrategy,
Component,
Input,
ViewChild,
} from '@angular/core'
import { marker } from '@biesbjerg/ngx-translate-extract-marker'
import {
ROUTER_ROUTE_SEARCH,
RouterFacade,
} from '@geonetwork-ui/feature/router'
import {
FieldsService,
FuzzySearchComponent,
LocationSearchComponent,
SearchFacade,
SearchService,
} from '@geonetwork-ui/feature/search'
Expand Down Expand Up @@ -40,6 +47,11 @@ marker('datahub.header.popularRecords')
export class HomeHeaderComponent {
@Input() expandRatio: number

// specific geocat: used to trigger the other field when one is triggered
@ViewChild(FuzzySearchComponent)
textSearch: FuzzySearchComponent
@ViewChild(LocationSearchComponent) locationSearch: LocationSearchComponent

backgroundCss =
getThemeConfig().HEADER_BACKGROUND ||
`center /cover url('assets/img/header_bg.webp')`
Expand Down Expand Up @@ -95,4 +107,12 @@ export class HomeHeaderComponent {
this.searchService.setFilters(searchFilters)
}
}

// specific geocat
updateLocationFilter() {
this.locationSearch.trigger()
}
updateTextFilter() {
this.textSearch.trigger()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,24 @@ describe('ElasticsearchService', () => {
query: 'Org:(world)',
},
},
{
geo_shape: {
geom: {
relation: 'intersects',
shape: {
coordinates: [
[
[3.017921158755172, 50.65759907920972],
[3.017921158755172, 50.613483610573155],
[3.1098886148436122, 50.613483610573155],
[3.017921158755172, 50.65759907920972],
],
],
type: 'Polygon',
},
},
},
},
],
must: [
{
Expand Down Expand Up @@ -458,15 +476,6 @@ describe('ElasticsearchService', () => {
boost: 10.0,
},
},
{
geo_shape: {
geom: {
shape: geojsonPolygon,
relation: 'intersects',
},
boost: 7.0,
},
},
],
},
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ export class ElasticsearchService {
string,
unknown
>[]

if (any) {
must.push({
query_string: {
Expand All @@ -282,26 +281,24 @@ export class ElasticsearchService {
})
}
if (geometry) {
should.push(
{
geo_shape: {
geom: {
shape: geometry,
relation: 'within',
},
boost: 10.0,
// geocat specific: exclude records outside of geometry
should.push({
geo_shape: {
geom: {
shape: geometry,
relation: 'within',
},
boost: 10.0,
},
{
geo_shape: {
geom: {
shape: geometry,
relation: 'intersects',
},
boost: 7.0,
})
filter.push({
geo_shape: {
geom: {
shape: geometry,
relation: 'intersects',
},
}
)
},
})
}

return {
Expand Down
2 changes: 2 additions & 0 deletions libs/feature/router/src/lib/default/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ export enum ROUTE_PARAMS {
SORT = '_sort',
PUBLISHER = 'publisher', // FIXME: this shouldn't be here as it is a search field
PAGE = '_page',
LOCATION = 'location',
BBOX = 'bbox',
}
export type SearchRouteParams = Record<string, string | string[] | number>
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { FieldsService, SearchFacade } from '@geonetwork-ui/feature/search'
import {
FieldsService,
LocationBbox,
SearchFacade,
} from '@geonetwork-ui/feature/search'
import {
SortByEnum,
SortByField,
} from '@geonetwork-ui/common/domain/model/search'
import { BehaviorSubject, of } from 'rxjs'
import { RouterFacade } from '../state'
import { RouterSearchService } from './router-search.service'
import { RouterService } from '../router.service'

let state = {}
class SearchFacadeMock {
Expand All @@ -16,6 +21,7 @@ class SearchFacadeMock {
class RouterFacadeMock {
setSearch = jest.fn()
updateSearch = jest.fn()
go = jest.fn()
}

class FieldsServiceMock {
Expand Down Expand Up @@ -43,18 +49,29 @@ class FieldsServiceMock {
)
}

class RouterServiceMock {
getSearchRoute = jest.fn().mockReturnValue('/test/path')
}

describe('RouterSearchService', () => {
let service: RouterSearchService
let routerFacade: RouterFacade
let searchFacade: SearchFacade
let fieldsService: FieldsService
let routerService: RouterService

beforeEach(() => {
state = { OrgForResource: { mel: true } }
routerFacade = new RouterFacadeMock() as any
searchFacade = new SearchFacadeMock() as any
fieldsService = new FieldsServiceMock() as any
service = new RouterSearchService(searchFacade, routerFacade, fieldsService)
routerService = new RouterServiceMock() as any
service = new RouterSearchService(
searchFacade,
routerFacade,
fieldsService,
routerService
)
})

it('should be created', () => {
Expand Down Expand Up @@ -118,4 +135,40 @@ describe('RouterSearchService', () => {
})
})
})

describe('#setLocationFilter', () => {
beforeEach(() => {
const location: LocationBbox = {
label: 'New location',
bbox: [4, 5, 6, 7],
}
service.setLocationFilter(location)
})
it('dispatch setLocationFilter with merged mapped params', () => {
expect(routerFacade.go).toHaveBeenCalledWith({
path: '/test/path',
query: {
location: 'New location',
bbox: '4,5,6,7',
},
queryParamsHandling: 'merge',
})
})
})

describe('#clearLocationFilter', () => {
beforeEach(() => {
service.clearLocationFilter()
})
it('dispatch clearLocationFilter with merged mapped params', () => {
expect(routerFacade.go).toHaveBeenCalledWith({
path: '/test/path',
query: {
location: undefined,
bbox: undefined,
},
queryParamsHandling: 'merge',
})
})
})
})
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Injectable } from '@angular/core'
import {
FieldsService,
LocationBbox,
SearchFacade,
SearchServiceI,
} from '@geonetwork-ui/feature/search'
Expand All @@ -11,14 +12,16 @@ import {
import { ROUTE_PARAMS, SearchRouteParams } from '../constants'
import { RouterFacade } from '../state/router.facade'
import { firstValueFrom } from 'rxjs'
import { RouterService } from '../router.service'
import { sortByToString } from '@geonetwork-ui/util/shared'

@Injectable()
export class RouterSearchService implements SearchServiceI {
constructor(
private searchFacade: SearchFacade,
private facade: RouterFacade,
private fieldsService: FieldsService
private fieldsService: FieldsService,
private routerService: RouterService
) {}

setSortAndFilters(filters: FieldFilters, sortBy: SortByField) {
Expand Down Expand Up @@ -65,4 +68,20 @@ export class RouterSearchService implements SearchServiceI {
[ROUTE_PARAMS.PAGE]: page,
})
}

setLocationFilter(location: LocationBbox) {
this.facade.go({
path: this.routerService.getSearchRoute(),
query: { location: location.label, bbox: location.bbox.join() },
queryParamsHandling: 'merge',
})
}

clearLocationFilter() {
this.facade.go({
path: this.routerService.getSearchRoute(),
query: { location: undefined, bbox: undefined },
queryParamsHandling: 'merge',
})
}
}
Loading

0 comments on commit 7547c79

Please sign in to comment.