geonetwork-ui 2.8.0-dev.1f70ea679 → 2.8.0-dev.27e1de86f

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 (200) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/dcat-ap/dcat-ap.converter.mjs +3 -3
  2. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.mjs +24 -1
  3. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.mjs +7 -7
  4. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +3 -2
  5. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +4 -3
  6. package/esm2022/libs/api/repository/src/lib/gn4/elasticsearch/constant.mjs +1 -2
  7. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
  8. package/esm2022/libs/feature/dataviz/src/index.mjs +1 -2
  9. package/esm2022/libs/feature/dataviz/src/lib/geo-table-view/geo-table-view.component.mjs +2 -2
  10. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +26 -8
  11. package/esm2022/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.mjs +3 -3
  12. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +23 -3
  13. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +2 -2
  14. package/esm2022/libs/feature/map/src/lib/map-state-container/map-state-container.component.mjs +2 -2
  15. package/esm2022/libs/feature/record/src/index.mjs +2 -1
  16. package/esm2022/libs/feature/record/src/lib/data-view/data-view.component.mjs +1 -1
  17. package/esm2022/libs/feature/record/src/lib/data-view-permalink/data-view-permalink.component.mjs +13 -4
  18. package/esm2022/libs/feature/record/src/lib/data-view-web-component/data-view-web-component.component.mjs +23 -8
  19. package/esm2022/libs/feature/record/src/lib/gpf-api-dl/gpf-api-dl.component.mjs +4 -4
  20. package/esm2022/libs/feature/record/src/lib/gpf-api-dl-list-item/gpf-api-dl-list-item.component.mjs +1 -1
  21. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +2 -2
  22. package/esm2022/libs/feature/record/src/lib/stac-view/stac-view.component.mjs +230 -0
  23. package/esm2022/libs/feature/record/src/lib/stac-view/utils.mjs +26 -0
  24. package/esm2022/libs/feature/record/src/lib/state/mdview.effects.mjs +2 -2
  25. package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +13 -1
  26. package/esm2022/libs/feature/search/src/lib/constants.mjs +1 -2
  27. package/esm2022/libs/ui/elements/src/index.mjs +3 -1
  28. package/esm2022/libs/ui/elements/src/lib/downloads-list/downloads-list.component.mjs +1 -1
  29. package/esm2022/libs/ui/elements/src/lib/metadata-doi/metadata-doi.component.mjs +37 -0
  30. package/esm2022/libs/ui/elements/src/lib/metadata-info/metadata-info.component.mjs +5 -9
  31. package/esm2022/libs/ui/elements/src/lib/stac-items-result-grid/stac-items-result-grid.component.mjs +18 -0
  32. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.mjs +5 -5
  33. package/esm2022/libs/ui/inputs/src/index.mjs +2 -1
  34. package/esm2022/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.mjs +3 -3
  35. package/esm2022/libs/ui/inputs/src/lib/date-picker/date-picker.component.mjs +21 -7
  36. package/esm2022/libs/ui/inputs/src/lib/date-range-dropdown/date-range-dropdown.component.mjs +3 -3
  37. package/esm2022/libs/ui/inputs/src/lib/date-range-inputs/date-range-inputs.component.mjs +35 -0
  38. package/esm2022/libs/ui/layout/src/lib/paginable.interface.mjs +1 -1
  39. package/esm2022/libs/ui/layout/src/lib/previous-next-buttons/previous-next-buttons.component.mjs +13 -5
  40. package/esm2022/libs/ui/map/src/lib/components/map-container/map-container.component.mjs +86 -32
  41. package/esm2022/libs/ui/map/src/lib/components/spatial-extent/spatial-extent.component.mjs +1 -1
  42. package/esm2022/libs/ui/widgets/src/lib/loading-mask/loading-mask.component.mjs +3 -3
  43. package/esm2022/libs/util/i18n/src/lib/date-locales.mjs +33 -0
  44. package/esm2022/libs/util/shared/src/index.mjs +2 -1
  45. package/esm2022/libs/util/shared/src/lib/humanize-date.directive.mjs +33 -0
  46. package/esm2022/libs/util/shared/src/lib/services/date.service.mjs +19 -2
  47. package/esm2022/translations/de.json +14 -4
  48. package/esm2022/translations/en.json +14 -4
  49. package/esm2022/translations/es.json +10 -0
  50. package/esm2022/translations/fr.json +14 -4
  51. package/esm2022/translations/it.json +15 -5
  52. package/esm2022/translations/nl.json +10 -0
  53. package/esm2022/translations/pt.json +10 -0
  54. package/esm2022/translations/sk.json +11 -1
  55. package/fesm2022/geonetwork-ui-date-locales-DhlIiWpT.mjs +35 -0
  56. package/fesm2022/geonetwork-ui-date-locales-DhlIiWpT.mjs.map +1 -0
  57. package/fesm2022/geonetwork-ui.mjs +753 -232
  58. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  59. package/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.d.ts.map +1 -1
  60. package/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.d.ts.map +1 -1
  61. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts +5 -1
  62. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts.map +1 -1
  63. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  64. package/libs/api/repository/src/lib/gn4/elasticsearch/constant.d.ts.map +1 -1
  65. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +6 -1
  66. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  67. package/libs/feature/dataviz/src/index.d.ts +0 -1
  68. package/libs/feature/dataviz/src/index.d.ts.map +1 -1
  69. package/libs/feature/dataviz/src/lib/service/data.service.d.ts +2 -1
  70. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  71. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +2 -0
  72. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
  73. package/libs/feature/record/src/index.d.ts +1 -0
  74. package/libs/feature/record/src/index.d.ts.map +1 -1
  75. package/libs/feature/record/src/lib/data-view/data-view.component.d.ts +5 -1
  76. package/libs/feature/record/src/lib/data-view/data-view.component.d.ts.map +1 -1
  77. package/libs/feature/record/src/lib/data-view-permalink/data-view-permalink.component.d.ts +3 -2
  78. package/libs/feature/record/src/lib/data-view-permalink/data-view-permalink.component.d.ts.map +1 -1
  79. package/libs/feature/record/src/lib/data-view-web-component/data-view-web-component.component.d.ts +3 -2
  80. package/libs/feature/record/src/lib/data-view-web-component/data-view-web-component.component.d.ts.map +1 -1
  81. package/libs/feature/record/src/lib/gpf-api-dl/gpf-api-dl.component.d.ts +12 -5
  82. package/libs/feature/record/src/lib/gpf-api-dl/gpf-api-dl.component.d.ts.map +1 -1
  83. package/libs/feature/record/src/lib/gpf-api-dl-list-item/gpf-api-dl-list-item.component.d.ts +3 -1
  84. package/libs/feature/record/src/lib/gpf-api-dl-list-item/gpf-api-dl-list-item.component.d.ts.map +1 -1
  85. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts +5 -1
  86. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  87. package/libs/feature/record/src/lib/stac-view/stac-view.component.d.ts +53 -0
  88. package/libs/feature/record/src/lib/stac-view/stac-view.component.d.ts.map +1 -0
  89. package/libs/feature/record/src/lib/stac-view/utils.d.ts +7 -0
  90. package/libs/feature/record/src/lib/stac-view/utils.d.ts.map +1 -0
  91. package/libs/feature/record/src/lib/state/mdview.facade.d.ts +4 -0
  92. package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
  93. package/libs/feature/search/src/lib/constants.d.ts.map +1 -1
  94. package/libs/ui/elements/src/index.d.ts +2 -0
  95. package/libs/ui/elements/src/index.d.ts.map +1 -1
  96. package/libs/ui/elements/src/lib/metadata-doi/metadata-doi.component.d.ts +8 -0
  97. package/libs/ui/elements/src/lib/metadata-doi/metadata-doi.component.d.ts.map +1 -0
  98. package/libs/ui/elements/src/lib/metadata-info/metadata-info.component.d.ts +0 -2
  99. package/libs/ui/elements/src/lib/metadata-info/metadata-info.component.d.ts.map +1 -1
  100. package/libs/ui/elements/src/lib/stac-items-result-grid/stac-items-result-grid.component.d.ts +8 -0
  101. package/libs/ui/elements/src/lib/stac-items-result-grid/stac-items-result-grid.component.d.ts.map +1 -0
  102. package/libs/ui/inputs/src/index.d.ts +1 -0
  103. package/libs/ui/inputs/src/index.d.ts.map +1 -1
  104. package/libs/ui/inputs/src/lib/date-picker/date-picker.component.d.ts +5 -0
  105. package/libs/ui/inputs/src/lib/date-picker/date-picker.component.d.ts.map +1 -1
  106. package/libs/ui/inputs/src/lib/date-range-inputs/date-range-inputs.component.d.ts +12 -0
  107. package/libs/ui/inputs/src/lib/date-range-inputs/date-range-inputs.component.d.ts.map +1 -0
  108. package/libs/ui/layout/src/lib/paginable.interface.d.ts +3 -3
  109. package/libs/ui/layout/src/lib/paginable.interface.d.ts.map +1 -1
  110. package/libs/ui/layout/src/lib/previous-next-buttons/previous-next-buttons.component.d.ts +2 -1
  111. package/libs/ui/layout/src/lib/previous-next-buttons/previous-next-buttons.component.d.ts.map +1 -1
  112. package/libs/ui/map/src/lib/components/map-container/map-container.component.d.ts +24 -14
  113. package/libs/ui/map/src/lib/components/map-container/map-container.component.d.ts.map +1 -1
  114. package/libs/util/i18n/src/lib/date-locales.d.ts +5 -0
  115. package/libs/util/i18n/src/lib/date-locales.d.ts.map +1 -0
  116. package/libs/util/shared/src/index.d.ts +1 -0
  117. package/libs/util/shared/src/index.d.ts.map +1 -1
  118. package/libs/util/shared/src/lib/humanize-date.directive.d.ts +15 -0
  119. package/libs/util/shared/src/lib/humanize-date.directive.d.ts.map +1 -0
  120. package/libs/util/shared/src/lib/services/date.service.d.ts +4 -0
  121. package/libs/util/shared/src/lib/services/date.service.d.ts.map +1 -1
  122. package/package.json +5 -5
  123. package/src/libs/api/metadata-converter/src/lib/dcat-ap/dcat-ap.converter.ts +2 -2
  124. package/src/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts +1 -1
  125. package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.service+eaux-usees.ts +1 -1
  126. package/src/libs/api/metadata-converter/src/lib/fixtures/geo2france.records.ts +5 -2
  127. package/src/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +1 -1
  128. package/src/libs/api/metadata-converter/src/lib/fixtures/georhena.records.ts +1 -1
  129. package/src/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts +2 -2
  130. package/src/libs/api/metadata-converter/src/lib/fixtures/wallonie.records.reuse.ts +1 -1
  131. package/src/libs/api/metadata-converter/src/lib/fixtures/wallonie.records.service+napitswallonia.ts +1 -1
  132. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +26 -0
  133. package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +13 -6
  134. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +6 -2
  135. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +4 -2
  136. package/src/libs/api/repository/src/lib/gn4/elasticsearch/constant.ts +0 -1
  137. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +8 -1
  138. package/src/libs/feature/dataviz/src/index.ts +0 -1
  139. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +30 -5
  140. package/src/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.html +1 -0
  141. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +3 -3
  142. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +30 -0
  143. package/src/libs/feature/editor/src/lib/fields.config.ts +1 -1
  144. package/src/libs/feature/record/src/index.ts +1 -0
  145. package/src/libs/feature/record/src/lib/data-view/data-view.component.ts +5 -1
  146. package/src/libs/feature/record/src/lib/data-view-permalink/data-view-permalink.component.ts +7 -1
  147. package/src/libs/feature/record/src/lib/data-view-web-component/data-view-web-component.component.ts +23 -4
  148. package/src/libs/feature/record/src/lib/gpf-api-dl/gpf-api-dl.component.ts +10 -8
  149. package/src/libs/feature/record/src/lib/gpf-api-dl-list-item/gpf-api-dl-list-item.component.ts +1 -1
  150. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +5 -2
  151. package/src/libs/feature/record/src/lib/stac-view/stac-view.component.css +8 -0
  152. package/src/libs/feature/record/src/lib/stac-view/stac-view.component.html +87 -0
  153. package/src/libs/feature/record/src/lib/stac-view/stac-view.component.ts +339 -0
  154. package/src/libs/feature/record/src/lib/stac-view/utils.ts +57 -0
  155. package/src/libs/feature/record/src/lib/state/mdview.effects.ts +1 -1
  156. package/src/libs/feature/record/src/lib/state/mdview.facade.ts +19 -0
  157. package/src/libs/feature/search/src/lib/constants.ts +0 -1
  158. package/src/libs/ui/elements/src/index.ts +2 -0
  159. package/src/libs/ui/elements/src/lib/metadata-doi/metadata-doi.component.html +31 -0
  160. package/src/libs/ui/elements/src/lib/metadata-doi/metadata-doi.component.ts +30 -0
  161. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +67 -21
  162. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.ts +2 -9
  163. package/src/libs/ui/elements/src/lib/stac-items-result-grid/stac-items-result-grid.component.css +0 -0
  164. package/src/libs/ui/elements/src/lib/stac-items-result-grid/stac-items-result-grid.component.html +13 -0
  165. package/src/libs/ui/elements/src/lib/stac-items-result-grid/stac-items-result-grid.component.ts +15 -0
  166. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.html +1 -1
  167. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.ts +2 -2
  168. package/src/libs/ui/inputs/src/index.ts +1 -0
  169. package/src/libs/ui/inputs/src/lib/check-toggle/check-toggle.component.html +3 -3
  170. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.ts +17 -1
  171. package/src/libs/ui/inputs/src/lib/date-range-inputs/date-range-inputs.component.css +0 -0
  172. package/src/libs/ui/inputs/src/lib/date-range-inputs/date-range-inputs.component.html +15 -0
  173. package/src/libs/ui/inputs/src/lib/date-range-inputs/date-range-inputs.component.ts +41 -0
  174. package/src/libs/ui/layout/src/lib/paginable.interface.ts +3 -3
  175. package/src/libs/ui/layout/src/lib/previous-next-buttons/previous-next-buttons.component.html +12 -6
  176. package/src/libs/ui/layout/src/lib/previous-next-buttons/previous-next-buttons.component.ts +4 -1
  177. package/src/libs/ui/map/src/lib/components/map-container/map-container.component.html +16 -14
  178. package/src/libs/ui/map/src/lib/components/map-container/map-container.component.ts +144 -65
  179. package/src/libs/util/i18n/src/lib/date-locales.ts +63 -0
  180. package/src/libs/util/shared/src/index.ts +1 -0
  181. package/src/libs/util/shared/src/lib/humanize-date.directive.ts +35 -0
  182. package/src/libs/util/shared/src/lib/services/date.service.ts +27 -1
  183. package/translations/de.json +14 -4
  184. package/translations/en.json +14 -4
  185. package/translations/es.json +10 -0
  186. package/translations/fr.json +14 -4
  187. package/translations/it.json +15 -5
  188. package/translations/nl.json +10 -0
  189. package/translations/pt.json +10 -0
  190. package/translations/sk.json +11 -1
  191. package/esm2022/libs/feature/dataviz/src/lib/stac-view/stac-view.component.mjs +0 -22
  192. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.mjs +0 -59
  193. package/libs/feature/dataviz/src/lib/stac-view/stac-view.component.d.ts +0 -11
  194. package/libs/feature/dataviz/src/lib/stac-view/stac-view.component.d.ts.map +0 -1
  195. package/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.d.ts +0 -11
  196. package/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.d.ts.map +0 -1
  197. package/src/libs/feature/dataviz/src/lib/stac-view/stac-view.component.html +0 -5
  198. package/src/libs/feature/dataviz/src/lib/stac-view/stac-view.component.ts +0 -27
  199. package/src/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.ts +0 -54
  200. /package/src/libs/{feature/dataviz/src/lib/stac-view/stac-view.component.css → ui/elements/src/lib/metadata-doi/metadata-doi.component.css} +0 -0
