geonetwork-ui 2.10.0-dev.cf0577fae → 2.10.0-dev.d26e9afe1

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 (101) hide show
  1. package/fesm2022/geonetwork-ui.mjs +1035 -6108
  2. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  3. package/index.d.ts +147 -154
  4. package/index.d.ts.map +1 -1
  5. package/material-styles.css +483 -0
  6. package/package.json +25 -35
  7. package/src/libs/api/metadata-converter/src/lib/gn4/atomic-operations.ts +48 -7
  8. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +5 -4
  9. package/src/libs/api/metadata-converter/src/lib/gn4/metadata-url.service.ts +2 -2
  10. package/src/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.ts +1 -0
  11. package/src/libs/api/repository/src/lib/gn4/auth/auth.service.ts +4 -4
  12. package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +2 -2
  13. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +49 -35
  14. package/src/libs/api/repository/src/lib/gn4/organizations/organizations-from-groups.service.ts +1 -1
  15. package/src/libs/api/repository/src/lib/gn4/organizations/organizations-from-metadata.service.ts +1 -1
  16. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +48 -2
  17. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +2 -5
  18. package/src/libs/common/domain/src/lib/model/thesaurus/thesaurus.model.ts +2 -1
  19. package/src/libs/common/domain/src/lib/model/user/group.model.ts +8 -0
  20. package/src/libs/common/domain/src/lib/model/user/index.ts +1 -0
  21. package/src/libs/common/domain/src/lib/platform.service.interface.ts +2 -0
  22. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +51 -0
  23. package/src/libs/feature/catalog/src/lib/sources/sources.service.ts +5 -2
  24. package/src/libs/feature/editor/src/lib/+state/editor.actions.ts +4 -1
  25. package/src/libs/feature/editor/src/lib/+state/editor.effects.ts +26 -19
  26. package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +5 -1
  27. package/src/libs/feature/editor/src/lib/components/constraint-card/constraint-card.component.ts +0 -2
  28. package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.html +5 -5
  29. package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.ts +2 -1
  30. package/src/libs/feature/editor/src/lib/components/record-form/form-field/field-focus.directive.ts +4 -1
  31. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-constraints-shortcuts/form-field-constraints-shortcuts.component.ts +6 -7
  32. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.ts +1 -1
  33. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.ts +12 -5
  34. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.html +4 -4
  35. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.ts +7 -0
  36. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-topics/form-field-topics.component.ts +2 -2
  37. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html +6 -2
  38. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.ts +3 -1
  39. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.css +0 -34
  40. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +20 -16
  41. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +9 -0
  42. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.css +35 -0
  43. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.html +18 -5
  44. package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.ts +76 -19
  45. package/src/libs/feature/editor/src/lib/expressions.ts +380 -8
  46. package/src/libs/feature/editor/src/lib/fields.config.ts +310 -336
  47. package/src/libs/feature/editor/src/lib/models/editor-config.model.ts +2 -3
  48. package/src/libs/feature/editor/src/lib/services/editor.service.ts +8 -12
  49. package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +33 -0
  50. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +9 -1
  51. package/src/libs/feature/search/src/lib/results-table/results-table-container.component.ts +10 -5
  52. package/src/libs/ui/catalog/src/lib/language-switcher/language-switcher.component.ts +2 -2
  53. package/src/libs/ui/dataviz/src/index.ts +0 -1
  54. package/src/libs/ui/elements/src/lib/contact-details/contact-details.component.html +48 -56
  55. package/src/libs/ui/elements/src/lib/contact-pill/contact-pill.component.html +7 -3
  56. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.css +13 -0
  57. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.html +13 -3
  58. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.ts +43 -6
  59. package/src/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.ts +2 -2
  60. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +18 -8
  61. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.ts +29 -1
  62. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html +4 -5
  63. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +4 -0
  64. package/src/libs/ui/inputs/src/lib/button/button.component.ts +4 -0
  65. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.ts +2 -2
  66. package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.html +1 -1
  67. package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.ts +3 -3
  68. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.html +5 -5
  69. package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.ts +9 -1
  70. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.html +1 -1
  71. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.ts +3 -8
  72. package/src/libs/ui/layout/src/lib/sortable-list/sortable-list.component.html +7 -7
  73. package/src/libs/ui/layout/src/lib/sortable-list/sortable-list.component.ts +14 -1
  74. package/src/libs/ui/map/src/lib/components/spatial-extent/spatial-extent.component.ts +4 -54
  75. package/src/libs/ui/map/src/lib/map-utils.ts +48 -0
  76. package/src/libs/ui/search/src/lib/record-preview-feed/record-preview-feed.component.ts +1 -1
  77. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.html +12 -8
  78. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.ts +3 -1
  79. package/src/libs/ui/search/src/lib/results-table/results-table.component.html +1 -0
  80. package/src/libs/ui/widgets/src/lib/popover/popover.component.ts +7 -1
  81. package/src/libs/util/app-config/src/lib/app-config.ts +21 -9
  82. package/src/libs/util/data-fetcher/src/lib/readers/base-file.ts +1 -2
  83. package/src/libs/util/data-fetcher/src/lib/readers/wfs.ts +6 -3
  84. package/src/libs/util/i18n/src/index.ts +0 -1
  85. package/src/libs/util/i18n/src/lib/i18n.constants.ts +17 -11
  86. package/src/libs/util/i18n/src/lib/i18n.interceptor.ts +2 -2
  87. package/src/libs/util/i18n/src/lib/i18n.providers.ts +14 -17
  88. package/src/libs/util/i18n/src/lib/test.translate.loader.ts +48 -0
  89. package/src/libs/util/shared/src/lib/links/link-utils.ts +1 -1
  90. package/src/libs/util/shared/src/lib/services/date.service.ts +3 -3
  91. package/src/libs/util/shared/src/lib/utils/geojson.ts +58 -1
  92. package/style.css +0 -1
  93. package/tailwind.base.css +8 -0
  94. package/translations/de.json +50 -47
  95. package/translations/en.json +55 -52
  96. package/translations/es.json +24 -21
  97. package/translations/fr.json +50 -47
  98. package/translations/it.json +50 -47
  99. package/translations/nl.json +23 -20
  100. package/translations/pt.json +24 -21
  101. package/translations/sk.json +24 -21
