geonetwork-ui 2.2.0-dev.95b40cd8 → 2.2.0-dev.9f0a89f5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/gn4/atomic-operations.mjs +27 -1
  2. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.mjs +8 -8
  3. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.mjs +2 -2
  4. package/esm2022/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.mjs +1 -1
  5. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/codelists/keyword.mapper.mjs +14 -0
  6. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/converter.mjs +7 -9
  7. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +30 -8
  8. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +31 -14
  9. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
  10. package/esm2022/libs/feature/search/src/lib/favorites/favorite-star/favorite-star.component.mjs +3 -3
  11. package/esm2022/libs/ui/catalog/src/lib/language-switcher/language-switcher.component.mjs +3 -3
  12. package/esm2022/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.mjs +3 -3
  13. package/esm2022/libs/ui/elements/src/lib/metadata-info/metadata-info.component.mjs +7 -7
  14. package/esm2022/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.mjs +2 -2
  15. package/esm2022/libs/ui/elements/src/lib/thumbnail/thumbnail.component.mjs +3 -3
  16. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +4 -4
  17. package/esm2022/libs/ui/inputs/src/lib/button/button.component.mjs +3 -3
  18. package/esm2022/libs/ui/inputs/src/lib/navigation-button/navigation-button.component.mjs +3 -3
  19. package/esm2022/libs/ui/inputs/src/lib/text-area/text-area.component.mjs +3 -3
  20. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +6 -6
  21. package/esm2022/translations/de.json +1 -1
  22. package/esm2022/translations/en.json +1 -1
  23. package/esm2022/translations/es.json +1 -1
  24. package/esm2022/translations/fr.json +1 -1
  25. package/esm2022/translations/it.json +1 -1
  26. package/esm2022/translations/nl.json +1 -1
  27. package/esm2022/translations/pt.json +1 -1
  28. package/fesm2022/geonetwork-ui.mjs +152 -77
  29. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  30. package/libs/api/metadata-converter/src/lib/gn4/atomic-operations.d.ts +2 -0
  31. package/libs/api/metadata-converter/src/lib/gn4/atomic-operations.d.ts.map +1 -1
  32. package/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.d.ts.map +1 -1
  33. package/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.d.ts +3 -5
  34. package/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.d.ts.map +1 -1
  35. package/libs/api/metadata-converter/src/lib/iso19139/codelists/keyword.mapper.d.ts +3 -0
  36. package/libs/api/metadata-converter/src/lib/iso19139/codelists/keyword.mapper.d.ts.map +1 -0
  37. package/libs/api/metadata-converter/src/lib/iso19139/converter.d.ts.map +1 -1
  38. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts +2 -3
  39. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts.map +1 -1
  40. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts +1 -1
  41. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  42. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +13 -2
  43. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  44. package/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.d.ts +1 -1
  45. package/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.d.ts.map +1 -1
  46. package/libs/ui/elements/src/lib/metadata-info/metadata-info.component.d.ts +3 -3
  47. package/libs/ui/elements/src/lib/metadata-info/metadata-info.component.d.ts.map +1 -1
  48. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +13 -13
  49. package/libs/ui/inputs/src/lib/button/button.component.d.ts +1 -1
  50. package/libs/ui/inputs/src/lib/button/button.component.d.ts.map +1 -1
  51. package/libs/ui/inputs/src/lib/text-area/text-area.component.d.ts +1 -1
  52. package/libs/ui/inputs/src/lib/text-area/text-area.component.d.ts.map +1 -1
  53. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +40 -40
  54. package/libs/ui/layout/src/lib/interactive-table/interactive-table-column/interactive-table-column.component.d.ts +1 -1
  55. package/package.json +1 -1
  56. package/src/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts +55 -2
  57. package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts +50 -6
  58. package/src/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +203 -20
  59. package/src/libs/api/metadata-converter/src/lib/gn4/atomic-operations.ts +29 -0
  60. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +11 -8
  61. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.metadata.mapper.ts +1 -1
  62. package/src/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.ts +3 -5
  63. package/src/libs/api/metadata-converter/src/lib/iso19139/codelists/keyword.mapper.ts +16 -0
  64. package/src/libs/api/metadata-converter/src/lib/iso19139/converter.ts +5 -9
  65. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +53 -19
  66. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +78 -36
  67. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +16 -3
  68. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +44 -8
  69. package/src/libs/feature/search/src/lib/favorites/favorite-star/favorite-star.component.html +3 -4
  70. package/src/libs/ui/catalog/src/lib/language-switcher/language-switcher.component.html +1 -1
  71. package/src/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.css +5 -0
  72. package/src/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.html +39 -0
  73. package/src/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.ts +58 -0
  74. package/src/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.ts +1 -0
  75. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +6 -6
  76. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.ts +6 -3
  77. package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.ts +1 -1
  78. package/src/libs/ui/elements/src/lib/thumbnail/thumbnail.component.html +2 -2
  79. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +1 -1
  80. package/src/libs/ui/inputs/src/lib/button/button.component.ts +1 -0
  81. package/src/libs/ui/inputs/src/lib/navigation-button/navigation-button.component.css +3 -0
  82. package/src/libs/ui/inputs/src/lib/navigation-button/navigation-button.component.html +1 -1
  83. package/src/libs/ui/inputs/src/lib/text-area/text-area.component.ts +1 -0
  84. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +2 -2
  85. package/tailwind.base.config.js +3 -0
  86. package/tailwind.base.css +2 -2
  87. package/translations/de.json +1 -1
  88. package/translations/en.json +1 -1
  89. package/translations/es.json +1 -1
  90. package/translations/fr.json +1 -1
  91. package/translations/it.json +1 -1
  92. package/translations/nl.json +1 -1
  93. package/translations/pt.json +1 -1
  94. package/translations/sk.json +1 -1
