geonetwork-ui 2.3.0-dev.ff2a9db7 → 2.3.0

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 (98) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.mjs +2 -2
  2. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.mjs +9 -7
  3. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +22 -7
  4. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +14 -3
  5. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
  6. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +14 -2
  7. package/esm2022/libs/feature/map/src/lib/map-context/map-context.model.mjs +1 -1
  8. package/esm2022/libs/feature/map/src/lib/map-context/map-context.service.mjs +30 -10
  9. package/esm2022/libs/feature/map/src/lib/utils/map-utils.service.mjs +7 -3
  10. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +14 -7
  11. package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +34 -5
  12. package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +1 -3
  13. package/esm2022/libs/feature/search/src/lib/results-list/results-list.container.component.mjs +4 -4
  14. package/esm2022/libs/ui/elements/src/index.mjs +2 -2
  15. package/esm2022/libs/ui/elements/src/lib/error/error.component.mjs +30 -0
  16. package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +6 -7
  17. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +6 -6
  18. package/esm2022/libs/util/app-config/src/lib/app-config.mjs +3 -1
  19. package/esm2022/libs/util/app-config/src/lib/fixtures.mjs +2 -1
  20. package/esm2022/libs/util/app-config/src/lib/model.mjs +1 -1
  21. package/esm2022/translations/de.json +1 -0
  22. package/esm2022/translations/en.json +1 -0
  23. package/esm2022/translations/es.json +1 -0
  24. package/esm2022/translations/fr.json +1 -0
  25. package/esm2022/translations/it.json +1 -0
  26. package/esm2022/translations/nl.json +1 -0
  27. package/esm2022/translations/pt.json +1 -0
  28. package/fesm2022/geonetwork-ui.mjs +391 -287
  29. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  30. package/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.d.ts +2 -2
  31. package/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.d.ts.map +1 -1
  32. package/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.d.ts +1 -1
  33. package/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.d.ts.map +1 -1
  34. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts +4 -1
  35. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts.map +1 -1
  36. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts +2 -1
  37. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  38. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +3 -3
  39. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  40. package/libs/feature/dataviz/src/lib/service/data.service.d.ts +2 -1
  41. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  42. package/libs/feature/map/src/lib/map-context/map-context.model.d.ts +6 -0
  43. package/libs/feature/map/src/lib/map-context/map-context.model.d.ts.map +1 -1
  44. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts +1 -1
  45. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts.map +1 -1
  46. package/libs/feature/map/src/lib/utils/map-utils.service.d.ts.map +1 -1
  47. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts +2 -2
  48. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  49. package/libs/feature/record/src/lib/state/mdview.facade.d.ts +5 -2
  50. package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
  51. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
  52. package/libs/ui/elements/src/index.d.ts +1 -1
  53. package/libs/ui/elements/src/index.d.ts.map +1 -1
  54. package/libs/ui/elements/src/lib/error/error.component.d.ts +16 -0
  55. package/libs/ui/elements/src/lib/error/error.component.d.ts.map +1 -0
  56. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts.map +1 -1
  57. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +2 -2
  58. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  59. package/libs/util/app-config/src/lib/app-config.d.ts.map +1 -1
  60. package/libs/util/app-config/src/lib/fixtures.d.ts.map +1 -1
  61. package/libs/util/app-config/src/lib/model.d.ts +1 -0
  62. package/libs/util/app-config/src/lib/model.d.ts.map +1 -1
  63. package/package.json +2 -2
  64. package/src/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts +9 -1
  65. package/src/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.ts +3 -3
  66. package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +35 -31
  67. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +67 -15
  68. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +71 -13
  69. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +3 -3
  70. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +8 -0
  71. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +15 -1
  72. package/src/libs/feature/map/src/lib/map-context/map-context.model.ts +6 -0
  73. package/src/libs/feature/map/src/lib/map-context/map-context.service.ts +31 -9
  74. package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +6 -2
  75. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +15 -8
  76. package/src/libs/feature/record/src/lib/state/mdview.facade.ts +40 -3
  77. package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +0 -2
  78. package/src/libs/feature/search/src/lib/results-list/results-list.container.component.html +4 -4
  79. package/src/libs/ui/elements/src/index.ts +1 -1
  80. package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.html → error/error.component.html} +18 -3
  81. package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.ts → error/error.component.ts} +5 -4
  82. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +7 -8
  83. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +3 -4
  84. package/src/libs/util/app-config/src/lib/app-config.ts +2 -0
  85. package/src/libs/util/app-config/src/lib/fixtures.ts +1 -0
  86. package/src/libs/util/app-config/src/lib/model.ts +1 -0
  87. package/translations/de.json +1 -0
  88. package/translations/en.json +1 -0
  89. package/translations/es.json +1 -0
  90. package/translations/fr.json +1 -0
  91. package/translations/it.json +1 -0
  92. package/translations/nl.json +1 -0
  93. package/translations/pt.json +1 -0
  94. package/translations/sk.json +1 -0
  95. package/esm2022/libs/ui/elements/src/lib/search-results-error/search-results-error.component.mjs +0 -29
  96. package/libs/ui/elements/src/lib/search-results-error/search-results-error.component.d.ts +0 -15
  97. package/libs/ui/elements/src/lib/search-results-error/search-results-error.component.d.ts.map +0 -1
  98. /package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.css → error/error.component.css} +0 -0