@@ -0,0 +1,483 @@
1
+ /* These classes were extracted from the full Material theme to save size */
2
+ .cdk-overlay-pane {
3
+ position: absolute;
4
+ pointer-events: auto;
5
+ box-sizing: border-box;
6
+ z-index: 1000;
7
+ display: flex;
8
+ max-width: 100%;
9
+ max-height: 100%;
10
+ }
11
+
12
+ .cdk-overlay-connected-position-bounding-box {
13
+ position: absolute;
14
+ z-index: 1000;
15
+ display: flex;
16
+ flex-direction: column;
17
+ min-width: 1px;
18
+ min-height: 1px;
19
+ }
20
+
21
+ .cdk-overlay-backdrop {
22
+ position: absolute;
23
+ top: 0;
24
+ bottom: 0;
25
+ left: 0;
26
+ right: 0;
27
+ z-index: 1000;
28
+ pointer-events: auto;
29
+ transition: opacity 400ms cubic-bezier(0.25, 0.8, 0.25, 1);
30
+ opacity: 0;
31
+ }
32
+
33
+ .cdk-overlay-backdrop.cdk-overlay-backdrop-showing {
34
+ opacity: 1;
35
+ }
36
+
37
+ .cdk-overlay-transparent-backdrop {
38
+ transition:
39
+ visibility 1ms linear,
40
+ opacity 1ms linear;
41
+ visibility: hidden;
42
+ opacity: 1;
43
+ }
44
+
45
+ .cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing {
46
+ opacity: 0;
47
+ visibility: visible;
48
+ }
49
+
50
+ .mat-mdc-option.suggestion.mat-mdc-option-active {
51
+ background-color: var(--color-primary-lightest);
52
+ }
53
+
54
+ /* TODO(mdc-migration): The following rule targets internal classes of autocomplete that may no longer apply for the MDC version. */
55
+ .mat-mdc-autocomplete-panel
56
+ .mat-mdc-option.mat-selected:not(.mat-active):not(:hover):not(
57
+ .mat-option-disabled
58
+ ) {
59
+ color: rgba(0, 0, 0, 0.87);
60
+ }
61
+
62
+ .mat-mdc-option:hover:not(.mat-option-disabled),
63
+ .mat-mdc-option:focus:not(.mat-option-disabled) {
64
+ background: rgba(0, 0, 0, 0.04);
65
+ }
66
+
67
+ /* TODO(mdc-migration): The following rule targets internal classes of option that may no longer apply for the MDC version. */
68
+ .mat-mdc-option.mat-selected:not(.mat-mdc-option-multiple):not(
69
+ .mat-option-disabled
70
+ ) {
71
+ background: rgba(0, 0, 0, 0.04);
72
+ }
73
+
74
+ .mat-mdc-select-panel
75
+ .mat-mdc-option.mat-selected:not(.mat-mdc-option-multiple) {
76
+ background: rgba(0, 0, 0, 0.12);
77
+ }
78
+
79
+ .mdc-menu-surface.mat-mdc-autocomplete-panel {
80
+ margin-top: 10px !important;
81
+ border-radius: 8px;
82
+ background: white;
83
+ box-shadow:
84
+ 0 2px 4px -1px #0003,
85
+ 0 4px 5px #00000024,
86
+ 0 1px 10px #0000001f;
87
+ }
88
+
89
+ /* set up CSS variables for material (extracted from the prebuilt theme) */
90
+ :host {
91
+ --mat-tab-container-height: 48px;
92
+ --mat-tab-divider-color: transparent;
93
+ --mat-tab-divider-height: 0;
94
+ --mat-tab-active-indicator-height: 2px;
95
+ --mat-tab-active-indicator-shape: 0;
96
+ --mat-checkbox-disabled-selected-checkmark-color: white;
97
+ --mat-checkbox-selected-focus-state-layer-opacity: 0.12;
98
+ --mat-checkbox-selected-hover-state-layer-opacity: 0.04;
99
+ --mat-checkbox-selected-pressed-state-layer-opacity: 0.12;
100
+ --mat-checkbox-unselected-focus-state-layer-opacity: 0.12;
101
+ --mat-checkbox-unselected-hover-state-layer-opacity: 0.04;
102
+ --mat-checkbox-unselected-pressed-state-layer-opacity: 0.12;
103
+ --mat-checkbox-touch-target-size: 48px;
104
+ --mat-checkbox-disabled-label-color: color-mix(
105
+ in srgb,
106
+ rgba(0, 0, 0, 0.87) 38%,
107
+ transparent
108
+ );
109
+ --mat-checkbox-label-text-color: rgba(0, 0, 0, 0.87);
110
+ --mat-checkbox-disabled-selected-icon-color: color-mix(
111
+ in srgb,
112
+ rgba(0, 0, 0, 0.87) 38%,
113
+ transparent
114
+ );
115
+ --mat-checkbox-disabled-unselected-icon-color: color-mix(
116
+ in srgb,
117
+ rgba(0, 0, 0, 0.87) 38%,
118
+ transparent
119
+ );
120
+ --mat-checkbox-selected-checkmark-color: white;
121
+ --mat-checkbox-selected-focus-icon-color: #ff4081;
122
+ --mat-checkbox-selected-hover-icon-color: #ff4081;
123
+ --mat-checkbox-selected-icon-color: #ff4081;
124
+ --mat-checkbox-selected-pressed-icon-color: #ff4081;
125
+ --mat-checkbox-unselected-focus-icon-color: rgba(0, 0, 0, 0.87);
126
+ --mat-checkbox-unselected-hover-icon-color: rgba(0, 0, 0, 0.87);
127
+ --mat-checkbox-unselected-icon-color: rgba(0, 0, 0, 0.54);
128
+ --mat-checkbox-selected-focus-state-layer-color: #ff4081;
129
+ --mat-checkbox-selected-hover-state-layer-color: #ff4081;
130
+ --mat-checkbox-selected-pressed-state-layer-color: #ff4081;
131
+ --mat-checkbox-unselected-focus-state-layer-color: rgba(0, 0, 0, 0.87);
132
+ --mat-checkbox-unselected-hover-state-layer-color: rgba(0, 0, 0, 0.87);
133
+ --mat-checkbox-unselected-pressed-state-layer-color: rgba(0, 0, 0, 0.87);
134
+ --mat-checkbox-touch-target-display: block;
135
+ --mat-checkbox-state-layer-size: 40px;
136
+ --mat-checkbox-label-text-font: Roboto, sans-serif;
137
+ --mat-checkbox-label-text-line-height: 20px;
138
+ --mat-checkbox-label-text-size: 14px;
139
+ --mat-checkbox-label-text-tracking: 0.0178571429em;
140
+ --mat-checkbox-label-text-weight: 400;
141
+ --mat-button-filled-container-shape: 4px;
142
+ --mat-button-filled-horizontal-padding: 16px;
143
+ --mat-button-filled-icon-offset: -4px;
144
+ --mat-button-filled-icon-spacing: 8px;
145
+ --mat-button-filled-touch-target-size: 48px;
146
+ --mat-button-outlined-container-shape: 4px;
147
+ --mat-button-outlined-horizontal-padding: 15px;
148
+ --mat-button-outlined-icon-offset: -4px;
149
+ --mat-button-outlined-icon-spacing: 8px;
150
+ --mat-button-outlined-keep-touch-target: false;
151
+ --mat-button-outlined-outline-width: 1px;
152
+ --mat-button-outlined-touch-target-size: 48px;
153
+ --mat-button-protected-container-elevation-shadow: 0px 3px 1px -2px
154
+ rgba(0, 0, 0, 0.2),
155
+ 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
156
+ --mat-button-protected-container-shape: 4px;
157
+ --mat-button-protected-disabled-container-elevation-shadow: 0px 0px 0px 0px
158
+ rgba(0, 0, 0, 0.2),
159
+ 0px 0px 0px 0px rgba(0, 0, 0, 0.14), 0px 0px 0px 0px rgba(0, 0, 0, 0.12);
160
+ --mat-button-protected-focus-container-elevation-shadow: 0px 2px 4px -1px
161
+ rgba(0, 0, 0, 0.2),
162
+ 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12);
163
+ --mat-button-protected-horizontal-padding: 16px;
164
+ --mat-button-protected-hover-container-elevation-shadow: 0px 2px 4px -1px
165
+ rgba(0, 0, 0, 0.2),
166
+ 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12);
167
+ --mat-button-protected-icon-offset: -4px;
168
+ --mat-button-protected-icon-spacing: 8px;
169
+ --mat-button-protected-pressed-container-elevation-shadow: 0px 5px 5px -3px
170
+ rgba(0, 0, 0, 0.2),
171
+ 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12);
172
+ --mat-button-protected-touch-target-size: 48px;
173
+ --mat-button-text-container-shape: 4px;
174
+ --mat-button-text-horizontal-padding: 8px;
175
+ --mat-button-text-icon-offset: 0;
176
+ --mat-button-text-icon-spacing: 8px;
177
+ --mat-button-text-with-icon-horizontal-padding: 8px;
178
+ --mat-button-text-touch-target-size: 48px;
179
+ --mat-button-tonal-container-shape: 4px;
180
+ --mat-button-tonal-horizontal-padding: 16px;
181
+ --mat-button-tonal-icon-offset: -4px;
182
+ --mat-button-tonal-icon-spacing: 8px;
183
+ --mat-button-tonal-touch-target-size: 48px;
184
+ --mat-button-filled-container-color: white;
185
+ --mat-button-filled-disabled-container-color: color-mix(
186
+ in srgb,
187
+ rgba(0, 0, 0, 0.87) 12%,
188
+ transparent
189
+ );
190
+ --mat-button-filled-disabled-label-text-color: color-mix(
191
+ in srgb,
192
+ rgba(0, 0, 0, 0.87) 38%,
193
+ transparent
194
+ );
195
+ --mat-button-filled-disabled-state-layer-color: rgba(0, 0, 0, 0.54);
196
+ --mat-button-filled-focus-state-layer-opacity: 0.12;
197
+ --mat-button-filled-hover-state-layer-opacity: 0.04;
198
+ --mat-button-filled-label-text-color: rgba(0, 0, 0, 0.87);
199
+ --mat-button-filled-pressed-state-layer-opacity: 0.12;
200
+ --mat-button-filled-ripple-color: color-mix(
201
+ in srgb,
202
+ rgba(0, 0, 0, 0.87) 12%,
203
+ transparent
204
+ );
205
+ --mat-button-filled-state-layer-color: rgba(0, 0, 0, 0.87);
206
+ --mat-button-outlined-disabled-label-text-color: color-mix(
207
+ in srgb,
208
+ rgba(0, 0, 0, 0.87) 38%,
209
+ transparent
210
+ );
211
+ --mat-button-outlined-disabled-outline-color: rgba(0, 0, 0, 0.12);
212
+ --mat-button-outlined-disabled-state-layer-color: rgba(0, 0, 0, 0.54);
213
+ --mat-button-outlined-focus-state-layer-opacity: 0.12;
214
+ --mat-button-outlined-hover-state-layer-opacity: 0.04;
215
+ --mat-button-outlined-label-text-color: rgba(0, 0, 0, 0.87);
216
+ --mat-button-outlined-outline-color: rgba(0, 0, 0, 0.12);
217
+ --mat-button-outlined-pressed-state-layer-opacity: 0.12;
218
+ --mat-button-outlined-ripple-color: color-mix(
219
+ in srgb,
220
+ rgba(0, 0, 0, 0.87) 12%,
221
+ transparent
222
+ );
223
+ --mat-button-outlined-state-layer-color: rgba(0, 0, 0, 0.87);
224
+ --mat-button-protected-container-color: white;
225
+ --mat-button-protected-disabled-container-color: color-mix(
226
+ in srgb,
227
+ rgba(0, 0, 0, 0.87) 12%,
228
+ transparent
229
+ );
230
+ --mat-button-protected-disabled-label-text-color: color-mix(
231
+ in srgb,
232
+ rgba(0, 0, 0, 0.87) 38%,
233
+ transparent
234
+ );
235
+ --mat-button-protected-disabled-state-layer-color: rgba(0, 0, 0, 0.54);
236
+ --mat-button-protected-focus-state-layer-opacity: 0.12;
237
+ --mat-button-protected-hover-state-layer-opacity: 0.04;
238
+ --mat-button-protected-label-text-color: rgba(0, 0, 0, 0.87);
239
+ --mat-button-protected-pressed-state-layer-opacity: 0.12;
240
+ --mat-button-protected-ripple-color: color-mix(
241
+ in srgb,
242
+ rgba(0, 0, 0, 0.87) 12%,
243
+ transparent
244
+ );
245
+ --mat-button-protected-state-layer-color: rgba(0, 0, 0, 0.87);
246
+ --mat-button-text-disabled-label-text-color: color-mix(
247
+ in srgb,
248
+ rgba(0, 0, 0, 0.87) 38%,
249
+ transparent
250
+ );
251
+ --mat-button-text-disabled-state-layer-color: rgba(0, 0, 0, 0.54);
252
+ --mat-button-text-focus-state-layer-opacity: 0.12;
253
+ --mat-button-text-hover-state-layer-opacity: 0.04;
254
+ --mat-button-text-label-text-color: rgba(0, 0, 0, 0.87);
255
+ --mat-button-text-pressed-state-layer-opacity: 0.12;
256
+ --mat-button-text-ripple-color: color-mix(
257
+ in srgb,
258
+ rgba(0, 0, 0, 0.87) 12%,
259
+ transparent
260
+ );
261
+ --mat-button-text-state-layer-color: rgba(0, 0, 0, 0.87);
262
+ --mat-button-tonal-container-color: white;
263
+ --mat-button-tonal-disabled-container-color: color-mix(
264
+ in srgb,
265
+ rgba(0, 0, 0, 0.87) 12%,
266
+ transparent
267
+ );
268
+ --mat-button-tonal-disabled-label-text-color: color-mix(
269
+ in srgb,
270
+ rgba(0, 0, 0, 0.87) 38%,
271
+ transparent
272
+ );
273
+ --mat-button-tonal-disabled-state-layer-color: rgba(0, 0, 0, 0.54);
274
+ --mat-button-tonal-focus-state-layer-opacity: 0.12;
275
+ --mat-button-tonal-hover-state-layer-opacity: 0.04;
276
+ --mat-button-tonal-label-text-color: rgba(0, 0, 0, 0.87);
277
+ --mat-button-tonal-pressed-state-layer-opacity: 0.12;
278
+ --mat-button-tonal-ripple-color: color-mix(
279
+ in srgb,
280
+ rgba(0, 0, 0, 0.87) 12%,
281
+ transparent
282
+ );
283
+ --mat-button-tonal-state-layer-color: rgba(0, 0, 0, 0.87);
284
+ --mat-button-filled-container-height: 36px;
285
+ --mat-button-filled-touch-target-display: block;
286
+ --mat-button-outlined-container-height: 36px;
287
+ --mat-button-outlined-touch-target-display: block;
288
+ --mat-button-protected-container-height: 36px;
289
+ --mat-button-protected-touch-target-display: block;
290
+ --mat-button-text-container-height: 36px;
291
+ --mat-button-text-touch-target-display: block;
292
+ --mat-button-tonal-container-height: 36px;
293
+ --mat-button-tonal-touch-target-display: block;
294
+ --mat-button-filled-label-text-font: Roboto, sans-serif;
295
+ --mat-button-filled-label-text-size: 14px;
296
+ --mat-button-filled-label-text-tracking: 0.0892857143em;
297
+ --mat-button-filled-label-text-transform: none;
298
+ --mat-button-filled-label-text-weight: 500;
299
+ --mat-button-outlined-label-text-font: Roboto, sans-serif;
300
+ --mat-button-outlined-label-text-size: 14px;
301
+ --mat-button-outlined-label-text-tracking: 0.0892857143em;
302
+ --mat-button-outlined-label-text-transform: none;
303
+ --mat-button-outlined-label-text-weight: 500;
304
+ --mat-button-protected-label-text-font: Roboto, sans-serif;
305
+ --mat-button-protected-label-text-size: 14px;
306
+ --mat-button-protected-label-text-tracking: 0.0892857143em;
307
+ --mat-button-protected-label-text-transform: none;
308
+ --mat-button-protected-label-text-weight: 500;
309
+ --mat-button-text-label-text-font: Roboto, sans-serif;
310
+ --mat-button-text-label-text-size: 14px;
311
+ --mat-button-text-label-text-tracking: 0.0892857143em;
312
+ --mat-button-text-label-text-transform: none;
313
+ --mat-button-text-label-text-weight: 500;
314
+ --mat-button-tonal-label-text-font: Roboto, sans-serif;
315
+ --mat-button-tonal-label-text-size: 14px;
316
+ --mat-button-tonal-label-text-tracking: 0.0892857143em;
317
+ --mat-button-tonal-label-text-transform: none;
318
+ --mat-button-tonal-label-text-weight: 500;
319
+ --mat-progress-spinner-active-indicator-width: 4px;
320
+ --mat-progress-spinner-size: 48px;
321
+ --mat-progress-spinner-active-indicator-color: #3f51b5;
322
+ --mat-option-selected-state-label-text-color: #3f51b5;
323
+ --mat-option-label-text-color: rgba(0, 0, 0, 0.87);
324
+ --mat-option-hover-state-layer-color: color-mix(
325
+ in srgb,
326
+ rgba(0, 0, 0, 0.87) 4%,
327
+ transparent
328
+ );
329
+ --mat-option-focus-state-layer-color: color-mix(
330
+ in srgb,
331
+ rgba(0, 0, 0, 0.87) 12%,
332
+ transparent
333
+ );
334
+ --mat-option-selected-state-layer-color: color-mix(
335
+ in srgb,
336
+ rgba(0, 0, 0, 0.87) 12%,
337
+ transparent
338
+ );
339
+ --mat-dialog-container-shape: 4px;
340
+ --mat-dialog-container-elevation-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2),
341
+ 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12);
342
+ --mat-dialog-container-max-width: 80vw;
343
+ --mat-dialog-container-small-max-width: 80vw;
344
+ --mat-dialog-container-min-width: 0;
345
+ --mat-dialog-actions-alignment: start;
346
+ --mat-dialog-actions-padding: 8px;
347
+ --mat-dialog-content-padding: 20px 24px;
348
+ --mat-dialog-with-actions-content-padding: 20px 24px;
349
+ --mat-dialog-headline-padding: 0 24px 9px;
350
+ --mat-dialog-container-color: white;
351
+ --mat-dialog-subhead-color: rgba(0, 0, 0, 0.87);
352
+ --mat-dialog-supporting-text-color: rgba(0, 0, 0, 0.54);
353
+ --mat-dialog-subhead-font: Roboto, sans-serif;
354
+ --mat-dialog-subhead-line-height: 32px;
355
+ --mat-dialog-subhead-size: 20px;
356
+ --mat-dialog-subhead-weight: 500;
357
+ --mat-dialog-subhead-tracking: 0.0125em;
358
+ --mat-dialog-supporting-text-font: Roboto, sans-serif;
359
+ --mat-dialog-supporting-text-line-height: 24px;
360
+ --mat-dialog-supporting-text-size: 16px;
361
+ --mat-dialog-supporting-text-weight: 400;
362
+ --mat-dialog-supporting-text-tracking: 0.03125em;
363
+ --mat-tooltip-container-shape: 4px;
364
+ --mat-tooltip-supporting-text-line-height: 16px;
365
+ --mat-tooltip-container-color: #424242;
366
+ --mat-tooltip-supporting-text-color: white;
367
+ --mat-tooltip-supporting-text-font: Roboto, sans-serif;
368
+ --mat-tooltip-supporting-text-size: 12px;
369
+ --mat-tooltip-supporting-text-weight: 400;
370
+ --mat-tooltip-supporting-text-tracking: 0.0333333333em;
371
+ --mat-radio-disabled-selected-icon-opacity: 0.38;
372
+ --mat-radio-disabled-unselected-icon-opacity: 0.38;
373
+ --mat-radio-state-layer-size: 40px;
374
+ --mat-radio-touch-target-size: 48px;
375
+ --mat-sort-arrow-color: rgba(0, 0, 0, 0.87);
376
+ --mat-paginator-page-size-select-width: 84px;
377
+ --mat-paginator-page-size-select-touch-target-height: 48px;
378
+ --mat-paginator-container-text-color: rgba(0, 0, 0, 0.87);
379
+ --mat-paginator-container-background-color: white;
380
+ --mat-paginator-enabled-icon-color: rgba(0, 0, 0, 0.54);
381
+ --mat-paginator-disabled-icon-color: color-mix(
382
+ in srgb,
383
+ rgba(0, 0, 0, 0.87) 38%,
384
+ transparent
385
+ );
386
+ --mat-paginator-container-size: 56px;
387
+ --mat-paginator-form-field-container-height: 40px;
388
+ --mat-paginator-form-field-container-vertical-padding: 8px;
389
+ --mat-paginator-touch-target-display: block;
390
+ --mat-paginator-container-text-font: Roboto, sans-serif;
391
+ --mat-paginator-container-text-line-height: 20px;
392
+ --mat-paginator-container-text-size: 12px;
393
+ --mat-paginator-container-text-tracking: 0.0333333333em;
394
+ --mat-paginator-container-text-weight: 400;
395
+ --mat-paginator-select-trigger-text-size: 12px;
396
+ --mat-autocomplete-container-shape: 4px;
397
+ --mat-autocomplete-container-elevation-shadow: 0px 5px 5px -3px
398
+ rgba(0, 0, 0, 0.2),
399
+ 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12);
400
+ --mat-autocomplete-background-color: white;
401
+ --mat-datepicker-calendar-container-shape: 4px;
402
+ --mat-datepicker-calendar-container-touch-shape: 4px;
403
+ --mat-datepicker-calendar-container-elevation-shadow: 0px 2px 4px -1px
404
+ rgba(0, 0, 0, 0.2),
405
+ 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12);
406
+ --mat-datepicker-calendar-container-touch-elevation-shadow: 0px 11px 15px -7px
407
+ rgba(0, 0, 0, 0.2),
408
+ 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12);
409
+ --mat-datepicker-calendar-date-in-range-state-background-color: color-mix(
410
+ in srgb,
411
+ #3f51b5 20%,
412
+ transparent
413
+ );
414
+ --mat-datepicker-calendar-date-in-comparison-range-state-background-color: color-mix(
415
+ in srgb,
416
+ #ff4081 20%,
417
+ transparent
418
+ );
419
+ --mat-datepicker-calendar-date-in-overlap-range-state-background-color: #a8dab5;
420
+ --mat-datepicker-calendar-date-in-overlap-range-selected-state-background-color: rgb(
421
+ 69.5241935484,
422
+ 163.4758064516,
423
+ 93.9516129032
424
+ );
425
+ --mat-datepicker-calendar-date-selected-state-text-color: white;
426
+ --mat-datepicker-calendar-date-selected-state-background-color: #3f51b5;
427
+ --mat-datepicker-calendar-date-selected-disabled-state-background-color: color-mix(
428
+ in srgb,
429
+ #3f51b5 38%,
430
+ transparent
431
+ );
432
+ --mat-datepicker-calendar-date-today-selected-state-outline-color: white;
433
+ --mat-datepicker-calendar-date-focus-state-background-color: color-mix(
434
+ in srgb,
435
+ #3f51b5 12%,
436
+ transparent
437
+ );
438
+ --mat-datepicker-calendar-date-hover-state-background-color: color-mix(
439
+ in srgb,
440
+ #3f51b5 4%,
441
+ transparent
442
+ );
443
+ --mat-datepicker-toggle-active-state-icon-color: #3f51b5;
444
+ --mat-datepicker-toggle-icon-color: rgba(0, 0, 0, 0.54);
445
+ --mat-datepicker-calendar-body-label-text-color: rgba(0, 0, 0, 0.54);
446
+ --mat-datepicker-calendar-period-button-text-color: rgba(0, 0, 0, 0.87);
447
+ --mat-datepicker-calendar-period-button-icon-color: rgba(0, 0, 0, 0.54);
448
+ --mat-datepicker-calendar-navigation-button-icon-color: rgba(0, 0, 0, 0.54);
449
+ --mat-datepicker-calendar-header-divider-color: rgba(0, 0, 0, 0.12);
450
+ --mat-datepicker-calendar-header-text-color: rgba(0, 0, 0, 0.54);
451
+ --mat-datepicker-calendar-date-today-outline-color: rgba(0, 0, 0, 0.54);
452
+ --mat-datepicker-calendar-date-today-disabled-state-outline-color: color-mix(
453
+ in srgb,
454
+ rgba(0, 0, 0, 0.87) 38%,
455
+ transparent
456
+ );
457
+ --mat-datepicker-calendar-date-text-color: rgba(0, 0, 0, 0.87);
458
+ --mat-datepicker-calendar-date-outline-color: transparent;
459
+ --mat-datepicker-calendar-date-disabled-state-text-color: color-mix(
460
+ in srgb,
461
+ rgba(0, 0, 0, 0.87) 38%,
462
+ transparent
463
+ );
464
+ --mat-datepicker-calendar-date-preview-state-outline-color: rgba(
465
+ 0,
466
+ 0,
467
+ 0,
468
+ 0.54
469
+ );
470
+ --mat-datepicker-range-input-separator-color: rgba(0, 0, 0, 0.87);
471
+ --mat-datepicker-range-input-disabled-state-separator-color: color-mix(
472
+ in srgb,
473
+ rgba(0, 0, 0, 0.87) 38%,
474
+ transparent
475
+ );
476
+ --mat-datepicker-range-input-disabled-state-text-color: color-mix(
477
+ in srgb,
478
+ rgba(0, 0, 0, 0.87) 38%,
479
+ transparent
480
+ );
481
+ --mat-datepicker-calendar-container-background-color: white;
482
+ --mat-datepicker-calendar-container-text-color: rgba(0, 0, 0, 0.87);
483
+ }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "geonetwork-ui",
3
- "version": "2.10.0-dev.cf0577fae",
3
+ "version": "2.10.0-dev.d26e9afe1",
4
4
  "engines": {
5
- "node": ">=20"
5
+ "node": ">=24"
6
6
  },
