geonetwork-ui 2.10.0-dev.e97ea6950 → 2.10.0-dev.f1c00d5fe

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 (174) hide show
  1. package/fesm2022/geonetwork-ui.mjs +2558 -6985
  2. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  3. package/index.d.ts +299 -189
  4. package/index.d.ts.map +1 -1
  5. package/package.json +25 -35
  6. package/src/libs/api/metadata-converter/src/lib/dcat-ap/dcat-ap.converter.ts +20 -0
  7. package/src/libs/api/metadata-converter/src/lib/fixtures/eu.dcat-ap.records.ts +4 -0
  8. package/src/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts +23 -0
  9. package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.reuse+ongules.ts +8 -0
  10. package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.reuse+roilaye.ts +2 -0
  11. package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts +2 -0
  12. package/src/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +2 -0
  13. package/src/libs/api/metadata-converter/src/lib/fixtures/georhena.records.ts +2 -0
  14. package/src/libs/api/metadata-converter/src/lib/fixtures/metadata-for-i18n.records.ts +4 -0
  15. package/src/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts +23 -0
  16. package/src/libs/api/metadata-converter/src/lib/fixtures/opendataswiss.records.ts +2 -0
  17. package/src/libs/api/metadata-converter/src/lib/fixtures/sextant.records.ts +4 -0
  18. package/src/libs/api/metadata-converter/src/lib/fixtures/vlaanderen.dcat-ap.records.ts +2 -0
  19. package/src/libs/api/metadata-converter/src/lib/fixtures/wallonie.records.reuse.ts +9 -0
  20. package/src/libs/api/metadata-converter/src/lib/gn4/atomic-operations.ts +48 -7
  21. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.converter.ts +2 -0
  22. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +6 -5
  23. package/src/libs/api/metadata-converter/src/lib/gn4/metadata-url.service.ts +2 -2
  24. package/src/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.ts +1 -0
  25. package/src/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.ts +11 -0
  26. package/src/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.ts +21 -0
  27. package/src/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.ts +52 -0
  28. package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +24 -1
  29. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +73 -0
  30. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +79 -0
  31. package/src/libs/api/repository/src/lib/gn4/auth/auth.service.ts +8 -4
  32. package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +2 -2
  33. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +79 -41
  34. package/src/libs/api/repository/src/lib/gn4/gn4.provider.ts +6 -1
  35. package/src/libs/api/repository/src/lib/gn4/organizations/organizations-from-groups.service.ts +1 -1
  36. package/src/libs/api/repository/src/lib/gn4/organizations/organizations-from-metadata.service.ts +1 -1
  37. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +37 -2
  38. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +23 -5
  39. package/src/libs/common/domain/src/lib/model/thesaurus/thesaurus.model.ts +2 -1
  40. package/src/libs/common/domain/src/lib/model/user/group.model.ts +8 -0
  41. package/src/libs/common/domain/src/lib/model/user/index.ts +1 -0
  42. package/src/libs/common/domain/src/lib/platform.service.interface.ts +2 -0
  43. package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +2 -1
  44. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +62 -0
  45. package/src/libs/feature/catalog/src/lib/sources/sources.service.ts +5 -2
  46. package/src/libs/feature/editor/src/index.ts +1 -0
  47. package/src/libs/feature/editor/src/lib/+state/editor.actions.ts +10 -1
  48. package/src/libs/feature/editor/src/lib/+state/editor.effects.ts +26 -20
  49. package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +15 -2
  50. package/src/libs/feature/editor/src/lib/components/constraint-card/constraint-card.component.ts +0 -2
  51. package/src/libs/feature/editor/src/lib/components/contact-details/contact-details-form.component.css +0 -0
  52. package/src/libs/feature/editor/src/lib/components/contact-details/contact-details-form.component.html +68 -0
  53. package/src/libs/feature/editor/src/lib/components/contact-details/contact-details-form.component.ts +41 -0
  54. package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.html +5 -14
  55. package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.ts +3 -28
  56. package/src/libs/feature/editor/src/lib/components/metadata-quality-panel/metadata-quality-panel.component.html +18 -3
  57. package/src/libs/feature/editor/src/lib/components/metadata-quality-panel/metadata-quality-panel.component.ts +33 -40
  58. package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.html +5 -5
  59. package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.ts +2 -1
  60. package/src/libs/feature/editor/src/lib/components/record-form/form-field/field-focus.directive.ts +41 -0
  61. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-constraints-shortcuts/form-field-constraints-shortcuts.component.ts +33 -34
  62. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts/form-field-contacts.component.html +13 -13
  63. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts/form-field-contacts.component.ts +18 -4
  64. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.html +8 -7
  65. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.ts +6 -6
  66. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.ts +1 -1
  67. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-single-link-resource/form-field-online-single-link-resource.component.css +0 -0
  68. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-single-link-resource/form-field-online-single-link-resource.component.html +5 -0
  69. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-single-link-resource/form-field-online-single-link-resource.component.ts +89 -0
  70. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.ts +12 -5
  71. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.html +4 -4
  72. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.ts +7 -0
  73. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-topics/form-field-topics.component.ts +2 -2
  74. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html +6 -2
  75. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.ts +3 -1
  76. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.css +3 -0
  77. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +28 -16
  78. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +16 -0
  79. package/src/libs/feature/editor/src/lib/components/record-form/form-field/index.ts +1 -0
  80. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.css +35 -0
  81. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.html +18 -5
  82. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.ts +118 -5
  83. package/src/libs/feature/editor/src/lib/expressions.ts +380 -8
  84. package/src/libs/feature/editor/src/lib/fields.config.ts +354 -337
  85. package/src/libs/feature/editor/src/lib/models/editor-config.model.ts +10 -3
  86. package/src/libs/feature/editor/src/lib/services/editor.service.ts +9 -13
  87. package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +33 -0
  88. package/src/libs/feature/notify-reuse/src/index.ts +2 -0
  89. package/src/libs/feature/notify-reuse/src/lib/edit-delete-reuse-buttons/edit-delete-reuse-buttons.component.css +0 -0
  90. package/src/libs/feature/notify-reuse/src/lib/edit-delete-reuse-buttons/edit-delete-reuse-buttons.component.html +23 -0
  91. package/src/libs/feature/notify-reuse/src/lib/edit-delete-reuse-buttons/edit-delete-reuse-buttons.component.ts +114 -0
  92. package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.css +0 -0
  93. package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.html +111 -0
  94. package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.ts +234 -0
  95. package/src/libs/feature/notify-reuse/src/lib/utils/url.ts +16 -0
  96. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +9 -1
  97. package/src/libs/feature/search/src/lib/results-table/results-table-container.component.ts +10 -5
  98. package/src/libs/ui/catalog/src/lib/language-switcher/language-switcher.component.ts +2 -2
  99. package/src/libs/ui/dataviz/src/index.ts +0 -1
  100. package/src/libs/ui/elements/src/index.ts +3 -0
  101. package/src/libs/ui/elements/src/lib/contact-details/contact-details.component.html +88 -0
  102. package/src/libs/ui/elements/src/lib/contact-details/contact-details.component.ts +45 -0
  103. package/src/libs/ui/elements/src/lib/contact-pill/contact-pill.component.html +41 -0
  104. package/src/libs/ui/elements/src/lib/contact-pill/contact-pill.component.ts +70 -0
  105. package/src/libs/ui/elements/src/lib/external-link-card/external-link-card.component.html +2 -1
  106. package/src/libs/ui/elements/src/lib/external-link-card/external-link-card.component.ts +2 -2
  107. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.css +13 -0
  108. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.html +13 -3
  109. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.ts +43 -6
  110. package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.html +1 -1
  111. package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.ts +0 -1
  112. package/src/libs/ui/elements/src/lib/keyword-badge/keyword-badge.component.html +14 -0
  113. package/src/libs/ui/elements/src/lib/keyword-badge/keyword-badge.component.ts +85 -0
  114. package/src/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.ts +2 -2
  115. package/src/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.ts +2 -5
  116. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.css +3 -2
  117. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +26 -68
  118. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.ts +30 -10
  119. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html +4 -5
  120. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +4 -0
  121. package/src/libs/ui/inputs/src/lib/badge/badge.component.html +33 -26
  122. package/src/libs/ui/inputs/src/lib/badge/badge.component.ts +9 -0
  123. package/src/libs/ui/inputs/src/lib/button/button.component.ts +8 -0
  124. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.ts +2 -2
  125. package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.html +1 -1
  126. package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.ts +3 -3
  127. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.css +0 -3
  128. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.html +11 -7
  129. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.ts +56 -30
  130. package/src/libs/ui/inputs/src/lib/url-input/url-input.component.html +2 -2
  131. package/src/libs/ui/inputs/src/lib/url-input/url-input.component.ts +2 -1
  132. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.html +5 -5
  133. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.ts +9 -1
  134. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.html +1 -1
  135. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.ts +3 -8
  136. package/src/libs/ui/layout/src/lib/sortable-list/sortable-list.component.html +7 -7
  137. package/src/libs/ui/layout/src/lib/sortable-list/sortable-list.component.ts +14 -1
  138. package/src/libs/ui/map/src/lib/components/map-container/map-container.component.ts +2 -1
  139. package/src/libs/ui/map/src/lib/components/spatial-extent/spatial-extent.component.ts +15 -64
  140. package/src/libs/ui/map/src/lib/map-utils.ts +48 -0
  141. package/src/libs/ui/search/src/lib/record-preview-feed/record-preview-feed.component.ts +1 -1
  142. package/src/libs/ui/search/src/lib/record-preview-row/record-preview-row.component.html +0 -1
  143. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.html +12 -8
  144. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.ts +3 -1
  145. package/src/libs/ui/search/src/lib/results-table/results-table.component.html +1 -0
  146. package/src/libs/ui/widgets/src/lib/popover/popover.component.ts +7 -1
  147. package/src/libs/ui/widgets/src/lib/spinning-loader/spinning-loader.component.html +1 -1
  148. package/src/libs/util/app-config/src/lib/app-config.ts +70 -9
  149. package/src/libs/util/app-config/src/lib/model.ts +7 -0
  150. package/src/libs/util/app-config/src/lib/parse-utils.ts +50 -1
  151. package/src/libs/util/data-fetcher/src/lib/readers/base-file.ts +1 -2
  152. package/src/libs/util/data-fetcher/src/lib/readers/wfs.ts +6 -3
  153. package/src/libs/util/i18n/src/index.ts +0 -1
  154. package/src/libs/util/i18n/src/lib/i18n.constants.ts +17 -11
  155. package/src/libs/util/i18n/src/lib/i18n.interceptor.ts +2 -2
  156. package/src/libs/util/i18n/src/lib/i18n.providers.ts +14 -17
  157. package/src/libs/util/i18n/src/lib/test.translate.loader.ts +48 -0
  158. package/src/libs/util/shared/src/lib/links/link-utils.ts +23 -1
  159. package/src/libs/util/shared/src/lib/record/quality-score.util.ts +33 -18
  160. package/src/libs/util/shared/src/lib/services/date.service.ts +3 -3
  161. package/src/libs/util/shared/src/lib/utils/geojson.ts +58 -1
  162. package/src/libs/util/shared/src/lib/utils/index.ts +1 -0
  163. package/src/libs/util/shared/src/lib/utils/user-display.ts +32 -0
  164. package/style.css +0 -1
  165. package/tailwind.base.css +26 -2
  166. package/translations/de.json +112 -50
  167. package/translations/en.json +117 -55
  168. package/translations/es.json +86 -24
  169. package/translations/fr.json +114 -52
  170. package/translations/it.json +113 -51
  171. package/translations/nl.json +85 -23
  172. package/translations/pt.json +86 -24
  173. package/translations/sk.json +86 -24
  174. package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.css +0 -3
