geonetwork-ui 2.3.0-dev.c4b41b40 → 2.3.0-dev.cd1164a9

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 (148) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +2 -2
  2. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +2 -2
  3. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +9 -7
  4. package/esm2022/libs/feature/dataviz/src/lib/chart-view/chart-view.component.mjs +1 -1
  5. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +5 -23
  6. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.mjs +1 -1
  7. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.mjs +104 -0
  8. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +8 -3
  9. package/esm2022/libs/feature/editor/src/lib/components/wizard-field/wizard-field.component.mjs +1 -1
  10. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +8 -1
  11. package/esm2022/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.mjs +73 -20
  12. package/esm2022/libs/feature/map/src/lib/add-layer-from-wfs/add-layer-from-wfs.component.mjs +1 -1
  13. package/esm2022/libs/feature/map/src/lib/add-layer-from-wms/add-layer-from-wms.component.mjs +1 -1
  14. package/esm2022/libs/feature/map/src/lib/map-context/map-context.model.mjs +1 -1
  15. package/esm2022/libs/feature/map/src/lib/map-context/map-context.service.mjs +58 -17
  16. package/esm2022/libs/feature/map/src/lib/utils/map-utils.service.mjs +6 -2
  17. package/esm2022/libs/feature/record/src/lib/data-view/data-view.component.mjs +1 -1
  18. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +5 -3
  19. package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +1 -3
  20. package/esm2022/libs/feature/search/src/index.mjs +2 -1
  21. package/esm2022/libs/feature/search/src/lib/results-layout/results-layout.component.mjs +1 -1
  22. package/esm2022/libs/feature/search/src/lib/results-list/results-list.container.component.mjs +4 -4
  23. package/esm2022/libs/feature/search/src/lib/sort-by/sort-by.component.mjs +1 -1
  24. package/esm2022/libs/feature/search/src/lib/utils/service/fields.service.mjs +1 -1
  25. package/esm2022/libs/ui/catalog/src/lib/language-switcher/language-switcher.component.mjs +1 -1
  26. package/esm2022/libs/ui/catalog/src/lib/organisations-filter/organisations-filter.component.mjs +1 -1
  27. package/esm2022/libs/ui/elements/src/index.mjs +2 -2
  28. package/esm2022/libs/ui/elements/src/lib/api-card/api-card.component.mjs +3 -2
  29. package/esm2022/libs/ui/elements/src/lib/downloads-list/downloads-list.component.mjs +2 -2
  30. package/esm2022/libs/ui/elements/src/lib/error/error.component.mjs +30 -0
  31. package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +89 -54
  32. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +6 -6
  33. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.mjs +3 -5
  34. package/esm2022/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.mjs +4 -3
  35. package/esm2022/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.mjs +5 -3
  36. package/esm2022/libs/ui/inputs/src/lib/text-input/text-input.component.mjs +5 -3
  37. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +6 -5
  38. package/esm2022/libs/ui/layout/src/lib/carousel/carousel.component.mjs +3 -3
  39. package/esm2022/libs/util/app-config/src/lib/app-config.mjs +3 -1
  40. package/esm2022/libs/util/app-config/src/lib/fixtures.mjs +2 -1
  41. package/esm2022/libs/util/app-config/src/lib/model.mjs +1 -1
  42. package/esm2022/translations/de.json +12 -14
  43. package/esm2022/translations/en.json +12 -14
  44. package/esm2022/translations/es.json +12 -14
  45. package/esm2022/translations/fr.json +12 -14
  46. package/esm2022/translations/it.json +12 -14
  47. package/esm2022/translations/nl.json +12 -14
  48. package/esm2022/translations/pt.json +12 -14
  49. package/fesm2022/geonetwork-ui.mjs +493 -277
  50. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  51. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  52. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
  53. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  54. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts +21 -0
  55. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.d.ts.map +1 -0
  56. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +1 -0
  57. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
  58. package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
  59. package/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.d.ts +10 -5
  60. package/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.d.ts.map +1 -1
  61. package/libs/feature/map/src/lib/map-context/map-context.model.d.ts +7 -0
  62. package/libs/feature/map/src/lib/map-context/map-context.model.d.ts.map +1 -1
  63. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts +1 -1
  64. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts.map +1 -1
  65. package/libs/feature/map/src/lib/utils/map-utils.service.d.ts.map +1 -1
  66. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  67. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
  68. package/libs/feature/search/src/index.d.ts +1 -0
  69. package/libs/feature/search/src/index.d.ts.map +1 -1
  70. package/libs/feature/search/src/lib/utils/service/fields.service.d.ts +3 -3
  71. package/libs/feature/search/src/lib/utils/service/fields.service.d.ts.map +1 -1
  72. package/libs/ui/elements/src/index.d.ts +1 -1
  73. package/libs/ui/elements/src/index.d.ts.map +1 -1
  74. package/libs/ui/elements/src/lib/api-card/api-card.component.d.ts.map +1 -1
  75. package/libs/ui/elements/src/lib/error/error.component.d.ts +16 -0
  76. package/libs/ui/elements/src/lib/error/error.component.d.ts.map +1 -0
  77. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts +22 -4
  78. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts.map +1 -1
  79. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +2 -2
  80. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  81. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts +1 -2
  82. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts.map +1 -1
  83. package/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.d.ts +1 -1
  84. package/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.d.ts.map +1 -1
  85. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts +2 -1
  86. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts.map +1 -1
  87. package/libs/ui/inputs/src/lib/text-input/text-input.component.d.ts +2 -1
  88. package/libs/ui/inputs/src/lib/text-input/text-input.component.d.ts.map +1 -1
  89. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +27 -27
  90. package/libs/util/app-config/src/lib/app-config.d.ts.map +1 -1
  91. package/libs/util/app-config/src/lib/fixtures.d.ts.map +1 -1
  92. package/libs/util/app-config/src/lib/model.d.ts +1 -0
  93. package/libs/util/app-config/src/lib/model.d.ts.map +1 -1
  94. package/package.json +2 -2
  95. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +1 -1
  96. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +1 -4
  97. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +16 -10
  98. package/src/libs/common/fixtures/src/lib/link.fixtures.ts +8 -0
  99. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +4 -21
  100. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.css +0 -0
  101. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.html +14 -0
  102. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-update-frequency/form-field-update-frequency.component.ts +143 -0
  103. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +5 -0
  104. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +5 -0
  105. package/src/libs/feature/editor/src/lib/fields.config.ts +7 -0
  106. package/src/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.css +7 -0
  107. package/src/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.html +32 -18
  108. package/src/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.ts +72 -17
  109. package/src/libs/feature/map/src/lib/map-context/map-context.model.ts +7 -0
  110. package/src/libs/feature/map/src/lib/map-context/map-context.service.ts +57 -17
  111. package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +5 -1
  112. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +4 -4
  113. package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +0 -2
  114. package/src/libs/feature/search/src/index.ts +1 -0
  115. package/src/libs/feature/search/src/lib/results-list/results-list.container.component.html +4 -4
  116. package/src/libs/feature/search/src/lib/utils/service/fields.service.ts +2 -2
  117. package/src/libs/ui/elements/src/index.ts +1 -1
  118. package/src/libs/ui/elements/src/lib/api-card/api-card.component.ts +2 -1
  119. package/src/libs/ui/elements/src/lib/downloads-list/downloads-list.component.ts +1 -1
  120. package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.html → error/error.component.html} +18 -3
  121. package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.ts → error/error.component.ts} +5 -4
  122. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html +25 -9
  123. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +116 -57
  124. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +3 -4
  125. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.html +1 -1
  126. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.ts +0 -1
  127. package/src/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.ts +3 -0
  128. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.html +1 -0
  129. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.ts +1 -0
  130. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.html +1 -0
  131. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.ts +1 -0
  132. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +1 -1
  133. package/src/libs/ui/layout/src/lib/carousel/carousel.component.css +1 -0
  134. package/src/libs/util/app-config/src/lib/app-config.ts +2 -0
  135. package/src/libs/util/app-config/src/lib/fixtures.ts +1 -0
  136. package/src/libs/util/app-config/src/lib/model.ts +1 -0
  137. package/translations/de.json +12 -14
  138. package/translations/en.json +12 -14
  139. package/translations/es.json +12 -14
  140. package/translations/fr.json +12 -14
  141. package/translations/it.json +12 -14
  142. package/translations/nl.json +12 -14
  143. package/translations/pt.json +12 -14
  144. package/translations/sk.json +12 -14
  145. package/esm2022/libs/ui/elements/src/lib/search-results-error/search-results-error.component.mjs +0 -29
  146. package/libs/ui/elements/src/lib/search-results-error/search-results-error.component.d.ts +0 -15
  147. package/libs/ui/elements/src/lib/search-results-error/search-results-error.component.d.ts.map +0 -1
  148. /package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.css → error/error.component.css} +0 -0