@@ -81,7 +81,7 @@ export const RECORD_RESOURCE_CREATED_FIELD: EditorField = {
81
81
  }
82
82
 
83
83
  export const RESOURCE_IDENTIFIER_FIELD: EditorField = {
84
- model: 'resourceIdentifier',
84
+ model: 'resourceIdentifiers',
85
85
  formFieldConfig: {
86
86
  labelKey: marker('editor.record.form.field.resourceIdentifier'),
87
87
  },
@@ -8,3 +8,4 @@ export * from './lib/external-viewer-button/external-viewer-button.component'
8
8
  export * from './lib/gpf-api-dl/gpf-api-dl.component'
9
9
  export * from './lib/map-view/map-view.component'
10
10
  export * from './lib/record-meta/record-meta.component'
11
+ export * from './lib/stac-view/stac-view.component'
@@ -56,7 +56,11 @@ export class DataViewComponent {
56
56
  this.linkSelected.emit(this.selectedLink$.value)
57
57
  }
58
58
  }
59
- @Input() set datavizConfig(value: any) {
59
+ @Input() set datavizConfig(value: {
60
+ view?: string
61
+ source?: DatasetOnlineResource
62
+ chartConfig?: DatavizChartConfigModel
63
+ }) {
60
64
  if ((value && value.view === 'table') || value.view === 'chart') {
61
65
  this._selectedView = value.view
62
66
  }
@@ -12,7 +12,7 @@ import { MdViewFacade } from '../state'
12
12
  import { CopyTextButtonComponent } from '../../../../../../libs/ui/inputs/src'
13
13
  import { CommonModule } from '@angular/common'
14
14
  import { TranslatePipe } from '@ngx-translate/core'
15
- import { GEONETWORK_UI_TAG_NAME } from '../../../../../../libs/util/shared/src'
15
+ import { GEONETWORK_UI_TAG_NAME, PROXY_PATH } from '../../../../../../libs/util/shared/src'
16
16
 
17
17
  export const WEB_COMPONENT_EMBEDDER_URL = new InjectionToken<string>(
18
18
  'webComponentEmbedderUrl'
@@ -60,6 +60,9 @@ export class DataViewPermalinkComponent {
60
60
  url.searchParams.append('e', `gn-dataset-view-map`)
61
61
  }
62
62
  url.searchParams.append('a', `api-url=${this.config.basePath}`)
63
+ if (this.proxyPath) {
64
+ url.searchParams.append('a', `proxy-path=${this.proxyPath}`)
65
+ }
63
66
  url.searchParams.append('a', `dataset-id=${metadata.uniqueIdentifier}`)
64
67
  url.searchParams.append('a', `primary-color=#0f4395`)
65
68
  url.searchParams.append('a', `secondary-color=#8bc832`)
@@ -72,6 +75,9 @@ export class DataViewPermalinkComponent {
72
75
  constructor(
73
76
  @Inject(Configuration) private config: Configuration,
74
77
  @Optional()
78
+ @Inject(PROXY_PATH)
79
+ private proxyPath: string,
80
+ @Optional()
75
81
  @Inject(WEB_COMPONENT_EMBEDDER_URL)
76
82
  protected wcEmbedderBaseUrl: string,
77
83
  private facade: MdViewFacade
@@ -3,6 +3,7 @@ import {
3
3
  Component,
4
4
  Inject,
5
5
  Input,
6
+ Optional,
6
7
  } from '@angular/core'
7
8
  import { Configuration } from '../../../../../../libs/data-access/gn4/src'
8
9
  import { MdViewFacade } from '../state'
@@ -10,7 +11,7 @@ import { BehaviorSubject, combineLatest, map } from 'rxjs'
10
11
  import { CopyTextButtonComponent } from '../../../../../../libs/ui/inputs/src'
11
12
  import { CommonModule } from '@angular/common'
12
13
  import { TranslatePipe } from '@ngx-translate/core'
13
- import { GEONETWORK_UI_TAG_NAME } from '../../../../../../libs/util/shared/src'
14
+ import { GEONETWORK_UI_TAG_NAME, PROXY_PATH } from '../../../../../../libs/util/shared/src'
14
15
 
15
16
  @Component({
16
17
  selector: 'gn-ui-data-view-web-component',
@@ -42,7 +43,12 @@ export class DataViewWebComponentComponent {
42
43
  api-url="${new URL(
43
44
  this.config.basePath,
44
45
  window.location.origin
45
- ).toString()}"
46
+ ).toString()}"${
47
+ this.proxyPath
48
+ ? `
49
+ proxy-path="${this.proxyPath}"`
50
+ : ''
51
+ }
46
52
  dataset-id="${metadata.uniqueIdentifier}"
47
53
  aggregation="${aggregation}"
48
54
  x-property="${xProperty}"
@@ -65,7 +71,12 @@ export class DataViewWebComponentComponent {
65
71
  api-url="${new URL(
66
72
  this.config.basePath,
67
73
  window.location.origin
68
- ).toString()}"
74
+ ).toString()}"${
75
+ this.proxyPath
76
+ ? `
77
+ proxy-path="${this.proxyPath}"`
78
+ : ''
79
+ }
69
80
  dataset-id="${metadata.uniqueIdentifier}"
