geonetwork-ui 2.9.0-dev.2757b04b7 → 2.9.0-dev.388501cd7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/fesm2022/geonetwork-ui.mjs +524 -492
  2. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  3. package/index.d.ts +238 -157
  4. package/index.d.ts.map +1 -1
  5. package/package.json +1 -1
  6. package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +5 -1
  7. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +13 -6
  8. package/src/libs/feature/editor/src/index.ts +8 -7
  9. package/src/libs/feature/editor/src/lib/+state/editor.actions.ts +6 -1
  10. package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +5 -1
  11. package/src/libs/feature/editor/src/lib/+state/editor.reducer.ts +4 -0
  12. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +2 -2
  13. package/src/libs/feature/search/src/lib/utils/service/fields.service.ts +9 -3
  14. package/src/libs/feature/search/src/lib/utils/service/fields.ts +5 -5
  15. package/src/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.html +11 -8
  16. package/src/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.ts +3 -3
  17. package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.ts +7 -5
  18. package/src/libs/util/app-config/src/lib/app-config.ts +3 -0
  19. package/src/libs/util/app-config/src/lib/fixtures.ts +1 -0
  20. package/src/libs/util/app-config/src/lib/model.ts +1 -0
  21. package/src/libs/util/shared/src/lib/gn-ui-version.ts +5 -4
  22. package/translations/de.json +3 -2
  23. package/translations/en.json +6 -5
  24. package/translations/es.json +1 -0
  25. package/translations/fr.json +6 -5
  26. package/translations/it.json +6 -5
  27. package/translations/nl.json +1 -0
  28. package/translations/pt.json +1 -0
  29. package/translations/sk.json +2 -1
@@ -13,7 +13,7 @@ import * as i4 from '@ngx-translate/core';
13
13
  import { TranslateLoader, TranslateCompiler, TranslateDefaultParser, TranslateParser, TranslateService, provideTranslateService, TranslateDirective, TranslatePipe, TranslateModule } from '@ngx-translate/core';
14
14
  import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler';
15
15
  import { TranslateHttpLoader } from '@ngx-translate/http-loader';
16
- import { map as map$1, shareReplay as shareReplay$1, catchError, tap as tap$1, filter as filter$1, startWith as startWith$1, withLatestFrom, switchMap as switchMap$1, take, mergeMap, delay, distinctUntilChanged, debounceTime, finalize, throttleTime, first as first$1, pairwise as pairwise$1, share, defaultIfEmpty, toArray } from 'rxjs/operators';
16
+ import { map as map$1, shareReplay as shareReplay$1, catchError, tap as tap$1, filter as filter$1, startWith as startWith$1, withLatestFrom, switchMap as switchMap$1, take, mergeMap, delay, debounceTime, distinctUntilChanged, finalize, throttleTime, first as first$1, pairwise as pairwise$1, share, defaultIfEmpty, toArray } from 'rxjs/operators';
17
17
  import { of, map as map$2, lastValueFrom, fromEvent, startWith, shareReplay, filter, pairwise, switchMap, Subject, combineLatest, from, exhaustMap, throwError, forkJoin, takeLast, firstValueFrom, merge, BehaviorSubject, timer, ReplaySubject, Subscription, first, distinctUntilChanged as distinctUntilChanged$1, animationFrameScheduler, debounceTime as debounceTime$1, Observable, buffer, tap as tap$2, combineLatestWith, take as take$1, catchError as catchError$1, takeUntil, EMPTY, mergeMap as mergeMap$1, withLatestFrom as withLatestFrom$1 } from 'rxjs';
18
18
  import { lt, valid, coerce, satisfies, ltr } from 'semver';
19
19
  import chroma from 'chroma-js';
@@ -41,7 +41,7 @@ import * as TOML from '@ltd/j-toml';
41
41
  import { Style, Stroke, Fill, Circle } from 'ol/style.js';
42
42
  import CircleStyle from 'ol/style/Circle.js';
43
43
  import EmblaCarousel from 'embla-carousel';
44
- import { iconoirNavArrowLeft, iconoirNavArrowRight, iconoirLongArrowDownLeft, iconoirSearch, iconoirCalendar, iconoirArrowUp, iconoirLink, iconoirFramePlusIn, iconoirCloudUpload, iconoirReduce, iconoirNavArrowUp, iconoirNavArrowDown, iconoirExpand, iconoirSettings, iconoirDownload, iconoirPlus, iconoirBin, iconoirMediaImageXmark, iconoirMediaImage, iconoirAppWindow, iconoirCode, iconoirDatabase, iconoirAppleWallet, iconoirBank, iconoirList, iconoirTranslate, iconoirLock, iconoirUser, iconoirArrowLeft, iconoirLightBulbOn, iconoirImport, iconoirAttachment, iconoirRefresh, iconoirCircle, iconoirCheckCircle, iconoirBadgeCheck, iconoirSystemShut } from '@ng-icons/iconoir';
44
+ import { iconoirNavArrowLeft, iconoirNavArrowRight, iconoirLongArrowDownLeft, iconoirSearch, iconoirCalendar, iconoirArrowUp, iconoirLink, iconoirFramePlusIn, iconoirCloudUpload, iconoirReduce, iconoirNavArrowUp, iconoirNavArrowDown, iconoirExpand, iconoirSettings, iconoirDownload, iconoirPlus, iconoirBin, iconoirMediaImageXmark, iconoirMediaImage, iconoirAppWindow, iconoirCode, iconoirDatabase, iconoirAppleWallet, iconoirBank, iconoirList, iconoirTranslate, iconoirLock, iconoirUser, iconoirArrowLeft, iconoirLightBulbOn, iconoirImport, iconoirBadgeCheck, iconoirSystemShut, iconoirCircle, iconoirCheckCircle, iconoirAttachment, iconoirRefresh } from '@ng-icons/iconoir';
45
45
  import { MatButtonModule } from '@angular/material/button';
46
46
  import * as i1$8 from '@angular/cdk/overlay';
