geonetwork-ui 2.8.3-dev.a76ac18c6 → 2.9.0-dev.023c4f049

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 (50) hide show
  1. package/fesm2022/geonetwork-ui.mjs +645 -545
  2. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  3. package/index.d.ts +249 -158
  4. package/index.d.ts.map +1 -1
  5. package/package.json +7 -8
  6. package/src/libs/common/domain/src/index.ts +1 -0
  7. package/src/libs/feature/dataviz/src/lib/chart-view/chart-view.component.html +10 -12
  8. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +8 -3
  9. package/src/libs/feature/editor/src/index.ts +8 -7
  10. package/src/libs/feature/editor/src/lib/+state/editor.actions.ts +6 -1
  11. package/src/libs/feature/editor/src/lib/+state/editor.facade.ts +5 -1
  12. package/src/libs/feature/editor/src/lib/+state/editor.reducer.ts +4 -0
  13. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +2 -2
  14. package/src/libs/feature/record/src/lib/external-viewer-button/external-viewer-button.component.ts +2 -0
  15. package/src/libs/feature/record/src/lib/gpf-api-dl/gpf-api-dl.component.html +4 -4
  16. package/src/libs/feature/record/src/lib/gpf-api-dl/gpf-api-dl.component.ts +3 -4
  17. package/src/libs/feature/record/src/lib/map-view/map-view.component.html +10 -18
  18. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +96 -9
  19. package/src/libs/feature/router/src/lib/default/router.module.ts +3 -3
  20. package/src/libs/feature/router/src/lib/default/router.service.ts +2 -2
  21. package/src/libs/feature/router/src/lib/default/services/router-search.service.ts +12 -3
  22. package/src/libs/feature/router/src/lib/default/state/router.effects.ts +34 -4
  23. package/src/libs/feature/search/src/lib/state/reducer.ts +3 -0
  24. package/src/libs/ui/elements/src/lib/api-card/api-card.component.html +2 -2
  25. package/src/libs/ui/elements/src/lib/application-banner/application-banner.component.ts +2 -3
  26. package/src/libs/ui/elements/src/lib/downloads-list/downloads-list.component.ts +5 -3
  27. package/src/libs/ui/elements/src/lib/image-input/image-input.component.html +5 -2
  28. package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.html +63 -56
  29. package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.scss +5 -5
  30. package/src/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.html +10 -7
  31. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html +1 -1
  32. package/src/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.html +1 -1
  33. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.ts +1 -1
  34. package/src/libs/ui/map/src/lib/map-utils.ts +1 -1
  35. package/src/libs/ui/search/src/lib/record-preview-feed/record-preview-feed.component.html +19 -16
  36. package/src/libs/util/app-config/src/lib/app-config.ts +8 -2
  37. package/src/libs/util/app-config/src/lib/fixtures.ts +1 -0
  38. package/src/libs/util/app-config/src/lib/model.ts +1 -0
  39. package/src/libs/util/shared/src/lib/gn-ui-version.ts +1 -1
  40. package/src/libs/util/shared/src/lib/links/link-utils.ts +8 -4
  41. package/src/libs/util/shared/src/lib/services/theme.service.ts +9 -23
  42. package/tailwind.base.config.js +3 -2
  43. package/translations/de.json +4 -3
  44. package/translations/en.json +6 -5
  45. package/translations/es.json +1 -0
  46. package/translations/fr.json +6 -5
  47. package/translations/it.json +6 -5
  48. package/translations/nl.json +1 -0
  49. package/translations/pt.json +1 -0
  50. package/translations/sk.json +2 -1
@@ -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';
@@ -92,7 +92,6 @@ import { MatTableModule } from '@angular/material/table';
92
92
  import * as i3 from '@angular/material/paginator';
93
93
  import { MatPaginatorIntl, MatPaginatorModule, MatPaginator } from '@angular/material/paginator';
94
94
  import { LetDirective } from '@ngrx/component';
95
- import axios from 'axios';
96
95
  import { Meta } from '@angular/platform-browser';
97
96
  import { tablerFolderOpen } from '@ng-icons/tabler-icons';
98
97
  import * as i3$1 from '@angular/material/radio';