@@ -14,7 +14,7 @@ import {
14
14
  MapContextLayerTypeEnum,
15
15
  } from '../map-context/map-context.model'
16
16
  import { TranslateModule } from '@ngx-translate/core'
17
- import { UiInputsModule } from '../../../../../../libs/ui/inputs/src'
17
+ import { DropdownChoice, UiInputsModule } from '../../../../../../libs/ui/inputs/src'
18
18
  import { CommonModule } from '@angular/common'
19
19
  import { MapLayer } from '../+state/map.models'
20
20
 
@@ -30,18 +30,16 @@ export class AddLayerFromOgcApiComponent implements OnInit {
30
30
  @Output() layerAdded = new EventEmitter<MapLayer>()
31
31
 
32
32
  urlChange = new Subject<string>()
33
- layerUrl = ''
34
33
  loading = false
35
- layers: string[] = []
36
- ogcEndpoint: OgcApiEndpoint = null
34
+ layers: any[] = []
37
35
  errorMessage: string | null = null
36
+ selectedLayerTypes: { [key: string]: DropdownChoice['value'] } = {}
38
37
 
39
38
  constructor(private changeDetectorRef: ChangeDetectorRef) {}
40
39
 
41
40
  ngOnInit() {
42
41
  this.urlChange.pipe(debounceTime(700)).subscribe(() => {
43
42
  this.loadLayers()
44
- this.changeDetectorRef.detectChanges() // manually trigger change detection
45
43
  })
46
44
  }
47
45
 
@@ -49,14 +47,13 @@ export class AddLayerFromOgcApiComponent implements OnInit {
49
47
  this.errorMessage = null
50
48
  try {
51
49
  this.loading = true
52
- if (this.ogcUrl.trim() === '') {
50
+ if (!this.ogcUrl.trim()) {
53
51
  this.layers = []
54
52
  return
55
53
  }
56
- this.ogcEndpoint = await new OgcApiEndpoint(this.ogcUrl)
57
-
58
- // Currently only supports feature collections
59
- this.layers = await this.ogcEndpoint.featureCollections
54
+ const ogcEndpoint = await new OgcApiEndpoint(this.ogcUrl)
55
+ this.layers = await ogcEndpoint.allCollections
56
+ this.setDefaultLayerTypes()
60
57
  } catch (error) {
61
58
  const err = error as Error
62
59
  this.layers = []
@@ -67,14 +64,72 @@ export class AddLayerFromOgcApiComponent implements OnInit {
67
64
  }
68
65
  }
69
66
 
70
- async addLayer(layer: string) {
71
- this.layerUrl = await this.ogcEndpoint.getCollectionItemsUrl(layer)
67
+ setDefaultLayerTypes() {
68
+ this.layers.forEach((layer) => {
69
+ const choices = this.getLayerChoices(layer)
70
+ if (choices.length > 0) {
71
+ this.selectedLayerTypes[layer.name] = choices[0].value
72
+ }
73
+ })
74
+ }
72
75
 
73
- const layerToAdd: MapContextLayerModel = {
74
- name: layer,
75
- url: this.layerUrl,
76
- type: MapContextLayerTypeEnum.OGCAPI,
76
+ getLayerChoices(layer: any) {
77
+ const choices = []
78
+ if (layer.hasRecords) {
79
+ choices.push({ label: 'Records', value: 'record' })
80
+ }
81
+ if (layer.hasFeatures) {
82
+ choices.push({ label: 'Features', value: 'features' })
83
+ }
84
+ if (layer.hasVectorTiles) {
85
+ choices.push({ label: 'Vector Tiles', value: 'vectorTiles' })
86
+ }
87
+ if (layer.hasMapTiles) {
88
+ choices.push({ label: 'Map Tiles', value: 'mapTiles' })
89
+ }
90
+ return choices
91
+ }
92
+
93
+ shouldDisplayLayer(layer: any) {
94
+ return (
95
+ layer.hasRecords ||
96
+ layer.hasFeatures ||
97
+ layer.hasVectorTiles ||
98
+ layer.hasMapTiles
99
+ )
100
+ }
101
+
102
+ onLayerTypeSelect(layerName: string, selectedType: any) {
103
+ this.selectedLayerTypes[layerName] = selectedType
104
+ ? selectedType
105
+ : this.getLayerChoices(layerName)[0]?.value
106
+ }
107
+
108
+ async addLayer(layer: string, layerType: any) {
109
+ try {
110
+ const ogcEndpoint = await new OgcApiEndpoint(this.ogcUrl)
111
+ let layerUrl: string
112
+
113
+ if (layerType === 'vectorTiles') {
114
+ layerUrl = await ogcEndpoint.getVectorTilesetUrl(layer)
115
+ } else if (layerType === 'mapTiles') {
116
+ layerUrl = await ogcEndpoint.getMapTilesetUrl(layer)
117
+ } else {
118
+ layerUrl = await ogcEndpoint.getCollectionItemsUrl(layer, {
119
+ outputFormat: 'json',
120
+ })
121
+ }
122
+
123
+ const layerToAdd: MapContextLayerModel = {
124
+ name: layer,
125
+ url: layerUrl,
126
+ type: MapContextLayerTypeEnum.OGCAPI,
127
+ layerType: layerType,
128
+ }
129
+ this.layerAdded.emit({ ...layerToAdd, title: layer })
130
+ } catch (error) {
131
+ const err = error as Error
132
+ console.error('Error adding layer:', err.message)
77
133
  }
78
- this.layerAdded.emit({ ...layerToAdd, title: layer })
79
134
  }
80
135
  }
@@ -20,29 +20,35 @@ export interface MapContextLayerWmsModel {
20
20
  type: 'wms'
21
21
  url: string
22
22
  name: string
23
+ attributions?: string
23
24
  }
24
25
 
25
26
  export interface MapContextLayerWmtsModel {
26
27
  type: 'wmts'
27
28
  url: string
28
29
  name: string
30
+ attributions?: string
29
31
  }
30
32
 
31
33
  interface MapContextLayerWfsModel {
32
34
  type: 'wfs'
33
35
  url: string
34
36
  name: string
37
+ attributions?: string
35
38
  }
36
39
 
37
40
  export interface MapContextLayerOgcapiModel {
38
41
  type: 'ogcapi'
39
42
  url: string
40
43
  name: string
44
+ layerType: 'feature' | 'vectorTiles' | 'mapTiles' | 'record'
45
+ attributions?: string
41
46
  }
42
47
 
43
48
  interface LayerXyzModel {
44
49
  type: 'xyz'
45
50
  name?: string
51
+ attributions?: string
46
52
  }
47
53
  interface LayerXyzModelWithUrl extends LayerXyzModel {
48
54
  url: string
@@ -58,6 +64,7 @@ export type MapContextLayerXyzModel =
58
64
 
59
65
  interface LayerGeojson {
60
66
  type: 'geojson'
67
+ attributions?: string
61
68
  }
62
69
  interface LayerGeojsonWithUrl extends LayerGeojson {
63
70
  url: string
@@ -25,6 +25,12 @@ import WMTS from 'ol/source/WMTS'
25
25
  import { Geometry } from 'ol/geom'
26
26
  import Feature from 'ol/Feature'
27
27
  import { WfsEndpoint, WmtsEndpoint } from '@camptocamp/ogc-client'
28
+ import OGCVectorTile from 'ol/source/OGCVectorTile.js'
29
+ import { MVT } from 'ol/format'
30
+ import VectorTileLayer from 'ol/layer/VectorTile'
31
+ import OGCMapTile from 'ol/source/OGCMapTile.js'
32
+ import ImageLayer from 'ol/layer/Image'
33
+ import ImageWMS from 'ol/source/ImageWMS'
28
34
 
29
35
  export const DEFAULT_BASELAYER_CONTEXT: MapContextLayerXyzModel = {
30
36
  type: MapContextLayerTypeEnum.XYZ,
@@ -33,6 +39,7 @@ export const DEFAULT_BASELAYER_CONTEXT: MapContextLayerXyzModel = {
33
39
  `https://b.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`,
34
40
  `https://c.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`,
35
41
  ],
42
+ attributions: `<span>© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="https://carto.com/">Carto</a></span>`,
36
43
  }
37
44
 
38
45
  export const DEFAULT_VIEW: MapContextViewModel = {
@@ -69,38 +76,69 @@ export class MapContextService {
69
76
  }
70
77
  map.setView(this.createView(mapContext.view, map))
71
78
  map.getLayers().clear()
72
- mapContext.layers.forEach((layer) => map.addLayer(this.createLayer(layer)))
79
+ mapContext.layers.forEach((layer) =>
80
+ map.addLayer(this.createLayer(layer, mapConfig))
81
+ )
73
82
  return map
74
83
  }
75
84
 
76
- createLayer(layerModel: MapContextLayerModel): Layer {
85
+ createLayer(layerModel: MapContextLayerModel, mapConfig?: MapConfig): Layer {
77
86
  const { type } = layerModel
78
87
  const style = this.styleService.styles.default
79
88
  switch (type) {
80
89
  case MapContextLayerTypeEnum.OGCAPI:
81
- return new VectorLayer({
82
- source: new VectorSource({
83
- format: new GeoJSON(),
84
- url: layerModel.url,
85
- }),
86
- style,
87
- })
88
-
90
+ if (layerModel.layerType === 'vectorTiles') {
91
+ return new VectorTileLayer({
92
+ source: new OGCVectorTile({
93
+ url: layerModel.url,
94
+ format: new MVT(),
95
+ attributions: layerModel.attributions,
96
+ }),
97
+ })
98
+ } else if (layerModel.layerType === 'mapTiles') {
99
+ return new TileLayer({
100
+ source: new OGCMapTile({
101
+ url: layerModel.url,
102
+ attributions: layerModel.attributions,
103
+ }),
104
+ })
105
+ } else {
106
+ return new VectorLayer({
107
+ source: new VectorSource({
108
+ format: new GeoJSON(),
109
+ url: layerModel.url,
110
+ attributions: layerModel.attributions,
111
+ }),
112
+ style,
113
+ })
114
+ }
89
115
  case MapContextLayerTypeEnum.XYZ:
90
116
  return new TileLayer({
91
117
  source: new XYZ({
92
118
  url: 'url' in layerModel ? layerModel.url : undefined,
93
119
  urls: 'urls' in layerModel ? layerModel.urls : undefined,
120
+ attributions: layerModel.attributions,
94
121
  }),
95
122
  })
96
123
  case MapContextLayerTypeEnum.WMS:
97
- return new TileLayer({
98
- source: new TileWMS({
99
- url: layerModel.url,
100
- params: { LAYERS: layerModel.name },
101
- gutter: 20,
102
- }),
103
- })
124
+ if (mapConfig?.DO_NOT_TILE_WMS) {
125
+ return new ImageLayer({
126
+ source: new ImageWMS({
127
+ url: layerModel.url,
128
+ params: { LAYERS: layerModel.name },
129
+ attributions: layerModel.attributions,
130
+ }),
131
+ })
132
+ } else {
133
+ return new TileLayer({
134
+ source: new TileWMS({
135
+ url: layerModel.url,
136
+ params: { LAYERS: layerModel.name, TILED: true },
137
+ attributions: layerModel.attributions,
138
+ }),
139
+ })
140
+ }
141
+
104
142
  case MapContextLayerTypeEnum.WMTS: {
105
143
  // TODO: isolate this in utils service
106
144
  const olLayer = new TileLayer({})
@@ -123,6 +161,7 @@ export class MapContextService {
123
161
  tileGrid,
124
162
  projection: matrixSet.crs,
125
163
  dimensions,
164
+ attributions: layerModel.attributions,
126
165
  })
127
166
  )
128
167
  })
@@ -148,6 +187,7 @@ export class MapContextService {
148
187
  })
149
188
  },
150
189
  strategy: bboxStrategy,
190
+ attributions: layerModel.attributions,
151
191
  })
152
192
  )
153
193
  })