47
47
  import { OverlayContainer, ScrollStrategyOptions, OverlayModule, CdkConnectedOverlay, ScrollDispatcher, Overlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
@@ -18975,6 +18975,7 @@ var de = {
18975
18975
  "multiselect.filter.placeholder": "Suche",
18976
18976
  "nav.back": "Zurück",
18977
18977
  "navbar.mobile.menuTitle": "Schnellzugriff",
18978
+ "ogc.geojson.notsupported": "Dieser OGC API-Dienst unterstützt das GeoJSON-Format nicht.",
18978
18979
  "ogc.unreachable.unknown": "Der Dienst konnte nicht erreicht werden",
18979
18980
  "organisation.filter.placeholder": "Ergebnisse filtern",
18980
18981
  "organisation.sort.sortBy": "Sortieren nach:",
@@ -19060,7 +19061,7 @@ var de = {
19060
19061
  "record.metadata.download": "Herunterladen",
19061
19062
  "record.metadata.feature.catalog": "Attributkatalog",
19062
19063
  "record.metadata.formats": "Formate",
19063
- "record.metadata.isGeographical": "Geographischer Datensatz",
19064
+ "record.metadata.isGeographical": "geographischer Datensatz",
19064
19065
  "record.metadata.keywords": "Stichworte",
19065
19066
  "record.metadata.languages": "Sprachen",
19066
19067
  "record.metadata.link.postgis.table": "Tabelle:",
@@ -19249,7 +19250,7 @@ var de = {
19249
19250
  "wfs.feature.limit": "Zu viele Features, um den WFS-Layer anzuzeigen!",
19250
19251
  "wfs.featuretype.notfound": "Kein passender Feature-Typ wurde im Dienst gefunden",
19251
19252
  "wfs.geojsongml.notsupported": "Dieser Dienst unterstützt das GeoJSON- oder GML-Format nicht",
19252
- "wfs.unreachable.cors": "Der Dienst konnte aufgrund von CORS-Beschränkungen nicht erreicht werden",
19253
+ "wfs.unreachable.cors": "Der Remote-Dienst ist nicht für den Datenempfang (CORS) konfiguriert",
19253
19254
  "wfs.unreachable.http": "Der Dienst hat einen HTTP-Fehler zurückgegeben",
19254
19255
  "wfs.unreachable.unknown": "Der Dienst konnte nicht erreicht werden"
19255
19256
  };
@@ -19645,6 +19646,7 @@ var en = {
19645
19646
  "multiselect.filter.placeholder": "Search",
19646
19647
  "nav.back": "Back",
19647
19648
  "navbar.mobile.menuTitle": "Quick access",
19649
+ "ogc.geojson.notsupported": "This OGC API does not support the GeoJSON format",
19648
19650
  "ogc.unreachable.unknown": "The service could not be reached",
19649
19651
  "organisation.filter.placeholder": "Filter results",
19650
19652
  "organisation.sort.sortBy": "Sort by:",
@@ -19672,9 +19674,9 @@ var en = {
19672
19674
  "record.feature.catalog.number.total.attribute": "Total amount of objects",
19673
19675
  "record.feature.catalog.number.total.object": "Total amount of attributes",
19674
19676
  "record.feature.limit": "Preview disabled due to too many elements",
19675
- "record.kind.dataset": "Dataset",
19676
- "record.kind.reuse": "Reuse",
19677
- "record.kind.service": "Service",
19677
+ "record.kind.dataset": "dataset",
19678
+ "record.kind.reuse": "reuse",
19679
+ "record.kind.service": "service",
19678
19680
  "record.metadata.about": "Description",
19679
19681
  "record.metadata.api": "API",
19680
19682
  "record.metadata.api.accessServiceProtocol.GPFDL": "GPFDL",
@@ -19730,7 +19732,7 @@ var en = {
19730
19732
  "record.metadata.download": "Downloads",
19731
19733
  "record.metadata.feature.catalog": "Feature catalog",
19732
19734
  "record.metadata.formats": "Formats",
19733
- "record.metadata.isGeographical": "Geographical dataset",
19735
+ "record.metadata.isGeographical": "geographic dataset",
19734
19736
  "record.metadata.keywords": "Keywords",
19735
19737
  "record.metadata.languages": "Languages",
19736
19738
  "record.metadata.link.postgis.table": "table :",
@@ -19920,7 +19922,7 @@ var en = {
19920
19922
  "wfs.feature.limit": "Too many features to display the WFS layer!",
19921
19923
  "wfs.featuretype.notfound": "No matching feature type was found in the service",
19922
19924
  "wfs.geojsongml.notsupported": "This service does not support the GeoJSON or GML format",
19923
- "wfs.unreachable.cors": "The service could not be reached due to CORS limitations",
19925
+ "wfs.unreachable.cors": "The remote service is not configured to allow data retrieval (CORS)",
19924
19926
  "wfs.unreachable.http": "The service returned an HTTP error",
19925
19927
  "wfs.unreachable.unknown": "The service could not be reached"
19926
19928
  };
@@ -20316,6 +20318,7 @@ var es = {
20316
20318
  "multiselect.filter.placeholder": "",
20317
20319
  "nav.back": "",
20318
20320
  "navbar.mobile.menuTitle": "Acceso rápido",
20321
+ "ogc.geojson.notsupported": "",
20319
20322
  "ogc.unreachable.unknown": "",
20320
20323
  "organisation.filter.placeholder": "",
20321
20324
  "organisation.sort.sortBy": "",
@@ -20987,6 +20990,7 @@ var fr = {
20987
20990
  "multiselect.filter.placeholder": "Rechercher",
20988
20991
  "nav.back": "Retour",
20989
20992
  "navbar.mobile.menuTitle": "Navigation rapide",
20993
+ "ogc.geojson.notsupported": "Le service OGC API ne supporte pas le format GeoJSON",
20990
20994
  "ogc.unreachable.unknown": "Le service n'est pas accessible",
20991
20995
  "organisation.filter.placeholder": "Filtrer les résultats",
20992
20996
  "organisation.sort.sortBy": "Trier par :",
@@ -21014,9 +21018,9 @@ var fr = {
21014
21018
  "record.feature.catalog.number.total.attribute": "Nombre total d'attributs",
21015
21019
  "record.feature.catalog.number.total.object": "Nombre total d'objets",
21016
21020
  "record.feature.limit": "L’aperçu a été désactivé en raison d’un trop grand nombre d'éléments",
21017
- "record.kind.dataset": "Donnée",
21018
- "record.kind.reuse": "Réutilisation",
21019
- "record.kind.service": "Service",
21021
+ "record.kind.dataset": "donnée",
21022
+ "record.kind.reuse": "réutilisation",
21023
+ "record.kind.service": "service",
21020
21024
  "record.metadata.about": "A propos",
21021
21025
  "record.metadata.api": "API",
21022
21026
  "record.metadata.api.accessServiceProtocol.GPFDL": "",
@@ -21072,7 +21076,7 @@ var fr = {
21072
21076
  "record.metadata.download": "Téléchargements",
21073
21077
  "record.metadata.feature.catalog": "Catalogue d'attributs",
21074
21078
  "record.metadata.formats": "Formats",
21075
- "record.metadata.isGeographical": "Donnée géographique",
21079
+ "record.metadata.isGeographical": "donnée géographique",
21076
21080
  "record.metadata.keywords": "Mots-clés",
21077
21081
  "record.metadata.languages": "Langues",
21078
21082
  "record.metadata.link.postgis.table": "table :",
@@ -21262,7 +21266,7 @@ var fr = {
21262
21266
  "wfs.feature.limit": "Trop d'objets pour afficher la couche WFS !",
21263
21267
  "wfs.featuretype.notfound": "La classe d'objets n'a pas été trouvée dans le service",
21264
21268
  "wfs.geojsongml.notsupported": "Le service ne supporte pas le format GeoJSON ou GML",
21265
- "wfs.unreachable.cors": "Le service n'est pas accessible en raison de limitations CORS",
21269
+ "wfs.unreachable.cors": "Le service distant n'est pas configuré pour autoriser la consommation des données (CORS)",
21266
21270
  "wfs.unreachable.http": "Le service a retourné une erreur HTTP",
21267
21271
  "wfs.unreachable.unknown": "Le service n'est pas accessible"
21268
21272
  };
@@ -21658,6 +21662,7 @@ var it = {
21658
21662
  "multiselect.filter.placeholder": "Cerca",
21659
21663
  "nav.back": "Indietro",
21660
21664
  "navbar.mobile.menuTitle": "Accesso rapido",
21665
+ "ogc.geojson.notsupported": "Il servizio OGC API non supporta il formato GeoJSON.",
21661
21666
  "ogc.unreachable.unknown": "Il servizio non è accessibile",
21662
21667
  "organisation.filter.placeholder": "Filtra i risultati",
21663
21668
  "organisation.sort.sortBy": "Ordina per:",
@@ -21685,9 +21690,9 @@ var it = {
21685
21690
  "record.feature.catalog.number.total.attribute": "Quantità totale di oggetti",
21686
21691
  "record.feature.catalog.number.total.object": "Quantità totale di attributi",
21687
21692
  "record.feature.limit": "La visualizzazione è stata disabilitata a causa di troppi elementi ",
21688
- "record.kind.dataset": "Dataset",
21689
- "record.kind.reuse": "Riutilizzato",
21690
- "record.kind.service": "Servizio",
21693
+ "record.kind.dataset": "dataset",
21694
+ "record.kind.reuse": "riutilizzato",
21695
+ "record.kind.service": "servizio",
21691
21696
  "record.metadata.about": "Descrizione",
21692
21697
  "record.metadata.api": "API",
21693
21698
  "record.metadata.api.accessServiceProtocol.GPFDL": "",
@@ -21743,7 +21748,7 @@ var it = {
21743
21748
  "record.metadata.download": "Download",
21744
21749
  "record.metadata.feature.catalog": "Catalogo dei oggetti",
21745
21750
  "record.metadata.formats": "Formati",
21746
- "record.metadata.isGeographical": "Dati geografici",
21751
+ "record.metadata.isGeographical": "dati geografici",
21747
21752
  "record.metadata.keywords": "Parole chiave",
21748
21753
  "record.metadata.languages": "Lingue",
21749
21754
  "record.metadata.link.postgis.table": "",
@@ -21933,7 +21938,7 @@ var it = {
21933
21938
  "wfs.feature.limit": "Troppi oggetti per visualizzare il WFS layer!",
21934
21939
  "wfs.featuretype.notfound": "La classe di oggetto non è stata trovata nel servizio",
21935
21940
  "wfs.geojsongml.notsupported": "Il servizio non supporta il formato GeoJSON o GML",
21936
- "wfs.unreachable.cors": "Il servizio non è accessibile a causa di limitazioni CORS",
21941
+ "wfs.unreachable.cors": "Il servizio remoto non è configurato per consentire il consumo di dati (CORS)",
21937
21942
  "wfs.unreachable.http": "Il servizio ha restituito un errore HTTP",
21938
21943
  "wfs.unreachable.unknown": "Il servizio non è accessibile"
21939
21944
  };
@@ -22329,6 +22334,7 @@ var nl = {
22329
22334
  "multiselect.filter.placeholder": "",
22330
22335
  "nav.back": "",
22331
22336
  "navbar.mobile.menuTitle": "",
22337
+ "ogc.geojson.notsupported": "",
22332
22338
  "ogc.unreachable.unknown": "",
22333
22339
  "organisation.filter.placeholder": "",
22334
22340
  "organisation.sort.sortBy": "",
@@ -23000,6 +23006,7 @@ var pt = {
23000
23006
  "multiselect.filter.placeholder": "",
23001
23007
  "nav.back": "",
23002
23008
  "navbar.mobile.menuTitle": "",
23009
+ "ogc.geojson.notsupported": "",
23003
23010
  "ogc.unreachable.unknown": "",
23004
23011
  "organisation.filter.placeholder": "",
23005
23012
  "organisation.sort.sortBy": "",
@@ -23671,6 +23678,7 @@ var sk = {
23671
23678
  "multiselect.filter.placeholder": "Hľadať",
23672
23679
  "nav.back": "Späť",
23673
23680
  "navbar.mobile.menuTitle": "",
23681
+ "ogc.geojson.notsupported": "",
23674
23682
  "ogc.unreachable.unknown": "So službou sa nedalo spojiť",
23675
23683
  "organisation.filter.placeholder": "Filtrovať výsledky",
23676
23684
  "organisation.sort.sortBy": "Zoradiť podľa:",
@@ -23946,7 +23954,7 @@ var sk = {
23946
23954
  "wfs.feature.limit": "",
23947
23955
  "wfs.featuretype.notfound": "V službe nebol nájdený žiadny zodpovedajúci typ funkcie",
23948
23956
  "wfs.geojsongml.notsupported": "Táto služba nepodporuje formát GeoJSON alebo GML",
23949
- "wfs.unreachable.cors": "Službu nemožno dosiahnuť z dôvodu obmedzení CORS",
23957
+ "wfs.unreachable.cors": "Vzdialená služba nie je nakonfigurovaná tak, aby povoľovala spotrebu dát (CORS)",
23950
23958
  "wfs.unreachable.http": "Služba vrátila chybu HTTP",
23951
23959
  "wfs.unreachable.unknown": "So službou sa nedalo spojiť"
23952
23960
  };
@@ -25511,7 +25519,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
25511
25519
  }] } });
25512
25520
 
25513
25521
  var name = "geonetwork-ui";
25514
- var version = "2.9.0-dev.2757b04b7";
25522
+ var version = "2.9.0-dev.388501cd7";
25515
25523
  var engines = {
25516
25524
  node: ">=20"
25517
25525
  };
@@ -25607,7 +25615,7 @@ var packageJson = {
25607
25615
  };
25608
25616
 
25609
25617
  const GEONETWORK_UI_VERSION = packageJson.version;
25610
- const GEONETWORK_UI_TAG_NAME = GEONETWORK_UI_VERSION.split('-')[1] === 'dev'
25618
+ const GEONETWORK_UI_TAG_NAME = GEONETWORK_UI_VERSION.split('-')[1]?.startsWith('dev')
25611
25619
  ? 'main'
25612
25620
  : `v${packageJson.version}`;
25613
25621
 
@@ -25925,14 +25933,18 @@ class ElasticsearchService {
25925
25933
  })
25926
25934
  .join(' OR ');
25927
25935
  };
25928
- const queryString = typeof filters === 'string'
25936
+ let queryString = typeof filters === 'string'
25929
25937
  ? filters
25930
25938
  : Object.keys(filters)
25939
+ .filter((fieldname) => fieldname !== 'gn-ui-crossFieldFilter')
25931
25940
  .filter((fieldname) => !isDateRange(filters[fieldname]))
25932
25941
  .filter((fieldname) => filters[fieldname] &&
25933
25942
  JSON.stringify(filters[fieldname]) !== '{}')
25934
25943
  .map((fieldname) => `${fieldname}:(${makeQuery(filters[fieldname])})`)
25935
25944
  .join(' AND ');
25945
+ if (filters['gn-ui-crossFieldFilter']) {
25946
+ queryString = `${queryString} AND (${filters['gn-ui-crossFieldFilter']})`;
25947
+ }
25936
25948
  const queryRange = Object.entries(filters)
25937
25949
  .filter(([, value]) => isDateRange(value))
25938
25950
  .map(([searchField, dateRange]) => {
@@ -28275,6 +28287,7 @@ function loadAppConfig() {
28275
28287
  'record_kind_quick_filter',
28276
28288
  'filter_geometry_data',
28277
28289
  'filter_geometry_url',
28290
+ 'do_not_use_default_search_preset',
28278
28291
  'search_preset',
28279
28292
  'advanced_filters',
28280
28293
  'limit',
@@ -28287,6 +28300,7 @@ function loadAppConfig() {
28287
28300
  RECORD_KIND_QUICK_FILTER: parsedSearchSection.record_kind_quick_filter,
28288
28301
  FILTER_GEOMETRY_DATA: parsedSearchSection.filter_geometry_data,
28289
28302
  FILTER_GEOMETRY_URL: parsedSearchSection.filter_geometry_url,
28303
+ DO_NOT_USE_DEFAULT_SEARCH_PRESET: !!parsedSearchSection.do_not_use_default_search_preset,
28290
28304
  SEARCH_PRESET: parsedSearchParams.map((param) => ({
28291
28305
  sort: param.sort,
28292
28306
  name: param.name,
@@ -28377,6 +28391,7 @@ fonts_stylesheet_url = "https://fonts.googleapis.com/css2?family=Open+Sans"
28377
28391
  [search]
28378
28392
  record_kind_quick_filter = false
28379
28393
  filter_geometry_url = 'https://my.domain.org/geom.json'
28394
+ do_not_use_default_search_preset = false
28380
28395
  advanced_filters = ['publicationYear', 'documentStandard', 'inspireKeyword', 'topic', 'license']
28381
28396
 
28382
28397
  [[search_preset]]
@@ -29192,9 +29207,8 @@ class AutocompleteComponent {
29192
29207
  ngOnChanges(changes) {
29193
29208
  const { value } = changes;
29194
29209
  if (value) {
29195
- const previousTextValue = this.displayWithFnInternal(value.previousValue);
29196
29210
  const currentTextValue = this.displayWithFnInternal(value.currentValue);
29197
- if (previousTextValue !== currentTextValue) {
29211
+ if (currentTextValue !== this.control.value) {
29198
29212
  if (currentTextValue) {
29199
29213
  this.searchActive = true;
29200
29214
  this.isSearchActive.emit(true);
@@ -29208,13 +29222,15 @@ class AutocompleteComponent {
29208
29222
  }
29209
29223
  }
29210
29224
  ngOnInit() {
29211
- const newValue$ = merge(of(''), this.inputCleared.pipe(map$1(() => '')), this.control.valueChanges.pipe(filter$1((value) => typeof value === 'string'), distinctUntilChanged(), debounceTime(400)));
29225
+ const newValue$ = merge(of(''), this.inputCleared.pipe(map$1(() => '')), this.control.valueChanges.pipe(filter$1((value) => typeof value === 'string'), debounceTime(400), distinctUntilChanged()));
29212
29226
  const externalValueChange$ = this.control.valueChanges.pipe(filter$1((value) => typeof value === 'object' && value.title), map$1((item) => item.title));
29213
29227
  // this observable emits arrays of suggestions loaded using the given action
29214
29228
  const suggestionsFromAction = merge(newValue$.pipe(filter$1((value) => value.length >= this.minCharacterCount)), externalValueChange$).pipe(tap$1(() => {
29215
29229
  this.searching = true;
29216
29230
  this.error = null;
29217
- }), switchMap$1((value) => this.action(value)), tap$1((suggestions) => {
29231
+ }), switchMap$1((value) => this.action(value)), // this can trigger http requests
29232
+ shareReplay$1(1), // share the loaded suggestions to avoid multiple requests
29233
+ tap$1((suggestions) => {
29218
29234
  // forcing the panel to open if there are suggestions
29219
29235
  if (suggestions.length > 0 && !this.searchActive) {
29220
29236
  this.triggerRef?.openPanel();
@@ -29275,6 +29291,7 @@ class AutocompleteComponent {
29275
29291
  }
29276
29292
  clear() {
29277
29293
  this.inputRef.nativeElement.value = '';
29294
+ this.control.setValue('');
29278
29295
  this.searchActive = false;
29279
29296
  this.isSearchActive.emit(false);
29280
29297
  this.inputCleared.emit();
@@ -32976,8 +32993,8 @@ class RecordKindField extends SimpleSearchField {
32976
32993
  };
32977
32994
  const presentationFormFilter = {};
32978
32995
  if (values.includes('reuse') && !values.includes('dataset')) {
32979
- presentationFormFilter['mapDigital'] = true;
32980
- presentationFormFilter['mapHardcopy'] = true;
32996
+ filters['gn-ui-crossFieldFilter'] =
32997
+ `(resourceType:("dataset" OR "document") AND cl_presentationForm.key:("mapDigital" OR "mapHardcopy")) OR resourceType:("application" OR "interactiveMap" OR "map" OR "map/static" OR "map/interactive" OR "map-interactive" OR "map-static" OR "mapDigital" OR "mapHardcopy" OR "staticMap")`;
32981
32998
  }
32982
32999
  else if (values.includes('dataset') && !values.includes('reuse')) {
32983
33000
  presentationFormFilter['mapDigital'] = false;
@@ -33070,7 +33087,12 @@ class FieldsService {
33070
33087
  : [fieldValues[fieldName]];
33071
33088
  return this.getFiltersForValues(fieldName, values);
33072
33089
  });
33073
- return forkJoin(filtersByField$).pipe(map$1((filters) => filters.reduce((prev, curr) => ({ ...prev, ...curr }), {})));
33090
+ return forkJoin(filtersByField$).pipe(map$1((filters) => {
33091
+ if (typeof filters === 'string') {
33092
+ return filters;
33093
+ }
33094
+ return filters.reduce((prev, curr) => ({ ...prev, ...curr }), {});
33095
+ }));
33074
33096
  }
33075
33097
  readFieldValuesFromFilters(filters) {
33076
33098
  const fieldValues$ = this.supportedFields.map((fieldName) => this.getValuesForFilters(fieldName, filters).pipe(map$1((values) => ({ [fieldName]: values }))));
@@ -33999,9 +34021,9 @@ class MetadataContactComponent {
33999
34021
  return this.metadata.ownerOrganization;
34000
34022
  }
34001
34023
  get contacts() {
34002
- return ((this.metadata.kind === 'dataset'
34003
- ? this.metadata.contactsForResource
34004
- : this.metadata.contacts) || []);
34024
+ return ((this.metadata.kind === 'service'
34025
+ ? this.metadata.contacts
34026
+ : this.metadata.contactsForResource) || []);
34005
34027
  }
34006
34028
  get address() {
34007
34029
  const addressParts = this.contacts[0].address
@@ -34013,7 +34035,7 @@ class MetadataContactComponent {
34013
34035
  this.organizationClick.emit(this.shownOrganization);
34014
34036
  }
34015
34037
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MetadataContactComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
34016
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: MetadataContactComponent, isStandalone: true, selector: "gn-ui-metadata-contact", inputs: { metadata: "metadata" }, outputs: { organizationClick: "organizationClick", contactClick: "contactClick" }, ngImport: i0, template: "<div\n class=\"py-5 px-5 rounded bg-gray-100 text-black\"\n data-cy=\"metadata-organization\"\n>\n <div class=\"grid gap-3 overflow-hidden\">\n <div>\n <p class=\"text-base font-medium\" translate>record.metadata.contact</p>\n </div>\n @if (shownOrganization?.logoUrl?.href) {\n <div\n class=\"flex items-center justify-center border-solid border border-gray-300 rounded-md bg-white h-32 overflow-hidden\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"shownOrganization.logoUrl.href\"\n fit=\"contain\"\n ></gn-ui-thumbnail>\n </div>\n }\n <div class=\"grid grid-cols-1 gap-1\">\n <div class=\"flex\">\n <div\n class=\"font-title text-21 mr-2 cursor-pointer hover:underline\"\n (click)=\"onOrganizationClick()\"\n data-cy=\"organization-name-link\"\n >\n {{ shownOrganization?.name }}\n </div>\n </div>\n @if (shownOrganization?.website) {\n <div>\n <a\n [href]=\"shownOrganization.website\"\n target=\"_blank\"\n class=\"contact-website text-sm cursor-pointer hover:underline transition-all\"\n >{{ shownOrganization.website }}\n <ng-icon\n class=\"!w-[12px] !h-[12px] opacity-75 shrink-0\"\n name=\"matOpenInNew\"\n ></ng-icon>\n </a>\n </div>\n }\n </div>\n <div class=\"grid grid-cols-1 gap-5 py-3 overflow-hidden\">\n @if (contacts[0]?.phone) {\n <div>\n <div class=\"flex\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matCallOutline\"\n ></ng-icon>\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">{{ contacts[0].phone }}</p>\n </div>\n </div>\n </div>\n }\n @if (contacts[0]?.email) {\n <div>\n <div class=\"flex gap-2\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matMailOutline\"\n ></ng-icon>\n @if (contacts.length) {\n <a\n [href]=\"'mailto:' + contacts[0].email\"\n class=\"break-all text-sm hover:underline\"\n target=\"_blank\"\n data-cy=\"contact-email\"\n >{{ contacts[0].email }}</a\n >\n }\n </div>\n </div>\n }\n @if (contacts[0]?.firstName || contacts[0]?.lastName) {\n <div>\n <div class=\"flex\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matPersonOutline\"\n ></ng-icon>\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">\n {{ contacts[0]?.firstName || '' }}\n {{ contacts[0]?.lastName || '' }}\n </p>\n </div>\n </div>\n </div>\n }\n @if (contacts[0]?.address) {\n <div>\n <div class=\"flex\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matLocationOnOutline\"\n ></ng-icon>\n <div class=\"flex flex-col ml-2\">\n @for (addressPart of address; track addressPart) {\n <p class=\"text-sm\">\n {{ addressPart }}\n </p>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], viewProviders: [
34038
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: MetadataContactComponent, isStandalone: true, selector: "gn-ui-metadata-contact", inputs: { metadata: "metadata" }, outputs: { organizationClick: "organizationClick", contactClick: "contactClick" }, ngImport: i0, template: "<div\n class=\"py-5 px-5 rounded bg-gray-100 text-black\"\n data-cy=\"metadata-organization\"\n>\n <div class=\"grid gap-3 overflow-hidden\">\n <div>\n <p class=\"text-base font-medium\" translate>record.metadata.contact</p>\n </div>\n @if (shownOrganization?.logoUrl?.href) {\n <div\n class=\"flex items-center justify-center border-solid border border-gray-300 rounded-md bg-white h-32 overflow-hidden\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"shownOrganization.logoUrl.href\"\n fit=\"contain\"\n ></gn-ui-thumbnail>\n </div>\n }\n <div class=\"grid grid-cols-1 gap-1\">\n <div class=\"flex\">\n <div\n class=\"font-title text-21 mr-2 cursor-pointer hover:underline\"\n (click)=\"onOrganizationClick()\"\n data-cy=\"organization-name-link\"\n >\n {{ shownOrganization?.name }}\n </div>\n </div>\n @if (shownOrganization?.website) {\n <div>\n <div class=\"flex items-center mt-1\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matOpenInNew\"\n ></ng-icon>\n <a\n [href]=\"shownOrganization.website\"\n target=\"_blank\"\n class=\"contact-website text-sm cursor-pointer hover:underline transition-all ml-2\"\n >\n {{ shownOrganization.website }}\n </a>\n </div>\n </div>\n }\n </div>\n <div class=\"grid grid-cols-1 gap-5 py-3 overflow-hidden\">\n @if (contacts[0]?.phone) {\n <div>\n <div class=\"flex\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matCallOutline\"\n ></ng-icon>\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">{{ contacts[0].phone }}</p>\n </div>\n </div>\n </div>\n }\n @if (contacts[0]?.email) {\n <div>\n <div class=\"flex gap-2\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matMailOutline\"\n ></ng-icon>\n @if (contacts.length) {\n <a\n [href]=\"'mailto:' + contacts[0].email\"\n class=\"break-all text-sm hover:underline\"\n target=\"_blank\"\n data-cy=\"contact-email\"\n >{{ contacts[0].email }}</a\n >\n }\n </div>\n </div>\n }\n @if (contacts[0]?.firstName || contacts[0]?.lastName) {\n <div>\n <div class=\"flex\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matPersonOutline\"\n ></ng-icon>\n <div class=\"flex flex-col ml-2\" data-cy=\"contact-full-name\">\n <p class=\"text-sm\">\n {{ contacts[0]?.firstName || '' }}\n {{ contacts[0]?.lastName || '' }}\n </p>\n </div>\n </div>\n </div>\n }\n @if (contacts[0]?.address) {\n <div>\n <div class=\"flex\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matLocationOnOutline\"\n ></ng-icon>\n <div class=\"flex flex-col ml-2\">\n @for (addressPart of address; track addressPart) {\n <p class=\"text-sm\">\n {{ addressPart }}\n </p>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], viewProviders: [
34017
34039
  provideIcons({
34018
34040
  matOpenInNew,
34019
34041
  matCallOutline,
@@ -34033,7 +34055,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
34033
34055
  matPersonOutline,
34034
34056
  matLocationOnOutline,
34035
34057
  }),
34036
- ], template: "<div\n class=\"py-5 px-5 rounded bg-gray-100 text-black\"\n data-cy=\"metadata-organization\"\n>\n <div class=\"grid gap-3 overflow-hidden\">\n <div>\n <p class=\"text-base font-medium\" translate>record.metadata.contact</p>\n </div>\n @if (shownOrganization?.logoUrl?.href) {\n <div\n class=\"flex items-center justify-center border-solid border border-gray-300 rounded-md bg-white h-32 overflow-hidden\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"shownOrganization.logoUrl.href\"\n fit=\"contain\"\n ></gn-ui-thumbnail>\n </div>\n }\n <div class=\"grid grid-cols-1 gap-1\">\n <div class=\"flex\">\n <div\n class=\"font-title text-21 mr-2 cursor-pointer hover:underline\"\n (click)=\"onOrganizationClick()\"\n data-cy=\"organization-name-link\"\n >\n {{ shownOrganization?.name }}\n </div>\n </div>\n @if (shownOrganization?.website) {\n <div>\n <a\n [href]=\"shownOrganization.website\"\n target=\"_blank\"\n class=\"contact-website text-sm cursor-pointer hover:underline transition-all\"\n >{{ shownOrganization.website }}\n <ng-icon\n class=\"!w-[12px] !h-[12px] opacity-75 shrink-0\"\n name=\"matOpenInNew\"\n ></ng-icon>\n </a>\n </div>\n }\n </div>\n <div class=\"grid grid-cols-1 gap-5 py-3 overflow-hidden\">\n @if (contacts[0]?.phone) {\n <div>\n <div class=\"flex\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matCallOutline\"\n ></ng-icon>\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">{{ contacts[0].phone }}</p>\n </div>\n </div>\n </div>\n }\n @if (contacts[0]?.email) {\n <div>\n <div class=\"flex gap-2\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matMailOutline\"\n ></ng-icon>\n @if (contacts.length) {\n <a\n [href]=\"'mailto:' + contacts[0].email\"\n class=\"break-all text-sm hover:underline\"\n target=\"_blank\"\n data-cy=\"contact-email\"\n >{{ contacts[0].email }}</a\n >\n }\n </div>\n </div>\n }\n @if (contacts[0]?.firstName || contacts[0]?.lastName) {\n <div>\n <div class=\"flex\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matPersonOutline\"\n ></ng-icon>\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">\n {{ contacts[0]?.firstName || '' }}\n {{ contacts[0]?.lastName || '' }}\n </p>\n </div>\n </div>\n </div>\n }\n @if (contacts[0]?.address) {\n <div>\n <div class=\"flex\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matLocationOnOutline\"\n ></ng-icon>\n <div class=\"flex flex-col ml-2\">\n @for (addressPart of address; track addressPart) {\n <p class=\"text-sm\">\n {{ addressPart }}\n </p>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n" }]
34058
+ ], template: "<div\n class=\"py-5 px-5 rounded bg-gray-100 text-black\"\n data-cy=\"metadata-organization\"\n>\n <div class=\"grid gap-3 overflow-hidden\">\n <div>\n <p class=\"text-base font-medium\" translate>record.metadata.contact</p>\n </div>\n @if (shownOrganization?.logoUrl?.href) {\n <div\n class=\"flex items-center justify-center border-solid border border-gray-300 rounded-md bg-white h-32 overflow-hidden\"\n >\n <gn-ui-thumbnail\n class=\"relative h-full w-full\"\n [thumbnailUrl]=\"shownOrganization.logoUrl.href\"\n fit=\"contain\"\n ></gn-ui-thumbnail>\n </div>\n }\n <div class=\"grid grid-cols-1 gap-1\">\n <div class=\"flex\">\n <div\n class=\"font-title text-21 mr-2 cursor-pointer hover:underline\"\n (click)=\"onOrganizationClick()\"\n data-cy=\"organization-name-link\"\n >\n {{ shownOrganization?.name }}\n </div>\n </div>\n @if (shownOrganization?.website) {\n <div>\n <div class=\"flex items-center mt-1\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matOpenInNew\"\n ></ng-icon>\n <a\n [href]=\"shownOrganization.website\"\n target=\"_blank\"\n class=\"contact-website text-sm cursor-pointer hover:underline transition-all ml-2\"\n >\n {{ shownOrganization.website }}\n </a>\n </div>\n </div>\n }\n </div>\n <div class=\"grid grid-cols-1 gap-5 py-3 overflow-hidden\">\n @if (contacts[0]?.phone) {\n <div>\n <div class=\"flex\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matCallOutline\"\n ></ng-icon>\n <div class=\"flex flex-col ml-2\">\n <p class=\"text-sm\">{{ contacts[0].phone }}</p>\n </div>\n </div>\n </div>\n }\n @if (contacts[0]?.email) {\n <div>\n <div class=\"flex gap-2\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matMailOutline\"\n ></ng-icon>\n @if (contacts.length) {\n <a\n [href]=\"'mailto:' + contacts[0].email\"\n class=\"break-all text-sm hover:underline\"\n target=\"_blank\"\n data-cy=\"contact-email\"\n >{{ contacts[0].email }}</a\n >\n }\n </div>\n </div>\n }\n @if (contacts[0]?.firstName || contacts[0]?.lastName) {\n <div>\n <div class=\"flex\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matPersonOutline\"\n ></ng-icon>\n <div class=\"flex flex-col ml-2\" data-cy=\"contact-full-name\">\n <p class=\"text-sm\">\n {{ contacts[0]?.firstName || '' }}\n {{ contacts[0]?.lastName || '' }}\n </p>\n </div>\n </div>\n </div>\n }\n @if (contacts[0]?.address) {\n <div>\n <div class=\"flex\">\n <ng-icon\n class=\"!w-5 !h-5 !text-[20px] opacity-75 shrink-0\"\n name=\"matLocationOnOutline\"\n ></ng-icon>\n <div class=\"flex flex-col ml-2\">\n @for (addressPart of address; track addressPart) {\n <p class=\"text-sm\">\n {{ addressPart }}\n </p>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n" }]
34037
34059
  }], propDecorators: { metadata: [{
34038
34060
  type: Input
34039
34061
  }], organizationClick: [{
@@ -38225,6 +38247,7 @@ marker('dataset.error.forbidden');
38225
38247
  marker('wfs.unreachable.unknown');
38226
38248
  marker('wfs.featuretype.notfound');
38227
38249
  marker('wfs.geojsongml.notsupported');
38250
+ marker('ogc.geojson.notsupported');
38228
38251
  marker('ogc.unreachable.unknown');
38229
38252
  marker('dataset.error.network');
38230
38253
  marker('dataset.error.http');
@@ -38452,12 +38475,14 @@ class DataService {
38452
38475
  else if (link.type === 'service' &&
38453
38476
  link.accessServiceProtocol === 'ogcFeatures') {
38454
38477
  return from(this.getDownloadUrlsFromOgcApi(link.url.href)).pipe(switchMap$1((collectionInfo) => {
38455
- const geojsonUrl = collectionInfo.jsonDownloadLink;
38456
- return openDataset(geojsonUrl, 'geojson', undefined, cacheActive);
38457
- }), tap$1((url) => {
38458
- if (url === null) {
38459
- throw new Error('wfs.geojsongml.notsupported');
38478
+ const isMimeTypeJson = (mimeType) => {
38479
+ return mimeType.toLowerCase().indexOf('json') > -1;
38480
+ };
38481
+ const geojsonUrl = collectionInfo.bulkDownloadLinks[Object.keys(collectionInfo.bulkDownloadLinks).find((mimeType) => isMimeTypeJson(mimeType))];
38482
+ if (!geojsonUrl) {
38483
+ return throwError(() => 'ogc.geojson.notsupported');
38460
38484
  }
38485
+ return openDataset(geojsonUrl, 'geojson', undefined, cacheActive);
38461
38486
  }));
38462
38487
  }
38463
38488
  return throwError(() => 'protocol not supported');
@@ -41099,6 +41124,7 @@ const saveRecordSuccess = createAction('[Editor] Save record success');
41099
41124
  const saveRecordFailure = createAction('[Editor] Save record failure', props());
41100
41125
  const draftSaveSuccess = createAction('[Editor] Draft save success');
41101
41126
  const undoRecordDraft = createAction('[Editor] Undo record draft');
41127
+ const setEditorConfiguration = createAction('[Editor] Set editor configuration', props());
41102
41128
  const setCurrentPage = createAction('[Editor] Set current page', props());
41103
41129
  const setFieldVisibility = createAction('[Editor] Set field visibility', props());
41104
41130
  const hasRecordChangedSinceDraft = createAction('[Editor] Has Record Changed Since Draft', props());
@@ -41521,6 +41547,9 @@ const reducer = createReducer(initialEditorState, on(openRecord, (state, { recor
41521
41547
  })), on(markRecordAsChanged, (state) => ({
41522
41548
  ...state,
41523
41549
  changedSinceSave: true,
41550
+ })), on(setEditorConfiguration, (state, { configuration }) => ({
41551
+ ...state,
41552
+ editorConfig: configuration,
41524
41553
  })), on(setCurrentPage, (state, { page }) => ({
41525
41554
  ...state,
41526
41555
  currentPage: page,
@@ -41623,6 +41652,9 @@ class EditorFacade {
41623
41652
  updateRecordLanguages(defaultLanguage, otherLanguages) {
41624
41653
  this.store.dispatch(updateRecordLanguages({ defaultLanguage, otherLanguages }));
41625
41654
  }
41655
+ setConfiguration(configuration) {
41656
+ this.store.dispatch(setEditorConfiguration({ configuration }));
41657
+ }
41626
41658
  setCurrentPage(page) {
41627
41659
  this.store.dispatch(setCurrentPage({ page }));
41628
41660
  }
@@ -41645,149 +41677,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
41645
41677
  type: Injectable
41646
41678
  }] });
41647
41679
 
41648
- function evaluate(expression) {
41649
- if (expression.match(/^\${.*}$/)) {
41650
- return evaluate(expression.slice(2, -1));
41651
- }
41652
- const operator = expression.split('(')[0];
41653
- switch (operator) {
41654
- case 'dateNow':
41655
- return () => new Date();
41656
- default:
41657
- throw new Error(`Unknown operator: ${operator}`);
41658
- }
41659
- }
41660
-
41661
- class EditorService {
41662
- constructor() {
41663
- this.recordsRepository = inject(RecordsRepositoryInterface);
41664
- }
41665
- // returns the record as it was when saved, alongside its source
41666
- saveRecord(record, recordSource, fieldsConfig) {
41667
- const savedRecord = { ...record };
41668
- const fields = fieldsConfig.pages.flatMap((page) => page.sections.flatMap((section) => section.fields));
41669
- // run onSave processes
41670
- for (const field of fields) {
41671
- if (field.onSaveProcess && field.model) {
41672
- const evaluator = evaluate(field.onSaveProcess);
41673
- savedRecord[field.model] = evaluator({
41674
- model: field.model,
41675
- value: record[field.model],
41676
- });
41677
- }
41678
- }
41679
- let publishToAll = true;
41680
- // if the record is new, generate a new unique identifier and pass publishToAll as false
41681
- if (!record.uniqueIdentifier) {
41682
- savedRecord.uniqueIdentifier = null;
41683
- publishToAll = false;
41684
- }
41685
- return this.recordsRepository
41686
- .saveRecord(savedRecord, recordSource, publishToAll)
41687
- .pipe(switchMap((uniqueIdentifier) => this.recordsRepository.openRecordForEdition(uniqueIdentifier)), tap$1(() => {
41688
- // if saving was successful, the original draft can be discarded
41689
- this.recordsRepository.clearRecordDraft(record.uniqueIdentifier);
41690
- }), map$1(([record, recordSource]) => [record, recordSource]));
41691
- }
41692
- // emits and completes once saving is done
41693
- // note: onSave processes are not run for drafts
41694
- saveRecordAsDraft(record, recordSource) {
41695
- record.recordUpdated = new Date();
41696
- return this.recordsRepository
41697
- .saveRecordAsDraft(record, recordSource)
41698
- .pipe(map$1(() => undefined));
41699
- }
41700
- undoRecordDraft(record) {
41701
- this.recordsRepository.clearRecordDraft(record.uniqueIdentifier);
41702
- return this.recordsRepository.openRecordForEdition(record.uniqueIdentifier);
41703
- }
41704
- hasRecordChangedSinceDraft(localRecord) {
41705
- return this.recordsRepository.hasRecordChangedSinceDraft(localRecord);
41706
- }
41707
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
41708
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorService, providedIn: 'root' }); }
41709
- }
41710
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorService, decorators: [{
41711
- type: Injectable,
41712
- args: [{
41713
- providedIn: 'root',
41714
- }]
41715
- }] });
41716
-
41717
- class EditorEffects {
41718
- constructor() {
41719
- this.actions$ = inject(Actions);
41720
- this.editorService = inject(EditorService);
41721
- this.recordsRepository = inject(RecordsRepositoryInterface);
41722
- this.plateformService = inject(PlatformServiceInterface);
41723
- this.store = inject(Store);
41724
- this.saveRecord$ = createEffect(() => this.actions$.pipe(ofType(saveRecord), withLatestFrom$1(this.store.select(selectRecord), this.store.select(selectRecordSource), this.store.select(selectEditorConfig)), switchMap$1(([, record, recordSource, fieldsConfig]) => this.editorService.saveRecord(record, recordSource, fieldsConfig).pipe(switchMap$1(([savedRecord, savedRecordSource]) => {
41725
- const actions = [saveRecordSuccess()];
41726
- if (!record?.uniqueIdentifier) {
41727
- actions.push(openRecord({
41728
- record: savedRecord,
41729
- recordSource: savedRecordSource,
41730
- }));
41731
- }
41732
- return of(...actions);
41733
- }), catchError((error) => of(saveRecordFailure({
41734
- error,
41735
- })))))));
41736
- this.cleanRecordAttachments$ = createEffect(() => this.actions$.pipe(ofType(saveRecordSuccess), withLatestFrom$1(this.store.select(selectRecord)), switchMap$1(([_, record]) => {
41737
- if (record.uniqueIdentifier !== null) {
41738
- this.plateformService.cleanRecordAttachments(record).subscribe({
41739
- next: (_) => undefined,
41740
- error: (err) => {
41741
- console.error(err);
41742
- },
41743
- });
41744
- }
41745
- return EMPTY;
41746
- }), catchError((error) => {
41747
- console.error(error);
41748
- return EMPTY;
41749
- })), { dispatch: false });
41750
- this.markAsChanged$ = createEffect(() => this.actions$.pipe(ofType(updateRecordField, updateRecordLanguages), map$1(() => markRecordAsChanged())));
41751
- this.saveRecordDraft$ = createEffect(() => this.actions$.pipe(ofType(updateRecordField, updateRecordLanguages), debounceTime$1(1000), withLatestFrom$1(this.store.select(selectRecord), this.store.select(selectRecordSource)), switchMap$1(([, record, recordSource]) => this.editorService.saveRecordAsDraft(record, recordSource)), map$1(() => draftSaveSuccess())));
41752
- this.undoRecordDraft$ = createEffect(() => this.actions$.pipe(ofType(undoRecordDraft), withLatestFrom$1(this.store.select(selectRecord)), switchMap$1(([, record]) => this.editorService.undoRecordDraft(record)), map$1(([record, recordSource]) => openRecord({
41753
- record,
41754
- recordSource,
41755
- }))));
41756
- this.checkHasChangesOnOpen$ = createEffect(() => this.actions$.pipe(ofType(openRecord), map$1(({ record }) => this.recordsRepository.recordHasDraft(record.uniqueIdentifier)), filter((hasDraft) => hasDraft), map$1(() => markRecordAsChanged())));
41757
- this.hasRecordChangedSinceDraft$ = createEffect(() => this.actions$.pipe(ofType(hasRecordChangedSinceDraft), switchMap$1(({ record }) => this.editorService
41758
- .hasRecordChangedSinceDraft(record)
41759
- .pipe(map$1((changes) => hasRecordChangedSinceDraftSuccess({ changes }))))));
41760
- this.checkIsRecordPublished$ = createEffect(() => this.actions$.pipe(ofType(openRecord), map$1(({ record }) => record.uniqueIdentifier), switchMap$1((uniqueIdentifier) => this.recordsRepository.getRecordPublicationStatus(uniqueIdentifier)), map$1((isPublished$1) => isPublished({
41761
- isPublished: isPublished$1,
41762
- }))));
41763
- this.checkCanEditRecord$ = createEffect(() => this.actions$.pipe(ofType(openRecord), map$1(({ record }) => record.uniqueIdentifier), switchMap$1((uniqueIdentifier) => this.recordsRepository.canEditRecord(uniqueIdentifier)), map$1((canEditRecord$1) => canEditRecord({
41764
- canEditRecord: canEditRecord$1,
41765
- }))));
41766
- }
41767
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorEffects, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
41768
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorEffects }); }
41769
- }
41770
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorEffects, decorators: [{
41771
- type: Injectable
41772
- }] });
41773
-
41774
- class FeatureEditorModule {
41775
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
41776
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, imports: [i1.StoreFeatureModule, i2$2.EffectsFeatureModule] }); }
41777
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, providers: [EditorFacade, provideHttpClient()], imports: [StoreModule.forFeature(EDITOR_FEATURE_KEY, editorReducer),
41778
- EffectsModule.forFeature([EditorEffects])] }); }
41779
- }
41780
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, decorators: [{
41781
- type: NgModule,
41782
- args: [{
41783
- imports: [
41784
- StoreModule.forFeature(EDITOR_FEATURE_KEY, editorReducer),
41785
- EffectsModule.forFeature([EditorEffects]),
41786
- ],
41787
- providers: [EditorFacade, provideHttpClient()],
41788
- }]
41789
- }] });
41790
-
41791
41680
  class ImportRecordComponent {
41792
41681
  constructor() {
41793
41682
  this.router = inject(Router);
@@ -41883,6 +41772,328 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
41883
41772
  type: Output
41884
41773
  }] } });
41885
41774
 
41775
+ //forced translations that are not available in fields.config.ts
41776
+ marker('editor.record.form.field.keywords');
41777
+ marker('editor.record.form.field.topics');
41778
+ marker('editor.record.form.field.contacts');
41779
+ marker('editor.record.form.field.organisation');
41780
+ class MetadataQualityPanelComponent {
41781
+ constructor() {
41782
+ this.propsToValidate = getAllKeysValidator();
41783
+ this.propertiesByPage = [];
41784
+ }
41785
+ ngOnChanges() {
41786
+ if (this.editorConfig && this.record) {
41787
+ const fieldsByPage = this.editorConfig.pages.map((page) => page.sections.flatMap((section) => section.fields
41788
+ .filter((field) => this.propsToValidate.includes(field.model))
41789
+ .map((field) => field.model)));
41790
+ // FIXME: temporarily add topics and organisation to the first and third page
41791
+ // as long as they are not handled by the editor
41792
+ if (fieldsByPage.length > 0) {
41793
+ fieldsByPage[0].includes('topics') || fieldsByPage[0].push('topics');
41794
+ fieldsByPage[2].includes('organisation') ||
41795
+ fieldsByPage[2].push('organisation');
41796
+ }
41797
+ this.propertiesByPage = fieldsByPage
41798
+ .map((fields) => getQualityValidators(this.record, fields).map(({ name, validator }) => ({
41799
+ label: `editor.record.form.field.${name}`, // use same translations as in fields.config.ts
41800
+ value: validator(),
41801
+ })))
41802
+ .filter((arr) => arr.length > 0);
41803
+ }
41804
+ }
41805
+ getExtraClass(checked) {
41806
+ const baseClasses = 'flex flex-row justify-between rounded mb-1 h-[34px] w-full focus:ring-0 hover:border-none border-none hover:text-black text-black cursor-default';
41807
+ return checked
41808
+ ? `${baseClasses} bg-neutral-100 hover:bg-neutral-100`
41809
+ : `${baseClasses} bg-transparent hover:bg-transparent`;
41810
+ }
41811
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MetadataQualityPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
41812
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: MetadataQualityPanelComponent, isStandalone: true, selector: "gn-ui-metadata-quality-panel", inputs: { editorConfig: "editorConfig", record: "record" }, providers: [
41813
+ provideIcons({
41814
+ iconoirSystemShut,
41815
+ iconoirBadgeCheck,
41816
+ }),
41817
+ provideNgIconsConfig({
41818
+ size: '1.25em',
41819
+ }),
41820
+ ], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"flex flex-col h-full w-[302px] border-l border-gray-300 py-8 px-3 gap-3 overflow-auto\"\n style=\"background-color: #fafaf9\"\n>\n <div class=\"flex flex-row px-2 justify-between\">\n <span class=\"text-3xl font-title text-black/80\" translate\n >editor.record.form.metadataQuality.title</span\n >\n </div>\n @for (properties of propertiesByPage; track properties; let i = $index) {\n <div class=\"flex flex-col gap-2\">\n @for (property of properties; track property) {\n <gn-ui-button\n [extraClass]=\"getExtraClass(property.value)\"\n type=\"outline\"\n attr.data-cy=\"md-quality-btn-{{ property.label }}\"\n >\n <span>{{ property.label | translate }}</span>\n <div class=\"flex flex-row gap-2 items-center\">\n @if (property.value) {\n <ng-icon class=\"text-primary\" name=\"iconoirBadgeCheck\"></ng-icon>\n } @else {\n <ng-icon\n class=\"text-neutral-300\"\n name=\"iconoirSystemShut\"\n ></ng-icon>\n }\n </div>\n </gn-ui-button>\n }\n @if (i !== propertiesByPage.length - 1) {\n <hr class=\"border-gray-300 w-11/12 mx-auto\" />\n }\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
41821
+ }
41822
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MetadataQualityPanelComponent, decorators: [{
41823
+ type: Component,
41824
+ args: [{ selector: 'gn-ui-metadata-quality-panel', standalone: true, imports: [
41825
+ TranslateDirective,
41826
+ TranslatePipe,
41827
+ ButtonComponent,
41828
+ NgIconComponent,
41829
+ ], providers: [
41830
+ provideIcons({
41831
+ iconoirSystemShut,
41832
+ iconoirBadgeCheck,
41833
+ }),
41834
+ provideNgIconsConfig({
41835
+ size: '1.25em',
41836
+ }),
41837
+ ], template: "<div\n class=\"flex flex-col h-full w-[302px] border-l border-gray-300 py-8 px-3 gap-3 overflow-auto\"\n style=\"background-color: #fafaf9\"\n>\n <div class=\"flex flex-row px-2 justify-between\">\n <span class=\"text-3xl font-title text-black/80\" translate\n >editor.record.form.metadataQuality.title</span\n >\n </div>\n @for (properties of propertiesByPage; track properties; let i = $index) {\n <div class=\"flex flex-col gap-2\">\n @for (property of properties; track property) {\n <gn-ui-button\n [extraClass]=\"getExtraClass(property.value)\"\n type=\"outline\"\n attr.data-cy=\"md-quality-btn-{{ property.label }}\"\n >\n <span>{{ property.label | translate }}</span>\n <div class=\"flex flex-row gap-2 items-center\">\n @if (property.value) {\n <ng-icon class=\"text-primary\" name=\"iconoirBadgeCheck\"></ng-icon>\n } @else {\n <ng-icon\n class=\"text-neutral-300\"\n name=\"iconoirSystemShut\"\n ></ng-icon>\n }\n </div>\n </gn-ui-button>\n }\n @if (i !== propertiesByPage.length - 1) {\n <hr class=\"border-gray-300 w-11/12 mx-auto\" />\n }\n </div>\n }\n</div>\n" }]
41838
+ }], propDecorators: { editorConfig: [{
41839
+ type: Input
41840
+ }], record: [{
41841
+ type: Input
41842
+ }] } });
41843
+
41844
+ const extraFlagMap = {
41845
+ ar: 'arab',
41846
+ en: 'gb',
41847
+ ko: 'kr',
41848
+ cs: 'cz',
41849
+ zh: 'cn',
41850
+ ca: 'es-ct',
41851
+ rm: 'ch',
41852
+ da: 'dk',
41853
+ sv: 'se',
41854
+ cy: 'gb-wls',
41855
+ hy: 'am',
41856
+ ka: 'ge',
41857
+ uk: 'ua',
41858
+ };
41859
+ class MultilingualPanelComponent {
41860
+ constructor() {
41861
+ this.facade = inject(EditorFacade);
41862
+ this.dialog = inject(MatDialog);
41863
+ this.translateService = inject(TranslateService);
41864
+ this.recordsRepository = inject(RecordsRepositoryInterface);
41865
+ this.overlay = inject(Overlay);
41866
+ this.viewContainerRef = inject(ViewContainerRef);
41867
+ this.cdr = inject(ChangeDetectorRef);
41868
+ this.selectedLanguages = [];
41869
+ this.recordLanguages = [];
41870
+ this.formLanguage = '';
41871
+ this.isActionMenuOpen = false;
41872
+ this.subscription = new Subscription();
41873
+ this.supportedLanguages$ = this.recordsRepository
41874
+ .getApplicationLanguages()
41875
+ .pipe(map$2((languages) => this.sortLanguages(languages)));
41876
+ }
41877
+ set record(value) {
41878
+ this._record = value;
41879
+ this.isMultilingual = value.otherLanguages.length > 0;
41880
+ this.editTranslations = false;
41881
+ this.recordLanguages = [...value.otherLanguages, value.defaultLanguage];
41882
+ this.selectedLanguages = this.recordLanguages;
41883
+ this.formLanguage = value.defaultLanguage;
41884
+ }
41885
+ ngOnDestroy() {
41886
+ this.subscription.unsubscribe();
41887
+ }
41888
+ sortLanguages(languages) {
41889
+ return languages
41890
+ .map((lang) => {
41891
+ const label = this.translateService.instant('language.' + lang);
41892
+ const isTranslated = label !== 'language.' + lang;
41893
+ return {
41894
+ lang,
41895
+ label,
41896
+ isTranslated,
41897
+ };
41898
+ })
41899
+ .sort((a, b) => {
41900
+ if (a.isTranslated && !b.isTranslated)
41901
+ return -1;
41902
+ if (!a.isTranslated && b.isTranslated)
41903
+ return 1;
41904
+ return a.label.localeCompare(b.label);
41905
+ })
41906
+ .map((item) => item.lang);
41907
+ }
41908
+ toggleLanguageSelection() {
41909
+ this.editTranslations = !this.editTranslations;
41910
+ }
41911
+ getIconClass(lang) {
41912
+ return extraFlagMap[lang]
41913
+ ? `fi fi-${extraFlagMap[lang]} w-4 h-3`
41914
+ : `fi fi-${lang} w-4 h-3`;
41915
+ }
41916
+ switchMultilingual() {
41917
+ if (this.isMultilingual && this.selectedLanguages.length > 1) {
41918
+ this.confirmDeleteAction();
41919
+ }
41920
+ else {
41921
+ this.isMultilingual = true;
41922
+ this.editTranslations = true;
41923
+ }
41924
+ }
41925
+ getExtraClass(lang) {
41926
+ const baseClass = 'h-[34px] w-full font-bold justify-start hover:bg-white';
41927
+ if (this.selectedLanguages.includes(lang)) {
41928
+ return `${baseClass} bg-white border border-black`;
41929
+ }
41930
+ return baseClass;
41931
+ }
41932
+ toggleLanguage(lang) {
41933
+ if (this.selectedLanguages.includes(lang)) {
41934
+ this.removeSelectedLanguage(lang);
41935
+ }
41936
+ else {
41937
+ this.selectedLanguages.push(lang);
41938
+ }
41939
+ }
41940
+ removeSelectedLanguage(lang) {
41941
+ this.selectedLanguages = this.selectedLanguages.filter((language) => language !== lang);
41942
+ }
41943
+ validateTranslations() {
41944
+ const equalLength = this.selectedLanguages.length === this.recordLanguages.length;
41945
+ if (this.selectedLanguages.length < this.recordLanguages.length ||
41946
+ (equalLength && this.selectedLanguages !== this.recordLanguages)) {
41947
+ this.confirmDeleteAction(this.selectedLanguages);
41948
+ }
41949
+ else {
41950
+ this.updateTranslations();
41951
+ }
41952
+ }
41953
+ updateTranslations() {
41954
+ const newLanguageSelection = this.selectedLanguages.filter((lang) => lang !== this.formLanguage);
41955
+ this.facade.updateRecordLanguages(this.formLanguage, newLanguageSelection);
41956
+ this.recordLanguages = newLanguageSelection;
41957
+ this.editTranslations = false;
41958
+ }
41959
+ switchFormLang(lang) {
41960
+ // TO IMPLEMENT FURTHER
41961
+ }
41962
+ switchDefaultLang(lang) {
41963
+ this.formLanguage = lang;
41964
+ this.facade.updateRecordLanguages(lang, this.selectedLanguages.filter((lang) => lang !== this.formLanguage));
41965
+ this.closeActionMenu();
41966
+ }
41967
+ confirmDeleteAction(lang) {
41968
+ const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
41969
+ data: {
41970
+ title: this.translateService.instant('editor.record.multilingual.confirmation.title'),
41971
+ message: this.translateService.instant('editor.record.multilingual.confirmation.message'),
41972
+ confirmText: this.translateService.instant('editor.record.multilingual.confirmation.confirmText'),
41973
+ cancelText: this.translateService.instant('editor.record.multilingual.confirmation.cancelText'),
41974
+ focusCancel: true,
41975
+ },
41976
+ restoreFocus: true,
41977
+ });
41978
+ this.subscription.add(dialogRef.afterClosed().subscribe((confirmed) => {
41979
+ if (confirmed) {
41980
+ if (lang) {
41981
+ if (!Array.isArray(lang)) {
41982
+ this.removeSelectedLanguage(lang);
41983
+ this.closeActionMenu();
41984
+ }
41985
+ this.updateTranslations();
41986
+ }
41987
+ else {
41988
+ this.facade.updateRecordLanguages(this.formLanguage, []);
41989
+ this.isMultilingual = false;
41990
+ this.selectedLanguages = [];
41991
+ }
41992
+ }
41993
+ else {
41994
+ this.isMultilingual = true;
41995
+ this.selectedLanguages = this.recordLanguages;
41996
+ }
41997
+ this.editTranslations = false;
41998
+ }));
41999
+ }
42000
+ isFirstUnsupported(index) {
42001
+ const langs = this.sortLanguages(this.recordLanguages);
42002
+ return (langs[index].length === 3 &&
42003
+ langs.slice(0, index).every((lang) => lang.length !== 3));
42004
+ }
42005
+ isLangSupported(lang) {
42006
+ return lang.length === 2;
42007
+ }
42008
+ getToggleTitle(lang) {
42009
+ if (lang === this._record.defaultLanguage) {
42010
+ return this.translateService.instant('editor.record.form.multilingual.forbidden');
42011
+ }
42012
+ return '';
42013
+ }
42014
+ openActionMenu(item, template) {
42015
+ this.isActionMenuOpen = true;
42016
+ const index = this.sortLanguages(this.selectedLanguages).indexOf(item);
42017
+ const buttonElement = this.actionMenuButtons.toArray()[index];
42018
+ const positionStrategy = this.overlay
42019
+ .position()
42020
+ .flexibleConnectedTo(buttonElement)
42021
+ .withFlexibleDimensions(true)
42022
+ .withPush(true)
42023
+ .withPositions([
42024
+ {
42025
+ originX: 'end',
42026
+ originY: 'bottom',
42027
+ overlayX: 'end',
42028
+ overlayY: 'top',
42029
+ },
42030
+ {
42031
+ originX: 'end',
42032
+ originY: 'top',
42033
+ overlayX: 'end',
42034
+ overlayY: 'bottom',
42035
+ },
42036
+ ]);
42037
+ this.overlayRef = this.overlay.create({
42038
+ hasBackdrop: true,
42039
+ backdropClass: 'cdk-overlay-transparent-backdrop',
42040
+ positionStrategy: positionStrategy,
42041
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
42042
+ });
42043
+ const portal = new TemplatePortal(template, this.viewContainerRef);
42044
+ this.overlayRef.attach(portal);
42045
+ this.subscription.add(this.overlayRef.backdropClick().subscribe(() => {
42046
+ this.closeActionMenu();
42047
+ }));
42048
+ }
42049
+ closeActionMenu() {
42050
+ if (this.overlayRef) {
42051
+ this.isActionMenuOpen = false;
42052
+ this.overlayRef.dispose();
42053
+ this.cdr.markForCheck();
42054
+ }
42055
+ }
42056
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MultilingualPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
42057
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: MultilingualPanelComponent, isStandalone: true, selector: "gn-ui-multilingual-panel", inputs: { record: "record" }, providers: [
42058
+ provideIcons({
42059
+ iconoirSettings,
42060
+ matMoreHorizOutline,
42061
+ iconoirCheckCircle,
42062
+ iconoirCircle,
42063
+ }),
42064
+ provideNgIconsConfig({
42065
+ size: '1.25em',
42066
+ }),
42067
+ ], viewQueries: [{ propertyName: "actionMenuButtons", predicate: ["actionMenuButton"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div\n class=\"flex flex-col h-full w-[302px] border-l border-gray-300 py-8 px-3 gap-6 overflow-auto\"\n style=\"background-color: #fafaf9\"\n>\n <div class=\"flex flex-row px-2 justify-between\">\n <span class=\"text-3xl font-title text-black/80\" translate\n >editor.record.form.multilingual.title</span\n >\n @if (isMultilingual) {\n <button\n [title]=\"'editor.record.form.multilingual.open' | translate\"\n (click)=\"toggleLanguageSelection()\"\n data-test=\"activateSelection\"\n >\n <ng-icon class=\"mt-1\" name=\"iconoirSettings\"></ng-icon>\n </button>\n }\n </div>\n @if (editTranslations || !isMultilingual) {\n <div class=\"flex flex-col gap-2\">\n <gn-ui-check-toggle\n class=\"p-2\"\n [label]=\"'editor.record.form.multilingual.enable' | translate\"\n [color]=\"'primary'\"\n [(value)]=\"isMultilingual\"\n (toggled)=\"switchMultilingual($event)\"\n ></gn-ui-check-toggle>\n @if (isMultilingual) {\n <div class=\"flex flex-col gap-2\">\n <div\n class=\"flex flex-row justify-between border-t border-gray-300 p-3\"\n >\n <span class=\"mt-2 text-sm text-gray-600\" translate\n >editor.record.form.multilingual.activate</span\n >\n <gn-ui-button\n extraClass=\"w-16 h-8 font-bold\"\n type=\"gray\"\n (buttonClick)=\"validateTranslations()\"\n data-test=\"validateSelection\"\n >{{ 'editor.record.form.multilingual.validate' | translate }}\n </gn-ui-button>\n </div>\n @if (supportedLanguages$ | async; as languages) {\n @for (lang of languages; track lang) {\n <div\n class=\"flex flex-col gap-2 w-full px-2\"\n data-test=\"langAvailable\"\n [attr.data-test-lang]=\"lang\"\n >\n <gn-ui-button\n [extraClass]=\"getExtraClass(lang)\"\n type=\"gray\"\n (buttonClick)=\"toggleLanguage(lang)\"\n [disabled]=\"lang === _record.defaultLanguage\"\n [title]=\"getToggleTitle(lang)\"\n >\n <span [class]=\"getIconClass(lang)\"></span>\n <span class=\"ml-2\">{{ 'language.' + lang | translate }}</span>\n </gn-ui-button>\n </div>\n }\n }\n </div>\n }\n </div>\n }\n @if (!editTranslations && isMultilingual) {\n <div class=\"flex flex-col gap-2\">\n @for (\n recordLang of sortLanguages(recordLanguages);\n track recordLang;\n let i = $index\n ) {\n <gn-ui-button\n extraClass=\"flex flex-row justify-between bg-white border border-white rounded mb-1 h-[34px] w-full\"\n [ngClass]=\"{\n 'mt-8': isFirstUnsupported(i),\n '': true,\n }\"\n (buttonClick)=\"switchFormLang(recordLang)\"\n type=\"outline\"\n data-test=\"langSwitch\"\n >\n <div class=\"flex flex-row gap-2 items-center\">\n @if (recordLang === formLanguage) {\n <ng-icon\n class=\"text-primary mt-1\"\n name=\"iconoirCheckCircle\"\n ></ng-icon>\n }\n @if (recordLang !== formLanguage) {\n <ng-icon\n class=\"text-gray-800 mt-1\"\n name=\"iconoirCircle\"\n ></ng-icon>\n }\n @if (recordLang.length === 2) {\n <span [class]=\"getIconClass(recordLang) + 'mt-1'\"></span>\n }\n <span [ngClass]=\"recordLang === formLanguage ? 'text-black' : ''\">{{\n isLangSupported(recordLang)\n ? ('language.' + recordLang | translate)\n : recordLang.toUpperCase()\n }}</span>\n </div>\n <div class=\"flex flex-row gap-2 items-center\">\n @if (recordLang === formLanguage) {\n <span class=\"text-xs text-base\" translate\n >editor.record.form.multilingual.default</span\n >\n }\n <button\n (click)=\"\n openActionMenu(recordLang, template); $event.stopPropagation()\n \"\n cdkOverlayOrigin\n #actionMenuButton\n >\n <ng-icon class=\"pb-5\" name=\"matMoreHorizOutline\"></ng-icon>\n </button>\n <ng-template #template>\n <gn-ui-action-menu\n [canDelete]=\"recordLang !== _record.defaultLanguage\"\n page=\"record\"\n (delete)=\"confirmDeleteAction(recordLang)\"\n (closeActionMenu)=\"closeActionMenu()\"\n (switch)=\"switchDefaultLang(recordLang)\"\n >\n </gn-ui-action-menu>\n </ng-template>\n </div>\n </gn-ui-button>\n }\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: CheckToggleComponent, selector: "gn-ui-check-toggle", inputs: ["title", "label", "value", "color"], outputs: ["toggled"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: ActionMenuComponent, selector: "gn-ui-action-menu", inputs: ["canDuplicate", "isDuplicating", "canDelete", "page"], outputs: ["duplicate", "delete", "closeActionMenu", "rollback", "switch"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
42068
+ }
42069
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MultilingualPanelComponent, decorators: [{
42070
+ type: Component,
42071
+ args: [{ selector: 'gn-ui-multilingual-panel', standalone: true, imports: [
42072
+ CommonModule,
42073
+ CheckToggleComponent,
42074
+ TranslateDirective,
42075
+ TranslatePipe,
42076
+ ButtonComponent,
42077
+ NgIconComponent,
42078
+ ActionMenuComponent,
42079
+ ], providers: [
42080
+ provideIcons({
42081
+ iconoirSettings,
42082
+ matMoreHorizOutline,
42083
+ iconoirCheckCircle,
42084
+ iconoirCircle,
42085
+ }),
42086
+ provideNgIconsConfig({
42087
+ size: '1.25em',
42088
+ }),
42089
+ ], template: "<div\n class=\"flex flex-col h-full w-[302px] border-l border-gray-300 py-8 px-3 gap-6 overflow-auto\"\n style=\"background-color: #fafaf9\"\n>\n <div class=\"flex flex-row px-2 justify-between\">\n <span class=\"text-3xl font-title text-black/80\" translate\n >editor.record.form.multilingual.title</span\n >\n @if (isMultilingual) {\n <button\n [title]=\"'editor.record.form.multilingual.open' | translate\"\n (click)=\"toggleLanguageSelection()\"\n data-test=\"activateSelection\"\n >\n <ng-icon class=\"mt-1\" name=\"iconoirSettings\"></ng-icon>\n </button>\n }\n </div>\n @if (editTranslations || !isMultilingual) {\n <div class=\"flex flex-col gap-2\">\n <gn-ui-check-toggle\n class=\"p-2\"\n [label]=\"'editor.record.form.multilingual.enable' | translate\"\n [color]=\"'primary'\"\n [(value)]=\"isMultilingual\"\n (toggled)=\"switchMultilingual($event)\"\n ></gn-ui-check-toggle>\n @if (isMultilingual) {\n <div class=\"flex flex-col gap-2\">\n <div\n class=\"flex flex-row justify-between border-t border-gray-300 p-3\"\n >\n <span class=\"mt-2 text-sm text-gray-600\" translate\n >editor.record.form.multilingual.activate</span\n >\n <gn-ui-button\n extraClass=\"w-16 h-8 font-bold\"\n type=\"gray\"\n (buttonClick)=\"validateTranslations()\"\n data-test=\"validateSelection\"\n >{{ 'editor.record.form.multilingual.validate' | translate }}\n </gn-ui-button>\n </div>\n @if (supportedLanguages$ | async; as languages) {\n @for (lang of languages; track lang) {\n <div\n class=\"flex flex-col gap-2 w-full px-2\"\n data-test=\"langAvailable\"\n [attr.data-test-lang]=\"lang\"\n >\n <gn-ui-button\n [extraClass]=\"getExtraClass(lang)\"\n type=\"gray\"\n (buttonClick)=\"toggleLanguage(lang)\"\n [disabled]=\"lang === _record.defaultLanguage\"\n [title]=\"getToggleTitle(lang)\"\n >\n <span [class]=\"getIconClass(lang)\"></span>\n <span class=\"ml-2\">{{ 'language.' + lang | translate }}</span>\n </gn-ui-button>\n </div>\n }\n }\n </div>\n }\n </div>\n }\n @if (!editTranslations && isMultilingual) {\n <div class=\"flex flex-col gap-2\">\n @for (\n recordLang of sortLanguages(recordLanguages);\n track recordLang;\n let i = $index\n ) {\n <gn-ui-button\n extraClass=\"flex flex-row justify-between bg-white border border-white rounded mb-1 h-[34px] w-full\"\n [ngClass]=\"{\n 'mt-8': isFirstUnsupported(i),\n '': true,\n }\"\n (buttonClick)=\"switchFormLang(recordLang)\"\n type=\"outline\"\n data-test=\"langSwitch\"\n >\n <div class=\"flex flex-row gap-2 items-center\">\n @if (recordLang === formLanguage) {\n <ng-icon\n class=\"text-primary mt-1\"\n name=\"iconoirCheckCircle\"\n ></ng-icon>\n }\n @if (recordLang !== formLanguage) {\n <ng-icon\n class=\"text-gray-800 mt-1\"\n name=\"iconoirCircle\"\n ></ng-icon>\n }\n @if (recordLang.length === 2) {\n <span [class]=\"getIconClass(recordLang) + 'mt-1'\"></span>\n }\n <span [ngClass]=\"recordLang === formLanguage ? 'text-black' : ''\">{{\n isLangSupported(recordLang)\n ? ('language.' + recordLang | translate)\n : recordLang.toUpperCase()\n }}</span>\n </div>\n <div class=\"flex flex-row gap-2 items-center\">\n @if (recordLang === formLanguage) {\n <span class=\"text-xs text-base\" translate\n >editor.record.form.multilingual.default</span\n >\n }\n <button\n (click)=\"\n openActionMenu(recordLang, template); $event.stopPropagation()\n \"\n cdkOverlayOrigin\n #actionMenuButton\n >\n <ng-icon class=\"pb-5\" name=\"matMoreHorizOutline\"></ng-icon>\n </button>\n <ng-template #template>\n <gn-ui-action-menu\n [canDelete]=\"recordLang !== _record.defaultLanguage\"\n page=\"record\"\n (delete)=\"confirmDeleteAction(recordLang)\"\n (closeActionMenu)=\"closeActionMenu()\"\n (switch)=\"switchDefaultLang(recordLang)\"\n >\n </gn-ui-action-menu>\n </ng-template>\n </div>\n </gn-ui-button>\n }\n </div>\n }\n</div>\n" }]
42090
+ }], propDecorators: { record: [{
42091
+ type: Input
42092
+ }], actionMenuButtons: [{
42093
+ type: ViewChildren,
42094
+ args: ['actionMenuButton', { read: ElementRef }]
42095
+ }] } });
42096
+
41886
42097
  class GenericKeywordsComponent {
41887
42098
  constructor() {
41888
42099
  this.platformService = inject(PlatformServiceInterface);
@@ -43689,7 +43900,7 @@ class FormFieldComponent {
43689
43900
  }
43690
43901
  }
43691
43902
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
43692
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: FormFieldComponent, isStandalone: true, selector: "gn-ui-form-field", inputs: { uniqueIdentifier: "uniqueIdentifier", model: "model", modelSpecifier: "modelSpecifier", componentName: "componentName", config: "config", value: "value" }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "titleInput", first: true, predicate: ["titleInput"], descendants: true }], ngImport: i0, template: "<!-- TEMPORARY - disabling the open data switch -->\n<!-- <ng-container *ngIf=\"model === 'licenses'\">\n <gn-ui-form-field-open-data\n [value]=\"valueAsConstraints\"\n (valueChange)=\"valueChange.emit($event)\"\n (openDataChange)=\"toggleIsOpenData($event)\"\n ></gn-ui-form-field-open-data>\n</ng-container> -->\n<div class=\"flex flex-col h-full\">\n <ng-container *ngIf=\"withoutWrapper; else withGenericWrapper\">\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </ng-container>\n <ng-template #withGenericWrapper>\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey! | translate\"\n [hint]=\"config.hintKey! | translate\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n </ng-template>\n</div>\n\n<ng-template #fieldContent>\n <ng-container [ngSwitch]=\"model\">\n <ng-container *ngSwitchCase=\"'title'\">\n <div class=\"flex flex-row flex-start items-center gap-3 mb-[12px]\">\n <textarea\n #titleInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n data-test=\"recordTitleInput\"\n class=\"grow font-title text-3xl font-normal overflow-hidden text-black/80\"\n (change)=\"valueChange.emit($event.target.value)\"\n [placeholder]=\"\n 'editor.record.form.field.title.placeholder' | translate\n \"\n >{{ valueAsString }}</textarea\n >\n <div class=\"flex flex-row justify-between self-start mt-0.5\">\n <span\n class=\"material-symbols-outlined gn-ui-icon-small m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n >edit</span\n >\n <span\n *ngIf=\"config.hintKey\"\n class=\"material-symbols-outlined gn-ui-icon-small m-2\"\n [matTooltip]=\"config.hintKey! | translate\"\n matTooltipPosition=\"above\"\n >\n help\n </span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'abstract'\">\n <gn-ui-form-field-rich\n [label]=\"config.labelKey! | translate\"\n [hint]=\"config.hintKey! | translate\"\n [value]=\"valueAsString\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-rich>\n </ng-container>\n <ng-container *ngSwitchCase=\"'overviews'\">\n <gn-ui-form-field-overviews\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOverviews\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-overviews>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceIdentifiers'\">\n <gn-ui-form-field-simple\n [type]=\"'text'\"\n [value]=\"valueAsResourceIdentifierCode\"\n (valueChange)=\"handleResourceIdentifierChange($event)\"\n ></gn-ui-form-field-simple>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceCreated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceUpdated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'updateFrequency'\">\n <gn-ui-form-field-update-frequency\n [value]=\"valueAsUpdateFrequency\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-update-frequency>\n </ng-container>\n <ng-container *ngSwitchCase=\"'temporalExtents'\">\n <gn-ui-form-field-temporal-extents\n [value]=\"valueAsTemporalExtents\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-temporal-extents>\n </ng-container>\n <ng-container *ngSwitchCase=\"'spatialExtents'\">\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n </ng-container>\n <ng-container *ngSwitchCase=\"'keywords'\">\n <gn-ui-form-field-keywords\n [value]=\"valueAsKeywords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-keywords>\n </ng-container>\n <ng-container *ngSwitchCase=\"'topics'\">\n <gn-ui-form-field-topics\n [value]=\"valueAsTopics\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-topics>\n </ng-container>\n <ng-container *ngSwitchCase=\"'licenses'\">\n <gn-ui-form-field-license\n [label]=\"config.labelKey! | translate\"\n [recordLicences]=\"valueAsConstraints\"\n (recordLicencesChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-license>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'legalConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'securityConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'otherConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container\n ></ng-container>\n <ng-template #formFieldConstraints>\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints\n ></ng-template>\n\n <ng-container *ngSwitchCase=\"'contactsForResource'\">\n <gn-ui-form-field-contacts-for-resource\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts-for-resource>\n </ng-container>\n <ng-container *ngSwitchCase=\"'contacts'\">\n <gn-ui-form-field-contacts\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:!link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-resources>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-link-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-link-resources>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"!model\">\n <ng-container [ngSwitch]=\"componentName\">\n <ng-container *ngSwitchCase=\"'form-field-constraints-shortcuts'\">\n <gn-ui-form-field-constraints-shortcuts></gn-ui-form-field-constraints-shortcuts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'form-field-spatial-toggle'\">\n <gn-ui-form-field-spatial-toggle></gn-ui-form-field-spatial-toggle>\n </ng-container>\n </ng-container>\n </ng-container>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: FormFieldWrapperComponent, selector: "gn-ui-form-field-wrapper", inputs: ["label", "hint"] }, { kind: "component", type: FormFieldLicenseComponent, selector: "gn-ui-form-field-license", inputs: ["label", "recordLicences"], outputs: ["recordLicencesChange"] }, { kind: "component", type: FormFieldDateComponent, selector: "gn-ui-form-field-date", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldUpdateFrequencyComponent, selector: "gn-ui-form-field-update-frequency", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldTemporalExtentsComponent, selector: "gn-ui-form-field-temporal-extents", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldSimpleComponent, selector: "gn-ui-form-field-simple", inputs: ["type", "readonly", "invalid", "placeholder", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldRichComponent, selector: "gn-ui-form-field-rich", inputs: ["label", "hint", "placeholder", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldSpatialExtentComponent, selector: "gn-ui-form-field-spatial-extent" }, { kind: "component", type: FormFieldKeywordsComponent, selector: "gn-ui-form-field-keywords", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOverviewsComponent, selector: "gn-ui-form-field-overviews", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldContactsForResourceComponent, selector: "gn-ui-form-field-contacts-for-resource", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineResourcesComponent, selector: "gn-ui-form-field-online-resources", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineLinkResourcesComponent, selector: "gn-ui-form-field-online-link-resources", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldContactsComponent, selector: "gn-ui-form-field-contacts", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldConstraintsComponent, selector: "gn-ui-form-field-constraints", inputs: ["label", "value", "constraintType"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldConstraintsShortcutsComponent, selector: "gn-ui-form-field-constraints-shortcuts" }, { kind: "component", type: FormFieldSpatialToggleComponent, selector: "gn-ui-form-field-spatial-toggle" }, { kind: "component", type: FormFieldTopicsComponent, selector: "gn-ui-form-field-topics", inputs: ["value"], outputs: ["valueChange"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "directive", type: i3$2.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
43903
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: FormFieldComponent, isStandalone: true, selector: "gn-ui-form-field", inputs: { uniqueIdentifier: "uniqueIdentifier", model: "model", modelSpecifier: "modelSpecifier", componentName: "componentName", config: "config", value: "value" }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "titleInput", first: true, predicate: ["titleInput"], descendants: true }], ngImport: i0, template: "<!-- TEMPORARY - disabling the open data switch -->\n<!-- <ng-container *ngIf=\"model === 'licenses'\">\n <gn-ui-form-field-open-data\n [value]=\"valueAsConstraints\"\n (valueChange)=\"valueChange.emit($event)\"\n (openDataChange)=\"toggleIsOpenData($event)\"\n ></gn-ui-form-field-open-data>\n</ng-container> -->\n<div class=\"flex flex-col h-full\">\n <ng-container *ngIf=\"withoutWrapper; else withGenericWrapper\">\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </ng-container>\n <ng-template #withGenericWrapper>\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey! | translate\"\n [hint]=\"config.hintKey! | translate\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n </ng-template>\n</div>\n\n<ng-template #fieldContent>\n <ng-container [ngSwitch]=\"model\">\n <ng-container *ngSwitchCase=\"'title'\">\n <div class=\"flex flex-row flex-start items-center gap-3 mb-[12px]\">\n <textarea\n #titleInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n data-test=\"recordTitleInput\"\n class=\"grow font-title text-3xl font-normal overflow-hidden text-black/80\"\n [value]=\"valueAsString\"\n (change)=\"valueChange.emit($event.target.value)\"\n [placeholder]=\"\n 'editor.record.form.field.title.placeholder' | translate\n \"\n ></textarea>\n <div class=\"flex flex-row justify-between self-start mt-0.5\">\n <span\n class=\"material-symbols-outlined gn-ui-icon-small m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n >edit</span\n >\n <span\n *ngIf=\"config.hintKey\"\n class=\"material-symbols-outlined gn-ui-icon-small m-2\"\n [matTooltip]=\"config.hintKey! | translate\"\n matTooltipPosition=\"above\"\n >\n help\n </span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'abstract'\">\n <gn-ui-form-field-rich\n [label]=\"config.labelKey! | translate\"\n [hint]=\"config.hintKey! | translate\"\n [value]=\"valueAsString\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-rich>\n </ng-container>\n <ng-container *ngSwitchCase=\"'overviews'\">\n <gn-ui-form-field-overviews\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOverviews\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-overviews>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceIdentifiers'\">\n <gn-ui-form-field-simple\n [type]=\"'text'\"\n [value]=\"valueAsResourceIdentifierCode\"\n (valueChange)=\"handleResourceIdentifierChange($event)\"\n ></gn-ui-form-field-simple>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceCreated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceUpdated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'updateFrequency'\">\n <gn-ui-form-field-update-frequency\n [value]=\"valueAsUpdateFrequency\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-update-frequency>\n </ng-container>\n <ng-container *ngSwitchCase=\"'temporalExtents'\">\n <gn-ui-form-field-temporal-extents\n [value]=\"valueAsTemporalExtents\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-temporal-extents>\n </ng-container>\n <ng-container *ngSwitchCase=\"'spatialExtents'\">\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n </ng-container>\n <ng-container *ngSwitchCase=\"'keywords'\">\n <gn-ui-form-field-keywords\n [value]=\"valueAsKeywords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-keywords>\n </ng-container>\n <ng-container *ngSwitchCase=\"'topics'\">\n <gn-ui-form-field-topics\n [value]=\"valueAsTopics\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-topics>\n </ng-container>\n <ng-container *ngSwitchCase=\"'licenses'\">\n <gn-ui-form-field-license\n [label]=\"config.labelKey! | translate\"\n [recordLicences]=\"valueAsConstraints\"\n (recordLicencesChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-license>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'legalConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'securityConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'otherConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container\n ></ng-container>\n <ng-template #formFieldConstraints>\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints\n ></ng-template>\n\n <ng-container *ngSwitchCase=\"'contactsForResource'\">\n <gn-ui-form-field-contacts-for-resource\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts-for-resource>\n </ng-container>\n <ng-container *ngSwitchCase=\"'contacts'\">\n <gn-ui-form-field-contacts\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:!link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-resources>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-link-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-link-resources>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"!model\">\n <ng-container [ngSwitch]=\"componentName\">\n <ng-container *ngSwitchCase=\"'form-field-constraints-shortcuts'\">\n <gn-ui-form-field-constraints-shortcuts></gn-ui-form-field-constraints-shortcuts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'form-field-spatial-toggle'\">\n <gn-ui-form-field-spatial-toggle></gn-ui-form-field-spatial-toggle>\n </ng-container>\n </ng-container>\n </ng-container>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: FormFieldWrapperComponent, selector: "gn-ui-form-field-wrapper", inputs: ["label", "hint"] }, { kind: "component", type: FormFieldLicenseComponent, selector: "gn-ui-form-field-license", inputs: ["label", "recordLicences"], outputs: ["recordLicencesChange"] }, { kind: "component", type: FormFieldDateComponent, selector: "gn-ui-form-field-date", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldUpdateFrequencyComponent, selector: "gn-ui-form-field-update-frequency", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldTemporalExtentsComponent, selector: "gn-ui-form-field-temporal-extents", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldSimpleComponent, selector: "gn-ui-form-field-simple", inputs: ["type", "readonly", "invalid", "placeholder", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldRichComponent, selector: "gn-ui-form-field-rich", inputs: ["label", "hint", "placeholder", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldSpatialExtentComponent, selector: "gn-ui-form-field-spatial-extent" }, { kind: "component", type: FormFieldKeywordsComponent, selector: "gn-ui-form-field-keywords", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOverviewsComponent, selector: "gn-ui-form-field-overviews", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldContactsForResourceComponent, selector: "gn-ui-form-field-contacts-for-resource", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineResourcesComponent, selector: "gn-ui-form-field-online-resources", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldOnlineLinkResourcesComponent, selector: "gn-ui-form-field-online-link-resources", inputs: ["metadataUuid", "value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldContactsComponent, selector: "gn-ui-form-field-contacts", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldConstraintsComponent, selector: "gn-ui-form-field-constraints", inputs: ["label", "value", "constraintType"], outputs: ["valueChange"] }, { kind: "component", type: FormFieldConstraintsShortcutsComponent, selector: "gn-ui-form-field-constraints-shortcuts" }, { kind: "component", type: FormFieldSpatialToggleComponent, selector: "gn-ui-form-field-spatial-toggle" }, { kind: "component", type: FormFieldTopicsComponent, selector: "gn-ui-form-field-topics", inputs: ["value"], outputs: ["valueChange"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "directive", type: i3$2.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
43693
43904
  }
43694
43905
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormFieldComponent, decorators: [{
43695
43906
  type: Component,
@@ -43716,7 +43927,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
43716
43927
  FormFieldSpatialToggleComponent,
43717
43928
  FormFieldTopicsComponent,
43718
43929
  TextFieldModule,
43719
- ], template: "<!-- TEMPORARY - disabling the open data switch -->\n<!-- <ng-container *ngIf=\"model === 'licenses'\">\n <gn-ui-form-field-open-data\n [value]=\"valueAsConstraints\"\n (valueChange)=\"valueChange.emit($event)\"\n (openDataChange)=\"toggleIsOpenData($event)\"\n ></gn-ui-form-field-open-data>\n</ng-container> -->\n<div class=\"flex flex-col h-full\">\n <ng-container *ngIf=\"withoutWrapper; else withGenericWrapper\">\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </ng-container>\n <ng-template #withGenericWrapper>\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey! | translate\"\n [hint]=\"config.hintKey! | translate\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n </ng-template>\n</div>\n\n<ng-template #fieldContent>\n <ng-container [ngSwitch]=\"model\">\n <ng-container *ngSwitchCase=\"'title'\">\n <div class=\"flex flex-row flex-start items-center gap-3 mb-[12px]\">\n <textarea\n #titleInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n data-test=\"recordTitleInput\"\n class=\"grow font-title text-3xl font-normal overflow-hidden text-black/80\"\n (change)=\"valueChange.emit($event.target.value)\"\n [placeholder]=\"\n 'editor.record.form.field.title.placeholder' | translate\n \"\n >{{ valueAsString }}</textarea\n >\n <div class=\"flex flex-row justify-between self-start mt-0.5\">\n <span\n class=\"material-symbols-outlined gn-ui-icon-small m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n >edit</span\n >\n <span\n *ngIf=\"config.hintKey\"\n class=\"material-symbols-outlined gn-ui-icon-small m-2\"\n [matTooltip]=\"config.hintKey! | translate\"\n matTooltipPosition=\"above\"\n >\n help\n </span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'abstract'\">\n <gn-ui-form-field-rich\n [label]=\"config.labelKey! | translate\"\n [hint]=\"config.hintKey! | translate\"\n [value]=\"valueAsString\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-rich>\n </ng-container>\n <ng-container *ngSwitchCase=\"'overviews'\">\n <gn-ui-form-field-overviews\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOverviews\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-overviews>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceIdentifiers'\">\n <gn-ui-form-field-simple\n [type]=\"'text'\"\n [value]=\"valueAsResourceIdentifierCode\"\n (valueChange)=\"handleResourceIdentifierChange($event)\"\n ></gn-ui-form-field-simple>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceCreated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceUpdated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'updateFrequency'\">\n <gn-ui-form-field-update-frequency\n [value]=\"valueAsUpdateFrequency\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-update-frequency>\n </ng-container>\n <ng-container *ngSwitchCase=\"'temporalExtents'\">\n <gn-ui-form-field-temporal-extents\n [value]=\"valueAsTemporalExtents\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-temporal-extents>\n </ng-container>\n <ng-container *ngSwitchCase=\"'spatialExtents'\">\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n </ng-container>\n <ng-container *ngSwitchCase=\"'keywords'\">\n <gn-ui-form-field-keywords\n [value]=\"valueAsKeywords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-keywords>\n </ng-container>\n <ng-container *ngSwitchCase=\"'topics'\">\n <gn-ui-form-field-topics\n [value]=\"valueAsTopics\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-topics>\n </ng-container>\n <ng-container *ngSwitchCase=\"'licenses'\">\n <gn-ui-form-field-license\n [label]=\"config.labelKey! | translate\"\n [recordLicences]=\"valueAsConstraints\"\n (recordLicencesChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-license>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'legalConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'securityConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'otherConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container\n ></ng-container>\n <ng-template #formFieldConstraints>\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints\n ></ng-template>\n\n <ng-container *ngSwitchCase=\"'contactsForResource'\">\n <gn-ui-form-field-contacts-for-resource\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts-for-resource>\n </ng-container>\n <ng-container *ngSwitchCase=\"'contacts'\">\n <gn-ui-form-field-contacts\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:!link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-resources>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-link-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-link-resources>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"!model\">\n <ng-container [ngSwitch]=\"componentName\">\n <ng-container *ngSwitchCase=\"'form-field-constraints-shortcuts'\">\n <gn-ui-form-field-constraints-shortcuts></gn-ui-form-field-constraints-shortcuts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'form-field-spatial-toggle'\">\n <gn-ui-form-field-spatial-toggle></gn-ui-form-field-spatial-toggle>\n </ng-container>\n </ng-container>\n </ng-container>\n</ng-template>\n" }]
43930
+ ], template: "<!-- TEMPORARY - disabling the open data switch -->\n<!-- <ng-container *ngIf=\"model === 'licenses'\">\n <gn-ui-form-field-open-data\n [value]=\"valueAsConstraints\"\n (valueChange)=\"valueChange.emit($event)\"\n (openDataChange)=\"toggleIsOpenData($event)\"\n ></gn-ui-form-field-open-data>\n</ng-container> -->\n<div class=\"flex flex-col h-full\">\n <ng-container *ngIf=\"withoutWrapper; else withGenericWrapper\">\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </ng-container>\n <ng-template #withGenericWrapper>\n <gn-ui-form-field-wrapper\n [label]=\"config.labelKey! | translate\"\n [hint]=\"config.hintKey! | translate\"\n >\n <ng-container *ngTemplateOutlet=\"fieldContent\"></ng-container>\n </gn-ui-form-field-wrapper>\n </ng-template>\n</div>\n\n<ng-template #fieldContent>\n <ng-container [ngSwitch]=\"model\">\n <ng-container *ngSwitchCase=\"'title'\">\n <div class=\"flex flex-row flex-start items-center gap-3 mb-[12px]\">\n <textarea\n #titleInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"1\"\n data-test=\"recordTitleInput\"\n class=\"grow font-title text-3xl font-normal overflow-hidden text-black/80\"\n [value]=\"valueAsString\"\n (change)=\"valueChange.emit($event.target.value)\"\n [placeholder]=\"\n 'editor.record.form.field.title.placeholder' | translate\n \"\n ></textarea>\n <div class=\"flex flex-row justify-between self-start mt-0.5\">\n <span\n class=\"material-symbols-outlined gn-ui-icon-small m-2 cursor-pointer\"\n (click)=\"focusTitleInput()\"\n >edit</span\n >\n <span\n *ngIf=\"config.hintKey\"\n class=\"material-symbols-outlined gn-ui-icon-small m-2\"\n [matTooltip]=\"config.hintKey! | translate\"\n matTooltipPosition=\"above\"\n >\n help\n </span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'abstract'\">\n <gn-ui-form-field-rich\n [label]=\"config.labelKey! | translate\"\n [hint]=\"config.hintKey! | translate\"\n [value]=\"valueAsString\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-rich>\n </ng-container>\n <ng-container *ngSwitchCase=\"'overviews'\">\n <gn-ui-form-field-overviews\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOverviews\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-overviews>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceIdentifiers'\">\n <gn-ui-form-field-simple\n [type]=\"'text'\"\n [value]=\"valueAsResourceIdentifierCode\"\n (valueChange)=\"handleResourceIdentifierChange($event)\"\n ></gn-ui-form-field-simple>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceCreated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'resourceUpdated'\">\n <gn-ui-form-field-date\n [value]=\"valueAsDate\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-date>\n </ng-container>\n <ng-container *ngSwitchCase=\"'updateFrequency'\">\n <gn-ui-form-field-update-frequency\n [value]=\"valueAsUpdateFrequency\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-update-frequency>\n </ng-container>\n <ng-container *ngSwitchCase=\"'temporalExtents'\">\n <gn-ui-form-field-temporal-extents\n [value]=\"valueAsTemporalExtents\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-temporal-extents>\n </ng-container>\n <ng-container *ngSwitchCase=\"'spatialExtents'\">\n <gn-ui-form-field-spatial-extent></gn-ui-form-field-spatial-extent>\n </ng-container>\n <ng-container *ngSwitchCase=\"'keywords'\">\n <gn-ui-form-field-keywords\n [value]=\"valueAsKeywords\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-keywords>\n </ng-container>\n <ng-container *ngSwitchCase=\"'topics'\">\n <gn-ui-form-field-topics\n [value]=\"valueAsTopics\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-topics>\n </ng-container>\n <ng-container *ngSwitchCase=\"'licenses'\">\n <gn-ui-form-field-license\n [label]=\"config.labelKey! | translate\"\n [recordLicences]=\"valueAsConstraints\"\n (recordLicencesChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-license>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'legalConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'securityConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'otherConstraints'\">\n <ng-container *ngTemplateOutlet=\"formFieldConstraints\"></ng-container\n ></ng-container>\n <ng-template #formFieldConstraints>\n <gn-ui-form-field-constraints\n [label]=\"config.labelKey\"\n [value]=\"valueAsConstraints\"\n [constraintType]=\"model\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-constraints\n ></ng-template>\n\n <ng-container *ngSwitchCase=\"'contactsForResource'\">\n <gn-ui-form-field-contacts-for-resource\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts-for-resource>\n </ng-container>\n <ng-container *ngSwitchCase=\"'contacts'\">\n <gn-ui-form-field-contacts\n [value]=\"valueAsIndividuals\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-contacts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:!link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-resources>\n </ng-container>\n <ng-container *ngSwitchCase=\"'onlineResources'\">\n <gn-ui-form-field-online-link-resources\n *ngIf=\"modelSpecifier === 'onlineResourceType:link'\"\n [metadataUuid]=\"uniqueIdentifier\"\n [value]=\"valueAsOnlineResources\"\n (valueChange)=\"valueChange.emit($event)\"\n ></gn-ui-form-field-online-link-resources>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"!model\">\n <ng-container [ngSwitch]=\"componentName\">\n <ng-container *ngSwitchCase=\"'form-field-constraints-shortcuts'\">\n <gn-ui-form-field-constraints-shortcuts></gn-ui-form-field-constraints-shortcuts>\n </ng-container>\n <ng-container *ngSwitchCase=\"'form-field-spatial-toggle'\">\n <gn-ui-form-field-spatial-toggle></gn-ui-form-field-spatial-toggle>\n </ng-container>\n </ng-container>\n </ng-container>\n</ng-template>\n" }]
43720
43931
  }], propDecorators: { uniqueIdentifier: [{
43721
43932
  type: Input
43722
43933
  }], model: [{
@@ -43761,327 +43972,148 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
43761
43972
  args: [{ selector: 'gn-ui-record-form', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormFieldComponent, TranslateDirective], template: "<div class=\"flex flex-col gap-6\">\n @for (\n section of facade.currentSections$ | async;\n track sectionTracker($index, section)\n ) {\n @if (!section.hidden) {\n <div class=\"flex flex-col gap-6 border p-8 rounded-[8px] shadow\">\n <div class=\"flex flex-col gap-2\">\n @if (section.labelKey) {\n <div class=\"text-2xl font-title text-black\" translate>\n {{ section.labelKey }}\n </div>\n }\n @if (section.descriptionKey) {\n <div class=\"text-gray-800 text-sm\" translate>\n {{ section.descriptionKey }}\n </div>\n }\n </div>\n <div class=\"grid auto-rows-auto grid-cols-2 gap-[32px]\">\n @for (\n field of section.fieldsWithValues;\n track fieldTracker($index, field)\n ) {\n @if (!field.config.hidden) {\n <gn-ui-form-field\n [ngClass]=\"\n field.config.gridColumnSpan === 1\n ? 'col-span-1'\n : 'col-span-2'\n \"\n [uniqueIdentifier]=\"recordUniqueIdentifier$ | async\"\n [model]=\"field.config.model!\"\n [modelSpecifier]=\"field.config.modelSpecifier!\"\n [config]=\"field.config.formFieldConfig\"\n [value]=\"field.value\"\n [componentName]=\"field.config.componentName\"\n (valueChange)=\"\n handleFieldValueChange(field.config.model!, $event)\n \"\n ></gn-ui-form-field>\n }\n }\n </div>\n </div>\n }\n }\n</div>\n" }]
43762
43973
  }] });
