Skip to content

Commit

Permalink
Merge pull request #593 from geonetwork/better-i18n-handling
Browse files Browse the repository at this point in the history
Adding i18n to records
  • Loading branch information
f-necas authored Sep 1, 2023
2 parents 421a373 + 7633dc9 commit a79eb32
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 33 deletions.
21 changes: 13 additions & 8 deletions libs/api/metadata-converter/src/lib/gn4/atomic-operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ export const selectFallback = <T, U>(field: T, fallback: U): T | U =>
field === null ? fallback : field

export const selectTranslatedValue = <T>(
source: SourceWithUnknownProps
): T | null => selectField(source, 'default')
source: SourceWithUnknownProps,
lang3: string
): T | null =>
selectFallback(selectField(source, lang3), selectField(source, 'default'))

export const selectTranslatedField = <T>(
source: SourceWithUnknownProps,
fieldName: string
): T | null => selectTranslatedValue(selectField(source, fieldName))
fieldName: string,
lang3: string
): T | null => selectTranslatedValue(selectField(source, fieldName), lang3)

export const toDate = (field) => new Date(field)

Expand Down Expand Up @@ -59,13 +62,14 @@ export const mapLogo = (source: SourceWithUnknownProps) => {
}

export const mapOrganization = (
sourceContact: SourceWithUnknownProps
sourceContact: SourceWithUnknownProps,
lang3: string
): Organization => {
const website = getAsUrl(selectField<string>(sourceContact, 'website'))
const logoUrl = getAsUrl(selectField<string>(sourceContact, 'logo'))
return {
name: selectFallback(
selectTranslatedField<string>(sourceContact, 'organisationObject'),
selectTranslatedField<string>(sourceContact, 'organisationObject', lang3),
selectField<string>(sourceContact, 'organisation')
),
...(logoUrl && { logoUrl }),
Expand All @@ -74,13 +78,14 @@ export const mapOrganization = (
}

export const mapContact = (
sourceContact: SourceWithUnknownProps
sourceContact: SourceWithUnknownProps,
lang3: string
): Individual => {
const address = selectField<string>(sourceContact, 'address')
const phone = selectField<string>(sourceContact, 'phone')
return {
lastName: selectField<string>(sourceContact, 'individual'),
organization: mapOrganization(sourceContact),
organization: mapOrganization(sourceContact, lang3),
email: selectField<string>(sourceContact, 'email'),
role: getRoleFromRoleCode(selectField<string>(sourceContact, 'role')),
...(address && { address }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,28 @@ import { TestBed } from '@angular/core/testing'
import { ES_LINK_FIXTURES } from '@geonetwork-ui/common/fixtures'
import { Gn4FieldMapper } from './gn4.field.mapper'
import { MetadataUrlService } from './metadata-url.service'
import { TranslateService } from '@ngx-translate/core'

class MetadataUrlServiceMock {
translate = undefined
getUrl = () => 'url'
}

const translateServiceMock = {
currentLang: 'de',
}

describe('Gn4FieldMapper', () => {
let service: Gn4FieldMapper

beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{ provide: MetadataUrlService, useClass: MetadataUrlServiceMock },
{
provide: TranslateService,
useValue: translateServiceMock,
},
],
})
service = TestBed.inject(Gn4FieldMapper)
Expand Down
42 changes: 28 additions & 14 deletions libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
OnlineLinkResource,
} from '@geonetwork-ui/common/domain/record'
import { matchProtocol } from '../common/distribution.mapper'
import { LangService } from '@geonetwork-ui/util/i18n'

type ESResponseSource = SourceWithUnknownProps

Expand All @@ -37,7 +38,12 @@ type EsFieldMapperFn = (
providedIn: 'root',
})
export class Gn4FieldMapper {
constructor(private metadataUrlService: MetadataUrlService) {}
constructor(
private metadataUrlService: MetadataUrlService,
private langService: LangService
) {}

private lang3 = this.langService.gnLang

protected fields: Record<string, EsFieldMapperFn> = {
id: (output, source) =>
Expand All @@ -50,21 +56,22 @@ export class Gn4FieldMapper {
resourceTitleObject: (output, source) => ({
...output,
title: selectFallback(
selectTranslatedField(source, 'resourceTitleObject'),
selectTranslatedField(source, 'resourceTitleObject', this.lang3),
'no title'
),
}),
resourceAbstractObject: (output, source) => ({
...output,
abstract: selectFallback(
selectTranslatedField(source, 'resourceAbstractObject'),
selectTranslatedField(source, 'resourceAbstractObject', this.lang3),
'no title'
),
}),
overview: (output, source) => {
const firstOverview = getFirstValue(selectField(source, 'overview'))
const description = selectTranslatedValue<string>(
selectField(firstOverview, 'text')
selectField(firstOverview, 'text'),
this.lang3
)
return {
...output,
Expand Down Expand Up @@ -121,7 +128,9 @@ export class Gn4FieldMapper {
},
contact: (output, source) => ({
...output,
contacts: [mapContact(getFirstValue(selectField(source, 'contact')))],
contacts: [
mapContact(getFirstValue(selectField(source, 'contact')), this.lang3),
],
}),
contactForResource: (output, source) => ({
...output,
Expand All @@ -131,7 +140,7 @@ export class Gn4FieldMapper {
? output.contactsForResource
: []),
...getAsArray(selectField(source, 'contactForResource')).map(
(contact) => mapContact(contact)
(contact) => mapContact(contact, this.lang3)
),
],
}),
Expand All @@ -150,7 +159,7 @@ export class Gn4FieldMapper {
...output,
keywords: getAsArray(
selectField<SourceWithUnknownProps[]>(source, 'tag')
).map((tag) => selectTranslatedValue<string>(tag)),
).map((tag) => selectTranslatedValue<string>(tag, this.lang3)),
}),
inspireTheme: (output, source) => ({
...output,
Expand Down Expand Up @@ -183,14 +192,14 @@ export class Gn4FieldMapper {
).map((license) => {
const link = getAsUrl(selectField(license, 'link'))
return {
text: selectTranslatedValue<string>(license),
text: selectTranslatedValue<string>(license, this.lang3),
...(link ? { link } : {}),
}
}),
}),
lineageObject: (output, source) => ({
...output,
lineage: selectTranslatedField(source, 'lineageObject'),
lineage: selectTranslatedField(source, 'lineageObject', this.lang3),
}),
mainLanguage: (output) => output,
userSavedCount: (output, source) =>
Expand Down Expand Up @@ -243,7 +252,8 @@ export class Gn4FieldMapper {
useLimitations: [
...(output.useLimitations || []),
...selectField<SourceWithUnknownProps[]>(source, fieldName).map(
selectTranslatedValue
(source: SourceWithUnknownProps) =>
selectTranslatedValue(source, this.lang3)
),
],
}
Expand All @@ -252,7 +262,7 @@ export class Gn4FieldMapper {
...(output.accessConstraints || []),
...selectField<SourceWithUnknownProps[]>(source, fieldName).map(
(field) => ({
text: selectTranslatedValue(field),
text: selectTranslatedValue(field, this.lang3),
type: this.getConstraintsType(fieldName),
})
),
Expand Down Expand Up @@ -299,16 +309,20 @@ export class Gn4FieldMapper {
): DatasetDistribution | null => {
const url = getAsUrl(
selectFallback(
selectTranslatedField<string>(sourceLink, 'urlObject'),
selectTranslatedField<string>(sourceLink, 'urlObject', this.lang3),
selectField<string>(sourceLink, 'url')
)
)
const name = selectFallback(
selectTranslatedField<string>(sourceLink, 'nameObject'),
selectTranslatedField<string>(sourceLink, 'nameObject', this.lang3),
selectField<string>(sourceLink, 'name')
)
const description = selectFallback(
selectTranslatedField<string>(sourceLink, 'descriptionObject'),
selectTranslatedField<string>(
sourceLink,
'descriptionObject',
this.lang3
),
selectField<string>(sourceLink, 'description')
)
// no url: fail early
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
CatalogRecord,
DatasetRecord,
} from '@geonetwork-ui/common/domain/record'
import { TranslateService } from '@ngx-translate/core'

class MetadataUrlServiceMock {
translate = undefined
Expand All @@ -31,6 +32,10 @@ class OrganisationsServiceMock {
)
}

const translateServiceMock = {
currentLang: 'de',
}

describe('Gn4MetadataMapper', () => {
let service: Gn4MetadataMapper

Expand All @@ -46,6 +51,10 @@ describe('Gn4MetadataMapper', () => {
provide: OrganizationsServiceInterface,
useClass: OrganisationsServiceMock,
},
{
provide: TranslateService,
useValue: translateServiceMock,
},
],
})
})
Expand Down Expand Up @@ -634,7 +643,7 @@ describe('Gn4MetadataMapper', () => {
updatedTimes: 1,
},
useLimitations: [
'Restriction lié à l’exercice du droit moral',
'Einschränkung im Zusammenhang mit der Ausübung moralischer Rechte',
"Restriction légale d'utilisation à préciser",
],
spatialExtents: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ES_FIXTURE_FULL_RESPONSE,
GROUPS_FIXTURE,
} from '@geonetwork-ui/common/fixtures'
import { LangService } from '@geonetwork-ui/util/i18n'

const sampleOrgA: Organization = {
description: 'A description for ARE',
Expand Down Expand Up @@ -152,6 +153,10 @@ class SiteApiServiceMock {
)
}

class LangServiceMock {
gnLang = jest.fn(() => 'langger')
}

describe.each(['4.2.2-00', '4.2.3-xx', '4.2.5-xx'])(
'OrganizationsFromMetadataService (gn v%s)',
(gnVersion) => {
Expand All @@ -178,6 +183,10 @@ describe.each(['4.2.2-00', '4.2.3-xx', '4.2.5-xx'])(
provide: SiteApiService,
useClass: SiteApiServiceMock,
},
{
provide: LangService,
useClass: LangServiceMock,
},
],
})
service = TestBed.inject(OrganizationsFromMetadataService)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from '@geonetwork-ui/api/metadata-converter'
import { combineLatest, Observable, of, switchMap, takeLast } from 'rxjs'
import { filter, map, shareReplay, startWith, tap } from 'rxjs/operators'
import { LangService } from '@geonetwork-ui/util/i18n'

const IMAGE_URL = '/geonetwork/images/harvesting/'

Expand Down Expand Up @@ -114,9 +115,12 @@ export class OrganizationsFromMetadataService
private esService: ElasticsearchService,
private searchApiService: SearchApiService,
private groupsApiService: GroupsApiService,
private siteApiService: SiteApiService
private siteApiService: SiteApiService,
private langService: LangService
) {}

private lang3 = this.langService.gnLang

equalsNormalizedStrings(
str1: string,
str2: string,
Expand Down Expand Up @@ -276,19 +280,19 @@ export class OrganizationsFromMetadataService
): Observable<CatalogRecord> {
const contacts: SourceWithUnknownProps[] = getAsArray(
selectFallback(
selectTranslatedField(source, 'contactObject'),
selectTranslatedField(source, 'contactObject', this.lang3),
selectField(source, 'contact')
)
)
const resourceContacts: SourceWithUnknownProps[] = getAsArray(
selectFallback(
selectTranslatedField(source, 'contactForResourceObject'),
selectTranslatedField(source, 'contactForResourceObject', this.lang3),
selectField(source, 'contactForResource')
)
)
const allContactOrgs = resourceContacts
.concat(contacts)
.map((contact) => mapOrganization(contact))
.map((contact) => mapOrganization(contact, this.lang3))

if (!allContactOrgs.length) return of(record)

Expand Down
2 changes: 2 additions & 0 deletions libs/common/fixtures/src/lib/elasticsearch/full-response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,8 @@ export const ES_FIXTURE_FULL_RESPONSE = deepFreeze({
{
default: 'Restriction lié à l’exercice du droit moral',
langfre: 'Restriction lié à l’exercice du droit moral',
langger:
'Einschränkung im Zusammenhang mit der Ausübung moralischer Rechte',
},
],
geom: {
Expand Down
13 changes: 8 additions & 5 deletions libs/feature/catalog/src/lib/feature-catalog.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ import {
} from '@geonetwork-ui/data-access/gn4'
import { CommonModule } from '@angular/common'
import { SourceLabelComponent } from './source-label/source-label.component'
import { UtilI18nModule } from '@geonetwork-ui/util/i18n'
import { LangService, UtilI18nModule } from '@geonetwork-ui/util/i18n'
import { OrganisationsComponent } from './organisations/organisations.component'
import { UiLayoutModule } from '@geonetwork-ui/ui/layout'
import { TranslateModule, TranslateService } from '@ngx-translate/core'
import { UiElementsModule } from '@geonetwork-ui/ui/elements'
import { OrganizationsServiceInterface } from '@geonetwork-ui/common/domain/organizations.service.interface'
import {
OrganizationsFromMetadataService,
ElasticsearchService,
ORGANIZATIONS_STRATEGY,
OrganizationsFromGroupsService,
OrganizationsFromMetadataService,
OrganizationsStrategy,
ElasticsearchService,
} from '@geonetwork-ui/api/repository/gn4'

// expects the replacement key ${name}
Expand All @@ -34,7 +34,8 @@ const organizationsServiceFactory = (
searchApiService: SearchApiService,
groupsApiService: GroupsApiService,
translateService: TranslateService,
siteApiService: SiteApiService
siteApiService: SiteApiService,
langService: LangService
) =>
strategy === 'groups'
? new OrganizationsFromGroupsService(
Expand All @@ -47,7 +48,8 @@ const organizationsServiceFactory = (
esService,
searchApiService,
groupsApiService,
siteApiService
siteApiService,
langService
)

@NgModule({
Expand Down Expand Up @@ -77,6 +79,7 @@ const organizationsServiceFactory = (
GroupsApiService,
TranslateService,
SiteApiService,
LangService,
],
},
],
Expand Down
Loading

0 comments on commit a79eb32

Please sign in to comment.