@@ -18970,6 +18969,7 @@ var de = {
18970
18969
  "map.ogc.urlInput.hint": "Die URL des OGC API-Dienstes eingeben",
18971
18970
  "map.select.layer": "Datenquelle",
18972
18971
  "map.select.style": "Style",
18972
+ "map.style.default": "Standard",
18973
18973
  "map.wfs.urlInput.hint": "Die WFS URL eingeben",
18974
18974
  "map.wms.urlInput.hint": "Die WMS URL eingeben",
18975
18975
  "multiselect.filter.placeholder": "Suche",
@@ -19061,7 +19061,7 @@ var de = {
19061
19061
  "record.metadata.download": "Herunterladen",
19062
19062
  "record.metadata.feature.catalog": "Attributkatalog",
19063
19063
  "record.metadata.formats": "Formate",
19064
- "record.metadata.isGeographical": "Geographischer Datensatz",
19064
+ "record.metadata.isGeographical": "geographischer Datensatz",
19065
19065
  "record.metadata.keywords": "Stichworte",
19066
19066
  "record.metadata.languages": "Sprachen",
19067
19067
  "record.metadata.link.postgis.table": "Tabelle:",
@@ -19192,6 +19192,7 @@ var de = {
19192
19192
  "search.filters.producerOrg": "Herausgeber",
19193
19193
  "search.filters.publicationYear": "Veröffentlichungsjahr",
19194
19194
  "search.filters.publisherOrg": "Vertreiber",
19195
+ "search.filters.recordKind": "",
19195
19196
  "search.filters.recordKind.all": "Alle",
19196
19197
  "search.filters.recordKind.dataset": "Datensätze",
19197
19198
  "search.filters.recordKind.reuse": "Wiederverwendungen",
@@ -19230,8 +19231,8 @@ var de = {
19230
19231
  "service.metadata.spatialExtent": "Räumliche Ausdehnung",
19231
19232
  "share.tab.permalink": "Teilen",
19232
19233
  "share.tab.webComponent": "Integrieren",
19233
- "stac.filter.reset": "",
19234
19234
  "stac.filter.enable": "",
19235
+ "stac.filter.reset": "",
19235
19236
  "stac.results.noResults": "Ihre Suchfilter lieferten keine Ergebnisse",
19236
19237
  "table.loading.data": "Daten werden geladen...",
19237
19238
  "table.object.count": "Objekte in diesem Datensatz",
@@ -19250,7 +19251,7 @@ var de = {
19250
19251
  "wfs.feature.limit": "Zu viele Features, um den WFS-Layer anzuzeigen!",
19251
19252
  "wfs.featuretype.notfound": "Kein passender Feature-Typ wurde im Dienst gefunden",
19252
19253
  "wfs.geojsongml.notsupported": "Dieser Dienst unterstützt das GeoJSON- oder GML-Format nicht",
19253
- "wfs.unreachable.cors": "Der Dienst konnte aufgrund von CORS-Beschränkungen nicht erreicht werden",
19254
+ "wfs.unreachable.cors": "Der Remote-Dienst ist nicht für den Datenempfang (CORS) konfiguriert",
19254
19255
  "wfs.unreachable.http": "Der Dienst hat einen HTTP-Fehler zurückgegeben",
19255
19256
  "wfs.unreachable.unknown": "Der Dienst konnte nicht erreicht werden"
19256
19257
  };
@@ -19641,6 +19642,7 @@ var en = {
19641
19642
  "map.ogc.urlInput.hint": "Enter OGC API service URL",
19642
19643
  "map.select.layer": "Data source",
19643
19644
  "map.select.style": "Style",
19645
+ "map.style.default": "Default",
19644
19646
  "map.wfs.urlInput.hint": "Enter WFS service URL",
19645
19647
  "map.wms.urlInput.hint": "Enter WMS service URL",
19646
19648
  "multiselect.filter.placeholder": "Search",
@@ -19674,9 +19676,9 @@ var en = {
19674
19676
  "record.feature.catalog.number.total.attribute": "Total amount of objects",
19675
19677
  "record.feature.catalog.number.total.object": "Total amount of attributes",
19676
19678
  "record.feature.limit": "Preview disabled due to too many elements",
19677
- "record.kind.dataset": "Dataset",
19678
- "record.kind.reuse": "Reuse",
19679
- "record.kind.service": "Service",
19679
+ "record.kind.dataset": "dataset",
19680
+ "record.kind.reuse": "reuse",
19681
+ "record.kind.service": "service",
19680
19682
  "record.metadata.about": "Description",
19681
19683
  "record.metadata.api": "API",
19682
19684
  "record.metadata.api.accessServiceProtocol.GPFDL": "GPFDL",
@@ -19732,7 +19734,7 @@ var en = {
19732
19734
  "record.metadata.download": "Downloads",
19733
19735
  "record.metadata.feature.catalog": "Feature catalog",
19734
19736
  "record.metadata.formats": "Formats",
19735
- "record.metadata.isGeographical": "Geographical dataset",
19737
+ "record.metadata.isGeographical": "geographic dataset",
19736
19738
  "record.metadata.keywords": "Keywords",
19737
19739
  "record.metadata.languages": "Languages",
19738
19740
  "record.metadata.link.postgis.table": "table :",
@@ -19922,7 +19924,7 @@ var en = {
19922
19924
  "wfs.feature.limit": "Too many features to display the WFS layer!",
19923
19925
  "wfs.featuretype.notfound": "No matching feature type was found in the service",
19924
19926
  "wfs.geojsongml.notsupported": "This service does not support the GeoJSON or GML format",
19925
- "wfs.unreachable.cors": "The service could not be reached due to CORS limitations",
19927
+ "wfs.unreachable.cors": "The remote service is not configured to allow data retrieval (CORS)",
19926
19928
  "wfs.unreachable.http": "The service returned an HTTP error",
19927
19929
  "wfs.unreachable.unknown": "The service could not be reached"
19928
19930
  };
@@ -20313,6 +20315,7 @@ var es = {
20313
20315
  "map.ogc.urlInput.hint": "",
20314
20316
  "map.select.layer": "",
20315
20317
  "map.select.style": "",
20318
+ "map.style.default": "Por defecto",
20316
20319
  "map.wfs.urlInput.hint": "",
20317
20320
  "map.wms.urlInput.hint": "",
20318
20321
  "multiselect.filter.placeholder": "",
@@ -20985,6 +20988,7 @@ var fr = {
20985
20988
  "map.ogc.urlInput.hint": "Entrez l'URL du service OGC API",
20986
20989
  "map.select.layer": "Source de données",
20987
20990
  "map.select.style": "Style",
20991
+ "map.style.default": "Par défaut",
20988
20992
  "map.wfs.urlInput.hint": "Entrez l'URL du service WFS",
20989
20993
  "map.wms.urlInput.hint": "Entrez l'URL du service WMS",
20990
20994
  "multiselect.filter.placeholder": "Rechercher",
@@ -21018,9 +21022,9 @@ var fr = {
21018
21022
  "record.feature.catalog.number.total.attribute": "Nombre total d'attributs",
21019
21023
  "record.feature.catalog.number.total.object": "Nombre total d'objets",
21020
21024
  "record.feature.limit": "L’aperçu a été désactivé en raison d’un trop grand nombre d'éléments",
21021
- "record.kind.dataset": "Donnée",
21022
- "record.kind.reuse": "Réutilisation",
21023
- "record.kind.service": "Service",
21025
+ "record.kind.dataset": "donnée",
21026
+ "record.kind.reuse": "réutilisation",
21027
+ "record.kind.service": "service",
21024
21028
  "record.metadata.about": "A propos",
21025
21029
  "record.metadata.api": "API",
21026
21030
  "record.metadata.api.accessServiceProtocol.GPFDL": "",
@@ -21076,7 +21080,7 @@ var fr = {
21076
21080
  "record.metadata.download": "Téléchargements",
21077
21081
  "record.metadata.feature.catalog": "Catalogue d'attributs",
21078
21082
  "record.metadata.formats": "Formats",
21079
- "record.metadata.isGeographical": "Donnée géographique",
21083
+ "record.metadata.isGeographical": "donnée géographique",
21080
21084
  "record.metadata.keywords": "Mots-clés",
21081
21085
  "record.metadata.languages": "Langues",
21082
21086
  "record.metadata.link.postgis.table": "table :",
@@ -21266,7 +21270,7 @@ var fr = {
21266
21270
  "wfs.feature.limit": "Trop d'objets pour afficher la couche WFS !",
21267
21271
  "wfs.featuretype.notfound": "La classe d'objets n'a pas été trouvée dans le service",
21268
21272
  "wfs.geojsongml.notsupported": "Le service ne supporte pas le format GeoJSON ou GML",
21269
- "wfs.unreachable.cors": "Le service n'est pas accessible en raison de limitations CORS",
21273
+ "wfs.unreachable.cors": "Le service distant n'est pas configuré pour autoriser la consommation des données (CORS)",
21270
21274
  "wfs.unreachable.http": "Le service a retourné une erreur HTTP",
21271
21275
  "wfs.unreachable.unknown": "Le service n'est pas accessible"
21272
21276
  };
@@ -21657,6 +21661,7 @@ var it = {
21657
21661
  "map.ogc.urlInput.hint": "Inserisci URL del servizio OGC API",
21658
21662
  "map.select.layer": "Sorgente dati",
21659
21663
  "map.select.style": "Style",
21664
+ "map.style.default": "Predefinito",
21660
21665
  "map.wfs.urlInput.hint": "Inserisci URL del servizio WFS",
21661
21666
  "map.wms.urlInput.hint": "Inserisci URL del servizio WMS",
21662
21667
  "multiselect.filter.placeholder": "Cerca",
@@ -21690,9 +21695,9 @@ var it = {
21690
21695
  "record.feature.catalog.number.total.attribute": "Quantità totale di oggetti",
21691
21696
  "record.feature.catalog.number.total.object": "Quantità totale di attributi",
21692
21697
  "record.feature.limit": "La visualizzazione è stata disabilitata a causa di troppi elementi ",
21693
- "record.kind.dataset": "Dataset",
21694
- "record.kind.reuse": "Riutilizzato",
21695
- "record.kind.service": "Servizio",
21698
+ "record.kind.dataset": "dataset",
21699
+ "record.kind.reuse": "riutilizzato",
21700
+ "record.kind.service": "servizio",
21696
21701
  "record.metadata.about": "Descrizione",
21697
21702
  "record.metadata.api": "API",
21698
21703
  "record.metadata.api.accessServiceProtocol.GPFDL": "",
@@ -21748,7 +21753,7 @@ var it = {
21748
21753
  "record.metadata.download": "Download",
21749
21754
  "record.metadata.feature.catalog": "Catalogo dei oggetti",
21750
21755
  "record.metadata.formats": "Formati",
21751
- "record.metadata.isGeographical": "Dati geografici",
21756
+ "record.metadata.isGeographical": "dati geografici",
21752
21757
  "record.metadata.keywords": "Parole chiave",
21753
21758
  "record.metadata.languages": "Lingue",
21754
21759
  "record.metadata.link.postgis.table": "",
@@ -21938,7 +21943,7 @@ var it = {
21938
21943
  "wfs.feature.limit": "Troppi oggetti per visualizzare il WFS layer!",
21939
21944
  "wfs.featuretype.notfound": "La classe di oggetto non è stata trovata nel servizio",
21940
21945
  "wfs.geojsongml.notsupported": "Il servizio non supporta il formato GeoJSON o GML",
21941
- "wfs.unreachable.cors": "Il servizio non è accessibile a causa di limitazioni CORS",
21946
+ "wfs.unreachable.cors": "Il servizio remoto non è configurato per consentire il consumo di dati (CORS)",
21942
21947
  "wfs.unreachable.http": "Il servizio ha restituito un errore HTTP",
21943
21948
  "wfs.unreachable.unknown": "Il servizio non è accessibile"
21944
21949
  };
@@ -22329,6 +22334,7 @@ var nl = {
22329
22334
  "map.ogc.urlInput.hint": "",
22330
22335
  "map.select.layer": "",
22331
22336
  "map.select.style": "",
22337
+ "map.style.default": "Standaard",
22332
22338
  "map.wfs.urlInput.hint": "",
22333
22339
  "map.wms.urlInput.hint": "",
22334
22340
  "multiselect.filter.placeholder": "",
@@ -23001,6 +23007,7 @@ var pt = {
23001
23007
  "map.ogc.urlInput.hint": "",
23002
23008
  "map.select.layer": "",
23003
23009
  "map.select.style": "",
23010
+ "map.style.default": "Padrão",
23004
23011
  "map.wfs.urlInput.hint": "",
23005
23012
  "map.wms.urlInput.hint": "",
23006
23013
  "multiselect.filter.placeholder": "",
@@ -23673,6 +23680,7 @@ var sk = {
23673
23680
  "map.ogc.urlInput.hint": "",
23674
23681
  "map.select.layer": "Zdroj dát",
23675
23682
  "map.select.style": "",
23683
+ "map.style.default": "Predvolené",
23676
23684
  "map.wfs.urlInput.hint": "Zadajte URL adresu služby WFS",
23677
23685
  "map.wms.urlInput.hint": "Zadajte URL adresu služby WMS",
23678
23686
  "multiselect.filter.placeholder": "Hľadať",
@@ -23954,7 +23962,7 @@ var sk = {
23954
23962
  "wfs.feature.limit": "",
23955
23963
  "wfs.featuretype.notfound": "V službe nebol nájdený žiadny zodpovedajúci typ funkcie",
23956
23964
  "wfs.geojsongml.notsupported": "Táto služba nepodporuje formát GeoJSON alebo GML",
23957
- "wfs.unreachable.cors": "Službu nemožno dosiahnuť z dôvodu obmedzení CORS",
23965
+ "wfs.unreachable.cors": "Vzdialená služba nie je nakonfigurovaná tak, aby povoľovala spotrebu dát (CORS)",
23958
23966
  "wfs.unreachable.http": "Služba vrátila chybu HTTP",
23959
23967
  "wfs.unreachable.unknown": "So službou sa nedalo spojiť"
23960
23968
  };
@@ -24528,34 +24536,23 @@ class ThemeService {
24528
24536
  static getColor(name) {
24529
24537
  return document.documentElement.style.getPropertyValue(`--color-${name}`);
24530
24538
  }
24531
- static generateBgOpacityClasses(colorName, colorValue, opacities = [0, 10, 25, 50, 75]) {
24532
- const color = chroma(colorValue);
24533
- const styleElement = document.createElement('style');
24534
- styleElement.innerHTML = opacities.reduce((cssRules, opacity) => {
24535
- cssRules += `.bg-${colorName}-opacity-${opacity}{background-color:${color
24536
- .alpha(opacity / 100)
24537
- .css()};}`;
24538
- cssRules += `.hover-bg-${colorName}-opacity-${opacity}:hover {background-color:${color
24539
- .alpha(opacity / 100)
24540
- .css()};}`;
24541
- return cssRules;
24542
- }, '');
24543
- document.getElementsByTagName('head')[0].appendChild(styleElement);
24544
- }
24545
24539
  static applyCssVariables(primaryColor, secondaryColor, mainColor, backgroundColor, mainFont, titleFont, fontsStylesheetUrl) {
24546
- const applyColor = (name, color) => {
24540
+ const applyColor = (name, color, includeRawValues) => {
24547
24541
  document.documentElement.style.setProperty(`--color-${name}`, color.css());
24542
+ if (includeRawValues) {
24543
+ document.documentElement.style.setProperty(`--color-raw-${name}`, color.css().replace(/^rgba?\((.*)\)/, '$1'));
24544
+ }
24548
24545
  };
24549
24546
  const black = chroma('black');
24550
24547
  const white = chroma('white');
24551
- applyColor('primary', chroma(primaryColor));
24548
+ applyColor('primary', chroma(primaryColor), true);
24552
24549
  applyColor('primary-lighter', chroma.scale([primaryColor, white]).mode('lab')(0.3));
24553
24550
  applyColor('primary-lightest', chroma.scale([primaryColor, white]).mode('lab')(0.6));
24554
24551
  applyColor('primary-white', chroma.scale([primaryColor, white]).mode('lab')(0.85));
24555
24552
  applyColor('primary-darker', chroma.scale([primaryColor, black]).mode('lab')(0.3));
24556
24553
  applyColor('primary-darkest', chroma.scale([primaryColor, black]).mode('lab')(0.6));
24557
24554
  applyColor('primary-black', chroma.scale([primaryColor, black]).mode('lab')(0.85));
24558
- applyColor('secondary', chroma(secondaryColor));
24555
+ applyColor('secondary', chroma(secondaryColor), true);
24559
24556
  applyColor('secondary-lighter', chroma.scale([secondaryColor, white]).mode('lab')(0.3));
24560
24557
  applyColor('secondary-lightest', chroma.scale([secondaryColor, white]).mode('lab')(0.6));
24561
24558
  applyColor('secondary-white', chroma.scale([secondaryColor, white]).mode('lab')(0.85));
@@ -25386,9 +25383,11 @@ async function getLayers(url, serviceProtocol) {
25386
25383
  case 'wfs': {
25387
25384
  const endpointWfs = await new WfsEndpoint(url).isReady();
25388
25385
  const featureTypes = await endpointWfs.getFeatureTypes();
25389
- const layers = await Promise.all(featureTypes.map(async (collection) => {
25390
- return await endpointWfs.getFeatureTypeFull(collection.name);
25391
- }));
25386
+ const layers = (await Promise.allSettled(featureTypes.map((collection) => {
25387
+ return endpointWfs.getFeatureTypeFull(collection.name);
25388
+ })))
25389
+ .filter((settled) => settled.status === 'fulfilled')
25390
+ .map((fulfilled) => fulfilled.value);
25392
25391
  return layers;
25393
25392
  }
25394
25393
  case 'wms': {
@@ -25519,7 +25518,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
25519
25518
  }] } });
25520
25519
 
25521
25520
  var name = "geonetwork-ui";
25522
- var version = "2.8.3-dev.a76ac18c6";
25521
+ var version = "2.9.0-dev.023c4f049";
25523
25522
  var engines = {
25524
25523
  node: ">=20"
25525
25524
  };
@@ -25559,11 +25558,11 @@ var peerDependencies = {
25559
25558
  };
25560
25559
  var dependencies = {
25561
25560
  "@biesbjerg/ngx-translate-extract-marker": "~1.0.0",
25562
- "@camptocamp/ogc-client": "1.3.1-dev.1d137ae",
25563
- "@geospatial-sdk/core": "0.0.5-dev.42",
25564
- "@geospatial-sdk/geocoding": "0.0.5-dev.42",
25565
- "@geospatial-sdk/legend": "0.0.5-dev.42",
25566
- "@geospatial-sdk/openlayers": "0.0.5-dev.42",
25561
+ "@camptocamp/ogc-client": "1.3.1-dev.12086e8",
25562
+ "@geospatial-sdk/core": "0.0.5-dev.61",
25563
+ "@geospatial-sdk/geocoding": "0.0.5-dev.61",
25564
+ "@geospatial-sdk/legend": "0.0.5-dev.61",
25565
+ "@geospatial-sdk/openlayers": "0.0.5-dev.61",
25567
25566
  "@ltd/j-toml": "~1.35.2",
25568
25567
  "@messageformat/core": "^3.0.1",
25569
25568
  "@ng-icons/core": "29.10.0",
@@ -25573,7 +25572,6 @@ var dependencies = {
25573
25572
  "@nx/angular": "22.0.4",
25574
25573
  "@rgrove/parse-xml": "4.2.0",
25575
25574
  alasql: "4.6.0",
25576
- axios: "1.12.0",
25577
25575
  basiclightbox: "^5.0.4",
25578
25576
  "chart.js": "4.4.7",
25579
25577
  "chroma-js": "3.1.2",
@@ -25589,7 +25587,7 @@ var dependencies = {
25589
25587
  "ngx-chips": "3.0.0",
25590
25588
  "ngx-dropzone": "3.1.0",
25591
25589
  "ngx-translate-messageformat-compiler": "~7.1.0",
25592
- ol: "^8.2.0",
25590
+ ol: "^10.0.0",
25593
25591
  papaparse: "5.4.1",
25594
25592
  pg: "^8.9.0",
25595
25593
  proj4: "^2.9.2",
@@ -25616,7 +25614,7 @@ var packageJson = {
25616
25614
 
25617
25615
  const GEONETWORK_UI_VERSION = packageJson.version;
25618
25616
  const GEONETWORK_UI_TAG_NAME = GEONETWORK_UI_VERSION.split('-')[1]?.startsWith('dev')
25619
- ? '2.8.x'
25617
+ ? 'main'
25620
25618
  : `v${packageJson.version}`;
25621
25619
 
25622
25620
  const ValidatorMapper = {
@@ -28177,8 +28175,9 @@ function getCustomTranslations(langCode) {
28177
28175
  return langCode in customTranslations ? customTranslations[langCode] : {};
28178
28176
  }
28179
28177
  let appConfigLoaded = false;
28180
- function loadAppConfig() {
28181
- return fetch('assets/configuration/default.toml')
28178
+ function loadAppConfig(configUrl = 'assets/configuration/default.toml') {
28179
+ console.log(`[geonetwork-ui] Loading application configuration from ${configUrl}`);
28180
+ return fetch(configUrl)
28182
28181
  .then((resp) => {
28183
28182
  if (!resp.ok)
28184
28183
  throw new Error('Configuration file could not be loaded');
@@ -28287,6 +28286,7 @@ function loadAppConfig() {
28287
28286
  'record_kind_quick_filter',
28288
28287
  'filter_geometry_data',
28289
28288
  'filter_geometry_url',
28289
+ 'do_not_use_default_search_preset',
28290
28290
  'search_preset',
28291
28291
  'advanced_filters',
28292
28292
  'limit',
@@ -28299,6 +28299,7 @@ function loadAppConfig() {
28299
28299
  RECORD_KIND_QUICK_FILTER: parsedSearchSection.record_kind_quick_filter,
28300
28300
  FILTER_GEOMETRY_DATA: parsedSearchSection.filter_geometry_data,
28301
28301
  FILTER_GEOMETRY_URL: parsedSearchSection.filter_geometry_url,
28302
+ DO_NOT_USE_DEFAULT_SEARCH_PRESET: !!parsedSearchSection.do_not_use_default_search_preset,
28302
28303
  SEARCH_PRESET: parsedSearchParams.map((param) => ({
28303
28304
  sort: param.sort,
28304
28305
  name: param.name,
@@ -28389,6 +28390,7 @@ fonts_stylesheet_url = "https://fonts.googleapis.com/css2?family=Open+Sans"
28389
28390
  [search]
28390
28391
  record_kind_quick_filter = false
28391
28392
  filter_geometry_url = 'https://my.domain.org/geom.json'
28393
+ do_not_use_default_search_preset = false
28392
28394
  advanced_filters = ['publicationYear', 'documentStandard', 'inspireKeyword', 'topic', 'license']
28393
28395
 
28394
28396
  [[search_preset]]
@@ -29915,7 +29917,7 @@ class DropdownSelectorComponent {
29915
29917
  return this.title.toLowerCase().replace(/[^a-z]+/g, '-');
29916
29918
  }
29917
29919
  getChoiceLabel() {
29918
- return this.selectedChoice?.label;
29920
+ return this.selectedChoice?.label ?? '\u00A0';
29919
29921
  }
29920
29922
  ngOnInit() {
29921
29923
  if (!this.maxRows)
@@ -32018,6 +32020,8 @@ function reducerSearch(state, action) {
32018
32020
  },
32019
32021
  };
32020
32022
  }
32023
+ // From router.effects
32024
+ // From home - fuzzy-search - search.service
32021
32025
  case SET_FILTERS: {
32022
32026
  return {
32023
32027
  ...state,
@@ -32039,6 +32043,7 @@ function reducerSearch(state, action) {
32039
32043
  },
32040
32044
  };
32041
32045
  }
32046
+ // From results WC
32042
32047
  case SET_SEARCH: {
32043
32048
  return {
32044
32049
  ...state,
@@ -33146,7 +33151,7 @@ class ApiCardComponent {
33146
33151
  }
33147
33152
  }
33148
33153
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ApiCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
33149
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ApiCardComponent, isStandalone: true, selector: "gn-ui-api-card", inputs: { link: "link", currentLink: "currentLink", size: "size" }, outputs: { openRecordApiForm: "openRecordApiForm" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"group flex justify-between rounded filter overflow-hidden card-shadow\"\n [ngClass]=\"cardClass\"\n>\n @if (size !== 'S') {\n <div class=\"flex-1 min-w-0\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </div>\n <div class=\"flex items-center min-w-[32px]\">\n <ng-container *ngTemplateOutlet=\"buttons\"></ng-container>\n </div>\n }\n @if (size === 'S') {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n }\n</div>\n\n<ng-template #buttons>\n <div class=\"flex flex-row gap-2\">\n <gn-ui-copy-text-button\n [text]=\"link.url\"\n [tooltipText]=\"'tooltip.url.copy' | translate\"\n [displayText]=\"false\"\n class=\"border border-gray-300 rounded-lg pt-1 px-2 h-[34px]\"\n ></gn-ui-copy-text-button>\n @if (displayApiFormButton) {\n <button\n type=\"button\"\n class=\"gn-ui-card-icon\"\n [ngClass]=\"{\n 'py-2 px-4 rounded-r-md bg-gray-400 hover:bg-gray-600 focus:bg-gray-800 text-white':\n displayText,\n }\"\n [matTooltip]=\"\n !currentlyActive\n ? ('record.metadata.api.form.openForm' | translate)\n : ('record.metadata.api.form.closeForm' | translate)\n \"\n matTooltipPosition=\"above\"\n (click)=\"openRecordApiFormPanel()\"\n >\n <ng-icon\n class=\"pointer-events-none align-middle card-icon\"\n name=\"iconoirSettings\"\n [ngClass]=\"{\n 'text-secondary opacity-100': currentlyActive,\n }\"\n ></ng-icon>\n </button>\n }\n </div>\n</ng-template>\n\n<ng-template #content>\n <div class=\"flex-1 min-w-0\">\n <div class=\"gn-ui-card-title\">\n {{ link.description || link.name }}\n </div>\n <div class=\"gn-ui-card-detail\">\n {{ link.name }}\n </div>\n </div>\n <div class=\"flex flex-row justify-between\">\n <div class=\"flex flex-row gap-2.5 items-center pt-1\">\n @if (link.accessServiceProtocol !== 'GPFDL') {\n <span\n class=\"bg-primary-opacity-50 uppercase inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded text-primary-lightest group-hover:bg-primary transition-colors\"\n [ngClass]=\"{\n '!bg-primary': currentlyActive,\n }\"\n translate\n >record.metadata.api.accessServiceProtocol.{{\n link.accessServiceProtocol\n }}</span\n >\n }\n @if (link.accessServiceProtocol === 'GPFDL') {\n <span\n class=\"bg-primary-opacity-50 uppercase inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded text-primary-lightest group-hover:bg-primary transition-colors\"\n [ngClass]=\"{\n '!bg-primary': currentlyActive,\n }\"\n translate\n >\n record.metadata.api.gpfdl</span\n >\n }\n </div>\n @if (size === 'S') {\n <div>\n <ng-container *ngTemplateOutlet=\"buttons\"></ng-container>\n </div>\n }\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CopyTextButtonComponent, selector: "gn-ui-copy-text-button", inputs: ["text", "tooltipText", "displayText", "rows"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { 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: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], viewProviders: [
33154
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ApiCardComponent, isStandalone: true, selector: "gn-ui-api-card", inputs: { link: "link", currentLink: "currentLink", size: "size" }, outputs: { openRecordApiForm: "openRecordApiForm" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"group flex justify-between rounded filter overflow-hidden card-shadow\"\n [ngClass]=\"cardClass\"\n>\n @if (size !== 'S') {\n <div class=\"flex-1 min-w-0\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </div>\n <div class=\"flex items-center min-w-[32px]\">\n <ng-container *ngTemplateOutlet=\"buttons\"></ng-container>\n </div>\n }\n @if (size === 'S') {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n }\n</div>\n\n<ng-template #buttons>\n <div class=\"flex flex-row gap-2\">\n <gn-ui-copy-text-button\n [text]=\"link.url\"\n [tooltipText]=\"'tooltip.url.copy' | translate\"\n [displayText]=\"false\"\n class=\"border border-gray-300 rounded-lg pt-1 px-2 h-[34px]\"\n ></gn-ui-copy-text-button>\n @if (displayApiFormButton) {\n <button\n type=\"button\"\n class=\"gn-ui-card-icon\"\n [ngClass]=\"{\n 'py-2 px-4 rounded-r-md bg-gray-400 hover:bg-gray-600 focus:bg-gray-800 text-white':\n displayText,\n }\"\n [matTooltip]=\"\n !currentlyActive\n ? ('record.metadata.api.form.openForm' | translate)\n : ('record.metadata.api.form.closeForm' | translate)\n \"\n matTooltipPosition=\"above\"\n (click)=\"openRecordApiFormPanel()\"\n >\n <ng-icon\n class=\"pointer-events-none align-middle card-icon\"\n name=\"iconoirSettings\"\n [ngClass]=\"{\n 'text-secondary opacity-100': currentlyActive,\n }\"\n ></ng-icon>\n </button>\n }\n </div>\n</ng-template>\n\n<ng-template #content>\n <div class=\"flex-1 min-w-0\">\n <div class=\"gn-ui-card-title\">\n {{ link.description || link.name }}\n </div>\n <div class=\"gn-ui-card-detail\">\n {{ link.name }}\n </div>\n </div>\n <div class=\"flex flex-row justify-between\">\n <div class=\"flex flex-row gap-2.5 items-center pt-1\">\n @if (link.accessServiceProtocol !== 'GPFDL') {\n <span\n class=\"bg-primary/50 uppercase inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded text-primary-lightest group-hover:bg-primary transition-colors\"\n [ngClass]=\"{\n '!bg-primary': currentlyActive,\n }\"\n translate\n >record.metadata.api.accessServiceProtocol.{{\n link.accessServiceProtocol\n }}</span\n >\n }\n @if (link.accessServiceProtocol === 'GPFDL') {\n <span\n class=\"bg-primary/50 uppercase inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded text-primary-lightest group-hover:bg-primary transition-colors\"\n [ngClass]=\"{\n '!bg-primary': currentlyActive,\n }\"\n translate\n >\n record.metadata.api.gpfdl</span\n >\n }\n </div>\n @if (size === 'S') {\n <div>\n <ng-container *ngTemplateOutlet=\"buttons\"></ng-container>\n </div>\n }\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CopyTextButtonComponent, selector: "gn-ui-copy-text-button", inputs: ["text", "tooltipText", "displayText", "rows"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { 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: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], viewProviders: [
33150
33155
  provideIcons({
33151
33156
  iconoirSettings,
33152
33157
  }),
@@ -33171,7 +33176,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
33171
33176
  provideNgIconsConfig({
33172
33177
  size: '1.5em',
33173
33178
  }),
33174
- ], template: "<div\n class=\"group flex justify-between rounded filter overflow-hidden card-shadow\"\n [ngClass]=\"cardClass\"\n>\n @if (size !== 'S') {\n <div class=\"flex-1 min-w-0\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </div>\n <div class=\"flex items-center min-w-[32px]\">\n <ng-container *ngTemplateOutlet=\"buttons\"></ng-container>\n </div>\n }\n @if (size === 'S') {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n }\n</div>\n\n<ng-template #buttons>\n <div class=\"flex flex-row gap-2\">\n <gn-ui-copy-text-button\n [text]=\"link.url\"\n [tooltipText]=\"'tooltip.url.copy' | translate\"\n [displayText]=\"false\"\n class=\"border border-gray-300 rounded-lg pt-1 px-2 h-[34px]\"\n ></gn-ui-copy-text-button>\n @if (displayApiFormButton) {\n <button\n type=\"button\"\n class=\"gn-ui-card-icon\"\n [ngClass]=\"{\n 'py-2 px-4 rounded-r-md bg-gray-400 hover:bg-gray-600 focus:bg-gray-800 text-white':\n displayText,\n }\"\n [matTooltip]=\"\n !currentlyActive\n ? ('record.metadata.api.form.openForm' | translate)\n : ('record.metadata.api.form.closeForm' | translate)\n \"\n matTooltipPosition=\"above\"\n (click)=\"openRecordApiFormPanel()\"\n >\n <ng-icon\n class=\"pointer-events-none align-middle card-icon\"\n name=\"iconoirSettings\"\n [ngClass]=\"{\n 'text-secondary opacity-100': currentlyActive,\n }\"\n ></ng-icon>\n </button>\n }\n </div>\n</ng-template>\n\n<ng-template #content>\n <div class=\"flex-1 min-w-0\">\n <div class=\"gn-ui-card-title\">\n {{ link.description || link.name }}\n </div>\n <div class=\"gn-ui-card-detail\">\n {{ link.name }}\n </div>\n </div>\n <div class=\"flex flex-row justify-between\">\n <div class=\"flex flex-row gap-2.5 items-center pt-1\">\n @if (link.accessServiceProtocol !== 'GPFDL') {\n <span\n class=\"bg-primary-opacity-50 uppercase inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded text-primary-lightest group-hover:bg-primary transition-colors\"\n [ngClass]=\"{\n '!bg-primary': currentlyActive,\n }\"\n translate\n >record.metadata.api.accessServiceProtocol.{{\n link.accessServiceProtocol\n }}</span\n >\n }\n @if (link.accessServiceProtocol === 'GPFDL') {\n <span\n class=\"bg-primary-opacity-50 uppercase inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded text-primary-lightest group-hover:bg-primary transition-colors\"\n [ngClass]=\"{\n '!bg-primary': currentlyActive,\n }\"\n translate\n >\n record.metadata.api.gpfdl</span\n >\n }\n </div>\n @if (size === 'S') {\n <div>\n <ng-container *ngTemplateOutlet=\"buttons\"></ng-container>\n </div>\n }\n </div>\n</ng-template>\n" }]
33179
+ ], template: "<div\n class=\"group flex justify-between rounded filter overflow-hidden card-shadow\"\n [ngClass]=\"cardClass\"\n>\n @if (size !== 'S') {\n <div class=\"flex-1 min-w-0\">\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n </div>\n <div class=\"flex items-center min-w-[32px]\">\n <ng-container *ngTemplateOutlet=\"buttons\"></ng-container>\n </div>\n }\n @if (size === 'S') {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n }\n</div>\n\n<ng-template #buttons>\n <div class=\"flex flex-row gap-2\">\n <gn-ui-copy-text-button\n [text]=\"link.url\"\n [tooltipText]=\"'tooltip.url.copy' | translate\"\n [displayText]=\"false\"\n class=\"border border-gray-300 rounded-lg pt-1 px-2 h-[34px]\"\n ></gn-ui-copy-text-button>\n @if (displayApiFormButton) {\n <button\n type=\"button\"\n class=\"gn-ui-card-icon\"\n [ngClass]=\"{\n 'py-2 px-4 rounded-r-md bg-gray-400 hover:bg-gray-600 focus:bg-gray-800 text-white':\n displayText,\n }\"\n [matTooltip]=\"\n !currentlyActive\n ? ('record.metadata.api.form.openForm' | translate)\n : ('record.metadata.api.form.closeForm' | translate)\n \"\n matTooltipPosition=\"above\"\n (click)=\"openRecordApiFormPanel()\"\n >\n <ng-icon\n class=\"pointer-events-none align-middle card-icon\"\n name=\"iconoirSettings\"\n [ngClass]=\"{\n 'text-secondary opacity-100': currentlyActive,\n }\"\n ></ng-icon>\n </button>\n }\n </div>\n</ng-template>\n\n<ng-template #content>\n <div class=\"flex-1 min-w-0\">\n <div class=\"gn-ui-card-title\">\n {{ link.description || link.name }}\n </div>\n <div class=\"gn-ui-card-detail\">\n {{ link.name }}\n </div>\n </div>\n <div class=\"flex flex-row justify-between\">\n <div class=\"flex flex-row gap-2.5 items-center pt-1\">\n @if (link.accessServiceProtocol !== 'GPFDL') {\n <span\n class=\"bg-primary/50 uppercase inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded text-primary-lightest group-hover:bg-primary transition-colors\"\n [ngClass]=\"{\n '!bg-primary': currentlyActive,\n }\"\n translate\n >record.metadata.api.accessServiceProtocol.{{\n link.accessServiceProtocol\n }}</span\n >\n }\n @if (link.accessServiceProtocol === 'GPFDL') {\n <span\n class=\"bg-primary/50 uppercase inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded text-primary-lightest group-hover:bg-primary transition-colors\"\n [ngClass]=\"{\n '!bg-primary': currentlyActive,\n }\"\n translate\n >\n record.metadata.api.gpfdl</span\n >\n }\n </div>\n @if (size === 'S') {\n <div>\n <ng-container *ngTemplateOutlet=\"buttons\"></ng-container>\n </div>\n }\n </div>\n</ng-template>\n" }]
33175
33180
  }], propDecorators: { link: [{
33176
33181
  type: Input
33177
33182
  }], currentLink: [{
@@ -33310,10 +33315,12 @@ class DownloadsListComponent {
33310
33315
  }
33311
33316
  removeDuplicateFormats(links) {
33312
33317
  const preferredLinks = new Map();
33313
- links.forEach((link) => {
33318
+ links.forEach((link, index) => {
33314
33319
  const format = getFileFormat(link);
33315
33320
  const withoutNameSpace = (link.name || link.description || '').replace(/^.*?:/, '');
33316
- const uniqueKey = `${format}-${withoutNameSpace}`;
33321
+ const uniqueKey = link.accessServiceProtocol
33322
+ ? `${format}-${withoutNameSpace}`
33323
+ : index.toString(); // direct download links should not be deduplicated
33317
33324
  if (!preferredLinks.has(uniqueKey)) {
33318
33325
  preferredLinks.set(uniqueKey, link);
33319
33326
  }
@@ -33773,7 +33780,7 @@ class ImageInputComponent {
33773
33780
  provideNgIconsConfig({
33774
33781
  size: '1.5rem',
33775
33782
  }),
33776
- ], ngImport: i0, template: "@if (previewUrl) {\n <div class=\"w-80 h-full flex flex-col gap-2\">\n <gn-ui-image-overlay-preview class=\"h-48\" [imageUrl]=\"previewUrl\">\n </gn-ui-image-overlay-preview>\n @if (showAltTextInput) {\n <gn-ui-text-input\n [placeholder]=\"'input.image.altTextPlaceholder' | translate\"\n [value]=\"altText ?? ''\"\n (valueChange)=\"handleAltTextChange($event)\"\n extraClass=\"gn-ui-editor-textarea\"\n ></gn-ui-text-input>\n }\n <div class=\"flex flex-row gap-2 mt-2\">\n <gn-ui-button\n type=\"gray\"\n (buttonClick)=\"handleDelete()\"\n data-cy=\"delete-image\"\n >\n <ng-icon class=\"me-1 text-primary\" name=\"iconoirBin\"></ng-icon>\n {{ 'input.image.delete' | translate }}\n </gn-ui-button>\n @if (!showAltTextInput) {\n <gn-ui-button type=\"gray\" (buttonClick)=\"toggleAltTextInput()\">\n <ng-icon name=\"iconoirPlus\" class=\"me-1 text-primary\"></ng-icon>\n {{ 'input.image.displayAltTextInput' | translate }}\n </gn-ui-button>\n }\n </div>\n </div>\n} @else {\n <div class=\"w-full h-full flex flex-col gap-2\">\n <label\n gnUiFilesDrop\n class=\"flex-1 border-2 border-dashed rounded-lg p-6 flex flex-col items-center justify-center gap-4 transition-colors duration-100\"\n [ngClass]=\"{\n 'border-primary-lighter bg-primary-white': dragFilesOver,\n 'border-gray-300': !dragFilesOver,\n 'cursor-pointer hover:border-gray-500': !getIsActionBlocked(),\n 'cursor-not-allowed': disabled,\n }\"\n [attr.tabindex]=\"getIsActionBlocked() ? null : 0\"\n (keydown.enter)=\"fileInput.click()\"\n (dragFilesOver)=\"handleDragFilesOver($event)\"\n (dropFiles)=\"handleDropFiles($event)\"\n >\n @if (!isUploadInProgress && !imageFileError) {\n <div class=\"w-14 h-14 rounded-md bg-gray-50 grid\">\n @if (!dragFilesOver) {\n <ng-icon\n class=\"place-self-center text-primary\"\n name=\"iconoirMediaImage\"\n ></ng-icon>\n }\n @if (dragFilesOver) {\n <ng-icon\n class=\"place-self-center text-primary\"\n name=\"iconoirFramePlusIn\"\n ></ng-icon>\n }\n </div>\n }\n @if (isUploadInProgress && !imageFileError) {\n <div class=\"w-14 h-14 grid items-center justify-center relative\">\n <div class=\"text-gray-100 absolute\">\n <mat-progress-spinner\n class=\"place-self-center\"\n [diameter]=\"56\"\n mode=\"determinate\"\n [value]=\"100\"\n ></mat-progress-spinner>\n </div>\n <div class=\"text-primary absolute\">\n <mat-progress-spinner\n class=\"place-self-center\"\n [diameter]=\"56\"\n mode=\"determinate\"\n [value]=\"uploadProgress\"\n ></mat-progress-spinner>\n </div>\n <span class=\"text-sm text-main font-bold\">{{ uploadProgress }}%</span>\n </div>\n }\n @if (imageFileError) {\n <div class=\"w-14 h-14 rounded-md bg-gray-50 grid\">\n <ng-icon\n name=\"iconoirMediaImageXmark\"\n class=\"place-self-center text-rose-500\"\n data-cy=\"imgErrorIcon\"\n ></ng-icon>\n </div>\n }\n <div class=\"flex flex-col items-center gap-1\">\n <p class=\"font-medium\" data-cy=\"imgInputMsgPrimary\">\n {{ getPrimaryText() | translate }}\n </p>\n <p\n class=\"text-sm\"\n data-cy=\"imgInputMsgSecondary\"\n [class]=\"\n isUploadInProgress\n ? 'font-bold text-blue-500 cursor-pointer'\n : 'font-medium text-gray-500'\n \"\n (click)=\"handleSecondaryTextClick($event)\"\n >\n {{ getSecondaryText() | translate }}\n </p>\n </div>\n <input\n #fileInput\n accept=\"image/*\"\n type=\"file\"\n class=\"hidden\"\n (change)=\"handleFileInput($event)\"\n [disabled]=\"isUploadInProgress || disabled\"\n />\n </label>\n @if (!showUrlInput) {\n <div class=\"flex-none mt-2\">\n <gn-ui-button\n data-cy=\"imgUrlBtn\"\n (buttonClick)=\"displayUrlInput()\"\n type=\"gray\"\n [disabled]=\"disabled\"\n [extraClass]=\"disabled && 'cursor-not-allowed'\"\n >\n <ng-icon class=\"me-1 text-primary\" name=\"iconoirLink\"></ng-icon>\n {{ 'input.image.displayUrlInput' | translate }}\n </gn-ui-button>\n </div>\n }\n @if (showUrlInput) {\n <gn-ui-url-input\n class=\"mt-3.5\"\n data-cy=\"imgUrlInput\"\n (uploadClick)=\"downloadUrl($event)\"\n [disabled]=\"isUploadInProgress || disabled\"\n >\n </gn-ui-url-input>\n }\n </div>\n}\n", styles: [":host{--gn-ui-button-padding: 8px 8px;--gn-ui-button-rounded: 8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "directive", type: FilesDropDirective, selector: "[gnUiFilesDrop]", outputs: ["dragFilesOver", "dropFiles"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: UrlInputComponent, selector: "gn-ui-url-input", inputs: ["value", "extraClass", "placeholder", "disabled", "showValidateButton", "resetUrlOnChange"], outputs: ["valueChange", "uploadClick"] }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "placeholder", "required", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: ImageOverlayPreviewComponent, selector: "gn-ui-image-overlay-preview", inputs: ["imageUrl"], outputs: ["isPlaceholderShown"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33783
+ ], ngImport: i0, template: "@if (previewUrl) {\n <div class=\"w-[314px] h-full flex flex-col gap-2\">\n <gn-ui-image-overlay-preview\n class=\"w-[314px] h-[314px]\"\n [imageUrl]=\"previewUrl\"\n >\n </gn-ui-image-overlay-preview>\n @if (showAltTextInput) {\n <gn-ui-text-input\n [placeholder]=\"'input.image.altTextPlaceholder' | translate\"\n [value]=\"altText ?? ''\"\n (valueChange)=\"handleAltTextChange($event)\"\n extraClass=\"gn-ui-editor-textarea\"\n ></gn-ui-text-input>\n }\n <div class=\"flex flex-row gap-2 mt-2\">\n <gn-ui-button\n type=\"gray\"\n (buttonClick)=\"handleDelete()\"\n data-cy=\"delete-image\"\n >\n <ng-icon class=\"me-1 text-primary\" name=\"iconoirBin\"></ng-icon>\n {{ 'input.image.delete' | translate }}\n </gn-ui-button>\n @if (!showAltTextInput) {\n <gn-ui-button type=\"gray\" (buttonClick)=\"toggleAltTextInput()\">\n <ng-icon name=\"iconoirPlus\" class=\"me-1 text-primary\"></ng-icon>\n {{ 'input.image.displayAltTextInput' | translate }}\n </gn-ui-button>\n }\n </div>\n </div>\n} @else {\n <div class=\"w-full h-full flex flex-col gap-2\">\n <label\n gnUiFilesDrop\n class=\"flex-1 border-2 border-dashed rounded-lg p-6 flex flex-col items-center justify-center gap-4 transition-colors duration-100\"\n [ngClass]=\"{\n 'border-primary-lighter bg-primary-white': dragFilesOver,\n 'border-gray-300': !dragFilesOver,\n 'cursor-pointer hover:border-gray-500': !getIsActionBlocked(),\n 'cursor-not-allowed': disabled,\n }\"\n [attr.tabindex]=\"getIsActionBlocked() ? null : 0\"\n (keydown.enter)=\"fileInput.click()\"\n (dragFilesOver)=\"handleDragFilesOver($event)\"\n (dropFiles)=\"handleDropFiles($event)\"\n >\n @if (!isUploadInProgress && !imageFileError) {\n <div class=\"w-14 h-14 rounded-md bg-gray-50 grid\">\n @if (!dragFilesOver) {\n <ng-icon\n class=\"place-self-center text-primary\"\n name=\"iconoirMediaImage\"\n ></ng-icon>\n }\n @if (dragFilesOver) {\n <ng-icon\n class=\"place-self-center text-primary\"\n name=\"iconoirFramePlusIn\"\n ></ng-icon>\n }\n </div>\n }\n @if (isUploadInProgress && !imageFileError) {\n <div class=\"w-14 h-14 grid items-center justify-center relative\">\n <div class=\"text-gray-100 absolute\">\n <mat-progress-spinner\n class=\"place-self-center\"\n [diameter]=\"56\"\n mode=\"determinate\"\n [value]=\"100\"\n ></mat-progress-spinner>\n </div>\n <div class=\"text-primary absolute\">\n <mat-progress-spinner\n class=\"place-self-center\"\n [diameter]=\"56\"\n mode=\"determinate\"\n [value]=\"uploadProgress\"\n ></mat-progress-spinner>\n </div>\n <span class=\"text-sm text-main font-bold\">{{ uploadProgress }}%</span>\n </div>\n }\n @if (imageFileError) {\n <div class=\"w-14 h-14 rounded-md bg-gray-50 grid\">\n <ng-icon\n name=\"iconoirMediaImageXmark\"\n class=\"place-self-center text-rose-500\"\n data-cy=\"imgErrorIcon\"\n ></ng-icon>\n </div>\n }\n <div class=\"flex flex-col items-center gap-1\">\n <p class=\"font-medium\" data-cy=\"imgInputMsgPrimary\">\n {{ getPrimaryText() | translate }}\n </p>\n <p\n class=\"text-sm\"\n data-cy=\"imgInputMsgSecondary\"\n [class]=\"\n isUploadInProgress\n ? 'font-bold text-blue-500 cursor-pointer'\n : 'font-medium text-gray-500'\n \"\n (click)=\"handleSecondaryTextClick($event)\"\n >\n {{ getSecondaryText() | translate }}\n </p>\n </div>\n <input\n #fileInput\n accept=\"image/*\"\n type=\"file\"\n class=\"hidden\"\n (change)=\"handleFileInput($event)\"\n [disabled]=\"isUploadInProgress || disabled\"\n />\n </label>\n @if (!showUrlInput) {\n <div class=\"flex-none mt-2\">\n <gn-ui-button\n data-cy=\"imgUrlBtn\"\n (buttonClick)=\"displayUrlInput()\"\n type=\"gray\"\n [disabled]=\"disabled\"\n [extraClass]=\"disabled && 'cursor-not-allowed'\"\n >\n <ng-icon class=\"me-1 text-primary\" name=\"iconoirLink\"></ng-icon>\n {{ 'input.image.displayUrlInput' | translate }}\n </gn-ui-button>\n </div>\n }\n @if (showUrlInput) {\n <gn-ui-url-input\n class=\"mt-3.5\"\n data-cy=\"imgUrlInput\"\n (uploadClick)=\"downloadUrl($event)\"\n [disabled]=\"isUploadInProgress || disabled\"\n >\n </gn-ui-url-input>\n }\n </div>\n}\n", styles: [":host{--gn-ui-button-padding: 8px 8px;--gn-ui-button-rounded: 8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "directive", type: FilesDropDirective, selector: "[gnUiFilesDrop]", outputs: ["dragFilesOver", "dropFiles"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: UrlInputComponent, selector: "gn-ui-url-input", inputs: ["value", "extraClass", "placeholder", "disabled", "showValidateButton", "resetUrlOnChange"], outputs: ["valueChange", "uploadClick"] }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "placeholder", "required", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: ImageOverlayPreviewComponent, selector: "gn-ui-image-overlay-preview", inputs: ["imageUrl"], outputs: ["isPlaceholderShown"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
33777
33784
  }
33778
33785
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ImageInputComponent, decorators: [{
33779
33786
  type: Component,
@@ -33799,7 +33806,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
33799
33806
  provideNgIconsConfig({
33800
33807
  size: '1.5rem',
33801
33808
  }),
33802
- ], template: "@if (previewUrl) {\n <div class=\"w-80 h-full flex flex-col gap-2\">\n <gn-ui-image-overlay-preview class=\"h-48\" [imageUrl]=\"previewUrl\">\n </gn-ui-image-overlay-preview>\n @if (showAltTextInput) {\n <gn-ui-text-input\n [placeholder]=\"'input.image.altTextPlaceholder' | translate\"\n [value]=\"altText ?? ''\"\n (valueChange)=\"handleAltTextChange($event)\"\n extraClass=\"gn-ui-editor-textarea\"\n ></gn-ui-text-input>\n }\n <div class=\"flex flex-row gap-2 mt-2\">\n <gn-ui-button\n type=\"gray\"\n (buttonClick)=\"handleDelete()\"\n data-cy=\"delete-image\"\n >\n <ng-icon class=\"me-1 text-primary\" name=\"iconoirBin\"></ng-icon>\n {{ 'input.image.delete' | translate }}\n </gn-ui-button>\n @if (!showAltTextInput) {\n <gn-ui-button type=\"gray\" (buttonClick)=\"toggleAltTextInput()\">\n <ng-icon name=\"iconoirPlus\" class=\"me-1 text-primary\"></ng-icon>\n {{ 'input.image.displayAltTextInput' | translate }}\n </gn-ui-button>\n }\n </div>\n </div>\n} @else {\n <div class=\"w-full h-full flex flex-col gap-2\">\n <label\n gnUiFilesDrop\n class=\"flex-1 border-2 border-dashed rounded-lg p-6 flex flex-col items-center justify-center gap-4 transition-colors duration-100\"\n [ngClass]=\"{\n 'border-primary-lighter bg-primary-white': dragFilesOver,\n 'border-gray-300': !dragFilesOver,\n 'cursor-pointer hover:border-gray-500': !getIsActionBlocked(),\n 'cursor-not-allowed': disabled,\n }\"\n [attr.tabindex]=\"getIsActionBlocked() ? null : 0\"\n (keydown.enter)=\"fileInput.click()\"\n (dragFilesOver)=\"handleDragFilesOver($event)\"\n (dropFiles)=\"handleDropFiles($event)\"\n >\n @if (!isUploadInProgress && !imageFileError) {\n <div class=\"w-14 h-14 rounded-md bg-gray-50 grid\">\n @if (!dragFilesOver) {\n <ng-icon\n class=\"place-self-center text-primary\"\n name=\"iconoirMediaImage\"\n ></ng-icon>\n }\n @if (dragFilesOver) {\n <ng-icon\n class=\"place-self-center text-primary\"\n name=\"iconoirFramePlusIn\"\n ></ng-icon>\n }\n </div>\n }\n @if (isUploadInProgress && !imageFileError) {\n <div class=\"w-14 h-14 grid items-center justify-center relative\">\n <div class=\"text-gray-100 absolute\">\n <mat-progress-spinner\n class=\"place-self-center\"\n [diameter]=\"56\"\n mode=\"determinate\"\n [value]=\"100\"\n ></mat-progress-spinner>\n </div>\n <div class=\"text-primary absolute\">\n <mat-progress-spinner\n class=\"place-self-center\"\n [diameter]=\"56\"\n mode=\"determinate\"\n [value]=\"uploadProgress\"\n ></mat-progress-spinner>\n </div>\n <span class=\"text-sm text-main font-bold\">{{ uploadProgress }}%</span>\n </div>\n }\n @if (imageFileError) {\n <div class=\"w-14 h-14 rounded-md bg-gray-50 grid\">\n <ng-icon\n name=\"iconoirMediaImageXmark\"\n class=\"place-self-center text-rose-500\"\n data-cy=\"imgErrorIcon\"\n ></ng-icon>\n </div>\n }\n <div class=\"flex flex-col items-center gap-1\">\n <p class=\"font-medium\" data-cy=\"imgInputMsgPrimary\">\n {{ getPrimaryText() | translate }}\n </p>\n <p\n class=\"text-sm\"\n data-cy=\"imgInputMsgSecondary\"\n [class]=\"\n isUploadInProgress\n ? 'font-bold text-blue-500 cursor-pointer'\n : 'font-medium text-gray-500'\n \"\n (click)=\"handleSecondaryTextClick($event)\"\n >\n {{ getSecondaryText() | translate }}\n </p>\n </div>\n <input\n #fileInput\n accept=\"image/*\"\n type=\"file\"\n class=\"hidden\"\n (change)=\"handleFileInput($event)\"\n [disabled]=\"isUploadInProgress || disabled\"\n />\n </label>\n @if (!showUrlInput) {\n <div class=\"flex-none mt-2\">\n <gn-ui-button\n data-cy=\"imgUrlBtn\"\n (buttonClick)=\"displayUrlInput()\"\n type=\"gray\"\n [disabled]=\"disabled\"\n [extraClass]=\"disabled && 'cursor-not-allowed'\"\n >\n <ng-icon class=\"me-1 text-primary\" name=\"iconoirLink\"></ng-icon>\n {{ 'input.image.displayUrlInput' | translate }}\n </gn-ui-button>\n </div>\n }\n @if (showUrlInput) {\n <gn-ui-url-input\n class=\"mt-3.5\"\n data-cy=\"imgUrlInput\"\n (uploadClick)=\"downloadUrl($event)\"\n [disabled]=\"isUploadInProgress || disabled\"\n >\n </gn-ui-url-input>\n }\n </div>\n}\n", styles: [":host{--gn-ui-button-padding: 8px 8px;--gn-ui-button-rounded: 8px}\n"] }]
33809
+ ], template: "@if (previewUrl) {\n <div class=\"w-[314px] h-full flex flex-col gap-2\">\n <gn-ui-image-overlay-preview\n class=\"w-[314px] h-[314px]\"\n [imageUrl]=\"previewUrl\"\n >\n </gn-ui-image-overlay-preview>\n @if (showAltTextInput) {\n <gn-ui-text-input\n [placeholder]=\"'input.image.altTextPlaceholder' | translate\"\n [value]=\"altText ?? ''\"\n (valueChange)=\"handleAltTextChange($event)\"\n extraClass=\"gn-ui-editor-textarea\"\n ></gn-ui-text-input>\n }\n <div class=\"flex flex-row gap-2 mt-2\">\n <gn-ui-button\n type=\"gray\"\n (buttonClick)=\"handleDelete()\"\n data-cy=\"delete-image\"\n >\n <ng-icon class=\"me-1 text-primary\" name=\"iconoirBin\"></ng-icon>\n {{ 'input.image.delete' | translate }}\n </gn-ui-button>\n @if (!showAltTextInput) {\n <gn-ui-button type=\"gray\" (buttonClick)=\"toggleAltTextInput()\">\n <ng-icon name=\"iconoirPlus\" class=\"me-1 text-primary\"></ng-icon>\n {{ 'input.image.displayAltTextInput' | translate }}\n </gn-ui-button>\n }\n </div>\n </div>\n} @else {\n <div class=\"w-full h-full flex flex-col gap-2\">\n <label\n gnUiFilesDrop\n class=\"flex-1 border-2 border-dashed rounded-lg p-6 flex flex-col items-center justify-center gap-4 transition-colors duration-100\"\n [ngClass]=\"{\n 'border-primary-lighter bg-primary-white': dragFilesOver,\n 'border-gray-300': !dragFilesOver,\n 'cursor-pointer hover:border-gray-500': !getIsActionBlocked(),\n 'cursor-not-allowed': disabled,\n }\"\n [attr.tabindex]=\"getIsActionBlocked() ? null : 0\"\n (keydown.enter)=\"fileInput.click()\"\n (dragFilesOver)=\"handleDragFilesOver($event)\"\n (dropFiles)=\"handleDropFiles($event)\"\n >\n @if (!isUploadInProgress && !imageFileError) {\n <div class=\"w-14 h-14 rounded-md bg-gray-50 grid\">\n @if (!dragFilesOver) {\n <ng-icon\n class=\"place-self-center text-primary\"\n name=\"iconoirMediaImage\"\n ></ng-icon>\n }\n @if (dragFilesOver) {\n <ng-icon\n class=\"place-self-center text-primary\"\n name=\"iconoirFramePlusIn\"\n ></ng-icon>\n }\n </div>\n }\n @if (isUploadInProgress && !imageFileError) {\n <div class=\"w-14 h-14 grid items-center justify-center relative\">\n <div class=\"text-gray-100 absolute\">\n <mat-progress-spinner\n class=\"place-self-center\"\n [diameter]=\"56\"\n mode=\"determinate\"\n [value]=\"100\"\n ></mat-progress-spinner>\n </div>\n <div class=\"text-primary absolute\">\n <mat-progress-spinner\n class=\"place-self-center\"\n [diameter]=\"56\"\n mode=\"determinate\"\n [value]=\"uploadProgress\"\n ></mat-progress-spinner>\n </div>\n <span class=\"text-sm text-main font-bold\">{{ uploadProgress }}%</span>\n </div>\n }\n @if (imageFileError) {\n <div class=\"w-14 h-14 rounded-md bg-gray-50 grid\">\n <ng-icon\n name=\"iconoirMediaImageXmark\"\n class=\"place-self-center text-rose-500\"\n data-cy=\"imgErrorIcon\"\n ></ng-icon>\n </div>\n }\n <div class=\"flex flex-col items-center gap-1\">\n <p class=\"font-medium\" data-cy=\"imgInputMsgPrimary\">\n {{ getPrimaryText() | translate }}\n </p>\n <p\n class=\"text-sm\"\n data-cy=\"imgInputMsgSecondary\"\n [class]=\"\n isUploadInProgress\n ? 'font-bold text-blue-500 cursor-pointer'\n : 'font-medium text-gray-500'\n \"\n (click)=\"handleSecondaryTextClick($event)\"\n >\n {{ getSecondaryText() | translate }}\n </p>\n </div>\n <input\n #fileInput\n accept=\"image/*\"\n type=\"file\"\n class=\"hidden\"\n (change)=\"handleFileInput($event)\"\n [disabled]=\"isUploadInProgress || disabled\"\n />\n </label>\n @if (!showUrlInput) {\n <div class=\"flex-none mt-2\">\n <gn-ui-button\n data-cy=\"imgUrlBtn\"\n (buttonClick)=\"displayUrlInput()\"\n type=\"gray\"\n [disabled]=\"disabled\"\n [extraClass]=\"disabled && 'cursor-not-allowed'\"\n >\n <ng-icon class=\"me-1 text-primary\" name=\"iconoirLink\"></ng-icon>\n {{ 'input.image.displayUrlInput' | translate }}\n </gn-ui-button>\n </div>\n }\n @if (showUrlInput) {\n <gn-ui-url-input\n class=\"mt-3.5\"\n data-cy=\"imgUrlInput\"\n (uploadClick)=\"downloadUrl($event)\"\n [disabled]=\"isUploadInProgress || disabled\"\n >\n </gn-ui-url-input>\n }\n </div>\n}\n", styles: [":host{--gn-ui-button-padding: 8px 8px;--gn-ui-button-rounded: 8px}\n"] }]
33803
33810
  }], propDecorators: { previewUrl: [{
33804
33811
  type: Input
33805
33812
  }], altText: [{
@@ -34032,7 +34039,7 @@ class MetadataContactComponent {
34032
34039
  this.organizationClick.emit(this.shownOrganization);
34033
34040
  }
34034
34041
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MetadataContactComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
34035
- 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\" 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: [
34042
+ 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: [
34036
34043
  provideIcons({
34037
34044
  matOpenInNew,
34038
34045
  matCallOutline,
@@ -34052,7 +34059,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
34052
34059
  matPersonOutline,
34053
34060
  matLocationOnOutline,
34054
34061
  }),
34055
- ], 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\" 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" }]
34062
+ ], 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" }]
34056
34063
  }], propDecorators: { metadata: [{
34057
34064
  type: Input
34058
34065
  }], organizationClick: [{
@@ -34552,7 +34559,7 @@ class RecordApiFormComponent {
34552
34559
  }
34553
34560
  }
34554
34561
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RecordApiFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
34555
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: RecordApiFormComponent, isStandalone: true, selector: "gn-ui-record-api-form", inputs: { apiLink: "apiLink" }, ngImport: i0, template: "<div class=\"flex flex-col gap-8\">\n <div class=\"flex flex-col bg-white p-8 ng-star-inserted shadow-xl gap-8\">\n <div class=\"flex flex-row\">\n <div class=\"text-[16px] text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.create\n </div>\n <button\n (click)=\"resetUrl()\"\n class=\"bg-primary-opacity-50 inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded capitalize text-primary-lightest hover:bg-primary transition-colors\"\n >\n <p class=\"text-[13px] uppercase\" translate>\n record.metadata.api.form.reset\n </p>\n </button>\n </div>\n <div class=\"flex flex-row flex-wrap justify-between grow gap-5\">\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-[14px]\" translate>record.metadata.api.form.limit</p>\n <div class=\"flex flex-row items-center gap-2\">\n <gn-ui-text-input\n class=\"mr-2 w-20\"\n (valueChange)=\"setLimit($event)\"\n [value]=\"displayLimit$ | async\"\n placeholder=\"\"\n >\n </gn-ui-text-input>\n <div class=\"flex items-center\">\n <input\n class=\"mr-2 cursor-pointer\"\n type=\"checkbox\"\n [checked]=\"noLimitChecked$ | async\"\n (change)=\"setLimit('-1')\"\n />\n <span class=\"text-sm\" translate\n >record.metadata.api.form.limit.all</span\n >\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3 relative\">\n <p class=\"text-sm\" [class.text-gray-600]=\"!supportOffset\" translate>\n record.metadata.api.form.offset\n </p>\n <div class=\"flex items-center\">\n <gn-ui-text-input\n class=\"w-20\"\n [value]=\"offset$ | async\"\n [disabled]=\"!supportOffset\"\n (valueChange)=\"supportOffset ? setOffset($event) : null\"\n placeholder=\"\"\n >\n </gn-ui-text-input>\n @if (!supportOffset) {\n <div class=\"flex items-center gap-2 text-orange-500 z-10 ml-3\">\n <span\n class=\"material-symbols-outlined\"\n matTooltip=\"Not supported on this service\"\n >\n warning\n </span>\n </div>\n }\n </div>\n </div>\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-sm\" translate>record.metadata.api.form.type</p>\n <gn-ui-dropdown-selector\n #dropdown\n [title]=\"''\"\n extraBtnClass=\"secondary min-w-full !w-40 !text-black\"\n [showTitle]=\"false\"\n class=\"text-black\"\n [choices]=\"outputFormats\"\n (selectValue)=\"setFormat($event)\"\n [selected]=\"format$ | async\"\n ></gn-ui-dropdown-selector>\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3 mb-3\">\n <div class=\"text-sm text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.customUrl\n </div>\n <div class=\"bg-white rounded-lg\">\n <gn-ui-copy-text-button\n [text]=\"apiQueryUrl$ | async\"\n ></gn-ui-copy-text-button>\n </div>\n </div>\n</div>\n", styles: [":host ::ng-deep input{color:#000;opacity:1}:host ::ng-deep gn-ui-copy-text-button input[type=text]{color:#000;background-color:#fff}:host ::ng-deep gn-ui-copy-text-button button,host ::ng-deep gn-ui-copy-text-button button:hover{background-color:var(--color-secondary)!important}:host ::ng-deep gn-ui-copy-text-button button ng-icon{color:#fff!important;opacity:1!important}:host ::ng-deep gn-ui-copy-text-button button:hover ng-icon{color:#d3d3d3!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "placeholder", "required", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth", "disabled"], outputs: ["selectValue"] }, { kind: "component", type: CopyTextButtonComponent, selector: "gn-ui-copy-text-button", inputs: ["text", "tooltipText", "displayText", "rows"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
34562
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: RecordApiFormComponent, isStandalone: true, selector: "gn-ui-record-api-form", inputs: { apiLink: "apiLink" }, ngImport: i0, template: "<div class=\"flex flex-col gap-8\">\n <div class=\"flex flex-col bg-white p-8 ng-star-inserted shadow-xl gap-8\">\n <div class=\"flex flex-row\">\n <div class=\"text-[16px] text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.create\n </div>\n <button\n (click)=\"resetUrl()\"\n class=\"bg-primary/50 inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded capitalize text-primary-lightest hover:bg-primary transition-colors\"\n >\n <p class=\"text-[13px] uppercase\" translate>\n record.metadata.api.form.reset\n </p>\n </button>\n </div>\n <div class=\"flex flex-row flex-wrap justify-between grow gap-5\">\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-[14px]\" translate>record.metadata.api.form.limit</p>\n <div class=\"flex flex-row items-center gap-2\">\n <gn-ui-text-input\n class=\"mr-2 w-20\"\n (valueChange)=\"setLimit($event)\"\n [value]=\"displayLimit$ | async\"\n placeholder=\"\"\n >\n </gn-ui-text-input>\n <div class=\"flex items-center\">\n <input\n class=\"mr-2 cursor-pointer\"\n type=\"checkbox\"\n [checked]=\"noLimitChecked$ | async\"\n (change)=\"setLimit('-1')\"\n />\n <span class=\"text-sm\" translate\n >record.metadata.api.form.limit.all</span\n >\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3 relative\">\n <p class=\"text-sm\" [class.text-gray-600]=\"!supportOffset\" translate>\n record.metadata.api.form.offset\n </p>\n <div class=\"flex items-center\">\n <gn-ui-text-input\n class=\"w-20\"\n [value]=\"offset$ | async\"\n [disabled]=\"!supportOffset\"\n (valueChange)=\"supportOffset ? setOffset($event) : null\"\n placeholder=\"\"\n >\n </gn-ui-text-input>\n @if (!supportOffset) {\n <div class=\"flex items-center gap-2 text-orange-500 z-10 ml-3\">\n <span\n class=\"material-symbols-outlined\"\n matTooltip=\"Not supported on this service\"\n >\n warning\n </span>\n </div>\n }\n </div>\n </div>\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-sm\" translate>record.metadata.api.form.type</p>\n <gn-ui-dropdown-selector\n #dropdown\n [title]=\"''\"\n extraBtnClass=\"secondary min-w-full !w-40 !text-black\"\n [showTitle]=\"false\"\n class=\"text-black\"\n [choices]=\"outputFormats\"\n (selectValue)=\"setFormat($event)\"\n [selected]=\"format$ | async\"\n ></gn-ui-dropdown-selector>\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3 mb-3\">\n <div class=\"text-sm text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.customUrl\n </div>\n <div class=\"bg-white rounded-lg\">\n <gn-ui-copy-text-button\n [text]=\"apiQueryUrl$ | async\"\n ></gn-ui-copy-text-button>\n </div>\n </div>\n</div>\n", styles: [":host ::ng-deep input{color:#000;opacity:1}:host ::ng-deep gn-ui-copy-text-button input[type=text]{color:#000;background-color:#fff}:host ::ng-deep gn-ui-copy-text-button button,host ::ng-deep gn-ui-copy-text-button button:hover{background-color:var(--color-secondary)!important}:host ::ng-deep gn-ui-copy-text-button button ng-icon{color:#fff!important;opacity:1!important}:host ::ng-deep gn-ui-copy-text-button button:hover ng-icon{color:#d3d3d3!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "placeholder", "required", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth", "disabled"], outputs: ["selectValue"] }, { kind: "component", type: CopyTextButtonComponent, selector: "gn-ui-copy-text-button", inputs: ["text", "tooltipText", "displayText", "rows"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
34556
34563
  }
34557
34564
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RecordApiFormComponent, decorators: [{
34558
34565
  type: Component,
@@ -34563,7 +34570,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
34563
34570
  CopyTextButtonComponent,
34564
34571
  TranslateDirective,
34565
34572
  MatTooltipModule,
34566
- ], template: "<div class=\"flex flex-col gap-8\">\n <div class=\"flex flex-col bg-white p-8 ng-star-inserted shadow-xl gap-8\">\n <div class=\"flex flex-row\">\n <div class=\"text-[16px] text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.create\n </div>\n <button\n (click)=\"resetUrl()\"\n class=\"bg-primary-opacity-50 inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded capitalize text-primary-lightest hover:bg-primary transition-colors\"\n >\n <p class=\"text-[13px] uppercase\" translate>\n record.metadata.api.form.reset\n </p>\n </button>\n </div>\n <div class=\"flex flex-row flex-wrap justify-between grow gap-5\">\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-[14px]\" translate>record.metadata.api.form.limit</p>\n <div class=\"flex flex-row items-center gap-2\">\n <gn-ui-text-input\n class=\"mr-2 w-20\"\n (valueChange)=\"setLimit($event)\"\n [value]=\"displayLimit$ | async\"\n placeholder=\"\"\n >\n </gn-ui-text-input>\n <div class=\"flex items-center\">\n <input\n class=\"mr-2 cursor-pointer\"\n type=\"checkbox\"\n [checked]=\"noLimitChecked$ | async\"\n (change)=\"setLimit('-1')\"\n />\n <span class=\"text-sm\" translate\n >record.metadata.api.form.limit.all</span\n >\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3 relative\">\n <p class=\"text-sm\" [class.text-gray-600]=\"!supportOffset\" translate>\n record.metadata.api.form.offset\n </p>\n <div class=\"flex items-center\">\n <gn-ui-text-input\n class=\"w-20\"\n [value]=\"offset$ | async\"\n [disabled]=\"!supportOffset\"\n (valueChange)=\"supportOffset ? setOffset($event) : null\"\n placeholder=\"\"\n >\n </gn-ui-text-input>\n @if (!supportOffset) {\n <div class=\"flex items-center gap-2 text-orange-500 z-10 ml-3\">\n <span\n class=\"material-symbols-outlined\"\n matTooltip=\"Not supported on this service\"\n >\n warning\n </span>\n </div>\n }\n </div>\n </div>\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-sm\" translate>record.metadata.api.form.type</p>\n <gn-ui-dropdown-selector\n #dropdown\n [title]=\"''\"\n extraBtnClass=\"secondary min-w-full !w-40 !text-black\"\n [showTitle]=\"false\"\n class=\"text-black\"\n [choices]=\"outputFormats\"\n (selectValue)=\"setFormat($event)\"\n [selected]=\"format$ | async\"\n ></gn-ui-dropdown-selector>\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3 mb-3\">\n <div class=\"text-sm text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.customUrl\n </div>\n <div class=\"bg-white rounded-lg\">\n <gn-ui-copy-text-button\n [text]=\"apiQueryUrl$ | async\"\n ></gn-ui-copy-text-button>\n </div>\n </div>\n</div>\n", styles: [":host ::ng-deep input{color:#000;opacity:1}:host ::ng-deep gn-ui-copy-text-button input[type=text]{color:#000;background-color:#fff}:host ::ng-deep gn-ui-copy-text-button button,host ::ng-deep gn-ui-copy-text-button button:hover{background-color:var(--color-secondary)!important}:host ::ng-deep gn-ui-copy-text-button button ng-icon{color:#fff!important;opacity:1!important}:host ::ng-deep gn-ui-copy-text-button button:hover ng-icon{color:#d3d3d3!important}\n"] }]
34573
+ ], template: "<div class=\"flex flex-col gap-8\">\n <div class=\"flex flex-col bg-white p-8 ng-star-inserted shadow-xl gap-8\">\n <div class=\"flex flex-row\">\n <div class=\"text-[16px] text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.create\n </div>\n <button\n (click)=\"resetUrl()\"\n class=\"bg-primary/50 inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded capitalize text-primary-lightest hover:bg-primary transition-colors\"\n >\n <p class=\"text-[13px] uppercase\" translate>\n record.metadata.api.form.reset\n </p>\n </button>\n </div>\n <div class=\"flex flex-row flex-wrap justify-between grow gap-5\">\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-[14px]\" translate>record.metadata.api.form.limit</p>\n <div class=\"flex flex-row items-center gap-2\">\n <gn-ui-text-input\n class=\"mr-2 w-20\"\n (valueChange)=\"setLimit($event)\"\n [value]=\"displayLimit$ | async\"\n placeholder=\"\"\n >\n </gn-ui-text-input>\n <div class=\"flex items-center\">\n <input\n class=\"mr-2 cursor-pointer\"\n type=\"checkbox\"\n [checked]=\"noLimitChecked$ | async\"\n (change)=\"setLimit('-1')\"\n />\n <span class=\"text-sm\" translate\n >record.metadata.api.form.limit.all</span\n >\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3 relative\">\n <p class=\"text-sm\" [class.text-gray-600]=\"!supportOffset\" translate>\n record.metadata.api.form.offset\n </p>\n <div class=\"flex items-center\">\n <gn-ui-text-input\n class=\"w-20\"\n [value]=\"offset$ | async\"\n [disabled]=\"!supportOffset\"\n (valueChange)=\"supportOffset ? setOffset($event) : null\"\n placeholder=\"\"\n >\n </gn-ui-text-input>\n @if (!supportOffset) {\n <div class=\"flex items-center gap-2 text-orange-500 z-10 ml-3\">\n <span\n class=\"material-symbols-outlined\"\n matTooltip=\"Not supported on this service\"\n >\n warning\n </span>\n </div>\n }\n </div>\n </div>\n <div class=\"flex flex-col gap-3\">\n <p class=\"text-sm\" translate>record.metadata.api.form.type</p>\n <gn-ui-dropdown-selector\n #dropdown\n [title]=\"''\"\n extraBtnClass=\"secondary min-w-full !w-40 !text-black\"\n [showTitle]=\"false\"\n class=\"text-black\"\n [choices]=\"outputFormats\"\n (selectValue)=\"setFormat($event)\"\n [selected]=\"format$ | async\"\n ></gn-ui-dropdown-selector>\n </div>\n </div>\n </div>\n <div class=\"flex flex-col gap-3 mb-3\">\n <div class=\"text-sm text-black truncate font-title w-11/12\" translate>\n record.metadata.api.form.customUrl\n </div>\n <div class=\"bg-white rounded-lg\">\n <gn-ui-copy-text-button\n [text]=\"apiQueryUrl$ | async\"\n ></gn-ui-copy-text-button>\n </div>\n </div>\n</div>\n", styles: [":host ::ng-deep input{color:#000;opacity:1}:host ::ng-deep gn-ui-copy-text-button input[type=text]{color:#000;background-color:#fff}:host ::ng-deep gn-ui-copy-text-button button,host ::ng-deep gn-ui-copy-text-button button:hover{background-color:var(--color-secondary)!important}:host ::ng-deep gn-ui-copy-text-button button ng-icon{color:#fff!important;opacity:1!important}:host ::ng-deep gn-ui-copy-text-button button:hover ng-icon{color:#d3d3d3!important}\n"] }]
34567
34574
  }], propDecorators: { apiLink: [{
34568
34575
  type: Input
34569
34576
  }] } });
@@ -34666,13 +34673,12 @@ class ApplicationBannerComponent {
34666
34673
  this.icon = 'matWarning';
34667
34674
  break;
34668
34675
  case 'light':
34669
- this.msgClass =
34670
- 'bg-primary-opacity-10 border-primary-lightest text-black';
34676
+ this.msgClass = 'bg-primary/10 border-primary-lightest text-black';
34671
34677
  this.icon = 'matInfoOutline';
34672
34678
  break;
34673
34679
  case 'secondary':
34674
34680
  default:
34675
- this.msgClass = 'bg-primary-opacity-50 border-primary-darker text-black';
34681
+ this.msgClass = 'bg-primary/50 border-primary-darker text-black';
34676
34682
  this.icon = 'matWarningAmberOutline';
34677
34683
  break;
34678
34684
  }
@@ -34761,7 +34767,7 @@ class InternalLinkCardComponent {
34761
34767
  provideNgIconsConfig({
34762
34768
  size: '1.2em',
34763
34769
  }),
34764
- ], ngImport: i0, template: "<a\n [attr.href]=\"linkHref\"\n [target]=\"linkTarget\"\n class=\"record-card\"\n [ngClass]=\"cardClass\"\n>\n @if (shouldShowThumbnail) {\n <div class=\"record-card__thumbnail\">\n <gn-ui-thumbnail\n class=\"w-full h-full object-cover\"\n [thumbnailUrl]=\"record.overviews?.[0]?.url?.toString() || ''\"\n [fit]=\"'cover'\"\n ></gn-ui-thumbnail>\n </div>\n }\n <div class=\"grow pt-1\" [ngClass]=\"shouldShowThumbnail ? 'sm:w-0' : ''\">\n <div class=\"flex flex-col gap-2 h-full\">\n <h4\n class=\"record-card__title\"\n data-cy=\"recordTitle\"\n [title]=\"record.title\"\n >\n {{ record.title }}\n </h4>\n <!-- force max width here as long a-href urls within the markdown parser can cause layout issues -->\n <div class=\"grow max-w-[248px] sm:max-w-full\">\n <gn-ui-markdown-parser\n data-cy=\"recordAbstract\"\n [textContent]=\"abstract\"\n [whitoutStyles]=\"true\"\n class=\"record-card__abstract\"\n [title]=\"abstract\"\n ></gn-ui-markdown-parser>\n </div>\n <div class=\"record-card__footer\">\n @if (record.ownerOrganization?.name) {\n <div\n data-cy=\"recordOrg\"\n class=\"grow flex flex-row gap-1 items-center text-primary-lighter\"\n [ngClass]=\"displayContactIconOnly ? 'justify-center' : ''\"\n >\n <ng-icon\n name=\"iconoirBank\"\n class=\"text-primary -translate-y-[0.5px] shrink-0\"\n [title]=\"record.ownerOrganization.name\"\n ></ng-icon>\n @if (!displayContactIconOnly) {\n <span\n data-cy=\"recordOrgName\"\n class=\"line-clamp-1\"\n [title]=\"record.ownerOrganization.name\"\n >{{ record.ownerOrganization.name }}</span\n >\n }\n </div>\n }\n <div class=\"record-card__footer__other\">\n <div\n class=\"xs:border-r last:border-r-0 flex grow gap-4 px-4 last:pr-0\"\n >\n <gn-ui-kind-badge\n [extraClass]=\"'text-[1.2em]'\"\n [styling]=\"'gray'\"\n [kind]=\"record?.kind\"\n [contentTemplate]=\"customTemplate\"\n class=\"pt-1\"\n >\n <ng-template #customTemplate></ng-template\n ></gn-ui-kind-badge>\n @if (metadataQualityDisplay) {\n <gn-ui-metadata-quality\n class=\"flex items-center min-w-[113px]\"\n [smaller]=\"true\"\n [metadata]=\"record\"\n [metadataQualityDisplay]=\"metadataQualityDisplay\"\n [popoverDisplay]=\"true\"\n ></gn-ui-metadata-quality>\n }\n </div>\n <div\n class=\"flex justify-center\"\n data-cy=\"recordFav\"\n [ngClass]=\"displayContactIconOnly ? 'px-1' : 'px-4'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"favoriteTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: record }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n</a>\n", styles: [".record-card{@apply rounded-md bg-white hover:cursor-pointer hover:bg-slate-50 overflow-hidden items-stretch flex flex-row md:gap-0 justify-between py-3 pl-3 pr-5;}.record-card.size-L{@apply w-full md:h-[208px] gap-5;}.record-card.size-M{@apply max-w-[940px] md:h-[231px] gap-4;}.record-card.size-S{@apply max-w-[572px] md:h-[315px] gap-4;}.record-card.size-XS{@apply max-w-[280px] md:h-[315px] gap-4;}.record-card:hover .record-card__title{@apply text-primary;}.record-card__thumbnail{@apply border rounded-lg overflow-hidden shrink-0;}.size-L .record-card__thumbnail{@apply w-full w-[190px] h-[184px];}.size-M .record-card__thumbnail{@apply w-full w-[138px] h-[207px];}.record-card__title{@apply text-xl font-medium text-title leading-6;}.size-L .record-card__title{@apply line-clamp-2;}.size-M .record-card__title{@apply line-clamp-2 ml-2;}.size-S .record-card__title,.size-XS .record-card__title{@apply line-clamp-3 ml-2;}.record-card__abstract{@apply text-gray-900 overflow-hidden;}.size-L .record-card__abstract{@apply line-clamp-3;}.size-M .record-card__abstract{@apply line-clamp-3 ml-2;}.size-S .record-card__abstract,.size-XS .record-card__abstract{@apply line-clamp-4 ml-2;}.record-card__footer{@apply flex sm:flex-row flex-col flex-nowrap gap-3 justify-end items-center w-full border-t pt-1 overflow-hidden;}@media (max-width: 450px){.size-S .record-card__footer{@apply flex-col items-stretch;}}.size-XS .record-card__footer{@apply flex-col items-stretch gap-2;}.record-card__footer__other{@apply flex flex-col xs:flex-row flex-nowrap gap-3 xs:border-l first:border-l-0;}.record-card__footer__other>div{@apply py-1;}@media (max-width: 450px){.size-S .record-card__footer__other,.size-S .record-card__footer__other>div{@apply border-0 px-0 py-0;}}.size-XS .record-card__footer__other,.size-XS .record-card__footer__other>div{@apply border-0;}.size-XS .record-card__footer__other>div{@apply px-0 py-0;}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: MetadataQualityComponent, selector: "gn-ui-metadata-quality", inputs: ["metadata", "smaller", "metadataQualityDisplay", "popoverDisplay", "propsToValidate", "forceComputeScore"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: KindBadgeComponent, selector: "gn-ui-kind-badge", inputs: ["styling", "contentTemplate", "kind", "extraClass"] }, { kind: "component", type: MarkdownParserComponent, selector: "gn-ui-markdown-parser", inputs: ["textContent", "whitoutStyles"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }] }); }
34770
+ ], ngImport: i0, template: "<a\n [attr.href]=\"linkHref\"\n [target]=\"linkTarget\"\n class=\"record-card\"\n [ngClass]=\"cardClass\"\n>\n @if (shouldShowThumbnail) {\n <div class=\"record-card__thumbnail\">\n <gn-ui-thumbnail\n class=\"w-full h-full object-cover\"\n [thumbnailUrl]=\"record.overviews?.[0]?.url?.toString() || ''\"\n [fit]=\"'cover'\"\n ></gn-ui-thumbnail>\n </div>\n }\n <div class=\"grow pt-1\" [ngClass]=\"shouldShowThumbnail ? 'sm:w-0' : ''\">\n <div class=\"flex flex-col gap-2\" [class.h-full]=\"size !== 'M'\">\n <h4\n class=\"record-card__title\"\n data-cy=\"recordTitle\"\n [title]=\"record.title\"\n >\n {{ record.title }}\n </h4>\n <!-- force max width here as long a-href urls within the markdown parser can cause layout issues -->\n <div class=\"grow max-w-[248px] sm:max-w-full\">\n <gn-ui-markdown-parser\n data-cy=\"recordAbstract\"\n [textContent]=\"abstract\"\n [whitoutStyles]=\"true\"\n class=\"record-card__abstract\"\n [title]=\"abstract\"\n ></gn-ui-markdown-parser>\n </div>\n @if (size !== 'M') {\n <ng-container [ngTemplateOutlet]=\"footerTpl\"></ng-container>\n }\n </div>\n </div>\n @if (size === 'M') {\n <ng-container [ngTemplateOutlet]=\"footerTpl\"></ng-container>\n }\n</a>\n\n<ng-template #footerTpl>\n <div class=\"record-card__footer\">\n @if (record.ownerOrganization?.name) {\n <div\n data-cy=\"recordOrg\"\n class=\"grow flex flex-row gap-1 items-center text-primary-lighter\"\n [ngClass]=\"displayContactIconOnly ? 'justify-center' : ''\"\n >\n <ng-icon\n name=\"iconoirBank\"\n class=\"text-primary -translate-y-[0.5px] shrink-0\"\n [title]=\"record.ownerOrganization.name\"\n ></ng-icon>\n @if (!displayContactIconOnly) {\n <span\n data-cy=\"recordOrgName\"\n class=\"line-clamp-1\"\n [title]=\"record.ownerOrganization.name\"\n >{{ record.ownerOrganization.name }}</span\n >\n }\n </div>\n }\n <div class=\"record-card__footer__other\">\n <div class=\"xs:border-r last:border-r-0 flex grow gap-4 px-4 last:pr-0\">\n <gn-ui-kind-badge\n [extraClass]=\"'text-[1.2em]'\"\n [styling]=\"'gray'\"\n [kind]=\"record?.kind\"\n [contentTemplate]=\"customTemplate\"\n class=\"pt-1\"\n >\n <ng-template #customTemplate></ng-template\n ></gn-ui-kind-badge>\n @if (metadataQualityDisplay) {\n <gn-ui-metadata-quality\n class=\"flex items-center min-w-[113px]\"\n [smaller]=\"true\"\n [metadata]=\"record\"\n [metadataQualityDisplay]=\"metadataQualityDisplay\"\n [popoverDisplay]=\"true\"\n ></gn-ui-metadata-quality>\n }\n </div>\n <div\n class=\"flex justify-center\"\n data-cy=\"recordFav\"\n [ngClass]=\"displayContactIconOnly ? 'px-1' : 'px-4'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"favoriteTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: record }\"\n ></ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".record-card{@apply rounded-md bg-white hover:cursor-pointer hover:bg-slate-50 overflow-hidden items-stretch flex flex-row md:gap-0 justify-between py-3 pl-3 pr-5;}.record-card.size-L{@apply w-full md:h-[208px] gap-5;}.record-card.size-M{@apply max-w-[940px] gap-4 flex-wrap;}.record-card.size-S{@apply max-w-[572px] md:h-[315px] gap-4;}.record-card.size-XS{@apply max-w-[280px] md:h-[315px] gap-4;}.record-card:hover .record-card__title{@apply text-primary;}.record-card__thumbnail{@apply border rounded-lg overflow-hidden shrink-0;}.size-L .record-card__thumbnail{@apply w-[184px] h-[184px];}.size-M .record-card__thumbnail{@apply w-[138px] h-[138px];}.record-card__title{@apply text-xl font-medium text-title leading-6;}.size-L .record-card__title,.size-M .record-card__title{@apply line-clamp-2;}.size-S .record-card__title,.size-XS .record-card__title{@apply line-clamp-3 ml-2;}.record-card__abstract{@apply text-gray-900 overflow-hidden;}.size-L .record-card__abstract,.size-M .record-card__abstract{@apply line-clamp-3;}.size-S .record-card__abstract,.size-XS .record-card__abstract{@apply line-clamp-4 ml-2;}.record-card__footer{@apply flex sm:flex-row flex-col flex-nowrap gap-3 justify-end items-center w-full border-t pt-1 overflow-hidden;}@media (max-width: 450px){.size-S .record-card__footer{@apply flex-col items-stretch;}}.size-XS .record-card__footer{@apply flex-col items-stretch gap-2;}.record-card__footer__other{@apply flex flex-col xs:flex-row flex-nowrap gap-3 xs:border-l first:border-l-0;}.record-card__footer__other>div{@apply py-1;}@media (max-width: 450px){.size-S .record-card__footer__other,.size-S .record-card__footer__other>div{@apply border-0 px-0 py-0;}}.size-XS .record-card__footer__other,.size-XS .record-card__footer__other>div{@apply border-0;}.size-XS .record-card__footer__other>div{@apply px-0 py-0;}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: MetadataQualityComponent, selector: "gn-ui-metadata-quality", inputs: ["metadata", "smaller", "metadataQualityDisplay", "popoverDisplay", "propsToValidate", "forceComputeScore"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: KindBadgeComponent, selector: "gn-ui-kind-badge", inputs: ["styling", "contentTemplate", "kind", "extraClass"] }, { kind: "component", type: MarkdownParserComponent, selector: "gn-ui-markdown-parser", inputs: ["textContent", "whitoutStyles"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }] }); }
34765
34771
  }
34766
34772
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InternalLinkCardComponent, decorators: [{
34767
34773
  type: Component,
@@ -34781,7 +34787,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
34781
34787
  provideNgIconsConfig({
34782
34788
  size: '1.2em',
34783
34789
  }),
34784
- ], template: "<a\n [attr.href]=\"linkHref\"\n [target]=\"linkTarget\"\n class=\"record-card\"\n [ngClass]=\"cardClass\"\n>\n @if (shouldShowThumbnail) {\n <div class=\"record-card__thumbnail\">\n <gn-ui-thumbnail\n class=\"w-full h-full object-cover\"\n [thumbnailUrl]=\"record.overviews?.[0]?.url?.toString() || ''\"\n [fit]=\"'cover'\"\n ></gn-ui-thumbnail>\n </div>\n }\n <div class=\"grow pt-1\" [ngClass]=\"shouldShowThumbnail ? 'sm:w-0' : ''\">\n <div class=\"flex flex-col gap-2 h-full\">\n <h4\n class=\"record-card__title\"\n data-cy=\"recordTitle\"\n [title]=\"record.title\"\n >\n {{ record.title }}\n </h4>\n <!-- force max width here as long a-href urls within the markdown parser can cause layout issues -->\n <div class=\"grow max-w-[248px] sm:max-w-full\">\n <gn-ui-markdown-parser\n data-cy=\"recordAbstract\"\n [textContent]=\"abstract\"\n [whitoutStyles]=\"true\"\n class=\"record-card__abstract\"\n [title]=\"abstract\"\n ></gn-ui-markdown-parser>\n </div>\n <div class=\"record-card__footer\">\n @if (record.ownerOrganization?.name) {\n <div\n data-cy=\"recordOrg\"\n class=\"grow flex flex-row gap-1 items-center text-primary-lighter\"\n [ngClass]=\"displayContactIconOnly ? 'justify-center' : ''\"\n >\n <ng-icon\n name=\"iconoirBank\"\n class=\"text-primary -translate-y-[0.5px] shrink-0\"\n [title]=\"record.ownerOrganization.name\"\n ></ng-icon>\n @if (!displayContactIconOnly) {\n <span\n data-cy=\"recordOrgName\"\n class=\"line-clamp-1\"\n [title]=\"record.ownerOrganization.name\"\n >{{ record.ownerOrganization.name }}</span\n >\n }\n </div>\n }\n <div class=\"record-card__footer__other\">\n <div\n class=\"xs:border-r last:border-r-0 flex grow gap-4 px-4 last:pr-0\"\n >\n <gn-ui-kind-badge\n [extraClass]=\"'text-[1.2em]'\"\n [styling]=\"'gray'\"\n [kind]=\"record?.kind\"\n [contentTemplate]=\"customTemplate\"\n class=\"pt-1\"\n >\n <ng-template #customTemplate></ng-template\n ></gn-ui-kind-badge>\n @if (metadataQualityDisplay) {\n <gn-ui-metadata-quality\n class=\"flex items-center min-w-[113px]\"\n [smaller]=\"true\"\n [metadata]=\"record\"\n [metadataQualityDisplay]=\"metadataQualityDisplay\"\n [popoverDisplay]=\"true\"\n ></gn-ui-metadata-quality>\n }\n </div>\n <div\n class=\"flex justify-center\"\n data-cy=\"recordFav\"\n [ngClass]=\"displayContactIconOnly ? 'px-1' : 'px-4'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"favoriteTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: record }\"\n ></ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n</a>\n", styles: [".record-card{@apply rounded-md bg-white hover:cursor-pointer hover:bg-slate-50 overflow-hidden items-stretch flex flex-row md:gap-0 justify-between py-3 pl-3 pr-5;}.record-card.size-L{@apply w-full md:h-[208px] gap-5;}.record-card.size-M{@apply max-w-[940px] md:h-[231px] gap-4;}.record-card.size-S{@apply max-w-[572px] md:h-[315px] gap-4;}.record-card.size-XS{@apply max-w-[280px] md:h-[315px] gap-4;}.record-card:hover .record-card__title{@apply text-primary;}.record-card__thumbnail{@apply border rounded-lg overflow-hidden shrink-0;}.size-L .record-card__thumbnail{@apply w-full w-[190px] h-[184px];}.size-M .record-card__thumbnail{@apply w-full w-[138px] h-[207px];}.record-card__title{@apply text-xl font-medium text-title leading-6;}.size-L .record-card__title{@apply line-clamp-2;}.size-M .record-card__title{@apply line-clamp-2 ml-2;}.size-S .record-card__title,.size-XS .record-card__title{@apply line-clamp-3 ml-2;}.record-card__abstract{@apply text-gray-900 overflow-hidden;}.size-L .record-card__abstract{@apply line-clamp-3;}.size-M .record-card__abstract{@apply line-clamp-3 ml-2;}.size-S .record-card__abstract,.size-XS .record-card__abstract{@apply line-clamp-4 ml-2;}.record-card__footer{@apply flex sm:flex-row flex-col flex-nowrap gap-3 justify-end items-center w-full border-t pt-1 overflow-hidden;}@media (max-width: 450px){.size-S .record-card__footer{@apply flex-col items-stretch;}}.size-XS .record-card__footer{@apply flex-col items-stretch gap-2;}.record-card__footer__other{@apply flex flex-col xs:flex-row flex-nowrap gap-3 xs:border-l first:border-l-0;}.record-card__footer__other>div{@apply py-1;}@media (max-width: 450px){.size-S .record-card__footer__other,.size-S .record-card__footer__other>div{@apply border-0 px-0 py-0;}}.size-XS .record-card__footer__other,.size-XS .record-card__footer__other>div{@apply border-0;}.size-XS .record-card__footer__other>div{@apply px-0 py-0;}\n"] }]
34790
+ ], template: "<a\n [attr.href]=\"linkHref\"\n [target]=\"linkTarget\"\n class=\"record-card\"\n [ngClass]=\"cardClass\"\n>\n @if (shouldShowThumbnail) {\n <div class=\"record-card__thumbnail\">\n <gn-ui-thumbnail\n class=\"w-full h-full object-cover\"\n [thumbnailUrl]=\"record.overviews?.[0]?.url?.toString() || ''\"\n [fit]=\"'cover'\"\n ></gn-ui-thumbnail>\n </div>\n }\n <div class=\"grow pt-1\" [ngClass]=\"shouldShowThumbnail ? 'sm:w-0' : ''\">\n <div class=\"flex flex-col gap-2\" [class.h-full]=\"size !== 'M'\">\n <h4\n class=\"record-card__title\"\n data-cy=\"recordTitle\"\n [title]=\"record.title\"\n >\n {{ record.title }}\n </h4>\n <!-- force max width here as long a-href urls within the markdown parser can cause layout issues -->\n <div class=\"grow max-w-[248px] sm:max-w-full\">\n <gn-ui-markdown-parser\n data-cy=\"recordAbstract\"\n [textContent]=\"abstract\"\n [whitoutStyles]=\"true\"\n class=\"record-card__abstract\"\n [title]=\"abstract\"\n ></gn-ui-markdown-parser>\n </div>\n @if (size !== 'M') {\n <ng-container [ngTemplateOutlet]=\"footerTpl\"></ng-container>\n }\n </div>\n </div>\n @if (size === 'M') {\n <ng-container [ngTemplateOutlet]=\"footerTpl\"></ng-container>\n }\n</a>\n\n<ng-template #footerTpl>\n <div class=\"record-card__footer\">\n @if (record.ownerOrganization?.name) {\n <div\n data-cy=\"recordOrg\"\n class=\"grow flex flex-row gap-1 items-center text-primary-lighter\"\n [ngClass]=\"displayContactIconOnly ? 'justify-center' : ''\"\n >\n <ng-icon\n name=\"iconoirBank\"\n class=\"text-primary -translate-y-[0.5px] shrink-0\"\n [title]=\"record.ownerOrganization.name\"\n ></ng-icon>\n @if (!displayContactIconOnly) {\n <span\n data-cy=\"recordOrgName\"\n class=\"line-clamp-1\"\n [title]=\"record.ownerOrganization.name\"\n >{{ record.ownerOrganization.name }}</span\n >\n }\n </div>\n }\n <div class=\"record-card__footer__other\">\n <div class=\"xs:border-r last:border-r-0 flex grow gap-4 px-4 last:pr-0\">\n <gn-ui-kind-badge\n [extraClass]=\"'text-[1.2em]'\"\n [styling]=\"'gray'\"\n [kind]=\"record?.kind\"\n [contentTemplate]=\"customTemplate\"\n class=\"pt-1\"\n >\n <ng-template #customTemplate></ng-template\n ></gn-ui-kind-badge>\n @if (metadataQualityDisplay) {\n <gn-ui-metadata-quality\n class=\"flex items-center min-w-[113px]\"\n [smaller]=\"true\"\n [metadata]=\"record\"\n [metadataQualityDisplay]=\"metadataQualityDisplay\"\n [popoverDisplay]=\"true\"\n ></gn-ui-metadata-quality>\n }\n </div>\n <div\n class=\"flex justify-center\"\n data-cy=\"recordFav\"\n [ngClass]=\"displayContactIconOnly ? 'px-1' : 'px-4'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"favoriteTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: record }\"\n ></ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".record-card{@apply rounded-md bg-white hover:cursor-pointer hover:bg-slate-50 overflow-hidden items-stretch flex flex-row md:gap-0 justify-between py-3 pl-3 pr-5;}.record-card.size-L{@apply w-full md:h-[208px] gap-5;}.record-card.size-M{@apply max-w-[940px] gap-4 flex-wrap;}.record-card.size-S{@apply max-w-[572px] md:h-[315px] gap-4;}.record-card.size-XS{@apply max-w-[280px] md:h-[315px] gap-4;}.record-card:hover .record-card__title{@apply text-primary;}.record-card__thumbnail{@apply border rounded-lg overflow-hidden shrink-0;}.size-L .record-card__thumbnail{@apply w-[184px] h-[184px];}.size-M .record-card__thumbnail{@apply w-[138px] h-[138px];}.record-card__title{@apply text-xl font-medium text-title leading-6;}.size-L .record-card__title,.size-M .record-card__title{@apply line-clamp-2;}.size-S .record-card__title,.size-XS .record-card__title{@apply line-clamp-3 ml-2;}.record-card__abstract{@apply text-gray-900 overflow-hidden;}.size-L .record-card__abstract,.size-M .record-card__abstract{@apply line-clamp-3;}.size-S .record-card__abstract,.size-XS .record-card__abstract{@apply line-clamp-4 ml-2;}.record-card__footer{@apply flex sm:flex-row flex-col flex-nowrap gap-3 justify-end items-center w-full border-t pt-1 overflow-hidden;}@media (max-width: 450px){.size-S .record-card__footer{@apply flex-col items-stretch;}}.size-XS .record-card__footer{@apply flex-col items-stretch gap-2;}.record-card__footer__other{@apply flex flex-col xs:flex-row flex-nowrap gap-3 xs:border-l first:border-l-0;}.record-card__footer__other>div{@apply py-1;}@media (max-width: 450px){.size-S .record-card__footer__other,.size-S .record-card__footer__other>div{@apply border-0 px-0 py-0;}}.size-XS .record-card__footer__other,.size-XS .record-card__footer__other>div{@apply border-0;}.size-XS .record-card__footer__other>div{@apply px-0 py-0;}\n"] }]
34785
34791
  }], propDecorators: { record: [{
34786
34792
  type: Input
34787
34793
  }], linkTarget: [{
@@ -34919,7 +34925,7 @@ class ServiceCapabilitiesComponent {
34919
34925
  : `h-8 rounded-lg`;
34920
34926
  }
34921
34927
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ServiceCapabilitiesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
34922
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ServiceCapabilitiesComponent, isStandalone: true, selector: "gn-ui-service-capabilities", inputs: { apiLinks: "apiLinks" }, ngImport: i0, template: "@if (apiLinks.length > 0) {\n <div style=\"height: 652px\" id=\"preview\">\n <div class=\"bg-primary-opacity-10 overflow-visible\" style=\"height: 420px\">\n <div class=\"container-lg px-4 lg:mx-auto\">\n <div>\n <div class=\"gn-ui-section-title mb-6\" translate>\n service.metadata.capabilities\n </div>\n @if (loading) {\n <div class=\"flex justify-center w-full h-[200px] items-center\">\n <gn-ui-spinning-loader></gn-ui-spinning-loader>\n </div>\n }\n @if (!loading) {\n <div>\n <div class=\"flex flex-row gap-5\">\n <div class=\"h-14 md:w-2/5 w-full mb-4 flex flex-row relative\">\n <gn-ui-text-input\n class=\"w-full\"\n [(value)]=\"searchQuery\"\n [extraClass]=\"getExtraInputClass()\"\n [placeholder]=\"'service.metadata.search' | translate\"\n (input)=\"onSearchChange($event)\"\n (keydown.enter)=\"onSearchEnter($event)\"\n >\n </gn-ui-text-input>\n <div\n class=\"absolute right-14 h-14 w-14 flex items-center justify-center\"\n >\n @if (searchQuery) {\n <button\n #inputBtn\n [aria-label]=\"\n 'service.metadata.search.clear' | translate\n \"\n (click)=\"clearSearch()\"\n class=\"h-12 w-12 border-0 flex items-center justify-center\"\n >\n <ng-icon name=\"matClose\"></ng-icon>\n </button>\n }\n </div>\n <div\n class=\"border-l absolute border-gray-200 right-0 h-14 w-14\"\n >\n <gn-ui-button\n #inputBtn\n type=\"outline\"\n extraClass=\"h-12 w-12 border-0 absolute right-1 top-1 bg-white\"\n (buttonClick)=\"searchLayers()\"\n >\n <ng-icon name=\"iconoirSearch\"></ng-icon>\n </gn-ui-button>\n </div>\n </div>\n <gn-ui-popover\n [content]=\"popoverItems\"\n theme=\"light\"\n class=\"w-14 h-14 border border-gray-300 rounded-lg flex justify-center items-center\"\n >\n <ng-icon\n name=\"matInfoOutline\"\n class=\"w-6 h-6 pt-0.5\"\n ></ng-icon>\n </gn-ui-popover>\n </div>\n <div\n style=\"height: 500px\"\n class=\"bg-white shadow-xl rounded p-0 flex md:flex-row flex-col\"\n >\n <div\n class=\"flex flex-col gap-2 bg-gray-100 md:w-1/2 md:h-full w-full h-1/2 rounded-l overflow-y-auto py-5 pr-1 pl-3\"\n data-test=\"layer-list\"\n >\n @for (layerItem of filteredLayers; track layerItem) {\n <gn-ui-button\n type=\"outline\"\n [extraClass]=\"getExtraClass(layerItem)\"\n (buttonClick)=\"selectLayer(layerItem)\"\n >\n {{ layerItem.title || layerItem.name }}\n </gn-ui-button>\n }\n @if (filteredLayers.length === 0) {\n <span class=\"text-gray-800\">\n {{ 'service.metadata.filter.noLayers' | translate }}\n </span>\n }\n </div>\n <div\n data-test=\"layer-information\"\n class=\"flex flex-col gap-4 md:h-full md:w-1/2 w-full h-1/2 py-5 px-10 overflow-y-auto\"\n >\n @for (item of layerInformation; track item) {\n <div class=\"flex flex-row gap-4 border-b border-gray-200\">\n <span class=\"font-semibold w-24\">{{\n item.displayName\n }}</span>\n @if (isList(item.value)) {\n <div>\n @for (subItem of item.value; track subItem) {\n <div class=\"flex flex-row break-words max-w-72\">\n {{ subItem }}\n </div>\n }\n </div>\n }\n @if (!isList(item.value)) {\n <div class=\"break-words max-w-72\">\n {{ item.value }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n}\n<ng-template #popoverItems>\n <div class=\"p-2 py-4\">\n <div translate>service.metadata.filter</div>\n </div>\n</ng-template>\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: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "placeholder", "required", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: PopoverComponent, selector: "gn-ui-popover", inputs: ["content", "theme"] }, { kind: "component", type: SpinningLoaderComponent, selector: "gn-ui-spinning-loader" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], viewProviders: [
34928
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ServiceCapabilitiesComponent, isStandalone: true, selector: "gn-ui-service-capabilities", inputs: { apiLinks: "apiLinks" }, ngImport: i0, template: "@if (apiLinks.length > 0) {\n <div style=\"height: 652px\" id=\"preview\">\n <div class=\"bg-primary/10 overflow-visible\" style=\"height: 420px\">\n <div class=\"container-lg px-4 lg:mx-auto\">\n <div>\n <div class=\"gn-ui-section-title mb-6\" translate>\n service.metadata.capabilities\n </div>\n @if (loading) {\n <div class=\"flex justify-center w-full h-[200px] items-center\">\n <gn-ui-spinning-loader></gn-ui-spinning-loader>\n </div>\n }\n @if (!loading) {\n <div>\n <div class=\"flex flex-row gap-5\">\n <div class=\"h-14 md:w-2/5 w-full mb-4 flex flex-row relative\">\n <gn-ui-text-input\n class=\"w-full\"\n [(value)]=\"searchQuery\"\n [extraClass]=\"getExtraInputClass()\"\n [placeholder]=\"'service.metadata.search' | translate\"\n (input)=\"onSearchChange($event)\"\n (keydown.enter)=\"onSearchEnter($event)\"\n >\n </gn-ui-text-input>\n <div\n class=\"absolute right-14 h-14 w-14 flex items-center justify-center\"\n >\n @if (searchQuery) {\n <button\n #inputBtn\n [aria-label]=\"\n 'service.metadata.search.clear' | translate\n \"\n (click)=\"clearSearch()\"\n class=\"h-12 w-12 border-0 flex items-center justify-center\"\n >\n <ng-icon name=\"matClose\"></ng-icon>\n </button>\n }\n </div>\n <div\n class=\"border-l absolute border-gray-200 right-0 h-14 w-14\"\n >\n <gn-ui-button\n #inputBtn\n type=\"outline\"\n extraClass=\"h-12 w-12 border-0 absolute right-1 top-1 bg-white\"\n (buttonClick)=\"searchLayers()\"\n >\n <ng-icon name=\"iconoirSearch\"></ng-icon>\n </gn-ui-button>\n </div>\n </div>\n <gn-ui-popover\n [content]=\"popoverItems\"\n theme=\"light\"\n class=\"w-14 h-14 border border-gray-300 rounded-lg flex justify-center items-center\"\n >\n <ng-icon\n name=\"matInfoOutline\"\n class=\"w-6 h-6 pt-0.5\"\n ></ng-icon>\n </gn-ui-popover>\n </div>\n <div\n style=\"height: 500px\"\n class=\"bg-white shadow-xl rounded p-0 flex md:flex-row flex-col\"\n >\n <div\n class=\"flex flex-col gap-2 bg-gray-100 md:w-1/2 md:h-full w-full h-1/2 rounded-l overflow-y-auto py-5 pr-1 pl-3\"\n data-test=\"layer-list\"\n >\n @for (layerItem of filteredLayers; track layerItem) {\n <gn-ui-button\n type=\"outline\"\n [extraClass]=\"getExtraClass(layerItem)\"\n (buttonClick)=\"selectLayer(layerItem)\"\n >\n {{ layerItem.title || layerItem.name }}\n </gn-ui-button>\n }\n @if (filteredLayers.length === 0) {\n <span class=\"text-gray-800\">\n {{ 'service.metadata.filter.noLayers' | translate }}\n </span>\n }\n </div>\n <div\n data-test=\"layer-information\"\n class=\"flex flex-col gap-4 md:h-full md:w-1/2 w-full h-1/2 py-5 px-10 overflow-y-auto\"\n >\n @for (item of layerInformation; track item) {\n <div class=\"flex flex-row gap-4 border-b border-gray-200\">\n <span class=\"font-semibold w-24\">{{\n item.displayName\n }}</span>\n @if (isList(item.value)) {\n <div>\n @for (subItem of item.value; track subItem) {\n <div class=\"flex flex-row break-words max-w-72\">\n {{ subItem }}\n </div>\n }\n </div>\n }\n @if (!isList(item.value)) {\n <div class=\"break-words max-w-72\">\n {{ item.value }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n}\n<ng-template #popoverItems>\n <div class=\"p-2 py-4\">\n <div translate>service.metadata.filter</div>\n </div>\n</ng-template>\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: TextInputComponent, selector: "gn-ui-text-input", inputs: ["value", "extraClass", "placeholder", "required", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: PopoverComponent, selector: "gn-ui-popover", inputs: ["content", "theme"] }, { kind: "component", type: SpinningLoaderComponent, selector: "gn-ui-spinning-loader" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], viewProviders: [
34923
34929
  provideIcons({
34924
34930
  iconoirSearch,
34925
34931
  matInfoOutline,
@@ -34943,7 +34949,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
34943
34949
  matInfoOutline,
34944
34950
  matClose,
34945
34951
  }),
34946
- ], template: "@if (apiLinks.length > 0) {\n <div style=\"height: 652px\" id=\"preview\">\n <div class=\"bg-primary-opacity-10 overflow-visible\" style=\"height: 420px\">\n <div class=\"container-lg px-4 lg:mx-auto\">\n <div>\n <div class=\"gn-ui-section-title mb-6\" translate>\n service.metadata.capabilities\n </div>\n @if (loading) {\n <div class=\"flex justify-center w-full h-[200px] items-center\">\n <gn-ui-spinning-loader></gn-ui-spinning-loader>\n </div>\n }\n @if (!loading) {\n <div>\n <div class=\"flex flex-row gap-5\">\n <div class=\"h-14 md:w-2/5 w-full mb-4 flex flex-row relative\">\n <gn-ui-text-input\n class=\"w-full\"\n [(value)]=\"searchQuery\"\n [extraClass]=\"getExtraInputClass()\"\n [placeholder]=\"'service.metadata.search' | translate\"\n (input)=\"onSearchChange($event)\"\n (keydown.enter)=\"onSearchEnter($event)\"\n >\n </gn-ui-text-input>\n <div\n class=\"absolute right-14 h-14 w-14 flex items-center justify-center\"\n >\n @if (searchQuery) {\n <button\n #inputBtn\n [aria-label]=\"\n 'service.metadata.search.clear' | translate\n \"\n (click)=\"clearSearch()\"\n class=\"h-12 w-12 border-0 flex items-center justify-center\"\n >\n <ng-icon name=\"matClose\"></ng-icon>\n </button>\n }\n </div>\n <div\n class=\"border-l absolute border-gray-200 right-0 h-14 w-14\"\n >\n <gn-ui-button\n #inputBtn\n type=\"outline\"\n extraClass=\"h-12 w-12 border-0 absolute right-1 top-1 bg-white\"\n (buttonClick)=\"searchLayers()\"\n >\n <ng-icon name=\"iconoirSearch\"></ng-icon>\n </gn-ui-button>\n </div>\n </div>\n <gn-ui-popover\n [content]=\"popoverItems\"\n theme=\"light\"\n class=\"w-14 h-14 border border-gray-300 rounded-lg flex justify-center items-center\"\n >\n <ng-icon\n name=\"matInfoOutline\"\n class=\"w-6 h-6 pt-0.5\"\n ></ng-icon>\n </gn-ui-popover>\n </div>\n <div\n style=\"height: 500px\"\n class=\"bg-white shadow-xl rounded p-0 flex md:flex-row flex-col\"\n >\n <div\n class=\"flex flex-col gap-2 bg-gray-100 md:w-1/2 md:h-full w-full h-1/2 rounded-l overflow-y-auto py-5 pr-1 pl-3\"\n data-test=\"layer-list\"\n >\n @for (layerItem of filteredLayers; track layerItem) {\n <gn-ui-button\n type=\"outline\"\n [extraClass]=\"getExtraClass(layerItem)\"\n (buttonClick)=\"selectLayer(layerItem)\"\n >\n {{ layerItem.title || layerItem.name }}\n </gn-ui-button>\n }\n @if (filteredLayers.length === 0) {\n <span class=\"text-gray-800\">\n {{ 'service.metadata.filter.noLayers' | translate }}\n </span>\n }\n </div>\n <div\n data-test=\"layer-information\"\n class=\"flex flex-col gap-4 md:h-full md:w-1/2 w-full h-1/2 py-5 px-10 overflow-y-auto\"\n >\n @for (item of layerInformation; track item) {\n <div class=\"flex flex-row gap-4 border-b border-gray-200\">\n <span class=\"font-semibold w-24\">{{\n item.displayName\n }}</span>\n @if (isList(item.value)) {\n <div>\n @for (subItem of item.value; track subItem) {\n <div class=\"flex flex-row break-words max-w-72\">\n {{ subItem }}\n </div>\n }\n </div>\n }\n @if (!isList(item.value)) {\n <div class=\"break-words max-w-72\">\n {{ item.value }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n}\n<ng-template #popoverItems>\n <div class=\"p-2 py-4\">\n <div translate>service.metadata.filter</div>\n </div>\n</ng-template>\n" }]
34952
+ ], template: "@if (apiLinks.length > 0) {\n <div style=\"height: 652px\" id=\"preview\">\n <div class=\"bg-primary/10 overflow-visible\" style=\"height: 420px\">\n <div class=\"container-lg px-4 lg:mx-auto\">\n <div>\n <div class=\"gn-ui-section-title mb-6\" translate>\n service.metadata.capabilities\n </div>\n @if (loading) {\n <div class=\"flex justify-center w-full h-[200px] items-center\">\n <gn-ui-spinning-loader></gn-ui-spinning-loader>\n </div>\n }\n @if (!loading) {\n <div>\n <div class=\"flex flex-row gap-5\">\n <div class=\"h-14 md:w-2/5 w-full mb-4 flex flex-row relative\">\n <gn-ui-text-input\n class=\"w-full\"\n [(value)]=\"searchQuery\"\n [extraClass]=\"getExtraInputClass()\"\n [placeholder]=\"'service.metadata.search' | translate\"\n (input)=\"onSearchChange($event)\"\n (keydown.enter)=\"onSearchEnter($event)\"\n >\n </gn-ui-text-input>\n <div\n class=\"absolute right-14 h-14 w-14 flex items-center justify-center\"\n >\n @if (searchQuery) {\n <button\n #inputBtn\n [aria-label]=\"\n 'service.metadata.search.clear' | translate\n \"\n (click)=\"clearSearch()\"\n class=\"h-12 w-12 border-0 flex items-center justify-center\"\n >\n <ng-icon name=\"matClose\"></ng-icon>\n </button>\n }\n </div>\n <div\n class=\"border-l absolute border-gray-200 right-0 h-14 w-14\"\n >\n <gn-ui-button\n #inputBtn\n type=\"outline\"\n extraClass=\"h-12 w-12 border-0 absolute right-1 top-1 bg-white\"\n (buttonClick)=\"searchLayers()\"\n >\n <ng-icon name=\"iconoirSearch\"></ng-icon>\n </gn-ui-button>\n </div>\n </div>\n <gn-ui-popover\n [content]=\"popoverItems\"\n theme=\"light\"\n class=\"w-14 h-14 border border-gray-300 rounded-lg flex justify-center items-center\"\n >\n <ng-icon\n name=\"matInfoOutline\"\n class=\"w-6 h-6 pt-0.5\"\n ></ng-icon>\n </gn-ui-popover>\n </div>\n <div\n style=\"height: 500px\"\n class=\"bg-white shadow-xl rounded p-0 flex md:flex-row flex-col\"\n >\n <div\n class=\"flex flex-col gap-2 bg-gray-100 md:w-1/2 md:h-full w-full h-1/2 rounded-l overflow-y-auto py-5 pr-1 pl-3\"\n data-test=\"layer-list\"\n >\n @for (layerItem of filteredLayers; track layerItem) {\n <gn-ui-button\n type=\"outline\"\n [extraClass]=\"getExtraClass(layerItem)\"\n (buttonClick)=\"selectLayer(layerItem)\"\n >\n {{ layerItem.title || layerItem.name }}\n </gn-ui-button>\n }\n @if (filteredLayers.length === 0) {\n <span class=\"text-gray-800\">\n {{ 'service.metadata.filter.noLayers' | translate }}\n </span>\n }\n </div>\n <div\n data-test=\"layer-information\"\n class=\"flex flex-col gap-4 md:h-full md:w-1/2 w-full h-1/2 py-5 px-10 overflow-y-auto\"\n >\n @for (item of layerInformation; track item) {\n <div class=\"flex flex-row gap-4 border-b border-gray-200\">\n <span class=\"font-semibold w-24\">{{\n item.displayName\n }}</span>\n @if (isList(item.value)) {\n <div>\n @for (subItem of item.value; track subItem) {\n <div class=\"flex flex-row break-words max-w-72\">\n {{ subItem }}\n </div>\n }\n </div>\n }\n @if (!isList(item.value)) {\n <div class=\"break-words max-w-72\">\n {{ item.value }}\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n}\n<ng-template #popoverItems>\n <div class=\"p-2 py-4\">\n <div translate>service.metadata.filter</div>\n </div>\n</ng-template>\n" }]
34947
34953
  }], propDecorators: { apiLinks: [{
34948
34954
  type: Input
34949
34955
  }] } });