43763
43974
 
43764
- const extraFlagMap = {
43765
- ar: 'arab',
43766
- en: 'gb',
43767
- ko: 'kr',
43768
- cs: 'cz',
43769
- zh: 'cn',
43770
- ca: 'es-ct',
43771
- rm: 'ch',
43772
- da: 'dk',
43773
- sv: 'se',
43774
- cy: 'gb-wls',
43775
- hy: 'am',
43776
- ka: 'ge',
43777
- uk: 'ua',
43778
- };
43779
- class MultilingualPanelComponent {
43780
- constructor() {
43781
- this.facade = inject(EditorFacade);
43782
- this.dialog = inject(MatDialog);
43783
- this.translateService = inject(TranslateService);
43784
- this.recordsRepository = inject(RecordsRepositoryInterface);
43785
- this.overlay = inject(Overlay);
43786
- this.viewContainerRef = inject(ViewContainerRef);
43787
- this.cdr = inject(ChangeDetectorRef);
43788
- this.selectedLanguages = [];
43789
- this.recordLanguages = [];
43790
- this.formLanguage = '';
43791
- this.isActionMenuOpen = false;
43792
- this.subscription = new Subscription();
43793
- this.supportedLanguages$ = this.recordsRepository
43794
- .getApplicationLanguages()
43795
- .pipe(map$2((languages) => this.sortLanguages(languages)));
43796
- }
43797
- set record(value) {
43798
- this._record = value;
43799
- this.isMultilingual = value.otherLanguages.length > 0;
43800
- this.editTranslations = false;
43801
- this.recordLanguages = [...value.otherLanguages, value.defaultLanguage];
43802
- this.selectedLanguages = this.recordLanguages;
43803
- this.formLanguage = value.defaultLanguage;
43804
- }
43805
- ngOnDestroy() {
43806
- this.subscription.unsubscribe();
43807
- }
43808
- sortLanguages(languages) {
43809
- return languages
43810
- .map((lang) => {
43811
- const label = this.translateService.instant('language.' + lang);
43812
- const isTranslated = label !== 'language.' + lang;
43813
- return {
43814
- lang,
43815
- label,
43816
- isTranslated,
43817
- };
43818
- })
43819
- .sort((a, b) => {
43820
- if (a.isTranslated && !b.isTranslated)
43821
- return -1;
43822
- if (!a.isTranslated && b.isTranslated)
43823
- return 1;
43824
- return a.label.localeCompare(b.label);
43825
- })
43826
- .map((item) => item.lang);
43827
- }
43828
- toggleLanguageSelection() {
43829
- this.editTranslations = !this.editTranslations;
43830
- }
43831
- getIconClass(lang) {
43832
- return extraFlagMap[lang]
43833
- ? `fi fi-${extraFlagMap[lang]} w-4 h-3`
43834
- : `fi fi-${lang} w-4 h-3`;
43835
- }
43836
- switchMultilingual() {
43837
- if (this.isMultilingual && this.selectedLanguages.length > 1) {
43838
- this.confirmDeleteAction();
43839
- }
43840
- else {
43841
- this.isMultilingual = true;
43842
- this.editTranslations = true;
43843
- }
43844
- }
43845
- getExtraClass(lang) {
43846
- const baseClass = 'h-[34px] w-full font-bold justify-start hover:bg-white';
43847
- if (this.selectedLanguages.includes(lang)) {
43848
- return `${baseClass} bg-white border border-black`;
43849
- }
43850
- return baseClass;
43975
+ function evaluate(expression) {
43976
+ if (expression.match(/^\${.*}$/)) {
43977
+ return evaluate(expression.slice(2, -1));
43851
43978
  }
43852
- toggleLanguage(lang) {
43853
- if (this.selectedLanguages.includes(lang)) {
43854
- this.removeSelectedLanguage(lang);
43855
- }
43856
- else {
43857
- this.selectedLanguages.push(lang);
43858
- }
43979
+ const operator = expression.split('(')[0];
43980
+ switch (operator) {
43981
+ case 'dateNow':
43982
+ return () => new Date();
43983
+ default:
43984
+ throw new Error(`Unknown operator: ${operator}`);
43859
43985
  }
43860
- removeSelectedLanguage(lang) {
43861
- this.selectedLanguages = this.selectedLanguages.filter((language) => language !== lang);
43986
+ }
43987
+
43988
+ class EditorService {
43989
+ constructor() {
43990
+ this.recordsRepository = inject(RecordsRepositoryInterface);
43862
43991
  }
43863
- validateTranslations() {
43864
- const equalLength = this.selectedLanguages.length === this.recordLanguages.length;
43865
- if (this.selectedLanguages.length < this.recordLanguages.length ||
43866
- (equalLength && this.selectedLanguages !== this.recordLanguages)) {
43867
- this.confirmDeleteAction(this.selectedLanguages);
43992
+ // returns the record as it was when saved, alongside its source
43993
+ saveRecord(record, recordSource, fieldsConfig) {
43994
+ const savedRecord = { ...record };
43995
+ const fields = fieldsConfig.pages.flatMap((page) => page.sections.flatMap((section) => section.fields));
43996
+ // run onSave processes
43997
+ for (const field of fields) {
43998
+ if (field.onSaveProcess && field.model) {
43999
+ const evaluator = evaluate(field.onSaveProcess);
44000
+ savedRecord[field.model] = evaluator({
44001
+ model: field.model,
44002
+ value: record[field.model],
44003
+ });
44004
+ }
43868
44005
  }
43869
- else {
43870
- this.updateTranslations();
44006
+ let publishToAll = true;
44007
+ // if the record is new, generate a new unique identifier and pass publishToAll as false
44008
+ if (!record.uniqueIdentifier) {
44009
+ savedRecord.uniqueIdentifier = null;
44010
+ publishToAll = false;
43871
44011
  }
44012
+ return this.recordsRepository
44013
+ .saveRecord(savedRecord, recordSource, publishToAll)
44014
+ .pipe(switchMap((uniqueIdentifier) => this.recordsRepository.openRecordForEdition(uniqueIdentifier)), tap$1(() => {
44015
+ // if saving was successful, the original draft can be discarded
44016
+ this.recordsRepository.clearRecordDraft(record.uniqueIdentifier);
44017
+ }), map$1(([record, recordSource]) => [record, recordSource]));
43872
44018
  }
43873
- updateTranslations() {
43874
- const newLanguageSelection = this.selectedLanguages.filter((lang) => lang !== this.formLanguage);
43875
- this.facade.updateRecordLanguages(this.formLanguage, newLanguageSelection);
43876
- this.recordLanguages = newLanguageSelection;
43877
- this.editTranslations = false;
43878
- }
43879
- switchFormLang(lang) {
43880
- // TO IMPLEMENT FURTHER
43881
- }
43882
- switchDefaultLang(lang) {
43883
- this.formLanguage = lang;
43884
- this.facade.updateRecordLanguages(lang, this.selectedLanguages.filter((lang) => lang !== this.formLanguage));
43885
- this.closeActionMenu();
43886
- }
43887
- confirmDeleteAction(lang) {
43888
- const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
43889
- data: {
43890
- title: this.translateService.instant('editor.record.multilingual.confirmation.title'),
43891
- message: this.translateService.instant('editor.record.multilingual.confirmation.message'),
43892
- confirmText: this.translateService.instant('editor.record.multilingual.confirmation.confirmText'),
43893
- cancelText: this.translateService.instant('editor.record.multilingual.confirmation.cancelText'),
43894
- focusCancel: true,
43895
- },
43896
- restoreFocus: true,
43897
- });
43898
- this.subscription.add(dialogRef.afterClosed().subscribe((confirmed) => {
43899
- if (confirmed) {
43900
- if (lang) {
43901
- if (!Array.isArray(lang)) {
43902
- this.removeSelectedLanguage(lang);
43903
- this.closeActionMenu();
43904
- }
43905
- this.updateTranslations();
43906
- }
43907
- else {
43908
- this.facade.updateRecordLanguages(this.formLanguage, []);
43909
- this.isMultilingual = false;
43910
- this.selectedLanguages = [];
43911
- }
43912
- }
43913
- else {
43914
- this.isMultilingual = true;
43915
- this.selectedLanguages = this.recordLanguages;
43916
- }
43917
- this.editTranslations = false;
43918
- }));
43919
- }
43920
- isFirstUnsupported(index) {
43921
- const langs = this.sortLanguages(this.recordLanguages);
43922
- return (langs[index].length === 3 &&
43923
- langs.slice(0, index).every((lang) => lang.length !== 3));
43924
- }
43925
- isLangSupported(lang) {
43926
- return lang.length === 2;
43927
- }
43928
- getToggleTitle(lang) {
43929
- if (lang === this._record.defaultLanguage) {
43930
- return this.translateService.instant('editor.record.form.multilingual.forbidden');
43931
- }
43932
- return '';
44019
+ // emits and completes once saving is done
44020
+ // note: onSave processes are not run for drafts
44021
+ saveRecordAsDraft(record, recordSource) {
44022
+ record.recordUpdated = new Date();
44023
+ return this.recordsRepository
44024
+ .saveRecordAsDraft(record, recordSource)
44025
+ .pipe(map$1(() => undefined));
43933
44026
  }
43934
- openActionMenu(item, template) {
43935
- this.isActionMenuOpen = true;
43936
- const index = this.sortLanguages(this.selectedLanguages).indexOf(item);
43937
- const buttonElement = this.actionMenuButtons.toArray()[index];
43938
- const positionStrategy = this.overlay
43939
- .position()
43940
- .flexibleConnectedTo(buttonElement)
43941
- .withFlexibleDimensions(true)
43942
- .withPush(true)
43943
- .withPositions([
43944
- {
43945
- originX: 'end',
43946
- originY: 'bottom',
43947
- overlayX: 'end',
43948
- overlayY: 'top',
43949
- },
43950
- {
43951
- originX: 'end',
43952
- originY: 'top',
43953
- overlayX: 'end',
43954
- overlayY: 'bottom',
43955
- },
43956
- ]);
43957
- this.overlayRef = this.overlay.create({
43958
- hasBackdrop: true,
43959
- backdropClass: 'cdk-overlay-transparent-backdrop',
43960
- positionStrategy: positionStrategy,
43961
- scrollStrategy: this.overlay.scrollStrategies.reposition(),
43962
- });
43963
- const portal = new TemplatePortal(template, this.viewContainerRef);
43964
- this.overlayRef.attach(portal);
43965
- this.subscription.add(this.overlayRef.backdropClick().subscribe(() => {
43966
- this.closeActionMenu();
43967
- }));
44027
+ undoRecordDraft(record) {
44028
+ this.recordsRepository.clearRecordDraft(record.uniqueIdentifier);
44029
+ return this.recordsRepository.openRecordForEdition(record.uniqueIdentifier);
43968
44030
  }
43969
- closeActionMenu() {
43970
- if (this.overlayRef) {
43971
- this.isActionMenuOpen = false;
43972
- this.overlayRef.dispose();
43973
- this.cdr.markForCheck();
43974
- }
44031
+ hasRecordChangedSinceDraft(localRecord) {
44032
+ return this.recordsRepository.hasRecordChangedSinceDraft(localRecord);
43975
44033
  }
43976
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MultilingualPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
43977
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: MultilingualPanelComponent, isStandalone: true, selector: "gn-ui-multilingual-panel", inputs: { record: "record" }, providers: [
43978
- provideIcons({
43979
- iconoirSettings,
43980
- matMoreHorizOutline,
43981
- iconoirCheckCircle,
43982
- iconoirCircle,
43983
- }),
43984
- provideNgIconsConfig({
43985
- size: '1.25em',
43986
- }),
43987
- ], viewQueries: [{ propertyName: "actionMenuButtons", predicate: ["actionMenuButton"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div\n class=\"flex flex-col h-full w-[302px] border-l border-gray-300 py-8 px-3 gap-6 overflow-auto\"\n style=\"background-color: #fafaf9\"\n>\n <div class=\"flex flex-row px-2 justify-between\">\n <span class=\"text-3xl font-title text-black/80\" translate\n >editor.record.form.multilingual.title</span\n >\n @if (isMultilingual) {\n <button\n [title]=\"'editor.record.form.multilingual.open' | translate\"\n (click)=\"toggleLanguageSelection()\"\n data-test=\"activateSelection\"\n >\n <ng-icon class=\"mt-1\" name=\"iconoirSettings\"></ng-icon>\n </button>\n }\n </div>\n @if (editTranslations || !isMultilingual) {\n <div class=\"flex flex-col gap-2\">\n <gn-ui-check-toggle\n class=\"p-2\"\n [label]=\"'editor.record.form.multilingual.enable' | translate\"\n [color]=\"'primary'\"\n [(value)]=\"isMultilingual\"\n (toggled)=\"switchMultilingual($event)\"\n ></gn-ui-check-toggle>\n @if (isMultilingual) {\n <div class=\"flex flex-col gap-2\">\n <div\n class=\"flex flex-row justify-between border-t border-gray-300 p-3\"\n >\n <span class=\"mt-2 text-sm text-gray-600\" translate\n >editor.record.form.multilingual.activate</span\n >\n <gn-ui-button\n extraClass=\"w-16 h-8 font-bold\"\n type=\"gray\"\n (buttonClick)=\"validateTranslations()\"\n data-test=\"validateSelection\"\n >{{ 'editor.record.form.multilingual.validate' | translate }}\n </gn-ui-button>\n </div>\n @if (supportedLanguages$ | async; as languages) {\n @for (lang of languages; track lang) {\n <div\n class=\"flex flex-col gap-2 w-full px-2\"\n data-test=\"langAvailable\"\n [attr.data-test-lang]=\"lang\"\n >\n <gn-ui-button\n [extraClass]=\"getExtraClass(lang)\"\n type=\"gray\"\n (buttonClick)=\"toggleLanguage(lang)\"\n [disabled]=\"lang === _record.defaultLanguage\"\n [title]=\"getToggleTitle(lang)\"\n >\n <span [class]=\"getIconClass(lang)\"></span>\n <span class=\"ml-2\">{{ 'language.' + lang | translate }}</span>\n </gn-ui-button>\n </div>\n }\n }\n </div>\n }\n </div>\n }\n @if (!editTranslations && isMultilingual) {\n <div class=\"flex flex-col gap-2\">\n @for (\n recordLang of sortLanguages(recordLanguages);\n track recordLang;\n let i = $index\n ) {\n <gn-ui-button\n extraClass=\"flex flex-row justify-between bg-white border border-white rounded mb-1 h-[34px] w-full\"\n [ngClass]=\"{\n 'mt-8': isFirstUnsupported(i),\n '': true,\n }\"\n (buttonClick)=\"switchFormLang(recordLang)\"\n type=\"outline\"\n data-test=\"langSwitch\"\n >\n <div class=\"flex flex-row gap-2 items-center\">\n @if (recordLang === formLanguage) {\n <ng-icon\n class=\"text-primary mt-1\"\n name=\"iconoirCheckCircle\"\n ></ng-icon>\n }\n @if (recordLang !== formLanguage) {\n <ng-icon\n class=\"text-gray-800 mt-1\"\n name=\"iconoirCircle\"\n ></ng-icon>\n }\n @if (recordLang.length === 2) {\n <span [class]=\"getIconClass(recordLang) + 'mt-1'\"></span>\n }\n <span [ngClass]=\"recordLang === formLanguage ? 'text-black' : ''\">{{\n isLangSupported(recordLang)\n ? ('language.' + recordLang | translate)\n : recordLang.toUpperCase()\n }}</span>\n </div>\n <div class=\"flex flex-row gap-2 items-center\">\n @if (recordLang === formLanguage) {\n <span class=\"text-xs text-base\" translate\n >editor.record.form.multilingual.default</span\n >\n }\n <button\n (click)=\"\n openActionMenu(recordLang, template); $event.stopPropagation()\n \"\n cdkOverlayOrigin\n #actionMenuButton\n >\n <ng-icon class=\"pb-5\" name=\"matMoreHorizOutline\"></ng-icon>\n </button>\n <ng-template #template>\n <gn-ui-action-menu\n [canDelete]=\"recordLang !== _record.defaultLanguage\"\n page=\"record\"\n (delete)=\"confirmDeleteAction(recordLang)\"\n (closeActionMenu)=\"closeActionMenu()\"\n (switch)=\"switchDefaultLang(recordLang)\"\n >\n </gn-ui-action-menu>\n </ng-template>\n </div>\n </gn-ui-button>\n }\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: CheckToggleComponent, selector: "gn-ui-check-toggle", inputs: ["title", "label", "value", "color"], outputs: ["toggled"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: ActionMenuComponent, selector: "gn-ui-action-menu", inputs: ["canDuplicate", "isDuplicating", "canDelete", "page"], outputs: ["duplicate", "delete", "closeActionMenu", "rollback", "switch"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
44034
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
44035
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorService, providedIn: 'root' }); }
43988
44036
  }
43989
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MultilingualPanelComponent, decorators: [{
43990
- type: Component,
43991
- args: [{ selector: 'gn-ui-multilingual-panel', standalone: true, imports: [
43992
- CommonModule,
43993
- CheckToggleComponent,
43994
- TranslateDirective,
43995
- TranslatePipe,
43996
- ButtonComponent,
43997
- NgIconComponent,
43998
- ActionMenuComponent,
43999
- ], providers: [
44000
- provideIcons({
44001
- iconoirSettings,
44002
- matMoreHorizOutline,
44003
- iconoirCheckCircle,
44004
- iconoirCircle,
44005
- }),
44006
- provideNgIconsConfig({
44007
- size: '1.25em',
44008
- }),
44009
- ], template: "<div\n class=\"flex flex-col h-full w-[302px] border-l border-gray-300 py-8 px-3 gap-6 overflow-auto\"\n style=\"background-color: #fafaf9\"\n>\n <div class=\"flex flex-row px-2 justify-between\">\n <span class=\"text-3xl font-title text-black/80\" translate\n >editor.record.form.multilingual.title</span\n >\n @if (isMultilingual) {\n <button\n [title]=\"'editor.record.form.multilingual.open' | translate\"\n (click)=\"toggleLanguageSelection()\"\n data-test=\"activateSelection\"\n >\n <ng-icon class=\"mt-1\" name=\"iconoirSettings\"></ng-icon>\n </button>\n }\n </div>\n @if (editTranslations || !isMultilingual) {\n <div class=\"flex flex-col gap-2\">\n <gn-ui-check-toggle\n class=\"p-2\"\n [label]=\"'editor.record.form.multilingual.enable' | translate\"\n [color]=\"'primary'\"\n [(value)]=\"isMultilingual\"\n (toggled)=\"switchMultilingual($event)\"\n ></gn-ui-check-toggle>\n @if (isMultilingual) {\n <div class=\"flex flex-col gap-2\">\n <div\n class=\"flex flex-row justify-between border-t border-gray-300 p-3\"\n >\n <span class=\"mt-2 text-sm text-gray-600\" translate\n >editor.record.form.multilingual.activate</span\n >\n <gn-ui-button\n extraClass=\"w-16 h-8 font-bold\"\n type=\"gray\"\n (buttonClick)=\"validateTranslations()\"\n data-test=\"validateSelection\"\n >{{ 'editor.record.form.multilingual.validate' | translate }}\n </gn-ui-button>\n </div>\n @if (supportedLanguages$ | async; as languages) {\n @for (lang of languages; track lang) {\n <div\n class=\"flex flex-col gap-2 w-full px-2\"\n data-test=\"langAvailable\"\n [attr.data-test-lang]=\"lang\"\n >\n <gn-ui-button\n [extraClass]=\"getExtraClass(lang)\"\n type=\"gray\"\n (buttonClick)=\"toggleLanguage(lang)\"\n [disabled]=\"lang === _record.defaultLanguage\"\n [title]=\"getToggleTitle(lang)\"\n >\n <span [class]=\"getIconClass(lang)\"></span>\n <span class=\"ml-2\">{{ 'language.' + lang | translate }}</span>\n </gn-ui-button>\n </div>\n }\n }\n </div>\n }\n </div>\n }\n @if (!editTranslations && isMultilingual) {\n <div class=\"flex flex-col gap-2\">\n @for (\n recordLang of sortLanguages(recordLanguages);\n track recordLang;\n let i = $index\n ) {\n <gn-ui-button\n extraClass=\"flex flex-row justify-between bg-white border border-white rounded mb-1 h-[34px] w-full\"\n [ngClass]=\"{\n 'mt-8': isFirstUnsupported(i),\n '': true,\n }\"\n (buttonClick)=\"switchFormLang(recordLang)\"\n type=\"outline\"\n data-test=\"langSwitch\"\n >\n <div class=\"flex flex-row gap-2 items-center\">\n @if (recordLang === formLanguage) {\n <ng-icon\n class=\"text-primary mt-1\"\n name=\"iconoirCheckCircle\"\n ></ng-icon>\n }\n @if (recordLang !== formLanguage) {\n <ng-icon\n class=\"text-gray-800 mt-1\"\n name=\"iconoirCircle\"\n ></ng-icon>\n }\n @if (recordLang.length === 2) {\n <span [class]=\"getIconClass(recordLang) + 'mt-1'\"></span>\n }\n <span [ngClass]=\"recordLang === formLanguage ? 'text-black' : ''\">{{\n isLangSupported(recordLang)\n ? ('language.' + recordLang | translate)\n : recordLang.toUpperCase()\n }}</span>\n </div>\n <div class=\"flex flex-row gap-2 items-center\">\n @if (recordLang === formLanguage) {\n <span class=\"text-xs text-base\" translate\n >editor.record.form.multilingual.default</span\n >\n }\n <button\n (click)=\"\n openActionMenu(recordLang, template); $event.stopPropagation()\n \"\n cdkOverlayOrigin\n #actionMenuButton\n >\n <ng-icon class=\"pb-5\" name=\"matMoreHorizOutline\"></ng-icon>\n </button>\n <ng-template #template>\n <gn-ui-action-menu\n [canDelete]=\"recordLang !== _record.defaultLanguage\"\n page=\"record\"\n (delete)=\"confirmDeleteAction(recordLang)\"\n (closeActionMenu)=\"closeActionMenu()\"\n (switch)=\"switchDefaultLang(recordLang)\"\n >\n </gn-ui-action-menu>\n </ng-template>\n </div>\n </gn-ui-button>\n }\n </div>\n }\n</div>\n" }]
44010
- }], propDecorators: { record: [{
44011
- type: Input
44012
- }], actionMenuButtons: [{
44013
- type: ViewChildren,
44014
- args: ['actionMenuButton', { read: ElementRef }]
44015
- }] } });
44037
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorService, decorators: [{
44038
+ type: Injectable,
44039
+ args: [{
44040
+ providedIn: 'root',
44041
+ }]
44042
+ }] });
44016
44043
 
44017
- //forced translations that are not available in fields.config.ts
44018
- marker('editor.record.form.field.keywords');
44019
- marker('editor.record.form.field.topics');
44020
- marker('editor.record.form.field.contacts');
44021
- marker('editor.record.form.field.organisation');
44022
- class MetadataQualityPanelComponent {
44044
+ class EditorEffects {
44023
44045
  constructor() {
44024
- this.propsToValidate = getAllKeysValidator();
44025
- this.propertiesByPage = [];
44026
- }
44027
- ngOnChanges() {
44028
- if (this.editorConfig && this.record) {
44029
- const fieldsByPage = this.editorConfig.pages.map((page) => page.sections.flatMap((section) => section.fields
44030
- .filter((field) => this.propsToValidate.includes(field.model))
44031
- .map((field) => field.model)));
44032
- // FIXME: temporarily add topics and organisation to the first and third page
44033
- // as long as they are not handled by the editor
44034
- if (fieldsByPage.length > 0) {
44035
- fieldsByPage[0].includes('topics') || fieldsByPage[0].push('topics');
44036
- fieldsByPage[2].includes('organisation') ||
44037
- fieldsByPage[2].push('organisation');
44046
+ this.actions$ = inject(Actions);
44047
+ this.editorService = inject(EditorService);
44048
+ this.recordsRepository = inject(RecordsRepositoryInterface);
44049
+ this.plateformService = inject(PlatformServiceInterface);
44050
+ this.store = inject(Store);
44051
+ this.saveRecord$ = createEffect(() => this.actions$.pipe(ofType(saveRecord), withLatestFrom$1(this.store.select(selectRecord), this.store.select(selectRecordSource), this.store.select(selectEditorConfig)), switchMap$1(([, record, recordSource, fieldsConfig]) => this.editorService.saveRecord(record, recordSource, fieldsConfig).pipe(switchMap$1(([savedRecord, savedRecordSource]) => {
44052
+ const actions = [saveRecordSuccess()];
44053
+ if (!record?.uniqueIdentifier) {
44054
+ actions.push(openRecord({
44055
+ record: savedRecord,
44056
+ recordSource: savedRecordSource,
44057
+ }));
44038
44058
  }
44039
- this.propertiesByPage = fieldsByPage
44040
- .map((fields) => getQualityValidators(this.record, fields).map(({ name, validator }) => ({
44041
- label: `editor.record.form.field.${name}`, // use same translations as in fields.config.ts
44042
- value: validator(),
44043
- })))
44044
- .filter((arr) => arr.length > 0);
44045
- }
44046
- }
44047
- getExtraClass(checked) {
44048
- const baseClasses = 'flex flex-row justify-between rounded mb-1 h-[34px] w-full focus:ring-0 hover:border-none border-none hover:text-black text-black cursor-default';
44049
- return checked
44050
- ? `${baseClasses} bg-neutral-100 hover:bg-neutral-100`
44051
- : `${baseClasses} bg-transparent hover:bg-transparent`;
44059
+ return of(...actions);
44060
+ }), catchError((error) => of(saveRecordFailure({
44061
+ error,
44062
+ })))))));
44063
+ this.cleanRecordAttachments$ = createEffect(() => this.actions$.pipe(ofType(saveRecordSuccess), withLatestFrom$1(this.store.select(selectRecord)), switchMap$1(([_, record]) => {
44064
+ if (record.uniqueIdentifier !== null) {
44065
+ this.plateformService.cleanRecordAttachments(record).subscribe({
44066
+ next: (_) => undefined,
44067
+ error: (err) => {
44068
+ console.error(err);
44069
+ },
44070
+ });
44071
+ }
44072
+ return EMPTY;
44073
+ }), catchError((error) => {
44074
+ console.error(error);
44075
+ return EMPTY;
44076
+ })), { dispatch: false });
44077
+ this.markAsChanged$ = createEffect(() => this.actions$.pipe(ofType(updateRecordField, updateRecordLanguages), map$1(() => markRecordAsChanged())));
44078
+ this.saveRecordDraft$ = createEffect(() => this.actions$.pipe(ofType(updateRecordField, updateRecordLanguages), debounceTime$1(1000), withLatestFrom$1(this.store.select(selectRecord), this.store.select(selectRecordSource)), switchMap$1(([, record, recordSource]) => this.editorService.saveRecordAsDraft(record, recordSource)), map$1(() => draftSaveSuccess())));
44079
+ this.undoRecordDraft$ = createEffect(() => this.actions$.pipe(ofType(undoRecordDraft), withLatestFrom$1(this.store.select(selectRecord)), switchMap$1(([, record]) => this.editorService.undoRecordDraft(record)), map$1(([record, recordSource]) => openRecord({
44080
+ record,
44081
+ recordSource,
44082
+ }))));
44083
+ this.checkHasChangesOnOpen$ = createEffect(() => this.actions$.pipe(ofType(openRecord), map$1(({ record }) => this.recordsRepository.recordHasDraft(record.uniqueIdentifier)), filter((hasDraft) => hasDraft), map$1(() => markRecordAsChanged())));
44084
+ this.hasRecordChangedSinceDraft$ = createEffect(() => this.actions$.pipe(ofType(hasRecordChangedSinceDraft), switchMap$1(({ record }) => this.editorService
44085
+ .hasRecordChangedSinceDraft(record)
44086
+ .pipe(map$1((changes) => hasRecordChangedSinceDraftSuccess({ changes }))))));
44087
+ this.checkIsRecordPublished$ = createEffect(() => this.actions$.pipe(ofType(openRecord), map$1(({ record }) => record.uniqueIdentifier), switchMap$1((uniqueIdentifier) => this.recordsRepository.getRecordPublicationStatus(uniqueIdentifier)), map$1((isPublished$1) => isPublished({
44088
+ isPublished: isPublished$1,
44089
+ }))));
44090
+ this.checkCanEditRecord$ = createEffect(() => this.actions$.pipe(ofType(openRecord), map$1(({ record }) => record.uniqueIdentifier), switchMap$1((uniqueIdentifier) => this.recordsRepository.canEditRecord(uniqueIdentifier)), map$1((canEditRecord$1) => canEditRecord({
44091
+ canEditRecord: canEditRecord$1,
44092
+ }))));
44052
44093
  }
44053
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MetadataQualityPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
44054
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: MetadataQualityPanelComponent, isStandalone: true, selector: "gn-ui-metadata-quality-panel", inputs: { editorConfig: "editorConfig", record: "record" }, providers: [
44055
- provideIcons({
44056
- iconoirSystemShut,
44057
- iconoirBadgeCheck,
44058
- }),
44059
- provideNgIconsConfig({
44060
- size: '1.25em',
44061
- }),
44062
- ], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"flex flex-col h-full w-[302px] border-l border-gray-300 py-8 px-3 gap-3 overflow-auto\"\n style=\"background-color: #fafaf9\"\n>\n <div class=\"flex flex-row px-2 justify-between\">\n <span class=\"text-3xl font-title text-black/80\" translate\n >editor.record.form.metadataQuality.title</span\n >\n </div>\n @for (properties of propertiesByPage; track properties; let i = $index) {\n <div class=\"flex flex-col gap-2\">\n @for (property of properties; track property) {\n <gn-ui-button\n [extraClass]=\"getExtraClass(property.value)\"\n type=\"outline\"\n attr.data-cy=\"md-quality-btn-{{ property.label }}\"\n >\n <span>{{ property.label | translate }}</span>\n <div class=\"flex flex-row gap-2 items-center\">\n @if (property.value) {\n <ng-icon class=\"text-primary\" name=\"iconoirBadgeCheck\"></ng-icon>\n } @else {\n <ng-icon\n class=\"text-neutral-300\"\n name=\"iconoirSystemShut\"\n ></ng-icon>\n }\n </div>\n </gn-ui-button>\n }\n @if (i !== propertiesByPage.length - 1) {\n <hr class=\"border-gray-300 w-11/12 mx-auto\" />\n }\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
44094
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorEffects, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
44095
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorEffects }); }
44063
44096
  }
44064
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MetadataQualityPanelComponent, decorators: [{
44065
- type: Component,
44066
- args: [{ selector: 'gn-ui-metadata-quality-panel', standalone: true, imports: [
44067
- TranslateDirective,
44068
- TranslatePipe,
44069
- ButtonComponent,
44070
- NgIconComponent,
44071
- ], providers: [
44072
- provideIcons({
44073
- iconoirSystemShut,
44074
- iconoirBadgeCheck,
44075
- }),
44076
- provideNgIconsConfig({
44077
- size: '1.25em',
44078
- }),
44079
- ], template: "<div\n class=\"flex flex-col h-full w-[302px] border-l border-gray-300 py-8 px-3 gap-3 overflow-auto\"\n style=\"background-color: #fafaf9\"\n>\n <div class=\"flex flex-row px-2 justify-between\">\n <span class=\"text-3xl font-title text-black/80\" translate\n >editor.record.form.metadataQuality.title</span\n >\n </div>\n @for (properties of propertiesByPage; track properties; let i = $index) {\n <div class=\"flex flex-col gap-2\">\n @for (property of properties; track property) {\n <gn-ui-button\n [extraClass]=\"getExtraClass(property.value)\"\n type=\"outline\"\n attr.data-cy=\"md-quality-btn-{{ property.label }}\"\n >\n <span>{{ property.label | translate }}</span>\n <div class=\"flex flex-row gap-2 items-center\">\n @if (property.value) {\n <ng-icon class=\"text-primary\" name=\"iconoirBadgeCheck\"></ng-icon>\n } @else {\n <ng-icon\n class=\"text-neutral-300\"\n name=\"iconoirSystemShut\"\n ></ng-icon>\n }\n </div>\n </gn-ui-button>\n }\n @if (i !== propertiesByPage.length - 1) {\n <hr class=\"border-gray-300 w-11/12 mx-auto\" />\n }\n </div>\n }\n</div>\n" }]
44080
- }], propDecorators: { editorConfig: [{
44081
- type: Input
44082
- }], record: [{
44083
- type: Input
44084
- }] } });
44097
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorEffects, decorators: [{
44098
+ type: Injectable
44099
+ }] });
44100
+
44101
+ class FeatureEditorModule {
44102
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
44103
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, imports: [i1.StoreFeatureModule, i2$2.EffectsFeatureModule] }); }
44104
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, providers: [EditorFacade, provideHttpClient()], imports: [StoreModule.forFeature(EDITOR_FEATURE_KEY, editorReducer),
44105
+ EffectsModule.forFeature([EditorEffects])] }); }
44106
+ }
44107
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, decorators: [{
44108
+ type: NgModule,
44109
+ args: [{
44110
+ imports: [
44111
+ StoreModule.forFeature(EDITOR_FEATURE_KEY, editorReducer),
44112
+ EffectsModule.forFeature([EditorEffects]),
44113
+ ],
44114
+ providers: [EditorFacade, provideHttpClient()],
44115
+ }]
44116
+ }] });
44085
44117
 