@@ -8,11 +8,11 @@ import * as i1$1 from '@ngx-translate/core';
8
8
  import { TranslateCompiler, TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
9
9
  import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler';
10
10
  import { TranslateHttpLoader } from '@ngx-translate/http-loader';
11
- import { map as map$1, shareReplay, filter, tap as tap$1, startWith, withLatestFrom, switchMap as switchMap$1, catchError, take, delay, debounceTime, distinctUntilChanged, finalize, first, throttleTime, share, pairwise, mergeMap } from 'rxjs/operators';
11
+ import { map as map$1, shareReplay, filter, tap as tap$1, startWith, withLatestFrom, switchMap as switchMap$1, catchError, take, delay, debounceTime, distinctUntilChanged, finalize, first, throttleTime, share, pairwise, mergeMap, defaultIfEmpty, scan } from 'rxjs/operators';
12
12
  import { marker } from '@biesbjerg/ngx-translate-extract-marker';
13
13
  import * as i1$3 from '@angular/common';
14
14
  import { CommonModule, NgOptimizedImage, NgForOf } from '@angular/common';
15
- import { of, map as map$2, lastValueFrom, switchMap, combineLatest, takeLast, forkJoin, firstValueFrom, Subject, merge, throwError, BehaviorSubject, fromEvent, timer, Subscription, ReplaySubject, distinctUntilChanged as distinctUntilChanged$1, debounceTime as debounceTime$1, animationFrameScheduler, from, tap as tap$2, Observable, buffer, combineLatestWith, catchError as catchError$1, takeUntil, exhaustMap, mergeMap as mergeMap$1, EMPTY, withLatestFrom as withLatestFrom$1, filter as filter$1, startWith as startWith$1, pairwise as pairwise$1 } from 'rxjs';
15
+ import { of, map as map$2, lastValueFrom, switchMap, combineLatest, takeLast, forkJoin, firstValueFrom, Subject, merge, throwError, BehaviorSubject, fromEvent, timer, Subscription, ReplaySubject, distinctUntilChanged as distinctUntilChanged$1, debounceTime as debounceTime$1, filter as filter$1, animationFrameScheduler, from, tap as tap$2, Observable, buffer, combineLatestWith, catchError as catchError$1, takeUntil, EMPTY, exhaustMap, mergeMap as mergeMap$1, withLatestFrom as withLatestFrom$1, startWith as startWith$1, pairwise as pairwise$1 } from 'rxjs';
16
16
  import { valid, coerce, satisfies, ltr } from 'semver';
17
17
  import * as i1$2 from '@ngrx/store';
18
18
  import { createAction, props, createReducer, on, createFeatureSelector, createSelector, select, StoreModule, Store } from '@ngrx/store';
@@ -28,12 +28,13 @@ import { transformExtent, fromLonLat } from 'ol/proj';
28
28
  import ImageWMS from 'ol/source/ImageWMS';
29
29
  import TileWMS from 'ol/source/TileWMS';
30
30
  import VectorSource from 'ol/source/Vector';
31
- import { defaults, DragPan, MouseWheelZoom } from 'ol/interaction';
31
+ import { defaults as defaults$1, DragPan, MouseWheelZoom } from 'ol/interaction';
32
32
  import { mouseOnly, noModifierKeys, primaryAction, platformModifierKeyOnly } from 'ol/events/condition';
33
33
  import chroma from 'chroma-js';
34
34
  import { WmtsEndpoint, WmsEndpoint, WfsEndpoint, OgcApiEndpoint, sharedFetch, useCache } from '@camptocamp/ogc-client';
35
35
  import { register, fromEPSGCode } from 'ol/proj/proj4';
36
36
  import proj4 from 'proj4/dist/proj4';
37
+ import { defaults } from 'ol/control/defaults';
37
38
  import * as TOML from '@ltd/j-toml';
38
39
  import CircleStyle from 'ol/style/Circle';
39
40
  import View from 'ol/View';
@@ -46,6 +47,7 @@ import OGCVectorTile from 'ol/source/OGCVectorTile.js';
46
47
  import { MVT, WFS, GeoJSON as GeoJSON$1 } from 'ol/format';
47
48
  import VectorTileLayer from 'ol/layer/VectorTile';
48
49
  import OGCMapTile from 'ol/source/OGCMapTile.js';
50
+ import ImageLayer from 'ol/layer/Image';
49
51
  import * as i2$4 from '@angular/material/tabs';
50
52
  import { MatTabsModule } from '@angular/material/tabs';
51
53
  import * as i2$1 from '@angular/forms';
@@ -102,6 +104,39 @@ import * as i3$2 from '@ngrx/router-store';
102
104
  import { getRouterSelectors, routerReducer, StoreRouterConnectingModule, FullRouterStateSerializer } from '@ngrx/router-store';
103
105
  import { navigation } from '@ngrx/router-store/data-persistence';
104
106
 
107
+ class MetadataMapperContext {
108
+ }
109
+ class BaseConverter {
110
+ constructor(ctx = new MetadataMapperContext()) {
111
+ this.ctx = ctx;
112
+ }
113
+ readRecords(documents) {
114
+ return Promise.all(documents.map((doc) => this.readRecord(doc)));
115
+ }
116
+ writeRecords(records) {
117
+ return Promise.all(records.map((doc) => this.writeRecord(doc)));
118
+ }
119
+ }
120
+
121
+ function isEqual(a, b) {
122
+ if (Array.isArray(a) && Array.isArray(b)) {
123
+ return a.length === b.length && a.every((e, i) => isEqual(e, b[i]));
124
+ }
125
+ else if (a instanceof Date && b instanceof Date) {
126
+ return a.getTime() === b.getTime();
127
+ }
128
+ else if (a instanceof URL && b instanceof URL) {
129
+ return a.toString() === b.toString();
130
+ }
131
+ else if (a instanceof Object && b instanceof Object) {
132
+ const aKeys = Object.keys(a);
133
+ const bKeys = Object.keys(b);
134
+ return (aKeys.length === bKeys.length &&
135
+ aKeys.every((key) => isEqual(a[key], b[key])));
136
+ }
137
+ return a === b;
138
+ }
139
+
105
140
  function pipe(...fns) {
106
141
  return (value) => fns.reduce((prev, curr) => curr(prev), value);
107
142
  }
@@ -501,6 +536,108 @@ function renameElements(rootElement, replaceMap) {
501
536
  return rootElement;
502
537
  }
503
538
 
539
+ function matchProtocol(protocol) {
540
+ if (/wms/i.test(protocol))
541
+ return 'wms';
542
+ if (/wfs/i.test(protocol))
543
+ return 'wfs';
544
+ if (/wmts/i.test(protocol))
545
+ return 'wmts';
546
+ if (/wps/i.test(protocol))
547
+ return 'wps';
548
+ if (/ogc\W*api\W*features/i.test(protocol))
549
+ return 'ogcFeatures';
550
+ if (/esri/i.test(protocol))
551
+ return 'esriRest';
552
+ return 'other';
553
+ }
554
+ function matchMimeType(format) {
555
+ if (/shp|shapefile/i.test(format))
556
+ return 'x-gis/x-shapefile';
557
+ // TODO: check whether the format is a valid mime type
558
+ return format || null;
559
+ }
560
+
561
+ /**
562
+ * Parts are [firstName, lastName]
563
+ * Second part will be null if no separation could be done
564
+ * @param fullName
565
+ */
566
+ function fullNameToParts(fullName) {
567
+ const parts = fullName.trim().split(/\s+/);
568
+ const first = parts.shift();
569
+ return [first, parts.join(' ').trim() || null];
570
+ }
571
+ function namePartsToFull(firstName, lastName) {
572
+ const first = firstName?.trim();
573
+ const last = lastName?.trim();
574
+ if (!first && !last)
575
+ return null;
576
+ return last && first ? `${first} ${last}` : last || first;
577
+ }
578
+
579
+ function getKeywordTypeFromKeywordTypeCode(typeCode) {
580
+ if (!typeCode)
581
+ return 'other';
582
+ switch (typeCode) {
583
+ case 'theme':
584
+ case 'place':
585
+ case 'temporal':
586
+ case 'other':
587
+ return typeCode;
588
+ default:
589
+ return 'other';
590
+ }
591
+ }
592
+
593
+ function getRoleFromRoleCode(roleCode) {
594
+ if (!roleCode)
595
+ return 'unspecified';
596
+ switch (roleCode) {
597
+ case 'author':
598
+ case 'coAuthor':
599
+ return 'author';
600
+ case 'originator':
601
+ return 'originator';
602
+ case 'principalInvestigator':
603
+ return 'principal_investigator';
604
+ case 'resourceProvider':
605
+ return 'resource_provider';
606
+ case 'processor':
607
+ return 'processor';
608
+ case 'custodian':
609
+ return 'custodian';
610
+ case 'owner':
611
+ return 'owner';
612
+ case 'pointOfContact':
613
+ return 'point_of_contact';
614
+ case 'publisher':
615
+ return 'publisher';
616
+ case 'distributor':
617
+ return 'distributor';
618
+ case 'user':
619
+ return 'user';
620
+ case 'collaborator':
621
+ return 'collaborator';
622
+ case 'editor':
623
+ return 'editor';
624
+ case 'contributor':
625
+ return 'contributor';
626
+ case 'stakeholder':
627
+ return 'stakeholder';
628
+ case 'sponsor':
629
+ return 'sponsor';
630
+ case 'funder':
631
+ return 'funder';
632
+ case 'rightsHolder':
633
+ return 'rights_holder';
634
+ case 'mediator':
635
+ return 'mediator';
636
+ default:
637
+ return 'other';
638
+ }
639
+ }
640
+
504
641
  function getStatusFromStatusCode(statusCode) {
505
642
  switch (statusCode) {
506
643
  case 'completed':
@@ -583,108 +720,6 @@ function getUpdateFrequencyFromFrequencyCode(frequencyCode) {
583
720
  }
584
721
  }
585
722
 
586
- function getRoleFromRoleCode(roleCode) {
587
- if (!roleCode)
588
- return 'unspecified';
589
- switch (roleCode) {
590
- case 'author':
591
- case 'coAuthor':
592
- return 'author';
593
- case 'originator':
594
- return 'originator';
595
- case 'principalInvestigator':
596
- return 'principal_investigator';
597
- case 'resourceProvider':
598
- return 'resource_provider';
599
- case 'processor':
600
- return 'processor';
601
- case 'custodian':
602
- return 'custodian';
603
- case 'owner':
604
- return 'owner';
605
- case 'pointOfContact':
606
- return 'point_of_contact';
607
- case 'publisher':
608
- return 'publisher';
609
- case 'distributor':
610
- return 'distributor';
611
- case 'user':
612
- return 'user';
613
- case 'collaborator':
614
- return 'collaborator';
615
- case 'editor':
616
- return 'editor';
617
- case 'contributor':
618
- return 'contributor';
619
- case 'stakeholder':
620
- return 'stakeholder';
621
- case 'sponsor':
622
- return 'sponsor';
623
- case 'funder':
624
- return 'funder';
625
- case 'rightsHolder':
626
- return 'rights_holder';
627
- case 'mediator':
628
- return 'mediator';
629
- default:
630
- return 'other';
631
- }
632
- }
633
-
634
- function matchProtocol(protocol) {
635
- if (/wms/i.test(protocol))
636
- return 'wms';
637
- if (/wfs/i.test(protocol))
638
- return 'wfs';
639
- if (/wmts/i.test(protocol))
640
- return 'wmts';
641
- if (/wps/i.test(protocol))
642
- return 'wps';
643
- if (/ogc\W*api\W*features/i.test(protocol))
644
- return 'ogcFeatures';
645
- if (/esri/i.test(protocol))
646
- return 'esriRest';
647
- return 'other';
648
- }
649
- function matchMimeType(format) {
650
- if (/shp|shapefile/i.test(format))
651
- return 'x-gis/x-shapefile';
652
- // TODO: check whether the format is a valid mime type
653
- return format || null;
654
- }
655
-
656
- function getKeywordTypeFromKeywordTypeCode(typeCode) {
657
- if (!typeCode)
658
- return 'other';
659
- switch (typeCode) {
660
- case 'theme':
661
- case 'place':
662
- case 'temporal':
663
- case 'other':
664
- return typeCode;
665
- default:
666
- return 'other';
667
- }
668
- }
669
-
670
- /**
671
- * Parts are [firstName, lastName]
672
- * Second part will be null if no separation could be done
673
- * @param fullName
674
- */
675
- function fullNameToParts(fullName) {
676
- const parts = fullName.trim().split(/\s+/);
677
- const first = parts.shift();
678
- return [first, parts.join(' ').trim() || null];
679
- }
680
- function namePartsToFull(firstName, lastName) {
681
- const first = firstName?.trim();
682
- const last = lastName?.trim();
683
- if (!first && !last)
684
- return null;
685
- return last && first ? `${first} ${last}` : last || first;
686
- }
687
-
688
723
  function extractCharacterString() {
689
724
  return pipe(fallback(findChildElement('gco:CharacterString', false), findChildElement('gmx:Anchor', false)), readText());
690
725
  }
@@ -1033,6 +1068,21 @@ function extractServiceOnlineResources() {
1033
1068
  function readOnlineResources(rootEl) {
1034
1069
  return pipe(findNestedElements('gmd:distributionInfo', 'gmd:MD_Distribution'), mapArray(extractServiceOnlineResources()), flattenArray())(rootEl);
1035
1070
  }
1071
+ function readTemporalExtents(rootEl) {
1072
+ return pipe(findIdentification(), findNestedElements('gmd:extent', 'gmd:EX_Extent', 'gmd:temporalElement'), mapArray(combine(findNestedElement('gmd:EX_TemporalExtent', 'gmd:extent', 'gml:TimePeriod'), findNestedElement('gmd:EX_TemporalExtent', 'gmd:extent', 'gml:TimeInstant'))), mapArray(([periodEl, instantEl]) => {
1073
+ if (periodEl) {
1074
+ return pipe(combine(pipe(findChildElement('gml:beginPosition', false), readText(), map((dateStr) => (dateStr ? new Date(dateStr) : null))), pipe(findChildElement('gml:endPosition', false), readText(), map((dateStr) => (dateStr ? new Date(dateStr) : null)))), map(([start, end]) => ({
1075
+ start,
1076
+ end,
1077
+ })))(periodEl);
1078
+ }
1079
+ else {
1080
+ return pipe(findChildElement('gml:timePosition', false), readText(), map((dateStr) => (dateStr ? new Date(dateStr) : null)), map((date) => ({
1081
+ start: date,
1082
+ })))(instantEl);
1083
+ }
1084
+ }))(rootEl);
1085
+ }
1036
1086
 
1037
1087
  function writeCharacterString(text) {
1038
1088
  return tap(pipe(findChildOrCreate('gco:CharacterString'), setTextContent(text)));
@@ -1431,38 +1481,16 @@ function createOnlineResource(onlineResource) {
1431
1481
  function writeOnlineResources(record, rootEl) {
1432
1482
  pipe(removeDistributions(), appendChildren(...record.onlineResources.map(createOnlineResource)))(rootEl);
1433
1483
  }
1434
-
1435
- function isEqual(a, b) {
1436
- if (Array.isArray(a) && Array.isArray(b)) {
1437
- return a.length === b.length && a.every((e, i) => isEqual(e, b[i]));
1438
- }
1439
- else if (a instanceof Date && b instanceof Date) {
1440
- return a.getTime() === b.getTime();
1441
- }
1442
- else if (a instanceof URL && b instanceof URL) {
1443
- return a.toString() === b.toString();
1444
- }
1445
- else if (a instanceof Object && b instanceof Object) {
1446
- const aKeys = Object.keys(a);
1447
- const bKeys = Object.keys(b);
1448
- return (aKeys.length === bKeys.length &&
1449
- aKeys.every((key) => isEqual(a[key], b[key])));
1450
- }
1451
- return a === b;
1452
- }
1453
-
1454
- class MetadataMapperContext {
1455
- }
1456
- class BaseConverter {
1457
- constructor(ctx = new MetadataMapperContext()) {
1458
- this.ctx = ctx;
1459
- }
1460
- readRecords(documents) {
1461
- return Promise.all(documents.map((doc) => this.readRecord(doc)));
1462
- }
1463
- writeRecords(records) {
1464
- return Promise.all(records.map((doc) => this.writeRecord(doc)));
1465
- }
1484
+ function writeTemporalExtents(record, rootEl) {
1485
+ pipe(findOrCreateIdentification(), findNestedChildOrCreate('gmd:extent', 'gmd:EX_Extent'), removeChildrenByName('gmd:temporalElement'), appendChildren(...record.temporalExtents.map((extent) => pipe(createElement('gmd:temporalElement'), createChild('gmd:EX_TemporalExtent'), appendChildren('start' in extent && 'end' in extent
1486
+ ? pipe(createElement('gmd:extent'), createChild('gml:TimePeriod'), appendChildren(pipe(createElement('gml:beginPosition'), pipe(extent.start
1487
+ ? setTextContent(format(extent.start, 'yyyy-MM-dd'))
1488
+ : addAttribute('indeterminatePosition', 'unknown'))), pipe(createElement('gml:endPosition'), pipe(extent.end
1489
+ ? setTextContent(format(extent.end, 'yyyy-MM-dd'))
1490
+ : addAttribute('indeterminatePosition', 'unknown')))))
1491
+ : pipe(createElement('gmd:extent'), createChild('gml:TimeInstant'), appendChildren(pipe(createElement('gml:timePosition'), pipe(extent.start
1492
+ ? setTextContent(format(extent.start, 'yyyy-MM-dd'))
1493
+ : addAttribute('indeterminatePosition', 'unknown'))))))))))(rootEl);
1466
1494
  }
1467
1495
 
1468
1496
  class Iso19139Converter extends BaseConverter {
@@ -1495,9 +1523,9 @@ class Iso19139Converter extends BaseConverter {
1495
1523
  lineage: readLineage$1,
1496
1524
  distributions: readDistributions$1,
1497
1525
  onlineResources: readOnlineResources,
1526
+ temporalExtents: readTemporalExtents,
1498
1527
  // TODO
1499
1528
  spatialExtents: () => [],
1500
- temporalExtents: () => [],
1501
1529
  extras: () => undefined,
1502
1530
  landingPage: () => undefined,
1503
1531
  languages: () => [],
@@ -1529,9 +1557,9 @@ class Iso19139Converter extends BaseConverter {
1529
1557
  lineage: writeLineage$1,
1530
1558
  distributions: writeDistributions$1,
1531
1559
  onlineResources: writeOnlineResources,
1560
+ temporalExtents: writeTemporalExtents,
1532
1561
  // TODO
1533
1562
  spatialExtents: () => undefined,
1534
- temporalExtents: () => undefined,
1535
1563
  extras: () => undefined,
1536
1564
  landingPage: () => undefined,
1537
1565
  languages: () => undefined,
@@ -1688,6 +1716,8 @@ class Iso19139Converter extends BaseConverter {
1688
1716
  fieldChanged('spatialRepresentation') &&
1689
1717
  this.writers['spatialRepresentation'](record, rootEl);
1690
1718
  fieldChanged('overviews') && this.writers['overviews'](record, rootEl);
1719
+ fieldChanged('temporalExtents') &&
1720
+ this.writers['temporalExtents'](record, rootEl);
1691
1721
  fieldChanged('distributions') &&
1692
1722
  this.writers['distributions'](record, rootEl);
1693
1723
  fieldChanged('lineage') && this.writers['lineage'](record, rootEl);
@@ -17611,6 +17641,7 @@ var de = {
17611
17641
  "search.error.couldNotReachApi": "Die API konnte nicht erreicht werden",
17612
17642
  "search.error.receivedError": "Ein Fehler ist aufgetreten",
17613
17643
  "search.error.recordNotFound": "Der Datensatz mit der Kennung \"{ id }\" konnte nicht gefunden werden.",
17644
+ "search.error.recordHasnolink": "",
17614
17645
  "search.field.any.placeholder": "Suche Datensätze ...",
17615
17646
  "search.field.sortBy": "Sortieren nach:",
17616
17647
  "search.filters.clear": "Zurücksetzen",
@@ -18004,6 +18035,7 @@ var en = {
18004
18035
  "search.error.couldNotReachApi": "The API could not be reached",
18005
18036
  "search.error.receivedError": "An error was received",
18006
18037
  "search.error.recordNotFound": "The record with identifier \"{ id }\" could not be found.",
18038
+ "search.error.recordHasnolink": "This record currently has no link yet, please come back later.",
18007
18039
  "search.field.any.placeholder": "Search datasets ...",
18008
18040
  "search.field.sortBy": "Sort by:",
18009
18041
  "search.filters.clear": "Reset",
@@ -18397,6 +18429,7 @@ var es = {
18397
18429
  "search.error.couldNotReachApi": "",
18398
18430
  "search.error.receivedError": "",
18399
18431
  "search.error.recordNotFound": "",
18432
+ "search.error.recordHasnolink": "",
18400
18433
  "search.field.any.placeholder": "",
18401
18434
  "search.field.sortBy": "",
18402
18435
  "search.filters.clear": "",
@@ -18790,6 +18823,7 @@ var fr = {
18790
18823
  "search.error.couldNotReachApi": "Problème de connexion à l'API",
18791
18824
  "search.error.receivedError": "Erreur retournée",
18792
18825
  "search.error.recordNotFound": "Cette donnée n'a pu être trouvée.",
18826
+ "search.error.recordHasnolink": "Ce dataset n'a pas encore de lien, réessayez plus tard s'il vous plaît.",
18793
18827
  "search.field.any.placeholder": "Rechercher une donnée...",
18794
18828
  "search.field.sortBy": "Trier par :",
18795
18829
  "search.filters.clear": "Réinitialiser",
@@ -19183,6 +19217,7 @@ var it = {
19183
19217
  "search.error.couldNotReachApi": "Problema di connessione all'API",
19184
19218
  "search.error.receivedError": "Errore ricevuto",
19185
19219
  "search.error.recordNotFound": "Impossibile trovare questo dato",
19220
+ "search.error.recordHasnolink": "",
19186
19221
  "search.field.any.placeholder": "Cerca un dato...",
19187
19222
  "search.field.sortBy": "Ordina per:",
19188
19223
  "search.filters.clear": "Ripristina",
@@ -19576,6 +19611,7 @@ var nl = {
19576
19611
  "search.error.couldNotReachApi": "",
19577
19612
  "search.error.receivedError": "",
19578
19613
  "search.error.recordNotFound": "",
19614
+ "search.error.recordHasnolink": "",
19579
19615
  "search.field.any.placeholder": "",
19580
19616
  "search.field.sortBy": "",
19581
19617
  "search.filters.clear": "",
@@ -19969,6 +20005,7 @@ var pt = {
19969
20005
  "search.error.couldNotReachApi": "",
19970
20006
  "search.error.receivedError": "",
19971
20007
  "search.error.recordNotFound": "",
20008
+ "search.error.recordHasnolink": "",
19972
20009
  "search.field.any.placeholder": "",
19973
20010
  "search.field.sortBy": "",
19974
20011
  "search.filters.clear": "",
@@ -22561,7 +22598,10 @@ class MapUtilsService {
22561
22598
  }
22562
22599
  createEmptyMap() {
22563
22600
  return new Map$1({
22564
- controls: [],
22601
+ controls: defaults({
22602
+ attribution: true,
22603
+ attributionOptions: { collapsible: false },
22604
+ }),
22565
22605
  pixelRatio: 1,
22566
22606
  });
22567
22607
  }
@@ -22660,7 +22700,7 @@ class MapUtilsService {
22660
22700
  }
22661
22701
  prioritizePageScroll(interactions) {
22662
22702
  interactions.clear();
22663
- interactions.extend(defaults({
22703
+ interactions.extend(defaults$1({
22664
22704
  // remove rotate interactions
22665
22705
  altShiftDragRotate: false,
22666
22706
  pinchRotate: false,
@@ -22679,7 +22719,7 @@ class MapUtilsService {
22679
22719
  .getArray());
22680
22720
  }
22681
22721
  getRecordExtent(record) {
22682
- if (!('spatialExtents' in record)) {
22722
+ if (!('spatialExtents' in record) || record.spatialExtents.length === 0) {
22683
22723
  return null;
22684
22724
  }
22685
22725
  // transform an array of geojson geometries into a bbox
@@ -23400,6 +23440,7 @@ function loadAppConfig() {
23400
23440
  const parsedLayersSections = parseMultiConfigSection(parsed, 'map_layer', ['type'], ['name', 'url', 'data'], warnings, errors);
23401
23441
  const parsedMapSection = parseConfigSection(parsed, 'map', [], [
23402
23442
  'max_zoom',
23443
+ 'do_not_tile_wms',
23403
23444
  'max_extent',
23404
23445
  'baselayer',
23405
23446
  'do_not_use_default_basemap',
@@ -23411,6 +23452,7 @@ function loadAppConfig() {
23411
23452
  ? null
23412
23453
  : {
23413
23454
  MAX_ZOOM: parsedMapSection.max_zoom,
23455
+ DO_NOT_TILE_WMS: parsedMapSection.do_not_tile_wms,
23414
23456
  MAX_EXTENT: parsedMapSection.max_extent,
23415
23457
  EXTERNAL_VIEWER_URL_TEMPLATE: parsedMapSection.external_viewer_url_template,
23416
23458
  EXTERNAL_VIEWER_OPEN_NEW_TAB: parsedMapSection.external_viewer_open_new_tab,
@@ -23588,6 +23630,7 @@ const MAP_CONFIG_FIXTURE = {
23588
23630
  MAX_ZOOM: 10,
23589
23631
  MAX_EXTENT: [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855],
23590
23632
  DO_NOT_USE_DEFAULT_BASEMAP: false,
23633
+ DO_NOT_TILE_WMS: false,
23591
23634
  EXTERNAL_VIEWER_URL_TEMPLATE: 'https://example.com/myviewer/#/?actions=[{"type":"CATALOG:ADD_LAYERS_FROM_CATALOGS","layers":["${layer_name}"],"sources":[{"url":"${service_url}","type":"${service_type}"}]}]',
23592
23635
  EXTERNAL_VIEWER_OPEN_NEW_TAB: true,
23593
23636
  MAP_LAYERS: [
@@ -23777,6 +23820,7 @@ const DEFAULT_BASELAYER_CONTEXT = {
23777
23820
  `https://b.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`,
23778
23821
  `https://c.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`,
23779
23822
  ],
23823
+ attributions: `<span>© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="https://carto.com/">Carto</a></span>`,
23780
23824
  };
23781
23825
  const DEFAULT_VIEW = {
23782
23826
  center: [0, 15],
@@ -23801,10 +23845,10 @@ class MapContextService {
23801
23845
  }
23802
23846
  map.setView(this.createView(mapContext.view, map));
23803
23847
  map.getLayers().clear();
23804
- mapContext.layers.forEach((layer) => map.addLayer(this.createLayer(layer)));
23848
+ mapContext.layers.forEach((layer) => map.addLayer(this.createLayer(layer, mapConfig)));
23805
23849
  return map;
23806
23850
  }
23807
- createLayer(layerModel) {
23851
+ createLayer(layerModel, mapConfig) {
23808
23852
  const { type } = layerModel;
23809
23853
  const style = this.styleService.styles.default;
23810
23854
  switch (type) {
@@ -23814,6 +23858,7 @@ class MapContextService {
23814
23858
  source: new OGCVectorTile({
23815
23859
  url: layerModel.url,
23816
23860
  format: new MVT(),
23861
+ attributions: layerModel.attributions,
23817
23862
  }),
23818
23863
  });
23819
23864
  }
@@ -23821,6 +23866,7 @@ class MapContextService {
23821
23866
  return new TileLayer({
23822
23867
  source: new OGCMapTile({
23823
23868
  url: layerModel.url,
23869
+ attributions: layerModel.attributions,
23824
23870
  }),
23825
23871
  });
23826
23872
  }
@@ -23829,6 +23875,7 @@ class MapContextService {
23829
23875
  source: new VectorSource({
23830
23876
  format: new GeoJSON(),
23831
23877
  url: layerModel.url,
23878
+ attributions: layerModel.attributions,
23832
23879
  }),
23833
23880
  style,
23834
23881
  });
@@ -23838,16 +23885,28 @@ class MapContextService {
23838
23885
  source: new XYZ({
23839
23886
  url: 'url' in layerModel ? layerModel.url : undefined,
23840
23887
  urls: 'urls' in layerModel ? layerModel.urls : undefined,
23888
+ attributions: layerModel.attributions,
23841
23889
  }),
23842
23890
  });
23843
23891
  case MapContextLayerTypeEnum.WMS:
23844
- return new TileLayer({
23845
- source: new TileWMS({
23846
- url: layerModel.url,
23847
- params: { LAYERS: layerModel.name },
23848
- gutter: 20,
23849
- }),
23850
- });
23892
+ if (mapConfig?.DO_NOT_TILE_WMS) {
23893
+ return new ImageLayer({
23894
+ source: new ImageWMS({
23895
+ url: layerModel.url,
23896
+ params: { LAYERS: layerModel.name },
23897
+ attributions: layerModel.attributions,
23898
+ }),
23899
+ });
23900
+ }
23901
+ else {
23902
+ return new TileLayer({
23903
+ source: new TileWMS({
23904
+ url: layerModel.url,
23905
+ params: { LAYERS: layerModel.name, TILED: true },
23906
+ attributions: layerModel.attributions,
23907
+ }),
23908
+ });
23909
+ }
23851
23910
  case MapContextLayerTypeEnum.WMTS: {
23852
23911
  // TODO: isolate this in utils service
23853
23912
  const olLayer = new TileLayer({});
@@ -23869,6 +23928,7 @@ class MapContextService {
23869
23928
  tileGrid,
23870
23929
  projection: matrixSet.crs,
23871
23930
  dimensions,
23931
+ attributions: layerModel.attributions,
23872
23932
  }));
23873
23933
  });
23874
23934
  return olLayer;
@@ -23891,6 +23951,7 @@ class MapContextService {
23891
23951
  });
23892
23952
  },
23893
23953
  strategy: bbox,
23954
+ attributions: layerModel.attributions,
23894
23955
  }));
23895
23956
  });
23896
23957
  return olLayer;
@@ -27230,7 +27291,8 @@ class RecordApiFormComponent {
27230
27291
  this.offset$,
27231
27292
  this.limit$,
27232
27293
  this.format$,
27233
- this.endpoint$,
27294
+ // only compute the url if the endpoint was created
27295
+ this.endpoint$.pipe(filter$1((endpoint) => !!endpoint)),
27234
27296
  ]).pipe(switchMap(([offset, limit, format]) => this.generateApiQueryUrl(offset, limit, format)));
27235
27297
  this.noLimitChecked$ = this.limit$.pipe(map$2((limit) => limit === '-1' || limit === ''));
27236
27298
  this.displayLimit$ = this.limit$.pipe(map$2((limit) => (limit !== '-1' ? limit : '')));
@@ -27290,9 +27352,7 @@ class RecordApiFormComponent {
27290
27352
  return this.endpoint.getServiceInfo();
27291
27353
  }
27292
27354
  else {
27293
- {
27294
- return (await this.endpoint.getCollectionInfo(this.firstCollection));
27295
- }
27355
+ return (await this.endpoint.getCollectionInfo(this.firstCollection));
27296
27356
  }
27297
27357
  }
27298
27358
  async createEndpoint() {
@@ -27304,7 +27364,7 @@ class RecordApiFormComponent {
27304
27364
  }
27305
27365
  else {
27306
27366
  this.endpoint = new OgcApiEndpoint(this.apiBaseUrl);
27307
- this.firstCollection = (await this.endpoint.featureCollections)[0];
27367
+ this.firstCollection = (await this.endpoint.allCollections)[0].name;
27308
27368
  }
27309
27369
  this.endpoint$.next(this.endpoint);
27310
27370
  }
@@ -27352,17 +27412,18 @@ var ErrorType;
27352
27412
  ErrorType[ErrorType["COULD_NOT_REACH_API"] = 0] = "COULD_NOT_REACH_API";
27353
27413
  ErrorType[ErrorType["RECEIVED_ERROR"] = 1] = "RECEIVED_ERROR";
27354
27414
  ErrorType[ErrorType["RECORD_NOT_FOUND"] = 2] = "RECORD_NOT_FOUND";
27415
+ ErrorType[ErrorType["DATASET_HAS_NO_LINK"] = 3] = "DATASET_HAS_NO_LINK";
27355
27416
  })(ErrorType || (ErrorType = {}));
27356
- class SearchResultsErrorComponent {
27417
+ class ErrorComponent {
27357
27418
  constructor() {
27358
27419
  this.types = ErrorType;
27359
27420
  }
27360
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SearchResultsErrorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27361
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: SearchResultsErrorComponent, selector: "gn-ui-search-results-error", inputs: { type: "type", error: "error", recordId: "recordId" }, ngImport: i0, template: "<div\n class=\"p-[1.7em] bg-red-50 text-red-800 text-[1.5em] text-center rounded-lg\"\n>\n <div *ngIf=\"type === types.COULD_NOT_REACH_API\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">face</mat-icon>\n <mat-icon class=\"material-symbols-outlined question-mark1\"\n >question_mark</mat-icon\n >\n <mat-icon class=\"material-symbols-outlined question-mark2\"\n >question_mark</mat-icon\n >\n </div>\n <div translate>search.error.couldNotReachApi</div>\n </div>\n <div *ngIf=\"type === types.RECEIVED_ERROR\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">mood_bad</mat-icon>\n </div>\n <div translate>search.error.receivedError</div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n <div *ngIf=\"type === types.RECORD_NOT_FOUND\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined computer\">computer</mat-icon>\n <mat-icon class=\"material-symbols-outlined computer-question-mark\"\n >question_mark</mat-icon\n >\n </div>\n <div translate [translateParams]=\"{ id: recordId }\">\n search.error.recordNotFound\n </div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n</div>\n", styles: ["mat-icon{width:auto;height:auto}mat-icon.face{font-size:3em}mat-icon.question-mark1{position:absolute;bottom:1.1em;left:calc(50% + .7em);font-size:1.7em}mat-icon.question-mark2{position:absolute;bottom:1.6em;left:calc(50% + 1.6em);font-size:1.4em}.computer{font-size:3em}.computer-question-mark{position:absolute;top:.6em;left:calc(50% - .5em);font-size:1.2em}\n"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27421
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ErrorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27422
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ErrorComponent, selector: "gn-ui-error", inputs: { type: "type", error: "error", recordId: "recordId" }, ngImport: i0, template: "<div\n class=\"p-[1.7em] bg-red-50 text-red-800 text-[1.5em] text-center rounded-lg\"\n>\n <div\n *ngIf=\"type === types.COULD_NOT_REACH_API\"\n data-test=\"could-not-reach-api-error\"\n >\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">face</mat-icon>\n <mat-icon class=\"material-symbols-outlined question-mark1\"\n >question_mark</mat-icon\n >\n <mat-icon class=\"material-symbols-outlined question-mark2\"\n >question_mark</mat-icon\n >\n </div>\n <div translate>search.error.couldNotReachApi</div>\n </div>\n <div\n *ngIf=\"type === types.DATASET_HAS_NO_LINK\"\n data-test=\"dataset-has-no-link-error\"\n >\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">computer</mat-icon>\n </div>\n <div translate>search.error.recordHasnolink</div>\n </div>\n <div *ngIf=\"type === types.RECEIVED_ERROR\" data-test=\"received-error-error\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">mood_bad</mat-icon>\n </div>\n <div translate>search.error.receivedError</div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n <div\n *ngIf=\"type === types.RECORD_NOT_FOUND\"\n data-test=\"record-not-found-error\"\n >\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined computer\">computer</mat-icon>\n <mat-icon class=\"material-symbols-outlined computer-question-mark\"\n >question_mark</mat-icon\n >\n </div>\n <div translate [translateParams]=\"{ id: recordId }\">\n search.error.recordNotFound\n </div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n</div>\n", styles: ["mat-icon{width:auto;height:auto}mat-icon.face{font-size:3em}mat-icon.question-mark1{position:absolute;bottom:1.1em;left:calc(50% + .7em);font-size:1.7em}mat-icon.question-mark2{position:absolute;bottom:1.6em;left:calc(50% + 1.6em);font-size:1.4em}.computer{font-size:3em}.computer-question-mark{position:absolute;top:.6em;left:calc(50% - .5em);font-size:1.2em}\n"], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27362
27423
  }
27363
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SearchResultsErrorComponent, decorators: [{
27424
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ErrorComponent, decorators: [{
27364
27425
  type: Component,
27365
- args: [{ selector: 'gn-ui-search-results-error', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"p-[1.7em] bg-red-50 text-red-800 text-[1.5em] text-center rounded-lg\"\n>\n <div *ngIf=\"type === types.COULD_NOT_REACH_API\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">face</mat-icon>\n <mat-icon class=\"material-symbols-outlined question-mark1\"\n >question_mark</mat-icon\n >\n <mat-icon class=\"material-symbols-outlined question-mark2\"\n >question_mark</mat-icon\n >\n </div>\n <div translate>search.error.couldNotReachApi</div>\n </div>\n <div *ngIf=\"type === types.RECEIVED_ERROR\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">mood_bad</mat-icon>\n </div>\n <div translate>search.error.receivedError</div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n <div *ngIf=\"type === types.RECORD_NOT_FOUND\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined computer\">computer</mat-icon>\n <mat-icon class=\"material-symbols-outlined computer-question-mark\"\n >question_mark</mat-icon\n >\n </div>\n <div translate [translateParams]=\"{ id: recordId }\">\n search.error.recordNotFound\n </div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n</div>\n", styles: ["mat-icon{width:auto;height:auto}mat-icon.face{font-size:3em}mat-icon.question-mark1{position:absolute;bottom:1.1em;left:calc(50% + .7em);font-size:1.7em}mat-icon.question-mark2{position:absolute;bottom:1.6em;left:calc(50% + 1.6em);font-size:1.4em}.computer{font-size:3em}.computer-question-mark{position:absolute;top:.6em;left:calc(50% - .5em);font-size:1.2em}\n"] }]
27426
+ args: [{ selector: 'gn-ui-error', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"p-[1.7em] bg-red-50 text-red-800 text-[1.5em] text-center rounded-lg\"\n>\n <div\n *ngIf=\"type === types.COULD_NOT_REACH_API\"\n data-test=\"could-not-reach-api-error\"\n >\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">face</mat-icon>\n <mat-icon class=\"material-symbols-outlined question-mark1\"\n >question_mark</mat-icon\n >\n <mat-icon class=\"material-symbols-outlined question-mark2\"\n >question_mark</mat-icon\n >\n </div>\n <div translate>search.error.couldNotReachApi</div>\n </div>\n <div\n *ngIf=\"type === types.DATASET_HAS_NO_LINK\"\n data-test=\"dataset-has-no-link-error\"\n >\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">computer</mat-icon>\n </div>\n <div translate>search.error.recordHasnolink</div>\n </div>\n <div *ngIf=\"type === types.RECEIVED_ERROR\" data-test=\"received-error-error\">\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined face\">mood_bad</mat-icon>\n </div>\n <div translate>search.error.receivedError</div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n <div\n *ngIf=\"type === types.RECORD_NOT_FOUND\"\n data-test=\"record-not-found-error\"\n >\n <div class=\"relative opacity-40\">\n <mat-icon class=\"material-symbols-outlined computer\">computer</mat-icon>\n <mat-icon class=\"material-symbols-outlined computer-question-mark\"\n >question_mark</mat-icon\n >\n </div>\n <div translate [translateParams]=\"{ id: recordId }\">\n search.error.recordNotFound\n </div>\n <div *ngIf=\"error\">{{ error }}</div>\n </div>\n</div>\n", styles: ["mat-icon{width:auto;height:auto}mat-icon.face{font-size:3em}mat-icon.question-mark1{position:absolute;bottom:1.1em;left:calc(50% + .7em);font-size:1.7em}mat-icon.question-mark2{position:absolute;bottom:1.6em;left:calc(50% + 1.6em);font-size:1.4em}.computer{font-size:3em}.computer-question-mark{position:absolute;top:.6em;left:calc(50% - .5em);font-size:1.2em}\n"] }]
27366
27427
  }], propDecorators: { type: [{
27367
27428
  type: Input
27368
27429
  }], error: [{
@@ -27881,7 +27942,7 @@ class UiElementsModule {
27881
27942
  MetadataCatalogComponent,
27882
27943
  MetadataQualityComponent,
27883
27944
  MetadataQualityItemComponent,
27884
- SearchResultsErrorComponent,
27945
+ ErrorComponent,
27885
27946
  PaginationComponent,
27886
27947
  AvatarComponent,
27887
27948
  UserPreviewComponent,
@@ -27911,7 +27972,7 @@ class UiElementsModule {
27911
27972
  MetadataCatalogComponent,
27912
27973
  MetadataQualityComponent,
27913
27974
  MetadataQualityItemComponent,
27914
- SearchResultsErrorComponent,
27975
+ ErrorComponent,
27915
27976
  PaginationComponent,
27916
27977
  ThumbnailComponent,
27917
27978
  AvatarComponent,
@@ -27964,7 +28025,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
27964
28025
  MetadataCatalogComponent,
27965
28026
  MetadataQualityComponent,
27966
28027
  MetadataQualityItemComponent,
27967
- SearchResultsErrorComponent,
28028
+ ErrorComponent,
27968
28029
  PaginationComponent,
27969
28030
  AvatarComponent,
27970
28031
  UserPreviewComponent,
@@ -27986,7 +28047,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
27986
28047
  MetadataCatalogComponent,
27987
28048
  MetadataQualityComponent,
27988
28049
  MetadataQualityItemComponent,
27989
- SearchResultsErrorComponent,
28050
+ ErrorComponent,
27990
28051
  PaginationComponent,
27991
28052
  ThumbnailComponent,
27992
28053
  AvatarComponent,
@@ -29395,11 +29456,11 @@ class ResultsListContainerComponent {
29395
29456
  return this.recordUrlTemplate.replace('${uuid}', metadata.uniqueIdentifier);
29396
29457
  }
29397
29458
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ResultsListContainerComponent, deps: [{ token: SearchFacade }, { token: RESULTS_LAYOUT_CONFIG }, { token: RECORD_URL_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
29398
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ResultsListContainerComponent, selector: "gn-ui-results-list-container", inputs: { metadataQualityDisplay: "metadataQualityDisplay", layout: "layout", showMore: "showMore" }, outputs: { mdSelect: "mdSelect" }, ngImport: i0, template: "<div *ngIf=\"(error$ | async) === null\" class=\"search-results relative\">\n <gn-ui-results-list\n [records]=\"facade.results$ | async\"\n [layoutConfig]=\"layoutConfig$ | async\"\n [metadataQualityDisplay]=\"\n metadataQualityDisplay && (pipelineForQualityScoreActivated | async)\n \"\n [favoriteTemplate]=\"favoriteToggle\"\n [recordUrlGetter]=\"recordUrlGetter\"\n (mdSelect)=\"onMetadataSelection($event)\"\n ></gn-ui-results-list>\n <ng-container\n *ngIf=\"\n (facade.isLoading$ | async) === false &&\n (facade.isEndOfResults$ | async) === false\n \"\n >\n <div class=\"show-more h-[100px] pt-[30px]\" *ngIf=\"showMore === 'button'\">\n <gn-ui-button\n data-cy=\"addMoreBtn\"\n type=\"secondary\"\n (buttonClick)=\"onShowMore()\"\n extraClass=\"m-auto !p-[22px]\"\n >\n <span class=\"uppercase font-medium tracking-widest\" translate\n >results.showMore</span\n >\n </gn-ui-button>\n </div>\n <div class=\"show-more h-[100px]\" *ngIf=\"showMore === 'auto'\">\n <gn-ui-viewport-intersector\n (entersViewport)=\"onShowMore()\"\n ></gn-ui-viewport-intersector>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"(facade.isLoading$ | async) === true\">\n <div class=\"loading flex justify-center h-[100px] pt-[45px]\">\n <gn-ui-spinning-loader></gn-ui-spinning-loader>\n </div>\n </ng-container>\n</div>\n\n<div class=\"p-4 max-w-[600px] m-auto text-[13px]\">\n <gn-ui-search-results-error\n *ngIf=\"(errorCode$ | async) === 0\"\n [type]=\"errorTypes.COULD_NOT_REACH_API\"\n >\n </gn-ui-search-results-error>\n <gn-ui-search-results-error\n *ngIf=\"(error$ | async) !== null && (errorCode$ | async) !== 0\"\n [type]=\"errorTypes.RECEIVED_ERROR\"\n [error]=\"errorMessage$ | async\"\n ></gn-ui-search-results-error>\n</div>\n\n<ng-template #favoriteToggle let-record>\n <gn-ui-favorite-star [record]=\"record\"></gn-ui-favorite-star>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ResultsListComponent, selector: "gn-ui-results-list", inputs: ["records", "layoutConfig", "favoriteTemplate", "recordUrlGetter", "metadataQualityDisplay"], outputs: ["mdSelect"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: ViewportIntersectorComponent, selector: "gn-ui-viewport-intersector", outputs: ["isInViewport", "entersViewport", "exitsViewport"] }, { kind: "component", type: SearchResultsErrorComponent, selector: "gn-ui-search-results-error", inputs: ["type", "error", "recordId"] }, { kind: "component", type: SpinningLoaderComponent, selector: "gn-ui-spinning-loader" }, { kind: "component", type: FavoriteStarComponent, selector: "gn-ui-favorite-star", inputs: ["displayCount", "record"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }] }); }
29459
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: ResultsListContainerComponent, selector: "gn-ui-results-list-container", inputs: { metadataQualityDisplay: "metadataQualityDisplay", layout: "layout", showMore: "showMore" }, outputs: { mdSelect: "mdSelect" }, ngImport: i0, template: "<div *ngIf=\"(error$ | async) === null\" class=\"search-results relative\">\n <gn-ui-results-list\n [records]=\"facade.results$ | async\"\n [layoutConfig]=\"layoutConfig$ | async\"\n [metadataQualityDisplay]=\"\n metadataQualityDisplay && (pipelineForQualityScoreActivated | async)\n \"\n [favoriteTemplate]=\"favoriteToggle\"\n [recordUrlGetter]=\"recordUrlGetter\"\n (mdSelect)=\"onMetadataSelection($event)\"\n ></gn-ui-results-list>\n <ng-container\n *ngIf=\"\n (facade.isLoading$ | async) === false &&\n (facade.isEndOfResults$ | async) === false\n \"\n >\n <div class=\"show-more h-[100px] pt-[30px]\" *ngIf=\"showMore === 'button'\">\n <gn-ui-button\n data-cy=\"addMoreBtn\"\n type=\"secondary\"\n (buttonClick)=\"onShowMore()\"\n extraClass=\"m-auto !p-[22px]\"\n >\n <span class=\"uppercase font-medium tracking-widest\" translate\n >results.showMore</span\n >\n </gn-ui-button>\n </div>\n <div class=\"show-more h-[100px]\" *ngIf=\"showMore === 'auto'\">\n <gn-ui-viewport-intersector\n (entersViewport)=\"onShowMore()\"\n ></gn-ui-viewport-intersector>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"(facade.isLoading$ | async) === true\">\n <div class=\"loading flex justify-center h-[100px] pt-[45px]\">\n <gn-ui-spinning-loader></gn-ui-spinning-loader>\n </div>\n </ng-container>\n</div>\n\n<div class=\"p-4 max-w-[600px] m-auto text-[13px]\">\n <gn-ui-error\n *ngIf=\"(errorCode$ | async) === 0\"\n [type]=\"errorTypes.COULD_NOT_REACH_API\"\n >\n </gn-ui-error>\n <gn-ui-error\n *ngIf=\"(error$ | async) !== null && (errorCode$ | async) !== 0\"\n [type]=\"errorTypes.RECEIVED_ERROR\"\n [error]=\"errorMessage$ | async\"\n ></gn-ui-error>\n</div>\n\n<ng-template #favoriteToggle let-record>\n <gn-ui-favorite-star [record]=\"record\"></gn-ui-favorite-star>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: ResultsListComponent, selector: "gn-ui-results-list", inputs: ["records", "layoutConfig", "favoriteTemplate", "recordUrlGetter", "metadataQualityDisplay"], outputs: ["mdSelect"] }, { kind: "component", type: ButtonComponent, selector: "gn-ui-button", inputs: ["type", "disabled", "extraClass"], outputs: ["buttonClick"] }, { kind: "component", type: ViewportIntersectorComponent, selector: "gn-ui-viewport-intersector", outputs: ["isInViewport", "entersViewport", "exitsViewport"] }, { kind: "component", type: ErrorComponent, selector: "gn-ui-error", inputs: ["type", "error", "recordId"] }, { kind: "component", type: SpinningLoaderComponent, selector: "gn-ui-spinning-loader" }, { kind: "component", type: FavoriteStarComponent, selector: "gn-ui-favorite-star", inputs: ["displayCount", "record"] }, { kind: "pipe", type: i1$3.AsyncPipe, name: "async" }] }); }
29399
29460
  }
29400
29461
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: ResultsListContainerComponent, decorators: [{
29401
29462
  type: Component,
29402
- args: [{ selector: 'gn-ui-results-list-container', template: "<div *ngIf=\"(error$ | async) === null\" class=\"search-results relative\">\n <gn-ui-results-list\n [records]=\"facade.results$ | async\"\n [layoutConfig]=\"layoutConfig$ | async\"\n [metadataQualityDisplay]=\"\n metadataQualityDisplay && (pipelineForQualityScoreActivated | async)\n \"\n [favoriteTemplate]=\"favoriteToggle\"\n [recordUrlGetter]=\"recordUrlGetter\"\n (mdSelect)=\"onMetadataSelection($event)\"\n ></gn-ui-results-list>\n <ng-container\n *ngIf=\"\n (facade.isLoading$ | async) === false &&\n (facade.isEndOfResults$ | async) === false\n \"\n >\n <div class=\"show-more h-[100px] pt-[30px]\" *ngIf=\"showMore === 'button'\">\n <gn-ui-button\n data-cy=\"addMoreBtn\"\n type=\"secondary\"\n (buttonClick)=\"onShowMore()\"\n extraClass=\"m-auto !p-[22px]\"\n >\n <span class=\"uppercase font-medium tracking-widest\" translate\n >results.showMore</span\n >\n </gn-ui-button>\n </div>\n <div class=\"show-more h-[100px]\" *ngIf=\"showMore === 'auto'\">\n <gn-ui-viewport-intersector\n (entersViewport)=\"onShowMore()\"\n ></gn-ui-viewport-intersector>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"(facade.isLoading$ | async) === true\">\n <div class=\"loading flex justify-center h-[100px] pt-[45px]\">\n <gn-ui-spinning-loader></gn-ui-spinning-loader>\n </div>\n </ng-container>\n</div>\n\n<div class=\"p-4 max-w-[600px] m-auto text-[13px]\">\n <gn-ui-search-results-error\n *ngIf=\"(errorCode$ | async) === 0\"\n [type]=\"errorTypes.COULD_NOT_REACH_API\"\n >\n </gn-ui-search-results-error>\n <gn-ui-search-results-error\n *ngIf=\"(error$ | async) !== null && (errorCode$ | async) !== 0\"\n [type]=\"errorTypes.RECEIVED_ERROR\"\n [error]=\"errorMessage$ | async\"\n ></gn-ui-search-results-error>\n</div>\n\n<ng-template #favoriteToggle let-record>\n <gn-ui-favorite-star [record]=\"record\"></gn-ui-favorite-star>\n</ng-template>\n" }]
29463
+ args: [{ selector: 'gn-ui-results-list-container', template: "<div *ngIf=\"(error$ | async) === null\" class=\"search-results relative\">\n <gn-ui-results-list\n [records]=\"facade.results$ | async\"\n [layoutConfig]=\"layoutConfig$ | async\"\n [metadataQualityDisplay]=\"\n metadataQualityDisplay && (pipelineForQualityScoreActivated | async)\n \"\n [favoriteTemplate]=\"favoriteToggle\"\n [recordUrlGetter]=\"recordUrlGetter\"\n (mdSelect)=\"onMetadataSelection($event)\"\n ></gn-ui-results-list>\n <ng-container\n *ngIf=\"\n (facade.isLoading$ | async) === false &&\n (facade.isEndOfResults$ | async) === false\n \"\n >\n <div class=\"show-more h-[100px] pt-[30px]\" *ngIf=\"showMore === 'button'\">\n <gn-ui-button\n data-cy=\"addMoreBtn\"\n type=\"secondary\"\n (buttonClick)=\"onShowMore()\"\n extraClass=\"m-auto !p-[22px]\"\n >\n <span class=\"uppercase font-medium tracking-widest\" translate\n >results.showMore</span\n >\n </gn-ui-button>\n </div>\n <div class=\"show-more h-[100px]\" *ngIf=\"showMore === 'auto'\">\n <gn-ui-viewport-intersector\n (entersViewport)=\"onShowMore()\"\n ></gn-ui-viewport-intersector>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"(facade.isLoading$ | async) === true\">\n <div class=\"loading flex justify-center h-[100px] pt-[45px]\">\n <gn-ui-spinning-loader></gn-ui-spinning-loader>\n </div>\n </ng-container>\n</div>\n\n<div class=\"p-4 max-w-[600px] m-auto text-[13px]\">\n <gn-ui-error\n *ngIf=\"(errorCode$ | async) === 0\"\n [type]=\"errorTypes.COULD_NOT_REACH_API\"\n >\n </gn-ui-error>\n <gn-ui-error\n *ngIf=\"(error$ | async) !== null && (errorCode$ | async) !== 0\"\n [type]=\"errorTypes.RECEIVED_ERROR\"\n [error]=\"errorMessage$ | async\"\n ></gn-ui-error>\n</div>\n\n<ng-template #favoriteToggle let-record>\n <gn-ui-favorite-star [record]=\"record\"></gn-ui-favorite-star>\n</ng-template>\n" }]
29403
29464
  }], ctorParameters: function () { return [{ type: SearchFacade }, { type: undefined, decorators: [{
29404
29465
  type: Inject,
29405
29466
  args: [RESULTS_LAYOUT_CONFIG]
@@ -30965,14 +31026,12 @@ on(setChartConfig, (state, { chartConfig }) => ({
30965
31026
  */
30966
31027
  on(loadUserFeedbacks, (state) => ({
30967
31028
  ...state,
30968
- error: null,
30969
31029
  allUserFeedbacksLoading: true,
30970
31030
  })), on(addUserFeedback, (state) => ({
30971
31031
  ...state,
30972
31032
  addUserFeedbackLoading: true,
30973
31033
  })), on(loadUserFeedbacksSuccess, (state, { userFeedbacks }) => ({
30974
31034
  ...state,
30975
- error: null,
30976
31035
  userFeedbacks: userFeedbacks,
30977
31036
  addUserFeedbackLoading: false,
30978
31037
  allUserFeedbacksLoading: false,
@@ -31010,117 +31069,6 @@ const getUserFeedbacks = createSelector(getMdViewState, (state) => state.userFee
31010
31069
  const getAllUserFeedbacksLoading = createSelector(getMdViewState, (state) => state.allUserFeedbacksLoading);
31011
31070
  const getAddUserFeedbacksLoading = createSelector(getMdViewState, (state) => state.addUserFeedbackLoading);
31012
31071
 
31013
- /**
31014
- * The Metadata View Facade is used to render complete metadata records.
31015
- * Supply it with an incomplete record (at least containing the uuid) and the
31016
- * corresponding full record will be loaded.
31017
- * To clear the current record use the `close()` method.
31018
- */
31019
- class MdViewFacade {
31020
- constructor(store, linkClassifier, avatarService) {
31021
- this.store = store;
31022
- this.linkClassifier = linkClassifier;
31023
- this.avatarService = avatarService;
31024
- this.isPresent$ = this.store.pipe(select(getMetadataUuid), map$1((uuid) => !!uuid));
31025
- this.isMetadataLoading$ = this.store.pipe(select(getMetadataIsLoading));
31026
- this.metadata$ = this.store.pipe(select(getMetadata), filter((md) => !!md));
31027
- this.isIncomplete$ = this.store.pipe(select(getMetadataIsIncomplete), filter((incomplete) => incomplete !== null));
31028
- this.error$ = this.store.pipe(select(getMetadataError));
31029
- this.related$ = this.store.pipe(select(getRelated));
31030
- this.chartConfig$ = this.store.pipe(select(getChartConfig));
31031
- this.allLinks$ = this.metadata$.pipe(map$1((record) => ('distributions' in record ? record.distributions : [])));
31032
- this.apiLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.API))));
31033
- this.mapApiLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.MAP_API))));
31034
- this.downloadLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.DOWNLOAD))));
31035
- this.dataLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.DATA))));
31036
- this.geoDataLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.GEODATA))));
31037
- this.landingPageLinks$ = this.metadata$.pipe(map$1((record) => ('landingPage' in record ? [record.landingPage] : [])));
31038
- this.otherLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.UNKNOWN))));
31039
- this.userFeedbacks$ = this.store.pipe(select(getUserFeedbacks));
31040
- this.isAllUserFeedbackLoading$ = this.store.pipe(select(getAllUserFeedbacksLoading));
31041
- this.isAddUserFeedbackLoading$ = this.store.pipe(select(getAddUserFeedbacksLoading));
31042
- }
31043
- /**
31044
- * This will show an incomplete record (e.g. from a search result) as a preview
31045
- * Note: the full record will not be loaded automatically; use the `loadFull` method for that
31046
- */
31047
- setIncompleteMetadata(incomplete) {
31048
- this.store.dispatch(setIncompleteMetadata({ incomplete }));
31049
- }
31050
- /**
31051
- * This will trigger the load of a full metadata record
31052
- */
31053
- loadFull(uuid) {
31054
- this.store.dispatch(loadFullMetadata({ uuid }));
31055
- }
31056
- closeMetadata() {
31057
- this.store.dispatch(closeMetadata());
31058
- }
31059
- setChartConfig(chartConfig) {
31060
- this.store.dispatch(setChartConfig({ chartConfig }));
31061
- }
31062
- /**
31063
- * UserFeedbacks
31064
- */
31065
- addUserFeedback(userFeedback) {
31066
- this.store.dispatch(addUserFeedback({ userFeedback }));
31067
- }
31068
- loadUserFeedbacks(datasetUuid) {
31069
- this.store.dispatch(loadUserFeedbacks({ datasetUuid }));
31070
- }
31071
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewFacade, deps: [{ token: i1$2.Store }, { token: LinkClassifierService }, { token: AvatarServiceInterface }], target: i0.ɵɵFactoryTarget.Injectable }); }
31072
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewFacade }); }
31073
- }
31074
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewFacade, decorators: [{
31075
- type: Injectable
31076
- }], ctorParameters: function () { return [{ type: i1$2.Store }, { type: LinkClassifierService }, { type: AvatarServiceInterface }]; } });
31077
-
31078
- class MdViewEffects {
31079
- constructor(actions$, recordsRepository, platformServiceInterface) {
31080
- this.actions$ = actions$;
31081
- this.recordsRepository = recordsRepository;
31082
- this.platformServiceInterface = platformServiceInterface;
31083
- /*
31084
- Metadata effects
31085
- */
31086
- this.loadFullMetadata$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadata), switchMap$1(({ uuid }) => this.recordsRepository.getByUniqueIdentifier(uuid)), map$1((record) => {
31087
- if (record === null) {
31088
- return loadFullMetadataFailure({ notFound: true });
31089
- }
31090
- return loadFullMetadataSuccess({ full: record });
31091
- }), catchError((error) => of(loadFullMetadataFailure({ otherError: error.message })))));
31092
- /*
31093
- Related effects
31094
- */
31095
- this.loadRelatedRecords$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadataSuccess), switchMap$1(({ full }) => this.recordsRepository.getSimilarRecords(full)), map$1((related) => {
31096
- return setRelated({ related });
31097
- }), catchError((error) => of(setRelated({ related: null })))));
31098
- /*
31099
- UserFeedback effects
31100
- */
31101
- this.loadUserFeedbacks$ = createEffect(() => this.actions$.pipe(ofType(loadUserFeedbacks), exhaustMap(({ datasetUuid }) => this.platformServiceInterface.getUserFeedbacks(datasetUuid).pipe(map$1((userFeedbacks) => loadUserFeedbacksSuccess({ userFeedbacks })), catchError((error) => of(loadUserFeedbacksFailure({
31102
- otherError: error.message,
31103
- })))))));
31104
- this.reloadUserFeedbacks$ = createEffect(() => this.actions$.pipe(ofType(addUserFeedbackSuccess), exhaustMap(({ datasetUuid }) => this.platformServiceInterface.getUserFeedbacks(datasetUuid).pipe(map$1((userFeedbacks) => loadUserFeedbacksSuccess({ userFeedbacks })), catchError((error) => of(loadUserFeedbacksFailure({
31105
- otherError: error.message,
31106
- })))))));
31107
- this.addUserFeedback$ = createEffect(() => this.actions$.pipe(ofType(addUserFeedback), mergeMap$1((action) => this.platformServiceInterface
31108
- .postUserFeedbacks(action.userFeedback)
31109
- .pipe(map$1(() => addUserFeedbackSuccess({
31110
- datasetUuid: action.userFeedback.metadataUUID,
31111
- })), catchError((error) => {
31112
- return of(addUserFeedbackFailure({
31113
- otherError: error.message,
31114
- }));
31115
- })))));
31116
- }
31117
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewEffects, deps: [{ token: i1$8.Actions }, { token: RecordsRepositoryInterface }, { token: PlatformServiceInterface }], target: i0.ɵɵFactoryTarget.Injectable }); }
31118
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewEffects }); }
31119
- }
31120
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewEffects, decorators: [{
31121
- type: Injectable
31122
- }], ctorParameters: function () { return [{ type: i1$8.Actions }, { type: RecordsRepositoryInterface }, { type: PlatformServiceInterface }]; } });
31123
-
31124
31072
  class FigureComponent {
31125
31073
  constructor() {
31126
31074
  this.color = 'primary';
@@ -32316,10 +32264,22 @@ class DataService {
32316
32264
  });
32317
32265
  }
