geonetwork-ui 2.3.0-dev.139106e0 → 2.3.0-dev.22f4da74

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 (215) hide show
  1. package/esm2022/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.mjs +1 -1
  2. package/esm2022/libs/api/repository/src/lib/gn4/auth/gravatar.service.mjs +12 -1
  3. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.mjs +36 -3
  4. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +19 -7
  5. package/esm2022/libs/common/domain/src/lib/model/record/index.mjs +2 -1
  6. package/esm2022/libs/common/domain/src/lib/model/record/user-feedbacks.model.mjs +2 -0
  7. package/esm2022/libs/common/domain/src/lib/model/user/index.mjs +2 -0
  8. package/esm2022/libs/common/domain/src/lib/platform.service.interface.mjs +1 -1
  9. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +35 -2
  10. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.mjs +64 -0
  11. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.mjs +15 -0
  12. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +20 -6
  13. package/esm2022/libs/feature/editor/src/lib/components/wizard-field/wizard-field.component.mjs +1 -1
  14. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +16 -1
  15. package/esm2022/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.mjs +73 -20
  16. package/esm2022/libs/feature/map/src/lib/add-layer-from-wfs/add-layer-from-wfs.component.mjs +1 -1
  17. package/esm2022/libs/feature/map/src/lib/add-layer-from-wms/add-layer-from-wms.component.mjs +1 -1
  18. package/esm2022/libs/feature/map/src/lib/map-context/map-context.model.mjs +1 -1
  19. package/esm2022/libs/feature/map/src/lib/map-context/map-context.service.mjs +29 -8
  20. package/esm2022/libs/feature/record/src/lib/feature-record.module.mjs +4 -4
  21. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +3 -2
  22. package/esm2022/libs/feature/record/src/lib/state/mdview.actions.mjs +22 -4
  23. package/esm2022/libs/feature/record/src/lib/state/mdview.effects.mjs +37 -10
  24. package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +22 -7
  25. package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +52 -17
  26. package/esm2022/libs/feature/record/src/lib/state/mdview.selectors.mjs +18 -3
  27. package/esm2022/libs/feature/router/src/lib/default/state/router.effects.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/link-card/link-card.component.mjs +16 -3
  31. package/esm2022/libs/ui/elements/src/lib/markdown-editor/markdown-editor.component.mjs +2 -2
  32. package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +77 -15
  33. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +10 -7
  34. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.mjs +59 -0
  35. package/esm2022/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.mjs +62 -0
  36. package/esm2022/libs/ui/inputs/src/index.mjs +16 -15
  37. package/esm2022/libs/ui/inputs/src/lib/date-picker/date-picker.component.mjs +22 -0
  38. package/esm2022/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.mjs +7 -5
  39. package/esm2022/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.mjs +17 -8
  40. package/esm2022/libs/ui/inputs/src/lib/previous-next-buttons/previous-next-buttons.component.mjs +29 -0
  41. package/esm2022/libs/ui/inputs/src/lib/text-area/text-area.component.mjs +27 -4
  42. package/esm2022/libs/ui/inputs/src/lib/text-input/text-input.component.mjs +21 -3
  43. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +11 -9
  44. package/esm2022/libs/ui/layout/src/index.mjs +2 -1
  45. package/esm2022/libs/ui/layout/src/lib/block-list/block-list.component.mjs +76 -0
  46. package/esm2022/libs/ui/layout/src/lib/carousel/carousel.component.mjs +42 -18
  47. package/esm2022/libs/ui/layout/src/lib/ui-layout.module.mjs +3 -8
  48. package/esm2022/libs/util/shared/src/lib/links/link-classifier.service.mjs +2 -2
  49. package/esm2022/libs/util/shared/src/lib/links/link-utils.mjs +22 -1
  50. package/esm2022/translations/de.json +21 -0
  51. package/esm2022/translations/en.json +21 -0
  52. package/esm2022/translations/es.json +21 -0
  53. package/esm2022/translations/fr.json +21 -0
  54. package/esm2022/translations/it.json +21 -0
  55. package/esm2022/translations/nl.json +21 -0
  56. package/esm2022/translations/pt.json +21 -0
  57. package/fesm2022/geonetwork-ui.mjs +1705 -808
  58. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  59. package/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.d.ts +1 -0
  60. package/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.d.ts.map +1 -1
  61. package/libs/api/repository/src/lib/gn4/auth/gravatar.service.d.ts +1 -0
  62. package/libs/api/repository/src/lib/gn4/auth/gravatar.service.d.ts.map +1 -1
  63. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.d.ts +6 -2
  64. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.d.ts.map +1 -1
  65. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts +9 -6
  66. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
  67. package/libs/common/domain/src/lib/model/record/index.d.ts +1 -0
  68. package/libs/common/domain/src/lib/model/record/index.d.ts.map +1 -1
  69. package/libs/common/domain/src/lib/model/record/user-feedbacks.model.d.ts +15 -0
  70. package/libs/common/domain/src/lib/model/record/user-feedbacks.model.d.ts.map +1 -0
  71. package/libs/common/domain/src/lib/model/user/index.d.ts +2 -0
  72. package/libs/common/domain/src/lib/model/user/index.d.ts.map +1 -0
  73. package/libs/common/domain/src/lib/platform.service.interface.d.ts +3 -0
  74. package/libs/common/domain/src/lib/platform.service.interface.d.ts.map +1 -1
  75. package/libs/feature/dataviz/src/lib/service/data.service.d.ts +3 -1
  76. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  77. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts +39 -0
  78. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.d.ts.map +1 -0
  79. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.d.ts +8 -0
  80. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.d.ts.map +1 -0
  81. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +4 -1
  82. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
  83. package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
  84. package/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.d.ts +10 -5
  85. package/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.d.ts.map +1 -1
  86. package/libs/feature/map/src/lib/map-context/map-context.model.d.ts +1 -0
  87. package/libs/feature/map/src/lib/map-context/map-context.model.d.ts.map +1 -1
  88. package/libs/feature/map/src/lib/map-context/map-context.service.d.ts.map +1 -1
  89. package/libs/feature/record/src/lib/feature-record.module.d.ts.map +1 -1
  90. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  91. package/libs/feature/record/src/lib/state/mdview.actions.d.ts +40 -6
  92. package/libs/feature/record/src/lib/state/mdview.actions.d.ts.map +1 -1
  93. package/libs/feature/record/src/lib/state/mdview.effects.d.ts +24 -4
  94. package/libs/feature/record/src/lib/state/mdview.effects.d.ts.map +1 -1
  95. package/libs/feature/record/src/lib/state/mdview.facade.d.ts +14 -4
  96. package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
  97. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts +8 -5
  98. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
  99. package/libs/feature/record/src/lib/state/mdview.selectors.d.ts +12 -9
  100. package/libs/feature/record/src/lib/state/mdview.selectors.d.ts.map +1 -1
  101. package/libs/ui/elements/src/lib/api-card/api-card.component.d.ts.map +1 -1
  102. package/libs/ui/elements/src/lib/downloads-list/downloads-list.component.d.ts +1 -1
  103. package/libs/ui/elements/src/lib/link-card/link-card.component.d.ts +3 -1
  104. package/libs/ui/elements/src/lib/link-card/link-card.component.d.ts.map +1 -1
  105. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts +12 -3
  106. package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts.map +1 -1
  107. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +16 -15
  108. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  109. package/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.d.ts +11 -0
  110. package/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.d.ts.map +1 -0
  111. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts +22 -0
  112. package/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.d.ts.map +1 -0
  113. package/libs/ui/inputs/src/index.d.ts +15 -14
  114. package/libs/ui/inputs/src/index.d.ts.map +1 -1
  115. package/libs/ui/inputs/src/lib/date-picker/date-picker.component.d.ts +9 -0
  116. package/libs/ui/inputs/src/lib/date-picker/date-picker.component.d.ts.map +1 -0
  117. package/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.d.ts +1 -1
  118. package/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.d.ts.map +1 -1
  119. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts +1 -1
  120. package/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.d.ts.map +1 -1
  121. package/libs/ui/inputs/src/lib/previous-next-buttons/previous-next-buttons.component.d.ts +12 -0
  122. package/libs/ui/inputs/src/lib/previous-next-buttons/previous-next-buttons.component.d.ts.map +1 -0
  123. package/libs/ui/inputs/src/lib/text-area/text-area.component.d.ts +7 -1
  124. package/libs/ui/inputs/src/lib/text-area/text-area.component.d.ts.map +1 -1
  125. package/libs/ui/inputs/src/lib/text-input/text-input.component.d.ts +5 -1
  126. package/libs/ui/inputs/src/lib/text-input/text-input.component.d.ts.map +1 -1
  127. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +35 -35
  128. package/libs/ui/layout/src/index.d.ts +1 -0
  129. package/libs/ui/layout/src/index.d.ts.map +1 -1
  130. package/libs/ui/layout/src/lib/block-list/block-list.component.d.ts +25 -0
  131. package/libs/ui/layout/src/lib/block-list/block-list.component.d.ts.map +1 -0
  132. package/libs/ui/layout/src/lib/carousel/carousel.component.d.ts +13 -6
  133. package/libs/ui/layout/src/lib/carousel/carousel.component.d.ts.map +1 -1
  134. package/libs/ui/layout/src/lib/ui-layout.module.d.ts +4 -5
  135. package/libs/ui/layout/src/lib/ui-layout.module.d.ts.map +1 -1
  136. package/libs/util/shared/src/lib/links/link-utils.d.ts +18 -0
  137. package/libs/util/shared/src/lib/links/link-utils.d.ts.map +1 -1
  138. package/package.json +1 -1
  139. package/src/libs/api/repository/src/lib/gn4/auth/avatar.service.interface.ts +1 -0
  140. package/src/libs/api/repository/src/lib/gn4/auth/gravatar.service.ts +12 -1
  141. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.mapper.ts +51 -1
  142. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +34 -7
  143. package/src/libs/common/domain/src/lib/model/record/index.ts +1 -0
  144. package/src/libs/common/domain/src/lib/model/record/user-feedbacks.model.ts +15 -0
  145. package/src/libs/common/domain/src/lib/platform.service.interface.ts +3 -0
  146. package/src/libs/common/fixtures/src/index.ts +8 -6
  147. package/src/libs/common/fixtures/src/lib/link.fixtures.ts +8 -0
  148. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +3 -3
  149. package/src/libs/common/fixtures/src/lib/user-feedbacks.fixtures.ts +83 -0
  150. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +51 -1
  151. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.css +0 -0
  152. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.html +8 -0
  153. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-license/form-field-license.component.ts +64 -0
  154. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.css +0 -0
  155. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.html +4 -0
  156. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-resource-updated/form-field-resource-updated.component.ts +15 -0
  157. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +33 -33
  158. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +16 -0
  159. package/src/libs/feature/editor/src/lib/fields.config.ts +15 -0
  160. package/src/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.css +7 -0
  161. package/src/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.html +32 -18
  162. package/src/libs/feature/map/src/lib/add-layer-from-ogc-api/add-layer-from-ogc-api.component.ts +72 -17
  163. package/src/libs/feature/map/src/lib/map-context/map-context.model.ts +1 -0
  164. package/src/libs/feature/map/src/lib/map-context/map-context.service.ts +26 -8
  165. package/src/libs/feature/record/src/lib/feature-record.module.ts +5 -2
  166. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +2 -1
  167. package/src/libs/feature/record/src/lib/state/mdview.actions.ts +51 -6
  168. package/src/libs/feature/record/src/lib/state/mdview.effects.ts +82 -7
  169. package/src/libs/feature/record/src/lib/state/mdview.facade.ts +48 -8
  170. package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +81 -24
  171. package/src/libs/feature/record/src/lib/state/mdview.selectors.ts +40 -10
  172. package/src/libs/feature/router/src/lib/default/state/router.effects.ts +2 -2
  173. package/src/libs/ui/elements/src/lib/api-card/api-card.component.ts +2 -1
  174. package/src/libs/ui/elements/src/lib/downloads-list/downloads-list.component.ts +1 -1
  175. package/src/libs/ui/elements/src/lib/link-card/link-card.component.html +38 -20
  176. package/src/libs/ui/elements/src/lib/link-card/link-card.component.ts +12 -0
  177. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.html +26 -10
  178. package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +87 -8
  179. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +5 -2
  180. package/src/libs/ui/elements/src/lib/user-feedback-item/time-since.pipe.ts +54 -0
  181. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.css +0 -0
  182. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.html +75 -0
  183. package/src/libs/ui/elements/src/lib/user-feedback-item/user-feedback-item.component.ts +63 -0
  184. package/src/libs/ui/inputs/src/index.ts +15 -14
  185. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.css +3 -0
  186. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.html +11 -0
  187. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.ts +16 -0
  188. package/src/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.ts +8 -1
  189. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.ts +13 -0
  190. package/src/libs/ui/inputs/src/lib/previous-next-buttons/previous-next-buttons.component.css +6 -0
  191. package/src/libs/ui/inputs/src/lib/previous-next-buttons/previous-next-buttons.component.html +26 -0
  192. package/src/libs/ui/inputs/src/lib/previous-next-buttons/previous-next-buttons.component.ts +32 -0
  193. package/src/libs/ui/inputs/src/lib/text-area/text-area.component.html +2 -1
  194. package/src/libs/ui/inputs/src/lib/text-area/text-area.component.ts +29 -0
  195. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.html +2 -1
  196. package/src/libs/ui/inputs/src/lib/text-input/text-input.component.ts +17 -1
  197. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +2 -2
  198. package/src/libs/ui/layout/src/index.ts +1 -0
  199. package/src/libs/ui/layout/src/lib/block-list/block-list.component.css +23 -0
  200. package/src/libs/ui/layout/src/lib/block-list/block-list.component.html +20 -0
  201. package/src/libs/ui/layout/src/lib/block-list/block-list.component.ts +84 -0
  202. package/src/libs/ui/layout/src/lib/carousel/carousel.component.css +7 -4
  203. package/src/libs/ui/layout/src/lib/carousel/carousel.component.html +4 -4
  204. package/src/libs/ui/layout/src/lib/carousel/carousel.component.ts +45 -15
  205. package/src/libs/ui/layout/src/lib/ui-layout.module.ts +0 -2
  206. package/src/libs/util/shared/src/lib/links/link-classifier.service.ts +1 -1
  207. package/src/libs/util/shared/src/lib/links/link-utils.ts +21 -0
  208. package/translations/de.json +21 -0
  209. package/translations/en.json +21 -0
  210. package/translations/es.json +21 -0
  211. package/translations/fr.json +21 -0
  212. package/translations/it.json +21 -0
  213. package/translations/nl.json +21 -0
  214. package/translations/pt.json +21 -0
  215. package/translations/sk.json +21 -0