44086
44118
  const ROUTER_STATE_KEY = 'router';
44087
44119
  const ROUTER_ROUTE_SEARCH = 'search';
@@ -44524,5 +44556,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
44524
44556
  * Generated bundle index. Do not edit.
44525
44557
  */
44526
44558
 
44527
- export { ADD_RESULTS, ADD_SEARCH, AbstractAction, AbstractSearchField, ActionMenuComponent, AddLayerFromCatalogComponent, AddLayerRecordPreviewComponent, AddResults, AddSearch, AnchorLinkDirective, ApiCardComponent, ApplicationBannerComponent, AuthService, AutocompleteComponent, AvailableServicesField, AvatarComponent, AvatarServiceInterface, BASEMAP_LAYERS, BadgeComponent, BaseConverter, BaseFileReader, BaseReader, BlockListComponent, ButtonComponent, CLEAR_ERROR, CLEAR_RESULTS, CarouselComponent, CatalogTitleComponent, CellPopinComponent, ChartComponent, ChartViewComponent, CheckToggleComponent, CheckboxComponent, ClearError, ClearResults, ColorScaleComponent, ConfirmationDialogComponent, ContentGhostComponent, CopyTextButtonComponent, DEFAULT_GN4_LOGIN_URL, DEFAULT_GN4_LOGOUT_URL, DEFAULT_GN4_SETTINGS_URL, DEFAULT_LANG, DEFAULT_PAGE_SIZE, DEFAULT_RESULTS_LAYOUT_CONFIG, DEFAULT_SEARCH_KEY, DISABLE_AUTH, DO_NOT_USE_DEFAULT_BASEMAP, DataService, DataTableComponent, DataViewComponent, DataViewPermalinkComponent, DataViewShareComponent, DataViewWebComponentComponent, DatePickerComponent, DateRangeDropdownComponent, DateRangeInputsComponent, DateRangePickerComponent, DateRangeSearchField, DateService, DcatApConverter, DefaultRouterModule, DownloadItemComponent, DownloadsListComponent, DragAndDropFileInputComponent, DropdownMultiselectComponent, DropdownSelectorComponent, EDITOR_FEATURE_KEY, ES_QUERY_FIELDS_PRIORITY, ES_RESOURCES_VALUES, ES_SOURCE_SUMMARY, EXTERNAL_VIEWER_OPEN_NEW_TAB, EXTERNAL_VIEWER_URL_TEMPLATE, EditableLabelDirective, EditorFacade, EditorService, ElasticsearchService, EmbeddedTranslateLoader, ErrorComponent, ErrorType, ExpandablePanelButtonComponent, ExpandablePanelComponent, ExternalLinkCardComponent, ExternalViewerButtonComponent, FIELDS_BRIEF, FIELDS_SUMMARY, FILTER_GEOMETRY, FILTER_SUMMARY_IGNORE_LIST, FORMATS, FacetBlockComponent, FacetItemComponent, FacetListComponent, FacetsContainerComponent, FavoriteStarComponent, FavoritesService, FeatureCatalogListComponent, FeatureDetailComponent, FeatureEditorModule, FeatureMapModule, FeatureRecordModule, FeatureSearchModule, FetchError, FieldsService, FigureComponent, FigureContainerComponent, FileInputComponent, FileTranslateLoader, FilesDropDirective, FilterDropdownComponent, FormFieldArrayComponent, FormFieldComponent, FormFieldDateComponent, FormFieldFileComponent, FormFieldKeywordsComponent, FormFieldLicenseComponent, FormFieldObjectComponent, FormFieldRichComponent, FormFieldSimpleComponent, FormFieldSpatialExtentComponent, FormFieldTemporalExtentsComponent, FormFieldTopicsComponent, FormFieldWrapperComponent, FullTextSearchField, FuzzySearchComponent, GEONETWORK_UI_TAG_NAME, GEONETWORK_UI_VERSION, GeoDataBadgeComponent, GeoTableViewComponent, GeocodingComponent, GeojsonReader, Gn4Converter, Gn4PlatformMapper, Gn4PlatformService, Gn4Repository, Gn4SettingsService, GnUiHumanizeDateDirective, GpfApiDlComponent, GravatarService, HttpLoaderFactory, I18nInterceptor, ImageFallbackDirective, ImageInputComponent, ImageOverlayPreviewComponent, ImportRecordComponent, InlineFilterComponent, InteractiveTableColumnComponent, InteractiveTableComponent, InternalLinkCardComponent, IsSpatialSearchField, Iso191153Converter, Iso19139Converter, KindBadgeComponent, LANGUAGES_LIST, LANGUAGE_NAMES, LANGUAGE_STORAGE_KEY, LANG_2_TO_3_MAPPER, LOGIN_URL, LOGOUT_URL, LONLAT_CRS_CODES, LanguageSwitcherComponent, LayersPanelComponent, LicenseSearchField, LinkClassifierService, LinkUsage, LoadingMaskComponent, LogService, MAP_FEATURE_KEY, MAP_VIEW_CONSTRAINTS, METADATA_LANGUAGE, MapContainerComponent, MapFacade, MapLegendComponent, MapStateContainerComponent, MapStyleService, MapUtilsService, MapViewComponent, MarkdownEditorComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataDoiComponent, MetadataInfoComponent, MetadataLinkType, MetadataMapperContext, MetadataQualityComponent, MetadataQualityItemComponent, MetadataQualityPanelComponent, ModalDialogComponent, MultilingualPanelComponent, MultilingualSearchField, MyOrgService, NAMESPACES, NOT_APPLICABLE_CONSTRAINT, NOT_KNOWN_CONSTRAINT, NotificationComponent, NotificationsContainerComponent, NotificationsService, ORGANIZATIONS_STRATEGY, ORGANIZATION_PAGE_URL_TOKEN, ORGANIZATION_URL_TOKEN, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationSearchField, OrganizationsFromGroupsService, OrganizationsFromMetadataService, OrganizationsServiceInterface, OwnerSearchField, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PaginationDotsComponent, PatchResultsAggregations, PlatformServiceInterface, PopoverComponent, PopupAlertComponent, PossibleResourceTypes, PossibleResourceTypesDefinition, PreviousNextButtonsComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_DATASET_URL_TOKEN, RECORD_REUSE_URL_TOKEN, RECORD_SERVICE_URL_TOKEN, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESULTS_LAYOUT_CONFIG, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_ORGANIZATION, ROUTER_ROUTE_REUSE, ROUTER_ROUTE_SEARCH, ROUTER_ROUTE_SERVICE, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordKindField, RecordMetaComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordsMetricsComponent, RecordsRepositoryInterface, RecordsService, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResourceTypeLegacyField, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsHitsSearchKindComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, ResultsTableContainerComponent, ReusePresentationForms, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, SETTINGS_URL, SET_CONFIG_AGGREGATIONS, SET_CONFIG_FILTERS, SET_CONFIG_REQUEST_FIELDS, SET_ERROR, SET_FAVORITES_ONLY, SET_FILTERS, SET_INCLUDE_ON_AGGREGATION, SET_PAGE_SIZE, SET_RESULTS_AGGREGATIONS, SET_RESULTS_HITS, SET_RESULTS_LAYOUT, SET_SEARCH, SET_SORT_BY, SET_SPATIAL_FILTER_ENABLED, SearchEffects, SearchFacade, SearchFeatureCatalogComponent, SearchFiltersSummaryComponent, SearchFiltersSummaryItemComponent, SearchInputComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, ServiceCapabilitiesComponent, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SimpleSearchField, SiteTitleComponent, SortByComponent, SortableListComponent, SourceLabelComponent, SourcesService, SpatialExtentComponent, SpinningLoaderComponent, StacItemsResultGridComponent, StacViewComponent, StarToggleComponent, StickyHeaderComponent, SupportedTypes, SwitchToggleComponent, THUMBNAIL_PLACEHOLDER, TRANSLATE_DEBUG_CONFIG, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, TranslatedSearchField, TruncatedTextComponent, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, UpdateConfigAggregations, UpdateFilters, UrlInputComponent, UserFeedbackItemComponent, UserPreviewComponent, UserSearchField, VECTOR_STYLE_DEFAULT, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, XmlParseError, _reset, allChildrenElement, appConfigWithTranslationFixture, appendChildTree, appendChildren, assertValidXml, blockModelFixture, bytesToMegabytes, canEditRecord, checkFileFormat, clearSelectedFeatures, createChild, createDocument, createElement, createFuzzyFilter, createNestedChild, createNestedElement, currentPage, defaultMapStyleFixture, defaultMapStyleHlFixture, downgradeImage, downsizeImage, draftSaveSuccess, dragPanCondition, dropEmptyTranslations, editorReducer, emptyBlockModelFixture, findChildElement, findChildOrCreate, findChildrenElement, findConverterForDocument, findNestedChildOrCreate, findNestedElement, findNestedElements, findParent, firstChildElement, formatDate, formatUserInfo, getAllKeysValidator, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryBoundingBox, getGeometryFromGeoJSON, getGlobalConfig, getIsMobile, getJsonDataItemsProxy, getLayers, getLinkId, getLinkLabel, getLinkPriority, getMapContext, getMapContextLayerFromConfig, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getNamespace, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getQualityValidators, getResourceType, getReusePresentationForm, getReuseType, getRootElement, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSelectedFeatures, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, handleScrollOnNavigation, hasRecordChangedSinceDraft, hasRecordChangedSinceDraftSuccess, initSearch, initialEditorState, initialMapState, initialState, isConfigLoaded, isDateRange, isFormatInQueryParam, isPublished, itemModelFixture, kindToCodeListValue, loadAppConfig, malformedConfigFixture, mapConfigFixture, mapContact, mapKeywords, mapLogo, mapOrganization, mapReducer, markRecordAsChanged, matchesNoApplicableConstraint, matchesNoKnownConstraint, megabytesToBytes, mimeTypeToFormat, minimalAppConfigFixture, missingMandatoryConfigFixture, mouseWheelZoomCondition, noDuplicateFileName, okAppConfigFixture, openDataset, openRecord, organizationsServiceFactory, parse, parseXmlString, placeholder, prioritizePageScroll, propagateToDocumentOnly, provideGn4, provideI18n, provideRepositoryUrl, readAttribute, readDataset, readDatasetHeaders, readText, reducer$2 as reducer, reducerSearch, removeAllChildren, removeChildren, removeChildrenByName, removeSearchParams, removeWhitespace, renameElements, saveRecord, saveRecordFailure, saveRecordSuccess, selectCanEditRecord, selectCurrentPage, selectEditorConfig, selectEditorState, selectFallback, selectFallbackFields, selectField, selectHasRecordChanged, selectIsPublished, selectRecord, selectRecordChangedSinceSave, selectRecordSaveError, selectRecordSaving, selectRecordSections, selectRecordSource, selectTranslatedField, selectTranslatedValue, setContext, setCurrentPage, setFieldVisibility, setSelectedFeatures, setTextContent, someHabTableItemFixture, sortByFromString, sortByToString, sortByToStrings, stripHtml, stripNamespace, tableItemsFixture, toDate, toLang2, toLang3, totalPages, undoRecordDraft, unrecognizedKeysConfigFixture, updateLanguages, updateRecordField, updateRecordLanguages, wmsLayerFlatten, writeAttribute, wrongLanguageCodeConfigFixture, xmlToString };
44559
+ export { ABOUT_SECTION, ADD_RESULTS, ADD_SEARCH, ANNEXES_SECTION, ASSOCIATED_RESOURCES_SECTION, AVAILABLE_LICENSES, AbstractAction, AbstractSearchField, ActionMenuComponent, AddLayerFromCatalogComponent, AddLayerRecordPreviewComponent, AddResults, AddSearch, AnchorLinkDirective, ApiCardComponent, ApplicationBannerComponent, AuthService, AutocompleteComponent, AvailableServicesField, AvatarComponent, AvatarServiceInterface, BASEMAP_LAYERS, BadgeComponent, BaseConverter, BaseFileReader, BaseReader, BlockListComponent, ButtonComponent, CLASSIFICATION_SECTION, CLEAR_ERROR, CLEAR_RESULTS, CONSTRAINTS_SHORTCUTS, CONTACTS, CONTACTS_FOR_RESOURCE_FIELD, CarouselComponent, CatalogTitleComponent, CellPopinComponent, ChartComponent, ChartViewComponent, CheckToggleComponent, CheckboxComponent, ClearError, ClearResults, ColorScaleComponent, ConfirmationDialogComponent, ContentGhostComponent, CopyTextButtonComponent, DATA_MANAGERS_SECTION, DEFAULT_CONFIGURATION, DEFAULT_GN4_LOGIN_URL, DEFAULT_GN4_LOGOUT_URL, DEFAULT_GN4_SETTINGS_URL, DEFAULT_LANG, DEFAULT_PAGE_SIZE, DEFAULT_RESULTS_LAYOUT_CONFIG, DEFAULT_SEARCH_KEY, DISABLE_AUTH, DO_NOT_USE_DEFAULT_BASEMAP, DataService, DataTableComponent, DataViewComponent, DataViewPermalinkComponent, DataViewShareComponent, DataViewWebComponentComponent, DatePickerComponent, DateRangeDropdownComponent, DateRangeInputsComponent, DateRangePickerComponent, DateRangeSearchField, DateService, DcatApConverter, DefaultRouterModule, DownloadItemComponent, DownloadsListComponent, DragAndDropFileInputComponent, DropdownMultiselectComponent, DropdownSelectorComponent, EDITOR_FEATURE_KEY, ES_QUERY_FIELDS_PRIORITY, ES_RESOURCES_VALUES, ES_SOURCE_SUMMARY, EXTERNAL_VIEWER_OPEN_NEW_TAB, EXTERNAL_VIEWER_URL_TEMPLATE, EditableLabelDirective, EditorFacade, EditorService, ElasticsearchService, EmbeddedTranslateLoader, ErrorComponent, ErrorType, ExpandablePanelButtonComponent, ExpandablePanelComponent, ExternalLinkCardComponent, ExternalViewerButtonComponent, FIELDS_BRIEF, FIELDS_SUMMARY, FILTER_GEOMETRY, FILTER_SUMMARY_IGNORE_LIST, FORMATS, FacetBlockComponent, FacetItemComponent, FacetListComponent, FacetsContainerComponent, FavoriteStarComponent, FavoritesService, FeatureCatalogListComponent, FeatureDetailComponent, FeatureEditorModule, FeatureMapModule, FeatureRecordModule, FeatureSearchModule, FetchError, FieldsService, FigureComponent, FigureContainerComponent, FileInputComponent, FileTranslateLoader, FilesDropDirective, FilterDropdownComponent, FormFieldArrayComponent, FormFieldComponent, FormFieldDateComponent, FormFieldFileComponent, FormFieldKeywordsComponent, FormFieldLicenseComponent, FormFieldObjectComponent, FormFieldRichComponent, FormFieldSimpleComponent, FormFieldSpatialExtentComponent, FormFieldTemporalExtentsComponent, FormFieldTopicsComponent, FormFieldWrapperComponent, FullTextSearchField, FuzzySearchComponent, GEOGRAPHICAL_COVERAGE_SECTION, GEONETWORK_UI_TAG_NAME, GEONETWORK_UI_VERSION, GeoDataBadgeComponent, GeoTableViewComponent, GeocodingComponent, GeojsonReader, Gn4Converter, Gn4PlatformMapper, Gn4PlatformService, Gn4Repository, Gn4SettingsService, GnUiHumanizeDateDirective, GpfApiDlComponent, GravatarService, HttpLoaderFactory, I18nInterceptor, INSPIRE_TOPICS, ImageFallbackDirective, ImageInputComponent, ImageOverlayPreviewComponent, ImportRecordComponent, InlineFilterComponent, InteractiveTableColumnComponent, InteractiveTableComponent, InternalLinkCardComponent, IsSpatialSearchField, Iso191153Converter, Iso19139Converter, KindBadgeComponent, LANGUAGES_LIST, LANGUAGE_NAMES, LANGUAGE_STORAGE_KEY, LANG_2_TO_3_MAPPER, LEGAL_CONSTRAINTS_FIELD, LOGIN_URL, LOGOUT_URL, LONLAT_CRS_CODES, LanguageSwitcherComponent, LayersPanelComponent, LicenseSearchField, LinkClassifierService, LinkUsage, LoadingMaskComponent, LogService, MAP_FEATURE_KEY, MAP_VIEW_CONSTRAINTS, MAX_UPLOAD_SIZE_MB, METADATA_LANGUAGE, METADATA_POINT_OF_CONTACT_SECTION, MapContainerComponent, MapFacade, MapLegendComponent, MapStateContainerComponent, MapStyleService, MapUtilsService, MapViewComponent, MarkdownEditorComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataDoiComponent, MetadataInfoComponent, MetadataLinkType, MetadataMapperContext, MetadataQualityComponent, MetadataQualityItemComponent, MetadataQualityPanelComponent, ModalDialogComponent, MultilingualPanelComponent, MultilingualSearchField, MyOrgService, NAMESPACES, NOT_APPLICABLE_CONSTRAINT, NOT_KNOWN_CONSTRAINT, NotificationComponent, NotificationsContainerComponent, NotificationsService, OPEN_DATA_LICENSE, ORGANIZATIONS_STRATEGY, ORGANIZATION_PAGE_URL_TOKEN, ORGANIZATION_URL_TOKEN, OTHER_CONSTRAINTS_FIELD, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationSearchField, OrganizationsFromGroupsService, OrganizationsFromMetadataService, OrganizationsServiceInterface, OwnerSearchField, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PaginationDotsComponent, PatchResultsAggregations, PlatformServiceInterface, PopoverComponent, PopupAlertComponent, PossibleResourceTypes, PossibleResourceTypesDefinition, PreviousNextButtonsComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_ABSTRACT_FIELD, RECORD_DATASET_URL_TOKEN, RECORD_GRAPHICAL_OVERVIEW_FIELD, RECORD_KEYWORDS_FIELD, RECORD_LICENSE_FIELD, RECORD_ONLINE_LINK_RESOURCES, RECORD_ONLINE_RESOURCES, RECORD_RESOURCE_CREATED_FIELD, RECORD_RESOURCE_UPDATED_FIELD, RECORD_REUSE_URL_TOKEN, RECORD_SERVICE_URL_TOKEN, RECORD_SPATIAL_EXTENTS_FIELD, RECORD_SPATIAL_TOGGLE_FIELD, RECORD_TEMPORAL_EXTENTS_FIELD, RECORD_TITLE_FIELD, RECORD_TOPICS_FIELD, RECORD_UNIQUE_IDENTIFIER_FIELD, RECORD_UPDATED_FIELD, RECORD_UPDATE_FREQUENCY_FIELD, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESOURCE_IDENTIFIER_FIELD, RESULTS_LAYOUT_CONFIG, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_ORGANIZATION, ROUTER_ROUTE_REUSE, ROUTER_ROUTE_SEARCH, ROUTER_ROUTE_SERVICE, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordKindField, RecordMetaComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordsMetricsComponent, RecordsRepositoryInterface, RecordsService, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResourceTypeLegacyField, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsHitsSearchKindComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, ResultsTableContainerComponent, ReusePresentationForms, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, SECURITY_CONSTRAINTS_FIELD, SETTINGS_URL, SET_CONFIG_AGGREGATIONS, SET_CONFIG_FILTERS, SET_CONFIG_REQUEST_FIELDS, SET_ERROR, SET_FAVORITES_ONLY, SET_FILTERS, SET_INCLUDE_ON_AGGREGATION, SET_PAGE_SIZE, SET_RESULTS_AGGREGATIONS, SET_RESULTS_HITS, SET_RESULTS_LAYOUT, SET_SEARCH, SET_SORT_BY, SET_SPATIAL_FILTER_ENABLED, SPATIAL_SCOPES, SearchEffects, SearchFacade, SearchFeatureCatalogComponent, SearchFiltersSummaryComponent, SearchFiltersSummaryItemComponent, SearchInputComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, ServiceCapabilitiesComponent, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SimpleSearchField, SiteTitleComponent, SortByComponent, SortableListComponent, SourceLabelComponent, SourcesService, SpatialExtentComponent, SpinningLoaderComponent, StacItemsResultGridComponent, StacViewComponent, StarToggleComponent, StickyHeaderComponent, SupportedTypes, SwitchToggleComponent, THUMBNAIL_PLACEHOLDER, TITLE_SECTION, TOPICS_SECTION, TRANSLATE_DEBUG_CONFIG, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, TranslatedSearchField, TruncatedTextComponent, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, USE_AND_ACCESS_CONDITIONS_SECTION, UpdateConfigAggregations, UpdateFilters, UrlInputComponent, UserFeedbackItemComponent, UserPreviewComponent, UserSearchField, VECTOR_STYLE_DEFAULT, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, XmlParseError, _reset, allChildrenElement, appConfigWithTranslationFixture, appendChildTree, appendChildren, assertValidXml, blockModelFixture, bytesToMegabytes, canEditRecord, checkFileFormat, clearSelectedFeatures, createChild, createDocument, createElement, createFuzzyFilter, createNestedChild, createNestedElement, currentPage, defaultMapStyleFixture, defaultMapStyleHlFixture, downgradeImage, downsizeImage, draftSaveSuccess, dragPanCondition, dropEmptyTranslations, editorReducer, emptyBlockModelFixture, findChildElement, findChildOrCreate, findChildrenElement, findConverterForDocument, findNestedChildOrCreate, findNestedElement, findNestedElements, findParent, firstChildElement, formatDate, formatUserInfo, getAllKeysValidator, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryBoundingBox, getGeometryFromGeoJSON, getGlobalConfig, getIsMobile, getJsonDataItemsProxy, getLayers, getLinkId, getLinkLabel, getLinkPriority, getMapContext, getMapContextLayerFromConfig, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getNamespace, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getQualityValidators, getResourceType, getReusePresentationForm, getReuseType, getRootElement, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSelectedFeatures, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, handleScrollOnNavigation, hasRecordChangedSinceDraft, hasRecordChangedSinceDraftSuccess, initSearch, initialEditorState, initialMapState, initialState, isConfigLoaded, isDateRange, isFormatInQueryParam, isPublished, itemModelFixture, kindToCodeListValue, loadAppConfig, malformedConfigFixture, mapConfigFixture, mapContact, mapKeywords, mapLogo, mapOrganization, mapReducer, markRecordAsChanged, matchesNoApplicableConstraint, matchesNoKnownConstraint, megabytesToBytes, mimeTypeToFormat, minimalAppConfigFixture, missingMandatoryConfigFixture, mouseWheelZoomCondition, noDuplicateFileName, okAppConfigFixture, openDataset, openRecord, organizationsServiceFactory, parse, parseXmlString, placeholder, prioritizePageScroll, propagateToDocumentOnly, provideGn4, provideI18n, provideRepositoryUrl, readAttribute, readDataset, readDatasetHeaders, readText, reducer$2 as reducer, reducerSearch, removeAllChildren, removeChildren, removeChildrenByName, removeSearchParams, removeWhitespace, renameElements, saveRecord, saveRecordFailure, saveRecordSuccess, selectCanEditRecord, selectCurrentPage, selectEditorConfig, selectEditorState, selectFallback, selectFallbackFields, selectField, selectHasRecordChanged, selectIsPublished, selectRecord, selectRecordChangedSinceSave, selectRecordSaveError, selectRecordSaving, selectRecordSections, selectRecordSource, selectTranslatedField, selectTranslatedValue, setContext, setCurrentPage, setEditorConfiguration, setFieldVisibility, setSelectedFeatures, setTextContent, someHabTableItemFixture, sortByFromString, sortByToString, sortByToStrings, stripHtml, stripNamespace, tableItemsFixture, toDate, toLang2, toLang3, totalPages, undoRecordDraft, unrecognizedKeysConfigFixture, updateLanguages, updateRecordField, updateRecordLanguages, wmsLayerFlatten, writeAttribute, wrongLanguageCodeConfigFixture, xmlToString };
44528
44560
  //# sourceMappingURL=geonetwork-ui.mjs.map