@@ -26,6 +26,7 @@ import {
26
26
  MapContextLayerWmsModel,
27
27
  } from '../map-context/map-context.model'
28
28
  import Collection from 'ol/Collection'
29
+ import { defaults as defaultControls } from 'ol/control.js'
29
30
  import MapBrowserEvent from 'ol/MapBrowserEvent'
30
31
  import { CatalogRecord } from '../../../../../../libs/common/domain/src/lib/model/record'
31
32
  import { ProxyService } from '../../../../../../libs/util/shared/src'
@@ -47,7 +48,10 @@ export class MapUtilsService {
47
48
 
48
49
  createEmptyMap(): Map {
49
50
  return new Map({
50
- controls: [],
51
+ controls: defaultControls({
52
+ attribution: true,
53
+ attributionOptions: { collapsible: false },
54
+ }),
51
55
  pixelRatio: 1,
52
56
  })
53
57
  }
@@ -15,7 +15,7 @@ import {
15
15
  MapUtilsService,
16
16
  } from '../../../../../../libs/feature/map/src'
17
17
  import { getOptionalMapConfig, MapConfig } from '../../../../../../libs/util/app-config/src'
18
- import { getLinkLabel, ProxyService } from '../../../../../../libs/util/shared/src'
18
+ import { getLinkLabel } from '../../../../../../libs/util/shared/src'
19
19
  import Feature from 'ol/Feature'
20
20
  import { Geometry } from 'ol/geom'
21
21
  import { StyleLike } from 'ol/style/Style'
@@ -23,10 +23,8 @@ import {
23
23
  BehaviorSubject,
24
24
  combineLatest,
25
25
  from,
26
- lastValueFrom,
27
26
  Observable,
28
27
  of,
29
- startWith,
30
28
  Subscription,
31
29
  throwError,
32
30
  withLatestFrom,
@@ -117,7 +115,9 @@ export class MapViewComponent implements OnInit, OnDestroy {
117
115
  },
118
116
  } as MapContextModel)
