Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(platform-service): Exclude place thesarus keywords #915

Merged
merged 3 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions libs/api/repository/src/lib/gn4/platform/gn4-platform.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,151 @@ describe('Gn4PlatformService', () => {
})
})
})
describe('#searchKeywords', () => {
beforeEach(() => {
jest.spyOn(service, 'searchKeywords')
})
it('calls api service with qeury', () => {
service.searchKeywords('road', ['theme']).subscribe()
expect(registriesApiService.searchKeywords).toHaveBeenCalledWith(
'road',
'fre',
10,
0,
null,
['external.theme.httpinspireeceuropaeutheme-theme'],
null,
'*road*'
)
})
it('returns mapped thesaurus with translated values', async () => {
const keywords = await lastValueFrom(
service.searchKeywords('road', ['theme'])
)
expect(keywords).toEqual([
{
description:
'Localisation des propriétés fondée sur les identifiants des adresses, habituellement le nom de la rue, le numéro de la maison et le code postal.',
key: 'http://inspire.ec.europa.eu/theme/ad',
label: 'Adresses',
thesaurus: {
id: 'external.theme.httpinspireeceuropaeutheme-theme',
name: 'GEMET - INSPIRE themes, version 1.0',
type: 'theme',
url: new URL(
'http://localhost:8080/geonetwork/srv/api/registries/vocabularies/external.theme.httpinspireeceuropaeutheme-theme'
),
},
type: 'theme',
},
{
description:
"Modèles numériques pour l'altitude des surfaces terrestres, glaciaires et océaniques. Comprend l'altitude terrestre, la bathymétrie et la ligne de rivage.",
key: 'http://inspire.ec.europa.eu/theme/el',
label: 'Altitude',
thesaurus: {
id: 'external.theme.httpinspireeceuropaeutheme-theme',
name: 'GEMET - INSPIRE themes, version 1.0',
type: 'theme',
url: new URL(
'http://localhost:8080/geonetwork/srv/api/registries/vocabularies/external.theme.httpinspireeceuropaeutheme-theme'
),
},
type: 'theme',
},
])
})
describe('if translations are unavailable', () => {
it('uses default values', async () => {
service['langService']['iso3'] = 'ger'
const keywords = await lastValueFrom(
service.searchKeywords('road', ['theme'])
)
expect(keywords).toEqual([
{
description: 'localization of properties',
key: 'http://inspire.ec.europa.eu/theme/ad',
label: 'addresses',
thesaurus: {
id: 'external.theme.httpinspireeceuropaeutheme-theme',
name: 'GEMET - INSPIRE themes, version 1.0',
type: 'theme',
url: new URL(
'http://localhost:8080/geonetwork/srv/api/registries/vocabularies/external.theme.httpinspireeceuropaeutheme-theme'
),
},
type: 'theme',
},
{
description: 'digital terrain models',
key: 'http://inspire.ec.europa.eu/theme/el',
label: 'altitude',
thesaurus: {
id: 'external.theme.httpinspireeceuropaeutheme-theme',
name: 'GEMET - INSPIRE themes, version 1.0',
type: 'theme',
url: new URL(
'http://localhost:8080/geonetwork/srv/api/registries/vocabularies/external.theme.httpinspireeceuropaeutheme-theme'
),
},
type: 'theme',
},
])
})
})
describe('if keywordType is empty Array', () => {
it('calls api service with empty array and returns keywords from all thesauri', async () => {
service.searchKeywords('road', ['theme']).subscribe()
const keywords = await lastValueFrom(
service.searchKeywords('road', ['theme'])
)

expect(registriesApiService.searchKeywords).toHaveBeenCalledWith(
'road',
'fre',
10,
0,
null,
['external.theme.httpinspireeceuropaeutheme-theme'],
null,
'*road*'
)

expect(keywords).toEqual([
{
description:
'Localisation des propriétés fondée sur les identifiants des adresses, habituellement le nom de la rue, le numéro de la maison et le code postal.',
key: 'http://inspire.ec.europa.eu/theme/ad',
label: 'Adresses',
thesaurus: {
id: 'external.theme.httpinspireeceuropaeutheme-theme',
name: 'GEMET - INSPIRE themes, version 1.0',
type: 'theme',
url: new URL(
'http://localhost:8080/geonetwork/srv/api/registries/vocabularies/external.theme.httpinspireeceuropaeutheme-theme'
),
},
type: 'theme',
},
{
description:
"Modèles numériques pour l'altitude des surfaces terrestres, glaciaires et océaniques. Comprend l'altitude terrestre, la bathymétrie et la ligne de rivage.",
key: 'http://inspire.ec.europa.eu/theme/el',
label: 'Altitude',
thesaurus: {
id: 'external.theme.httpinspireeceuropaeutheme-theme',
name: 'GEMET - INSPIRE themes, version 1.0',
type: 'theme',
url: new URL(
'http://localhost:8080/geonetwork/srv/api/registries/vocabularies/external.theme.httpinspireeceuropaeutheme-theme'
),
},
type: 'theme',
},
])
})
})
})
describe('#getKeywordsByUri', () => {
it('calls api service ', async () => {
service.getKeywordsByUri('http://inspire.ec.europa.eu/theme/')
Expand Down
41 changes: 26 additions & 15 deletions libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
MeApiService,
RegistriesApiService,
SiteApiService,
ThesaurusInfoApiModel,
ToolsApiService,
UserfeedbackApiService,
UsersApiService,
Expand All @@ -25,6 +24,7 @@ import {
KeywordApiResponse,
ThesaurusApiResponse,
} from '@geonetwork-ui/api/metadata-converter'
import { KeywordType } from '@geonetwork-ui/common/domain/model/thesaurus'

const minApiVersion = '4.2.2'

Expand Down Expand Up @@ -146,25 +146,36 @@ export class Gn4PlatformService implements PlatformServiceInterface {
)
.pipe(
map((thesaurus) => {
// FIXME: find a better way to exclude place keywords
// thesaurus[0].filter((thes) => thes.dname !== 'place')
return thesaurus[0] as ThesaurusApiResponse[]
}),
shareReplay(1)
)

searchKeywords(query: string): Observable<Keyword[]> {
const keywords$: Observable<KeywordApiResponse[]> =
this.registriesApiService.searchKeywords(
query,
this.langService.iso3,
10,
0,
null,
null,
null,
`*${query}*`
) as Observable<KeywordApiResponse[]>
searchKeywords(
query: string,
keywordTypes: KeywordType[]
): Observable<Keyword[]> {
const keywords$: Observable<KeywordApiResponse[]> = this.allThesaurus$.pipe(
switchMap((thesaurus) => {
const selectedThesauri = []
keywordTypes.map((keywordType) => {
selectedThesauri.push(
...thesaurus.filter((thes) => thes.dname === keywordType)
)
})

return this.registriesApiService.searchKeywords(
query,
this.langService.iso3,
10,
0,
null,
selectedThesauri.map((thes) => thes.key),
null,
`*${query}*`
) as Observable<KeywordApiResponse[]>
})
)

return combineLatest([keywords$, this.allThesaurus$]).pipe(
map(([keywords, thesaurus]) => {
Expand Down
6 changes: 5 additions & 1 deletion libs/common/domain/src/lib/platform.service.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Observable } from 'rxjs'
import type { UserModel } from './model/user/user.model'
import type { Organization } from './model/record/organization.model'
import { Keyword, UserFeedback } from './model/record'
import { KeywordType } from './model/thesaurus'

export abstract class PlatformServiceInterface {
abstract getType(): string
Expand All @@ -15,7 +16,10 @@ export abstract class PlatformServiceInterface {
): Observable<UserModel[]>
abstract getOrganizations(): Observable<Organization[]>
abstract translateKey(key: string): Observable<string>
abstract searchKeywords(query: string): Observable<Keyword[]>
abstract searchKeywords(
query: string,
keywordTypes: KeywordType[]
): Observable<Keyword[]>
abstract getKeywordsByUri(uri: string): Observable<Keyword[]>
abstract getUserFeedbacks(recordUuid: string): Observable<UserFeedback[]>
abstract postUserFeedbacks(recordUuid: UserFeedback): Observable<void>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ export class FormFieldKeywordsComponent {
}

autoCompleteAction = (query: string) => {
return this.platformService.searchKeywords(query).pipe(
map((keywords) =>
keywords.map((keyword) => {
return { title: keyword.label, value: keyword }
})
return this.platformService
.searchKeywords(query, ['temporal', 'theme', 'other'])
.pipe(
map((keywords) =>
keywords.map((keyword) => {
return { title: keyword.label, value: keyword }
})
)
)
)
}

constructor(private platformService: PlatformServiceInterface) {}
Expand Down
11 changes: 5 additions & 6 deletions translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"Add Layer As": "",
"button.login": "",
"catalog.figures.datasets": "{count, plural, =0{Datensätze} one{Datensatz} other{Datensätze}}",
"catalog.figures.organizations": "{count, plural, =0{Organisationen} one{Organisation} other{Organisationen}}",
"catalog.figures.organisations": "{count, plural, =0{Organisationen} one{Organisation} other{Organisationen}}",
"chart.aggregation.average": "Durchschnitt",
"chart.aggregation.count": "Anzahl",
"chart.aggregation.max": "Maximum",
Expand Down Expand Up @@ -153,6 +153,7 @@
"downloads.format.unknown": "unbekannt",
"downloads.wfs.featuretype.not.found": "Der Layer wurde nicht gefunden",
"dropFile": "Datei ablegen",
"editor.record.form.keywords": "Schlagwörter",
"editor.record.form.license": "Lizenz",
"editor.record.form.license.cc-by": "",
"editor.record.form.license.cc-by-sa": "",
Expand Down Expand Up @@ -252,10 +253,8 @@
"organisations.sortBy.nameDesc": "Name Z → A",
"organisations.sortBy.recordCountAsc": "Veröffentlichungen 0 → 9",
"organisations.sortBy.recordCountDesc": "Veröffentlichungen 9 → 0",
"organization.header.recordCount": "{count, plural, =0{} one{} other{}}",
"organization.details.publishedDataset": "{count, plural, =0{} one{} other{}}",
"organization.details.mailContact": "",
"organization.datasets": "",
"organization.header.recordCount": "{count, plural, =0{} one{} other{}}",
"organization.lastPublishedDatasets": "",
"organization.lastPublishedDatasets.searchAllButton": "",
"pagination.nextPage": "Nächste Seite",
Expand Down Expand Up @@ -355,11 +354,11 @@
"results.sortBy.relevancy": "Relevanz",
"search.autocomplete.error": "Vorschläge konnten nicht abgerufen werden:",
"search.error.couldNotReachApi": "Die API konnte nicht erreicht werden",
"search.error.organizationHasNoDataset": "",
"search.error.organizationNotFound": "",
"search.error.receivedError": "Ein Fehler ist aufgetreten",
"search.error.recordHasnolink": "",
"search.error.recordNotFound": "Der Datensatz mit der Kennung \"{ id }\" konnte nicht gefunden werden.",
"search.error.organizationNotFound": "",
"search.error.organizationHasNoDataset": "",
"search.field.any.placeholder": "Suche Datensätze ...",
"search.field.sortBy": "Sortieren nach:",
"search.filters.clear": "Zurücksetzen",
Expand Down
11 changes: 5 additions & 6 deletions translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"Add Layer As": "",
"button.login": "Log in",
"catalog.figures.datasets": "{count, plural, =0{datasets} one{dataset} other{datasets}}",
"catalog.figures.organizations": "{count, plural, =0{organisations} one{organisation} other{organisations}}",
"catalog.figures.organisations": "",
"chart.aggregation.average": "average",
"chart.aggregation.count": "count",
"chart.aggregation.max": "max",
Expand Down Expand Up @@ -153,6 +153,7 @@
"downloads.format.unknown": "unknown",
"downloads.wfs.featuretype.not.found": "The layer was not found",
"dropFile": "drop file",
"editor.record.form.keywords": "Keywords",
"editor.record.form.license": "License",
"editor.record.form.license.cc-by": "Creative Commons CC-BY",
"editor.record.form.license.cc-by-sa": "Creative Commons CC-BY-SA",
Expand Down Expand Up @@ -252,10 +253,8 @@
"organisations.sortBy.nameDesc": "Name Z → A",
"organisations.sortBy.recordCountAsc": "Publications 0 → 9",
"organisations.sortBy.recordCountDesc": "Publications 9 → 0",
"organization.header.recordCount": "{count, plural, =0{data} one{data} other{datas}}",
"organization.details.publishedDataset": "{count, plural, =0{published dataset} one{published dataset} other{published datasets}}",
"organization.details.mailContact": "Contact by email",
"organization.datasets": "Datasets",
"organization.header.recordCount": "{count, plural, =0{data} one{data} other{datas}}",
"organization.lastPublishedDatasets": "Last published datasets",
"organization.lastPublishedDatasets.searchAllButton": "Search all",
"pagination.nextPage": "Next page",
Expand Down Expand Up @@ -355,11 +354,11 @@
"results.sortBy.relevancy": "Relevancy",
"search.autocomplete.error": "Suggestions could not be fetched:",
"search.error.couldNotReachApi": "The API could not be reached",
"search.error.organizationHasNoDataset": "This organization has no dataset yet.",
"search.error.organizationNotFound": "This organization could not be found.",
"search.error.receivedError": "An error was received",
"search.error.recordHasnolink": "This record currently has no link yet, please come back later.",
"search.error.recordNotFound": "The record with identifier \"{ id }\" could not be found.",
"search.error.organizationNotFound": "This organization could not be found.",
"search.error.organizationHasNoDataset": "This organization has no dataset yet.",
"search.field.any.placeholder": "Search datasets ...",
"search.field.sortBy": "Sort by:",
"search.filters.clear": "Reset",
Expand Down
11 changes: 5 additions & 6 deletions translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"Add Layer As": "",
"button.login": "",
"catalog.figures.datasets": "conjuntos de datos",
"catalog.figures.organizations": "organizaciones",
"catalog.figures.organisations": "",
"chart.aggregation.average": "promedio",
"chart.aggregation.count": "conteo",
"chart.aggregation.max": "máximo",
Expand Down Expand Up @@ -153,6 +153,7 @@
"downloads.format.unknown": "",
"downloads.wfs.featuretype.not.found": "",
"dropFile": "",
"editor.record.form.keywords": "",
"editor.record.form.license": "",
"editor.record.form.license.cc-by": "",
"editor.record.form.license.cc-by-sa": "",
Expand Down Expand Up @@ -252,10 +253,8 @@
"organisations.sortBy.nameDesc": "",
"organisations.sortBy.recordCountAsc": "",
"organisations.sortBy.recordCountDesc": "",
"organization.header.recordCount": "{count, plural, =0{} one{} other{}}",
"organization.details.publishedDataset": "{count, plural, =0{} one{} other{{}}",
"organization.details.mailContact": "",
"organization.datasets": "",
"organization.header.recordCount": "{count, plural, =0{} one{} other{}}",
"organization.lastPublishedDatasets": "",
"organization.lastPublishedDatasets.searchAllButton": "",
"pagination.nextPage": "",
Expand Down Expand Up @@ -355,11 +354,11 @@
"results.sortBy.relevancy": "",
"search.autocomplete.error": "",
"search.error.couldNotReachApi": "",
"search.error.organizationHasNoDataset": "",
"search.error.organizationNotFound": "",
"search.error.receivedError": "",
"search.error.recordHasnolink": "",
"search.error.recordNotFound": "",
"search.error.organizationNotFound": "",
"search.error.organizationHasNoDataset": "",
"search.field.any.placeholder": "",
"search.field.sortBy": "",
"search.filters.clear": "",
Expand Down
Loading
Loading