32318
32266
  async getDownloadUrlsFromOgcApi(url) {
32267
+ const endpoint = new OgcApiEndpoint(this.proxy.getProxiedUrl(url));
32268
+ return await endpoint.allCollections
32269
+ .then((collections) => {
32270
+ return endpoint.getCollectionInfo(collections[0].name);
32271
+ })
32272
+ .catch((error) => {
32273
+ throw new Error(`ogc.unreachable.unknown`);
32274
+ });
32275
+ }
32276
+ async getItemsFromOgcApi(url) {
32319
32277
  const endpoint = new OgcApiEndpoint(this.proxy.getProxiedUrl(url));
32320
32278
  return await endpoint.featureCollections
32321
32279
  .then((collections) => {
32322
- return endpoint.getCollectionInfo(collections[0]);
32280
+ return collections.length
32281
+ ? endpoint.getCollectionItem(collections[0], '1')
32282
+ : null;
32323
32283
  })
32324
32284
  .catch((error) => {
32325
32285
  throw new Error(`ogc.unreachable.unknown`);
@@ -32679,6 +32639,143 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
32679
32639
  }]
32680
32640
  }] });
32681
32641
 
32642
+ /**
32643
+ * The Metadata View Facade is used to render complete metadata records.
32644
+ * Supply it with an incomplete record (at least containing the uuid) and the
32645
+ * corresponding full record will be loaded.
32646
+ * To clear the current record use the `close()` method.
32647
+ */
32648
+ class MdViewFacade {
32649
+ constructor(store, linkClassifier, avatarService, dataService) {
32650
+ this.store = store;
32651
+ this.linkClassifier = linkClassifier;
32652
+ this.avatarService = avatarService;
32653
+ this.dataService = dataService;
32654
+ this.isPresent$ = this.store.pipe(select(getMetadataUuid), map$1((uuid) => !!uuid));
32655
+ this.isMetadataLoading$ = this.store.pipe(select(getMetadataIsLoading));
32656
+ this.metadata$ = this.store.pipe(select(getMetadata), filter((md) => !!md));
32657
+ this.isIncomplete$ = this.store.pipe(select(getMetadataIsIncomplete), filter((incomplete) => incomplete !== null));
32658
+ this.error$ = this.store.pipe(select(getMetadataError));
32659
+ this.related$ = this.store.pipe(select(getRelated));
32660
+ this.chartConfig$ = this.store.pipe(select(getChartConfig));
32661
+ this.allLinks$ = this.metadata$.pipe(map$1((record) => ('distributions' in record ? record.distributions : [])));
32662
+ this.apiLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.API))));
32663
+ this.mapApiLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.MAP_API))));
32664
+ this.downloadLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.DOWNLOAD))));
32665
+ this.dataLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.DATA))));
32666
+ this.geoDataLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.GEODATA))));
32667
+ this.geoDataLinksWithGeometry$ = this.allLinks$.pipe(mergeMap((links) => {
32668
+ return from(links);
32669
+ }), mergeMap((link) => {
32670
+ if (this.linkClassifier.hasUsage(link, LinkUsage.GEODATA)) {
32671
+ if (link.type === 'service' &&
32672
+ link.accessServiceProtocol === 'ogcFeatures') {
32673
+ return from(this.dataService.getItemsFromOgcApi(link.url.href)).pipe(map$1((collectionRecords) => {
32674
+ return collectionRecords && collectionRecords.geometry
32675
+ ? link
32676
+ : null;
32677
+ }), defaultIfEmpty(null));
32678
+ }
32679
+ else {
32680
+ return of(link);
32681
+ }
32682
+ }
32683
+ else {
32684
+ return of(null);
32685
+ }
32686
+ }), scan((acc, val) => {
32687
+ if (val !== null && !acc.includes(val)) {
32688
+ acc.push(val);
32689
+ }
32690
+ return acc;
32691
+ }, []));
32692
+ this.landingPageLinks$ = this.metadata$.pipe(map$1((record) => ('landingPage' in record ? [record.landingPage] : [])));
32693
+ this.otherLinks$ = this.allLinks$.pipe(map$1((links) => links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.UNKNOWN))));
32694
+ this.userFeedbacks$ = this.store.pipe(select(getUserFeedbacks));
32695
+ this.isAllUserFeedbackLoading$ = this.store.pipe(select(getAllUserFeedbacksLoading));
32696
+ this.isAddUserFeedbackLoading$ = this.store.pipe(select(getAddUserFeedbacksLoading));
32697
+ }
32698
+ /**
32699
+ * This will show an incomplete record (e.g. from a search result) as a preview
32700
+ * Note: the full record will not be loaded automatically; use the `loadFull` method for that
32701
+ */
32702
+ setIncompleteMetadata(incomplete) {
32703
+ this.store.dispatch(setIncompleteMetadata({ incomplete }));
32704
+ }
32705
+ /**
32706
+ * This will trigger the load of a full metadata record
32707
+ */
32708
+ loadFull(uuid) {
32709
+ this.store.dispatch(loadFullMetadata({ uuid }));
32710
+ }
32711
+ closeMetadata() {
32712
+ this.store.dispatch(closeMetadata());
32713
+ }
32714
+ setChartConfig(chartConfig) {
32715
+ this.store.dispatch(setChartConfig({ chartConfig }));
32716
+ }
32717
+ /**
32718
+ * UserFeedbacks
32719
+ */
32720
+ addUserFeedback(userFeedback) {
32721
+ this.store.dispatch(addUserFeedback({ userFeedback }));
32722
+ }
32723
+ loadUserFeedbacks(datasetUuid) {
32724
+ this.store.dispatch(loadUserFeedbacks({ datasetUuid }));
32725
+ }
32726
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewFacade, deps: [{ token: i1$2.Store }, { token: LinkClassifierService }, { token: AvatarServiceInterface }, { token: DataService }], target: i0.ɵɵFactoryTarget.Injectable }); }
32727
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewFacade }); }
32728
+ }
32729
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewFacade, decorators: [{
32730
+ type: Injectable
32731
+ }], ctorParameters: function () { return [{ type: i1$2.Store }, { type: LinkClassifierService }, { type: AvatarServiceInterface }, { type: DataService }]; } });
32732
+
32733
+ class MdViewEffects {
32734
+ constructor(actions$, recordsRepository, platformServiceInterface) {
32735
+ this.actions$ = actions$;
32736
+ this.recordsRepository = recordsRepository;
32737
+ this.platformServiceInterface = platformServiceInterface;
32738
+ /*
32739
+ Metadata effects
32740
+ */
32741
+ this.loadFullMetadata$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadata), switchMap$1(({ uuid }) => this.recordsRepository.getByUniqueIdentifier(uuid)), map$1((record) => {
32742
+ if (record === null) {
32743
+ return loadFullMetadataFailure({ notFound: true });
32744
+ }
32745
+ return loadFullMetadataSuccess({ full: record });
32746
+ }), catchError((error) => of(loadFullMetadataFailure({ otherError: error.message })))));
32747
+ /*
32748
+ Related effects
32749
+ */
32750
+ this.loadRelatedRecords$ = createEffect(() => this.actions$.pipe(ofType(loadFullMetadataSuccess), switchMap$1(({ full }) => this.recordsRepository.getSimilarRecords(full)), map$1((related) => {
32751
+ return setRelated({ related });
32752
+ }), catchError((error) => of(setRelated({ related: null })))));
32753
+ /*
32754
+ UserFeedback effects
32755
+ */
32756
+ this.loadUserFeedbacks$ = createEffect(() => this.actions$.pipe(ofType(loadUserFeedbacks), exhaustMap(({ datasetUuid }) => this.platformServiceInterface.getUserFeedbacks(datasetUuid).pipe(map$1((userFeedbacks) => loadUserFeedbacksSuccess({ userFeedbacks })), catchError((error) => of(loadUserFeedbacksFailure({
32757
+ otherError: error.message,
32758
+ })))))));
32759
+ this.reloadUserFeedbacks$ = createEffect(() => this.actions$.pipe(ofType(addUserFeedbackSuccess), exhaustMap(({ datasetUuid }) => this.platformServiceInterface.getUserFeedbacks(datasetUuid).pipe(map$1((userFeedbacks) => loadUserFeedbacksSuccess({ userFeedbacks })), catchError((error) => of(loadUserFeedbacksFailure({
32760
+ otherError: error.message,
32761
+ })))))));
32762
+ this.addUserFeedback$ = createEffect(() => this.actions$.pipe(ofType(addUserFeedback), mergeMap$1((action) => this.platformServiceInterface
32763
+ .postUserFeedbacks(action.userFeedback)
32764
+ .pipe(map$1(() => addUserFeedbackSuccess({
32765
+ datasetUuid: action.userFeedback.metadataUUID,
32766
+ })), catchError((error) => {
32767
+ return of(addUserFeedbackFailure({
32768
+ otherError: error.message,
32769
+ }));
32770
+ })))));
32771
+ }
32772
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewEffects, deps: [{ token: i1$8.Actions }, { token: RecordsRepositoryInterface }, { token: PlatformServiceInterface }], target: i0.ɵɵFactoryTarget.Injectable }); }
32773
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewEffects }); }
32774
+ }
32775
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: MdViewEffects, decorators: [{
32776
+ type: Injectable
32777
+ }], ctorParameters: function () { return [{ type: i1$8.Actions }, { type: RecordsRepositoryInterface }, { type: PlatformServiceInterface }]; } });
32778
+
32682
32779
  marker('externalviewer.dataset.unnamed');