@@ -5,7 +5,11 @@ import * as MdViewActions from './mdview.actions'
5
5
  import * as MdViewSelectors from './mdview.selectors'
6
6
  import { LinkClassifierService, LinkUsage } from '../../../../../../libs/util/shared/src'
7
7
  import { DatavizConfigurationModel } from '../../../../../../libs/common/domain/src/lib/model/dataviz/dataviz-configuration.model'
8
- import { CatalogRecord } from '../../../../../../libs/common/domain/src/lib/model/record'
8
+ import {
9
+ CatalogRecord,
10
+ UserFeedback,
11
+ } from '../../../../../../libs/common/domain/src/lib/model/record'
12
+ import { AvatarServiceInterface } from '../../../../../../libs/api/repository/src'
9
13
 
10
14
  @Injectable()
11
15
  /**
@@ -15,19 +19,31 @@ import { CatalogRecord } from '../../../../../../libs/common/domain/src/lib/mode
15
19
  * To clear the current record use the `close()` method.
16
20
  */
17
21
  export class MdViewFacade {
22
+ constructor(
23
+ private store: Store,
24
+ private linkClassifier: LinkClassifierService,
25
+ private avatarService: AvatarServiceInterface
26
+ ) {}
27
+
18
28
  isPresent$ = this.store.pipe(
19
29
  select(MdViewSelectors.getMetadataUuid),
20
30
  map((uuid) => !!uuid)
21
31
  )
22
- isLoading$ = this.store.pipe(select(MdViewSelectors.getMetadataIsLoading))
32
+
33
+ isMetadataLoading$ = this.store.pipe(
34
+ select(MdViewSelectors.getMetadataIsLoading)
35
+ )
36
+
23
37
  metadata$ = this.store.pipe(
24
38
  select(MdViewSelectors.getMetadata),
25
39
  filter((md) => !!md)
26
40
  )
41
+
27
42
  isIncomplete$ = this.store.pipe(
28
43
  select(MdViewSelectors.getMetadataIsIncomplete),
29
44
  filter((incomplete) => incomplete !== null)
30
45
  )
46
+
31
47
  error$ = this.store.pipe(select(MdViewSelectors.getMetadataError))
32
48
 
33
49
  related$ = this.store.pipe(select(MdViewSelectors.getRelated))
@@ -37,11 +53,13 @@ export class MdViewFacade {
37
53
  allLinks$ = this.metadata$.pipe(
38
54
  map((record) => ('distributions' in record ? record.distributions : []))
39
55
  )
56
+
40
57
  apiLinks$ = this.allLinks$.pipe(
41
58
  map((links) =>
42
59
  links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.API))
43
60
  )
44
61
  )