@@ -33,25 +33,185 @@ export const GEOCAT_CH_DATASET_RECORD: DatasetRecord = {
33
33
  title: 'Alpenkonvention',
34
34
  abstract: `Perimeter der Alpenkonvention in der Schweiz. Die Alpenkonvention ist ein völkerrechtlicher Vertrag zwischen den acht Alpenländern Deutschland, Frankreich, Italien, Liechtenstein, Monaco, Österreich, Schweiz, Slowenien sowie der Europäischen Union. Das Ziel des Übereinkommens ist der Schutz der Alpen durch eine sektorübergreifende, ganzheitliche und nachhaltige Politik.`,
35
35
  overviews: [],
36
- themes: [
37
- 'Aufbewahrungs- und Archivierungsplanung AAP - Bund',
38
- 'Geobasisdaten',
39
- 'e-geo.ch',
40
- 'opendata.swiss',
41
- 'Nachhaltige Entwicklung',
42
- 'Raumplanung',
43
- 'Bergschutz',
44
- 'Bodenschutz',
45
- 'Umweltpolitik',
46
- 'Umweltpolitik',
47
- 'Verkehr',
48
- 'Verkehr',
49
- 'Verkehr',
50
- 'Umweltüberwachung',
51
- 'Verwaltungseinheiten',
52
- 'BGDI Bundesgeodaten-Infrastruktur',
36
+ topics: ['planningCadastre', 'planningCadastre_Planning'],
37
+ keywords: [
38
+ {
39
+ thesaurus: {
40
+ name: 'geocat.ch',
41
+ id: 'geonetwork.thesaurus.local.theme.geocat.ch',
42
+ url: new URL(
43
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
44
+ ),
45
+ },
46
+ type: 'theme',
47
+ label: 'Aufbewahrungs- und Archivierungsplanung AAP - Bund',
48
+ },
49
+ {
50
+ thesaurus: {
51
+ name: 'geocat.ch',
52
+ id: 'geonetwork.thesaurus.local.theme.geocat.ch',
53
+ url: new URL(
54
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
55
+ ),
56
+ },
57
+ type: 'theme',
58
+ label: 'Geobasisdaten',
59
+ },
60
+ {
61
+ thesaurus: {
62
+ name: 'geocat.ch',
63
+ id: 'geonetwork.thesaurus.local.theme.geocat.ch',
64
+ url: new URL(
65
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
66
+ ),
67
+ },
68
+ type: 'theme',
69
+ label: 'e-geo.ch',
70
+ },
71
+ {
72
+ label: 'opendata.swiss',
73
+ thesaurus: {
74
+ id: 'geonetwork.thesaurus.local.theme.geocat.ch',
75
+ name: 'geocat.ch',
76
+ url: new URL(
77
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
78
+ ),
79
+ },
80
+ type: 'theme',
81
+ },
82
+ {
83
+ label: 'Nachhaltige Entwicklung',
84
+ thesaurus: {
85
+ id: 'geonetwork.thesaurus.external.theme.gemet',
86
+ name: 'GEMET',
87
+ url: new URL(
88
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
89
+ ),
90
+ },
91
+ type: 'theme',
92
+ },
93
+ {
94
+ label: 'Raumplanung',
95
+ thesaurus: {
96
+ id: 'geonetwork.thesaurus.external.theme.gemet',
97
+ name: 'GEMET',
98
+ url: new URL(
99
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
100
+ ),
101
+ },
102
+ type: 'theme',
103
+ },
104
+ {
105
+ label: 'Bergschutz',
106
+ thesaurus: {
107
+ id: 'geonetwork.thesaurus.external.theme.gemet',
108
+ name: 'GEMET',
109
+ url: new URL(
110
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
111
+ ),
112
+ },
113
+ type: 'theme',
114
+ },
115
+ {
116
+ label: 'Bodenschutz',
117
+ thesaurus: {
118
+ id: 'geonetwork.thesaurus.external.theme.gemet',
119
+ name: 'GEMET',
120
+ url: new URL(
121
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
122
+ ),
123
+ },
124
+ type: 'theme',
125
+ },
126
+ {
127
+ label: 'Umweltpolitik',
128
+ thesaurus: {
129
+ id: 'geonetwork.thesaurus.external.theme.gemet',
130
+ name: 'GEMET',
131
+ url: new URL(
132
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
133
+ ),
134
+ },
135
+ type: 'theme',
136
+ },
137
+ {
138
+ label: 'Umweltpolitik',
139
+ thesaurus: {
140
+ id: 'geonetwork.thesaurus.external.theme.gemet',
141
+ name: 'GEMET',
142
+ url: new URL(
143
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
144
+ ),
145
+ },
146
+ type: 'theme',
147
+ },
148
+ {
149
+ label: 'Verkehr',
150
+ thesaurus: {
151
+ id: 'geonetwork.thesaurus.external.theme.gemet',
152
+ name: 'GEMET',
153
+ url: new URL(
154
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
155
+ ),
156
+ },
157
+ type: 'theme',
158
+ },
159
+ {
160
+ label: 'Verkehr',
161
+ thesaurus: {
162
+ id: 'geonetwork.thesaurus.external.theme.gemet',
163
+ name: 'GEMET',
164
+ url: new URL(
165
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
166
+ ),
167
+ },
168
+ type: 'theme',
169
+ },
170
+ {
171
+ label: 'Verkehr',
172
+ thesaurus: {
173
+ id: 'geonetwork.thesaurus.external.theme.gemet',
174
+ name: 'GEMET',
175
+ url: new URL(
176
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
177
+ ),
178
+ },
179
+ type: 'theme',
180
+ },
181
+ {
182
+ label: 'Umweltüberwachung',
183
+ thesaurus: {
184
+ id: 'geonetwork.thesaurus.external.theme.inspire-theme',
185
+ name: 'GEMET - INSPIRE themes, version 1.0',
186
+ url: new URL(
187
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
188
+ ),
189
+ },
190
+ type: 'theme',
191
+ },
192
+ {
193
+ label: 'Verwaltungseinheiten',
194
+ thesaurus: {
195
+ id: 'geonetwork.thesaurus.external.theme.inspire-theme',
196
+ name: 'GEMET - INSPIRE themes, version 1.0',
197
+ url: new URL(
198
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
199
+ ),
200
+ },
201
+ type: 'theme',
202
+ },
203
+ {
204
+ label: 'BGDI Bundesgeodaten-Infrastruktur',
205
+ thesaurus: {
206
+ id: 'geonetwork.thesaurus.local.theme.geocat.ch',
207
+ name: 'geocat.ch',
208
+ url: new URL(
209
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
210
+ ),
211
+ },
212
+ type: 'theme',
213
+ },
53
214
  ],
54
- keywords: [],
55
215
  spatialRepresentation: 'vector',
56
216
  distributions: [
57
217
  {
@@ -210,8 +370,31 @@ export const GEOCAT_CH_SERVICE_RECORD: ServiceRecord = {
210
370
  description: 'Vorschaubild',
211
371
  },
212
372
  ],
213
- themes: [],
214
- keywords: ['Verkehr', 'opendata.swiss'],
373
+ topics: [],
374
+ keywords: [
375
+ {
376
+ label: 'Verkehr',
377
+ thesaurus: {
378
+ id: 'geonetwork.thesaurus.external.theme.gemet',
379
+ name: 'GEMET',
380
+ url: new URL(
381
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
382
+ ),
383
+ },
384
+ type: 'other',
385
+ },
386
+ {
387
+ label: 'opendata.swiss',
388
+ thesaurus: {
389
+ id: 'geonetwork.thesaurus.local.theme.geocat.ch',
390
+ name: 'geocat.ch',
391
+ url: new URL(
392
+ 'https://geocat-dev.dev.bgdi.ch/geonetwork/srv/api/registries/vocabularies/local.theme.geocat.ch'
393
+ ),
394
+ },
395
+ type: 'other',
396
+ },
397
+ ],
215
398
  onlineResources: [
216
399
  {
217
400
  type: 'link',
@@ -3,6 +3,8 @@ import {
3
3
  Organization,
4
4
  } from '../../../../../../libs/common/domain/src/lib/model/record'
5
5
  import { getRoleFromRoleCode } from '../iso19139/codelists/role.mapper'
6
+ import { Thesaurus } from './types'
7
+ import { getKeywordTypeFromKeywordTypeCode } from '../iso19139/codelists/keyword.mapper'
6
8
 
7
9
  export type SourceWithUnknownProps = { [key: string]: unknown }
8
10
 
@@ -98,3 +100,30 @@ export const mapContact = (
98
100
  ...(phone && { phone }),
99
101
  }
100
102
  }
103
+
104
+ export const mapKeywords = (thesauri: Thesaurus[], language: string) => {
105
+ const keywords = []
106
+ for (const thesaurusId in thesauri) {
107
+ const rawThesaurus = thesauri[thesaurusId]
108
+ let thesaurus = null
109
+ if (rawThesaurus.id) {
110
+ const thesaurusSource: SourceWithUnknownProps = { ...rawThesaurus }
111
+ const url = getAsUrl(selectField(thesaurusSource, 'link'))
112
+ const name = selectField(thesaurusSource, 'title')
113
+ thesaurus = {
114
+ id: rawThesaurus.id,
115
+ ...(name && { name }),
116
+ ...(url && { url }),
117
+ }
118
+ }
119
+ for (const keyword of rawThesaurus.keywords) {
120
+ keywords.push({
121
+ label: selectTranslatedValue<string>(keyword, language),
122
+ type: getKeywordTypeFromKeywordTypeCode(rawThesaurus.theme),
123
+ ...(thesaurus && { thesaurus }),
124
+ })
125
+ }
126
+ }
127
+
128
+ return keywords
129
+ }
@@ -4,6 +4,7 @@ import {
4
4
  getAsUrl,
5
5
  getFirstValue,
6
6
  mapContact,
7
+ mapKeywords,
7
8
  selectFallback,
8
9
  selectFallbackFields,
9
10
  selectField,
@@ -28,6 +29,7 @@ import {
28
29
  } from '../../../../../../libs/common/domain/src/lib/model/record'
29
30
  import { matchProtocol } from '../common/distribution.mapper'
30
31
  import { LangService } from '../../../../../../libs/util/i18n/src'
32
+ import { Thesaurus } from './types'
31
33
 
32
34
  type ESResponseSource = SourceWithUnknownProps
33
35
 
@@ -92,8 +94,8 @@ export class Gn4FieldMapper {
92
94
  },
93
95
  cl_topic: (output, source) => ({
94
96
  ...output,
95
- themes: [
96
- ...(output.themes || []),
97
+ topics: [
98
+ ...(output.topics || []),
97
99
  ...getAsArray(
98
100
  selectField<SourceWithUnknownProps[]>(source, 'cl_topic')
99
101
  ).map((topic) => selectTranslatedValue<string>(topic, this.lang3)),
@@ -171,16 +173,17 @@ export class Gn4FieldMapper {
171
173
  output
172
174
  )
173
175
  },
174
- tag: (output, source) => ({
176
+ allKeywords: (output, source) => ({
175
177
  ...output,
176
- keywords: getAsArray(
177
- selectField<SourceWithUnknownProps[]>(source, 'tag')
178
- ).map((tag) => selectTranslatedValue<string>(tag, this.lang3)),
178
+ keywords: mapKeywords(
179
+ selectField<Thesaurus[]>(source, 'allKeywords'),
180
+ this.lang3
181
+ ),
179
182
  }),
180
183
  inspireTheme: (output, source) => ({
181
184
  ...output,
182
- themes: [
183
- ...(output.themes || []),
185
+ topics: [
186
+ ...(output.topics || []),
184
187
  ...getAsArray(selectField(source, 'inspireTheme_syn')),
185
188
  ],
186
189
  }),
@@ -32,7 +32,7 @@ export class Gn4MetadataMapper extends MetadataBaseMapper<Gn4Record> {
32
32
  contacts: [],
33
33
  contactsForResource: [],
34
34
  keywords: [],
35
- themes: [],
35
+ topics: [],
36
36
  spatialExtents: [],
37
37
  temporalExtents: [],
38
38
  overviews: [],
@@ -56,15 +56,13 @@ interface SpecificationConformance {
56
56
  pass: BooleanString
57
57
  }
58
58
 
59
- type Keyword = MultilingualField
60
- type Keywords = Keyword[]
61
59
  type ThesaurusName = string
62
- interface Thesaurus {
60
+ export interface Thesaurus {
63
61
  id?: string
64
62
  title?: string
65
63
  theme?: string
66
64
  link?: string
67
- keywords: Keywords
65
+ keywords: MultilingualField[]
68
66
  }
69
67
 
70
68
  export interface Link {
@@ -175,7 +173,7 @@ export type MetadataObject = Partial<{
175
173
  specificationConformance: MaybeArray<SpecificationConformance>
176
174
  standardNameObject: MultilingualField
177
175
  standardVersionObject: MultilingualField
178
- tag: Keywords
176
+ tag: MultilingualField[]
179
177
  tagNumber: string
180
178
  userSavedCount: string
181
179
  userinfo: string
@@ -0,0 +1,16 @@
1
+ import { KeywordType } from '../../../../../../../libs/common/domain/src/lib/model/record'
2
+
3
+ export function getKeywordTypeFromKeywordTypeCode(
4
+ typeCode: string
5
+ ): KeywordType {
6
+ if (!typeCode) return 'other'
7
+ switch (typeCode) {
8
+ case 'theme':
9
+ case 'place':
10
+ case 'temporal':
11
+ case 'other':
12
+ return typeCode
13
+ default:
14
+ return 'other'
15
+ }
16
+ }
@@ -29,7 +29,7 @@ import {
29
29
  writeSecurityConstraints,
30
30
  writeSpatialRepresentation,
31
31
  writeStatus,
32
- writeThemes,
32
+ writeTopics,
33
33
  writeTitle,
34
34
  writeUniqueIdentifier,
35
35
  writeUpdateFrequency,
@@ -56,7 +56,6 @@ import {
56
56
  readSpatialRepresentation,
57
57
  readStatus,
58
58
  readTemporalExtents,
59
- readThemes,
60
59
  readTitle,
61
60
  readUniqueIdentifier,
62
61
  readUpdateFrequency,
@@ -76,16 +75,13 @@ export function toModel(xml: string): CatalogRecord {
76
75
  const recordUpdated = readRecordUpdated(rootEl)
77
76
  const recordCreated = recordUpdated
78
77
  const keywords = readKeywords(rootEl)
79
- const themes = readThemes(rootEl)
78
+ const topics = readIsoTopics(rootEl)
80
79
  const legalConstraints = readLegalConstraints(rootEl)
81
80
  const otherConstraints = readOtherConstraints(rootEl)
82
81
  const securityConstraints = readSecurityConstraints(rootEl)
83
82
  const licenses = readLicenses(rootEl)
84
83
  const overviews = readOverviews(rootEl)
85
84
 
86
- // not used yet
87
- const isoTopics = readIsoTopics(rootEl)
88
-
89
85
  if (kind === 'dataset') {
90
86
  const status = readStatus(rootEl)
91
87
  const datasetCreated = readDatasetCreated(rootEl)
@@ -109,7 +105,7 @@ export function toModel(xml: string): CatalogRecord {
109
105
  contacts,
110
106
  contactsForResource: [], // FIXME: is that really useful??
111
107
  keywords,
112
- themes,
108
+ topics,
113
109
  licenses,
114
110
  legalConstraints,
115
111
  securityConstraints,
@@ -136,7 +132,7 @@ export function toModel(xml: string): CatalogRecord {
136
132
  ownerOrganization,
137
133
  contacts,
138
134
  keywords,
139
- themes,
135
+ topics,
140
136
  licenses,
141
137
  legalConstraints,
142
138
  securityConstraints,
@@ -168,7 +164,7 @@ export function toXml(record: CatalogRecord, originalXml?: string): string {
168
164
  writeAbstract(record, rootEl)
169
165
  fieldChanged('contacts') && writeContacts(record, rootEl)
170
166
  fieldChanged('keywords') && writeKeywords(record, rootEl)
171
- fieldChanged('themes') && writeThemes(record, rootEl)
167
+ fieldChanged('topics') && writeTopics(record, rootEl)
172
168
  fieldChanged('legalConstraints') && writeLegalConstraints(record, rootEl)
173
169
  fieldChanged('securityConstraints') &&
174
170
  writeSecurityConstraints(record, rootEl)
@@ -5,6 +5,8 @@ import {
5
5
  DatasetTemporalExtent,
6
6
  GraphicOverview,
7
7
  Individual,
8
+ Keyword,
9
+ KeywordThesaurus,
8
10
  Organization,
9
11
  RecordKind,
10
12
  RecordStatus,
@@ -39,6 +41,7 @@ import {
39
41
  } from '../function-utils'
40
42
  import { getRoleFromRoleCode } from './codelists/role.mapper'
41
43
  import { matchMimeType, matchProtocol } from '../common/distribution.mapper'
44
+ import { getKeywordTypeFromKeywordTypeCode } from './codelists/keyword.mapper'
42
45
 
43
46
  function extractCharacterString(): ChainableFunction<XmlElement, string> {
44
47
  return pipe(
@@ -552,29 +555,60 @@ export function readContacts(rootEl: XmlElement): Individual[] {
552
555
  )(rootEl)
553
556
  }
554
557
 
555
- function readKeywordsOfType(isTheme: boolean) {
556
- return pipe(
557
- findIdentification(),
558
- findNestedElements('gmd:descriptiveKeywords', 'gmd:MD_Keywords'),
559
- filterArray(
560
- pipe(
561
- findChildrenElement('gmd:MD_KeywordTypeCode'),
562
- mapArray(readAttribute('codeListValue')),
563
- map((values) => isTheme === values.indexOf('theme') > -1)
564
- )
565
- ),
566
- mapArray(findChildrenElement('gmd:keyword')),
567
- flattenArray(),
568
- mapArray(extractCharacterString())
558
+ // from gmd:thesaurusName
559
+ function readThesaurus(rootEl: XmlElement): KeywordThesaurus {
560
+ if (!rootEl) return null
561
+
562
+ const findIdentifier = findNestedElement(
563
+ 'gmd:CI_Citation',
564
+ 'gmd:identifier',
565
+ 'gmd:MD_Identifier',
566
+ 'gmd:code'
569
567
  )
568
+ const id = pipe(findIdentifier, extractCharacterString())(rootEl)
569
+ const url = pipe(findIdentifier, extractUrl())(rootEl)
570
+ const name = pipe(
571
+ findNestedElement('gmd:CI_Citation', 'gmd:title'),
572
+ extractCharacterString()
573
+ )(rootEl)
574
+ return {
575
+ id,
576
+ ...(name && { name }),
577
+ ...(url && { url }),
578
+ }
570
579
  }
571
580
 
572
- export function readKeywords(rootEl: XmlElement): string[] {
573
- return readKeywordsOfType(false)(rootEl)
581
+ // from gmd:MD_Keywords
582
+ function readKeywordGroup(rootEl: XmlElement): Keyword[] {
583
+ const type = pipe(
584
+ findChildrenElement('gmd:MD_KeywordTypeCode'),
585
+ mapArray(readAttribute('codeListValue')),
586
+ map((values) => getKeywordTypeFromKeywordTypeCode(values[0]))
587
+ )(rootEl)
588
+ const thesaurus = pipe(
589
+ findNestedElement('gmd:thesaurusName'),
590
+ readThesaurus
591
+ )(rootEl)
592
+ return pipe(
593
+ findChildrenElement('gmd:keyword'),
594
+ mapArray((el) => {
595
+ const label = extractCharacterString()(el)
596
+ return {
597
+ ...(thesaurus ? { thesaurus } : {}),
598
+ label,
599
+ type,
600
+ } as Keyword
601
+ })
602
+ )(rootEl)
574
603
  }
575
604
 
576
- export function readThemes(rootEl: XmlElement): string[] {
577
- return readKeywordsOfType(true)(rootEl)
605
+ export function readKeywords(rootEl: XmlElement): Keyword[] {
606
+ return pipe(
607
+ findIdentification(),
608
+ findNestedElements('gmd:descriptiveKeywords', 'gmd:MD_Keywords'),
609
+ mapArray(readKeywordGroup),
610
+ flattenArray()
611
+ )(rootEl)
578
612
  }
579
613
 
580
614
  export function readStatus(rootEl: XmlElement): RecordStatus {
@@ -627,7 +661,7 @@ export function readLicenses(rootEl: XmlElement): Constraint[] {
627
661
  export function readIsoTopics(rootEl: XmlElement): string[] {
628
662
  return pipe(
629
663
  findIdentification(),
630
- findChildrenElement('gmd:MD_TopicCategoryCode', false),
664
+ findChildrenElement('gmd:MD_TopicCategoryCode', true),
631
665
  mapArray(readText())
632
666
  )(rootEl)
633
667
  }