32683
32780
  class ExternalViewerButtonComponent {
32684
32781
  get externalViewer() {
@@ -32746,8 +32843,10 @@ class MapViewComponent {
32746
32843
  this.subscription = new Subscription();
32747
32844
  this.compatibleMapLinks$ = combineLatest([
32748
32845
  this.mdViewFacade.mapApiLinks$,
32749
- this.mdViewFacade.geoDataLinks$,
32750
- ]).pipe(map$1(([mapApiLinks, geoDataLinks]) => [...mapApiLinks, ...geoDataLinks]));
32846
+ this.mdViewFacade.geoDataLinksWithGeometry$,
32847
+ ]).pipe(map$1(([mapApiLinks, geoDataLinksWithGeometry]) => {
32848
+ return [...mapApiLinks, ...geoDataLinksWithGeometry];
32849
+ }));
32751
32850
  this.dropdownChoices$ = this.compatibleMapLinks$.pipe(map$1((links) => links.length
32752
32851
  ? links.map((link, index) => ({
32753
32852
  label: getLinkLabel(link),
@@ -32773,15 +32872,20 @@ class MapViewComponent {
32773
32872
  return of([]);
32774
32873
  }), finalize(() => (this.loading = false)));
32775
32874
  }));
32776
- this.mapContext$ = this.currentLayers$.pipe(switchMap$1((layers) => from(this.mapUtils.getLayerExtent(layers[0])).pipe(catchError((error) => {
32777
- console.warn(error); // FIXME: report this to the user somehow
32875
+ this.mapContext$ = this.currentLayers$.pipe(switchMap$1((layers) => from(this.mapUtils.getLayerExtent(layers[0])).pipe(catchError(() => {
32876
+ this.error = 'The layer has no extent';
32778
32877
  return of(undefined);
32779
32878
  }), map$1((extent) => ({
32780
32879
  layers,
32781
32880
  view: {
32782
32881
  extent,
32783
32882
  },
32784
- })), tap$1(() => this.resetSelection()))), withLatestFrom$1(this.mdViewFacade.metadata$), map$1(([context, metadata]) => {
32883
+ })), tap$1((res) => {
32884
+ this.resetSelection();
32885
+ }))), startWith({
32886
+ layers: [],
32887
+ view: {},
32888
+ }), withLatestFrom$1(this.mdViewFacade.metadata$), map$1(([context, metadata]) => {
32785
32889
  if (context.view.extent)
32786
32890
  return context;
32787
32891
  const extent = this.mapUtils.getRecordExtent(metadata);
@@ -34957,5 +35061,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImpor
34957
35061
  * Generated bundle index. Do not edit.
34958
35062
  */
34959
35063
 
34960
- export { ADD_RESULTS, ADD_SEARCH, AbstractAction, AbstractSearchField, AddLayerFromCatalogComponent, AddLayerRecordPreviewComponent, AddResults, AddSearch, AnchorLinkDirective, ApiCardComponent, AuthService, AutocompleteComponent, AvatarComponent, AvatarServiceInterface, BLOCK_MODEL_FIXTURE, BadgeComponent, BaseReader, BlockListComponent, ButtonComponent, CLEAR_ERROR, CLEAR_RESULTS, CONFIG_MALFORMED, CONFIG_MINIMAL, CONFIG_MISSING_MANDATORY, CONFIG_OK, CONFIG_UNRECOGNIZED_KEYS, CONFIG_WITH_TRANSLATIONS, CONFIG_WRONG_LANGUAGE_CODE, CarouselComponent, CatalogTitleComponent, ChartComponent, ChartViewComponent, CheckToggleComponent, CheckboxComponent, ChipsInputComponent, ClearError, ClearResults, ColorScaleComponent, ContentGhostComponent, CopyTextButtonComponent, DEFAULT_BASELAYER_CONTEXT, DEFAULT_GN4_LOGIN_URL, DEFAULT_LANG, DEFAULT_PAGE_SIZE, DEFAULT_RESULTS_LAYOUT_CONFIG, DEFAULT_SEARCH_KEY, DEFAULT_STYLE_FIXTURE, DEFAULT_STYLE_HL_FIXTURE, DEFAULT_VIEW, DataService, DataViewComponent, DataViewPermalinkComponent, DataViewShareComponent, DataViewWebComponentComponent, DatePickerComponent, DateRangePickerComponent, DefaultRouterModule, DownloadItemComponent, DownloadsListComponent, DragAndDropFileInputComponent, DropdownMultiselectComponent, DropdownSelectorComponent, EDITOR_FEATURE_KEY, EMPTY_BLOCK_MODEL_FIXTURE, ES_QUERY_FIELDS_PRIORITY, ES_RESOURCES_VALUES, ES_SOURCE_SUMMARY, EditableLabelDirective, EditorFacade, EditorService, ElasticsearchService, EmbeddedTranslateLoader, ErrorType, ExpandablePanelButtonComponent, ExpandablePanelComponent, ExternalViewerButtonComponent, FACET_ITEM_FIXTURE, FEATURE_MAP_OPTIONS, FIELDS_BRIEF, FIELDS_SUMMARY, FILTER_GEOMETRY, FORMATS, FacetBlockComponent, FacetBlockStubComponent, FacetItemComponent, FacetItemStubComponent, FacetListComponent, FacetsContainerComponent, FacetsModule, FavoriteStarComponent, FavoritesService, FeatureAuthModule, FeatureCatalogModule, FeatureDatavizModule, FeatureDetailComponent, FeatureEditorModule, FeatureInfoService, FeatureMapModule, FeatureNotificationsModule, FeatureRecordModule, FeatureSearchModule, FetchError, FieldsService, FigureComponent, FigureContainerComponent, FileTranslateLoader, FilterDropdownComponent, FormFieldWrapperComponent, FullTextSearchField, FuzzySearchComponent, GN_UI_VERSION, GeoTableViewComponent, GeocodingComponent, Gn4Converter, Gn4PlatformMapper, Gn4PlatformService, Gn4Repository, Gn4SettingsService, GravatarService, HttpLoaderFactory, I18nInterceptor, ImageFallbackDirective, ImageOverlayPreviewComponent, InteractiveTableColumnComponent, InteractiveTableComponent, IsSpatialSearchField, Iso191153Converter, Iso19139Converter, LANGUAGES_LIST, LANGUAGE_NAMES, LANGUAGE_STORAGE_KEY, LANG_2_TO_3_MAPPER, LANG_3_TO_2_MAPPER, LOGIN_URL, LONLAT_CRS_CODES, LangService, LanguageSwitcherComponent, LayersPanelComponent, LicenseSearchField, LinkCardComponent, LinkClassifierService, LinkUsage, LoadingMaskComponent, LogService, MAP_CONFIG_FIXTURE, MAP_FEATURE_KEY, METADATA_LANGUAGE, MY_FORMATS, MapComponent, MapContainerComponent, MapContextComponent, MapContextLayerTypeEnum, MapContextService, MapFacade, MapInstanceDirective, MapManagerService, MapStyleService, MapUtilsService, MapViewComponent, MarkdownEditorComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataInfoComponent, MetadataLinkType, MetadataQualityComponent, MetadataQualityItemComponent, MultilingualSearchField, MyOrgService, NavigationButtonComponent, NotificationComponent, NotificationsContainerComponent, NotificationsService, ORGANIZATIONS_STRATEGY, ORGANIZATION_URL_TOKEN, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationSearchField, OrganizationsFromGroupsService, OrganizationsFromMetadataService, OwnerSearchField, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PatchResultsAggregations, PopupAlertComponent, PreviousNextButtonsComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_URL_TOKEN, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESULTS_LAYOUT_CONFIG, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_SEARCH, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordsMetricsComponent, RecordsService, RelatedRecordCardComponent, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, 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, SearchInputComponent, SearchResultsErrorComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SimpleSearchField, SiteTitleComponent, SortByComponent, SourceLabelComponent, SourcesService, SpinningLoaderComponent, StarToggleComponent, StepBarComponent, StickyHeaderComponent, SupportedTypes, TABLE_ITEM_FIXTURE, TABLE_ITEM_FIXTURE_HAB, THUMBNAIL_PLACEHOLDER, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableComponent, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, TranslatedSearchField, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, UiCatalogModule, UiDatavizModule, UiElementsModule, FacetsModule$1 as UiFacetsModule, UiInputsModule, UiLayoutModule, UiMapModule, UiSearchModule, UiWidgetsModule, UpdateConfigAggregations, UpdateFilters, UserPreviewComponent, UtilI18nModule, UtilSharedModule, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, WFS_MAX_FEATURES, WizardComponent, WizardFieldComponent, WizardFieldType, WizardService, WizardSummarizeComponent, _reset, addLayer, changeLayerOrder, checkFileFormat, clearLayerError, createFuzzyFilter, currentPage, defaultMapOptions, downgradeImage, downsizeImage, dragPanCondition, dropEmptyTranslations, editorReducer, findConverterForDocument, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryFromGeoJSON, getGlobalConfig, getJsonDataItemsProxy, getLangFromBrowser, getLinkLabel, getLinkPriority, getMapLayers, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, initSearch, initialEditorState, initialMapState, initialState, isConfigLoaded, isEndOfResults, isFormatInQueryParam, loadAppConfig, mapContact, mapKeywords, mapLogo, mapOrganization, mapReducer, markRecordAsChanged, megabytesToBytes, mimeTypeToFormat, mouseWheelZoomCondition, openDataset, openRecord, parse, placeholder, propagateToDocumentOnly, provideGn4, provideRepositoryUrl, readDataset, readDatasetHeaders, reducer$2 as reducer, reducerSearch, removeLayer, removeSearchParams, removeWhitespace, saveRecord, saveRecordFailure, saveRecordSuccess, selectEditorState, selectFallback, selectFallbackFields, selectField, selectRecord, selectRecordChangedSinceSave, selectRecordFields, selectRecordFieldsConfig, selectRecordSaveError, selectRecordSaving, selectTranslatedField, selectTranslatedValue, setLayerError, sortByFromString, sortByToString, sortByToStrings, stripHtml, toDate, totalPages, updateLayer, updateRecordField };
35064
+ export { ADD_RESULTS, ADD_SEARCH, AbstractAction, AbstractSearchField, AddLayerFromCatalogComponent, AddLayerRecordPreviewComponent, AddResults, AddSearch, AnchorLinkDirective, ApiCardComponent, AuthService, AutocompleteComponent, AvatarComponent, AvatarServiceInterface, BLOCK_MODEL_FIXTURE, BadgeComponent, BaseReader, BlockListComponent, ButtonComponent, CLEAR_ERROR, CLEAR_RESULTS, CONFIG_MALFORMED, CONFIG_MINIMAL, CONFIG_MISSING_MANDATORY, CONFIG_OK, CONFIG_UNRECOGNIZED_KEYS, CONFIG_WITH_TRANSLATIONS, CONFIG_WRONG_LANGUAGE_CODE, CarouselComponent, CatalogTitleComponent, ChartComponent, ChartViewComponent, CheckToggleComponent, CheckboxComponent, ChipsInputComponent, ClearError, ClearResults, ColorScaleComponent, ContentGhostComponent, CopyTextButtonComponent, DEFAULT_BASELAYER_CONTEXT, DEFAULT_GN4_LOGIN_URL, DEFAULT_LANG, DEFAULT_PAGE_SIZE, DEFAULT_RESULTS_LAYOUT_CONFIG, DEFAULT_SEARCH_KEY, DEFAULT_STYLE_FIXTURE, DEFAULT_STYLE_HL_FIXTURE, DEFAULT_VIEW, DataService, DataViewComponent, DataViewPermalinkComponent, DataViewShareComponent, DataViewWebComponentComponent, DatePickerComponent, DateRangePickerComponent, DefaultRouterModule, DownloadItemComponent, DownloadsListComponent, DragAndDropFileInputComponent, DropdownMultiselectComponent, DropdownSelectorComponent, EDITOR_FEATURE_KEY, EMPTY_BLOCK_MODEL_FIXTURE, ES_QUERY_FIELDS_PRIORITY, ES_RESOURCES_VALUES, ES_SOURCE_SUMMARY, EditableLabelDirective, EditorFacade, EditorService, ElasticsearchService, EmbeddedTranslateLoader, ErrorComponent, ErrorType, ExpandablePanelButtonComponent, ExpandablePanelComponent, ExternalViewerButtonComponent, FACET_ITEM_FIXTURE, FEATURE_MAP_OPTIONS, FIELDS_BRIEF, FIELDS_SUMMARY, FILTER_GEOMETRY, FORMATS, FacetBlockComponent, FacetBlockStubComponent, FacetItemComponent, FacetItemStubComponent, FacetListComponent, FacetsContainerComponent, FacetsModule, FavoriteStarComponent, FavoritesService, FeatureAuthModule, FeatureCatalogModule, FeatureDatavizModule, FeatureDetailComponent, FeatureEditorModule, FeatureInfoService, FeatureMapModule, FeatureNotificationsModule, FeatureRecordModule, FeatureSearchModule, FetchError, FieldsService, FigureComponent, FigureContainerComponent, FileTranslateLoader, FilterDropdownComponent, FormFieldWrapperComponent, FullTextSearchField, FuzzySearchComponent, GN_UI_VERSION, GeoTableViewComponent, GeocodingComponent, Gn4Converter, Gn4PlatformMapper, Gn4PlatformService, Gn4Repository, Gn4SettingsService, GravatarService, HttpLoaderFactory, I18nInterceptor, ImageFallbackDirective, ImageOverlayPreviewComponent, InteractiveTableColumnComponent, InteractiveTableComponent, IsSpatialSearchField, Iso191153Converter, Iso19139Converter, LANGUAGES_LIST, LANGUAGE_NAMES, LANGUAGE_STORAGE_KEY, LANG_2_TO_3_MAPPER, LANG_3_TO_2_MAPPER, LOGIN_URL, LONLAT_CRS_CODES, LangService, LanguageSwitcherComponent, LayersPanelComponent, LicenseSearchField, LinkCardComponent, LinkClassifierService, LinkUsage, LoadingMaskComponent, LogService, MAP_CONFIG_FIXTURE, MAP_FEATURE_KEY, METADATA_LANGUAGE, MY_FORMATS, MapComponent, MapContainerComponent, MapContextComponent, MapContextLayerTypeEnum, MapContextService, MapFacade, MapInstanceDirective, MapManagerService, MapStyleService, MapUtilsService, MapViewComponent, MarkdownEditorComponent, MarkdownParserComponent, MaxLinesComponent, mdview_actions as MdViewActions, MdViewFacade, MetadataCatalogComponent, MetadataContactComponent, MetadataInfoComponent, MetadataLinkType, MetadataQualityComponent, MetadataQualityItemComponent, MultilingualSearchField, MyOrgService, NavigationButtonComponent, NotificationComponent, NotificationsContainerComponent, NotificationsService, ORGANIZATIONS_STRATEGY, ORGANIZATION_URL_TOKEN, OrganisationPreviewComponent, OrganisationsComponent, OrganisationsFilterComponent, OrganisationsResultComponent, OrganizationSearchField, OrganizationsFromGroupsService, OrganizationsFromMetadataService, OwnerSearchField, PAGINATE, PARSE_DELIMITER, PATCH_RESULTS_AGGREGATIONS, PROXY_PATH, Paginate, PaginationButtonsComponent, PaginationComponent, PatchResultsAggregations, PopupAlertComponent, PreviousNextButtonsComponent, ProgressBarComponent, ProxyService, QUERY_FIELDS, RECORD_URL_TOKEN, REQUEST_MORE_ON_AGGREGATION, REQUEST_MORE_RESULTS, REQUEST_NEW_RESULTS, RESULTS_LAYOUT_CONFIG, ROUTER_CONFIG, ROUTER_ROUTE_DATASET, ROUTER_ROUTE_SEARCH, ROUTER_STATE_KEY, ROUTE_PARAMS, RecordApiFormComponent, RecordFormComponent, RecordMetricComponent, RecordPreviewCardComponent, RecordPreviewComponent, RecordPreviewFeedComponent, RecordPreviewListComponent, RecordPreviewRowComponent, RecordPreviewTextComponent, RecordPreviewTitleComponent, RecordsMetricsComponent, RecordsService, RelatedRecordCardComponent, RequestMoreOnAggregation, RequestMoreResults, RequestNewResults, ResultsHitsContainerComponent, ResultsHitsNumberComponent, ResultsLayoutComponent, ResultsLayoutConfigItem, ResultsListComponent, ResultsListContainerComponent, ResultsListItemComponent, ResultsTableComponent, RouterEffects, RouterFacade, RouterService, SEARCH_FEATURE_KEY, 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, SearchInputComponent, SearchRouterContainerDirective, SearchService, SearchStateContainerDirective, SelectionService, SetConfigAggregations, SetConfigFilters, SetConfigRequestFields, SetError, SetFavoritesOnly, SetFilters, SetIncludeOnAggregation, SetPageSize, SetResultsAggregations, SetResultsHits, SetResultsLayout, SetSearch, SetSortBy, SetSpatialFilterEnabled, SimpleSearchField, SiteTitleComponent, SortByComponent, SourceLabelComponent, SourcesService, SpinningLoaderComponent, StarToggleComponent, StepBarComponent, StickyHeaderComponent, SupportedTypes, TABLE_ITEM_FIXTURE, TABLE_ITEM_FIXTURE_HAB, THUMBNAIL_PLACEHOLDER, TRANSLATE_DEFAULT_CONFIG, TRANSLATE_WITH_OVERRIDES_CONFIG, TableComponent, TableViewComponent, TextAreaComponent, TextInputComponent, ThemeService, ThumbnailComponent, TranslatedSearchField, UPDATE_CONFIG_AGGREGATIONS, UPDATE_FILTERS, UPDATE_REQUEST_AGGREGATION_TERM, UiCatalogModule, UiDatavizModule, UiElementsModule, FacetsModule$1 as UiFacetsModule, UiInputsModule, UiLayoutModule, UiMapModule, UiSearchModule, UiWidgetsModule, UpdateConfigAggregations, UpdateFilters, UserPreviewComponent, UtilI18nModule, UtilSharedModule, ViewportIntersectorComponent, WEB_COMPONENT_EMBEDDER_URL, WFS_MAX_FEATURES, WizardComponent, WizardFieldComponent, WizardFieldType, WizardService, WizardSummarizeComponent, _reset, addLayer, changeLayerOrder, checkFileFormat, clearLayerError, createFuzzyFilter, currentPage, defaultMapOptions, downgradeImage, downsizeImage, dragPanCondition, dropEmptyTranslations, editorReducer, findConverterForDocument, getArrayItem, getAsArray, getAsUrl, getBadgeColor, getCustomTranslations, getError, getFavoritesOnly, getFileFormat, getFileFormatFromServiceOutput, getFirstValue, getFormatPriority, getGeometryFromGeoJSON, getGlobalConfig, getJsonDataItemsProxy, getLangFromBrowser, getLinkLabel, getLinkPriority, getMapLayers, getMapState, getMetadataQualityConfig, getMimeTypeForFormat, getOptionalMapConfig, getOptionalSearchConfig, getPageSize, getSearchConfigAggregations, getSearchFilters, getSearchResults, getSearchResultsAggregations, getSearchResultsHits, getSearchResultsLayout, getSearchResultsLoading, getSearchSortBy, getSearchState, getSearchStateSearch, getSpatialFilterEnabled, getTemporalRangeUnion, getThemeConfig, initSearch, initialEditorState, initialMapState, initialState, isConfigLoaded, isEndOfResults, isFormatInQueryParam, loadAppConfig, mapContact, mapKeywords, mapLogo, mapOrganization, mapReducer, markRecordAsChanged, megabytesToBytes, mimeTypeToFormat, mouseWheelZoomCondition, openDataset, openRecord, parse, placeholder, propagateToDocumentOnly, provideGn4, provideRepositoryUrl, readDataset, readDatasetHeaders, reducer$2 as reducer, reducerSearch, removeLayer, removeSearchParams, removeWhitespace, saveRecord, saveRecordFailure, saveRecordSuccess, selectEditorState, selectFallback, selectFallbackFields, selectField, selectRecord, selectRecordChangedSinceSave, selectRecordFields, selectRecordFieldsConfig, selectRecordSaveError, selectRecordSaving, selectTranslatedField, selectTranslatedValue, setLayerError, sortByFromString, sortByToString, sortByToStrings, stripHtml, toDate, totalPages, updateLayer, updateRecordField };
34961
35065
  //# sourceMappingURL=geonetwork-ui.mjs.map