@@ -35332,7 +35338,7 @@ class RecordPreviewFeedComponent extends RecordPreviewComponent {
35332
35338
  return this.timeFormat.format(this.record.recordCreated, Date.now());
35333
35339
  }
35334
35340
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RecordPreviewFeedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
35335
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: RecordPreviewFeedComponent, isStandalone: true, selector: "gn-ui-record-preview-feed", usesInheritance: true, ngImport: i0, template: "<div\n class=\"mx-[18px] pl-[18px] pb-[18px] border-solid border-l-2 border-gray-100\"\n>\n <a\n class=\"record-container block rounded-lg bg-white border border-white card-shadow\"\n [attr.href]=\"linkHref\"\n [target]=\"linkTarget\"\n >\n <div\n class=\"record-header py-4 px-4 border-b border-gray-300 flex flex-row items-center relative transition duration-200\"\n >\n <div\n class=\"absolute w-3 h-3 bg-secondary rounded-full\"\n style=\"right: calc(100% + 14px)\"\n ></div>\n <div\n class=\"record-header-image border border-gray-300 bg-white rounded-full w-16 h-16 object-contain mr-4 overflow-hidden transition duration-200 shrink-0\"\n >\n @if (!hasLogo) {\n <ng-icon\n class=\"text-gray-200\"\n name=\"{{ hasOnlyPerson ? 'matFace' : 'matHomeWorkOutline' }}\"\n style=\"width: 42px; height: 42px; font-size: 42px; margin: 10px\"\n ></ng-icon>\n }\n @if (hasLogo) {\n <gn-ui-thumbnail\n [thumbnailUrl]=\"record.ownerOrganization?.logoUrl?.toString()\"\n [fit]=\"'contain'\"\n ></gn-ui-thumbnail>\n }\n </div>\n <div class=\"flex flex-col overflow-hidden items-start\">\n @if (hasOrganization) {\n <span\n class=\"font-bold transition duration-200 text-primary truncate max-w-full\"\n >\n {{ record.ownerOrganization.name }}\n </span>\n }\n @if (hasOnlyPerson) {\n <span\n class=\"font-bold transition duration-200 text-primary truncate max-w-full\"\n >\n {{ contact.firstName }} {{ contact.lastName }}\n </span>\n }\n <p class=\"\">\n <span translate [translateParams]=\"{ time }\"\n >record.was.created.time</span\n >\n </p>\n </div>\n </div>\n <div class=\"pt-5 pb-5 px-10 relative\">\n <div class=\"absolute top-[0.85em] right-[0.85em]\">\n <ng-container\n [ngTemplateOutlet]=\"favoriteTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: record }\"\n ></ng-container>\n </div>\n <h1\n class=\"font-title text-black text-[21px] font-medium mb-3 pr-8\"\n data-cy=\"recordTitle\"\n >\n {{ record.title }}\n </h1>\n <p class=\"line-clamp-3\">\n <gn-ui-markdown-parser\n [textContent]=\"abstract\"\n [whitoutStyles]=\"true\"\n />\n </p>\n @if (record.overviews?.[0]) {\n <gn-ui-thumbnail\n class=\"block mt-3 w-full h-[136px] border border-gray-100 rounded-lg overflow-hidden\"\n [thumbnailUrl]=\"record.overviews?.[0]?.url.toString()\"\n ></gn-ui-thumbnail>\n }\n @if (isDownloadable || isViewable) {\n <div class=\"flex flex-row mt-3\">\n @if (isDownloadable) {\n <ng-icon\n class=\"text-primary opacity-45 mr-3\"\n name=\"matCloudDownloadOutline\"\n >\n </ng-icon>\n }\n @if (isViewable) {\n <ng-icon class=\"text-primary opacity-45 mr-3\" name=\"matMapOutline\">\n </ng-icon>\n }\n </div>\n }\n </div>\n </a>\n</div>\n", styles: [".record-container:hover .record-header,.record-container:hover .record-header-image{border-color:var(--color-primary-lightest)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "component", type: MarkdownParserComponent, selector: "gn-ui-markdown-parser", inputs: ["textContent", "whitoutStyles"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], viewProviders: [
35341
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: RecordPreviewFeedComponent, isStandalone: true, selector: "gn-ui-record-preview-feed", usesInheritance: true, ngImport: i0, template: "<div\n class=\"mx-[18px] pl-[18px] pb-[18px] border-solid border-l-2 border-gray-100\"\n>\n <a\n class=\"record-container block rounded-lg bg-white border border-white card-shadow\"\n [attr.href]=\"linkHref\"\n [target]=\"linkTarget\"\n >\n <div\n class=\"record-header py-4 px-4 border-b border-gray-300 flex flex-row items-center relative transition duration-200\"\n >\n <div\n class=\"absolute w-3 h-3 bg-secondary rounded-full\"\n style=\"right: calc(100% + 14px)\"\n ></div>\n <div\n class=\"record-header-image border border-gray-300 bg-white rounded-full w-16 h-16 object-contain mr-4 overflow-hidden transition duration-200 shrink-0\"\n >\n @if (!hasLogo) {\n <ng-icon\n class=\"text-gray-200\"\n name=\"{{ hasOnlyPerson ? 'matFace' : 'matHomeWorkOutline' }}\"\n style=\"width: 42px; height: 42px; font-size: 42px; margin: 10px\"\n ></ng-icon>\n }\n @if (hasLogo) {\n <gn-ui-thumbnail\n [thumbnailUrl]=\"record.ownerOrganization?.logoUrl?.toString()\"\n [fit]=\"'contain'\"\n ></gn-ui-thumbnail>\n }\n </div>\n <div class=\"flex flex-col overflow-hidden items-start grow\">\n @if (hasOrganization) {\n <span\n class=\"font-bold transition duration-200 text-primary truncate max-w-full\"\n >\n {{ record.ownerOrganization.name }}\n </span>\n }\n @if (hasOnlyPerson) {\n <span\n class=\"font-bold transition duration-200 text-primary truncate max-w-full\"\n >\n {{ contact.firstName }} {{ contact.lastName }}\n </span>\n }\n <p class=\"\">\n <span translate [translateParams]=\"{ time }\"\n >record.was.created.time</span\n >\n </p>\n </div>\n <div class=\"ml-3 shrink-0\">\n <ng-container\n [ngTemplateOutlet]=\"favoriteTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: record }\"\n ></ng-container>\n </div>\n </div>\n <div class=\"pt-5 pb-5 px-10 relative\">\n <div class=\"flex flex-col sm:flex-row gap-4 mb-3\">\n @if (record.overviews?.[0]) {\n <gn-ui-thumbnail\n class=\"block shrink-0 w-[120px] h-[120px] border border-gray-100 rounded-lg overflow-hidden\"\n [thumbnailUrl]=\"record.overviews?.[0]?.url.toString()\"\n [fit]=\"'cover'\"\n ></gn-ui-thumbnail>\n }\n <h1\n class=\"font-title text-black text-[21px] font-medium\"\n data-cy=\"recordTitle\"\n >\n {{ record.title }}\n </h1>\n </div>\n <p class=\"line-clamp-3\">\n <gn-ui-markdown-parser\n [textContent]=\"abstract\"\n [whitoutStyles]=\"true\"\n />\n </p>\n @if (isDownloadable || isViewable) {\n <div class=\"flex flex-row mt-3\">\n @if (isDownloadable) {\n <ng-icon\n class=\"text-primary opacity-45 mr-3\"\n name=\"matCloudDownloadOutline\"\n >\n </ng-icon>\n }\n @if (isViewable) {\n <ng-icon class=\"text-primary opacity-45 mr-3\" name=\"matMapOutline\">\n </ng-icon>\n }\n </div>\n }\n </div>\n </a>\n</div>\n", styles: [".record-container:hover .record-header,.record-container:hover .record-header-image{border-color:var(--color-primary-lightest)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: ThumbnailComponent, selector: "gn-ui-thumbnail", inputs: ["thumbnailUrl", "fit"], outputs: ["placeholderShown"] }, { kind: "component", type: MarkdownParserComponent, selector: "gn-ui-markdown-parser", inputs: ["textContent", "whitoutStyles"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], viewProviders: [
35336
35342
  provideIcons({
35337
35343
  matMapOutline,
35338
35344
  matCloudDownloadOutline,
@@ -35362,7 +35368,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
35362
35368
  provideNgIconsConfig({
35363
35369
  size: '1.5em',
35364
35370
  }),
35365
- ], template: "<div\n class=\"mx-[18px] pl-[18px] pb-[18px] border-solid border-l-2 border-gray-100\"\n>\n <a\n class=\"record-container block rounded-lg bg-white border border-white card-shadow\"\n [attr.href]=\"linkHref\"\n [target]=\"linkTarget\"\n >\n <div\n class=\"record-header py-4 px-4 border-b border-gray-300 flex flex-row items-center relative transition duration-200\"\n >\n <div\n class=\"absolute w-3 h-3 bg-secondary rounded-full\"\n style=\"right: calc(100% + 14px)\"\n ></div>\n <div\n class=\"record-header-image border border-gray-300 bg-white rounded-full w-16 h-16 object-contain mr-4 overflow-hidden transition duration-200 shrink-0\"\n >\n @if (!hasLogo) {\n <ng-icon\n class=\"text-gray-200\"\n name=\"{{ hasOnlyPerson ? 'matFace' : 'matHomeWorkOutline' }}\"\n style=\"width: 42px; height: 42px; font-size: 42px; margin: 10px\"\n ></ng-icon>\n }\n @if (hasLogo) {\n <gn-ui-thumbnail\n [thumbnailUrl]=\"record.ownerOrganization?.logoUrl?.toString()\"\n [fit]=\"'contain'\"\n ></gn-ui-thumbnail>\n }\n </div>\n <div class=\"flex flex-col overflow-hidden items-start\">\n @if (hasOrganization) {\n <span\n class=\"font-bold transition duration-200 text-primary truncate max-w-full\"\n >\n {{ record.ownerOrganization.name }}\n </span>\n }\n @if (hasOnlyPerson) {\n <span\n class=\"font-bold transition duration-200 text-primary truncate max-w-full\"\n >\n {{ contact.firstName }} {{ contact.lastName }}\n </span>\n }\n <p class=\"\">\n <span translate [translateParams]=\"{ time }\"\n >record.was.created.time</span\n >\n </p>\n </div>\n </div>\n <div class=\"pt-5 pb-5 px-10 relative\">\n <div class=\"absolute top-[0.85em] right-[0.85em]\">\n <ng-container\n [ngTemplateOutlet]=\"favoriteTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: record }\"\n ></ng-container>\n </div>\n <h1\n class=\"font-title text-black text-[21px] font-medium mb-3 pr-8\"\n data-cy=\"recordTitle\"\n >\n {{ record.title }}\n </h1>\n <p class=\"line-clamp-3\">\n <gn-ui-markdown-parser\n [textContent]=\"abstract\"\n [whitoutStyles]=\"true\"\n />\n </p>\n @if (record.overviews?.[0]) {\n <gn-ui-thumbnail\n class=\"block mt-3 w-full h-[136px] border border-gray-100 rounded-lg overflow-hidden\"\n [thumbnailUrl]=\"record.overviews?.[0]?.url.toString()\"\n ></gn-ui-thumbnail>\n }\n @if (isDownloadable || isViewable) {\n <div class=\"flex flex-row mt-3\">\n @if (isDownloadable) {\n <ng-icon\n class=\"text-primary opacity-45 mr-3\"\n name=\"matCloudDownloadOutline\"\n >\n </ng-icon>\n }\n @if (isViewable) {\n <ng-icon class=\"text-primary opacity-45 mr-3\" name=\"matMapOutline\">\n </ng-icon>\n }\n </div>\n }\n </div>\n </a>\n</div>\n", styles: [".record-container:hover .record-header,.record-container:hover .record-header-image{border-color:var(--color-primary-lightest)}\n"] }]
35371
+ ], template: "<div\n class=\"mx-[18px] pl-[18px] pb-[18px] border-solid border-l-2 border-gray-100\"\n>\n <a\n class=\"record-container block rounded-lg bg-white border border-white card-shadow\"\n [attr.href]=\"linkHref\"\n [target]=\"linkTarget\"\n >\n <div\n class=\"record-header py-4 px-4 border-b border-gray-300 flex flex-row items-center relative transition duration-200\"\n >\n <div\n class=\"absolute w-3 h-3 bg-secondary rounded-full\"\n style=\"right: calc(100% + 14px)\"\n ></div>\n <div\n class=\"record-header-image border border-gray-300 bg-white rounded-full w-16 h-16 object-contain mr-4 overflow-hidden transition duration-200 shrink-0\"\n >\n @if (!hasLogo) {\n <ng-icon\n class=\"text-gray-200\"\n name=\"{{ hasOnlyPerson ? 'matFace' : 'matHomeWorkOutline' }}\"\n style=\"width: 42px; height: 42px; font-size: 42px; margin: 10px\"\n ></ng-icon>\n }\n @if (hasLogo) {\n <gn-ui-thumbnail\n [thumbnailUrl]=\"record.ownerOrganization?.logoUrl?.toString()\"\n [fit]=\"'contain'\"\n ></gn-ui-thumbnail>\n }\n </div>\n <div class=\"flex flex-col overflow-hidden items-start grow\">\n @if (hasOrganization) {\n <span\n class=\"font-bold transition duration-200 text-primary truncate max-w-full\"\n >\n {{ record.ownerOrganization.name }}\n </span>\n }\n @if (hasOnlyPerson) {\n <span\n class=\"font-bold transition duration-200 text-primary truncate max-w-full\"\n >\n {{ contact.firstName }} {{ contact.lastName }}\n </span>\n }\n <p class=\"\">\n <span translate [translateParams]=\"{ time }\"\n >record.was.created.time</span\n >\n </p>\n </div>\n <div class=\"ml-3 shrink-0\">\n <ng-container\n [ngTemplateOutlet]=\"favoriteTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: record }\"\n ></ng-container>\n </div>\n </div>\n <div class=\"pt-5 pb-5 px-10 relative\">\n <div class=\"flex flex-col sm:flex-row gap-4 mb-3\">\n @if (record.overviews?.[0]) {\n <gn-ui-thumbnail\n class=\"block shrink-0 w-[120px] h-[120px] border border-gray-100 rounded-lg overflow-hidden\"\n [thumbnailUrl]=\"record.overviews?.[0]?.url.toString()\"\n [fit]=\"'cover'\"\n ></gn-ui-thumbnail>\n }\n <h1\n class=\"font-title text-black text-[21px] font-medium\"\n data-cy=\"recordTitle\"\n >\n {{ record.title }}\n </h1>\n </div>\n <p class=\"line-clamp-3\">\n <gn-ui-markdown-parser\n [textContent]=\"abstract\"\n [whitoutStyles]=\"true\"\n />\n </p>\n @if (isDownloadable || isViewable) {\n <div class=\"flex flex-row mt-3\">\n @if (isDownloadable) {\n <ng-icon\n class=\"text-primary opacity-45 mr-3\"\n name=\"matCloudDownloadOutline\"\n >\n </ng-icon>\n }\n @if (isViewable) {\n <ng-icon class=\"text-primary opacity-45 mr-3\" name=\"matMapOutline\">\n </ng-icon>\n }\n </div>\n }\n </div>\n </a>\n</div>\n", styles: [".record-container:hover .record-header,.record-container:hover .record-header-image{border-color:var(--color-primary-lightest)}\n"] }]
35366
35372
  }], ctorParameters: () => [] });
