geonetwork-ui 2.10.0-dev.91673b3ba → 2.10.0-dev.981f59a75
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.
- package/fesm2022/geonetwork-ui.mjs +1536 -6196
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/index.d.ts +257 -182
- package/index.d.ts.map +1 -1
- package/package.json +25 -35
- package/src/libs/api/metadata-converter/src/lib/dcat-ap/dcat-ap.converter.ts +9 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/eu.dcat-ap.records.ts +2 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.reuse+ongules.ts +7 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.reuse+roilaye.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/georhena.records.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/metadata-for-i18n.records.ts +2 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/opendataswiss.records.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/sextant.records.ts +2 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/vlaanderen.dcat-ap.records.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/fixtures/wallonie.records.reuse.ts +8 -0
- package/src/libs/api/metadata-converter/src/lib/gn4/atomic-operations.ts +48 -7
- package/src/libs/api/metadata-converter/src/lib/gn4/gn4.converter.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +6 -5
- package/src/libs/api/metadata-converter/src/lib/gn4/metadata-url.service.ts +2 -2
- package/src/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.ts +1 -0
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.ts +7 -0
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.ts +8 -0
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.ts +12 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +14 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +33 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +36 -0
- package/src/libs/api/repository/src/lib/gn4/auth/auth.service.ts +8 -4
- package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +2 -2
- package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +59 -37
- package/src/libs/api/repository/src/lib/gn4/organizations/organizations-from-groups.service.ts +1 -1
- package/src/libs/api/repository/src/lib/gn4/organizations/organizations-from-metadata.service.ts +1 -1
- package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +37 -2
- package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +13 -5
- package/src/libs/common/domain/src/lib/model/thesaurus/thesaurus.model.ts +2 -1
- package/src/libs/common/domain/src/lib/model/user/group.model.ts +8 -0
- package/src/libs/common/domain/src/lib/model/user/index.ts +1 -0
- package/src/libs/common/domain/src/lib/platform.service.interface.ts +2 -0
- package/src/libs/common/fixtures/src/lib/records.fixtures.ts +56 -0
- package/src/libs/feature/catalog/src/lib/sources/sources.service.ts +5 -2
- package/src/libs/feature/editor/src/lib/+state/editor.actions.ts +10 -1
- package/src/libs/feature/editor/src/lib/+state/editor.effects.ts +26 -19
- package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +15 -2
- package/src/libs/feature/editor/src/lib/components/constraint-card/constraint-card.component.ts +0 -2
- package/src/libs/feature/editor/src/lib/components/contact-details/contact-details-form.component.css +0 -0
- package/src/libs/feature/editor/src/lib/components/contact-details/contact-details-form.component.html +68 -0
- package/src/libs/feature/editor/src/lib/components/contact-details/contact-details-form.component.ts +39 -0
- package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.html +5 -14
- package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.ts +3 -28
- package/src/libs/feature/editor/src/lib/components/metadata-quality-panel/metadata-quality-panel.component.html +18 -3
- package/src/libs/feature/editor/src/lib/components/metadata-quality-panel/metadata-quality-panel.component.ts +33 -40
- package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.html +5 -5
- package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.ts +2 -1
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/field-focus.directive.ts +41 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-constraints-shortcuts/form-field-constraints-shortcuts.component.ts +33 -34
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts/form-field-contacts.component.html +9 -2
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts/form-field-contacts.component.ts +12 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-online-resources/form-field-online-resources.component.ts +1 -1
- 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
- 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
- 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
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-overviews/form-field-overviews.component.ts +12 -5
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.html +4 -4
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-rich/form-field-rich.component.ts +7 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-topics/form-field-topics.component.ts +2 -2
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html +6 -2
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.ts +3 -1
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.css +3 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +21 -16
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +14 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/index.ts +1 -0
- package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.css +35 -0
- package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.html +18 -5
- package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.ts +118 -5
- package/src/libs/feature/editor/src/lib/expressions.ts +380 -8
- package/src/libs/feature/editor/src/lib/fields.config.ts +310 -336
- package/src/libs/feature/editor/src/lib/models/editor-config.model.ts +6 -3
- package/src/libs/feature/editor/src/lib/services/editor.service.ts +9 -13
- package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +33 -0
- package/src/libs/feature/notify-reuse/src/index.ts +1 -0
- package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.css +0 -0
- package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.html +111 -0
- package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.ts +229 -0
- package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +9 -1
- package/src/libs/feature/search/src/lib/results-table/results-table-container.component.ts +10 -5
- package/src/libs/ui/catalog/src/lib/language-switcher/language-switcher.component.ts +2 -2
- package/src/libs/ui/dataviz/src/index.ts +0 -1
- package/src/libs/ui/elements/src/index.ts +2 -0
- package/src/libs/ui/elements/src/lib/contact-details/contact-details.component.html +88 -0
- package/src/libs/ui/elements/src/lib/contact-details/contact-details.component.ts +45 -0
- package/src/libs/ui/elements/src/lib/contact-pill/contact-pill.component.html +29 -4
- package/src/libs/ui/elements/src/lib/contact-pill/contact-pill.component.ts +51 -7
- package/src/libs/ui/elements/src/lib/external-link-card/external-link-card.component.html +2 -1
- package/src/libs/ui/elements/src/lib/external-link-card/external-link-card.component.ts +2 -2
- package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.css +13 -0
- package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.html +13 -3
- package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.ts +43 -6
- package/src/libs/ui/elements/src/lib/keyword-badge/keyword-badge.component.html +14 -0
- package/src/libs/ui/elements/src/lib/keyword-badge/keyword-badge.component.ts +85 -0
- package/src/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.ts +2 -2
- package/src/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.ts +2 -5
- package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.css +5 -0
- package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +7 -10
- package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.ts +2 -2
- package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html +4 -5
- package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +4 -0
- package/src/libs/ui/inputs/src/lib/badge/badge.component.html +33 -26
- package/src/libs/ui/inputs/src/lib/badge/badge.component.ts +9 -0
- package/src/libs/ui/inputs/src/lib/button/button.component.ts +4 -0
- package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.ts +2 -2
- package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.html +1 -1
- package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.ts +3 -3
- package/src/libs/ui/inputs/src/lib/text-input/text-input.component.css +0 -3
- package/src/libs/ui/inputs/src/lib/text-input/text-input.component.html +11 -7
- package/src/libs/ui/inputs/src/lib/text-input/text-input.component.ts +56 -30
- package/src/libs/ui/inputs/src/lib/url-input/url-input.component.html +2 -2
- package/src/libs/ui/inputs/src/lib/url-input/url-input.component.ts +2 -1
- package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.html +5 -5
- package/src/libs/ui/layout/src/lib/form-field-wrapper/form-field-wrapper.component.ts +9 -1
- package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.html +1 -1
- package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.ts +3 -8
- package/src/libs/ui/layout/src/lib/sortable-list/sortable-list.component.html +7 -7
- package/src/libs/ui/layout/src/lib/sortable-list/sortable-list.component.ts +14 -1
- package/src/libs/ui/map/src/lib/components/map-container/map-container.component.ts +2 -1
- package/src/libs/ui/map/src/lib/components/spatial-extent/spatial-extent.component.ts +15 -64
- package/src/libs/ui/map/src/lib/map-utils.ts +48 -0
- package/src/libs/ui/search/src/lib/record-preview-feed/record-preview-feed.component.ts +1 -1
- package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.html +12 -8
- package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.ts +3 -1
- package/src/libs/ui/search/src/lib/results-table/results-table.component.html +1 -0
- package/src/libs/ui/widgets/src/lib/popover/popover.component.ts +7 -1
- package/src/libs/ui/widgets/src/lib/spinning-loader/spinning-loader.component.html +1 -1
- package/src/libs/util/app-config/src/lib/app-config.ts +70 -9
- package/src/libs/util/app-config/src/lib/model.ts +7 -0
- package/src/libs/util/app-config/src/lib/parse-utils.ts +50 -1
- package/src/libs/util/data-fetcher/src/lib/readers/base-file.ts +1 -2
- package/src/libs/util/data-fetcher/src/lib/readers/wfs.ts +6 -3
- package/src/libs/util/i18n/src/index.ts +0 -1
- package/src/libs/util/i18n/src/lib/i18n.constants.ts +17 -11
- package/src/libs/util/i18n/src/lib/i18n.interceptor.ts +2 -2
- package/src/libs/util/i18n/src/lib/i18n.providers.ts +14 -17
- package/src/libs/util/i18n/src/lib/test.translate.loader.ts +48 -0
- package/src/libs/util/shared/src/lib/links/link-utils.ts +23 -1
- package/src/libs/util/shared/src/lib/record/quality-score.util.ts +33 -18
- package/src/libs/util/shared/src/lib/services/date.service.ts +3 -3
- package/src/libs/util/shared/src/lib/utils/geojson.ts +58 -1
- package/src/libs/util/shared/src/lib/utils/user-display.ts +9 -0
- package/style.css +0 -1
- package/tailwind.base.css +20 -2
- package/translations/de.json +93 -48
- package/translations/en.json +98 -53
- package/translations/es.json +67 -22
- package/translations/fr.json +95 -50
- package/translations/it.json +94 -49
- package/translations/nl.json +66 -21
- package/translations/pt.json +67 -22
- package/translations/sk.json +67 -22
- package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.css +0 -3
|
@@ -28,7 +28,13 @@ export class PopoverComponent implements AfterViewInit, OnChanges, OnDestroy {
|
|
|
28
28
|
|
|
29
29
|
@ViewChild('popoverContent', { static: false }) popoverContent: ElementRef
|
|
30
30
|
@Input() content: string | TemplateRef<any>
|
|
31
|
-
@Input() theme:
|
|
31
|
+
@Input() theme:
|
|
32
|
+
| 'light'
|
|
33
|
+
| 'light-border'
|
|
34
|
+
| 'translucent'
|
|
35
|
+
| 'material'
|
|
36
|
+
| 'dark'
|
|
37
|
+
| ''
|
|
32
38
|
|
|
33
39
|
private tippyInstance: Instance
|
|
34
40
|
private view: EmbeddedViewRef<any>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as TOML from '@ltd/j-toml'
|
|
2
2
|
import {
|
|
3
3
|
checkMetadataLanguage,
|
|
4
|
+
checkNewRecordDefaultLanguage,
|
|
5
|
+
checkNewRecordStandard,
|
|
4
6
|
parseConfigSection,
|
|
5
7
|
parseMultiConfigSection,
|
|
6
8
|
parseTranslationsConfigSection,
|
|
@@ -8,6 +10,7 @@ import {
|
|
|
8
10
|
import {
|
|
9
11
|
CustomTranslations,
|
|
10
12
|
CustomTranslationsAllLanguages,
|
|
13
|
+
EditorConfig,
|
|
11
14
|
GlobalConfig,
|
|
12
15
|
LayerConfig,
|
|
13
16
|
MapConfig,
|
|
@@ -15,10 +18,15 @@ import {
|
|
|
15
18
|
SearchConfig,
|
|
16
19
|
ThemeConfig,
|
|
17
20
|
} from './model'
|
|
18
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
TranslateCompiler,
|
|
23
|
+
TranslateLoader,
|
|
24
|
+
TranslateModuleConfig,
|
|
25
|
+
} from '@ngx-translate/core'
|
|
19
26
|
import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler'
|
|
20
|
-
import { HttpClient } from '@angular/common/http'
|
|
21
27
|
import { FileWithOverridesTranslateLoader } from './i18n/file-with-overrides.translate.loader'
|
|
28
|
+
import { TRANSLATE_HTTP_LOADER_CONFIG } from '@ngx-translate/http-loader'
|
|
29
|
+
import { HttpClient } from '@angular/common/http'
|
|
22
30
|
|
|
23
31
|
const MISSING_CONFIG_ERROR = `Application configuration was not initialized correctly.
|
|
24
32
|
This error might show up in case of an invalid/malformed configuration file.
|
|
@@ -51,6 +59,12 @@ export function getOptionalSearchConfig(): SearchConfig | null {
|
|
|
51
59
|
return searchConfig
|
|
52
60
|
}
|
|
53
61
|
|
|
62
|
+
let editorConfig: EditorConfig = null
|
|
63
|
+
|
|
64
|
+
export function getOptionalEditorConfig(): EditorConfig | null {
|
|
65
|
+
return editorConfig
|
|
66
|
+
}
|
|
67
|
+
|
|
54
68
|
let metadataQualityConfig: MetadataQualityConfig = null
|
|
55
69
|
export function getMetadataQualityConfig(): MetadataQualityConfig {
|
|
56
70
|
return (
|
|
@@ -285,6 +299,45 @@ export function loadAppConfig(configUrl = 'assets/configuration/default.toml') {
|
|
|
285
299
|
SORTABLE: parsedMetadataQualitySection.sortable,
|
|
286
300
|
} as MetadataQualityConfig)
|
|
287
301
|
|
|
302
|
+
let parsedEditingSection = parseConfigSection(
|
|
303
|
+
parsed,
|
|
304
|
+
'editing',
|
|
305
|
+
[],
|
|
306
|
+
['new_record_default_language', 'new_record_standard'],
|
|
307
|
+
warnings,
|
|
308
|
+
errors
|
|
309
|
+
)
|
|
310
|
+
if (
|
|
311
|
+
parsedEditingSection !== null &&
|
|
312
|
+
parsedEditingSection.new_record_default_language !== undefined
|
|
313
|
+
) {
|
|
314
|
+
parsedEditingSection = checkNewRecordDefaultLanguage(
|
|
315
|
+
parsedEditingSection,
|
|
316
|
+
warnings
|
|
317
|
+
)
|
|
318
|
+
}
|
|
319
|
+
if (
|
|
320
|
+
parsedEditingSection !== null &&
|
|
321
|
+
parsedEditingSection.new_record_standard !== undefined
|
|
322
|
+
) {
|
|
323
|
+
parsedEditingSection = checkNewRecordStandard(
|
|
324
|
+
parsedEditingSection,
|
|
325
|
+
warnings
|
|
326
|
+
)
|
|
327
|
+
}
|
|
328
|
+
editorConfig =
|
|
329
|
+
parsedEditingSection === null
|
|
330
|
+
? null
|
|
331
|
+
: ({
|
|
332
|
+
NEW_RECORD_DEFAULT_LANGUAGE:
|
|
333
|
+
parsedEditingSection.new_record_default_language as
|
|
334
|
+
| string
|
|
335
|
+
| undefined,
|
|
336
|
+
NEW_RECORD_STANDARD: parsedEditingSection.new_record_standard as
|
|
337
|
+
| EditorConfig['NEW_RECORD_STANDARD']
|
|
338
|
+
| undefined,
|
|
339
|
+
} as EditorConfig)
|
|
340
|
+
|
|
288
341
|
customTranslations = parseTranslationsConfigSection(
|
|
289
342
|
parsed,
|
|
290
343
|
'translations'
|
|
@@ -309,19 +362,27 @@ export function isConfigLoaded() {
|
|
|
309
362
|
export function _reset() {
|
|
310
363
|
globalConfig = null
|
|
311
364
|
themeConfig = null
|
|
365
|
+
editorConfig = null
|
|
312
366
|
customTranslations = null
|
|
313
367
|
}
|
|
314
368
|
|
|
315
|
-
export const TRANSLATE_WITH_OVERRIDES_CONFIG = {
|
|
369
|
+
export const TRANSLATE_WITH_OVERRIDES_CONFIG: TranslateModuleConfig = {
|
|
316
370
|
compiler: {
|
|
317
371
|
provide: TranslateCompiler,
|
|
318
372
|
useClass: TranslateMessageFormatCompiler,
|
|
319
373
|
},
|
|
320
|
-
loader:
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
374
|
+
loader: [
|
|
375
|
+
{
|
|
376
|
+
provide: TRANSLATE_HTTP_LOADER_CONFIG,
|
|
377
|
+
useValue: {
|
|
378
|
+
prefix: './assets/i18n/',
|
|
379
|
+
suffix: '.json',
|
|
380
|
+
},
|
|
324
381
|
},
|
|
325
|
-
|
|
326
|
-
|
|
382
|
+
{
|
|
383
|
+
provide: TranslateLoader,
|
|
384
|
+
useClass: FileWithOverridesTranslateLoader,
|
|
385
|
+
deps: [HttpClient, TRANSLATE_HTTP_LOADER_CONFIG],
|
|
386
|
+
},
|
|
387
|
+
],
|
|
327
388
|
}
|
|
@@ -69,6 +69,13 @@ export interface MetadataQualityConfig {
|
|
|
69
69
|
ENABLED: boolean
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
export type NewRecordStandard = 'iso19139' | 'iso19115-3'
|
|
73
|
+
|
|
74
|
+
export interface EditorConfig {
|
|
75
|
+
NEW_RECORD_DEFAULT_LANGUAGE?: string
|
|
76
|
+
NEW_RECORD_STANDARD?: NewRecordStandard
|
|
77
|
+
}
|
|
78
|
+
|
|
72
79
|
export type CustomTranslations = { [translationKey: string]: string }
|
|
73
80
|
export type CustomTranslationsAllLanguages = {
|
|
74
81
|
[lang: string]: CustomTranslations
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { toLang2 } from '../../../../../libs/util/i18n/src'
|
|
1
|
+
import { LANG_2_TO_3_MAPPER, toLang2 } from '../../../../../libs/util/i18n/src'
|
|
2
2
|
|
|
3
3
|
const flatten = (
|
|
4
4
|
base: string,
|
|
@@ -137,3 +137,52 @@ export function checkMetadataLanguage(
|
|
|
137
137
|
}
|
|
138
138
|
return parsedConfigSection
|
|
139
139
|
}
|
|
140
|
+
|
|
141
|
+
export function checkNewRecordDefaultLanguage(
|
|
142
|
+
parsedConfigSection: any,
|
|
143
|
+
outWarnings: string[]
|
|
144
|
+
) {
|
|
145
|
+
const lang2 = toLang2(
|
|
146
|
+
parsedConfigSection.new_record_default_language.toLowerCase()
|
|
147
|
+
)
|
|
148
|
+
if (!(lang2 in LANG_2_TO_3_MAPPER)) {
|
|
149
|
+
outWarnings.push(
|
|
150
|
+
`In the [editing] section: new_record_default_language = "${parsedConfigSection.new_record_default_language}" is not a recognized ISO 639 language code`
|
|
151
|
+
)
|
|
152
|
+
return {
|
|
153
|
+
...parsedConfigSection,
|
|
154
|
+
new_record_default_language: undefined,
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
...parsedConfigSection,
|
|
159
|
+
new_record_default_language: lang2,
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function checkNewRecordStandard(
|
|
164
|
+
parsedConfigSection: any,
|
|
165
|
+
outWarnings: string[]
|
|
166
|
+
) {
|
|
167
|
+
const standard = parsedConfigSection.new_record_standard
|
|
168
|
+
const normalizedStandard =
|
|
169
|
+
typeof standard === 'string' ? standard.trim().toLowerCase() : null
|
|
170
|
+
|
|
171
|
+
if (
|
|
172
|
+
normalizedStandard === 'iso19139' ||
|
|
173
|
+
normalizedStandard === 'iso19115-3'
|
|
174
|
+
) {
|
|
175
|
+
return {
|
|
176
|
+
...parsedConfigSection,
|
|
177
|
+
new_record_standard: normalizedStandard,
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
outWarnings.push(
|
|
182
|
+
`In the [editing] section: new_record_standard = "${standard}" is not a supported metadata standard`
|
|
183
|
+
)
|
|
184
|
+
return {
|
|
185
|
+
...parsedConfigSection,
|
|
186
|
+
new_record_standard: undefined,
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { BaseReader } from './base'
|
|
2
1
|
import { DataItem, DatasetInfo, PropertyInfo } from '../model'
|
|
3
2
|
import { getJsonDataItemsProxy, jsonToGeojsonFeature } from '../utils'
|
|
4
3
|
import { generateSqlQuery } from '../sql-utils'
|
|
@@ -58,7 +57,7 @@ export class BaseFileReader extends BaseCacheReader {
|
|
|
58
57
|
this.groupedBy,
|
|
59
58
|
this.aggregations
|
|
60
59
|
)
|
|
61
|
-
const result = await import('alasql').then((module) =>
|
|
60
|
+
const result: any[] = await import('alasql').then((module) =>
|
|
62
61
|
module.default(query, [jsonItems])
|
|
63
62
|
)
|
|
64
63
|
return result.map(jsonToGeojsonFeature)
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { EndpointError, WfsEndpoint, WfsVersion } from '@camptocamp/ogc-client'
|
|
2
2
|
import { DataItem, DatasetInfo, FetchError, PropertyInfo } from '../model'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
fetchDataAsText,
|
|
5
|
+
getJsonDataItemsProxy,
|
|
6
|
+
jsonToGeojsonFeature,
|
|
7
|
+
} from '../utils'
|
|
4
8
|
import { GmlReader, parseGml } from './gml'
|
|
5
9
|
import { GeojsonReader, parseGeojson } from './geojson'
|
|
6
10
|
import { BaseCacheReader } from './base-cache'
|
|
7
|
-
import { getJsonDataItemsProxy, jsonToGeojsonFeature } from '../utils'
|
|
8
11
|
import { generateSqlQuery } from '../sql-utils'
|
|
9
12
|
|
|
10
13
|
export async function getWfsEndpoint(wfsUrl: string): Promise<WfsEndpoint> {
|
|
@@ -167,7 +170,7 @@ export class WfsReader extends BaseCacheReader {
|
|
|
167
170
|
this.groupedBy,
|
|
168
171
|
this.aggregations
|
|
169
172
|
)
|
|
170
|
-
const result = await import('alasql').then((module) =>
|
|
173
|
+
const result: any[] = await import('alasql').then((module) =>
|
|
171
174
|
module.default(query, [jsonItems])
|
|
172
175
|
)
|
|
173
176
|
return result.map(jsonToGeojsonFeature)
|
|
@@ -2,6 +2,5 @@ export * from './lib/i18n.providers'
|
|
|
2
2
|
export * from './lib/i18n.constants'
|
|
3
3
|
export * from './lib/i18n.interceptor'
|
|
4
4
|
export * from './lib/file.translate.loader'
|
|
5
|
-
export * from './lib/embedded.translate.loader'
|
|
6
5
|
export * from './lib/translate.loader.utils'
|
|
7
6
|
export * from './lib/language-codes'
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { HttpClient } from '@angular/common/http'
|
|
2
1
|
import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler'
|
|
3
|
-
import { FileTranslateLoader } from './file.translate.loader'
|
|
4
2
|
import {
|
|
5
3
|
TranslateCompiler,
|
|
6
4
|
TranslateDefaultParser,
|
|
@@ -9,26 +7,34 @@ import {
|
|
|
9
7
|
TranslateParser,
|
|
10
8
|
} from '@ngx-translate/core'
|
|
11
9
|
import { Injectable } from '@angular/core'
|
|
10
|
+
import { TRANSLATE_HTTP_LOADER_CONFIG } from '@ngx-translate/http-loader'
|
|
11
|
+
import { HttpClient } from '@angular/common/http'
|
|
12
|
+
import { FileTranslateLoader } from './file.translate.loader'
|
|
12
13
|
|
|
13
14
|
export const DEFAULT_LANG = 'en'
|
|
14
15
|
|
|
15
16
|
// Caution: changing this can break language selection from third parties!
|
|
16
17
|
export const LANGUAGE_STORAGE_KEY = 'geonetwork-ui-language'
|
|
17
18
|
|
|
18
|
-
export function HttpLoaderFactory(http: HttpClient) {
|
|
19
|
-
return new FileTranslateLoader(http, './assets/i18n/')
|
|
20
|
-
}
|
|
21
|
-
|
|
22
19
|
export const TRANSLATE_DEFAULT_CONFIG: TranslateModuleConfig = {
|
|
23
20
|
compiler: {
|
|
24
21
|
provide: TranslateCompiler,
|
|
25
22
|
useClass: TranslateMessageFormatCompiler,
|
|
26
23
|
},
|
|
27
|
-
loader:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
loader: [
|
|
25
|
+
{
|
|
26
|
+
provide: TRANSLATE_HTTP_LOADER_CONFIG,
|
|
27
|
+
useValue: {
|
|
28
|
+
prefix: './assets/i18n/',
|
|
29
|
+
suffix: '.json',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
provide: TranslateLoader,
|
|
34
|
+
useClass: FileTranslateLoader,
|
|
35
|
+
deps: [HttpClient, TRANSLATE_HTTP_LOADER_CONFIG],
|
|
36
|
+
},
|
|
37
|
+
],
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
@Injectable()
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from '@angular/common/http'
|
|
7
7
|
import { DEFAULT_LANG } from './i18n.constants'
|
|
8
8
|
import { Observable } from 'rxjs'
|
|
9
|
-
import { Injectable, Injector
|
|
9
|
+
import { inject, Injectable, Injector } from '@angular/core'
|
|
10
10
|
import { TranslateService } from '@ngx-translate/core'
|
|
11
11
|
|
|
12
12
|
@Injectable()
|
|
@@ -21,7 +21,7 @@ export class I18nInterceptor implements HttpInterceptor {
|
|
|
21
21
|
const translate = this.injector.get(TranslateService)
|
|
22
22
|
request = request.clone({
|
|
23
23
|
setHeaders: {
|
|
24
|
-
'Accept-Language': translate.
|
|
24
|
+
'Accept-Language': translate.getCurrentLang() || DEFAULT_LANG,
|
|
25
25
|
},
|
|
26
26
|
})
|
|
27
27
|
return next.handle(request)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
APP_INITIALIZER,
|
|
3
2
|
EnvironmentProviders,
|
|
3
|
+
inject,
|
|
4
4
|
makeEnvironmentProviders,
|
|
5
|
+
provideAppInitializer,
|
|
5
6
|
Provider,
|
|
6
7
|
} from '@angular/core'
|
|
7
8
|
import {
|
|
@@ -22,17 +23,16 @@ import {
|
|
|
22
23
|
} from '@angular/common/http'
|
|
23
24
|
import { I18nInterceptor } from './i18n.interceptor'
|
|
24
25
|
|
|
25
|
-
function i18nInitializerFromLocalStorageFactory(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
translate.use(storageLang || translate.getBrowserLang() || DEFAULT_LANG)
|
|
26
|
+
function i18nInitializerFromLocalStorageFactory() {
|
|
27
|
+
const translate = inject(TranslateService)
|
|
28
|
+
translate.setFallbackLang(DEFAULT_LANG)
|
|
29
|
+
let storageLang = null
|
|
30
|
+
try {
|
|
31
|
+
storageLang = localStorage.getItem(LANGUAGE_STORAGE_KEY)
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.warn(error)
|
|
35
34
|
}
|
|
35
|
+
translate.use(storageLang || translate.getBrowserLang() || DEFAULT_LANG)
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export function provideI18n(
|
|
@@ -56,12 +56,9 @@ export function provideI18n(
|
|
|
56
56
|
provideTranslateService(usedConfig),
|
|
57
57
|
]
|
|
58
58
|
if (useLocalStorage) {
|
|
59
|
-
providers.push(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
deps: [TranslateService],
|
|
63
|
-
multi: true,
|
|
64
|
-
})
|
|
59
|
+
providers.push(
|
|
60
|
+
provideAppInitializer(i18nInitializerFromLocalStorageFactory)
|
|
61
|
+
)
|
|
65
62
|
}
|
|
66
63
|
|
|
67
64
|
return makeEnvironmentProviders(providers)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { inject, Injectable, InjectionToken } from '@angular/core'
|
|
2
|
+
import {
|
|
3
|
+
provideTranslateService,
|
|
4
|
+
TranslateCompiler,
|
|
5
|
+
TranslateLoader,
|
|
6
|
+
TranslationObject,
|
|
7
|
+
} from '@ngx-translate/core'
|
|
8
|
+
import { Observable, of } from 'rxjs'
|
|
9
|
+
import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* This translate loader is used for testing purposes, it allows to provide translations directly in the test file without having to create JSON files
|
|
13
|
+
* Taken from https://github.com/mwootendev/ngx-translate-plugins/issues/87
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const TestTranslations = new InjectionToken<Record<string, TranslationObject>>(
|
|
17
|
+
'test-translations'
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
@Injectable()
|
|
21
|
+
class TestTranslateLoader implements TranslateLoader {
|
|
22
|
+
translations = inject(TestTranslations)
|
|
23
|
+
getTranslation(lang: string): Observable<TranslationObject> {
|
|
24
|
+
return of(this.translations[lang] as TranslationObject)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function provideTranslateTestingService(
|
|
29
|
+
translations: Record<string, TranslationObject>
|
|
30
|
+
) {
|
|
31
|
+
return provideTranslateService({
|
|
32
|
+
loader: [
|
|
33
|
+
{
|
|
34
|
+
provide: TestTranslations,
|
|
35
|
+
useValue: translations,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
provide: TranslateLoader,
|
|
39
|
+
useClass: TestTranslateLoader,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
fallbackLang: 'en',
|
|
43
|
+
compiler: {
|
|
44
|
+
provide: TranslateCompiler,
|
|
45
|
+
useClass: TranslateMessageFormatCompiler,
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
}
|
|
@@ -171,6 +171,28 @@ export const FORMATS = {
|
|
|
171
171
|
},
|
|
172
172
|
} as const
|
|
173
173
|
|
|
174
|
+
marker('downloads.format.csv')
|
|
175
|
+
marker('downloads.format.excel')
|
|
176
|
+
marker('downloads.format.geojson')
|
|
177
|
+
marker('downloads.format.json')
|
|
178
|
+
marker('downloads.format.shp')
|
|
179
|
+
marker('downloads.format.gml')
|
|
180
|
+
marker('downloads.format.kml')
|
|
181
|
+
marker('downloads.format.gpkg')
|
|
182
|
+
marker('downloads.format.zip')
|
|
183
|
+
marker('downloads.format.pdf')
|
|
184
|
+
marker('downloads.format.jpg')
|
|
185
|
+
marker('downloads.format.png')
|
|
186
|
+
marker('downloads.format.tiff')
|
|
187
|
+
marker('downloads.format.svg')
|
|
188
|
+
marker('downloads.format.dxf')
|
|
189
|
+
marker('downloads.format.html')
|
|
190
|
+
marker('downloads.format.xml')
|
|
191
|
+
marker('downloads.format.fgb')
|
|
192
|
+
marker('downloads.format.jsonfg')
|
|
193
|
+
marker('downloads.format.webp')
|
|
194
|
+
marker('downloads.format.postgis')
|
|
195
|
+
|
|
174
196
|
export type FileFormat = keyof typeof FORMATS
|
|
175
197
|
|
|
176
198
|
export function getFormatPriority(linkFormat: FileFormat): number {
|
|
@@ -266,7 +288,7 @@ export function checkFileFormat(
|
|
|
266
288
|
new RegExp(`[./]${format}`, 'i').test(link.name.toLowerCase())) ||
|
|
267
289
|
('url' in link &&
|
|
268
290
|
new RegExp(`[./]${format}`, 'i').test(link.url.toString())) ||
|
|
269
|
-
('name' in link &&
|
|
291
|
+
('name' in link && new RegExp(`\\b${format}\\b`, 'i').test(link.name))
|
|
270
292
|
)
|
|
271
293
|
}
|
|
272
294
|
|
|
@@ -3,27 +3,41 @@ import {
|
|
|
3
3
|
RecordKind,
|
|
4
4
|
} from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
5
5
|
|
|
6
|
+
type TValidatorEntry = {
|
|
7
|
+
validator: (metadata: Partial<CatalogRecord>) => boolean
|
|
8
|
+
alias?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
6
11
|
type TValidatorMapper = {
|
|
7
|
-
[key: string]:
|
|
12
|
+
[key: string]: TValidatorEntry
|
|
8
13
|
}
|
|
9
14
|
|
|
10
15
|
const ValidatorMapper: TValidatorMapper = {
|
|
11
|
-
title: (record) => !!record?.title,
|
|
12
|
-
abstract: (record) => !!record?.abstract,
|
|
13
|
-
keywords: (record) => (record?.keywords?.length ?? 0) > 0,
|
|
14
|
-
legalConstraints:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
title: { validator: (record) => !!record?.title },
|
|
17
|
+
abstract: { validator: (record) => !!record?.abstract },
|
|
18
|
+
keywords: { validator: (record) => (record?.keywords?.length ?? 0) > 0 },
|
|
19
|
+
legalConstraints: {
|
|
20
|
+
validator: (record) =>
|
|
21
|
+
!!(
|
|
22
|
+
record?.legalConstraints?.length &&
|
|
23
|
+
record.legalConstraints.some((c) => c?.text?.trim().length > 0)
|
|
24
|
+
),
|
|
25
|
+
},
|
|
26
|
+
contacts: {
|
|
27
|
+
validator: (record) =>
|
|
28
|
+
!!record?.contacts?.[0]?.email &&
|
|
29
|
+
record.contacts[0].email !== 'missing@missing.com',
|
|
30
|
+
},
|
|
31
|
+
updateFrequency: {
|
|
32
|
+
validator: (record) =>
|
|
33
|
+
!!record?.updateFrequency && record.updateFrequency !== 'unknown',
|
|
34
|
+
},
|
|
35
|
+
topics: { validator: (record) => (record?.topics?.length ?? 0) > 0 },
|
|
36
|
+
organisation: {
|
|
37
|
+
validator: (record) => !!record?.contacts?.[0]?.organization?.name,
|
|
38
|
+
alias: 'contacts',
|
|
39
|
+
},
|
|
40
|
+
source: { validator: (record) => !!record?.extras?.sourcesIdentifiers },
|
|
27
41
|
} as const
|
|
28
42
|
|
|
29
43
|
export type ValidatorMapperKeys = keyof typeof ValidatorMapper & string
|
|
@@ -67,6 +81,7 @@ export function getQualityValidators(
|
|
|
67
81
|
|
|
68
82
|
return filteredProps.map((name) => ({
|
|
69
83
|
name,
|
|
70
|
-
validator: () => ValidatorMapper[name](record),
|
|
84
|
+
validator: () => ValidatorMapper[name].validator(record),
|
|
85
|
+
alias: ValidatorMapper[name].alias,
|
|
71
86
|
}))
|
|
72
87
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { inject, Injectable } from '@angular/core'
|
|
2
2
|
import { TranslateService } from '@ngx-translate/core'
|
|
3
3
|
import { type Locale } from 'date-fns/locale'
|
|
4
4
|
import { formatDistance } from 'date-fns/formatDistance'
|
|
@@ -30,13 +30,13 @@ export class DateService {
|
|
|
30
30
|
locale: string
|
|
31
31
|
dateObj: Date
|
|
32
32
|
} {
|
|
33
|
-
const locale = this.translateService.
|
|
33
|
+
const locale = this.translateService.getCurrentLang() || DEFAULT_LANGUAGE
|
|
34
34
|
const dateObj = this.getDateObject(date)
|
|
35
35
|
return { locale, dateObj }
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
private async getDateLocale(): Promise<Locale> {
|
|
39
|
-
const lang = this.translateService.
|
|
39
|
+
const lang = this.translateService.getCurrentLang() || DEFAULT_LANGUAGE
|
|
40
40
|
const locales = await this.dateLocales
|
|
41
41
|
return locales[lang]
|
|
42
42
|
}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Feature,
|
|
3
|
+
FeatureCollection,
|
|
4
|
+
Geometry,
|
|
5
|
+
Polygon,
|
|
6
|
+
Position,
|
|
7
|
+
} from 'geojson'
|
|
8
|
+
import type { DatasetSpatialExtent } from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
2
9
|
|
|
3
10
|
/**
|
|
4
11
|
* @returns The geometry if available, otherwise null.
|
|
@@ -94,3 +101,53 @@ export function getGeometryBoundingBox(geometry: Geometry): BoundingBox {
|
|
|
94
101
|
return coordinatesReducer(emptyExtent, geometry.coordinates)
|
|
95
102
|
}
|
|
96
103
|
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Builds the closed GeoJSON Polygon matching the given bounding box.
|
|
107
|
+
*/
|
|
108
|
+
export function bboxToPolygon(bbox: BoundingBox): Polygon {
|
|
109
|
+
const [minX, minY, maxX, maxY] = bbox
|
|
110
|
+
return {
|
|
111
|
+
type: 'Polygon',
|
|
112
|
+
coordinates: [
|
|
113
|
+
[
|
|
114
|
+
[minX, minY],
|
|
115
|
+
[minX, maxY],
|
|
116
|
+
[maxX, maxY],
|
|
117
|
+
[maxX, minY],
|
|
118
|
+
[minX, minY],
|
|
119
|
+
],
|
|
120
|
+
],
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Returns the geometry carried by a spatial extent, falling back to the polygon
|
|
126
|
+
* derived from its bounding box. Returns null when the extent has neither.
|
|
127
|
+
*/
|
|
128
|
+
export function spatialExtentToGeometry(
|
|
129
|
+
extent: DatasetSpatialExtent
|
|
130
|
+
): Geometry | null {
|
|
131
|
+
if (extent.geometry) return extent.geometry
|
|
132
|
+
if (extent.bbox) return bboxToPolygon(extent.bbox)
|
|
133
|
+
return null
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Converts a list of dataset spatial extents into a GeoJSON FeatureCollection,
|
|
138
|
+
* e.g. to be used as the data source of a map layer.
|
|
139
|
+
*/
|
|
140
|
+
export function spatialExtentsToFeatureCollection(
|
|
141
|
+
extents: DatasetSpatialExtent[]
|
|
142
|
+
): FeatureCollection {
|
|
143
|
+
return {
|
|
144
|
+
type: 'FeatureCollection',
|
|
145
|
+
features: extents.reduce<Feature[]>((features, extent) => {
|
|
146
|
+
const geometry = spatialExtentToGeometry(extent)
|
|
147
|
+
if (geometry) {
|
|
148
|
+
features.push({ type: 'Feature', properties: {}, geometry })
|
|
149
|
+
}
|
|
150
|
+
return features
|
|
151
|
+
}, []),
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -12,6 +12,15 @@ export function getIndividualDisplayName(individual: Individual): string {
|
|
|
12
12
|
return individual.organization?.name ?? individual.email ?? ''
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
export function getAddressLines(address: string | undefined): string[] {
|
|
16
|
+
return address
|
|
17
|
+
? address
|
|
18
|
+
.split(',')
|
|
19
|
+
.map((part) => part.trim())
|
|
20
|
+
.filter(Boolean)
|
|
21
|
+
: []
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
export function toIndividual(user: UserModel): Individual {
|
|
16
25
|
return {
|
|
17
26
|
firstName: user.name,
|
package/style.css
CHANGED