geonetwork-ui 2.10.0-dev.d0cd0940b → 2.10.0-dev.d37bc8ad9
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 +695 -5757
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/index.d.ts +165 -78
- package/index.d.ts.map +1 -1
- package/material-styles.css +483 -0
- 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 +5 -4
- 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 +8 -0
- package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +11 -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 +33 -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 +54 -32
- 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 +48 -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 +5 -0
- package/src/libs/feature/catalog/src/lib/sources/sources.service.ts +5 -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 +67 -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/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 +6 -8
- 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-topics/form-field-topics.component.ts +2 -2
- 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 +1 -0
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +5 -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 +34 -2
- package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.html +5 -2
- package/src/libs/feature/editor/src/lib/components/record-form/record-form.component.ts +51 -33
- package/src/libs/feature/editor/src/lib/fields.config.ts +60 -47
- package/src/libs/feature/editor/src/lib/models/editor-config.model.ts +4 -0
- package/src/libs/feature/editor/src/lib/services/editor.service.ts +1 -1
- package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +33 -0
- package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +9 -1
- 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 +1 -0
- package/src/libs/ui/elements/src/lib/contact-details/contact-details.component.html +96 -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/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/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.html +20 -10
- package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.ts +29 -1
- 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/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/map/src/lib/components/spatial-extent/spatial-extent.component.ts +4 -54
- 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/widgets/src/lib/popover/popover.component.ts +7 -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 +1 -1
- 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 +8 -0
- package/translations/de.json +31 -20
- package/translations/en.json +31 -20
- package/translations/es.json +31 -20
- package/translations/fr.json +31 -20
- package/translations/it.json +31 -20
- package/translations/nl.json +31 -20
- package/translations/pt.json +31 -20
- package/translations/sk.json +31 -20
|
@@ -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
|
+
}
|
|
@@ -266,7 +266,7 @@ export function checkFileFormat(
|
|
|
266
266
|
new RegExp(`[./]${format}`, 'i').test(link.name.toLowerCase())) ||
|
|
267
267
|
('url' in link &&
|
|
268
268
|
new RegExp(`[./]${format}`, 'i').test(link.url.toString())) ||
|
|
269
|
-
('name' in link &&
|
|
269
|
+
('name' in link && new RegExp(`\\b${format}\\b`, 'i').test(link.name))
|
|
270
270
|
)
|
|
271
271
|
}
|
|
272
272
|
|
|
@@ -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
package/tailwind.base.css
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@import './material-styles.css';
|
|
2
|
+
|
|
1
3
|
@tailwind base;
|
|
2
4
|
@tailwind components;
|
|
3
5
|
@tailwind utilities;
|
|
@@ -119,6 +121,12 @@
|
|
|
119
121
|
border-gray-100 focus:ring-4 focus:ring-gray-50;
|
|
120
122
|
}
|
|
121
123
|
|
|
124
|
+
.gn-ui-btn-gray-light {
|
|
125
|
+
@apply gn-ui-btn text-black
|
|
126
|
+
bg-gray-50 hover:bg-gray-100 focus:bg-gray-100 active:bg-gray-200
|
|
127
|
+
border-gray-50 focus:ring-4 focus:ring-gray-100;
|
|
128
|
+
}
|
|
129
|
+
|
|
122
130
|
.gn-ui-btn-black {
|
|
123
131
|
@apply gn-ui-btn text-white
|
|
124
132
|
bg-black hover:bg-gray-950 focus:bg-gray-950 active:bg-gray-900
|
package/translations/de.json
CHANGED
|
@@ -89,6 +89,10 @@
|
|
|
89
89
|
"domain.contact.role.stakeholder": "Beteiligter",
|
|
90
90
|
"domain.contact.role.unspecified": "Nicht angegeben",
|
|
91
91
|
"domain.contact.role.user": "Benutzer",
|
|
92
|
+
"domain.record.keywordType.other": "Stichworte",
|
|
93
|
+
"domain.record.keywordType.place": "Ort",
|
|
94
|
+
"domain.record.keywordType.temporal": "Zeitlich",
|
|
95
|
+
"domain.record.keywordType.theme": "Thema",
|
|
92
96
|
"domain.record.status.completed": "Abgeschlossen",
|
|
93
97
|
"domain.record.status.deprecated": "Veraltet",
|
|
94
98
|
"domain.record.status.ongoing": "Kontinuierliche Aktualisierung",
|
|
@@ -150,6 +154,14 @@
|
|
|
150
154
|
"editor.record.form.draft.updateAlert": "Seit der Erstellung dieses Entwurfs wurde dieser Datensatz am { date } von { user } geändert. Durch das Veröffentlichen Ihrer Version können dessen Änderungen gelöscht werden. Um dies zu vermeiden, können Sie Ihre Änderungen rückgängig machen oder Ihre Version in voller Kenntnis der Sachlage veröffentlichen.",
|
|
151
155
|
"editor.record.form.field.abstract": "Kurzbeschreibung",
|
|
152
156
|
"editor.record.form.field.constraintsShortcuts": "",
|
|
157
|
+
"editor.record.form.field.contactDetails.email": "",
|
|
158
|
+
"editor.record.form.field.contactDetails.email.placeholder": "",
|
|
159
|
+
"editor.record.form.field.contactDetails.firstName": "",
|
|
160
|
+
"editor.record.form.field.contactDetails.firstName.placeholder": "",
|
|
161
|
+
"editor.record.form.field.contactDetails.lastName": "",
|
|
162
|
+
"editor.record.form.field.contactDetails.lastName.placeholder": "",
|
|
163
|
+
"editor.record.form.field.contactDetails.organization": "",
|
|
164
|
+
"editor.record.form.field.contactDetails.organization.placeholder": "",
|
|
153
165
|
"editor.record.form.field.contacts": "Ansprechpartner - Email",
|
|
154
166
|
"editor.record.form.field.contacts.noContact": "Bitte geben Sie mindestens einen Ansprechpartner an.",
|
|
155
167
|
"editor.record.form.field.contacts.placeholder": "Kontakt auswählen",
|
|
@@ -235,25 +247,25 @@
|
|
|
235
247
|
"editor.record.form.temporalExtents.addRange": "Zeitraum",
|
|
236
248
|
"editor.record.form.temporalExtents.date": "Datum",
|
|
237
249
|
"editor.record.form.temporalExtents.range": "Datumsbereich",
|
|
238
|
-
"editor.record.form.topics.
|
|
239
|
-
"editor.record.form.topics.
|
|
240
|
-
"editor.record.form.topics.
|
|
241
|
-
"editor.record.form.topics.
|
|
242
|
-
"editor.record.form.topics.
|
|
243
|
-
"editor.record.form.topics.
|
|
244
|
-
"editor.record.form.topics.
|
|
245
|
-
"editor.record.form.topics.
|
|
246
|
-
"editor.record.form.topics.
|
|
247
|
-
"editor.record.form.topics.
|
|
248
|
-
"editor.record.form.topics.
|
|
249
|
-
"editor.record.form.topics.
|
|
250
|
-
"editor.record.form.topics.
|
|
251
|
-
"editor.record.form.topics.
|
|
252
|
-
"editor.record.form.topics.
|
|
253
|
-
"editor.record.form.topics.
|
|
254
|
-
"editor.record.form.topics.
|
|
255
|
-
"editor.record.form.topics.
|
|
256
|
-
"editor.record.form.topics.
|
|
250
|
+
"editor.record.form.topics.iso.biota": "Biologie",
|
|
251
|
+
"editor.record.form.topics.iso.boundaries": "Grenzen",
|
|
252
|
+
"editor.record.form.topics.iso.climatologyMeteorologyAtmosphere": "Klimatologie/Meteorologie/Atmosphäre",
|
|
253
|
+
"editor.record.form.topics.iso.economy": "Wirtschaft",
|
|
254
|
+
"editor.record.form.topics.iso.elevation": "Höhenangaben",
|
|
255
|
+
"editor.record.form.topics.iso.environment": "Umwelt",
|
|
256
|
+
"editor.record.form.topics.iso.farming": "Landwirtschaft",
|
|
257
|
+
"editor.record.form.topics.iso.geoscientificInformation": "Geowissenschaften",
|
|
258
|
+
"editor.record.form.topics.iso.health": "Gesundheitswesen",
|
|
259
|
+
"editor.record.form.topics.iso.imageryBaseMapsEarthCover": "Bilddaten/Basiskarten/Landbedeckung",
|
|
260
|
+
"editor.record.form.topics.iso.intelligenceMilitary": "Aufklärung/Militär",
|
|
261
|
+
"editor.record.form.topics.iso.location": "Ortsangaben",
|
|
262
|
+
"editor.record.form.topics.iso.oceans": "Meere",
|
|
263
|
+
"editor.record.form.topics.iso.planningCadastre": "Planungsunterlagen/Kataster",
|
|
264
|
+
"editor.record.form.topics.iso.society": "Gesellschaft",
|
|
265
|
+
"editor.record.form.topics.iso.structure": "Bauwerke",
|
|
266
|
+
"editor.record.form.topics.iso.transportation": "Verkehrswesen",
|
|
267
|
+
"editor.record.form.topics.iso.utilitiesCommunication": "Ver- und Entsorgung/Nachrichtenwesen",
|
|
268
|
+
"editor.record.form.topics.iso.inlandWaters": "Binnengewässer",
|
|
257
269
|
"editor.record.form.topics.placeholder": "Ein oder mehrere Themen auswählen",
|
|
258
270
|
"editor.record.form.updateFrequency.planned": "Dieses Dataset wird regelmäßig aktualisiert.",
|
|
259
271
|
"editor.record.importFromExternalFile.failure.body": "Beim Importieren des Datensatzes ist ein Fehler aufgetreten:",
|
|
@@ -495,7 +507,6 @@
|
|
|
495
507
|
"record.metadata.preview.config.idle": "Standardvorschau festlegen",
|
|
496
508
|
"record.metadata.preview.config.saved": "Gespeichert!",
|
|
497
509
|
"record.metadata.preview.config.saving": "Speichern...",
|
|
498
|
-
"record.metadata.producer": "Datenproduzent",
|
|
499
510
|
"record.metadata.publication": "Veröffentlichungsdatum",
|
|
500
511
|
"record.metadata.publications": "{count, plural, =0{Veröffentlichungsdatum} one{Veröffentlichungsdatum} other{Veröffentlichungen}}",
|
|
501
512
|
"record.metadata.quality": "Metadatenqualität",
|
package/translations/en.json
CHANGED
|
@@ -89,6 +89,10 @@
|
|
|
89
89
|
"domain.contact.role.stakeholder": "Stakeholder",
|
|
90
90
|
"domain.contact.role.unspecified": "Unspecified",
|
|
91
91
|
"domain.contact.role.user": "User",
|
|
92
|
+
"domain.record.keywordType.other": "Keywords",
|
|
93
|
+
"domain.record.keywordType.place": "Place",
|
|
94
|
+
"domain.record.keywordType.temporal": "Temporal",
|
|
95
|
+
"domain.record.keywordType.theme": "Theme",
|
|
92
96
|
"domain.record.status.completed": "Completed",
|
|
93
97
|
"domain.record.status.deprecated": "Deprecated",
|
|
94
98
|
"domain.record.status.ongoing": "Ongoing",
|
|
@@ -150,6 +154,14 @@
|
|
|
150
154
|
"editor.record.form.draft.updateAlert": "Since you created this draft, the dataset has been updated on { date } by { user }. Publishing your draft might erase their edits. To avoid this, you need to either cancel your changes or knowingly publish your own version.",
|
|
151
155
|
"editor.record.form.field.abstract": "Abstract",
|
|
152
156
|
"editor.record.form.field.constraintsShortcuts": "",
|
|
157
|
+
"editor.record.form.field.contactDetails.email": "Contact email",
|
|
158
|
+
"editor.record.form.field.contactDetails.email.placeholder": "example@domainname.com",
|
|
159
|
+
"editor.record.form.field.contactDetails.firstName": "Contact first name",
|
|
160
|
+
"editor.record.form.field.contactDetails.firstName.placeholder": "First name",
|
|
161
|
+
"editor.record.form.field.contactDetails.lastName": "Contact last name",
|
|
162
|
+
"editor.record.form.field.contactDetails.lastName.placeholder": "Last name",
|
|
163
|
+
"editor.record.form.field.contactDetails.organization": "Contact organization",
|
|
164
|
+
"editor.record.form.field.contactDetails.organization.placeholder": "Company",
|
|
153
165
|
"editor.record.form.field.contacts": "Point of contact - Email",
|
|
154
166
|
"editor.record.form.field.contacts.noContact": "Please provide at least one point of contact.",
|
|
155
167
|
"editor.record.form.field.contacts.placeholder": "Choose a contact",
|
|
@@ -235,25 +247,25 @@
|
|
|
235
247
|
"editor.record.form.temporalExtents.addRange": "Time period",
|
|
236
248
|
"editor.record.form.temporalExtents.date": "Date",
|
|
237
249
|
"editor.record.form.temporalExtents.range": "Date range",
|
|
238
|
-
"editor.record.form.topics.
|
|
239
|
-
"editor.record.form.topics.
|
|
240
|
-
"editor.record.form.topics.
|
|
241
|
-
"editor.record.form.topics.
|
|
242
|
-
"editor.record.form.topics.
|
|
243
|
-
"editor.record.form.topics.
|
|
244
|
-
"editor.record.form.topics.
|
|
245
|
-
"editor.record.form.topics.
|
|
246
|
-
"editor.record.form.topics.
|
|
247
|
-
"editor.record.form.topics.
|
|
248
|
-
"editor.record.form.topics.
|
|
249
|
-
"editor.record.form.topics.
|
|
250
|
-
"editor.record.form.topics.
|
|
251
|
-
"editor.record.form.topics.
|
|
252
|
-
"editor.record.form.topics.
|
|
253
|
-
"editor.record.form.topics.
|
|
254
|
-
"editor.record.form.topics.
|
|
255
|
-
"editor.record.form.topics.
|
|
256
|
-
"editor.record.form.topics.
|
|
250
|
+
"editor.record.form.topics.iso.biota": "Biota",
|
|
251
|
+
"editor.record.form.topics.iso.boundaries": "Boundaries",
|
|
252
|
+
"editor.record.form.topics.iso.climatologyMeteorologyAtmosphere": "Climatology / Meteorology / Atmosphere",
|
|
253
|
+
"editor.record.form.topics.iso.economy": "Economy",
|
|
254
|
+
"editor.record.form.topics.iso.elevation": "Elevation",
|
|
255
|
+
"editor.record.form.topics.iso.environment": "Environnement",
|
|
256
|
+
"editor.record.form.topics.iso.farming": "Farming",
|
|
257
|
+
"editor.record.form.topics.iso.geoscientificInformation": "Geoscientific Information",
|
|
258
|
+
"editor.record.form.topics.iso.health": "Health",
|
|
259
|
+
"editor.record.form.topics.iso.imageryBaseMapsEarthCover": "Imagery / Base Maps / Earth Cover",
|
|
260
|
+
"editor.record.form.topics.iso.intelligenceMilitary": "Intelligence / Military",
|
|
261
|
+
"editor.record.form.topics.iso.location": "Location",
|
|
262
|
+
"editor.record.form.topics.iso.oceans": "Oceans",
|
|
263
|
+
"editor.record.form.topics.iso.planningCadastre": "Planning / Cadastre",
|
|
264
|
+
"editor.record.form.topics.iso.society": "Society",
|
|
265
|
+
"editor.record.form.topics.iso.structure": "Structure",
|
|
266
|
+
"editor.record.form.topics.iso.transportation": "Transportation",
|
|
267
|
+
"editor.record.form.topics.iso.utilitiesCommunication": "Utilities / Communication",
|
|
268
|
+
"editor.record.form.topics.iso.inlandWaters": "Inland Waters",
|
|
257
269
|
"editor.record.form.topics.placeholder": "Select one or several topics",
|
|
258
270
|
"editor.record.form.updateFrequency.planned": "This dataset is updated regularly",
|
|
259
271
|
"editor.record.importFromExternalFile.failure.body": "Failure",
|
|
@@ -495,7 +507,6 @@
|
|
|
495
507
|
"record.metadata.preview.config.idle": "Set as default preview",
|
|
496
508
|
"record.metadata.preview.config.saved": "Saved !",
|
|
497
509
|
"record.metadata.preview.config.saving": "Saving...",
|
|
498
|
-
"record.metadata.producer": "Data producer",
|
|
499
510
|
"record.metadata.publication": "Date of publication",
|
|
500
511
|
"record.metadata.publications": "{count, plural, =0{publication} one{publication} other{publications}}",
|
|
501
512
|
"record.metadata.quality": "Metadata Quality",
|