35367
35373
 
35368
35374
  class RecordPreviewListComponent extends RecordPreviewComponent {
@@ -38358,13 +38364,15 @@ class DataService {
38358
38364
  }
38359
38365
  async getDownloadLinksFromOgcApiFeatures(ogcApiLink) {
38360
38366
  const collectionInfo = await this.getDownloadUrlsFromOgcApi(ogcApiLink.url.href);
38361
- return Object.keys(collectionInfo.bulkDownloadLinks).map((downloadLink) => {
38367
+ return Object.keys(collectionInfo.bulkDownloadLinks).map((mimeType) => {
38368
+ const urlWithoutLimit = new URL(collectionInfo.bulkDownloadLinks[mimeType]);
38369
+ urlWithoutLimit.searchParams.delete('limit');
38362
38370
  return {
38363
38371
  ...ogcApiLink,
38364
38372
  name: collectionInfo.id,
38365
38373
  type: 'download',
38366
- url: new URL(collectionInfo.bulkDownloadLinks[downloadLink]),
38367
- mimeType: getMimeTypeForFormat(getFileFormatFromServiceOutput(downloadLink)),
38374
+ url: urlWithoutLimit,
38375
+ mimeType: getMimeTypeForFormat(getFileFormatFromServiceOutput(mimeType)),
38368
38376
  };
38369
38377
  });
38370
38378
  }
@@ -39158,7 +39166,7 @@ class ChartViewComponent {
39158
39166
  this.changeDetector.detectChanges();
39159
39167
  }
39160
39168
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ChartViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
39161
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ChartViewComponent, isStandalone: true, selector: "gn-ui-chart-view", inputs: { featureCatalog: "featureCatalog", cacheActive: "cacheActive", link: "link", aggregation: "aggregation", xProperty: "xProperty", yProperty: "yProperty", chartType: "chartType", userChartConfig: "userChartConfig" }, outputs: { chartConfig$: "chartConfig$" }, ngImport: i0, template: "<div class=\"w-full h-full flex flex-col\">\n <div\n class=\"flex flex-col space-y-2 sm:flex-row sm:space-y-0 sm:space-x-2 justify-between text-[13px]\"\n >\n <gn-ui-dropdown-selector\n class=\"basis-1/4\"\n [choices]=\"typeChoices\"\n [extraBtnClass]=\"'secondary min-w-full'\"\n (selectValue)=\"chartType$.next($event)\"\n [selected]=\"chartType$.value\"\n [title]=\"'chart.dropdown.type' | translate\"\n ></gn-ui-dropdown-selector>\n <gn-ui-dropdown-selector\n class=\"basis-1/4\"\n [choices]=\"xChoices$ | async\"\n [extraBtnClass]=\"'secondary min-w-full'\"\n (selectValue)=\"xProperty$.next($event)\"\n [selected]=\"xProperty$.value\"\n [title]=\"'chart.dropdown.xProperty' | translate\"\n ></gn-ui-dropdown-selector>\n @if (yChoices$ | async; as yChoices) {\n @if (!isCountAggregation) {\n <gn-ui-dropdown-selector\n class=\"basis-1/4\"\n [choices]=\"yChoices\"\n (selectValue)=\"yProperty$.next($event)\"\n [selected]=\"yProperty$.value\"\n [title]=\"'chart.dropdown.yProperty' | translate\"\n class=\"select-y-prop\"\n ></gn-ui-dropdown-selector>\n }\n }\n <gn-ui-dropdown-selector\n class=\"basis-1/4\"\n [choices]=\"aggregationChoices\"\n class=\"aggregation-choices\"\n (selectValue)=\"aggregation$.next($event)\"\n [selected]=\"aggregation$.value\"\n [title]=\"'chart.dropdown.aggregation' | translate\"\n ></gn-ui-dropdown-selector>\n </div>\n <div\n class=\"relative h-full mt-2 bg-white border border-gray-300 rounded-lg overflow-hidden\"\n >\n @if (!error) {\n <gn-ui-chart\n [data]=\"chartData$ | async\"\n [type]=\"chartType$.value\"\n [prettyLabel]=\"prettyLabel$ | async\"\n [labelProperty]=\"labelProperty\"\n [valueProperty]=\"valueProperty\"\n ></gn-ui-chart>\n }\n @if (loading) {\n <gn-ui-loading-mask\n class=\"absolute inset-0\"\n [message]=\"'chart.loading.data' | translate\"\n ></gn-ui-loading-mask>\n }\n @if (error) {\n <gn-ui-popup-alert\n type=\"warning\"\n icon=\"matErrorOutlineOutline\"\n class=\"absolute m-2 inset-0\"\n >\n <span>{{ error }}</span>\n </gn-ui-popup-alert>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth", "disabled"], outputs: ["selectValue"] }, { kind: "component", type: ChartComponent, selector: "gn-ui-chart", inputs: ["data", "labelProperty", "prettyLabel", "valueProperty", "secondaryValueProperty", "type"] }, { kind: "component", type: LoadingMaskComponent, selector: "gn-ui-loading-mask", inputs: ["message"] }, { kind: "component", type: PopupAlertComponent, selector: "gn-ui-popup-alert", inputs: ["icon", "type", "position"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
39169
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ChartViewComponent, isStandalone: true, selector: "gn-ui-chart-view", inputs: { featureCatalog: "featureCatalog", cacheActive: "cacheActive", link: "link", aggregation: "aggregation", xProperty: "xProperty", yProperty: "yProperty", chartType: "chartType", userChartConfig: "userChartConfig" }, outputs: { chartConfig$: "chartConfig$" }, ngImport: i0, template: "<div class=\"w-full h-full flex flex-col\">\n <div\n class=\"flex flex-col space-y-2 sm:flex-row sm:space-y-0 sm:space-x-2 justify-between text-[13px]\"\n >\n <gn-ui-dropdown-selector\n class=\"basis-1/4\"\n [choices]=\"typeChoices\"\n [extraBtnClass]=\"'secondary min-w-full'\"\n (selectValue)=\"chartType$.next($event)\"\n [selected]=\"chartType$.value\"\n [title]=\"'chart.dropdown.type' | translate\"\n ></gn-ui-dropdown-selector>\n <gn-ui-dropdown-selector\n class=\"basis-1/4\"\n [choices]=\"xChoices$ | async\"\n [extraBtnClass]=\"'secondary min-w-full'\"\n (selectValue)=\"xProperty$.next($event)\"\n [selected]=\"xProperty$.value\"\n [title]=\"'chart.dropdown.xProperty' | translate\"\n ></gn-ui-dropdown-selector>\n @if (yChoices$ | async; as yChoices) {\n <gn-ui-dropdown-selector\n class=\"basis-1/4 flex items-center select-y-prop\"\n [choices]=\"yChoices\"\n [disabled]=\"isCountAggregation\"\n (selectValue)=\"yProperty$.next($event)\"\n [selected]=\"yProperty$.value\"\n [title]=\"'chart.dropdown.yProperty' | translate\"\n ></gn-ui-dropdown-selector>\n }\n <gn-ui-dropdown-selector\n class=\"basis-1/4 aggregation-choices\"\n [choices]=\"aggregationChoices\"\n [disabled]=\"!yProperty$.value\"\n (selectValue)=\"aggregation$.next($event)\"\n [selected]=\"aggregation$.value\"\n [title]=\"'chart.dropdown.aggregation' | translate\"\n ></gn-ui-dropdown-selector>\n </div>\n <div\n class=\"relative h-full mt-2 bg-white border border-gray-300 rounded-lg overflow-hidden\"\n >\n @if (!error) {\n <gn-ui-chart\n [data]=\"chartData$ | async\"\n [type]=\"chartType$.value\"\n [prettyLabel]=\"prettyLabel$ | async\"\n [labelProperty]=\"labelProperty\"\n [valueProperty]=\"valueProperty\"\n ></gn-ui-chart>\n }\n @if (loading) {\n <gn-ui-loading-mask\n class=\"absolute inset-0\"\n [message]=\"'chart.loading.data' | translate\"\n ></gn-ui-loading-mask>\n }\n @if (error) {\n <gn-ui-popup-alert\n type=\"warning\"\n icon=\"matErrorOutlineOutline\"\n class=\"absolute m-2 inset-0\"\n >\n <span>{{ error }}</span>\n </gn-ui-popup-alert>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth", "disabled"], outputs: ["selectValue"] }, { kind: "component", type: ChartComponent, selector: "gn-ui-chart", inputs: ["data", "labelProperty", "prettyLabel", "valueProperty", "secondaryValueProperty", "type"] }, { kind: "component", type: LoadingMaskComponent, selector: "gn-ui-loading-mask", inputs: ["message"] }, { kind: "component", type: PopupAlertComponent, selector: "gn-ui-popup-alert", inputs: ["icon", "type", "position"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
39162
39170
  }
39163
39171
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ChartViewComponent, decorators: [{
39164
39172
  type: Component,
@@ -39169,7 +39177,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
39169
39177
  LoadingMaskComponent,
39170
39178
  PopupAlertComponent,
39171
39179
  TranslatePipe,
39172
- ], standalone: true, template: "<div class=\"w-full h-full flex flex-col\">\n <div\n class=\"flex flex-col space-y-2 sm:flex-row sm:space-y-0 sm:space-x-2 justify-between text-[13px]\"\n >\n <gn-ui-dropdown-selector\n class=\"basis-1/4\"\n [choices]=\"typeChoices\"\n [extraBtnClass]=\"'secondary min-w-full'\"\n (selectValue)=\"chartType$.next($event)\"\n [selected]=\"chartType$.value\"\n [title]=\"'chart.dropdown.type' | translate\"\n ></gn-ui-dropdown-selector>\n <gn-ui-dropdown-selector\n class=\"basis-1/4\"\n [choices]=\"xChoices$ | async\"\n [extraBtnClass]=\"'secondary min-w-full'\"\n (selectValue)=\"xProperty$.next($event)\"\n [selected]=\"xProperty$.value\"\n [title]=\"'chart.dropdown.xProperty' | translate\"\n ></gn-ui-dropdown-selector>\n @if (yChoices$ | async; as yChoices) {\n @if (!isCountAggregation) {\n <gn-ui-dropdown-selector\n class=\"basis-1/4\"\n [choices]=\"yChoices\"\n (selectValue)=\"yProperty$.next($event)\"\n [selected]=\"yProperty$.value\"\n [title]=\"'chart.dropdown.yProperty' | translate\"\n class=\"select-y-prop\"\n ></gn-ui-dropdown-selector>\n }\n }\n <gn-ui-dropdown-selector\n class=\"basis-1/4\"\n [choices]=\"aggregationChoices\"\n class=\"aggregation-choices\"\n (selectValue)=\"aggregation$.next($event)\"\n [selected]=\"aggregation$.value\"\n [title]=\"'chart.dropdown.aggregation' | translate\"\n ></gn-ui-dropdown-selector>\n </div>\n <div\n class=\"relative h-full mt-2 bg-white border border-gray-300 rounded-lg overflow-hidden\"\n >\n @if (!error) {\n <gn-ui-chart\n [data]=\"chartData$ | async\"\n [type]=\"chartType$.value\"\n [prettyLabel]=\"prettyLabel$ | async\"\n [labelProperty]=\"labelProperty\"\n [valueProperty]=\"valueProperty\"\n ></gn-ui-chart>\n }\n @if (loading) {\n <gn-ui-loading-mask\n class=\"absolute inset-0\"\n [message]=\"'chart.loading.data' | translate\"\n ></gn-ui-loading-mask>\n }\n @if (error) {\n <gn-ui-popup-alert\n type=\"warning\"\n icon=\"matErrorOutlineOutline\"\n class=\"absolute m-2 inset-0\"\n >\n <span>{{ error }}</span>\n </gn-ui-popup-alert>\n }\n </div>\n</div>\n" }]
39180
+ ], standalone: true, template: "<div class=\"w-full h-full flex flex-col\">\n <div\n class=\"flex flex-col space-y-2 sm:flex-row sm:space-y-0 sm:space-x-2 justify-between text-[13px]\"\n >\n <gn-ui-dropdown-selector\n class=\"basis-1/4\"\n [choices]=\"typeChoices\"\n [extraBtnClass]=\"'secondary min-w-full'\"\n (selectValue)=\"chartType$.next($event)\"\n [selected]=\"chartType$.value\"\n [title]=\"'chart.dropdown.type' | translate\"\n ></gn-ui-dropdown-selector>\n <gn-ui-dropdown-selector\n class=\"basis-1/4\"\n [choices]=\"xChoices$ | async\"\n [extraBtnClass]=\"'secondary min-w-full'\"\n (selectValue)=\"xProperty$.next($event)\"\n [selected]=\"xProperty$.value\"\n [title]=\"'chart.dropdown.xProperty' | translate\"\n ></gn-ui-dropdown-selector>\n @if (yChoices$ | async; as yChoices) {\n <gn-ui-dropdown-selector\n class=\"basis-1/4 flex items-center select-y-prop\"\n [choices]=\"yChoices\"\n [disabled]=\"isCountAggregation\"\n (selectValue)=\"yProperty$.next($event)\"\n [selected]=\"yProperty$.value\"\n [title]=\"'chart.dropdown.yProperty' | translate\"\n ></gn-ui-dropdown-selector>\n }\n <gn-ui-dropdown-selector\n class=\"basis-1/4 aggregation-choices\"\n [choices]=\"aggregationChoices\"\n [disabled]=\"!yProperty$.value\"\n (selectValue)=\"aggregation$.next($event)\"\n [selected]=\"aggregation$.value\"\n [title]=\"'chart.dropdown.aggregation' | translate\"\n ></gn-ui-dropdown-selector>\n </div>\n <div\n class=\"relative h-full mt-2 bg-white border border-gray-300 rounded-lg overflow-hidden\"\n >\n @if (!error) {\n <gn-ui-chart\n [data]=\"chartData$ | async\"\n [type]=\"chartType$.value\"\n [prettyLabel]=\"prettyLabel$ | async\"\n [labelProperty]=\"labelProperty\"\n [valueProperty]=\"valueProperty\"\n ></gn-ui-chart>\n }\n @if (loading) {\n <gn-ui-loading-mask\n class=\"absolute inset-0\"\n [message]=\"'chart.loading.data' | translate\"\n ></gn-ui-loading-mask>\n }\n @if (error) {\n <gn-ui-popup-alert\n type=\"warning\"\n icon=\"matErrorOutlineOutline\"\n class=\"absolute m-2 inset-0\"\n >\n <span>{{ error }}</span>\n </gn-ui-popup-alert>\n }\n </div>\n</div>\n" }]
39173
39181
  }], propDecorators: { featureCatalog: [{
39174
39182
  type: Input
39175
39183
  }], cacheActive: [{
@@ -39900,6 +39908,7 @@ class ExternalViewerButtonComponent {
39900
39908
  this.translateService = inject(TranslateService);
39901
39909
  this.urlTemplate = inject(EXTERNAL_VIEWER_URL_TEMPLATE, { optional: true });
39902
39910
  this.openinNewTab = inject(EXTERNAL_VIEWER_OPEN_NEW_TAB);
39911
+ this.mimeType = '';
39903
39912
  this.extraClass = '';
39904
39913
  }
39905
39914
  get externalViewer() {
@@ -39930,11 +39939,12 @@ class ExternalViewerButtonComponent {
39930
39939
  const url = templateUrl
39931
39940
  .replace('${layer_name}', `${layerName}`)
39932
39941
  .replace('${service_url}', `${encodeURIComponent(this.link.url.toString())}`)
39933
- .replace('${service_type}', `${this.supportedLinkLayerType}`);
39942
+ .replace('${service_type}', `${this.supportedLinkLayerType}`)
39943
+ .replace('${mime_type}', `${encodeURIComponent(this.mimeType)}`);
39934
39944
  window.open(url, this.openinNewTab ? '_blank' : '_self').focus();
39935
39945
  }
39936
39946
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ExternalViewerButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
39937
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ExternalViewerButtonComponent, isStandalone: true, selector: "gn-ui-external-viewer-button", inputs: { link: "link", extraClass: "extraClass" }, ngImport: i0, template: "@if (externalViewer) {\n <gn-ui-button\n (buttonClick)=\"openInExternalViewer()\"\n type=\"primary\"\n [title]=\"'record.externalViewer.open' | translate\"\n [extraClass]=\"extraClass + 'bg-primary ms-2 !rounded-lg'\"\n >\n <ng-icon name=\"matOpenInNew\"></ng-icon>\n </gn-ui-button>\n}\n", styles: [""], dependencies: [{ kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], viewProviders: [
39947
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ExternalViewerButtonComponent, isStandalone: true, selector: "gn-ui-external-viewer-button", inputs: { link: "link", mimeType: "mimeType", extraClass: "extraClass" }, ngImport: i0, template: "@if (externalViewer) {\n <gn-ui-button\n (buttonClick)=\"openInExternalViewer()\"\n type=\"primary\"\n [title]=\"'record.externalViewer.open' | translate\"\n [extraClass]=\"extraClass + 'bg-primary ms-2 !rounded-lg'\"\n >\n <ng-icon name=\"matOpenInNew\"></ng-icon>\n </gn-ui-button>\n}\n", styles: [""], dependencies: [{ kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], viewProviders: [
39938
39948
  provideIcons({ matOpenInNew }),
39939
39949
  provideNgIconsConfig({
39940
39950
  size: '1.5em',
@@ -39951,6 +39961,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
39951
39961
  ], template: "@if (externalViewer) {\n <gn-ui-button\n (buttonClick)=\"openInExternalViewer()\"\n type=\"primary\"\n [title]=\"'record.externalViewer.open' | translate\"\n [extraClass]=\"extraClass + 'bg-primary ms-2 !rounded-lg'\"\n >\n <ng-icon name=\"matOpenInNew\"></ng-icon>\n </gn-ui-button>\n}\n" }]
39952
39962
  }], propDecorators: { link: [{
39953
39963
  type: Input
39964
+ }], mimeType: [{
39965
+ type: Input
39954
39966
  }], extraClass: [{
39955
39967
  type: Input
39956
39968
  }] } });
@@ -40113,7 +40125,7 @@ class GpfApiDlComponent {
40113
40125
  let choicesTest = undefined;
40114
40126
  let pageCount = 1;
40115
40127
  while (choicesTest === undefined && pageCount > page) {
40116
- const response = await axios.get(this.url.concat(`&limit=200&page=${page}`));
40128
+ const response = await fetch(this.url.concat(`&limit=200&page=${page}`)).then((resp) => resp.json());
40117
40129
  choicesTest = response.data.entry.filter((element) => element['id'] == this.apiBaseUrl)[0];
40118
40130
  page += 1;
40119
40131
  pageCount = response.data.pagecount;
@@ -40146,7 +40158,7 @@ class GpfApiDlComponent {
40146
40158
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
40147
40159
  }
40148
40160
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GpfApiDlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
40149
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: GpfApiDlComponent, isStandalone: true, selector: "gn-ui-gpf-api-dl", inputs: { apiLink: "apiLink" }, ngImport: i0, template: "<div class=\"flex flex-col gap-6 p-8 bg-white shadow-xl rounded-lg\">\n <!-- Header with Filter Title and Reset Button -->\n <div class=\"flex items-center justify-between\">\n <h2\n class=\"text-xl font-semibold\"\n translate\n [attr.aria-label]=\"\n 'record.metadata.api.form.filterDescription' | translate\n \"\n >\n record.metadata.api.form.filter\n </h2>\n <button\n (click)=\"resetUrl()\"\n class=\"bg-primary-opacity-50 inline-flex items-center justify-center px-4 py-2 text-white rounded hover:bg-primary transition\"\n [attr.title]=\"'record.metadata.api.form.resetTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.resetTooltip' | translate\"\n >\n <span translate>record.metadata.api.form.reset</span>\n </button>\n </div>\n\n <!-- Dropdown Selectors -->\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <gn-ui-dropdown-selector\n #zone\n [title]=\"'record.metadata.api.form.zoneTitle' | translate\"\n [choices]=\"bucketPromisesZone\"\n (selectValue)=\"setZone($event)\"\n [selected]=\"zone$ | async\"\n class=\"w-full\"\n [attr.title]=\"'record.metadata.api.form.zoneTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.zoneTooltip' | translate\"\n ></gn-ui-dropdown-selector>\n\n <gn-ui-dropdown-selector\n #format\n [title]=\"'record.metadata.api.form.formatTitle' | translate\"\n [choices]=\"bucketPromisesFormat\"\n (selectValue)=\"setFormat($event)\"\n [selected]=\"format$ | async\"\n class=\"w-full\"\n [attr.title]=\"'record.metadata.api.form.formatTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.formatTooltip' | translate\"\n ></gn-ui-dropdown-selector>\n\n <gn-ui-dropdown-selector\n #crs\n [title]=\"'record.metadata.api.form.crsTitle' | translate\"\n [choices]=\"bucketPromisesCrs\"\n (selectValue)=\"setCrs($event)\"\n [selected]=\"crs$ | async\"\n class=\"w-full\"\n [attr.title]=\"'record.metadata.api.form.crsTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.crsTooltip' | translate\"\n ></gn-ui-dropdown-selector>\n </div>\n\n <!-- Filtered Items Section -->\n <div class=\"bg-gray-50 p-4 rounded-lg\">\n <h3\n class=\"text-lg font-medium\"\n translate\n [attr.aria-label]=\"\n 'record.metadata.api.form.itemsDescription' | translate\n \"\n >\n record.metadata.api.form.items\n </h3>\n <div\n class=\"overflow-auto max-h-60\"\n [attr.title]=\"'record.metadata.api.form.itemsTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.itemsTooltip' | translate\"\n >\n @for (link of listFilteredProduct$ | async; track link) {\n <div class=\"mb-2 sm:mb-3\">\n <gn-ui-gpf-api-dl-list-item\n [link]=\"link\"\n color=\"rgb(124 45 18)\"\n [format]=\"getLinkFormat(link)\"\n [isFromWfs]=\"true\"\n [attr.title]=\"'record.metadata.api.form.productTooltip' | translate\"\n [attr.aria-label]=\"\n 'record.metadata.api.form.productTooltip' | translate\n \"\n ></gn-ui-gpf-api-dl-list-item>\n </div>\n }\n </div>\n </div>\n\n <!-- Pagination Section -->\n <div class=\"flex items-center justify-between\">\n <button\n (click)=\"lessResult()\"\n [class]=\"\n 'px-4 py-2 text-white rounded transition ' +\n ((page$ | async) <= 1\n ? 'bg-gray-400 cursor-not-allowed '\n : 'bg-primary-opacity-50 hover:bg-primary')\n \"\n [attr.title]=\"'record.metadata.api.form.previousPageTooltip' | translate\"\n [attr.aria-label]=\"\n 'record.metadata.api.form.previousPageTooltip' | translate\n \"\n >\n <span translate>record.metadata.api.form.previousPage</span>\n </button>\n <div\n class=\"font-semibold place-content-center\"\n [attr.aria-label]=\"\n 'record.metadata.api.form.paginationDescription' | translate\n \"\n >\n {{ page$ | async }}/{{ pageMax$ | async }}\n </div>\n <button\n (click)=\"moreResult()\"\n [class]=\"\n 'bg-primary-opacity-50 px-4 py-2 text-white rounded transition ' +\n ((page$ | async) >= (pageMax$ | async)\n ? 'bg-gray-400 cursor-not-allowed '\n : 'bg-primary-opacity-50 hover:bg-primary')\n \"\n [attr.title]=\"'record.metadata.api.form.nextPageTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.nextPageTooltip' | translate\"\n >\n <span translate>record.metadata.api.form.nextPage</span>\n </button>\n </div>\n</div>\n", styles: [":host ::ng-deep input{color:#000;opacity:1}:host ::ng-deep gn-ui-copy-text-button input[type=text]{color:#000;background-color:#fff}:host ::ng-deep gn-ui-copy-text-button button,host ::ng-deep gn-ui-copy-text-button button:hover{background-color:var(--color-secondary)!important}:host ::ng-deep gn-ui-copy-text-button button ng-icon{color:#fff!important;opacity:1!important}:host ::ng-deep gn-ui-copy-text-button button:hover ng-icon{color:#d3d3d3!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth", "disabled"], outputs: ["selectValue"] }, { kind: "component", type: GpfApiDlListItemComponent, selector: "gn-ui-gpf-api-dl-list-item", inputs: ["link", "color", "format", "isFromWfs"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
40161
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: GpfApiDlComponent, isStandalone: true, selector: "gn-ui-gpf-api-dl", inputs: { apiLink: "apiLink" }, ngImport: i0, template: "<div class=\"flex flex-col gap-6 p-8 bg-white shadow-xl rounded-lg\">\n <!-- Header with Filter Title and Reset Button -->\n <div class=\"flex items-center justify-between\">\n <h2\n class=\"text-xl font-semibold\"\n translate\n [attr.aria-label]=\"\n 'record.metadata.api.form.filterDescription' | translate\n \"\n >\n record.metadata.api.form.filter\n </h2>\n <button\n (click)=\"resetUrl()\"\n class=\"bg-primary/50 inline-flex items-center justify-center px-4 py-2 text-white rounded hover:bg-primary transition\"\n [attr.title]=\"'record.metadata.api.form.resetTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.resetTooltip' | translate\"\n >\n <span translate>record.metadata.api.form.reset</span>\n </button>\n </div>\n\n <!-- Dropdown Selectors -->\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <gn-ui-dropdown-selector\n #zone\n [title]=\"'record.metadata.api.form.zoneTitle' | translate\"\n [choices]=\"bucketPromisesZone\"\n (selectValue)=\"setZone($event)\"\n [selected]=\"zone$ | async\"\n class=\"w-full\"\n [attr.title]=\"'record.metadata.api.form.zoneTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.zoneTooltip' | translate\"\n ></gn-ui-dropdown-selector>\n\n <gn-ui-dropdown-selector\n #format\n [title]=\"'record.metadata.api.form.formatTitle' | translate\"\n [choices]=\"bucketPromisesFormat\"\n (selectValue)=\"setFormat($event)\"\n [selected]=\"format$ | async\"\n class=\"w-full\"\n [attr.title]=\"'record.metadata.api.form.formatTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.formatTooltip' | translate\"\n ></gn-ui-dropdown-selector>\n\n <gn-ui-dropdown-selector\n #crs\n [title]=\"'record.metadata.api.form.crsTitle' | translate\"\n [choices]=\"bucketPromisesCrs\"\n (selectValue)=\"setCrs($event)\"\n [selected]=\"crs$ | async\"\n class=\"w-full\"\n [attr.title]=\"'record.metadata.api.form.crsTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.crsTooltip' | translate\"\n ></gn-ui-dropdown-selector>\n </div>\n\n <!-- Filtered Items Section -->\n <div class=\"bg-gray-50 p-4 rounded-lg\">\n <h3\n class=\"text-lg font-medium\"\n translate\n [attr.aria-label]=\"\n 'record.metadata.api.form.itemsDescription' | translate\n \"\n >\n record.metadata.api.form.items\n </h3>\n <div\n class=\"overflow-auto max-h-60\"\n [attr.title]=\"'record.metadata.api.form.itemsTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.itemsTooltip' | translate\"\n >\n @for (link of listFilteredProduct$ | async; track link) {\n <div class=\"mb-2 sm:mb-3\">\n <gn-ui-gpf-api-dl-list-item\n [link]=\"link\"\n color=\"rgb(124 45 18)\"\n [format]=\"getLinkFormat(link)\"\n [isFromWfs]=\"true\"\n [attr.title]=\"'record.metadata.api.form.productTooltip' | translate\"\n [attr.aria-label]=\"\n 'record.metadata.api.form.productTooltip' | translate\n \"\n ></gn-ui-gpf-api-dl-list-item>\n </div>\n }\n </div>\n </div>\n\n <!-- Pagination Section -->\n <div class=\"flex items-center justify-between\">\n <button\n (click)=\"lessResult()\"\n [class]=\"\n 'px-4 py-2 text-white rounded transition ' +\n ((page$ | async) <= 1\n ? 'bg-gray-400 cursor-not-allowed '\n : 'bg-primary/50 hover:bg-primary')\n \"\n [attr.title]=\"'record.metadata.api.form.previousPageTooltip' | translate\"\n [attr.aria-label]=\"\n 'record.metadata.api.form.previousPageTooltip' | translate\n \"\n >\n <span translate>record.metadata.api.form.previousPage</span>\n </button>\n <div\n class=\"font-semibold place-content-center\"\n [attr.aria-label]=\"\n 'record.metadata.api.form.paginationDescription' | translate\n \"\n >\n {{ page$ | async }}/{{ pageMax$ | async }}\n </div>\n <button\n (click)=\"moreResult()\"\n [class]=\"\n 'bg-primary/50 px-4 py-2 text-white rounded transition ' +\n ((page$ | async) >= (pageMax$ | async)\n ? 'bg-gray-400 cursor-not-allowed '\n : 'bg-primary/50 hover:bg-primary')\n \"\n [attr.title]=\"'record.metadata.api.form.nextPageTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.nextPageTooltip' | translate\"\n >\n <span translate>record.metadata.api.form.nextPage</span>\n </button>\n </div>\n</div>\n", styles: [":host ::ng-deep input{color:#000;opacity:1}:host ::ng-deep gn-ui-copy-text-button input[type=text]{color:#000;background-color:#fff}:host ::ng-deep gn-ui-copy-text-button button,host ::ng-deep gn-ui-copy-text-button button:hover{background-color:var(--color-secondary)!important}:host ::ng-deep gn-ui-copy-text-button button ng-icon{color:#fff!important;opacity:1!important}:host ::ng-deep gn-ui-copy-text-button button:hover ng-icon{color:#d3d3d3!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth", "disabled"], outputs: ["selectValue"] }, { kind: "component", type: GpfApiDlListItemComponent, selector: "gn-ui-gpf-api-dl-list-item", inputs: ["link", "color", "format", "isFromWfs"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
40150
40162
  }
40151
40163
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GpfApiDlComponent, decorators: [{
40152
40164
  type: Component,
@@ -40156,7 +40168,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
40156
40168
  TranslatePipe,
40157
40169
  DropdownSelectorComponent,
40158
40170
  GpfApiDlListItemComponent,
40159
- ], template: "<div class=\"flex flex-col gap-6 p-8 bg-white shadow-xl rounded-lg\">\n <!-- Header with Filter Title and Reset Button -->\n <div class=\"flex items-center justify-between\">\n <h2\n class=\"text-xl font-semibold\"\n translate\n [attr.aria-label]=\"\n 'record.metadata.api.form.filterDescription' | translate\n \"\n >\n record.metadata.api.form.filter\n </h2>\n <button\n (click)=\"resetUrl()\"\n class=\"bg-primary-opacity-50 inline-flex items-center justify-center px-4 py-2 text-white rounded hover:bg-primary transition\"\n [attr.title]=\"'record.metadata.api.form.resetTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.resetTooltip' | translate\"\n >\n <span translate>record.metadata.api.form.reset</span>\n </button>\n </div>\n\n <!-- Dropdown Selectors -->\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <gn-ui-dropdown-selector\n #zone\n [title]=\"'record.metadata.api.form.zoneTitle' | translate\"\n [choices]=\"bucketPromisesZone\"\n (selectValue)=\"setZone($event)\"\n [selected]=\"zone$ | async\"\n class=\"w-full\"\n [attr.title]=\"'record.metadata.api.form.zoneTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.zoneTooltip' | translate\"\n ></gn-ui-dropdown-selector>\n\n <gn-ui-dropdown-selector\n #format\n [title]=\"'record.metadata.api.form.formatTitle' | translate\"\n [choices]=\"bucketPromisesFormat\"\n (selectValue)=\"setFormat($event)\"\n [selected]=\"format$ | async\"\n class=\"w-full\"\n [attr.title]=\"'record.metadata.api.form.formatTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.formatTooltip' | translate\"\n ></gn-ui-dropdown-selector>\n\n <gn-ui-dropdown-selector\n #crs\n [title]=\"'record.metadata.api.form.crsTitle' | translate\"\n [choices]=\"bucketPromisesCrs\"\n (selectValue)=\"setCrs($event)\"\n [selected]=\"crs$ | async\"\n class=\"w-full\"\n [attr.title]=\"'record.metadata.api.form.crsTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.crsTooltip' | translate\"\n ></gn-ui-dropdown-selector>\n </div>\n\n <!-- Filtered Items Section -->\n <div class=\"bg-gray-50 p-4 rounded-lg\">\n <h3\n class=\"text-lg font-medium\"\n translate\n [attr.aria-label]=\"\n 'record.metadata.api.form.itemsDescription' | translate\n \"\n >\n record.metadata.api.form.items\n </h3>\n <div\n class=\"overflow-auto max-h-60\"\n [attr.title]=\"'record.metadata.api.form.itemsTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.itemsTooltip' | translate\"\n >\n @for (link of listFilteredProduct$ | async; track link) {\n <div class=\"mb-2 sm:mb-3\">\n <gn-ui-gpf-api-dl-list-item\n [link]=\"link\"\n color=\"rgb(124 45 18)\"\n [format]=\"getLinkFormat(link)\"\n [isFromWfs]=\"true\"\n [attr.title]=\"'record.metadata.api.form.productTooltip' | translate\"\n [attr.aria-label]=\"\n 'record.metadata.api.form.productTooltip' | translate\n \"\n ></gn-ui-gpf-api-dl-list-item>\n </div>\n }\n </div>\n </div>\n\n <!-- Pagination Section -->\n <div class=\"flex items-center justify-between\">\n <button\n (click)=\"lessResult()\"\n [class]=\"\n 'px-4 py-2 text-white rounded transition ' +\n ((page$ | async) <= 1\n ? 'bg-gray-400 cursor-not-allowed '\n : 'bg-primary-opacity-50 hover:bg-primary')\n \"\n [attr.title]=\"'record.metadata.api.form.previousPageTooltip' | translate\"\n [attr.aria-label]=\"\n 'record.metadata.api.form.previousPageTooltip' | translate\n \"\n >\n <span translate>record.metadata.api.form.previousPage</span>\n </button>\n <div\n class=\"font-semibold place-content-center\"\n [attr.aria-label]=\"\n 'record.metadata.api.form.paginationDescription' | translate\n \"\n >\n {{ page$ | async }}/{{ pageMax$ | async }}\n </div>\n <button\n (click)=\"moreResult()\"\n [class]=\"\n 'bg-primary-opacity-50 px-4 py-2 text-white rounded transition ' +\n ((page$ | async) >= (pageMax$ | async)\n ? 'bg-gray-400 cursor-not-allowed '\n : 'bg-primary-opacity-50 hover:bg-primary')\n \"\n [attr.title]=\"'record.metadata.api.form.nextPageTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.nextPageTooltip' | translate\"\n >\n <span translate>record.metadata.api.form.nextPage</span>\n </button>\n </div>\n</div>\n", styles: [":host ::ng-deep input{color:#000;opacity:1}:host ::ng-deep gn-ui-copy-text-button input[type=text]{color:#000;background-color:#fff}:host ::ng-deep gn-ui-copy-text-button button,host ::ng-deep gn-ui-copy-text-button button:hover{background-color:var(--color-secondary)!important}:host ::ng-deep gn-ui-copy-text-button button ng-icon{color:#fff!important;opacity:1!important}:host ::ng-deep gn-ui-copy-text-button button:hover ng-icon{color:#d3d3d3!important}\n"] }]
40171
+ ], template: "<div class=\"flex flex-col gap-6 p-8 bg-white shadow-xl rounded-lg\">\n <!-- Header with Filter Title and Reset Button -->\n <div class=\"flex items-center justify-between\">\n <h2\n class=\"text-xl font-semibold\"\n translate\n [attr.aria-label]=\"\n 'record.metadata.api.form.filterDescription' | translate\n \"\n >\n record.metadata.api.form.filter\n </h2>\n <button\n (click)=\"resetUrl()\"\n class=\"bg-primary/50 inline-flex items-center justify-center px-4 py-2 text-white rounded hover:bg-primary transition\"\n [attr.title]=\"'record.metadata.api.form.resetTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.resetTooltip' | translate\"\n >\n <span translate>record.metadata.api.form.reset</span>\n </button>\n </div>\n\n <!-- Dropdown Selectors -->\n <div class=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <gn-ui-dropdown-selector\n #zone\n [title]=\"'record.metadata.api.form.zoneTitle' | translate\"\n [choices]=\"bucketPromisesZone\"\n (selectValue)=\"setZone($event)\"\n [selected]=\"zone$ | async\"\n class=\"w-full\"\n [attr.title]=\"'record.metadata.api.form.zoneTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.zoneTooltip' | translate\"\n ></gn-ui-dropdown-selector>\n\n <gn-ui-dropdown-selector\n #format\n [title]=\"'record.metadata.api.form.formatTitle' | translate\"\n [choices]=\"bucketPromisesFormat\"\n (selectValue)=\"setFormat($event)\"\n [selected]=\"format$ | async\"\n class=\"w-full\"\n [attr.title]=\"'record.metadata.api.form.formatTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.formatTooltip' | translate\"\n ></gn-ui-dropdown-selector>\n\n <gn-ui-dropdown-selector\n #crs\n [title]=\"'record.metadata.api.form.crsTitle' | translate\"\n [choices]=\"bucketPromisesCrs\"\n (selectValue)=\"setCrs($event)\"\n [selected]=\"crs$ | async\"\n class=\"w-full\"\n [attr.title]=\"'record.metadata.api.form.crsTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.crsTooltip' | translate\"\n ></gn-ui-dropdown-selector>\n </div>\n\n <!-- Filtered Items Section -->\n <div class=\"bg-gray-50 p-4 rounded-lg\">\n <h3\n class=\"text-lg font-medium\"\n translate\n [attr.aria-label]=\"\n 'record.metadata.api.form.itemsDescription' | translate\n \"\n >\n record.metadata.api.form.items\n </h3>\n <div\n class=\"overflow-auto max-h-60\"\n [attr.title]=\"'record.metadata.api.form.itemsTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.itemsTooltip' | translate\"\n >\n @for (link of listFilteredProduct$ | async; track link) {\n <div class=\"mb-2 sm:mb-3\">\n <gn-ui-gpf-api-dl-list-item\n [link]=\"link\"\n color=\"rgb(124 45 18)\"\n [format]=\"getLinkFormat(link)\"\n [isFromWfs]=\"true\"\n [attr.title]=\"'record.metadata.api.form.productTooltip' | translate\"\n [attr.aria-label]=\"\n 'record.metadata.api.form.productTooltip' | translate\n \"\n ></gn-ui-gpf-api-dl-list-item>\n </div>\n }\n </div>\n </div>\n\n <!-- Pagination Section -->\n <div class=\"flex items-center justify-between\">\n <button\n (click)=\"lessResult()\"\n [class]=\"\n 'px-4 py-2 text-white rounded transition ' +\n ((page$ | async) <= 1\n ? 'bg-gray-400 cursor-not-allowed '\n : 'bg-primary/50 hover:bg-primary')\n \"\n [attr.title]=\"'record.metadata.api.form.previousPageTooltip' | translate\"\n [attr.aria-label]=\"\n 'record.metadata.api.form.previousPageTooltip' | translate\n \"\n >\n <span translate>record.metadata.api.form.previousPage</span>\n </button>\n <div\n class=\"font-semibold place-content-center\"\n [attr.aria-label]=\"\n 'record.metadata.api.form.paginationDescription' | translate\n \"\n >\n {{ page$ | async }}/{{ pageMax$ | async }}\n </div>\n <button\n (click)=\"moreResult()\"\n [class]=\"\n 'bg-primary/50 px-4 py-2 text-white rounded transition ' +\n ((page$ | async) >= (pageMax$ | async)\n ? 'bg-gray-400 cursor-not-allowed '\n : 'bg-primary/50 hover:bg-primary')\n \"\n [attr.title]=\"'record.metadata.api.form.nextPageTooltip' | translate\"\n [attr.aria-label]=\"'record.metadata.api.form.nextPageTooltip' | translate\"\n >\n <span translate>record.metadata.api.form.nextPage</span>\n </button>\n </div>\n</div>\n", styles: [":host ::ng-deep input{color:#000;opacity:1}:host ::ng-deep gn-ui-copy-text-button input[type=text]{color:#000;background-color:#fff}:host ::ng-deep gn-ui-copy-text-button button,host ::ng-deep gn-ui-copy-text-button button:hover{background-color:var(--color-secondary)!important}:host ::ng-deep gn-ui-copy-text-button button ng-icon{color:#fff!important;opacity:1!important}:host ::ng-deep gn-ui-copy-text-button button:hover ng-icon{color:#d3d3d3!important}\n"] }]
40160
40172
  }], propDecorators: { apiLink: [{
40161
40173
  type: Input
40162
40174
  }] } });