70
81
  primary-color="#0f4395"
71
82
  secondary-color="#8bc832"
@@ -82,7 +93,12 @@ export class DataViewWebComponentComponent {
82
93
  api-url="${new URL(
83
94
  this.config.basePath,
84
95
  window.location.origin
85
- ).toString()}"
96
+ ).toString()}"${
97
+ this.proxyPath
98
+ ? `
99
+ proxy-path="${this.proxyPath}"`
100
+ : ''
101
+ }
86
102
  dataset-id="${metadata.uniqueIdentifier}"
87
103
  primary-color="#0f4395"
88
104
  secondary-color="#8bc832"
@@ -97,6 +113,9 @@ export class DataViewWebComponentComponent {
97
113
 
98
114
  constructor(
99
115
  @Inject(Configuration) private config: Configuration,
116
+ @Optional()
117
+ @Inject(PROXY_PATH)
118
+ private proxyPath: string,
100
119
  private facade: MdViewFacade
101
120
  ) {}
102
121
  }
@@ -45,8 +45,8 @@ export interface TermBucket {
45
45
  }
46
46
 
47
47
  export interface Field {
48
- entry: Array<any>
49
- link: any
48
+ entry: Array<unknown>
49
+ link: Record<string, unknown>
50
50
  }
51
51
 
