geonetwork-ui 2.9.0-dev.fc19cbfed → 2.10.0-dev.02185426a
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 +2382 -6943
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/index.d.ts +378 -196
- 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 +72 -37
- package/src/libs/api/repository/src/lib/gn4/gn4.provider.ts +6 -1
- 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/index.ts +2 -0
- package/src/libs/common/domain/src/lib/model/index.ts +3 -0
- package/src/libs/common/domain/src/lib/model/record/index.ts +2 -2
- package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +13 -5
- package/src/libs/common/domain/src/lib/model/search/index.ts +1 -1
- 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/dataviz/src/lib/chart-view/chart-view.component.html +3 -3
- package/src/libs/feature/editor/src/index.ts +2 -0
- 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 -20
- 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 +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/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 +11 -6
- package/src/libs/feature/editor/src/lib/components/online-service-resource-input/online-service-resource-input.component.ts +18 -2
- 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 +13 -13
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts/form-field-contacts.component.ts +18 -4
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.html +8 -7
- package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-contacts-for-resource/form-field-contacts-for-resource.component.ts +6 -6
- 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 +1 -0
- package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.ts +21 -0
- package/src/libs/feature/record/src/lib/gpf-api-dl/gpf-api-dl.component.ts +8 -4
- 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 +3 -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 +41 -0
- package/src/libs/ui/elements/src/lib/contact-pill/contact-pill.component.ts +70 -0
- package/src/libs/ui/elements/src/lib/downloads-list/downloads-list.component.ts +5 -3
- 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/internal-link-card/internal-link-card.component.html +1 -1
- package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.ts +0 -1
- 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 +3 -2
- package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +26 -68
- package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.ts +30 -10
- 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 +8 -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/dropdown-selector/dropdown-selector.component.ts +1 -1
- 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 +6 -2
- 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/record-preview-row/record-preview-row.component.html +0 -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/util/app-config/src/lib/app-config.ts +72 -9
- package/src/libs/util/app-config/src/lib/model.ts +8 -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/index.ts +1 -0
- package/src/libs/util/shared/src/lib/utils/user-display.ts +32 -0
- package/style.css +0 -1
- package/tailwind.base.css +28 -2
- package/translations/de.json +82 -48
- package/translations/en.json +87 -53
- package/translations/es.json +56 -22
- package/translations/fr.json +84 -50
- package/translations/it.json +82 -48
- package/translations/nl.json +55 -21
- package/translations/pt.json +56 -22
- package/translations/sk.json +56 -22
- package/src/libs/feature/editor/src/lib/components/generic-keywords/generic-keywords.component.css +0 -3
|
@@ -3,9 +3,10 @@ import {
|
|
|
3
3
|
HttpErrorResponse,
|
|
4
4
|
HttpHeaders,
|
|
5
5
|
} from '@angular/common/http'
|
|
6
|
-
import { Injectable,
|
|
6
|
+
import { inject, Injectable, InjectionToken } from '@angular/core'
|
|
7
7
|
import {
|
|
8
8
|
assertValidXml,
|
|
9
|
+
BaseConverter,
|
|
9
10
|
findConverterForDocument,
|
|
10
11
|
Gn4Converter,
|
|
11
12
|
Gn4SearchResults,
|
|
@@ -57,6 +58,16 @@ const TEMPORARY_ID_PREFIX = 'TEMP-ID-'
|
|
|
57
58
|
|
|
58
59
|
export type RecordAsXml = string
|
|
59
60
|
|
|
61
|
+
export const DISABLE_DRAFT = new InjectionToken<boolean>('gnDisableDraft', {
|
|
62
|
+
factory: () => false,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
export const DEFAULT_RECORD_CONVERTER = new InjectionToken<
|
|
66
|
+
BaseConverter<string>
|
|
67
|
+
>('defaultRecordConverter', {
|
|
68
|
+
factory: () => new Iso19139Converter(),
|
|
69
|
+
})
|
|
70
|
+
|
|
60
71
|
@Injectable()
|
|
61
72
|
export class Gn4Repository implements RecordsRepositoryInterface {
|
|
62
73
|
private httpClient = inject(HttpClient)
|
|
@@ -67,6 +78,8 @@ export class Gn4Repository implements RecordsRepositoryInterface {
|
|
|
67
78
|
private platformService = inject(PlatformServiceInterface)
|
|
68
79
|
private gn4LanguagesApi = inject(LanguagesApiService)
|
|
69
80
|
private settingsService = inject(Gn4SettingsService)
|
|
81
|
+
private disableDraft = inject(DISABLE_DRAFT, { optional: true }) ?? false
|
|
82
|
+
private defaultConverter = inject(DEFAULT_RECORD_CONVERTER)
|
|
70
83
|
|
|
71
84
|
_draftsChanged = new Subject<void>()
|
|
72
85
|
draftsChanged$ = this._draftsChanged.asObservable()
|
|
@@ -323,9 +336,10 @@ export class Gn4Repository implements RecordsRepositoryInterface {
|
|
|
323
336
|
|
|
324
337
|
private canEdit(record: CatalogRecord, allowEditHarvested: boolean): boolean {
|
|
325
338
|
return (
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
339
|
+
(this.platformService.supportsAuthentication() &&
|
|
340
|
+
record.extras?.['edit'] &&
|
|
341
|
+
(!record.extras?.['isHarvested'] || allowEditHarvested)) ??
|
|
342
|
+
false
|
|
329
343
|
)
|
|
330
344
|
}
|
|
331
345
|
|
|
@@ -349,7 +363,9 @@ export class Gn4Repository implements RecordsRepositoryInterface {
|
|
|
349
363
|
openRecordForEdition(
|
|
350
364
|
uniqueIdentifier: string
|
|
351
365
|
): Observable<[CatalogRecord, string, boolean] | null> {
|
|
352
|
-
const draft$ =
|
|
366
|
+
const draft$ = this.disableDraft
|
|
367
|
+
? of(null)
|
|
368
|
+
: of(this.getRecordFromLocalStorage(uniqueIdentifier))
|
|
353
369
|
const recordAsXml$ = this.getRecordAsXml(uniqueIdentifier)
|
|
354
370
|
|
|
355
371
|
return combineLatest([draft$, recordAsXml$]).pipe(
|
|
@@ -369,38 +385,52 @@ export class Gn4Repository implements RecordsRepositoryInterface {
|
|
|
369
385
|
openRecordForDuplication(
|
|
370
386
|
uniqueIdentifier: string
|
|
371
387
|
): Observable<[CatalogRecord, string, true] | null> {
|
|
372
|
-
return this.
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
388
|
+
return this.platformService.getUserPermissionsByGroup().pipe(
|
|
389
|
+
map((permissions) => {
|
|
390
|
+
const groupId =
|
|
391
|
+
permissions.find((p) => p.canApprove)?.groupId?.toString() ??
|
|
392
|
+
permissions.find((p) => p.canEdit)?.groupId?.toString()
|
|
393
|
+
if (!groupId)
|
|
394
|
+
throw new Error(
|
|
395
|
+
'Current user has no writable group to duplicate into'
|
|
396
|
+
)
|
|
397
|
+
return groupId
|
|
398
|
+
}),
|
|
399
|
+
switchMap((groupId) =>
|
|
400
|
+
this.gn4RecordsApi
|
|
401
|
+
.create(
|
|
402
|
+
uniqueIdentifier,
|
|
403
|
+
groupId,
|
|
404
|
+
'METADATA',
|
|
405
|
+
'',
|
|
406
|
+
false,
|
|
407
|
+
undefined,
|
|
408
|
+
true,
|
|
409
|
+
false,
|
|
410
|
+
undefined,
|
|
411
|
+
'body',
|
|
412
|
+
false,
|
|
413
|
+
{
|
|
414
|
+
httpHeaderAccept: 'application/json',
|
|
415
|
+
httpContentTypeSelected: 'application/json;charset=UTF-8',
|
|
416
|
+
}
|
|
417
|
+
)
|
|
418
|
+
.pipe(
|
|
419
|
+
switchMap((uniqueIdentifier) => {
|
|
420
|
+
return this.getRecordAsXml(uniqueIdentifier)
|
|
421
|
+
}),
|
|
422
|
+
switchMap((xml) => {
|
|
423
|
+
return from(
|
|
424
|
+
findConverterForDocument(xml)
|
|
425
|
+
.readRecord(xml)
|
|
426
|
+
.then((record) => {
|
|
427
|
+
return [record, xml, true] as [CatalogRecord, string, true]
|
|
428
|
+
})
|
|
429
|
+
)
|
|
430
|
+
})
|
|
401
431
|
)
|
|
402
|
-
})
|
|
403
432
|
)
|
|
433
|
+
)
|
|
404
434
|
}
|
|
405
435
|
|
|
406
436
|
saveRecord(
|
|
@@ -474,6 +504,7 @@ export class Gn4Repository implements RecordsRepositoryInterface {
|
|
|
474
504
|
record: CatalogRecord,
|
|
475
505
|
referenceRecordSource?: string
|
|
476
506
|
): Observable<string> {
|
|
507
|
+
if (this.disableDraft) return of('')
|
|
477
508
|
return this.serializeRecordToXml(record, referenceRecordSource).pipe(
|
|
478
509
|
tap((recordXml) => {
|
|
479
510
|
this.saveRecordToLocalStorage(recordXml, record.uniqueIdentifier)
|
|
@@ -483,16 +514,19 @@ export class Gn4Repository implements RecordsRepositoryInterface {
|
|
|
483
514
|
}
|
|
484
515
|
|
|
485
516
|
clearRecordDraft(uniqueIdentifier: string): void {
|
|
517
|
+
if (this.disableDraft) return
|
|
486
518
|
this.removeRecordFromLocalStorage(uniqueIdentifier)
|
|
487
519
|
this._draftsChanged.next()
|
|
488
520
|
}
|
|
489
521
|
|
|
490
522
|
recordHasDraft(uniqueIdentifier: string): boolean {
|
|
523
|
+
if (this.disableDraft) return false
|
|
491
524
|
return this.getRecordFromLocalStorage(uniqueIdentifier) !== null
|
|
492
525
|
}
|
|
493
526
|
|
|
494
527
|
// generated by copilot
|
|
495
528
|
getAllDrafts(): Observable<CatalogRecord[]> {
|
|
529
|
+
if (this.disableDraft) return of([])
|
|
496
530
|
const items = { ...window.localStorage }
|
|
497
531
|
const drafts = Object.keys(items)
|
|
498
532
|
.filter((key) => key.startsWith('geonetwork-ui-draft-'))
|
|
@@ -508,6 +542,7 @@ export class Gn4Repository implements RecordsRepositoryInterface {
|
|
|
508
542
|
}
|
|
509
543
|
|
|
510
544
|
getDraftsCount(): Observable<number> {
|
|
545
|
+
if (this.disableDraft) return of(0)
|
|
511
546
|
const items = { ...window.localStorage }
|
|
512
547
|
const draftCount = Object.keys(items)
|
|
513
548
|
.filter((key) => key.startsWith('geonetwork-ui-draft-'))
|
|
@@ -592,10 +627,10 @@ export class Gn4Repository implements RecordsRepositoryInterface {
|
|
|
592
627
|
record: CatalogRecord,
|
|
593
628
|
referenceRecordSource?: string
|
|
594
629
|
): Observable<string> {
|
|
595
|
-
// if there's a reference record, use that standard; otherwise, use
|
|
630
|
+
// if there's a reference record, use that standard; otherwise, use standard based on configuration or default
|
|
596
631
|
const converter = referenceRecordSource
|
|
597
632
|
? findConverterForDocument(referenceRecordSource)
|
|
598
|
-
:
|
|
633
|
+
: this.defaultConverter
|
|
599
634
|
return from(converter.writeRecord(record, referenceRecordSource))
|
|
600
635
|
}
|
|
601
636
|
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from './platform/gn4-platform.service'
|
|
7
7
|
import { Gn4PlatformMapper } from './platform/gn4-platform.mapper'
|
|
8
8
|
import { RecordsRepositoryInterface } from '../../../../../../libs/common/domain/src/lib/repository/records-repository.interface'
|
|
9
|
-
import { Gn4Repository } from './gn4-repository'
|
|
9
|
+
import { Gn4Repository, DISABLE_DRAFT } from './gn4-repository'
|
|
10
10
|
import { AvatarServiceInterface, GravatarService } from './auth'
|
|
11
11
|
import { OrganizationsServiceInterface } from '../../../../../../libs/common/domain/src/lib/organizations.service.interface'
|
|
12
12
|
import {
|
|
@@ -22,6 +22,7 @@ import { TranslateService } from '@ngx-translate/core'
|
|
|
22
22
|
|
|
23
23
|
interface Gn4ProvideOptions {
|
|
24
24
|
disableAuth?: boolean
|
|
25
|
+
disableDraft?: boolean
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
export function provideGn4(provideOptions?: Gn4ProvideOptions): Provider[] {
|
|
@@ -30,6 +31,10 @@ export function provideGn4(provideOptions?: Gn4ProvideOptions): Provider[] {
|
|
|
30
31
|
provide: DISABLE_AUTH,
|
|
31
32
|
useValue: provideOptions?.disableAuth,
|
|
32
33
|
},
|
|
34
|
+
{
|
|
35
|
+
provide: DISABLE_DRAFT,
|
|
36
|
+
useValue: provideOptions?.disableDraft,
|
|
37
|
+
},
|
|
33
38
|
{
|
|
34
39
|
provide: PlatformServiceInterface,
|
|
35
40
|
useClass: Gn4PlatformService,
|
package/src/libs/api/repository/src/lib/gn4/organizations/organizations-from-groups.service.ts
CHANGED
|
@@ -52,7 +52,7 @@ export class OrganizationsFromGroupsService
|
|
|
52
52
|
organisationsCount$ = this.organisations$.pipe(map((orgs) => orgs.length))
|
|
53
53
|
|
|
54
54
|
private get lang3() {
|
|
55
|
-
return toLang3(this.translateService.
|
|
55
|
+
return toLang3(this.translateService.getCurrentLang())
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
constructor(
|
package/src/libs/api/repository/src/lib/gn4/organizations/organizations-from-metadata.service.ts
CHANGED
|
@@ -128,7 +128,7 @@ export class OrganizationsFromMetadataService
|
|
|
128
128
|
) {}
|
|
129
129
|
|
|
130
130
|
private get langIndex() {
|
|
131
|
-
return `lang${toLang3(this.translateService.
|
|
131
|
+
return `lang${toLang3(this.translateService.getCurrentLang())}`
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
equalsNormalizedStrings(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HttpClient, HttpEventType } from '@angular/common/http'
|
|
2
|
-
import { Injectable, InjectionToken
|
|
2
|
+
import { inject, Injectable, InjectionToken } from '@angular/core'
|
|
3
3
|
import {
|
|
4
4
|
KeywordApiResponse,
|
|
5
5
|
ThesaurusApiResponse,
|
|
@@ -12,11 +12,13 @@ import {
|
|
|
12
12
|
} from '../../../../../../../libs/common/domain/src/lib/model/record'
|
|
13
13
|
import { KeywordType } from '../../../../../../../libs/common/domain/src/lib/model/thesaurus'
|
|
14
14
|
import { UserModel } from '../../../../../../../libs/common/domain/src/lib/model/user/user.model'
|
|
15
|
+
import { GroupModel } from '../../../../../../../libs/common/domain/src/lib/model/user/group.model'
|
|
15
16
|
import {
|
|
16
17
|
PlatformServiceInterface,
|
|
17
18
|
UploadEvent,
|
|
18
19
|
} from '../../../../../../../libs/common/domain/src/lib/platform.service.interface'
|
|
19
20
|
import {
|
|
21
|
+
GroupsApiService,
|
|
20
22
|
MeApiService,
|
|
21
23
|
RecordsApiService,
|
|
22
24
|
RegistriesApiService,
|
|
@@ -57,6 +59,7 @@ export const DISABLE_AUTH = new InjectionToken<boolean>('gnDisableAuth', {
|
|
|
57
59
|
export class Gn4PlatformService implements PlatformServiceInterface {
|
|
58
60
|
private meApi = inject(MeApiService)
|
|
59
61
|
private usersApi = inject(UsersApiService)
|
|
62
|
+
private groupsApi = inject(GroupsApiService)
|
|
60
63
|
private mapper = inject(Gn4PlatformMapper)
|
|
61
64
|
private toolsApiService = inject(ToolsApiService)
|
|
62
65
|
private registriesApiService = inject(RegistriesApiService)
|
|
@@ -97,7 +100,7 @@ export class Gn4PlatformService implements PlatformServiceInterface {
|
|
|
97
100
|
private keywordsByThesauri: Record<string, Observable<Keyword[]>> = {}
|
|
98
101
|
|
|
99
102
|
private get lang3() {
|
|
100
|
-
return toLang3(this.translateService.
|
|
103
|
+
return toLang3(this.translateService.getCurrentLang())
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
constructor() {
|
|
@@ -155,6 +158,49 @@ export class Gn4PlatformService implements PlatformServiceInterface {
|
|
|
155
158
|
return this.users$
|
|
156
159
|
}
|
|
157
160
|
|
|
161
|
+
getUserPermissionsByGroup(): Observable<GroupModel[]> {
|
|
162
|
+
if (this.disableAuth) return of([])
|
|
163
|
+
return combineLatest([this.meApi.getMe(), this.groupsApi.getGroups()]).pipe(
|
|
164
|
+
map(([meResponse, groups]) => {
|
|
165
|
+
if (!meResponse) return []
|
|
166
|
+
if (meResponse.admin) {
|
|
167
|
+
return groups.map((group) => ({
|
|
168
|
+
groupId: group.id,
|
|
169
|
+
groupName: group.name,
|
|
170
|
+
isMember: true,
|
|
171
|
+
canEdit: true,
|
|
172
|
+
canApprove: true,
|
|
173
|
+
canAdministrate: true,
|
|
174
|
+
}))
|
|
175
|
+
}
|
|
176
|
+
const reviewerIds = meResponse.groupsWithReviewer ?? []
|
|
177
|
+
const editorIds = meResponse.groupsWithEditor ?? []
|
|
178
|
+
const memberIds = meResponse.groupsWithRegisteredUser ?? []
|
|
179
|
+
const adminIds = meResponse.groupsWithUserAdmin ?? []
|
|
180
|
+
const groupsById = new Map(groups.map((g) => [g.id, g]))
|
|
181
|
+
return [
|
|
182
|
+
...new Set([
|
|
183
|
+
...reviewerIds,
|
|
184
|
+
...editorIds,
|
|
185
|
+
...groups.map((g) => g.id),
|
|
186
|
+
]),
|
|
187
|
+
]
|
|
188
|
+
.filter((id) => groupsById.has(id))
|
|
189
|
+
.map((id) => {
|
|
190
|
+
const group = groupsById.get(id)
|
|
191
|
+
return {
|
|
192
|
+
groupId: group.id,
|
|
193
|
+
groupName: group.name,
|
|
194
|
+
isMember: memberIds.includes(id),
|
|
195
|
+
canEdit: editorIds.includes(id),
|
|
196
|
+
canApprove: reviewerIds.includes(id),
|
|
197
|
+
canAdministrate: adminIds.includes(id),
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
})
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
|
|
158
204
|
translateKey(key: string): Observable<string> {
|
|
159
205
|
// if the key is a URI, use the registries API to look for the translation
|
|
160
206
|
if (key.match(/^https?:\/\//)) {
|
|
@@ -104,15 +104,12 @@ export interface Keyword {
|
|
|
104
104
|
type: KeywordType
|
|
105
105
|
thesaurus?: ThesaurusModel
|
|
106
106
|
bbox?: [number, number, number, number]
|
|
107
|
+
// thesaurus hierarchy path incl. the keyword as last element; unset for root-level keywords
|
|
108
|
+
hierarchyPath?: string[]
|
|
107
109
|
|
|
108
110
|
translations?: KeywordTranslations
|
|
109
111
|
}
|
|
110
112
|
|
|
111
|
-
export interface INSPIRE_topic {
|
|
112
|
-
value: string
|
|
113
|
-
label: string
|
|
114
|
-
}
|
|
115
|
-
|
|
116
113
|
export interface ResourceIdentifier {
|
|
117
114
|
code: string
|
|
118
115
|
codeSpace?: string
|
|
@@ -254,10 +251,20 @@ export interface DatasetTemporalExtent {
|
|
|
254
251
|
end?: Date
|
|
255
252
|
}
|
|
256
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Represents a source dataset referenced from a lineage entry.
|
|
256
|
+
*/
|
|
257
|
+
export interface SourceRecord {
|
|
258
|
+
uuid?: string
|
|
259
|
+
title?: string
|
|
260
|
+
href?: string
|
|
261
|
+
}
|
|
262
|
+
|
|
257
263
|
export interface DatasetRecord extends BaseRecord {
|
|
258
264
|
kind: 'dataset'
|
|
259
265
|
status: RecordStatus
|
|
260
266
|
lineage: string // Explanation of the origin of this record (e.g: how, why)"
|
|
267
|
+
sourceRecords: Array<SourceRecord>
|
|
261
268
|
onlineResources: Array<DatasetOnlineResource>
|
|
262
269
|
spatialExtents: Array<DatasetSpatialExtent>
|
|
263
270
|
temporalExtents: Array<DatasetTemporalExtent>
|
|
@@ -285,6 +292,7 @@ export interface ServiceRecord extends BaseRecord {
|
|
|
285
292
|
export interface ReuseRecord extends BaseRecord {
|
|
286
293
|
kind: 'reuse'
|
|
287
294
|
lineage: string // Explanation of the origin of this record (e.g: how, why)"
|
|
295
|
+
sourceRecords: Array<SourceRecord>
|
|
288
296
|
onlineResources: Array<DatasetOnlineResource>
|
|
289
297
|
reuseType: ReuseType
|
|
290
298
|
spatialExtents: Array<DatasetSpatialExtent>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Observable } from 'rxjs'
|
|
2
2
|
import type { UserModel } from './model/user/user.model'
|
|
3
|
+
import type { GroupModel } from './model/user/group.model'
|
|
3
4
|
import type { Organization } from './model/record/organization.model'
|
|
4
5
|
import { CatalogRecord, Keyword, UserFeedback } from './model/record'
|
|
5
6
|
import { KeywordType } from './model/thesaurus'
|
|
@@ -28,6 +29,7 @@ export abstract class PlatformServiceInterface {
|
|
|
28
29
|
abstract getMe(): Observable<UserModel>
|
|
29
30
|
abstract isAnonymous(): Observable<boolean>
|
|
30
31
|
abstract getUsers(): Observable<UserModel[]>
|
|
32
|
+
abstract getUserPermissionsByGroup(): Observable<GroupModel[]>
|
|
31
33
|
abstract getUsersByOrganization(
|
|
32
34
|
organisation: Organization
|
|
33
35
|
): Observable<UserModel[]>
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
DatasetRecord,
|
|
4
4
|
DatasetSpatialExtent,
|
|
5
5
|
Keyword,
|
|
6
|
+
ReuseRecord,
|
|
6
7
|
ServiceRecord,
|
|
7
8
|
} from '../../../../../libs/common/domain/src/lib/model/record'
|
|
8
9
|
|
|
@@ -134,6 +135,7 @@ Cette section contient des *caractères internationaux* (ainsi que des "caractè
|
|
|
134
135
|
lineage: `This record was edited manually to test the conversion processes
|
|
135
136
|
|
|
136
137
|
As such, **it is not very interesting at all.**`,
|
|
138
|
+
sourceRecords: [],
|
|
137
139
|
licenses: [
|
|
138
140
|
{
|
|
139
141
|
text: 'Licence ODbL mai 2013 (basée sur ODbL 1.0)',
|
|
@@ -310,6 +312,7 @@ Malgré l'attention portée à la création de ces données, il est rappelé que
|
|
|
310
312
|
],
|
|
311
313
|
lineage: `Document d’urbanisme numérisé conformément aux prescriptions nationales du CNIG par le Service d'Information Géographique de l'Agglomération de la Région de Compiègne.
|
|
312
314
|
Ce lot de données produit en 2019, a été numérisé à partir du PCI Vecteur de 2019 et contrôlé par le Service d'Information Géographique de l'Agglomération de la Région de Compiègne.`,
|
|
315
|
+
sourceRecords: [],
|
|
313
316
|
legalConstraints: [],
|
|
314
317
|
securityConstraints: [],
|
|
315
318
|
otherConstraints: [],
|
|
@@ -361,6 +364,7 @@ export const simpleDatasetRecordFixture = (): DatasetRecord => ({
|
|
|
361
364
|
overviews: [],
|
|
362
365
|
spatialExtents: [],
|
|
363
366
|
temporalExtents: [],
|
|
367
|
+
sourceRecords: [],
|
|
364
368
|
onlineResources: [
|
|
365
369
|
{
|
|
366
370
|
type: 'download',
|
|
@@ -413,6 +417,7 @@ export const simpleDatasetRecordWithFcatsFixture = (): DatasetRecord => ({
|
|
|
413
417
|
overviews: [],
|
|
414
418
|
spatialExtents: [],
|
|
415
419
|
temporalExtents: [],
|
|
420
|
+
sourceRecords: [],
|
|
416
421
|
onlineResources: [],
|
|
417
422
|
updateFrequency: { per: 'month', updatedTimes: 3 },
|
|
418
423
|
translations: {},
|
|
@@ -978,6 +983,7 @@ export const multilingualDatasetFixture: () => DatasetRecord = () => ({
|
|
|
978
983
|
title: 'English Title',
|
|
979
984
|
abstract: 'English Abstract',
|
|
980
985
|
lineage: 'English Lineage',
|
|
986
|
+
sourceRecords: [],
|
|
981
987
|
translations: {
|
|
982
988
|
title: { fr: 'Titre Français', de: 'Titel DE' },
|
|
983
989
|
abstract: { fr: 'Résumé Français', de: 'Beschreibung DE' },
|
|
@@ -1022,3 +1028,53 @@ export const multilingualDatasetFixture: () => DatasetRecord = () => ({
|
|
|
1022
1028
|
topics: [],
|
|
1023
1029
|
recordUpdated: null,
|
|
1024
1030
|
})
|
|
1031
|
+
|
|
1032
|
+
export const simpleReuseRecordFixture = (): ReuseRecord => ({
|
|
1033
|
+
abstract: `Sample reuse record`,
|
|
1034
|
+
kind: 'reuse',
|
|
1035
|
+
reuseType: 'application',
|
|
1036
|
+
recordUpdated: new Date('2023-03-17T07:38:08.875Z'),
|
|
1037
|
+
recordPublished: null,
|
|
1038
|
+
ownerOrganization: null,
|
|
1039
|
+
licenses: [],
|
|
1040
|
+
legalConstraints: [],
|
|
1041
|
+
securityConstraints: [],
|
|
1042
|
+
otherConstraints: [],
|
|
1043
|
+
contacts: [],
|
|
1044
|
+
contactsForResource: [],
|
|
1045
|
+
keywords: [],
|
|
1046
|
+
topics: [],
|
|
1047
|
+
spatialExtents: [],
|
|
1048
|
+
temporalExtents: [],
|
|
1049
|
+
lineage: 'bla',
|
|
1050
|
+
sourceRecords: [],
|
|
1051
|
+
overviews: [],
|
|
1052
|
+
defaultLanguage: null,
|
|
1053
|
+
otherLanguages: [],
|
|
1054
|
+
title: 'Sites de gestion des déchets miniers - Service de visualisation WMS',
|
|
1055
|
+
onlineResources: [
|
|
1056
|
+
{
|
|
1057
|
+
name: 'Rapport de disponibilité du service WMS',
|
|
1058
|
+
description:
|
|
1059
|
+
'Ce service de visualisation WMS permet de consulter la série de couches de données "Sites de gestion des déchets miniers - Série".',
|
|
1060
|
+
mimeType: 'text/html',
|
|
1061
|
+
type: 'link',
|
|
1062
|
+
url: new URL(
|
|
1063
|
+
'https://geoservices.wallonie.be/rapportDisponibilite/wms/sites_de_gestion_des_dechets_miniers_srie.html'
|
|
1064
|
+
),
|
|
1065
|
+
accessRestricted: false,
|
|
1066
|
+
},
|
|
1067
|
+
],
|
|
1068
|
+
uniqueIdentifier: '00b22798-ec8e-4500-89e8-90eeeda45919',
|
|
1069
|
+
landingPage: new URL(
|
|
1070
|
+
'http://localhost:4200/geonetwork/srv/fre/catalog.search#/metadata/00b22798-ec8e-4500-89e8-90eeeda45919'
|
|
1071
|
+
),
|
|
1072
|
+
extras: {
|
|
1073
|
+
isPublishedToAll: true,
|
|
1074
|
+
id: '723',
|
|
1075
|
+
isHarvested: true,
|
|
1076
|
+
ownerInfo: 'admin|admin|admin|Administrator',
|
|
1077
|
+
edit: true,
|
|
1078
|
+
},
|
|
1079
|
+
recordCreated: new Date('2023-03-17T07:38:08.875Z'),
|
|
1080
|
+
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { inject, Injectable } from '@angular/core'
|
|
2
2
|
import { SourcesApiService } from '../../../../../../libs/data-access/gn4/src'
|
|
3
3
|
import { Observable } from 'rxjs'
|
|
4
4
|
import { filter, map, shareReplay } from 'rxjs/operators'
|
|
@@ -21,7 +21,10 @@ export class SourcesService {
|
|
|
21
21
|
return this.sources$.pipe(
|
|
22
22
|
map((sources) => sources.filter((source) => source.uuid === uuid)[0]),
|
|
23
23
|
filter((source) => !!source),
|
|
24
|
-
map(
|
|
24
|
+
map(
|
|
25
|
+
(source) =>
|
|
26
|
+
source.label[toLang3(this.translateService.getCurrentLang())]
|
|
27
|
+
)
|
|
25
28
|
)
|
|
26
29
|
}
|
|
27
30
|
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
></gn-ui-dropdown-selector>
|
|
21
21
|
@if (yChoices$ | async; as yChoices) {
|
|
22
22
|
<gn-ui-dropdown-selector
|
|
23
|
-
class="basis-1/4 select-y-prop"
|
|
23
|
+
class="basis-1/4 flex items-center select-y-prop"
|
|
24
24
|
[choices]="yChoices"
|
|
25
25
|
[disabled]="isCountAggregation"
|
|
26
26
|
(selectValue)="yProperty$.next($event)"
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
></gn-ui-dropdown-selector>
|
|
30
30
|
}
|
|
31
31
|
<gn-ui-dropdown-selector
|
|
32
|
-
class="basis-1/4"
|
|
32
|
+
class="basis-1/4 aggregation-choices"
|
|
33
33
|
[choices]="aggregationChoices"
|
|
34
|
-
|
|
34
|
+
[disabled]="!yProperty$.value"
|
|
35
35
|
(selectValue)="aggregation$.next($event)"
|
|
36
36
|
[selected]="aggregation$.value"
|
|
37
37
|
[title]="'chart.dropdown.aggregation' | translate"
|
|
@@ -8,6 +8,8 @@ export * from './lib/components/metadata-quality-panel/metadata-quality-panel.co
|
|
|
8
8
|
export * from './lib/components/multilingual-panel/multilingual-panel.component'
|
|
9
9
|
export * from './lib/components/record-form/form-field'
|
|
10
10
|
export * from './lib/components/record-form/record-form.component'
|
|
11
|
+
export * from './lib/components/online-service-resource-input/online-service-resource-input.component'
|
|
12
|
+
export * from './lib/components/online-resource-card/online-resource-card.component'
|
|
11
13
|
export * from './lib/feature-editor.module'
|
|
12
14
|
export * from './lib/fields.config'
|
|
13
15
|
export * from './lib/services/editor.service'
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createAction, props } from '@ngrx/store'
|
|
2
2
|
import {
|
|
3
3
|
CatalogRecord,
|
|
4
|
+
CatalogRecordKeys,
|
|
4
5
|
LanguageCode,
|
|
5
6
|
} from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
6
7
|
import { SaveRecordError } from './editor.models'
|
|
@@ -28,7 +29,10 @@ export const markRecordAsChanged = createAction(
|
|
|
28
29
|
'[Editor] Mark record as changed'
|
|
29
30
|
)
|
|
30
31
|
|
|
31
|
-
export const saveRecord = createAction(
|
|
32
|
+
export const saveRecord = createAction(
|
|
33
|
+
'[Editor] Save record',
|
|
34
|
+
props<{ publish: boolean }>()
|
|
35
|
+
)
|
|
32
36
|
export const saveRecordSuccess = createAction('[Editor] Save record success')
|
|
33
37
|
export const saveRecordFailure = createAction(
|
|
34
38
|
'[Editor] Save record failure',
|
|
@@ -73,3 +77,8 @@ export const canEditRecord = createAction(
|
|
|
73
77
|
'[Editor] User can edit record',
|
|
74
78
|
props<{ canEditRecord: boolean }>()
|
|
75
79
|
)
|
|
80
|
+
|
|
81
|
+
export const setFocusedField = createAction(
|
|
82
|
+
'[Editor] Set focused field',
|
|
83
|
+
props<{ model: CatalogRecordKeys }>()
|
|
84
|
+
)
|