@@ -40165,6 +40177,7 @@ marker('map.dropdown.placeholder');
40165
40177
  marker('wfs.feature.limit');
40166
40178
  marker('dataset.error.restrictedAccess');
40167
40179
  marker('map.select.style');
40180
+ marker('map.style.default');
40168
40181
  class MapViewComponent {
40169
40182
  constructor() {
40170
40183
  this.mdViewFacade = inject(MdViewFacade);
@@ -40231,7 +40244,8 @@ class MapViewComponent {
40231
40244
  return compatibleLinks[0];
40232
40245
  }
40233
40246
  }
40234
- }));
40247
+ }), shareReplay$1(1));
40248
+ this.isWmsStyleMode$ = this.selectedSourceLink$.pipe(map$1((src) => src?.type === 'service' && src?.accessServiceProtocol === 'wms'), distinctUntilChanged(), shareReplay$1(1));
40235
40249
  this.styleLinks$ = this.selectedSourceLink$.pipe(switchMap$1((src) => {
40236
40250
  if (src &&
40237
40251
  src.type === 'service' &&
@@ -40248,6 +40262,17 @@ class MapViewComponent {
40248
40262
  return of(src);
40249
40263
  }));
40250
40264
  }
40265
+ if (src &&
40266
+ src.type === 'service' &&
40267
+ src.accessServiceProtocol === 'wms') {
40268
+ return from(new WmsEndpoint(src.url.toString()).isReady()).pipe(map$1((endpoint) => {
40269
+ const layer = endpoint.getLayerByName(src.name);
40270
+ return layer?.styles || [];
40271
+ }), catchError((error) => {
40272
+ this.handleError(error);
40273
+ return of([]);
40274
+ }));
40275
+ }
40251
40276
  return of([]);
40252
40277
  }), tap$1((styles) => {
40253
40278
  if (this._styleFromConfig && this._styleFromConfig <= styles.length) {
@@ -40257,23 +40282,60 @@ class MapViewComponent {
40257
40282
  this.selectedStyleId$.next(0);
40258
40283
  }
40259
40284
  }), shareReplay$1(1));