@@ -192,6 +192,29 @@ Cette section contient des *caractères internationaux* (ainsi que des "caractè
192
192
  lineage: `This record was edited manually to test the conversion processes
193
193
 
194
194
  As such, **it is not very interesting at all.**`,
195
+ sourceRecords: [],
196
+ associatedRecords: [
197
+ {
198
+ uuid: 'b1882436-3016-421e-9dfd-0326cca998f2',
199
+ associationType: 'crossReference',
200
+ },
201
+ {
202
+ uuid: 'b1741571-bbda-4732-a807-cbc36b64d54f',
203
+ associationType: 'crossReference',
204
+ },
205
+ {
206
+ uuid: 'bdcb789c-4b02-4c0c-863a-98dac4ed0240',
207
+ associationType: 'crossReference',
208
+ },
209
+ {
210
+ uuid: 'c0112b86-a6e3-4df3-9da1-2927376076f4',
211
+ associationType: 'partOfSeamlessDatabase',
212
+ },
213
+ {
214
+ uuid: '7451e2bd-22e8-4a74-a999-01c58b630369',
215
+ associationType: 'largerWorkCitation',
216
+ },
217
+ ],
195
218
  otherConstraints: [
196
219
  { text: 'Should only be used as a testing tool', translations: {} },
197
220
  { text: 'Might cause minor annoyance in people', translations: {} },
@@ -237,6 +237,14 @@ export const GEO2FRANCE_REUSE_ONGULES_RECORD: ReuseRecord = {
237
237
  ],
238
238
  translations: {},
239
239
  lineage: null,
240
+ sourceRecords: [
241
+ {
242
+ uuid: '67c60362-0461-4574-8975-f4e7cfa64d20',
243
+ title: 'Répartition des ongulés sauvages en France (données depuis 1980)',
244
+ href: 'https://data.ofb.fr/catalogue/Donnees-geographiques-OFB/fre/csw?service=CSW&request=GetRecordById&version=2.0.2&outputSchema=http://www.isotc211.org/2005/gmd&elementSetName=full&id=67c60362-0461-4574-8975-f4e7cfa64d20',
245
+ },
246
+ ],
247
+ associatedRecords: [],
240
248
  temporalExtents: [
241
249
  {
242
250
  start: null,
@@ -96,6 +96,8 @@ export const GEO2FRANCE_REUSE_ROILAYE_RECORD: ReuseRecord = {
96
96
  ],
97
97
  translations: {},
98
98
  lineage: null,
99
+ sourceRecords: [],
100
+ associatedRecords: [],
99
101
  temporalExtents: [{ start: null, end: null }],
100
102
  reuseType: 'map',
101
103
  }
@@ -122,6 +122,8 @@ Malgré l'attention portée à la création de ces données, il est rappelé que
122
122
  ],
123
123
  lineage: `Document d’urbanisme numérisé conformément aux prescriptions nationales du CNIG par le Service d'Information Géographique de l'Agglomération de la Région de Compiègne.
124
124
  Ce lot de données produit en 2019, a été numérisé à partir du PCI Vecteur de 2019 et contrôlé par le Service d'Information Géographique de l'Agglomération de la Région de Compiègne.`,
125
+ sourceRecords: [],
126
+ associatedRecords: [],
125
127
  licenses: [
126
128
  {
127
129
  text: "En dépit des efforts et diligences mis en œuvre pour en vérifier la fiabilité, le fournisseur n’est pas en mesure de garantir l’exactitude, la mise à jour, l’intégrité, l’exhaustivité des données et en particulier que les données sont exemptes d'erreurs, notamment de localisation, d’identification ou d’actualisation ou d’imprécisions. Les données ne sont pas fournies en vue d'une utilisation particulière et aucune garantie quant à leur aptitude à un usage particulier n'est apportée par le fournisseur. En conséquence, les utilisateurs utilisent les données sous leur responsabilité pleine et entière, à leurs risques et périls, sans recours possible contre le fournisseur dont la responsabilité ne saurait être engagée du fait d’un dommage résultant directement ou indirectement de l’utilisation de ces données. En particulier, il appartient aux utilisateurs d’apprécier, sous leur seule responsabilité : – l'opportunité d'utiliser les données ; – la compatibilité des fichiers avec leurs systèmes informatiques ; – l’adéquation des données à leurs besoins ; – qu’ils disposent de la compétence suffisante pour utiliser les données ; – l’opportunité d’utiliser la documentation ou les outils d’analyse fournis ou préconisés, en relation avec l’utilisation des données, le cas échéant. Le fournisseur n’est en aucune façon responsable des éléments extérieurs aux données et notamment des outils d’analyse, matériels, logiciels, réseaux..., utilisés pour consulter et/ou traiter les données, même s’il a préconisé ces éléments. L’utilisateur veille à vérifier que l’actualité des informations mises à disposition est compatible avec l’usage qu’il en fait.",
@@ -546,6 +546,8 @@ export const GEOCAT_CH_DATASET_RECORD: DatasetRecord = {
546
546
  ],
547
547
  lineage:
548
548
  'Digitalisiert nach den administrativen Einheiten der Schweiz, die im Anhang des Übereinkommens erscheinen.',
549
+ sourceRecords: [],
550
+ associatedRecords: [],
549
551
  licenses: [
550
552
  {
551
553
  text: "Licence passée entre l'Office fédéral de l'environnement (OFEV), et le canton de Fribourg, représenté par la Coordination SIT (SITel)",
@@ -206,6 +206,8 @@ export const GEORHENA_REUSE_SOLAIRE_RECORD: ReuseRecord = {
206
206
  },
207
207
  },
208
208
  lineage: null,
209
+ sourceRecords: [],
210
+ associatedRecords: [],
209
211
  temporalExtents: [
210
212
  {
211
213
  start: new Date('2016-01-01T00:00:00.000Z'),
@@ -2170,6 +2170,8 @@ export const METADATA_FOR_I18N_DATASET_RECORD: DatasetRecord = {
2170
2170
  },
2171
2171
  status: 'completed',
2172
2172
  lineage: 'This is a statement about the lineage.',
2173
+ sourceRecords: [],
2174
+ associatedRecords: [],
2173
2175
  spatialRepresentation: 'vector',
2174
2176
  temporalExtents: [],
2175
2177
  updateFrequency: 'continual',
@@ -4234,6 +4236,8 @@ export const METADATA_FOR_I18N_NO_OTHERLANGUAGE: DatasetRecord = {
4234
4236
  translations: { lineage: {}, title: {}, abstract: {} },
4235
4237
  status: 'completed',
4236
4238
  lineage: 'This is a statement about the lineage.',
4239
+ sourceRecords: [],
4240
+ associatedRecords: [],
4237
4241
  spatialRepresentation: 'vector',
4238
4242
  temporalExtents: [],
4239
4243
  updateFrequency: 'continual',
@@ -419,6 +419,29 @@ Cette donnée a été intégrée dans la base de données routière (BDR). Les D
419
419
 
420
420
  Ces données, intégrées dans la Banque de Données routières (BDR), ont fait l’objet d’une mise à jour massive en 2014-2015.
421
421
  Depuis, ce sont les Districts routiers qui assurent la tenue à jour de ces informations directement dans la base de données.`,
422
+ sourceRecords: [],
423
+ associatedRecords: [
424
+ {
425
+ uuid: 'b1882436-3016-421e-9dfd-0326cca998f2',
426
+ associationType: 'crossReference',
427
+ },
428
+ {
429
+ uuid: 'b1741571-bbda-4732-a807-cbc36b64d54f',
430
+ associationType: 'crossReference',
431
+ },
432
+ {
433
+ uuid: 'bdcb789c-4b02-4c0c-863a-98dac4ed0240',
434
+ associationType: 'crossReference',
435
+ },
436
+ {
437
+ uuid: 'c0112b86-a6e3-4df3-9da1-2927376076f4',
438
+ associationType: 'partOfSeamlessDatabase',
439
+ },
440
+ {
441
+ uuid: '7451e2bd-22e8-4a74-a999-01c58b630369',
442
+ associationType: 'largerWorkCitation',
443
+ },
444
+ ],
422
445
  otherConstraints: [],
423
446
  overviews: [
424
447
  {
@@ -370,6 +370,8 @@ export const OPENDATASWISS_DATASET_RECORD: DatasetRecord = {
370
370
  'http://dcat-ap.ch/vocabulary/themes/geography',
371
371
  ],
372
372
  lineage: '',
373
+ sourceRecords: [],
374
+ associatedRecords: [],
373
375
  ownerOrganization: {
374
376
  name: 'Bundesamt für Energie',
375
377
  },
@@ -82,6 +82,8 @@ export const SEXTANT_BATHYMETRY_DATASET_RECORD: DatasetRecord = {
82
82
  Le pas de la grille est de 25m.
83
83
  Produit interne Ifremer.`,
84
84
  lineage: '',
85
+ sourceRecords: [],
86
+ associatedRecords: [],
85
87
  ownerOrganization: null,
86
88
  recordUpdated: new Date('2020-06-03T22:34:05.000Z'),
87
89
  resourceUpdated: new Date('2020-06-03T22:34:05.000Z'),
@@ -322,6 +324,8 @@ export const SEXTANT_CURRENTS_DATASET_RECORD: CatalogRecord = {
322
324
  ],
323
325
  lineage:
324
326
  'Sallée, J.B.; Speer, K and Morrow, R. Southern Ocean fronts and their variability to climate modes, Journ. of Climate, 2008, Vol. 21(12), pp. 3020-3039',
327
+ sourceRecords: [],
328
+ associatedRecords: [],
325
329
  onlineResources: [
326
330
  {
327
331
  name: 'Digital Object Identifier (DOI)',
@@ -68,6 +68,8 @@ export const VLAANDEREN_DATASET_RECORD: DatasetRecord = {
68
68
  temporalExtents: [],
69
69
  topics: ['biodiversity'],
70
70
  lineage: '',
71
+ sourceRecords: [],
72
+ associatedRecords: [],
71
73
  recordUpdated: new Date('2024-09-19T01:15:09.732Z'),
72
74
  resourceUpdated: new Date('2021-04-14T11:15+02:00'),
73
75
  status: 'completed',
@@ -447,5 +447,14 @@ export const WALLONIE_REUSE_SPW_RECORD: ReuseRecord = {
447
447
  'https://metawal.wallonie.be/geonetwork/srv/api/records/83809bcd-1763-4d28-b820-2b9828083ba5'
448
448
  ),
449
449
  lineage: "L'application a été développée sur base de l'API GeoViewer",
450
+ sourceRecords: [
451
+ {
452
+ uuid: 'ee965118-2416-4d48-b07e-bbc696f002c2',
453
+ title:
454
+ 'SCoT (Schéma de cohérence territoriale) en région Hauts-de-France',
455
+ href: 'https://metawal.wallonie.be/geonetwork/srv/api/records/ee965118-2416-4d48-b07e-bbc696f002c2',
456
+ },
457
+ ],
458
+ associatedRecords: [],
450
459
  temporalExtents: [],
451
460
  }
@@ -101,27 +101,68 @@ export const mapContact = (
101
101
  }
102
102
  }
103
103
 
104
- export const mapKeywords = (thesauri: Thesaurus[], language: string) => {
104
+ export interface KeywordTree {
105
+ default?: string[]
106
+ }
107
+
108
+ /**
109
+ * Resolves a keyword's ancestor path within its thesaurus tree, or null for a
110
+ * root-level keyword (no ancestors to show). Tree entries are `^`-joined label
111
+ * paths (default language); they aren't index-aligned with the keywords, so we
112
+ * match on the last segment (not by position/URI), shortest path on poly-hierarchy.
113
+ */
114
+ export const getKeywordHierarchyPath = (
115
+ keywordDefaultLabel: string,
116
+ tree?: KeywordTree | null
117
+ ): string[] | null => {
118
+ if (!keywordDefaultLabel || !tree?.default) return null
119
+ const shortest = tree.default
120
+ .map((entry) => entry.split('^'))
121
+ .filter((path) => path[path.length - 1] === keywordDefaultLabel)
122
+ .reduce(
123
+ (shortest, path) =>
124
+ !shortest || path.length < shortest.length ? path : shortest,
125
+ null
126
+ )
127
+ return shortest?.length > 1 ? shortest : null
128
+ }
129
+
130
+ export const mapKeywords = (
131
+ thesauri: Record<string, Thesaurus>,
132
+ language: string,
133
+ source?: SourceWithUnknownProps
134
+ ) => {
105
135
  const keywords = []
106
136
  for (const thesaurusId in thesauri) {
107
137
  const rawThesaurus = thesauri[thesaurusId]
138
+ // thesauri have an `id` (registered) or a `multilingualTitle` (cited);
139
+ // free-keyword groups only have a machine-key `title` like "otherKeywords-theme"
140
+ const { id, multilingualTitle, link = null } = rawThesaurus
108
141
  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')
142
+ if (id || multilingualTitle) {
143
+ const url = getAsUrl(link)
144
+ const name = multilingualTitle
145
+ ? selectTranslatedValue<string>(multilingualTitle, language)
146
+ : rawThesaurus.title
113
147
  thesaurus = {
114
- id: rawThesaurus.id,
148
+ ...(id && { id }),
115
149
  ...(name && { name }),
116
150
  ...(url && { url }),
117
151
  }
118
152
  }
153
+ const tree =
154
+ source && selectField<KeywordTree>(source, `${thesaurusId}_tree`)
155
+ // free-keyword groups have no `theme` field; their type is in the group key
156
+ const typeCode =
157
+ rawThesaurus.theme || thesaurusId.match(/otherKeywords-(\w+)$/)?.[1]
119
158
  for (const keyword of rawThesaurus.keywords) {
159
+ const hierarchyPath = getKeywordHierarchyPath(keyword.default, tree)
120
160
  keywords.push({
121
161
  label: selectTranslatedValue<string>(keyword, language),
122
- type: getKeywordTypeFromKeywordTypeCode(rawThesaurus.theme),
162
+ type: getKeywordTypeFromKeywordTypeCode(typeCode),
123
163
  ...(keyword.link && { key: keyword.link }),
124
164
  ...(thesaurus && { thesaurus }),
165
+ ...(hierarchyPath && { hierarchyPath }),
125
166
  })
126
167
  }
127
168
  }
@@ -24,6 +24,8 @@ export class Gn4Converter extends BaseConverter<Gn4Record> {
24
24
  kind: 'dataset',
25
25
  status: null,
26
26
  lineage: null,
27
+ sourceRecords: [],
28
+ associatedRecords: [],
27
29
  recordUpdated: null,
28
30
  recordPublished: null,
29
31
  ownerOrganization: null,
@@ -14,7 +14,7 @@ import {
14
14
  toDate,
15
15
  } from './atomic-operations'
16
16
  import { MetadataUrlService } from './metadata-url.service'
17
- import { Injectable, inject } from '@angular/core'
17
+ import { inject, Injectable } from '@angular/core'
18
18
  import { getStatusFromStatusCode } from '../iso19139/utils/status.mapper'
19
19
  import { getUpdateFrequencyFromFrequencyCode } from '../iso19139/utils/update-frequency.mapper'
20
20
  import {
@@ -49,7 +49,7 @@ export class Gn4FieldMapper {
49
49
  private translateService = inject(TranslateService)
50
50
 
51
51
  private get getLocalizedIndexKey() {
52
- return `lang${toLang3(this.translateService.currentLang)}`
52
+ return `lang${toLang3(this.translateService.getCurrentLang())}`
53
53
  }
54
54
 
55
55
  protected fields: Record<string, EsFieldMapperFn> = {
@@ -84,7 +84,7 @@ export class Gn4FieldMapper {
84
84
  'resourceAbstractObject',
85
85
  this.getLocalizedIndexKey
86
86
  ),
87
- 'no title'
87
+ this.translateService.instant('record.metadata.abstract.empty')
88
88
  ),
89
89
  }),
90
90
  overview: (output, source) => {
@@ -240,8 +240,9 @@ export class Gn4FieldMapper {
240
240
  allKeywords: (output, source) => ({
241
241
  ...output,
242
242
  keywords: mapKeywords(
243
- selectField<Thesaurus[]>(source, 'allKeywords'),
244
- this.getLocalizedIndexKey
243
+ selectField<Record<string, Thesaurus>>(source, 'allKeywords'),
244
+ this.getLocalizedIndexKey,
245
+ source
245
246
  ),
246
247
  }),
247
248
  inspireTheme: (output, source) => ({
@@ -1,4 +1,4 @@
1
- import { Injectable, inject } from '@angular/core'
1
+ import { inject, Injectable } from '@angular/core'
2
2
  import { Configuration } from '../../../../../../libs/data-access/gn4/src'
3
3
  import { TranslateService } from '@ngx-translate/core'
4
4
  import { toLang3 } from '../../../../../../libs/util/i18n/src'
@@ -13,7 +13,7 @@ export class MetadataUrlService {
13
13
  getUrl(uuid: string, apiPath: string = this.apiConfiguration.basePath) {
14
14
  const prefix = `${apiPath}/../`
15
15
  return `${prefix}${toLang3(
16
- this.translate.currentLang
16
+ this.translate.getCurrentLang()
17
17
  )}/catalog.search#/metadata/${uuid}`
18
18
  }
19
19
  }
@@ -62,6 +62,7 @@ type ThesaurusName = string
62
62
  export interface Thesaurus {
63
63
  id?: string
64
64
  title?: string
65
+ multilingualTitle?: MultilingualField
65
66
  theme?: string
66
67
  link?: string
67
68
  keywords: MultilingualField[]
@@ -3,12 +3,14 @@ import { XmlElement } from '@rgrove/parse-xml'
3
3
  import { Iso19139Converter } from '../iso19139'
4
4
  import { renameElements } from '../xml-utils'
5
5
  import {
6
+ readAssociatedRecords,
6
7
  readContacts,
7
8
  readContactsForResource,
8
9
  readDefaultLanguage,
9
10
  readKind,
10
11
  readLandingPage,
11
12
  readLineage,
13
+ readSourceRecords,
12
14
  readOnlineResources,
13
15
  readOtherLanguages,
14
16
  readOwnerOrganization,
@@ -19,12 +21,14 @@ import {
19
21
  readUniqueIdentifier,
20
22
  } from './read-parts'
21
23
  import {
24
+ writeAssociatedRecords,
22
25
  writeContacts,
23
26
  writeContactsForResource,
24
27
  writeDefaultLanguage,
25
28
  writeKind,
26
29
  writeLandingPage,
27
30
  writeLineage,
31
+ writeSourceRecords,
28
32
  writeOnlineResources,
29
33
  writeOtherLanguages,
30
34
  writeRecordCreated,
@@ -53,6 +57,8 @@ export class Iso191153Converter extends Iso19139Converter {
53
57
  this.readers['ownerOrganization'] = readOwnerOrganization
54
58
  this.readers['landingPage'] = readLandingPage
55
59
  this.readers['lineage'] = readLineage
60
+ this.readers['sourceRecords'] = readSourceRecords
61
+ this.readers['associatedRecords'] = readAssociatedRecords
56
62
  this.readers['onlineResources'] = readOnlineResources
57
63
  this.readers['defaultLanguage'] = readDefaultLanguage
58
64
  this.readers['otherLanguages'] = readOtherLanguages
@@ -72,6 +78,8 @@ export class Iso191153Converter extends Iso19139Converter {
72
78
  this.writers['ownerOrganization'] = () => undefined // fixme: find a way to store this value properly
73
79
  this.writers['landingPage'] = writeLandingPage
74
80
  this.writers['lineage'] = writeLineage
81
+ this.writers['sourceRecords'] = writeSourceRecords
82
+ this.writers['associatedRecords'] = writeAssociatedRecords
75
83
  this.writers['onlineResources'] = writeOnlineResources
76
84
  this.writers['status'] = writeStatus
77
85
  this.writers['spatialRepresentation'] = writeSpatialRepresentation
@@ -167,6 +175,9 @@ export class Iso191153Converter extends Iso19139Converter {
167
175
  'gmd:fileName': 'mcc:fileName',
168
176
  'gmd:fileDescription': 'mcc:fileDescription',
169
177
 
178
+ // lineage sources
179
+ 'gmd:source': 'mrl:source',
180
+
170
181
  // no more URL elements
171
182
  'gmd:URL': 'gco:CharacterString',
172
183
  })
@@ -18,9 +18,11 @@ import {
18
18
  pipe,
19
19
  } from '../function-utils'
20
20
  import {
21
+ extractAssociatedRecords,
21
22
  extractCharacterString,
22
23
  extractDatasetOnlineResources,
23
24
  extractDateTime,
25
+ extractSourceRecords,
24
26
  extractLocalizedCharacterString,
25
27
  extractReuseOnlineResources,
26
28
  extractRole,
@@ -29,8 +31,10 @@ import {
29
31
  findIdentification,
30
32
  } from '../iso19139/read-parts'
31
33
  import {
34
+ AssociatedRecord,
32
35
  Individual,
33
36
  LanguageCode,
37
+ SourceRecord,
34
38
  OnlineResource,
35
39
  Organization,
36
40
  OrganizationTranslations,
@@ -291,6 +295,23 @@ export function readLineage(
291
295
  )(rootEl)
292
296
  }
293
297
 
298
+ export function readSourceRecords(rootEl: XmlElement): SourceRecord[] {
299
+ return extractSourceRecords(
300
+ pipe(findNestedElement('mdb:resourceLineage', 'mrl:LI_Lineage'))(rootEl)
301
+ )
302
+ }
303
+
304
+ export function readAssociatedRecords(rootEl: XmlElement): AssociatedRecord[] {
305
+ return pipe(
306
+ findIdentification(),
307
+ extractAssociatedRecords(
308
+ 'mri:associatedResource',
309
+ 'mri:MD_AssociatedResource',
310
+ pipe(findNestedElement('mri:metadataReference'), readAttribute('uuidref'))
311
+ )
312
+ )(rootEl)
313
+ }
314
+
294
315
  function extractDateInfo(
295
316
  type: 'creation' | 'revision' | 'publication'
296
317
  ): ChainableFunction<XmlElement, Date> {
@@ -3,6 +3,7 @@ import {
3
3
  DatasetRecord,
4
4
  Individual,
5
5
  LanguageCode,
6
+ ReuseRecord,
6
7
  } from '../../../../../../libs/common/domain/src/lib/model/record'
7
8
  import {
8
9
  allChildrenElement,
@@ -10,6 +11,7 @@ import {
10
11
  appendChildTree,
11
12
  createChild,
12
13
  createElement,
14
+ createNestedElement,
13
15
  findChildElement,
14
16
  findChildOrCreate,
15
17
  findChildrenElement,
@@ -34,6 +36,7 @@ import {
34
36
  } from '../function-utils'
35
37
  import {
36
38
  appendKeywords,
39
+ appendSourceRecords,
37
40
  appendOnlineResource,
38
41
  appendServiceOnlineResources,
39
42
  createDistributionInfo,
@@ -564,3 +567,52 @@ export function writeOtherLanguages(record: DatasetRecord, rootEl: XmlElement) {
564
567
  )
565
568
  )(rootEl)
566
569
  }
570
+
571
+ export function writeSourceRecords(
572
+ record: DatasetRecord | ReuseRecord,
573
+ rootEl: XmlElement
574
+ ) {
575
+ pipe(
576
+ findNestedChildOrCreate('mdb:resourceLineage', 'mrl:LI_Lineage'),
577
+ appendSourceRecords(record.sourceRecords)
578
+ )(rootEl)
579
+ }
580
+
581
+ export function writeAssociatedRecords(
582
+ record: DatasetRecord | ReuseRecord,
583
+ rootEl: XmlElement
584
+ ) {
585
+ pipe(
586
+ findOrCreateIdentification(),
587
+ removeChildrenByName('mri:associatedResource'),
588
+ appendChildren(
589
+ ...record.associatedRecords
590
+ .filter((assoc) => assoc.uuid && assoc.associationType)
591
+ .map((assoc) =>
592
+ pipe(
593
+ createNestedElement(
594
+ 'mri:associatedResource',
595
+ 'mri:MD_AssociatedResource'
596
+ ),
597
+ appendChildren(
598
+ pipe(
599
+ createNestedElement(
600
+ 'mri:associationType',
601
+ 'mri:DS_AssociationTypeCode'
602
+ ),
603
+ writeAttribute(
604
+ 'codeList',
605
+ 'http://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#DS_AssociationTypeCode'
606
+ ),
607
+ writeAttribute('codeListValue', assoc.associationType)
608
+ ),
609
+ pipe(
610
+ createElement('mri:metadataReference'),
611
+ writeAttribute('uuidref', assoc.uuid)
612
+ )
613
+ )
614
+ )
615
+ )
616
+ )
617
+ )(rootEl)
618
+ }
@@ -21,6 +21,7 @@ import {
21
21
  } from '../xml-utils'
22
22
  import {
23
23
  readAbstract,
24
+ readAssociatedRecords,
24
25
  readContacts,
25
26
  readContactsForResource,
26
27
  readDefaultLanguage,
@@ -30,6 +31,7 @@ import {
30
31
  readLegalConstraints,
31
32
  readLicenses,
32
33
  readLineage,
34
+ readSourceRecords,
33
35
  readOnlineResources,
34
36
  readOtherConstraints,
35
37
  readOtherLanguages,
@@ -52,6 +54,7 @@ import {
52
54
  } from './read-parts'
53
55
  import {
54
56
  writeAbstract,
57
+ writeAssociatedRecords,
55
58
  writeContacts,
56
59
  writeContactsForResource,
57
60
  writeDefaultLanguage,
@@ -62,6 +65,7 @@ import {
62
65
  writeLegalConstraints,
63
66
  writeLicenses,
64
67
  writeLineage,
68
+ writeSourceRecords,
65
69
  writeOnlineResources,
66
70
  writeOtherConstraints,
67
71
  writeRecordUpdated,
@@ -112,6 +116,8 @@ export class Iso19139Converter extends BaseConverter<string> {
112
116
  spatialRepresentation: readSpatialRepresentation,
113
117
  overviews: readOverviews,
114
118
  lineage: readLineage,
119
+ sourceRecords: readSourceRecords,
120
+ associatedRecords: readAssociatedRecords,
115
121
  onlineResources: readOnlineResources,
116
122
  temporalExtents: readTemporalExtents,
117
123
  spatialExtents: readSpatialExtents,
@@ -153,6 +159,8 @@ export class Iso19139Converter extends BaseConverter<string> {
153
159
  spatialRepresentation: writeSpatialRepresentation,
154
160
  overviews: writeGraphicOverviews,
155
161
  lineage: writeLineage,
162
+ sourceRecords: writeSourceRecords,
163
+ associatedRecords: writeAssociatedRecords,
156
164
  onlineResources: writeOnlineResources,
157
165
  temporalExtents: writeTemporalExtents,
158
166
  spatialExtents: writeSpatialExtents,
@@ -201,7 +209,7 @@ export class Iso19139Converter extends BaseConverter<string> {
201
209
  record.contacts.map((c) => fixLanguages(c.organization))
202
210
  record.contactsForResource.map((c) => fixLanguages(c.organization))
203
211
  fixLanguages(record.ownerOrganization)
204
- if (record.kind === 'dataset') {
212
+ if (record.kind === 'dataset' || record.kind === 'reuse') {
205
213
  record.spatialExtents.map(fixLanguages)
206
214
  }
207
215
 
@@ -295,6 +303,8 @@ export class Iso19139Converter extends BaseConverter<string> {
295
303
  )
296
304
  const temporalExtents = this.readers['temporalExtents'](rootEl, tr)
297
305
  const lineage = this.readers['lineage'](rootEl, tr)
306
+ const sourceRecords = this.readers['sourceRecords'](rootEl, tr)
307
+ const associatedRecords = this.readers['associatedRecords'](rootEl, tr)
298
308
  const updateFrequency = this.readers['updateFrequency'](rootEl, tr)
299
309
 
300
310
  return this.afterRecordRead({
@@ -302,6 +312,8 @@ export class Iso19139Converter extends BaseConverter<string> {
302
312
  kind,
303
313
  status,
304
314
  lineage,
315
+ ...(sourceRecords && { sourceRecords }),
316
+ associatedRecords,
305
317
  ...(spatialRepresentation && { spatialRepresentation }),
306
318
  temporalExtents,
307
319
  updateFrequency,
@@ -309,6 +321,8 @@ export class Iso19139Converter extends BaseConverter<string> {
309
321
  } as DatasetRecord)
310
322
  } else if (kind === 'reuse') {
311
323
  const lineage = this.readers['lineage'](rootEl, tr)
324
+ const sourceRecords = this.readers['sourceRecords'](rootEl, tr)
325
+ const associatedRecords = this.readers['associatedRecords'](rootEl, tr)
312
326
  const temporalExtents = this.readers['temporalExtents'](rootEl, tr)
313
327
  const reuseType = this.readers['reuseType'](rootEl, tr)
314
328
 
@@ -316,6 +330,8 @@ export class Iso19139Converter extends BaseConverter<string> {
316
330
  ...this.readBaseRecord(rootEl, tr),
317
331
  kind,
318
332
  lineage,
333
+ ...(sourceRecords && { sourceRecords }),
334
+ associatedRecords,
319
335
  temporalExtents,
320
336
  reuseType,
321
337
  } as ReuseRecord)
@@ -400,6 +416,8 @@ export class Iso19139Converter extends BaseConverter<string> {
400
416
 
401
417
  if (record.kind === 'dataset') {
402
418
  fieldChanged('status') && this.writers['status'](record, rootEl)
419
+ }
420
+ if (record.kind === 'dataset' || record.kind === 'reuse') {
403
421
  fieldChanged('updateFrequency') &&
404
422
  this.writers['updateFrequency'](record, rootEl)
405
423
  fieldChanged('spatialRepresentation') &&
@@ -411,7 +429,12 @@ export class Iso19139Converter extends BaseConverter<string> {
411
429
  this.writers['spatialExtents'](record, rootEl)
412
430
  ;(fieldChanged('lineage') || fieldChanged('translations')) &&
413
431
  this.writers['lineage'](record, rootEl)
432
+ fieldChanged('sourceRecords') &&
433
+ this.writers['sourceRecords'](record, rootEl)
434
+ fieldChanged('associatedRecords') &&
435
+ this.writers['associatedRecords'](record, rootEl)
414
436
  }
437
+
415
438
  fieldChanged('otherLanguages') &&
416
439
  this.writers['otherLanguages'](record, rootEl)
417
440