119
117
  ),
120
- tap(() => this.resetSelection())
118
+ tap((res) => {
119
+ this.resetSelection()
120
+ })
121
121
  )
122
122
  ),
123
123
  withLatestFrom(this.mdViewFacade.metadata$),
@@ -82,7 +82,6 @@ const metadataViewReducer = createReducer(
82
82
  */
83
83
  on(MetadataViewActions.loadUserFeedbacks, (state) => ({
84
84
  ...state,
85
- error: null,
86
85
  allUserFeedbacksLoading: true,
87
86
  })),
88
87
  on(MetadataViewActions.addUserFeedback, (state) => ({
@@ -93,7 +92,6 @@ const metadataViewReducer = createReducer(
93
92
  MetadataViewActions.loadUserFeedbacksSuccess,
94
93
  (state, { userFeedbacks }) => ({
95
94
  ...state,
96
- error: null,
97
95
  userFeedbacks: userFeedbacks,
98
96
  addUserFeedbackLoading: false,
99
97
  allUserFeedbacksLoading: false,
@@ -8,6 +8,7 @@ export * from './lib/state/effects'
8
8
  export * from './lib/state/reducer'
9
9
  export * from './lib/utils/service/search.service'
10
10
  export * from './lib/utils/service/fields.service'
11
+ export * from './lib/utils/service/fields'
11
12
  export * from './lib/results-list/results-list.container.component'
12
13
  export * from './lib/filter-dropdown/filter-dropdown.component'
13
14
  export * from './lib/constants'
@@ -42,16 +42,16 @@
42
42
  </div>
43
43
 
44
44
  <div class="p-4 max-w-[600px] m-auto text-[13px]">
45
- <gn-ui-search-results-error
45
+ <gn-ui-error
46
46
  *ngIf="(errorCode$ | async) === 0"
47
47
  [type]="errorTypes.COULD_NOT_REACH_API"
48
48
  >
49
- </gn-ui-search-results-error>
50
- <gn-ui-search-results-error
49
+ </gn-ui-error>
50
+ <gn-ui-error
51
51
  *ngIf="(error$ | async) !== null && (errorCode$ | async) !== 0"
52
52
  [type]="errorTypes.RECEIVED_ERROR"
53
53
  [error]="errorMessage$ | async"
54
- ></gn-ui-search-results-error>
54
+ ></gn-ui-error>
55
55
  </div>
56
56
 
57
57
  <ng-template #favoriteToggle let-record>
@@ -36,7 +36,7 @@ marker('search.filters.contact')
36
36
  providedIn: 'root',
37
37
  })
38
38
  export class FieldsService {
39
- private fields = {
39
+ protected fields = {
40
40
  publisher: new OrganizationSearchField(this.injector),
41
41
  format: new SimpleSearchField('format', this.injector, 'asc'),
42
42
  resourceType: new TranslatedSearchField(
@@ -76,7 +76,7 @@ export class FieldsService {
76
76
  return Object.keys(this.fields)
77
77
  }
78
78
 
79
- constructor(private injector: Injector) {}
79
+ constructor(protected injector: Injector) {}
80
80
 
81
81
  getAvailableValues(fieldName: string) {
82
82
  if (this.supportedFields.indexOf(fieldName) === -1)
@@ -17,7 +17,7 @@ export * from './lib/pagination-buttons/pagination-buttons.component'
17
17
  export * from './lib/pagination/pagination.component'
18
18
  export * from './lib/record-api-form/record-api-form.component'
19
19
  export * from './lib/related-record-card/related-record-card.component'
20
- export * from './lib/search-results-error/search-results-error.component'
20
+ export * from './lib/error/error.component'
21
21
  export * from './lib/thumbnail/thumbnail.component'
22
22
  export * from './lib/ui-elements.module'
23
23
  export * from './lib/user-preview/user-preview.component'
@@ -26,7 +26,8 @@ export class ApiCardComponent implements OnInit, OnChanges {
26
26
 
27
27
  ngOnInit() {
28
28
  this.displayApiFormButton =
29
- this.link.accessServiceProtocol === 'ogcFeatures' ? true : false
29
+ this.link.accessServiceProtocol === 'ogcFeatures' ||
30
+ this.link.accessServiceProtocol === 'wfs'
30
31
  }
31
32
 
32
33
  ngOnChanges(changes: SimpleChanges) {
@@ -95,6 +95,6 @@ export class DownloadsListComponent {
95
95
  }
96
96
 
97
97
  isFromWfs(link: DatasetDistribution) {
98
- return link.type === 'service' && link.accessServiceProtocol === 'wfs'
98
+ return link.type === 'download' && link.accessServiceProtocol === 'wfs'
99
99
  }
100
100
  }
@@ -1,7 +1,10 @@
1
1
  <div
2
2
  class="p-[1.7em] bg-red-50 text-red-800 text-[1.5em] text-center rounded-lg"
3
3
  >
4
- <div *ngIf="type === types.COULD_NOT_REACH_API">
4
+ <div
5
+ *ngIf="type === types.COULD_NOT_REACH_API"
6
+ data-test="could-not-reach-api-error"
7
+ >
5
8
  <div class="relative opacity-40">
6
9
  <mat-icon class="material-symbols-outlined face">face</mat-icon>
7
10
  <mat-icon class="material-symbols-outlined question-mark1"
@@ -13,14 +16,26 @@
13
16
  </div>
14
17
  <div translate>search.error.couldNotReachApi</div>
15
18
  </div>
16
- <div *ngIf="type === types.RECEIVED_ERROR">
19
+ <div
20
+ *ngIf="type === types.DATASET_HAS_NO_LINK"
21
+ data-test="dataset-has-no-link-error"
22
+ >
23
+ <div class="relative opacity-40">
24
+ <mat-icon class="material-symbols-outlined face">computer</mat-icon>
25
+ </div>
26
+ <div translate>search.error.recordHasnolink</div>
27
+ </div>
28
+ <div *ngIf="type === types.RECEIVED_ERROR" data-test="received-error-error">
17
29
  <div class="relative opacity-40">
18
30
  <mat-icon class="material-symbols-outlined face">mood_bad</mat-icon>
19
31
  </div>
20
32
  <div translate>search.error.receivedError</div>
21
33
  <div *ngIf="error">{{ error }}</div>
22
34
  </div>
23
- <div *ngIf="type === types.RECORD_NOT_FOUND">
35
+ <div
36
+ *ngIf="type === types.RECORD_NOT_FOUND"
37
+ data-test="record-not-found-error"
38
+ >
24
39
  <div class="relative opacity-40">
25
40
  <mat-icon class="material-symbols-outlined computer">computer</mat-icon>
26
41
  <mat-icon class="material-symbols-outlined computer-question-mark"
@@ -4,15 +4,16 @@ export enum ErrorType {
4
4
  COULD_NOT_REACH_API,
5
5
  RECEIVED_ERROR,
6
6
  RECORD_NOT_FOUND,
7
+ DATASET_HAS_NO_LINK,
7
8
  }
8
9
 
9
10
  @Component({
10
- selector: 'gn-ui-search-results-error',
11
- templateUrl: './search-results-error.component.html',
12
- styleUrls: ['./search-results-error.component.css'],
11
+ selector: 'gn-ui-error',
12
+ templateUrl: './error.component.html',
13
+ styleUrls: ['./error.component.css'],
13
14
  changeDetection: ChangeDetectionStrategy.OnPush,
14
15
  })
15
- export class SearchResultsErrorComponent {
16
+ export class ErrorComponent {
16
17
  @Input() type!: ErrorType
17
18
  @Input() error?: string
18
19
  @Input() recordId?: string
@@ -37,15 +37,31 @@
37
37
  </div>
38
38
  </div>
39
39
  </div>
40
- <div class="flex flex-col gap-3">
41
- <p class="text-sm" translate>record.metadata.api.form.offset</p>
42
- <gn-ui-text-input
43
- class="w-20"
44
- [value]="offset$ | async"
45
- (valueChange)="setOffset($event)"
46
- hint=""
47
- >
48
- </gn-ui-text-input>
40
+ <div class="flex flex-col gap-3 relative">
41
+ <p class="text-sm" [class.text-gray-600]="!supportOffset" translate>
42
+ record.metadata.api.form.offset
43
+ </p>
44
+ <div class="flex items-center">
45
+ <gn-ui-text-input
46
+ class="w-20"
47
+ [value]="offset$ | async"
48
+ [disabled]="!supportOffset"
49
+ (valueChange)="supportOffset ? setOffset($event) : null"
50
+ hint=""
51
+ >
52
+ </gn-ui-text-input>
53
+ <div
54
+ *ngIf="!supportOffset"
55
+ class="flex items-center gap-2 text-orange-500 z-10 ml-3"
56
+ >
57
+ <span
58
+ class="material-symbols-outlined"
59
+ matTooltip="Not supported on this service"
60
+ >
61
+ warning
62
+ </span>
63
+ </div>
64
+ </div>
49
65
  </div>
50
66
  <div class="flex flex-col gap-3">
51
67
  <p class="text-sm" translate>record.metadata.api.form.type</p>