40260
- this.styleDropdownChoices$ = this.styleLinks$.pipe(map$1((links) => links.length
40285
+ this.styleDropdownChoices$ = combineLatest([
40286
+ this.styleLinks$,
40287
+ this.isWmsStyleMode$,
40288
+ ]).pipe(map$1(([links, isWmsStyleMode]) => links.length
40261
40289
  ? links.map((link, index) => ({
40262
- label: getLinkLabel(link),
40290
+ label: isWmsStyleMode
40291
+ ? link.title || link.name
40292
+ : getLinkLabel(link),
40263
40293
  value: index,
40264
40294
  }))
40265
40295
  : [
40266
40296
  {
40267
- label: '\u00A0\u00A0\u00A0\u00A0',
40297
+ label: this.translateService.instant('map.style.default'),
40268
40298
  value: 0,
40269
40299
  },
40270
40300
  ]));
40301
+ this.selectedWmsStyleName$ = combineLatest([
40302
+ this.styleLinks$,
40303
+ this.isWmsStyleMode$,
40304
+ this.selectedStyleId$.pipe(distinctUntilChanged()),
40305
+ ]).pipe(map$1(([styles, isWmsStyleMode, styleIdx]) => isWmsStyleMode && Array.isArray(styles)
40306
+ ? styles[styleIdx]?.name
40307
+ : undefined));
40271
40308
  this.selectedLink$ = combineLatest([
40272
40309
  this.selectedSourceLink$,
40273
40310
  this.styleLinks$,
40274
40311
  this.selectedStyleId$.pipe(distinctUntilChanged()),
40275
- ]).pipe(map$1(([src, styles, styleIdx]) => (styles.length ? styles[styleIdx] : src)), shareReplay$1(1));
40276
- this.currentLayers$ = combineLatest([this.selectedLink$, this.excludeWfs$]).pipe(switchMap$1(([link, excludeWfs]) => {
40312
+ this.isWmsStyleMode$,
40313
+ ]).pipe(map$1(([src, styles, styleIdx, isWmsStyleMode]) => !isWmsStyleMode && styles.length ? styles[styleIdx] : src), shareReplay$1(1));
40314
+ this.wmsMimeType$ = this.selectedSourceLink$.pipe(switchMap$1((link) => {
40315
+ if (link?.type === 'service' && link?.accessServiceProtocol === 'wms') {
40316
+ return from(new WmsEndpoint(link.url.toString())
40317
+ .isReady()
40318
+ .then((endpoint) => {
40319
+ return endpoint.describeLayer(link.name).then((description) => {
40320
+ if (description) {
40321
+ return description.owsType === 'wfs'
40322
+ ? 'image/png'
40323
+ : 'image/jpeg';
40324
+ }
40325
+ const layer = endpoint.getLayerByName(link.name);
40326
+ return layer?.opaque ? 'image/jpeg' : 'image/png';
40327
+ });
40328
+ })
40329
+ .catch(() => 'image/png'));
40330
+ }
40331
+ return of('');
40332
+ }), shareReplay$1(1));
40333
+ this.currentLayers$ = combineLatest([
40334
+ this.selectedLink$,
40335
+ this.excludeWfs$,
40336
+ this.selectedWmsStyleName$,
40337
+ this.wmsMimeType$,
40338
+ ]).pipe(switchMap$1(([link, excludeWfs, wmsStyleName, wmsMimeType]) => {
40277
40339
  if (!link) {
40278
40340
  return of([]);
40279
40341
  }
@@ -40287,7 +40349,13 @@ class MapViewComponent {
40287
40349
  this.handleError('dataset.error.restrictedAccess');
40288
40350
  return of([]);
40289
40351
  }
40290
- return this.getLayerFromLink(link).pipe(map$1((layer) => [layer]), catchError((e) => {
40352
+ return this.getLayerFromLink(link).pipe(map$1((layer) => layer.type === 'wms'
40353
+ ? {
40354
+ ...layer,
40355
+ ...(wmsStyleName && { style: wmsStyleName }),
40356
+ ...(wmsMimeType && { format: wmsMimeType }),
40357
+ }
40358
+ : layer), map$1((layer) => [layer]), catchError((e) => {
40291
40359
  this.handleError(e);
40292
40360
  return of([]);
40293
40361
  }), finalize(() => (this.loading = false)));
@@ -40441,7 +40509,7 @@ class MapViewComponent {
40441
40509
  this.changeRef.detectChanges();
40442
40510
  }
40443
40511
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MapViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
40444
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: MapViewComponent, isStandalone: true, selector: "gn-ui-map-view", inputs: { exceedsLimit: "exceedsLimit", selectedView: "selectedView", datavizConfig: "datavizConfig", displaySource: "displaySource" }, outputs: { linkSelected: "linkSelected", styleSelected: "styleSelected" }, viewQueries: [{ propertyName: "mapContainer", first: true, predicate: ["mapContainer"], descendants: true }], ngImport: i0, template: "<div class=\"w-full h-full flex flex-col gap-[13px]\">\n <div\n class=\"flex flex-col md:flex-row gap-4 py-4 px-5 bg-white border border-color-border rounded-lg mt-6\"\n >\n @if (displaySource) {\n <gn-ui-dropdown-selector\n class=\"w-full md:flex-1 md:min-w-0\"\n extraBtnClass=\"font-sans font-bold\"\n [title]=\"'map.select.layer' | translate\"\n [choices]=\"dropdownChoices$ | async\"\n [selected]=\"_selectedChoice\"\n (selectValue)=\"selectLinkToDisplay($event)\"\n ></gn-ui-dropdown-selector>\n }\n\n @if ((styleLinks$ | async)?.length > 0) {\n <gn-ui-dropdown-selector\n class=\"w-full md:flex-1 md:min-w-0\"\n extraBtnClass=\"font-sans font-bold\"\n [title]=\"'map.select.style' | translate\"\n [choices]=\"styleDropdownChoices$ | async\"\n [selected]=\"_styleFromConfig\"\n (selectValue)=\"selectStyleToDisplay($event)\"\n ></gn-ui-dropdown-selector>\n } @else {\n <gn-ui-dropdown-selector\n class=\"w-full md:flex-1 md:min-w-0 text-gray-400\"\n extraBtnClass=\"font-sans font-bold text-gray-400\"\n [title]=\"'map.select.style' | translate\"\n [choices]=\"styleDropdownChoices$ | async\"\n [disabled]=\"true\"\n ></gn-ui-dropdown-selector>\n }\n\n <div class=\"self-end md:ml-2\">\n <gn-ui-external-viewer-button\n extraClass=\"w-[44px] h-[44px]\"\n [link]=\"selectedLink$ | async\"\n >\n </gn-ui-external-viewer-button>\n </div>\n </div>\n @if (hidePreview) {\n <gn-ui-popup-alert\n type=\"warning\"\n icon=\"matErrorOutlineOutline\"\n class=\"block h-12 p-1\"\n >\n <span translate>record.feature.limit</span>\n </gn-ui-popup-alert>\n } @else {\n <div\n class=\"relative w-full h-full bg-white border border-gray-300 rounded-lg overflow-hidden\"\n >\n <gn-ui-map-container\n #mapContainer\n [context]=\"mapContext$ | async\"\n (featuresClick)=\"onMapFeatureSelect($event)\"\n (sourceLoadError)=\"onSourceLoadError($event)\"\n ></gn-ui-map-container>\n <div\n class=\"top-[1em] right-[1em] p-3 bg-white absolute overflow-y-auto overflow-x-hidden max-h-72 w-56\"\n [class.hidden]=\"!selection\"\n >\n <gn-ui-button\n type=\"light\"\n (buttonClick)=\"resetSelection()\"\n style=\"\n --gn-ui-button-padding: 0px;\n --gn-ui-button-width: 24px;\n --gn-ui-button-height: 24px;\n \"\n extraClass=\"absolute right-[0.5em] ml-[8px] mr-[10px]\"\n >\n <ng-icon name=\"matClose\" class=\"align-middle text-sm\"></ng-icon>\n </gn-ui-button>\n <gn-ui-feature-detail\n [featureCatalog]=\"mdViewFacade.featureCatalog$ | async\"\n [feature]=\"selection\"\n ></gn-ui-feature-detail>\n </div>\n <div\n class=\"top-[1em] p-3 bg-white absolute overflow-y-auto overflow-x-hidden max-h-72 w-56\"\n [ngClass]=\"{ 'right-[1em]': !selection, 'right-[16em]': selection }\"\n [hidden]=\"!showLegend || !legendExists\"\n >\n <div class=\"flex justify-between items-center mb-2\">\n <div class=\"text-primary font-bold\" translate>map.legend.title</div>\n <gn-ui-button\n type=\"light\"\n (buttonClick)=\"toggleLegend()\"\n style=\"\n --gn-ui-button-padding: 0px;\n --gn-ui-button-width: 24px;\n --gn-ui-button-height: 24px;\n \"\n extraClass=\"ml-[8px] mr-[10px]\"\n >\n <ng-icon name=\"matClose\" class=\"align-middle text-sm\"></ng-icon>\n </gn-ui-button>\n </div>\n <gn-ui-map-legend\n [context]=\"mapContext$ | async\"\n (legendStatusChange)=\"onLegendStatusChange($event)\"\n ></gn-ui-map-legend>\n </div>\n @if (!showLegend && legendExists && !selection) {\n <gn-ui-button\n type=\"outline\"\n (buttonClick)=\"toggleLegend()\"\n extraClass=\"absolute top-[1em] right-[1em] rounded p-1 text-xs bg-white\"\n translate\n >\n {{ 'map.legend.title' | translate }}\n </gn-ui-button>\n }\n @if (loading) {\n <gn-ui-loading-mask\n class=\"absolute inset-0\"\n [message]=\"'map.loading.data' | translate\"\n ></gn-ui-loading-mask>\n }\n @if (error) {\n <gn-ui-popup-alert\n type=\"warning\"\n icon=\"matErrorOutlineOutline\"\n class=\"absolute m-2 inset-0\"\n >\n <span translate>{{ error }}</span>\n </gn-ui-popup-alert>\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: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth", "disabled"], outputs: ["selectValue"] }, { kind: "component", type: MapContainerComponent, selector: "gn-ui-map-container", inputs: ["context"], outputs: ["featuresClick", "featuresHover", "mapClick", "extentChange", "sourceLoadError", "resolvedExtentChange"] }, { kind: "component", type: FeatureDetailComponent, selector: "gn-ui-feature-detail", inputs: ["feature", "featureCatalog"] }, { kind: "component", type: PopupAlertComponent, selector: "gn-ui-popup-alert", inputs: ["icon", "type", "position"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: LoadingMaskComponent, selector: "gn-ui-loading-mask", inputs: ["message"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: ExternalViewerButtonComponent, selector: "gn-ui-external-viewer-button", inputs: ["link", "extraClass"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: MapLegendComponent, selector: "gn-ui-map-legend", inputs: ["context"], outputs: ["legendStatusChange"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], viewProviders: [
40512
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: MapViewComponent, isStandalone: true, selector: "gn-ui-map-view", inputs: { exceedsLimit: "exceedsLimit", selectedView: "selectedView", datavizConfig: "datavizConfig", displaySource: "displaySource" }, outputs: { linkSelected: "linkSelected", styleSelected: "styleSelected" }, viewQueries: [{ propertyName: "mapContainer", first: true, predicate: ["mapContainer"], descendants: true }], ngImport: i0, template: "<div class=\"w-full h-full flex flex-col gap-[13px]\">\n <div\n class=\"flex flex-col md:flex-row gap-4 py-4 px-5 bg-white border border-color-border rounded-lg mt-6\"\n >\n @if (displaySource) {\n <gn-ui-dropdown-selector\n class=\"w-full md:flex-1 md:min-w-0\"\n extraBtnClass=\"font-sans font-bold\"\n [title]=\"'map.select.layer' | translate\"\n [choices]=\"dropdownChoices$ | async\"\n [selected]=\"_selectedChoice\"\n (selectValue)=\"selectLinkToDisplay($event)\"\n ></gn-ui-dropdown-selector>\n }\n\n <gn-ui-dropdown-selector\n class=\"w-full md:flex-1 md:min-w-0\"\n extraBtnClass=\"font-sans font-bold\"\n [title]=\"'map.select.style' | translate\"\n [choices]=\"styleDropdownChoices$ | async\"\n [selected]=\"selectedStyleId$ | async\"\n [disabled]=\"(styleDropdownChoices$ | async)?.length <= 1\"\n (selectValue)=\"selectStyleToDisplay($event)\"\n ></gn-ui-dropdown-selector>\n\n <div class=\"self-end md:ml-2\">\n <gn-ui-external-viewer-button\n extraClass=\"w-[44px] h-[44px]\"\n [link]=\"selectedLink$ | async\"\n [mimeType]=\"wmsMimeType$ | async\"\n >\n </gn-ui-external-viewer-button>\n </div>\n </div>\n @if (hidePreview) {\n <gn-ui-popup-alert\n type=\"warning\"\n icon=\"matErrorOutlineOutline\"\n class=\"block h-12 p-1\"\n >\n <span translate>record.feature.limit</span>\n </gn-ui-popup-alert>\n } @else {\n <div\n class=\"relative w-full h-full bg-white border border-gray-300 rounded-lg overflow-hidden\"\n >\n <gn-ui-map-container\n #mapContainer\n [context]=\"mapContext$ | async\"\n (featuresClick)=\"onMapFeatureSelect($event)\"\n (sourceLoadError)=\"onSourceLoadError($event)\"\n ></gn-ui-map-container>\n <div\n class=\"top-[1em] right-[1em] p-3 bg-white absolute overflow-y-auto overflow-x-hidden max-h-72 w-56\"\n [class.hidden]=\"!selection\"\n >\n <gn-ui-button\n type=\"light\"\n (buttonClick)=\"resetSelection()\"\n style=\"\n --gn-ui-button-padding: 0px;\n --gn-ui-button-width: 24px;\n --gn-ui-button-height: 24px;\n \"\n extraClass=\"absolute right-[0.5em] ml-[8px] mr-[10px]\"\n >\n <ng-icon name=\"matClose\" class=\"align-middle text-sm\"></ng-icon>\n </gn-ui-button>\n <gn-ui-feature-detail\n [featureCatalog]=\"mdViewFacade.featureCatalog$ | async\"\n [feature]=\"selection\"\n ></gn-ui-feature-detail>\n </div>\n <div\n class=\"top-[1em] p-3 bg-white absolute overflow-y-auto overflow-x-hidden max-h-72 w-56\"\n [ngClass]=\"{ 'right-[1em]': !selection, 'right-[16em]': selection }\"\n [hidden]=\"!showLegend || !legendExists\"\n >\n <div class=\"flex justify-between items-center mb-2\">\n <div class=\"text-primary font-bold\" translate>map.legend.title</div>\n <gn-ui-button\n type=\"light\"\n (buttonClick)=\"toggleLegend()\"\n style=\"\n --gn-ui-button-padding: 0px;\n --gn-ui-button-width: 24px;\n --gn-ui-button-height: 24px;\n \"\n extraClass=\"ml-[8px] mr-[10px]\"\n >\n <ng-icon name=\"matClose\" class=\"align-middle text-sm\"></ng-icon>\n </gn-ui-button>\n </div>\n <gn-ui-map-legend\n [context]=\"mapContext$ | async\"\n (legendStatusChange)=\"onLegendStatusChange($event)\"\n ></gn-ui-map-legend>\n </div>\n @if (!showLegend && legendExists && !selection) {\n <gn-ui-button\n type=\"outline\"\n (buttonClick)=\"toggleLegend()\"\n extraClass=\"absolute top-[1em] right-[1em] rounded p-1 text-xs bg-white\"\n translate\n >\n {{ 'map.legend.title' | translate }}\n </gn-ui-button>\n }\n @if (loading) {\n <gn-ui-loading-mask\n class=\"absolute inset-0\"\n [message]=\"'map.loading.data' | translate\"\n ></gn-ui-loading-mask>\n }\n @if (error) {\n <gn-ui-popup-alert\n type=\"warning\"\n icon=\"matErrorOutlineOutline\"\n class=\"absolute m-2 inset-0\"\n >\n <span translate>{{ error }}</span>\n </gn-ui-popup-alert>\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: DropdownSelectorComponent, selector: "gn-ui-dropdown-selector", inputs: ["title", "showTitle", "ariaName", "choices", "selected", "maxRows", "extraBtnClass", "minWidth", "disabled"], outputs: ["selectValue"] }, { kind: "component", type: MapContainerComponent, selector: "gn-ui-map-container", inputs: ["context"], outputs: ["featuresClick", "featuresHover", "mapClick", "extentChange", "sourceLoadError", "resolvedExtentChange"] }, { kind: "component", type: FeatureDetailComponent, selector: "gn-ui-feature-detail", inputs: ["feature", "featureCatalog"] }, { kind: "component", type: PopupAlertComponent, selector: "gn-ui-popup-alert", inputs: ["icon", "type", "position"] }, { kind: "directive", type: TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: LoadingMaskComponent, selector: "gn-ui-loading-mask", inputs: ["message"] }, { kind: "component", type: NgIconComponent, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: ExternalViewerButtonComponent, selector: "gn-ui-external-viewer-button", inputs: ["link", "mimeType", "extraClass"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: MapLegendComponent, selector: "gn-ui-map-legend", inputs: ["context"], outputs: ["legendStatusChange"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], viewProviders: [
40445
40513
  provideIcons({ matClose }),
40446
40514
  provideNgIconsConfig({
40447
40515
  size: '1.5em',
@@ -40468,7 +40536,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
40468
40536
  provideNgIconsConfig({
40469
40537
  size: '1.5em',
40470
40538
  }),
40471
- ], template: "<div class=\"w-full h-full flex flex-col gap-[13px]\">\n <div\n class=\"flex flex-col md:flex-row gap-4 py-4 px-5 bg-white border border-color-border rounded-lg mt-6\"\n >\n @if (displaySource) {\n <gn-ui-dropdown-selector\n class=\"w-full md:flex-1 md:min-w-0\"\n extraBtnClass=\"font-sans font-bold\"\n [title]=\"'map.select.layer' | translate\"\n [choices]=\"dropdownChoices$ | async\"\n [selected]=\"_selectedChoice\"\n (selectValue)=\"selectLinkToDisplay($event)\"\n ></gn-ui-dropdown-selector>\n }\n\n @if ((styleLinks$ | async)?.length > 0) {\n <gn-ui-dropdown-selector\n class=\"w-full md:flex-1 md:min-w-0\"\n extraBtnClass=\"font-sans font-bold\"\n [title]=\"'map.select.style' | translate\"\n [choices]=\"styleDropdownChoices$ | async\"\n [selected]=\"_styleFromConfig\"\n (selectValue)=\"selectStyleToDisplay($event)\"\n ></gn-ui-dropdown-selector>\n } @else {\n <gn-ui-dropdown-selector\n class=\"w-full md:flex-1 md:min-w-0 text-gray-400\"\n extraBtnClass=\"font-sans font-bold text-gray-400\"\n [title]=\"'map.select.style' | translate\"\n [choices]=\"styleDropdownChoices$ | async\"\n [disabled]=\"true\"\n ></gn-ui-dropdown-selector>\n }\n\n <div class=\"self-end md:ml-2\">\n <gn-ui-external-viewer-button\n extraClass=\"w-[44px] h-[44px]\"\n [link]=\"selectedLink$ | async\"\n >\n </gn-ui-external-viewer-button>\n </div>\n </div>\n @if (hidePreview) {\n <gn-ui-popup-alert\n type=\"warning\"\n icon=\"matErrorOutlineOutline\"\n class=\"block h-12 p-1\"\n >\n <span translate>record.feature.limit</span>\n </gn-ui-popup-alert>\n } @else {\n <div\n class=\"relative w-full h-full bg-white border border-gray-300 rounded-lg overflow-hidden\"\n >\n <gn-ui-map-container\n #mapContainer\n [context]=\"mapContext$ | async\"\n (featuresClick)=\"onMapFeatureSelect($event)\"\n (sourceLoadError)=\"onSourceLoadError($event)\"\n ></gn-ui-map-container>\n <div\n class=\"top-[1em] right-[1em] p-3 bg-white absolute overflow-y-auto overflow-x-hidden max-h-72 w-56\"\n [class.hidden]=\"!selection\"\n >\n <gn-ui-button\n type=\"light\"\n (buttonClick)=\"resetSelection()\"\n style=\"\n --gn-ui-button-padding: 0px;\n --gn-ui-button-width: 24px;\n --gn-ui-button-height: 24px;\n \"\n extraClass=\"absolute right-[0.5em] ml-[8px] mr-[10px]\"\n >\n <ng-icon name=\"matClose\" class=\"align-middle text-sm\"></ng-icon>\n </gn-ui-button>\n <gn-ui-feature-detail\n [featureCatalog]=\"mdViewFacade.featureCatalog$ | async\"\n [feature]=\"selection\"\n ></gn-ui-feature-detail>\n </div>\n <div\n class=\"top-[1em] p-3 bg-white absolute overflow-y-auto overflow-x-hidden max-h-72 w-56\"\n [ngClass]=\"{ 'right-[1em]': !selection, 'right-[16em]': selection }\"\n [hidden]=\"!showLegend || !legendExists\"\n >\n <div class=\"flex justify-between items-center mb-2\">\n <div class=\"text-primary font-bold\" translate>map.legend.title</div>\n <gn-ui-button\n type=\"light\"\n (buttonClick)=\"toggleLegend()\"\n style=\"\n --gn-ui-button-padding: 0px;\n --gn-ui-button-width: 24px;\n --gn-ui-button-height: 24px;\n \"\n extraClass=\"ml-[8px] mr-[10px]\"\n >\n <ng-icon name=\"matClose\" class=\"align-middle text-sm\"></ng-icon>\n </gn-ui-button>\n </div>\n <gn-ui-map-legend\n [context]=\"mapContext$ | async\"\n (legendStatusChange)=\"onLegendStatusChange($event)\"\n ></gn-ui-map-legend>\n </div>\n @if (!showLegend && legendExists && !selection) {\n <gn-ui-button\n type=\"outline\"\n (buttonClick)=\"toggleLegend()\"\n extraClass=\"absolute top-[1em] right-[1em] rounded p-1 text-xs bg-white\"\n translate\n >\n {{ 'map.legend.title' | translate }}\n </gn-ui-button>\n }\n @if (loading) {\n <gn-ui-loading-mask\n class=\"absolute inset-0\"\n [message]=\"'map.loading.data' | translate\"\n ></gn-ui-loading-mask>\n }\n @if (error) {\n <gn-ui-popup-alert\n type=\"warning\"\n icon=\"matErrorOutlineOutline\"\n class=\"absolute m-2 inset-0\"\n >\n <span translate>{{ error }}</span>\n </gn-ui-popup-alert>\n }\n </div>\n }\n</div>\n" }]
40539
+ ], template: "<div class=\"w-full h-full flex flex-col gap-[13px]\">\n <div\n class=\"flex flex-col md:flex-row gap-4 py-4 px-5 bg-white border border-color-border rounded-lg mt-6\"\n >\n @if (displaySource) {\n <gn-ui-dropdown-selector\n class=\"w-full md:flex-1 md:min-w-0\"\n extraBtnClass=\"font-sans font-bold\"\n [title]=\"'map.select.layer' | translate\"\n [choices]=\"dropdownChoices$ | async\"\n [selected]=\"_selectedChoice\"\n (selectValue)=\"selectLinkToDisplay($event)\"\n ></gn-ui-dropdown-selector>\n }\n\n <gn-ui-dropdown-selector\n class=\"w-full md:flex-1 md:min-w-0\"\n extraBtnClass=\"font-sans font-bold\"\n [title]=\"'map.select.style' | translate\"\n [choices]=\"styleDropdownChoices$ | async\"\n [selected]=\"selectedStyleId$ | async\"\n [disabled]=\"(styleDropdownChoices$ | async)?.length <= 1\"\n (selectValue)=\"selectStyleToDisplay($event)\"\n ></gn-ui-dropdown-selector>\n\n <div class=\"self-end md:ml-2\">\n <gn-ui-external-viewer-button\n extraClass=\"w-[44px] h-[44px]\"\n [link]=\"selectedLink$ | async\"\n [mimeType]=\"wmsMimeType$ | async\"\n >\n </gn-ui-external-viewer-button>\n </div>\n </div>\n @if (hidePreview) {\n <gn-ui-popup-alert\n type=\"warning\"\n icon=\"matErrorOutlineOutline\"\n class=\"block h-12 p-1\"\n >\n <span translate>record.feature.limit</span>\n </gn-ui-popup-alert>\n } @else {\n <div\n class=\"relative w-full h-full bg-white border border-gray-300 rounded-lg overflow-hidden\"\n >\n <gn-ui-map-container\n #mapContainer\n [context]=\"mapContext$ | async\"\n (featuresClick)=\"onMapFeatureSelect($event)\"\n (sourceLoadError)=\"onSourceLoadError($event)\"\n ></gn-ui-map-container>\n <div\n class=\"top-[1em] right-[1em] p-3 bg-white absolute overflow-y-auto overflow-x-hidden max-h-72 w-56\"\n [class.hidden]=\"!selection\"\n >\n <gn-ui-button\n type=\"light\"\n (buttonClick)=\"resetSelection()\"\n style=\"\n --gn-ui-button-padding: 0px;\n --gn-ui-button-width: 24px;\n --gn-ui-button-height: 24px;\n \"\n extraClass=\"absolute right-[0.5em] ml-[8px] mr-[10px]\"\n >\n <ng-icon name=\"matClose\" class=\"align-middle text-sm\"></ng-icon>\n </gn-ui-button>\n <gn-ui-feature-detail\n [featureCatalog]=\"mdViewFacade.featureCatalog$ | async\"\n [feature]=\"selection\"\n ></gn-ui-feature-detail>\n </div>\n <div\n class=\"top-[1em] p-3 bg-white absolute overflow-y-auto overflow-x-hidden max-h-72 w-56\"\n [ngClass]=\"{ 'right-[1em]': !selection, 'right-[16em]': selection }\"\n [hidden]=\"!showLegend || !legendExists\"\n >\n <div class=\"flex justify-between items-center mb-2\">\n <div class=\"text-primary font-bold\" translate>map.legend.title</div>\n <gn-ui-button\n type=\"light\"\n (buttonClick)=\"toggleLegend()\"\n style=\"\n --gn-ui-button-padding: 0px;\n --gn-ui-button-width: 24px;\n --gn-ui-button-height: 24px;\n \"\n extraClass=\"ml-[8px] mr-[10px]\"\n >\n <ng-icon name=\"matClose\" class=\"align-middle text-sm\"></ng-icon>\n </gn-ui-button>\n </div>\n <gn-ui-map-legend\n [context]=\"mapContext$ | async\"\n (legendStatusChange)=\"onLegendStatusChange($event)\"\n ></gn-ui-map-legend>\n </div>\n @if (!showLegend && legendExists && !selection) {\n <gn-ui-button\n type=\"outline\"\n (buttonClick)=\"toggleLegend()\"\n extraClass=\"absolute top-[1em] right-[1em] rounded p-1 text-xs bg-white\"\n translate\n >\n {{ 'map.legend.title' | translate }}\n </gn-ui-button>\n }\n @if (loading) {\n <gn-ui-loading-mask\n class=\"absolute inset-0\"\n [message]=\"'map.loading.data' | translate\"\n ></gn-ui-loading-mask>\n }\n @if (error) {\n <gn-ui-popup-alert\n type=\"warning\"\n icon=\"matErrorOutlineOutline\"\n class=\"absolute m-2 inset-0\"\n >\n <span translate>{{ error }}</span>\n </gn-ui-popup-alert>\n }\n </div>\n }\n</div>\n" }]
40472
40540
  }], propDecorators: { exceedsLimit: [{
40473
40541
  type: Input
40474
40542
  }], selectedView: [{
@@ -41123,6 +41191,7 @@ const saveRecordSuccess = createAction('[Editor] Save record success');
41123
41191
  const saveRecordFailure = createAction('[Editor] Save record failure', props());
41124
41192
  const draftSaveSuccess = createAction('[Editor] Draft save success');
41125
41193
  const undoRecordDraft = createAction('[Editor] Undo record draft');
41194
+ const setEditorConfiguration = createAction('[Editor] Set editor configuration', props());
41126
41195
  const setCurrentPage = createAction('[Editor] Set current page', props());
41127
41196
  const setFieldVisibility = createAction('[Editor] Set field visibility', props());
41128
41197
  const hasRecordChangedSinceDraft = createAction('[Editor] Has Record Changed Since Draft', props());
@@ -41545,6 +41614,9 @@ const reducer = createReducer(initialEditorState, on(openRecord, (state, { recor
41545
41614
  })), on(markRecordAsChanged, (state) => ({
41546
41615
  ...state,
41547
41616
  changedSinceSave: true,
41617
+ })), on(setEditorConfiguration, (state, { configuration }) => ({
41618
+ ...state,
41619
+ editorConfig: configuration,
41548
41620
  })), on(setCurrentPage, (state, { page }) => ({
41549
41621
  ...state,
41550
41622
  currentPage: page,
@@ -41647,6 +41719,9 @@ class EditorFacade {
41647
41719
  updateRecordLanguages(defaultLanguage, otherLanguages) {
41648
41720
  this.store.dispatch(updateRecordLanguages({ defaultLanguage, otherLanguages }));
41649
41721
  }
41722
+ setConfiguration(configuration) {
41723
+ this.store.dispatch(setEditorConfiguration({ configuration }));
41724
+ }
41650
41725
  setCurrentPage(page) {
41651
41726
  this.store.dispatch(setCurrentPage({ page }));
41652
41727
  }
@@ -41669,149 +41744,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
41669
41744
  type: Injectable
41670
41745
  }] });
41671
41746
 
41672
- function evaluate(expression) {
41673
- if (expression.match(/^\${.*}$/)) {
41674
- return evaluate(expression.slice(2, -1));
41675
- }
41676
- const operator = expression.split('(')[0];
41677
- switch (operator) {
41678
- case 'dateNow':
41679
- return () => new Date();
41680
- default:
41681
- throw new Error(`Unknown operator: ${operator}`);
41682
- }
41683
- }
41684
-
41685
- class EditorService {
41686
- constructor() {
41687
- this.recordsRepository = inject(RecordsRepositoryInterface);
41688
- }
41689
- // returns the record as it was when saved, alongside its source
41690
- saveRecord(record, recordSource, fieldsConfig) {
41691
- const savedRecord = { ...record };
41692
- const fields = fieldsConfig.pages.flatMap((page) => page.sections.flatMap((section) => section.fields));
41693
- // run onSave processes
41694
- for (const field of fields) {
41695
- if (field.onSaveProcess && field.model) {
41696
- const evaluator = evaluate(field.onSaveProcess);
41697
- savedRecord[field.model] = evaluator({
41698
- model: field.model,
41699
- value: record[field.model],
41700
- });
41701
- }
41702
- }
41703
- let publishToAll = true;
41704
- // if the record is new, generate a new unique identifier and pass publishToAll as false
41705
- if (!record.uniqueIdentifier) {
41706
- savedRecord.uniqueIdentifier = null;
41707
- publishToAll = false;
41708
- }
41709
- return this.recordsRepository
41710
- .saveRecord(savedRecord, recordSource, publishToAll)
41711
- .pipe(switchMap((uniqueIdentifier) => this.recordsRepository.openRecordForEdition(uniqueIdentifier)), tap$1(() => {
41712
- // if saving was successful, the original draft can be discarded
41713
- this.recordsRepository.clearRecordDraft(record.uniqueIdentifier);
41714
- }), map$1(([record, recordSource]) => [record, recordSource]));
41715
- }
41716
- // emits and completes once saving is done
41717
- // note: onSave processes are not run for drafts
41718
- saveRecordAsDraft(record, recordSource) {
41719
- record.recordUpdated = new Date();
41720
- return this.recordsRepository
41721
- .saveRecordAsDraft(record, recordSource)
41722
- .pipe(map$1(() => undefined));
41723
- }
41724
- undoRecordDraft(record) {
41725
- this.recordsRepository.clearRecordDraft(record.uniqueIdentifier);
41726
- return this.recordsRepository.openRecordForEdition(record.uniqueIdentifier);
41727
- }
41728
- hasRecordChangedSinceDraft(localRecord) {
41729
- return this.recordsRepository.hasRecordChangedSinceDraft(localRecord);
41730
- }
41731
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
41732
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorService, providedIn: 'root' }); }
41733
- }
41734
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorService, decorators: [{
41735
- type: Injectable,
41736
- args: [{
41737
- providedIn: 'root',
41738
- }]
41739
- }] });
41740
-
41741
- class EditorEffects {
41742
- constructor() {
41743
- this.actions$ = inject(Actions);
41744
- this.editorService = inject(EditorService);
41745
- this.recordsRepository = inject(RecordsRepositoryInterface);
41746
- this.plateformService = inject(PlatformServiceInterface);
41747
- this.store = inject(Store);
41748
- 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]) => {
41749
- const actions = [saveRecordSuccess()];
41750
- if (!record?.uniqueIdentifier) {
41751
- actions.push(openRecord({
41752
- record: savedRecord,
41753
- recordSource: savedRecordSource,
41754
- }));
41755
- }
41756
- return of(...actions);
41757
- }), catchError((error) => of(saveRecordFailure({
41758
- error,
41759
- })))))));
41760
- this.cleanRecordAttachments$ = createEffect(() => this.actions$.pipe(ofType(saveRecordSuccess), withLatestFrom$1(this.store.select(selectRecord)), switchMap$1(([_, record]) => {
41761
- if (record.uniqueIdentifier !== null) {
41762
- this.plateformService.cleanRecordAttachments(record).subscribe({
41763
- next: (_) => undefined,
41764
- error: (err) => {
41765
- console.error(err);
41766
- },
41767
- });
41768
- }
41769
- return EMPTY;
41770
- }), catchError((error) => {
41771
- console.error(error);
41772
- return EMPTY;
41773
- })), { dispatch: false });
41774
- this.markAsChanged$ = createEffect(() => this.actions$.pipe(ofType(updateRecordField, updateRecordLanguages), map$1(() => markRecordAsChanged())));
41775
- 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())));
41776
- 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({
41777
- record,
41778
- recordSource,
41779
- }))));
41780
- this.checkHasChangesOnOpen$ = createEffect(() => this.actions$.pipe(ofType(openRecord), map$1(({ record }) => this.recordsRepository.recordHasDraft(record.uniqueIdentifier)), filter((hasDraft) => hasDraft), map$1(() => markRecordAsChanged())));
41781
- this.hasRecordChangedSinceDraft$ = createEffect(() => this.actions$.pipe(ofType(hasRecordChangedSinceDraft), switchMap$1(({ record }) => this.editorService
41782
- .hasRecordChangedSinceDraft(record)
41783
- .pipe(map$1((changes) => hasRecordChangedSinceDraftSuccess({ changes }))))));
41784
- 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({
41785
- isPublished: isPublished$1,
41786
- }))));
41787
- 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({
41788
- canEditRecord: canEditRecord$1,
41789
- }))));
41790
- }
41791
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorEffects, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
41792
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorEffects }); }
41793
- }
41794
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorEffects, decorators: [{
41795
- type: Injectable
41796
- }] });
41797
-
41798
- class FeatureEditorModule {
41799
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
41800
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, imports: [i1.StoreFeatureModule, i2$2.EffectsFeatureModule] }); }
41801
- 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),
41802
- EffectsModule.forFeature([EditorEffects])] }); }
41803
- }
41804
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, decorators: [{
41805
- type: NgModule,
41806
- args: [{
41807
- imports: [
41808
- StoreModule.forFeature(EDITOR_FEATURE_KEY, editorReducer),
41809
- EffectsModule.forFeature([EditorEffects]),
41810
- ],
41811
- providers: [EditorFacade, provideHttpClient()],
41812
- }]
41813
- }] });
41814
-
41815
41747
  class ImportRecordComponent {
41816
41748
  constructor() {
41817
41749
  this.router = inject(Router);
@@ -41907,6 +41839,328 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
41907
41839
  type: Output
41908
41840
  }] } });