62
+
45
63
  mapApiLinks$ = this.allLinks$.pipe(
46
64
  map((links) =>
47
65
  links.filter((link) =>
@@ -49,6 +67,7 @@ export class MdViewFacade {
49
67
  )
50
68
  )
51
69
  )
70
+
52
71
  downloadLinks$ = this.allLinks$.pipe(
53
72
  map((links) =>
54
73
  links.filter((link) =>
@@ -56,11 +75,13 @@ export class MdViewFacade {
56
75
  )
57
76
  )
58
77
  )
78
+
59
79
  dataLinks$ = this.allLinks$.pipe(
60
80
  map((links) =>
61
81
  links.filter((link) => this.linkClassifier.hasUsage(link, LinkUsage.DATA))
62
82
  )
63
83
  )
84
+
64
85
  geoDataLinks$ = this.allLinks$.pipe(
65
86
  map((links) =>
66
87
  links.filter((link) =>
@@ -68,9 +89,11 @@ export class MdViewFacade {
68
89
  )
69
90
  )
70
91
  )
92
+
71
93
  landingPageLinks$ = this.metadata$.pipe(
72
94
  map((record) => ('landingPage' in record ? [record.landingPage] : []))
73
95
  )
96
+
74
97
  otherLinks$ = this.allLinks$.pipe(
75
98
  map((links) =>
76
99
  links.filter((link) =>
@@ -79,10 +102,13 @@ export class MdViewFacade {
79
102
  )
80
103
  )
81
104
 
82
- constructor(
83
- private store: Store,
84
- private linkClassifier: LinkClassifierService
85
- ) {}
105
+ userFeedbacks$ = this.store.pipe(select(MdViewSelectors.getUserFeedbacks))
106
+ isAllUserFeedbackLoading$ = this.store.pipe(
107
+ select(MdViewSelectors.getAllUserFeedbacksLoading)
108
+ )
109
+ isAddUserFeedbackLoading$ = this.store.pipe(
110
+ select(MdViewSelectors.getAddUserFeedbacksLoading)
111
+ )
86
112
 
87
113
  /**
88
114
  * This will show an incomplete record (e.g. from a search result) as a preview
@@ -91,16 +117,30 @@ export class MdViewFacade {
91
117
  setIncompleteMetadata(incomplete: CatalogRecord) {
92
118
  this.store.dispatch(MdViewActions.setIncompleteMetadata({ incomplete }))
93
119
  }
120
+
94
121
  /**
95
122
  * This will trigger the load of a full metadata record
96
123
  */
97
124
  loadFull(uuid: string) {
98
125
  this.store.dispatch(MdViewActions.loadFullMetadata({ uuid }))
99
126
  }
100
- close() {
101
- this.store.dispatch(MdViewActions.close())
127
+
128
+ closeMetadata() {
129
+ this.store.dispatch(MdViewActions.closeMetadata())
102
130
  }
131
+
103
132
  setChartConfig(chartConfig: DatavizConfigurationModel) {
104
133
  this.store.dispatch(MdViewActions.setChartConfig({ chartConfig }))
105
134
  }
135
+
136
+ /**
137
+ * UserFeedbacks
138
+ */
139
+ addUserFeedback(userFeedback: UserFeedback) {
140
+ this.store.dispatch(MdViewActions.addUserFeedback({ userFeedback }))
141
+ }
142
+
143
+ loadUserFeedbacks(datasetUuid: string) {
144
+ this.store.dispatch(MdViewActions.loadUserFeedbacks({ datasetUuid }))
145
+ }
106
146
  }
@@ -1,61 +1,118 @@
1
1
  import { Action, createReducer, on } from '@ngrx/store'
2
- import * as MdViewActions from './mdview.actions'
2
+ import * as MetadataViewActions from './mdview.actions'
3
3
  import { DatavizConfigurationModel } from '../../../../../../libs/common/domain/src/lib/model/dataviz/dataviz-configuration.model'
4
- import { CatalogRecord } from '../../../../../../libs/common/domain/src/lib/model/record'
4
+ import {
5
+ CatalogRecord,
6
+ UserFeedback,
7
+ } from '../../../../../../libs/common/domain/src/lib/model/record'
5
8
 
6
- export const MD_VIEW_FEATURE_STATE_KEY = 'mdView'
9
+ export const METADATA_VIEW_FEATURE_STATE_KEY = 'metadataView'
7
10
 
8
- export interface MdViewState {
11
+ export interface MetadataViewState {
9
12
  loadingFull: boolean
10
13
  error: { notFound?: boolean; otherError?: string } | null
11
14
  metadata?: Partial<CatalogRecord>
12
15
  related?: CatalogRecord[]
16
+ userFeedbacks?: UserFeedback[]
17
+ allUserFeedbacksLoading: boolean
18
+ addUserFeedbackLoading: boolean
13
19
  chartConfig?: DatavizConfigurationModel
14
20
  }
15
21
 
16
- export const initialMdviewState: MdViewState = {
22
+ export const initialMetadataViewState: MetadataViewState = {
17
23
  error: null,
18
24
  loadingFull: false,
25
+ allUserFeedbacksLoading: false,
26
+ addUserFeedbackLoading: false,
19
27
  }
20
28
 
21
- const mdViewReducer = createReducer(
22
- initialMdviewState,
23
- on(MdViewActions.loadFullMetadata, (state) => ({
29
+ const metadataViewReducer = createReducer(
30
+ initialMetadataViewState,
31
+
32
+ /*
33
+ Metadata reducers
34
+ */
35
+ on(MetadataViewActions.loadFullMetadata, (state) => ({
24
36
  ...state,
25
37
  error: null,
26
38
  loadingFull: true,
27
39
  })),
28
- on(MdViewActions.setIncompleteMetadata, (state, { incomplete }) => ({
40
+ on(MetadataViewActions.setIncompleteMetadata, (state, { incomplete }) => ({
29
41
  ...state,
30
42
  error: null,
31
43
  metadata: incomplete,
32
44
  })),
33
- on(MdViewActions.loadFullSuccess, (state, { full }) => ({
45
+ on(MetadataViewActions.loadFullMetadataSuccess, (state, { full }) => ({
34
46
  ...state,
35
47
  error: null,
36
48
  metadata: full,
37
49
  loadingFull: false,
38
50
  })),
39
- on(MdViewActions.loadFullFailure, (state, { otherError, notFound }) => ({
40
- ...state,
41
- error: { otherError, notFound },
42
- loadingFull: false,
43
- })),
44
- on(MdViewActions.setRelated, (state, { related }) => ({
51
+ on(
52
+ MetadataViewActions.loadFullMetadataFailure,
53
+ (state, { otherError, notFound }) => ({
54
+ ...state,
55
+ error: { otherError, notFound },
56
+ loadingFull: false,
57
+ })
58
+ ),
59
+ on(MetadataViewActions.closeMetadata, (state) => {
60
+ const { metadata, related, userFeedbacks, ...stateWithoutMetadata } = state
61
+ return stateWithoutMetadata
62
+ }),
63
+
64
+ /*
65
+ Related reducers
66
+ */
67
+ on(MetadataViewActions.setRelated, (state, { related }) => ({
45
68
  ...state,
46
69
  related,
47
70
  })),
48
- on(MdViewActions.setChartConfig, (state, { chartConfig }) => ({
71
+
72
+ /*
73
+ ChartConfig reducers
74
+ */
75
+ on(MetadataViewActions.setChartConfig, (state, { chartConfig }) => ({
49
76
  ...state,
50
77
  chartConfig,
51
78
  })),
52
- on(MdViewActions.close, (state) => {
53
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
54
- const { metadata, related, ...stateWithoutMd } = state
55
- return stateWithoutMd
56
- })
79
+
80
+ /*
81
+ UserFeedbacks reducers
82
+ */
83
+ on(MetadataViewActions.loadUserFeedbacks, (state) => ({
84
+ ...state,
85
+ error: null,
86
+ allUserFeedbacksLoading: true,
87
+ })),
88
+ on(MetadataViewActions.addUserFeedback, (state) => ({
89
+ ...state,
90
+ addUserFeedbackLoading: true,
91
+ })),
92
+ on(
93
+ MetadataViewActions.loadUserFeedbacksSuccess,
94
+ (state, { userFeedbacks }) => ({
95
+ ...state,
96
+ error: null,
97
+ userFeedbacks: userFeedbacks,
98
+ addUserFeedbackLoading: false,
99
+ allUserFeedbacksLoading: false,
100
+ })
101
+ ),
102
+ on(
103
+ MetadataViewActions.loadUserFeedbacksFailure,
104
+ (state, { otherError, notFound }) => ({
105
+ ...state,
106
+ error: { otherError, notFound },
107
+ addUserFeedbackLoading: false,
108
+ allUserFeedbacksLoading: false,
109
+ })
110
+ )
57
111
  )
58
112
 
59
- export function reducer(state: MdViewState | undefined, action: Action) {
60
- return mdViewReducer(state, action)
113
+ export function reducer(
114
+ metadataViewState: MetadataViewState | undefined,
115
+ action: Action
116
+ ) {
117
+ return metadataViewReducer(metadataViewState, action)
61
118
  }
@@ -1,36 +1,66 @@
1
1
  import { createFeatureSelector, createSelector } from '@ngrx/store'
2
- import { MD_VIEW_FEATURE_STATE_KEY, MdViewState } from './mdview.reducer'
2
+ import {
3
+ METADATA_VIEW_FEATURE_STATE_KEY,
4
+ MetadataViewState,
5
+ } from './mdview.reducer'
3
6
 
4
- export const getMdViewState = createFeatureSelector<MdViewState>(
5
- MD_VIEW_FEATURE_STATE_KEY
7
+ export const getMdViewState = createFeatureSelector<MetadataViewState>(
8
+ METADATA_VIEW_FEATURE_STATE_KEY
6
9
  )
7
10
 
11
+ /*
12
+ Metadata selectors
13
+ */
8
14
  export const getMetadataUuid = createSelector(
9
15
  getMdViewState,
10
- (state: MdViewState) =>
16
+ (state: MetadataViewState) =>
11
17
  state.metadata ? state.metadata.uniqueIdentifier : null
12
18
  )
13
19
  export const getMetadata = createSelector(
14
20
  getMdViewState,
15
- (state: MdViewState) => state.metadata
21
+ (state: MetadataViewState) => state.metadata
16
22
  )
17
23
  export const getMetadataIsIncomplete = createSelector(
18
24
  getMdViewState,
19
- (state: MdViewState) => (state.metadata ? state.loadingFull : null)
25
+ (state: MetadataViewState) => (state.metadata ? state.loadingFull : null)
20
26
  )
21
27
  export const getMetadataIsLoading = createSelector(
22
28
  getMdViewState,
23
- (state: MdViewState) => state.loadingFull
29
+ (state: MetadataViewState) => state.loadingFull
24
30
  )
25
31
  export const getMetadataError = createSelector(
26
32
  getMdViewState,
27
- (state: MdViewState) => state.error
33
+ (state: MetadataViewState) => state.error
28
34
  )
35
+
36
+ /*
37
+ Related selectors
38
+ */
29
39
  export const getRelated = createSelector(
30
40
  getMdViewState,
31
- (state: MdViewState) => state.related
41
+ (state: MetadataViewState) => state.related
32
42
  )
43
+
44
+ /*
45
+ Metadata selectors
46
+ */
33
47
  export const getChartConfig = createSelector(
34
48
  getMdViewState,
35
- (state: MdViewState) => state.chartConfig
49
+ (state: MetadataViewState) => state.chartConfig
50
+ )
51
+
52
+ /*
53
+ UserFeedback selectors
54
+ */
55
+ export const getUserFeedbacks = createSelector(
56
+ getMdViewState,
57
+ (state: MetadataViewState) => state.userFeedbacks
58
+ )
59
+ export const getAllUserFeedbacksLoading = createSelector(
60
+ getMdViewState,
61
+ (state: MetadataViewState) => state.allUserFeedbacksLoading
62
+ )
63
+ export const getAddUserFeedbacksLoading = createSelector(
64
+ getMdViewState,
65
+ (state: MetadataViewState) => state.addUserFeedbackLoading
36
66
  )
@@ -15,7 +15,7 @@ import {
15
15
  } from '../../../../../../../libs/common/domain/src/lib/model/search'
16
16
  import { Actions, createEffect, ofType } from '@ngrx/effects'
17
17
  import { navigation } from '@ngrx/router-store/data-persistence'
18
- import { of, pairwise, startWith, withLatestFrom } from 'rxjs'
18
+ import { of, pairwise, startWith } from 'rxjs'
19
19
  import { map, mergeMap, tap } from 'rxjs/operators'
20
20
  import * as RouterActions from './router.actions'
21
21
  import { RouterFacade } from './router.facade'
@@ -141,7 +141,7 @@ export class RouterEffects {
141
141
  navigateToSearch$ = createEffect(() =>
142
142
  this._actions$.pipe(
143
143
  navigation(this.routerConfig.searchRouteComponent, {
144
- run: () => MdViewActions.close(),
144
+ run: () => MdViewActions.closeMetadata(),
145
145
  })
146
146
  )
147
147
  )
@@ -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,25 +1,43 @@
1
1
  <a
2
2
  [href]="link.url"
3
3
  target="_blank"
4
- class="flex flex-col justify-between group h-40 grow py-5 px-5 bg-white rounded border-gray-300 filter card-shadow overflow-hidden lg:w-80"
4
+ class="flex flex-col justify-between group grow py-5 px-5 bg-white rounded border-gray-300 filter card-shadow overflow-hidden"
5
+ [ngClass]="{ 'h-40': !compact }"
6
+ [title]="title"
5
7
  >
6
- <div class="max-h-24 overflow-hidden text-ellipsis">
7
- <p
8
- class="font-title font-medium text-21 text-black break-words mb-1 line-clamp-2"
9
- >
10
- {{ link.name }}
11
- </p>
12
- <p class="font-medium text-sm break-words">
13
- {{ link.description }}
14
- </p>
15
- <p
16
- *ngIf="!link.name && !link.description"
17
- class="font-medium text-sm break-words truncate"
18
- >
19
- {{ link.url }}
20
- </p>
21
- </div>
22
- <div>
23
- <mat-icon class="material-symbols-outlined card-icon">open_in_new</mat-icon>
24
- </div>
8
+ <ng-container *ngIf="!compact; else compactTpl">
9
+ <div class="max-h-24 overflow-hidden text-ellipsis">
10
+ <p
11
+ class="font-title font-medium text-21 text-black break-words mb-1 line-clamp-2"
12
+ >
13
+ {{ link.name }}
14
+ </p>
15
+ <p class="font-medium text-sm break-words">
16
+ {{ link.description }}
17
+ </p>
18
+ <p
19
+ *ngIf="!link.name && !link.description"
20
+ class="font-medium text-sm break-words truncate"
21
+ >
22
+ {{ link.url }}
23
+ </p>
24
+ </div>
25
+ <div>
26
+ <mat-icon class="material-symbols-outlined card-icon"
27
+ >open_in_new</mat-icon
28
+ >
29
+ </div>
30
+ </ng-container>
31
+ <ng-template #compactTpl>
32
+ <div class="flex items-center justify-between gap-4">
33
+ <p
34
+ class="overflow-hidden font-title font-medium text-21 text-black text-ellipsis whitespace-nowrap"
35
+ >
36
+ {{ link.name || link.description }}
37
+ </p>
38
+ <mat-icon class="material-symbols-outlined card-icon flex-shrink-0"
39
+ >open_in_new</mat-icon
40
+ >
41
+ </div>
42
+ </ng-template>
25
43
  </a>
@@ -1,12 +1,24 @@
1
1
  import { Component, ChangeDetectionStrategy, Input } from '@angular/core'
2
2
  import { DatasetDistribution } from '../../../../../../libs/common/domain/src/lib/model/record'
3
+ import { MatIconModule } from '@angular/material/icon'
4
+ import { CommonModule } from '@angular/common'
3
5
 
4
6
  @Component({
5
7
  selector: 'gn-ui-link-card',
6
8
  templateUrl: './link-card.component.html',
7
9
  styleUrls: ['./link-card.component.css'],
8
10
  changeDetection: ChangeDetectionStrategy.OnPush,
11
+ standalone: true,
12
+ imports: [CommonModule, MatIconModule],
9
13
  })
10
14
  export class LinkCardComponent {
11
15
  @Input() link: DatasetDistribution
16
+ @Input() compact = false
17
+
18
+ get title() {
19
+ if (this.link.name && this.link.description) {
20
+ return `${this.link.name} | ${this.link.description}`
21
+ }
22
+ return this.link.name || this.link.description || ''
23
+ }
12
24
  }
@@ -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>
@@ -55,7 +71,7 @@
55
71
  extraBtnClass="secondary min-w-full !w-40 !text-black"
56
72
  [showTitle]="false"
57
73
  class="text-black"
58
- [choices]="formatsList"
74
+ [choices]="outputFormats"
59
75
  (selectValue)="setFormat($event)"
60
76
  [selected]="format$ | async"
61
77
  ></gn-ui-dropdown-selector>
@@ -1,6 +1,11 @@
1
1
  import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
2
- import { DatasetServiceDistribution } from '../../../../../../libs/common/domain/src/lib/model/record'
3
- import { BehaviorSubject, combineLatest, map } from 'rxjs'
2
+ import { OgcApiEndpoint, WfsEndpoint } from '@camptocamp/ogc-client'
3
+ import {
4
+ DatasetServiceDistribution,
5
+ ServiceProtocol,
6
+ } from '../../../../../../libs/common/domain/src/lib/model/record'
7
+ import { mimeTypeToFormat } from '../../../../../../libs/util/shared/src'
8
+ import { BehaviorSubject, combineLatest, map, switchMap } from 'rxjs'
4
9
 
5
10
  const DEFAULT_PARAMS = {
6
11
  OFFSET: '',
@@ -15,19 +20,27 @@ const DEFAULT_PARAMS = {
15
20
  })
16
21
  export class RecordApiFormComponent {
17
22
  @Input() set apiLink(value: DatasetServiceDistribution) {
18
- this.apiBaseUrl = value ? value.url.href : undefined
23
+ this.outputFormats = [{ value: 'json', label: 'JSON' }]
24
+ this.accessServiceProtocol = value ? value.accessServiceProtocol : undefined
25
+ this.apiFeatureType = value ? value.name : undefined
26
+ if (value) {
27
+ this.apiBaseUrl = value.url.href
28
+ this.parseOutputFormats()
29
+ }
19
30
  this.resetUrl()
20
31
  }
32
+
21
33
  offset$ = new BehaviorSubject('')
22
34
  limit$ = new BehaviorSubject('')
23
35
  format$ = new BehaviorSubject('')
24
36
  apiBaseUrl: string
25
- formatsList = [
26
- { label: 'JSON', value: 'json' },
27
- { label: 'CSV', value: 'csv' },
28
- ]
37
+ apiFeatureType: string
38
+ supportOffset = true
39
+ accessServiceProtocol: ServiceProtocol | undefined
40
+ outputFormats = [{ value: 'json', label: 'JSON' }]
41
+
29
42
  apiQueryUrl$ = combineLatest([this.offset$, this.limit$, this.format$]).pipe(
30
- map(([offset, limit, format]) => {
43
+ switchMap(async ([offset, limit, format]) => {
31
44
  let outputUrl
32
45
  if (this.apiBaseUrl) {
33
46
  const url = new URL(this.apiBaseUrl)
@@ -41,6 +54,20 @@ export class RecordApiFormComponent {
41
54
  }
42
55
  outputUrl = url.toString()
43
56
  }
57
+
58
+ if (this.accessServiceProtocol === 'wfs') {
59
+ const wfsEndpoint = new WfsEndpoint(this.apiBaseUrl)
60
+ if (await wfsEndpoint.isReady()) {
61
+ const options = {
62
+ outputFormat: format,
63
+ startIndex: Number(offset),
64
+ }
65
+ if (limit !== '-1') {
66
+ options['maxFeatures'] = Number(limit)
67
+ }
68
+ outputUrl = wfsEndpoint.getFeatureUrl(this.apiFeatureType, options)
69
+ }
70
+ }
44
71
  return outputUrl
45
72
  })
46
73
  )
@@ -70,4 +97,56 @@ export class RecordApiFormComponent {
70
97
  this.limit$.next(DEFAULT_PARAMS.LIMIT)
71
98
  this.format$.next(DEFAULT_PARAMS.FORMAT)
72
99
  }
100
+
101
+ parseOutputFormats() {
102
+ const apiUrl =
103
+ this.apiBaseUrl.slice(-1) === '?'
104
+ ? this.apiBaseUrl.slice(0, -1)
105
+ : this.apiBaseUrl
106
+
107
+ this.getOutputFormats(apiUrl, this.accessServiceProtocol).then(
108
+ (outputFormats) => {
109
+ let formatsList = []
110
+ if ('itemFormats' in outputFormats) {
111
+ formatsList = this.mapFormats(outputFormats.itemFormats)
112
+ } else if ('outputFormats' in outputFormats) {
113
+ formatsList = this.mapFormats(outputFormats.outputFormats)
114
+ }
115
+ this.outputFormats = this.outputFormats.concat(
116
+ formatsList.filter(Boolean)
117
+ )
118
+ this.outputFormats = this.outputFormats
119
+ .filter(
120
+ (format, index, self) =>
121
+ index === self.findIndex((t) => t.value === format.value)
122
+ )
123
+ .sort((a, b) => a.label.localeCompare(b.label))
124
+ }
125
+ )
126
+ }
127
+
128
+ mapFormats(formats: any[]) {
129
+ return formats.map((format) => {
130
+ const normalizedFormat = mimeTypeToFormat(format)
131
+ if (normalizedFormat) {
132
+ return {
133
+ label: normalizedFormat.toUpperCase(),
134
+ value: normalizedFormat,
135
+ }
136
+ }
137
+ return null
138
+ })
139
+ }
140
+
141
+ async getOutputFormats(url: string, accessServiceProtocol: string) {
142
+ if (accessServiceProtocol === 'wfs') {
143
+ const endpoint = await new WfsEndpoint(url).isReady()
144
+ this.supportOffset = endpoint.supportsStartIndex()
145
+ return endpoint.getServiceInfo()
146
+ } else {
147
+ const endpoint = await new OgcApiEndpoint(url)
148
+ const firstCollection = (await endpoint.featureCollections)[0]
149
+ return endpoint.getCollectionInfo(firstCollection)
150
+ }
151
+ }
73
152
  }