Skip to content

Commit

Permalink
feat(datahub): do the field name mapping in the home-header
Browse files Browse the repository at this point in the history
  • Loading branch information
jahow committed Jul 3, 2023
1 parent 814383c commit c5a8b64
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import {
RouterFacade,
ROUTER_ROUTE_SEARCH,
} from '@geonetwork-ui/feature/router'
import { SearchFacade, SearchService } from '@geonetwork-ui/feature/search'
import {
FieldsService,
SearchFacade,
SearchService,
} from '@geonetwork-ui/feature/search'
import { SortByEnum } from '@geonetwork-ui/util/shared'
import { TranslateModule } from '@ngx-translate/core'
import { readFirst } from '@nrwl/angular/testing'
import { BehaviorSubject } from 'rxjs'
import { BehaviorSubject, of } from 'rxjs'
import { ROUTER_ROUTE_NEWS } from '../../router/constants'
import { HeaderBadgeButtonComponent } from '../header-badge-button/header-badge-button.component'
import { HomeHeaderComponent } from './home-header.component'
Expand All @@ -23,14 +27,14 @@ jest.mock('@geonetwork-ui/util/app-config', () => ({
getOptionalSearchConfig: () => ({
SEARCH_PRESET: [
{
_sort: '-createDate',
sort: '-createDate',
name: 'sortCeatedDateAndOrg',
OrgForResource: ['DREAL'],
filters: { publisher: ['DREAL'] },
},
{
_sort: '-createDate',
sort: '-createDate',
name: 'filterCarto',
any: 'Cartographie',
filters: { q: 'Cartographie' },
},
],
}),
Expand Down Expand Up @@ -59,6 +63,10 @@ class AuthServiceMock {
_authSubject$ = new BehaviorSubject({})
}

class FieldsServiceMock {
buildFiltersFromFieldValues = jest.fn(() => of({ thisIs: 'a fake filter' }))
}

describe('HeaderComponent', () => {
let component: HomeHeaderComponent
let fixture: ComponentFixture<HomeHeaderComponent>
Expand Down Expand Up @@ -89,6 +97,10 @@ describe('HeaderComponent', () => {
provide: AuthService,
useClass: AuthServiceMock,
},
{
provide: FieldsService,
useClass: FieldsServiceMock,
},
],
}).compileComponents()
authService = TestBed.inject(AuthService)
Expand Down Expand Up @@ -208,7 +220,7 @@ describe('HeaderComponent', () => {
})
it('should redirect correctly', () => {
expect(searchService.setSortAndFilters).toHaveBeenCalledWith(
{ OrgForResource: { DREAL: true } },
{ thisIs: 'a fake filter' },
SortByEnum.CREATE_DATE
)
})
Expand Down
49 changes: 19 additions & 30 deletions apps/datahub/src/app/home/home-header/home-header.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@ import {
RouterFacade,
ROUTER_ROUTE_SEARCH,
} from '@geonetwork-ui/feature/router'
import { SearchFacade, SearchService } from '@geonetwork-ui/feature/search'
import {
FieldValues,
FieldsService,
SearchFacade,
SearchService,
} from '@geonetwork-ui/feature/search'
import {
getOptionalSearchConfig,
getThemeConfig,
SearchConfig,
SearchPreset,
} from '@geonetwork-ui/util/app-config'
import {
MetadataRecord,
RawCustomSearchFilters,
SearchFilters,
SortByEnum,
} from '@geonetwork-ui/util/shared'
import { MetadataRecord, SortByEnum } from '@geonetwork-ui/util/shared'
import { map } from 'rxjs/operators'
import { ROUTER_ROUTE_NEWS } from '../../router/constants'
import { lastValueFrom } from 'rxjs'

marker('datahub.header.myfavorites')
marker('datahub.header.lastRecords')
Expand All @@ -45,7 +47,8 @@ export class HomeHeaderComponent {
public routerFacade: RouterFacade,
public searchFacade: SearchFacade,
private searchService: SearchService,
private authService: AuthService
private authService: AuthService,
private fieldsService: FieldsService
) {}

displaySortBadges$ = this.routerFacade.currentRoute$.pipe(
Expand All @@ -60,25 +63,6 @@ export class HomeHeaderComponent {
.authReady()
.pipe(map((user) => !!user?.id))

private mapArrayIntoSearchFiltersObject(
customSearchParameters: RawCustomSearchFilters
): SearchFilters {
const searchFilters = {}
for (const [key, value] of Object.entries(customSearchParameters)) {
if (value instanceof Array) {
const searchFilterProperty = {}
customSearchParameters[key].forEach((element) => {
searchFilterProperty[element] = true
})
searchFilters[key] = searchFilterProperty
} else if (key === 'any' && value) {
searchFilters[key] = value
}
}

return searchFilters
}

onFuzzySearchSelection(record: MetadataRecord) {
this.routerFacade.goToMetadata(record)
}
Expand All @@ -91,10 +75,15 @@ export class HomeHeaderComponent {
this.searchService.setSortAndFilters({}, sort)
}

clearSearchAndFilterAndSort(customSearchParameters: any): void {
async clearSearchAndFilterAndSort(customSearchParameters: SearchPreset) {
const searchFilters = await lastValueFrom(
this.fieldsService.buildFiltersFromFieldValues(
customSearchParameters.filters
)
)
this.searchService.setSortAndFilters(
this.mapArrayIntoSearchFiltersObject(customSearchParameters),
customSearchParameters._sort
searchFilters,
customSearchParameters.sort as SortByEnum
)
}
}
32 changes: 21 additions & 11 deletions conf/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,31 @@ background_color = "#fdfbff"
# Note: if the GeoJSON object contains multiple features, only the geometry of the first one will be kept!
# filter_geometry_url = "https://my.domain.org/assets/boundary.geojson"
# filter_geometry_data = '{ "coordinates": [...], "type": "Polygon" }'

# One or several search presets can be defined here; every search preset is composed of:
# - a name (which can be a translation key)
# - a sort criteria: either `createDate`, `userSavedCount` or `_score` (prepend with `-` for descending sort)
# - filters which can be expressed like so:
# [[search_preset]]
# filters.q = 'Full text search
# filters.publisher = ['Org 1', 'Org 2']
# filters.format = ['format 1', 'format 2']
# filters.documentStandard = ['iso19115-3.2018']
# filters.inspireKeyword = ['keyword 1', 'keyword 2']
# filters.topic = ['boundaries']
# filters.publicationYear = ['2023', '2022']
# filters.isSpatial = ['yes']
# filters.license = ['unknown']
#
# Search presets will be advertised to the user along the main search field.

# [[search_preset]]
# _sort = "-createDate"
# sort = "-createDate"
# name = 'filterByOrgs'
# any = 'Carto'
# organisation = ['DREAL', 'atmo Hauts-de-France']
# format = ['ESRI Shapefile']
# standard = ['iso19115-3.2018']
# #inspireKeyword = []
# topic = ['boundaries']
# publicationYear = ['2023', '2022']
# spatial = ['yes']
# license = ['unknown']
# filters.publisher = ['DREAL', 'atmo Hauts-de-France', 'blargz']
# [[search_preset]]
# name = 'Wind turbines'
# any = 'wind'
# filters.q = 'wind'

### MAP SETTINGS

Expand Down
4 changes: 2 additions & 2 deletions libs/feature/search/src/lib/utils/service/fields.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
SimpleSearchField,
TopicSearchField,
} from './fields'
import { combineLatest, forkJoin, Observable, of, takeLast } from 'rxjs'
import { map, mergeScan } from 'rxjs/operators'
import { forkJoin, Observable, of } from 'rxjs'
import { map } from 'rxjs/operators'

// key is the field name
export type FieldValues = Record<string, FieldValue[] | FieldValue>
Expand Down
16 changes: 9 additions & 7 deletions libs/util/app-config/src/lib/app-config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,15 @@ describe('app config utils', () => {
SEARCH_PRESET: [
{
name: 'filterByOrgs',
_sort: '-createDate',
any: 'Carto',
OrgForResource: ['Org1', 'Org2'],
'cl_topic.key': ['boundaries'],
format: ['ESRI Shapefile'],
isSpatial: ['yes'],
publicationYearForResource: ['2023', '2022'],
sort: '-createDate',
filters: {
q: 'Carto',
organisation: ['Org1', 'Org2'],
topic: ['boundaries'],
format: ['ESRI Shapefile'],
spatial: ['yes'],
publicationYear: ['2023', '2022'],
},
},
],
})
Expand Down
46 changes: 16 additions & 30 deletions libs/util/app-config/src/lib/app-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
SearchConfig,
ThemeConfig,
} from './model'
import { RawCustomSearchFilters } from '@geonetwork-ui/util/shared'

const MISSING_CONFIG_ERROR = `Application configuration was not initialized correctly.
This error might show up in case of an invalid/malformed configuration file.
Expand Down Expand Up @@ -199,18 +198,7 @@ export function loadAppConfig() {
parsed,
'search_preset',
['name'],
[
'_sort',
'any',
'organisation',
'format',
'standard',
'inspireKeyword',
'topic',
'publicationYear',
'spatial',
'license',
],
['sort', 'filters'],
warnings,
errors
)
Expand All @@ -220,23 +208,21 @@ export function loadAppConfig() {
: ({
FILTER_GEOMETRY_DATA: parsedSearchSection.filter_geometry_data,
FILTER_GEOMETRY_URL: parsedSearchSection.filter_geometry_url,
SEARCH_PRESET: parsedSearchParams.map(
(param) =>
({
_sort: param._sort,
name: param.name,
any: param.any,
OrgForResource: param.organisation,
format: param.format,
documentStandard: param.standard,
'th_httpinspireeceuropaeutheme-theme_tree.default':
param.inspireKeyword,
'cl_topic.key': param.topic,
publicationYearForResource: param.publicationYear,
isSpatial: param.spatial,
license: param.license,
} as RawCustomSearchFilters)
),
SEARCH_PRESET: parsedSearchParams.map((param) => ({
sort: param.sort,
name: param.name,
filters: param.filters,
// any: param.any,
// OrgForResource: param.organisation,
// format: param.format,
// documentStandard: param.standard,
// 'th_httpinspireeceuropaeutheme-theme_tree.default':
// param.inspireKeyword,
// 'cl_topic.key': param.topic,
// publicationYearForResource: param.publicationYear,
// isSpatial: param.spatial,
// license: param.license,
})),
} as any)

customTranslations = parseTranslationsConfigSection(
Expand Down
14 changes: 7 additions & 7 deletions libs/util/app-config/src/lib/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ fonts_stylesheet_url = "https://fonts.googleapis.com/css2?family=Open+Sans"
filter_geometry_url = 'https://my.domain.org/geom.json'
[[search_preset]]
_sort = "-createDate"
sort = "-createDate"
name = 'filterByOrgs'
any = 'Carto'
organisation = ['Org1', 'Org2']
format = ['ESRI Shapefile']
topic = ['boundaries']
publicationYear = ['2023', '2022']
spatial = ['yes']
filters.q = 'Carto'
filters.organisation = ['Org1', 'Org2']
filters.format = ['ESRI Shapefile']
filters.topic = ['boundaries']
filters.publicationYear = ['2023', '2022']
filters.spatial = ['yes']
[translations.en]
"my.first.key" = 'First label.'
Expand Down
12 changes: 7 additions & 5 deletions libs/util/app-config/src/lib/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,16 @@ export interface ThemeConfig {
FONTS_STYLESHEET_URL?: string
}

export interface SearchPreset {
sort: string
name: string
filters: Record<string, string[] | string>
}

export interface SearchConfig {
FILTER_GEOMETRY_URL?: string
FILTER_GEOMETRY_DATA?: string
SEARCH_PRESET?: {
_sort: string
_filters: unknown
name: string
}[]
SEARCH_PRESET?: SearchPreset[]
}

export type CustomTranslations = { [translationKey: string]: string }
Expand Down
2 changes: 1 addition & 1 deletion libs/util/app-config/src/lib/parse-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function parseConfigSection(
return null
}

const sectionConf = flatten('', fullConfigObj[sectionName])
const sectionConf = fullConfigObj[sectionName] as Record<string, string>
const keysCheck = checkKeys(sectionConf, mandatoryKeys, optionalKeys)

if (keysCheck.missing.length) {
Expand Down

0 comments on commit c5a8b64

Please sign in to comment.