7
7
  "main": "./index.ts",
8
8
  "type": "module",
@@ -28,7 +28,6 @@
28
28
  "@angular/core": "19.x || 20.x || 21.x",
29
29
  "@angular/forms": "19.x || 20.x || 21.x",
30
30
  "@angular/material": "19.x || 20.x || 21.x",
31
- "@angular/material-moment-adapter": "19.x || 20.x || 21.x",
32
31
  "@angular/platform-browser": "19.x || 20.x || 21.x",
33
32
  "@angular/platform-browser-dynamic": "19.x || 20.x || 21.x",
34
33
  "@angular/router": "19.x || 20.x || 21.x",
@@ -47,46 +46,37 @@
47
46
  },
48
47
  "dependencies": {
49
48
  "@biesbjerg/ngx-translate-extract-marker": "~1.0.0",
50
- "@camptocamp/ogc-client": "1.3.1-dev.afd9c26",
49
+ "@camptocamp/ogc-client": "1.3.1-dev.bb345f0",
51
50
  "@geospatial-sdk/core": "0.0.5-dev.61",
52
51
  "@geospatial-sdk/geocoding": "0.0.5-dev.61",
53
52
  "@geospatial-sdk/legend": "0.0.5-dev.61",
54
53
  "@geospatial-sdk/openlayers": "0.0.5-dev.61",
55
- "@ltd/j-toml": "~1.35.2",
56
- "@messageformat/core": "^3.0.1",
57
- "@ng-icons/core": "29.10.0",
58
- "@ng-icons/iconoir": "29.10.0",
59
- "@ng-icons/material-icons": "29.10.0",
60
- "@ng-icons/tabler-icons": "29.10.0",
61
- "@nx/angular": "22.0.4",
54
+ "@ltd/j-toml": "~1.38.0",
55
+ "@messageformat/core": "~3.4.0",
56
+ "@ng-icons/core": "~32.5.0",
57
+ "@ng-icons/iconoir": "~32.5.0",
58
+ "@ng-icons/material-icons": "~32.5.0",
59
+ "@ng-icons/tabler-icons": "~32.4.0",
62
60
  "@rgrove/parse-xml": "4.2.0",
63
- "alasql": "4.6.0",
64
- "basiclightbox": "^5.0.4",
65
- "chart.js": "4.4.7",
66
- "chroma-js": "3.1.2",
61
+ "alasql": "~4.17.0",
62
+ "chart.js": "~4.5.1",
63
+ "chroma-js": "~3.2.0",
67
64
  "date-fns": "4.1.0",
68
- "document-register-element": "^1.14.10",
69
- "duration-relativetimeformat": "^2.0.4",
70
- "embla-carousel": "8.5.1",
71
- "express": "4.22.0",
72
- "geojson-validation": "^1.0.2",
73
- "marked": "15.0.4",
74
- "moment": "2.30.1",
75
- "ng-table-virtual-scroll": "1.6.1",
76
- "ngx-chips": "3.0.0",
77
- "ngx-dropzone": "3.1.0",
78
- "ngx-translate-messageformat-compiler": "~7.1.0",
79
- "ol": "^10.0.0",
80
- "papaparse": "5.4.1",
81
- "pg": "^8.9.0",
82
- "proj4": "^2.9.2",
83
- "rdflib": "^2.3.0",
84
- "reflect-metadata": "^0.1.13",
85
- "semver": "7.6.3",
65
+ "document-register-element": "~1.14.10",
66
+ "duration-relativetimeformat": "~2.0.4",
67
+ "embla-carousel": "~8.6.0",
68
+ "flag-icons": "~7.5.0",
69
+ "geojson-validation": "~1.0.2",
70
+ "marked": "~17.0.4",
71
+ "ngx-dropzone": "~3.1.0",
72
+ "ngx-translate-messageformat-compiler": "~7.2.0",
73
+ "ol": "~10.8.0",
74
+ "papaparse": "~5.5.3",
75
+ "proj4": "~2.20.4",
76
+ "rdflib": "~2.3.5",
77
+ "semver": "~7.7.4",
86
78
  "tippy.js": "6.3.7",
87
79
  "tslib": "^2.3.0",
88
- "typeorm": "^0.3.27",
89
- "whatwg-fetch": "^3.6.2",
90
80
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
91
81
  },
92
82
  "module": "fesm2022/geonetwork-ui.mjs",
@@ -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
  }
@@ -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> = {
@@ -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) => ({