41909
41841
 
41842
+ //forced translations that are not available in fields.config.ts
41843
+ marker('editor.record.form.field.keywords');
41844
+ marker('editor.record.form.field.topics');
41845
+ marker('editor.record.form.field.contacts');
41846
+ marker('editor.record.form.field.organisation');
41847
+ class MetadataQualityPanelComponent {
41848
+ constructor() {
41849
+ this.propsToValidate = getAllKeysValidator();
41850
+ this.propertiesByPage = [];
41851
+ }
41852
+ ngOnChanges() {
41853
+ if (this.editorConfig && this.record) {
41854
+ const fieldsByPage = this.editorConfig.pages.map((page) => page.sections.flatMap((section) => section.fields
41855
+ .filter((field) => this.propsToValidate.includes(field.model))
41856
+ .map((field) => field.model)));
41857
+ // FIXME: temporarily add topics and organisation to the first and third page
41858
+ // as long as they are not handled by the editor
41859
+ if (fieldsByPage.length > 0) {
41860
+ fieldsByPage[0].includes('topics') || fieldsByPage[0].push('topics');
41861
+ fieldsByPage[2].includes('organisation') ||
41862
+ fieldsByPage[2].push('organisation');
41863
+ }
41864
+ this.propertiesByPage = fieldsByPage
41865
+ .map((fields) => getQualityValidators(this.record, fields).map(({ name, validator }) => ({
41866
+ label: `editor.record.form.field.${name}`, // use same translations as in fields.config.ts
41867
+ value: validator(),
41868
+ })))
41869
+ .filter((arr) => arr.length > 0);
41870
+ }
41871
+ }
41872
+ getExtraClass(checked) {
41873
+ 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';
41874
+ return checked
41875
+ ? `${baseClasses} bg-neutral-100 hover:bg-neutral-100`
41876
+ : `${baseClasses} bg-transparent hover:bg-transparent`;
41877
+ }
41878
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MetadataQualityPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
41879
+ 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: [
41880
+ provideIcons({
41881
+ iconoirSystemShut,
41882
+ iconoirBadgeCheck,
41883
+ }),
41884
+ provideNgIconsConfig({
41885
+ size: '1.25em',
41886
+ }),
41887
+ ], 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" }] }); }
41888
+ }
41889
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MetadataQualityPanelComponent, decorators: [{
41890
+ type: Component,
41891
+ args: [{ selector: 'gn-ui-metadata-quality-panel', standalone: true, imports: [
41892
+ TranslateDirective,
41893
+ TranslatePipe,
41894
+ ButtonComponent,
41895
+ NgIconComponent,
41896
+ ], providers: [
41897
+ provideIcons({
41898
+ iconoirSystemShut,
41899
+ iconoirBadgeCheck,
41900
+ }),
41901
+ provideNgIconsConfig({
41902
+ size: '1.25em',
41903
+ }),
41904
+ ], 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" }]
41905
+ }], propDecorators: { editorConfig: [{
41906
+ type: Input
41907
+ }], record: [{
41908
+ type: Input
41909
+ }] } });
41910
+
41911
+ const extraFlagMap = {
41912
+ ar: 'arab',
41913
+ en: 'gb',
41914
+ ko: 'kr',
41915
+ cs: 'cz',
41916
+ zh: 'cn',
41917
+ ca: 'es-ct',
41918
+ rm: 'ch',
41919
+ da: 'dk',
41920
+ sv: 'se',
41921
+ cy: 'gb-wls',
41922
+ hy: 'am',
41923
+ ka: 'ge',
41924
+ uk: 'ua',
41925
+ };
41926
+ class MultilingualPanelComponent {
41927
+ constructor() {
41928
+ this.facade = inject(EditorFacade);
41929
+ this.dialog = inject(MatDialog);
41930
+ this.translateService = inject(TranslateService);
41931
+ this.recordsRepository = inject(RecordsRepositoryInterface);
41932
+ this.overlay = inject(Overlay);
41933
+ this.viewContainerRef = inject(ViewContainerRef);
41934
+ this.cdr = inject(ChangeDetectorRef);
41935
+ this.selectedLanguages = [];
41936
+ this.recordLanguages = [];
41937
+ this.formLanguage = '';
41938
+ this.isActionMenuOpen = false;
41939
+ this.subscription = new Subscription();
41940
+ this.supportedLanguages$ = this.recordsRepository
41941
+ .getApplicationLanguages()
41942
+ .pipe(map$2((languages) => this.sortLanguages(languages)));
41943
+ }
41944
+ set record(value) {
41945
+ this._record = value;
41946
+ this.isMultilingual = value.otherLanguages.length > 0;
41947
+ this.editTranslations = false;
41948
+ this.recordLanguages = [...value.otherLanguages, value.defaultLanguage];
41949
+ this.selectedLanguages = this.recordLanguages;
41950
+ this.formLanguage = value.defaultLanguage;
41951
+ }
41952
+ ngOnDestroy() {
41953
+ this.subscription.unsubscribe();
41954
+ }
41955
+ sortLanguages(languages) {
41956
+ return languages
41957
+ .map((lang) => {
41958
+ const label = this.translateService.instant('language.' + lang);
41959
+ const isTranslated = label !== 'language.' + lang;
41960
+ return {
41961
+ lang,
41962
+ label,
41963
+ isTranslated,
41964
+ };
41965
+ })
41966
+ .sort((a, b) => {
41967
+ if (a.isTranslated && !b.isTranslated)
41968
+ return -1;
41969
+ if (!a.isTranslated && b.isTranslated)
41970
+ return 1;
41971
+ return a.label.localeCompare(b.label);
41972
+ })
41973
+ .map((item) => item.lang);
41974
+ }
41975
+ toggleLanguageSelection() {
41976
+ this.editTranslations = !this.editTranslations;
41977
+ }
41978
+ getIconClass(lang) {
41979
+ return extraFlagMap[lang]
41980
+ ? `fi fi-${extraFlagMap[lang]} w-4 h-3`
41981
+ : `fi fi-${lang} w-4 h-3`;
41982
+ }
41983
+ switchMultilingual() {
41984
+ if (this.isMultilingual && this.selectedLanguages.length > 1) {
41985
+ this.confirmDeleteAction();
41986
+ }
41987
+ else {
41988
+ this.isMultilingual = true;
41989
+ this.editTranslations = true;
41990
+ }
41991
+ }
41992
+ getExtraClass(lang) {
41993
+ const baseClass = 'h-[34px] w-full font-bold justify-start hover:bg-white';
41994
+ if (this.selectedLanguages.includes(lang)) {
41995
+ return `${baseClass} bg-white border border-black`;
41996
+ }
41997
+ return baseClass;
41998
+ }
41999
+ toggleLanguage(lang) {
42000
+ if (this.selectedLanguages.includes(lang)) {
42001
+ this.removeSelectedLanguage(lang);
42002
+ }
42003
+ else {
42004
+ this.selectedLanguages.push(lang);
42005
+ }
42006
+ }
42007
+ removeSelectedLanguage(lang) {
42008
+ this.selectedLanguages = this.selectedLanguages.filter((language) => language !== lang);
42009
+ }
42010
+ validateTranslations() {
42011
+ const equalLength = this.selectedLanguages.length === this.recordLanguages.length;
42012
+ if (this.selectedLanguages.length < this.recordLanguages.length ||
42013
+ (equalLength && this.selectedLanguages !== this.recordLanguages)) {
42014
+ this.confirmDeleteAction(this.selectedLanguages);
42015
+ }
42016
+ else {
42017
+ this.updateTranslations();
42018
+ }
42019
+ }
42020
+ updateTranslations() {
42021
+ const newLanguageSelection = this.selectedLanguages.filter((lang) => lang !== this.formLanguage);
42022
+ this.facade.updateRecordLanguages(this.formLanguage, newLanguageSelection);
42023
+ this.recordLanguages = newLanguageSelection;
42024
+ this.editTranslations = false;
42025
+ }
42026
+ switchFormLang(lang) {
42027
+ // TO IMPLEMENT FURTHER
42028
+ }
42029
+ switchDefaultLang(lang) {
42030
+ this.formLanguage = lang;
42031
+ this.facade.updateRecordLanguages(lang, this.selectedLanguages.filter((lang) => lang !== this.formLanguage));
42032
+ this.closeActionMenu();
42033
+ }
42034
+ confirmDeleteAction(lang) {
42035
+ const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
42036
+ data: {
42037
+ title: this.translateService.instant('editor.record.multilingual.confirmation.title'),
42038
+ message: this.translateService.instant('editor.record.multilingual.confirmation.message'),
42039
+ confirmText: this.translateService.instant('editor.record.multilingual.confirmation.confirmText'),
42040
+ cancelText: this.translateService.instant('editor.record.multilingual.confirmation.cancelText'),
42041
+ focusCancel: true,
42042
+ },
42043
+ restoreFocus: true,
42044
+ });
42045
+ this.subscription.add(dialogRef.afterClosed().subscribe((confirmed) => {
42046
+ if (confirmed) {
42047
+ if (lang) {
42048
+ if (!Array.isArray(lang)) {
42049
+ this.removeSelectedLanguage(lang);
42050
+ this.closeActionMenu();
42051
+ }
42052
+ this.updateTranslations();
42053
+ }
42054
+ else {
42055
+ this.facade.updateRecordLanguages(this.formLanguage, []);
42056
+ this.isMultilingual = false;
42057
+ this.selectedLanguages = [];
42058
+ }
42059
+ }
42060
+ else {
42061
+ this.isMultilingual = true;
42062
+ this.selectedLanguages = this.recordLanguages;
42063
+ }
42064
+ this.editTranslations = false;
42065
+ }));
42066
+ }
42067
+ isFirstUnsupported(index) {
42068
+ const langs = this.sortLanguages(this.recordLanguages);
42069
+ return (langs[index].length === 3 &&
42070
+ langs.slice(0, index).every((lang) => lang.length !== 3));
42071
+ }
42072
+ isLangSupported(lang) {
42073
+ return lang.length === 2;
42074
+ }
42075
+ getToggleTitle(lang) {
42076
+ if (lang === this._record.defaultLanguage) {
42077
+ return this.translateService.instant('editor.record.form.multilingual.forbidden');
42078
+ }
42079
+ return '';
42080
+ }
42081
+ openActionMenu(item, template) {
42082
+ this.isActionMenuOpen = true;
42083
+ const index = this.sortLanguages(this.selectedLanguages).indexOf(item);
42084
+ const buttonElement = this.actionMenuButtons.toArray()[index];
42085
+ const positionStrategy = this.overlay
42086
+ .position()
42087
+ .flexibleConnectedTo(buttonElement)
42088
+ .withFlexibleDimensions(true)
42089
+ .withPush(true)
42090
+ .withPositions([
42091
+ {
42092
+ originX: 'end',
42093
+ originY: 'bottom',
42094
+ overlayX: 'end',
42095
+ overlayY: 'top',
42096
+ },
42097
+ {
42098
+ originX: 'end',
42099
+ originY: 'top',
42100
+ overlayX: 'end',
42101
+ overlayY: 'bottom',
42102
+ },
42103
+ ]);
42104
+ this.overlayRef = this.overlay.create({
42105
+ hasBackdrop: true,
42106
+ backdropClass: 'cdk-overlay-transparent-backdrop',
42107
+ positionStrategy: positionStrategy,
42108
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
42109
+ });
42110
+ const portal = new TemplatePortal(template, this.viewContainerRef);
42111
+ this.overlayRef.attach(portal);
42112
+ this.subscription.add(this.overlayRef.backdropClick().subscribe(() => {
42113
+ this.closeActionMenu();
42114
+ }));
42115
+ }
42116
+ closeActionMenu() {
42117
+ if (this.overlayRef) {
42118
+ this.isActionMenuOpen = false;
42119
+ this.overlayRef.dispose();
42120
+ this.cdr.markForCheck();
42121
+ }
42122
+ }
42123
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MultilingualPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
42124
+ 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: [
42125
+ provideIcons({
42126
+ iconoirSettings,
42127
+ matMoreHorizOutline,
42128
+ iconoirCheckCircle,
42129
+ iconoirCircle,
42130
+ }),
42131
+ provideNgIconsConfig({
42132
+ size: '1.25em',
42133
+ }),
42134
+ ], 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" }] }); }
42135
+ }
42136
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MultilingualPanelComponent, decorators: [{
42137
+ type: Component,
42138
+ args: [{ selector: 'gn-ui-multilingual-panel', standalone: true, imports: [
42139
+ CommonModule,
42140
+ CheckToggleComponent,
42141
+ TranslateDirective,
42142
+ TranslatePipe,
42143
+ ButtonComponent,
42144
+ NgIconComponent,
42145
+ ActionMenuComponent,
42146
+ ], providers: [
42147
+ provideIcons({
42148
+ iconoirSettings,
42149
+ matMoreHorizOutline,
42150
+ iconoirCheckCircle,
42151
+ iconoirCircle,
42152
+ }),
42153
+ provideNgIconsConfig({
42154
+ size: '1.25em',
42155
+ }),
42156
+ ], 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" }]
42157
+ }], propDecorators: { record: [{
42158
+ type: Input
42159
+ }], actionMenuButtons: [{
42160
+ type: ViewChildren,
42161
+ args: ['actionMenuButton', { read: ElementRef }]
42162
+ }] } });
42163
+
41910
42164
  class GenericKeywordsComponent {
41911
42165
  constructor() {
41912
42166
  this.platformService = inject(PlatformServiceInterface);
@@ -43713,7 +43967,7 @@ class FormFieldComponent {
43713
43967
  }
43714
43968
  }
43715
43969
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
43716
- 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 }); }
43970
+ 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 }); }
43717
43971
  }