52
52
  @Component({
@@ -75,7 +75,7 @@ export class GpfApiDlComponent implements OnInit {
75
75
  page$ = new BehaviorSubject(1)
76
76
  url =
77
77
  'https://data.geopf.fr/telechargement/capabilities?outputFormat=application/json'
78
- choices: any
78
+ choices: { zone: TermBucket[]; format: TermBucket[]; category: TermBucket[] }
79
79
  bucketPromisesZone: Choice[]
80
80
  bucketPromisesFormat: Choice[]
81
81
  bucketPromisesCrs: Choice[]
@@ -144,8 +144,10 @@ export class GpfApiDlComponent implements OnInit {
144
144
  })
145
145
  )
146
146
 
147
- getFilteredProduct$(url): Observable<any> {
148
- return this.http.get(url)
147
+ getFilteredProduct$(
148
+ url
149
+ ): Observable<{ entry: unknown[]; totalentries: number }> {
150
+ return this.http.get<{ entry: unknown[]; totalentries: number }>(url)
149
151
  }
150
152
 
151
153
  getLinkFormat(produit): string {
@@ -224,7 +226,7 @@ export class GpfApiDlComponent implements OnInit {
224
226
 
225
227
  const tempZone = this.choices.zone.map((bucket) => ({
226
228
  value: bucket.term,
227
- label: bucket.label,
229
+ label: String(bucket.label),
228
230
  }))
229
231
  tempZone.sort((a, b) => (a.label > b.label ? 1 : -1))
230
232
  tempZone.unshift({ value: 'null', label: 'ZONE' })
@@ -233,7 +235,7 @@ export class GpfApiDlComponent implements OnInit {
233
235
 
234
236
  const tempFormat = this.choices.format.map((bucket) => ({
235
237
  value: bucket.term,
236
- label: bucket.label,
238
+ label: String(bucket.label),
237
239
  }))
238
240
  tempFormat.sort((a, b) => (a.label > b.label ? 1 : -1))
239
241
  tempFormat.unshift({ value: 'null', label: 'FORMAT' })
@@ -242,7 +244,7 @@ export class GpfApiDlComponent implements OnInit {
242
244
 
243
245
  const tempCrs = this.choices.category.map((bucket) => ({
244
246
  value: bucket.term,
245
- label: bucket.label,
247
+ label: String(bucket.label),
246
248
  }))
247
249
  tempCrs.sort((a, b) => (a.label > b.label ? 1 : -1))
248
250
  tempCrs.unshift({ value: 'null', label: 'CRS' })
@@ -28,7 +28,7 @@ export class GpfApiDlListItemComponent implements OnInit {
28
28
  @Input() isFromWfs: boolean
29
29
 
30
30
  constructor(protected http: HttpClient) {}
31
- liste$: Observable<any>
31
+ liste$: Observable<{ entry: unknown[] }>
32
32
 
33
33
  ngOnInit(): void {
34
34
  this.liste$ = this.http
@@ -27,7 +27,6 @@ import {
27
27
  map,
28
28
  shareReplay,
29
29
  switchMap,
30
- take,
31
30
  tap,
32
31
  } from 'rxjs/operators'
33
32
  import { MdViewFacade } from '../state/mdview.facade'
@@ -118,7 +117,11 @@ export class MapViewComponent implements AfterViewInit {
118
117
  @Input() set selectedView(value: string) {
119
118
  this.selectedView$.next(value)
120
119
  }
121
- @Input() set datavizConfig(value: any) {
120
+ @Input() set datavizConfig(value: {
121
+ view?: string
122
+ styleTMSIndex?: number
123
+ source?: DatasetOnlineResource
124
+ }) {
122
125
  if (value && value.view === 'map') {
123
126
  this.selectedView$.next(value.view)
124
127
  if (value.styleTMSIndex) {
@@ -0,0 +1,8 @@
1
+ :host {
2
+ --gn-ui-button-padding: 7px 8px;
3
+ }
4
+
5
+ /* Ensure OpenLayers controls are above the custom toggle */
6
+ ::ng-deep .ol-overlaycontainer-stopevent {
7
+ z-index: 11 !important;
8
+ }
@@ -0,0 +1,87 @@
1
+ <div class="mt-6 bg-white border border-gray-300 overflow-hidden rounded-lg">
2
+ <div
3
+ class="w-full h-[700px] md:h-[366px] flex md:flex-row flex-col border-b border-gray-300"
4
+ >
5
+ @let filterState = filterState$ | async;
6
+
7
+ <div class="w-full md:w-5/12 h-[366px] flex flex-col">
8
+ <gn-ui-date-range-inputs
9
+ [temporalExtent]="filterState.temporalExtent"
10
+ (temporalExtentChange)="onTemporalExtentChange($event)"
11
+ ></gn-ui-date-range-inputs>
12
+
13
+ <div class="mt-auto mb-8 mx-8" *ngIf="isFilterModified$ | async">
14
+ <gn-ui-button
15
+ id="reset-filters-button"
16
+ type="light"
17
+ (buttonClick)="onResetFilters()"
18
+ >
19
+ <span translate>stac.filter.reset</span>
20
+ <ng-icon name="matDeleteOutline" class="ml-2"></ng-icon>
21
+ </gn-ui-button>
22
+ </div>
23
+ </div>
24
+
25
+ <div class="w-full md:w-7/12 h-[334px] md:h-[366px] flex flex-col">
26
+ <gn-ui-map-container
27
+ #mapContainer
28
+ [context]="mapContext$ | async"
29
+ (extentChange)="onSpatialExtentChange($event)"
30
+ (resolvedExtentChange)="onResolvedMapExtentChange($event)"
31
+ class="w-full h-full"
32
+ >
33
+ <div
34
+ class="bg-white rounded-xl shadow-xl absolute left-1/2 transform -translate-x-1/2 bottom-0 mb-2.5 px-4 py-2 z-10 max-w-[90%] w-max"
35
+ >
36
+ <gn-ui-check-toggle
37
+ [value]="filterState.isSpatialExtentFilterEnabled"
38
+ (toggled)="onSpatialFilterToggle($event)"
39
+ [label]="'stac.filter.enable' | translate"
40
+ [color]="'primary'"
41
+ ></gn-ui-check-toggle>
42
+ </div>
43
+ </gn-ui-map-container>
44
+ </div>
45
+ </div>
46
+ <div
47
+ class="relative mx-5 my-[30px] min-h-[274px] flex items-center justify-center flex-col"
48
+ >
49
+ <!-- Keep grid outside ngIf to keep items$ observable alive -->
50
+ <gn-ui-stac-items-result-grid
51
+ [items]="items$ | async"
52
+ ></gn-ui-stac-items-result-grid>
53
+ <div
54
+ *ngIf="(items$ | async)?.length > 0; else noResultsOrError"
55
+ class="mt-[20px] mx-auto flex justify-center"
56
+ >
57
+ <gn-ui-previous-next-buttons
58
+ [listComponent]="this"
59
+ [displayLabels]="true"
60
+ ></gn-ui-previous-next-buttons>
61
+ </div>
62
+ <ng-template #noResultsOrError>
63
+ <gn-ui-popup-alert
64
+ *ngIf="error$ | async as error"
65
+ type="warning"
66
+ icon="matErrorOutlineOutline"
67
+ class="absolute left-0 top-0 w-full block"
68
+ >
69
+ <span translate>{{ error }}</span>
70
+ </gn-ui-popup-alert>
71
+ <div
72
+ *ngIf="(error$ | async) === null"
73
+ class="flex items-center justify-center flex-col h-full gap-[10px]"
74
+ >
75
+ <h2 class="text-center text-xl" translate>stac.results.noResults</h2>
76
+ <gn-ui-button
77
+ id="no-results-button"
78
+ type="secondary"
79
+ (buttonClick)="onResetFilters()"
80
+ >
81
+ <span translate>stac.filter.reset</span>
82
+ <ng-icon name="matDeleteOutline" class="ml-2"></ng-icon>
83
+ </gn-ui-button>
84
+ </div>
85
+ </ng-template>
86
+ </div>
87
+ </div>
@@ -0,0 +1,339 @@
1
+ import { CommonModule } from '@angular/common'
2
+ import {
3
+ AfterViewInit,
4
+ ChangeDetectionStrategy,
5
+ Component,
6
+ OnInit,
7
+ ViewChild,
8
+ } from '@angular/core'
9
+ import {
10
+ DatasetRecord,
11
+ DatasetTemporalExtent,
12
+ } from '../../../../../../libs/common/domain/src/lib/model/record'
13
+ import {
14
+ ButtonComponent,
15
+ DateRangeInputsComponent,
16
+ CheckToggleComponent,
17
+ } from '../../../../../../libs/ui/inputs/src'
18
+ import {
19
+ MapContainerComponent,
20
+ prioritizePageScroll,
21
+ } from '../../../../../../libs/ui/map/src'
22
+ import { Extent, MapContext } from '@geospatial-sdk/core/dist/model'
23
+ import { StacItemsResultGridComponent } from '../../../../../../libs/ui/elements/src'
24
+ import { NgIconComponent, provideIcons } from '@ng-icons/core'
25
+ import { matDeleteOutline } from '@ng-icons/material-icons/outline'
26
+ import {
27
+ TranslateDirective,
28
+ TranslatePipe,
29
+ TranslateService,
30
+ } from '@ngx-translate/core'
31
+ import { DataService } from '../../../../../../libs/feature/dataviz/src'
32
+ import {
33
+ BehaviorSubject,
34
+ catchError,
35
+ debounceTime,
36
+ distinctUntilChanged,
37
+ from,
38
+ map,
39
+ Observable,
40
+ of,
41
+ shareReplay,
42
+ switchMap,
43
+ take,
44
+ tap,
45
+ } from 'rxjs'
46
+ import { GetCollectionItemsOptions, StacItem } from '@camptocamp/ogc-client'
47
+ import { MdViewFacade } from '../state'
48
+ import {
49
+ areSpatialExtentsEqual,
50
+ areTemporalExtentsEqual,
51
+ areFilterStatesEqual,
52
+ } from './utils'
53
+ import { MapUtilsService } from '../../../../../../libs/feature/map/src'
54
+ import { PreviousNextButtonsComponent } from '../../../../../../libs/ui/layout/src'
55
+ import { FetchError } from '../../../../../../libs/util/data-fetcher/src'
56
+ import { PopupAlertComponent } from '../../../../../../libs/ui/widgets/src'
57
+
58
+ const STAC_ITEMS_PER_PAGE = 12
59
+ const DEBOUNCE_TIME_MS = 500
60
+
61
+ export interface StacFilterState {
62
+ temporalExtent: DatasetTemporalExtent | null
63
+ spatialExtent: Extent | null
64
+ isSpatialExtentFilterEnabled: boolean
65
+ pageUrl: string | null
66
+ }
67
+
68
+ @Component({
69
+ selector: 'gn-ui-stac-view',
70
+ templateUrl: './stac-view.component.html',
71
+ styleUrls: ['./stac-view.component.css'],
72
+ changeDetection: ChangeDetectionStrategy.OnPush,
73
+ standalone: true,
74
+ imports: [
75
+ CommonModule,
76
+ NgIconComponent,
77
+ TranslateDirective,
78
+ TranslatePipe,
79
+ StacItemsResultGridComponent,
80
+ DateRangeInputsComponent,
81
+ MapContainerComponent,
82
+ CheckToggleComponent,
83
+ PreviousNextButtonsComponent,
84
+ PopupAlertComponent,
85
+ ButtonComponent,
86
+ ],
87
+ viewProviders: [provideIcons({ matDeleteOutline })],
88
+ })
89
+ export class StacViewComponent implements OnInit, AfterViewInit {
90
+ @ViewChild('mapContainer') mapContainer: MapContainerComponent
91
+
92
+ initialTemporalExtent: DatasetTemporalExtent | null = null
93
+ initialSpatialExtent: Extent | null = null
94
+ resolvedInitialSpatialExtent: Extent | null = null
95
+ initialPageUrl: string
96
+ previousPageUrl: string
97
+ nextPageUrl: string
98
+
99
+ error$ = new BehaviorSubject<string | null>(null)
100
+ mapContext$ = new BehaviorSubject<MapContext>({
101
+ layers: [],
102
+ view: null,
103
+ })
104
+ filterState$ = new BehaviorSubject<StacFilterState>({
105
+ temporalExtent: null,
106
+ spatialExtent: null,
107
+ isSpatialExtentFilterEnabled: true,
108
+ pageUrl: null,
109
+ })
110
+
111
+ isFilterModified$ = this.filterState$.pipe(
112
+ map((filterState) => {
113
+ const isTemporalModified = !areTemporalExtentsEqual(
114
+ filterState.temporalExtent,
115
+ this.initialTemporalExtent
116
+ )
117
+
118
+ const isSpatialModified =
119
+ this.resolvedInitialSpatialExtent &&
120
+ filterState.spatialExtent !== null &&
121
+ filterState.isSpatialExtentFilterEnabled &&
122
+ !areSpatialExtentsEqual(
123
+ filterState.spatialExtent,
124
+ this.resolvedInitialSpatialExtent
125
+ )
126
+
127
+ return isTemporalModified || isSpatialModified
128
+ }),
129
+ shareReplay({ bufferSize: 1, refCount: false })
130
+ )
131
+
132
+ items$: Observable<StacItem[]> = this.filterState$.pipe(
133
+ debounceTime(DEBOUNCE_TIME_MS),
134
+ distinctUntilChanged((prev, curr) => areFilterStatesEqual(prev, curr)),
135
+ switchMap((filterState) => {
136
+ if (filterState.pageUrl === null) {
137
+ return of([])
138
+ }
139
+
140
+ this.error$.next(null)
141
+ return from(
142
+ this.dataService.getItemsFromStacApi(
143
+ filterState.pageUrl,
144
+ this.buildRequestOptions(filterState)
145
+ )
146
+ ).pipe(
147
+ tap((stacDocument) => {
148
+ this.previousPageUrl =
149
+ stacDocument.links.find((link) => link.rel === 'previous')?.href ||
150
+ null
151
+ this.nextPageUrl =
152
+ stacDocument.links.find((link) => link.rel === 'next')?.href || null
153
+ }),
154
+ map((stacDocument) => stacDocument.features),
155
+ catchError((err) => {
156
+ this.handleError(err)
157
+ return of([])
158
+ })
159
+ )
160
+ }),
161
+ shareReplay({ bufferSize: 1, refCount: false })
162
+ )
163
+
164
+ constructor(
165
+ private dataService: DataService,
166
+ private metadataViewFacade: MdViewFacade,
167
+ private mapUtils: MapUtilsService,
168
+ private translateService: TranslateService
169
+ ) {}
170
+
171
+ ngOnInit() {
172
+ this.metadataViewFacade.metadata$
173
+ .pipe(
174
+ take(1),
175
+ map((metadata) => {
176
+ const temporalExtents =
177
+ metadata?.kind === 'dataset'
178
+ ? (metadata as DatasetRecord).temporalExtents
179
+ : []
180
+
181
+ const temporalExtent =
182
+ temporalExtents.length > 0
183
+ ? temporalExtents[0]
184
+ : ({
185
+ start: null,
186
+ end: null,
187
+ } as DatasetTemporalExtent)
188
+
189
+ const spatialExtent = this.mapUtils.getRecordExtent(metadata)
190
+ return { temporalExtent, spatialExtent }
191
+ })
192
+ )
193
+ .subscribe(({ temporalExtent, spatialExtent }) => {
194
+ this.initialTemporalExtent = temporalExtent
195
+ this.initialSpatialExtent = spatialExtent
196
+
197
+ this.filterState$.next({
198
+ ...this.filterState$.value,
199
+ temporalExtent: this.initialTemporalExtent,
200
+ })
201
+
202
+ this.mapContext$.next({
203
+ ...this.mapContext$.value,
204
+ view: {
205
+ extent: spatialExtent,
206
+ },
207
+ })
208
+ })
209
+
210
+ this.metadataViewFacade.stacLinks$
211
+ .pipe(
212
+ take(1),
213
+ map((links) => (links && links.length > 0 ? links[0] : null))
214
+ )
215
+ .subscribe((link) => {
216
+ if (link) {
217
+ this.initialPageUrl = link.url.href
218
+ this.filterState$.next({
219
+ ...this.filterState$.value,
220
+ pageUrl: link.url.href,
221
+ })
222
+ }
223
+ })
224
+ }
225
+
226
+ async ngAfterViewInit() {
227
+ const map = await this.mapContainer.openlayersMap
228
+ prioritizePageScroll(map.getInteractions())
229
+ }
230
+
231
+ onTemporalExtentChange(extent: DatasetTemporalExtent | null) {
232
+ this.filterState$.next({
233
+ ...this.filterState$.value,
234
+ temporalExtent: extent,
235
+ pageUrl: this.initialPageUrl,
236
+ })
237
+ }
238
+
239
+ onSpatialExtentChange(extent: Extent) {
240
+ this.filterState$.next({
241
+ ...this.filterState$.value,
242
+ spatialExtent: extent,
243
+ pageUrl: this.initialPageUrl,
244
+ })
245
+ }
246
+
247
+ onResolvedMapExtentChange(extent: Extent) {
248
+ this.resolvedInitialSpatialExtent = extent
249
+ }
250
+
251
+ onSpatialFilterToggle(enabled: boolean) {
252
+ this.filterState$.next({
253
+ ...this.filterState$.value,
254
+ isSpatialExtentFilterEnabled: enabled,
255
+ pageUrl: this.initialPageUrl,
256
+ })
257
+ }
258
+
259
+ onResetFilters() {
260
+ this.mapContext$.next({
261
+ ...this.mapContext$.value,
262
+ view: {
263
+ extent: this.initialSpatialExtent,
264
+ },
265
+ })
266
+
267
+ this.filterState$.next({
268
+ temporalExtent: this.initialTemporalExtent,
269
+ spatialExtent: this.resolvedInitialSpatialExtent,
270
+ isSpatialExtentFilterEnabled: true,
271
+ pageUrl: this.initialPageUrl,
272
+ })
273
+ }
274
+
275
+ private buildRequestOptions(
276
+ filterState: StacFilterState
277
+ ): GetCollectionItemsOptions {
278
+ const options: GetCollectionItemsOptions = {
279
+ limit: STAC_ITEMS_PER_PAGE,
280
+ }
281
+
282
+ if (
283
+ filterState.temporalExtent &&
284
+ (filterState.temporalExtent.start || filterState.temporalExtent.end)
285
+ ) {
286
+ options.datetime = {
287
+ ...(filterState.temporalExtent.start && {
288
+ start: filterState.temporalExtent.start,
289
+ }),
290
+ ...(filterState.temporalExtent.end && {
291
+ end: filterState.temporalExtent.end,
292
+ }),
293
+ }
294
+ }
295
+
296
+ if (filterState.isSpatialExtentFilterEnabled && filterState.spatialExtent) {
297
+ options.bbox = filterState.spatialExtent
298
+ }
299
+
300
+ return options
301
+ }
302
+
303
+ handleError(error: FetchError | Error | string) {
304
+ if (error instanceof FetchError) {
305
+ this.error$.next(
306
+ this.translateService.instant(`dataset.error.${error.type}`, {
307
+ info: error.info,
308
+ })
309
+ )
310
+ console.warn(error.message)
311
+ } else if (error instanceof Error) {
312
+ this.error$.next(this.translateService.instant(error.message))
313
+ console.warn(error.stack || error)
314
+ } else {
315
+ this.error$.next(this.translateService.instant(error))
316
+ console.warn(error)
317
+ }
318
+ }
319
+
320
+ // Paginable API
321
+ get isFirstPage() {
322
+ return this.previousPageUrl == null
323
+ }
324
+ get isLastPage() {
325
+ return this.nextPageUrl == null
326
+ }
327
+ goToNextPage() {
328
+ this.filterState$.next({
329
+ ...this.filterState$.value,
330
+ pageUrl: this.nextPageUrl,
331
+ })
332
+ }
333
+ goToPrevPage() {
334
+ this.filterState$.next({
335
+ ...this.filterState$.value,
336
+ pageUrl: this.previousPageUrl,
337
+ })
338
+ }
339
+ }