43718
43972
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormFieldComponent, decorators: [{
43719
43973
  type: Component,
@@ -43740,7 +43994,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
43740
43994
  FormFieldSpatialToggleComponent,
43741
43995
  FormFieldTopicsComponent,
43742
43996
  TextFieldModule,
43743
- ], 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" }]
43997
+ ], 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" }]
43744
43998
  }], propDecorators: { uniqueIdentifier: [{
43745
43999
  type: Input
43746
44000
  }], model: [{
@@ -43785,327 +44039,148 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
43785
44039
  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" }]
43786
44040
  }] });
43787
44041
 
43788
- const extraFlagMap = {
43789
- ar: 'arab',
43790
- en: 'gb',
43791
- ko: 'kr',
43792
- cs: 'cz',
43793
- zh: 'cn',
43794
- ca: 'es-ct',
43795
- rm: 'ch',
43796
- da: 'dk',
43797
- sv: 'se',
43798
- cy: 'gb-wls',
43799
- hy: 'am',
43800
- ka: 'ge',
43801
- uk: 'ua',
43802
- };
43803
- class MultilingualPanelComponent {
43804
- constructor() {
43805
- this.facade = inject(EditorFacade);
43806
- this.dialog = inject(MatDialog);
43807
- this.translateService = inject(TranslateService);
43808
- this.recordsRepository = inject(RecordsRepositoryInterface);
43809
- this.overlay = inject(Overlay);
43810
- this.viewContainerRef = inject(ViewContainerRef);
43811
- this.cdr = inject(ChangeDetectorRef);
43812
- this.selectedLanguages = [];
43813
- this.recordLanguages = [];
43814
- this.formLanguage = '';
43815
- this.isActionMenuOpen = false;
43816
- this.subscription = new Subscription();
43817
- this.supportedLanguages$ = this.recordsRepository
43818
- .getApplicationLanguages()
43819
- .pipe(map$2((languages) => this.sortLanguages(languages)));
43820
- }
43821
- set record(value) {
43822
- this._record = value;
43823
- this.isMultilingual = value.otherLanguages.length > 0;
43824
- this.editTranslations = false;
43825
- this.recordLanguages = [...value.otherLanguages, value.defaultLanguage];
43826
- this.selectedLanguages = this.recordLanguages;
43827
- this.formLanguage = value.defaultLanguage;
43828
- }
43829
- ngOnDestroy() {
43830
- this.subscription.unsubscribe();
43831
- }
43832
- sortLanguages(languages) {
43833
- return languages
43834
- .map((lang) => {
43835
- const label = this.translateService.instant('language.' + lang);
43836
- const isTranslated = label !== 'language.' + lang;
43837
- return {
43838
- lang,
43839
- label,
43840
- isTranslated,
43841
- };
43842
- })
43843
- .sort((a, b) => {
43844
- if (a.isTranslated && !b.isTranslated)
43845
- return -1;
43846
- if (!a.isTranslated && b.isTranslated)
43847
- return 1;
43848
- return a.label.localeCompare(b.label);
43849
- })
43850
- .map((item) => item.lang);
43851
- }
43852
- toggleLanguageSelection() {
43853
- this.editTranslations = !this.editTranslations;
43854
- }
43855
- getIconClass(lang) {
43856
- return extraFlagMap[lang]
43857
- ? `fi fi-${extraFlagMap[lang]} w-4 h-3`
43858
- : `fi fi-${lang} w-4 h-3`;
43859
- }
43860
- switchMultilingual() {
43861
- if (this.isMultilingual && this.selectedLanguages.length > 1) {
43862
- this.confirmDeleteAction();
43863
- }
43864
- else {
43865
- this.isMultilingual = true;
43866
- this.editTranslations = true;
43867
- }
43868
- }
43869
- getExtraClass(lang) {
43870
- const baseClass = 'h-[34px] w-full font-bold justify-start hover:bg-white';
43871
- if (this.selectedLanguages.includes(lang)) {
43872
- return `${baseClass} bg-white border border-black`;
43873
- }
43874
- return baseClass;
44042
+ function evaluate(expression) {
44043
+ if (expression.match(/^\${.*}$/)) {
44044
+ return evaluate(expression.slice(2, -1));
43875
44045
  }
43876
- toggleLanguage(lang) {
43877
- if (this.selectedLanguages.includes(lang)) {
43878
- this.removeSelectedLanguage(lang);
43879
- }
43880
- else {
43881
- this.selectedLanguages.push(lang);
43882
- }
44046
+ const operator = expression.split('(')[0];
44047
+ switch (operator) {
44048
+ case 'dateNow':
44049
+ return () => new Date();
44050
+ default:
44051
+ throw new Error(`Unknown operator: ${operator}`);
43883
44052
  }
43884
- removeSelectedLanguage(lang) {
43885
- this.selectedLanguages = this.selectedLanguages.filter((language) => language !== lang);
44053
+ }
44054
+
44055
+ class EditorService {
44056
+ constructor() {
44057
+ this.recordsRepository = inject(RecordsRepositoryInterface);
43886
44058
  }
43887
- validateTranslations() {
43888
- const equalLength = this.selectedLanguages.length === this.recordLanguages.length;
43889
- if (this.selectedLanguages.length < this.recordLanguages.length ||
43890
- (equalLength && this.selectedLanguages !== this.recordLanguages)) {
43891
- this.confirmDeleteAction(this.selectedLanguages);
44059
+ // returns the record as it was when saved, alongside its source
44060
+ saveRecord(record, recordSource, fieldsConfig) {
44061
+ const savedRecord = { ...record };
44062
+ const fields = fieldsConfig.pages.flatMap((page) => page.sections.flatMap((section) => section.fields));
44063
+ // run onSave processes
44064
+ for (const field of fields) {
44065
+ if (field.onSaveProcess && field.model) {
44066
+ const evaluator = evaluate(field.onSaveProcess);
44067
+ savedRecord[field.model] = evaluator({
44068
+ model: field.model,
44069
+ value: record[field.model],
44070
+ });
44071
+ }
43892
44072
  }
43893
- else {
43894
- this.updateTranslations();
44073
+ let publishToAll = true;
44074
+ // if the record is new, generate a new unique identifier and pass publishToAll as false
44075
+ if (!record.uniqueIdentifier) {
44076
+ savedRecord.uniqueIdentifier = null;
44077
+ publishToAll = false;
43895
44078
  }
44079
+ return this.recordsRepository
44080
+ .saveRecord(savedRecord, recordSource, publishToAll)
44081
+ .pipe(switchMap((uniqueIdentifier) => this.recordsRepository.openRecordForEdition(uniqueIdentifier)), tap$1(() => {
44082
+ // if saving was successful, the original draft can be discarded
44083
+ this.recordsRepository.clearRecordDraft(record.uniqueIdentifier);
44084
+ }), map$1(([record, recordSource]) => [record, recordSource]));
43896
44085
  }
43897
- updateTranslations() {
43898
- const newLanguageSelection = this.selectedLanguages.filter((lang) => lang !== this.formLanguage);
43899
- this.facade.updateRecordLanguages(this.formLanguage, newLanguageSelection);
43900
- this.recordLanguages = newLanguageSelection;
43901
- this.editTranslations = false;
43902
- }
43903
- switchFormLang(lang) {
43904
- // TO IMPLEMENT FURTHER
43905
- }
43906
- switchDefaultLang(lang) {
43907
- this.formLanguage = lang;
43908
- this.facade.updateRecordLanguages(lang, this.selectedLanguages.filter((lang) => lang !== this.formLanguage));
43909
- this.closeActionMenu();
43910
- }
43911
- confirmDeleteAction(lang) {
43912
- const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
43913
- data: {
43914
- title: this.translateService.instant('editor.record.multilingual.confirmation.title'),
43915
- message: this.translateService.instant('editor.record.multilingual.confirmation.message'),
43916
- confirmText: this.translateService.instant('editor.record.multilingual.confirmation.confirmText'),
43917
- cancelText: this.translateService.instant('editor.record.multilingual.confirmation.cancelText'),
43918
- focusCancel: true,
43919
- },
43920
- restoreFocus: true,
43921
- });
43922
- this.subscription.add(dialogRef.afterClosed().subscribe((confirmed) => {
43923
- if (confirmed) {
43924
- if (lang) {
43925
- if (!Array.isArray(lang)) {
43926
- this.removeSelectedLanguage(lang);
43927
- this.closeActionMenu();
43928
- }
43929
- this.updateTranslations();
43930
- }
43931
- else {
43932
- this.facade.updateRecordLanguages(this.formLanguage, []);
43933
- this.isMultilingual = false;
43934
- this.selectedLanguages = [];
43935
- }
43936
- }
43937
- else {
43938
- this.isMultilingual = true;
43939
- this.selectedLanguages = this.recordLanguages;
43940
- }
43941
- this.editTranslations = false;
43942
- }));
43943
- }
43944
- isFirstUnsupported(index) {
43945
- const langs = this.sortLanguages(this.recordLanguages);
43946
- return (langs[index].length === 3 &&
43947
- langs.slice(0, index).every((lang) => lang.length !== 3));
43948
- }
43949
- isLangSupported(lang) {
43950
- return lang.length === 2;
43951
- }
43952
- getToggleTitle(lang) {
43953
- if (lang === this._record.defaultLanguage) {
43954
- return this.translateService.instant('editor.record.form.multilingual.forbidden');
43955
- }
43956
- return '';
44086
+ // emits and completes once saving is done
44087
+ // note: onSave processes are not run for drafts
44088
+ saveRecordAsDraft(record, recordSource) {
44089
+ record.recordUpdated = new Date();
44090
+ return this.recordsRepository
44091
+ .saveRecordAsDraft(record, recordSource)
44092
+ .pipe(map$1(() => undefined));
43957
44093
  }
43958
- openActionMenu(item, template) {
43959
- this.isActionMenuOpen = true;
43960
- const index = this.sortLanguages(this.selectedLanguages).indexOf(item);
43961
- const buttonElement = this.actionMenuButtons.toArray()[index];
43962
- const positionStrategy = this.overlay
43963
- .position()
43964
- .flexibleConnectedTo(buttonElement)
43965
- .withFlexibleDimensions(true)
43966
- .withPush(true)
43967
- .withPositions([
43968
- {
43969
- originX: 'end',
43970
- originY: 'bottom',
43971
- overlayX: 'end',
43972
- overlayY: 'top',
43973
- },
43974
- {
43975
- originX: 'end',
43976
- originY: 'top',
43977
- overlayX: 'end',
43978
- overlayY: 'bottom',
43979
- },
43980
- ]);
43981
- this.overlayRef = this.overlay.create({
43982
- hasBackdrop: true,
43983
- backdropClass: 'cdk-overlay-transparent-backdrop',
43984
- positionStrategy: positionStrategy,
43985
- scrollStrategy: this.overlay.scrollStrategies.reposition(),
43986
- });
43987
- const portal = new TemplatePortal(template, this.viewContainerRef);
43988
- this.overlayRef.attach(portal);
43989
- this.subscription.add(this.overlayRef.backdropClick().subscribe(() => {
43990
- this.closeActionMenu();
43991
- }));
44094
+ undoRecordDraft(record) {
44095
+ this.recordsRepository.clearRecordDraft(record.uniqueIdentifier);
44096
+ return this.recordsRepository.openRecordForEdition(record.uniqueIdentifier);
43992
44097
  }
43993
- closeActionMenu() {
43994
- if (this.overlayRef) {
43995
- this.isActionMenuOpen = false;
43996
- this.overlayRef.dispose();
43997
- this.cdr.markForCheck();
43998
- }
44098
+ hasRecordChangedSinceDraft(localRecord) {
44099
+ return this.recordsRepository.hasRecordChangedSinceDraft(localRecord);
43999
44100
  }
44000
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MultilingualPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
44001
- 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: [
44002
- provideIcons({
44003
- iconoirSettings,
44004
- matMoreHorizOutline,
44005
- iconoirCheckCircle,
44006
- iconoirCircle,
44007
- }),
44008
- provideNgIconsConfig({
44009
- size: '1.25em',
44010
- }),
44011
- ], 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" }] }); }
44101
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
44102
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorService, providedIn: 'root' }); }
44012
44103
  }
44013
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MultilingualPanelComponent, decorators: [{
44014
- type: Component,
44015
- args: [{ selector: 'gn-ui-multilingual-panel', standalone: true, imports: [
44016
- CommonModule,
44017
- CheckToggleComponent,
44018
- TranslateDirective,
44019
- TranslatePipe,
44020
- ButtonComponent,
44021
- NgIconComponent,
44022
- ActionMenuComponent,
44023
- ], providers: [
44024
- provideIcons({
44025
- iconoirSettings,
44026
- matMoreHorizOutline,
44027
- iconoirCheckCircle,
44028
- iconoirCircle,
44029
- }),
44030
- provideNgIconsConfig({
44031
- size: '1.25em',
44032
- }),
44033
- ], 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" }]
44034
- }], propDecorators: { record: [{
44035
- type: Input
44036
- }], actionMenuButtons: [{
44037
- type: ViewChildren,
44038
- args: ['actionMenuButton', { read: ElementRef }]
44039
- }] } });
44104
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorService, decorators: [{
44105
+ type: Injectable,
44106
+ args: [{
44107
+ providedIn: 'root',
44108
+ }]
44109
+ }] });
44040
44110
 
44041
- //forced translations that are not available in fields.config.ts
44042
- marker('editor.record.form.field.keywords');
44043
- marker('editor.record.form.field.topics');
44044
- marker('editor.record.form.field.contacts');
44045
- marker('editor.record.form.field.organisation');
44046
- class MetadataQualityPanelComponent {
44111
+ class EditorEffects {
44047
44112
  constructor() {
44048
- this.propsToValidate = getAllKeysValidator();
44049
- this.propertiesByPage = [];
44050
- }
44051
- ngOnChanges() {
44052
- if (this.editorConfig && this.record) {
44053
- const fieldsByPage = this.editorConfig.pages.map((page) => page.sections.flatMap((section) => section.fields
44054
- .filter((field) => this.propsToValidate.includes(field.model))
44055
- .map((field) => field.model)));
44056
- // FIXME: temporarily add topics and organisation to the first and third page
44057
- // as long as they are not handled by the editor
44058
- if (fieldsByPage.length > 0) {
44059
- fieldsByPage[0].includes('topics') || fieldsByPage[0].push('topics');
44060
- fieldsByPage[2].includes('organisation') ||
44061
- fieldsByPage[2].push('organisation');
44113
+ this.actions$ = inject(Actions);
44114
+ this.editorService = inject(EditorService);
44115
+ this.recordsRepository = inject(RecordsRepositoryInterface);
44116
+ this.plateformService = inject(PlatformServiceInterface);
44117
+ this.store = inject(Store);
44118
+ 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]) => {
44119
+ const actions = [saveRecordSuccess()];
44120
+ if (!record?.uniqueIdentifier) {
44121
+ actions.push(openRecord({
44122
+ record: savedRecord,
44123
+ recordSource: savedRecordSource,
44124
+ }));
44062
44125
  }
44063
- this.propertiesByPage = fieldsByPage
44064
- .map((fields) => getQualityValidators(this.record, fields).map(({ name, validator }) => ({
44065
- label: `editor.record.form.field.${name}`, // use same translations as in fields.config.ts
44066
- value: validator(),
44067
- })))
44068
- .filter((arr) => arr.length > 0);
44069
- }
44070
- }
44071
- getExtraClass(checked) {
44072
- 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';
44073
- return checked
44074
- ? `${baseClasses} bg-neutral-100 hover:bg-neutral-100`
44075
- : `${baseClasses} bg-transparent hover:bg-transparent`;
44126
+ return of(...actions);
44127
+ }), catchError((error) => of(saveRecordFailure({
44128
+ error,
44129
+ })))))));
44130
+ this.cleanRecordAttachments$ = createEffect(() => this.actions$.pipe(ofType(saveRecordSuccess), withLatestFrom$1(this.store.select(selectRecord)), switchMap$1(([_, record]) => {
44131
+ if (record.uniqueIdentifier !== null) {
44132
+ this.plateformService.cleanRecordAttachments(record).subscribe({
44133
+ next: (_) => undefined,
44134
+ error: (err) => {
44135
+ console.error(err);
44136
+ },
44137
+ });
44138
+ }
44139
+ return EMPTY;
44140
+ }), catchError((error) => {
44141
+ console.error(error);
44142
+ return EMPTY;
44143
+ })), { dispatch: false });
44144
+ this.markAsChanged$ = createEffect(() => this.actions$.pipe(ofType(updateRecordField, updateRecordLanguages), map$1(() => markRecordAsChanged())));
44145
+ 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())));
44146
+ 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({
44147
+ record,
44148
+ recordSource,
44149
+ }))));
44150
+ this.checkHasChangesOnOpen$ = createEffect(() => this.actions$.pipe(ofType(openRecord), map$1(({ record }) => this.recordsRepository.recordHasDraft(record.uniqueIdentifier)), filter((hasDraft) => hasDraft), map$1(() => markRecordAsChanged())));
44151
+ this.hasRecordChangedSinceDraft$ = createEffect(() => this.actions$.pipe(ofType(hasRecordChangedSinceDraft), switchMap$1(({ record }) => this.editorService
44152
+ .hasRecordChangedSinceDraft(record)
44153
+ .pipe(map$1((changes) => hasRecordChangedSinceDraftSuccess({ changes }))))));
44154
+ 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({
44155
+ isPublished: isPublished$1,
44156
+ }))));
44157
+ 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({
44158
+ canEditRecord: canEditRecord$1,
44159
+ }))));
44076
44160
  }
44077
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MetadataQualityPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
44078
- 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: [
44079
- provideIcons({
44080
- iconoirSystemShut,
44081
- iconoirBadgeCheck,
44082
- }),
44083
- provideNgIconsConfig({
44084
- size: '1.25em',
44085
- }),
44086
- ], 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" }] }); }
44161
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorEffects, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
44162
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorEffects }); }
44087
44163
  }
44088
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MetadataQualityPanelComponent, decorators: [{
44089
- type: Component,
44090
- args: [{ selector: 'gn-ui-metadata-quality-panel', standalone: true, imports: [
44091
- TranslateDirective,
44092
- TranslatePipe,
44093
- ButtonComponent,
44094
- NgIconComponent,
44095
- ], providers: [
44096
- provideIcons({
44097
- iconoirSystemShut,
44098
- iconoirBadgeCheck,
44099
- }),
44100
- provideNgIconsConfig({
44101
- size: '1.25em',
44102
- }),
44103
- ], 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" }]
44104
- }], propDecorators: { editorConfig: [{
44105
- type: Input
44106
- }], record: [{
44107
- type: Input
44108
- }] } });
44164
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: EditorEffects, decorators: [{
44165
+ type: Injectable
44166
+ }] });
44167
+
44168
+ class FeatureEditorModule {
44169
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
44170
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, imports: [i1.StoreFeatureModule, i2$2.EffectsFeatureModule] }); }
44171
+ 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),
44172
+ EffectsModule.forFeature([EditorEffects])] }); }
44173
+ }
44174
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeatureEditorModule, decorators: [{
44175
+ type: NgModule,
44176
+ args: [{
44177
+ imports: [
44178
+ StoreModule.forFeature(EDITOR_FEATURE_KEY, editorReducer),
44179
+ EffectsModule.forFeature([EditorEffects]),
44180
+ ],
44181
+ providers: [EditorFacade, provideHttpClient()],
44182
+ }]
44183
+ }] });
44109
44184
 
44110
44185
  const ROUTER_STATE_KEY = 'router';
44111
44186
  const ROUTER_ROUTE_SEARCH = 'search';
@@ -44378,6 +44453,23 @@ class RouterEffects {
44378
44453
  }
44379
44454
  return of(...actions);
44380
44455
  })));
44456
+ /**
44457
+ * This effect is needed because on the page load, the search params from the URL are
44458
+ * directly applied to the underlying search facade; this means that it doesn't go
44459
+ * through the RouterSearchService which makes sure that a relevancy sort is applied
44460
+ * whenever there's a full text search criteria set.
44461
+ */
44462
+ this.applyInitialRelevancySort$ = createEffect(() => this.facade.searchParams$.pipe(take(1), tap$1((filters) => {
44463
+ const relevancySort = sortByToString(SortByEnum.RELEVANCY);
44464
+ if (filters['q'] &&
44465
+ (!Array.isArray(filters['q']) || filters['q'].length > 0) &&
44466
+ !filters[ROUTE_PARAMS.SORT]) {
44467
+ this.facade.updateSearch({
44468
+ ...filters,
44469
+ [ROUTE_PARAMS.SORT]: relevancySort,
44470
+ });
44471
+ }
44472
+ })), { dispatch: false });
44381
44473
  /**
44382
44474
  * This effect will load the metadata when a navigation to
44383
44475
  * a metadata record happens
@@ -44478,8 +44570,10 @@ class RouterSearchService {
44478
44570
  });
44479
44571
  }
44480
44572
  async setFilters(newFilters) {
44481
- const sortBy = await firstValueFrom(this.searchFacade.sortBy$);
44573
+ let sortBy = await firstValueFrom(this.searchFacade.sortBy$);
44482
44574
  const fieldSearchParams = await firstValueFrom(this.fieldsService.readFieldValuesFromFilters(newFilters));
44575
+ // apply relevancy sort if a full text criteria is given
44576
+ sortBy = newFilters['any'] ? SortByEnum.RELEVANCY : sortBy;
44483
44577
  this.facade.setSearch({
44484
44578
  ...fieldSearchParams,
44485
44579
  [ROUTE_PARAMS.SORT]: sortBy ? sortByToString(sortBy) : undefined,
@@ -44488,7 +44582,13 @@ class RouterSearchService {
44488
44582
  async updateFilters(newFilters) {
44489
44583
  const currentFilters = await firstValueFrom(this.searchFacade.searchFilters$);
44490
44584
  const updatedFilters = { ...currentFilters, ...newFilters };
44491
- const newParams = await firstValueFrom(this.fieldsService.readFieldValuesFromFilters(updatedFilters));
44585
+ let newParams = await firstValueFrom(this.fieldsService.readFieldValuesFromFilters(updatedFilters));
44586
+ if (newFilters['any']) {
44587
+ newParams = {
44588
+ ...newParams,
44589
+ [ROUTE_PARAMS.SORT]: sortByToString(SortByEnum.RELEVANCY),
44590
+ };
44591
+ }
44492
44592
  this.facade.updateSearch(newParams);
44493
44593
  }
44494
44594
  setSortBy(sortBy) {
@@ -44548,5 +44648,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
44548
44648
  * Generated bundle index. Do not edit.
44549
44649
  */
44550
44650
 
44551
- 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, 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 };
44651
+ 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 };
44552
44652
  //# sourceMappingURL=geonetwork-ui.mjs.map