geonetwork-ui 2.7.0-dev.dbe423d28 → 2.7.0-dev.ed54e0aff

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 (242) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/dcat-ap/read-parts.mjs +4 -7
  2. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.mjs +20 -20
  3. package/esm2022/libs/api/metadata-converter/src/lib/gn4/metadata-url.service.mjs +3 -3
  4. package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.mjs +3 -3
  5. package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.mjs +3 -3
  6. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +4 -4
  7. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/utils/status.mapper.mjs +4 -1
  8. package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +9 -5
  9. package/esm2022/libs/api/repository/src/index.mjs +2 -2
  10. package/esm2022/libs/api/repository/src/lib/gn4/auth/auth.service.mjs +5 -5
  11. package/esm2022/libs/api/repository/src/lib/gn4/elasticsearch/constant.mjs +4 -6
  12. package/esm2022/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.mjs +55 -12
  13. package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +3 -3
  14. package/esm2022/libs/api/repository/src/lib/gn4/organizations/organizations-from-groups.service.mjs +3 -3
  15. package/esm2022/libs/api/repository/src/lib/gn4/organizations/organizations-from-metadata.service.mjs +3 -3
  16. package/esm2022/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.mjs +52 -24
  17. package/esm2022/libs/api/repository/src/lib/gn4/settings/gn4-settings.service.mjs +3 -1
  18. package/esm2022/libs/api/repository/src/lib/metadata-language.token.mjs +3 -0
  19. package/esm2022/libs/common/domain/src/lib/model/dataviz/dataviz-configuration.model.mjs +1 -1
  20. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +15 -1
  21. package/esm2022/libs/common/domain/src/lib/platform.service.interface.mjs +1 -1
  22. package/esm2022/libs/feature/catalog/src/lib/sources/sources.service.mjs +3 -3
  23. package/esm2022/libs/feature/dataviz/src/lib/chart-view/chart-view.component.mjs +10 -2
  24. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +2 -2
  25. package/esm2022/libs/feature/editor/src/index.mjs +2 -1
  26. package/esm2022/libs/feature/editor/src/lib/components/metadata-quality-panel/metadata-quality-panel.component.mjs +80 -0
  27. package/esm2022/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.mjs +3 -3
  28. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field-inspire-field/form-field-inspire-theme.component.mjs +55 -0
  29. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.mjs +8 -3
  30. package/esm2022/libs/feature/editor/src/lib/components/record-form/form-field/index.mjs +2 -1
  31. package/esm2022/libs/feature/editor/src/lib/fields.config.mjs +77 -3
  32. package/esm2022/libs/feature/map/src/lib/utils/map-utils.service.mjs +3 -5
  33. package/esm2022/libs/feature/record/src/lib/data-view/data-view.component.mjs +31 -12
  34. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +76 -27
  35. package/esm2022/libs/feature/router/src/lib/default/state/query-params.utils.mjs +4 -3
  36. package/esm2022/libs/feature/router/src/lib/default/state/router.facade.mjs +3 -2
  37. package/esm2022/libs/feature/search/src/lib/state/reducer.mjs +5 -2
  38. package/esm2022/libs/ui/dataviz/src/lib/data-table/data-table.component.mjs +4 -3
  39. package/esm2022/libs/ui/elements/src/lib/api-card/api-card.component.mjs +3 -3
  40. package/esm2022/libs/ui/elements/src/lib/downloads-list/downloads-list.component.mjs +5 -4
  41. package/esm2022/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.mjs +5 -4
  42. package/esm2022/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.mjs +4 -4
  43. package/esm2022/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.mjs +21 -46
  44. package/esm2022/libs/ui/elements/src/lib/metadata-quality-item/metadata-quality-item.component.mjs +7 -7
  45. package/esm2022/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.mjs +1 -6
  46. package/esm2022/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.mjs +5 -4
  47. package/esm2022/libs/util/app-config/src/lib/app-config.mjs +5 -1
  48. package/esm2022/libs/util/app-config/src/lib/fixtures.mjs +2 -2
  49. package/esm2022/libs/util/app-config/src/lib/model.mjs +1 -1
  50. package/esm2022/libs/util/app-config/src/lib/parse-utils.mjs +5 -4
  51. package/esm2022/libs/util/i18n/src/lib/language-codes.mjs +50 -9
  52. package/esm2022/libs/util/shared/src/index.mjs +2 -2
  53. package/esm2022/libs/util/shared/src/lib/links/link-utils.mjs +12 -2
  54. package/esm2022/libs/util/shared/src/lib/record/index.mjs +3 -0
  55. package/esm2022/libs/util/shared/src/lib/record/quality-score.util.mjs +46 -0
  56. package/esm2022/libs/util/shared/src/lib/record/record.util.mjs +56 -0
  57. package/esm2022/libs/util/shared/src/lib/utils/geojson.mjs +58 -1
  58. package/esm2022/libs/util/shared/src/lib/utils/index.mjs +2 -1
  59. package/esm2022/libs/util/shared/src/lib/utils/mobile-screen.mjs +9 -0
  60. package/esm2022/translations/de.json +60 -21
  61. package/esm2022/translations/en.json +61 -22
  62. package/esm2022/translations/es.json +47 -8
  63. package/esm2022/translations/fr.json +66 -27
  64. package/esm2022/translations/it.json +60 -21
  65. package/esm2022/translations/nl.json +47 -8
  66. package/esm2022/translations/pt.json +47 -8
  67. package/esm2022/translations/sk.json +51 -12
  68. package/fesm2022/geonetwork-ui.mjs +3337 -2966
  69. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  70. package/libs/api/metadata-converter/src/lib/dcat-ap/read-parts.d.ts.map +1 -1
  71. package/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.d.ts +1 -1
  72. package/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.d.ts.map +1 -1
  73. package/libs/api/metadata-converter/src/lib/iso19139/utils/status.mapper.d.ts.map +1 -1
  74. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts +2 -2
  75. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  76. package/libs/api/repository/src/index.d.ts +1 -1
  77. package/libs/api/repository/src/index.d.ts.map +1 -1
  78. package/libs/api/repository/src/lib/gn4/elasticsearch/constant.d.ts.map +1 -1
  79. package/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.d.ts +1 -2
  80. package/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.d.ts.map +1 -1
  81. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts +9 -7
  82. package/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.d.ts.map +1 -1
  83. package/libs/api/repository/src/lib/gn4/settings/gn4-settings.service.d.ts +2 -0
  84. package/libs/api/repository/src/lib/gn4/settings/gn4-settings.service.d.ts.map +1 -1
  85. package/libs/api/repository/src/lib/metadata-language.token.d.ts +5 -0
  86. package/libs/api/repository/src/lib/metadata-language.token.d.ts.map +1 -0
  87. package/libs/common/domain/src/lib/model/dataviz/dataviz-configuration.model.d.ts +1 -0
  88. package/libs/common/domain/src/lib/model/dataviz/dataviz-configuration.model.d.ts.map +1 -1
  89. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +5 -1
  90. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  91. package/libs/common/domain/src/lib/platform.service.interface.d.ts +2 -0
  92. package/libs/common/domain/src/lib/platform.service.interface.d.ts.map +1 -1
  93. package/libs/feature/catalog/src/lib/sources/sources.service.d.ts.map +1 -1
  94. package/libs/feature/dataviz/src/lib/chart-view/chart-view.component.d.ts +3 -2
  95. package/libs/feature/dataviz/src/lib/chart-view/chart-view.component.d.ts.map +1 -1
  96. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  97. package/libs/feature/editor/src/index.d.ts +1 -0
  98. package/libs/feature/editor/src/index.d.ts.map +1 -1
  99. package/libs/feature/editor/src/lib/components/metadata-quality-panel/metadata-quality-panel.component.d.ts +19 -0
  100. package/libs/feature/editor/src/lib/components/metadata-quality-panel/metadata-quality-panel.component.d.ts.map +1 -0
  101. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-inspire-field/form-field-inspire-theme.component.d.ts +20 -0
  102. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field-inspire-field/form-field-inspire-theme.component.d.ts.map +1 -0
  103. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts +1 -0
  104. package/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.d.ts.map +1 -1
  105. package/libs/feature/editor/src/lib/components/record-form/form-field/index.d.ts +1 -0
  106. package/libs/feature/editor/src/lib/components/record-form/form-field/index.d.ts.map +1 -1
  107. package/libs/feature/editor/src/lib/fields.config.d.ts +8 -1
  108. package/libs/feature/editor/src/lib/fields.config.d.ts.map +1 -1
  109. package/libs/feature/map/src/lib/utils/map-utils.service.d.ts +2 -2
  110. package/libs/feature/map/src/lib/utils/map-utils.service.d.ts.map +1 -1
  111. package/libs/feature/record/src/lib/data-view/data-view.component.d.ts +8 -4
  112. package/libs/feature/record/src/lib/data-view/data-view.component.d.ts.map +1 -1
  113. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts +12 -5
  114. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  115. package/libs/feature/router/src/lib/default/state/query-params.utils.d.ts.map +1 -1
  116. package/libs/feature/router/src/lib/default/state/router.facade.d.ts.map +1 -1
  117. package/libs/feature/search/src/lib/state/reducer.d.ts.map +1 -1
  118. package/libs/ui/dataviz/src/lib/data-table/data-table.component.d.ts.map +1 -1
  119. package/libs/ui/elements/src/lib/downloads-list/downloads-list.component.d.ts +1 -0
  120. package/libs/ui/elements/src/lib/downloads-list/downloads-list.component.d.ts.map +1 -1
  121. package/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.d.ts +1 -0
  122. package/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.d.ts.map +1 -1
  123. package/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.d.ts.map +1 -1
  124. package/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.d.ts +7 -7
  125. package/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.d.ts.map +1 -1
  126. package/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.d.ts.map +1 -1
  127. package/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.d.ts +1 -0
  128. package/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.d.ts.map +1 -1
  129. package/libs/util/app-config/src/lib/app-config.d.ts.map +1 -1
  130. package/libs/util/app-config/src/lib/model.d.ts +2 -0
  131. package/libs/util/app-config/src/lib/model.d.ts.map +1 -1
  132. package/libs/util/app-config/src/lib/parse-utils.d.ts.map +1 -1
  133. package/libs/util/i18n/src/lib/language-codes.d.ts +91 -31
  134. package/libs/util/i18n/src/lib/language-codes.d.ts.map +1 -1
  135. package/libs/util/shared/src/index.d.ts +1 -1
  136. package/libs/util/shared/src/index.d.ts.map +1 -1
  137. package/libs/util/shared/src/lib/links/link-utils.d.ts +2 -1
  138. package/libs/util/shared/src/lib/links/link-utils.d.ts.map +1 -1
  139. package/libs/util/shared/src/lib/record/index.d.ts +3 -0
  140. package/libs/util/shared/src/lib/record/index.d.ts.map +1 -0
  141. package/libs/util/shared/src/lib/record/quality-score.util.d.ts +13 -0
  142. package/libs/util/shared/src/lib/record/quality-score.util.d.ts.map +1 -0
  143. package/libs/util/shared/src/lib/record/record.util.d.ts +3 -0
  144. package/libs/util/shared/src/lib/record/record.util.d.ts.map +1 -0
  145. package/libs/util/shared/src/lib/utils/geojson.d.ts +7 -2
  146. package/libs/util/shared/src/lib/utils/geojson.d.ts.map +1 -1
  147. package/libs/util/shared/src/lib/utils/index.d.ts +1 -0
  148. package/libs/util/shared/src/lib/utils/index.d.ts.map +1 -1
  149. package/libs/util/shared/src/lib/utils/mobile-screen.d.ts +2 -0
  150. package/libs/util/shared/src/lib/utils/mobile-screen.d.ts.map +1 -0
  151. package/package.json +11 -10
  152. package/src/libs/api/metadata-converter/src/lib/dcat-ap/read-parts.ts +3 -6
  153. package/src/libs/api/metadata-converter/src/lib/dcat-ap/utils/status.mapper.ts +3 -0
  154. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +47 -22
  155. package/src/libs/api/metadata-converter/src/lib/gn4/metadata-url.service.ts +2 -2
  156. package/src/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.ts +2 -2
  157. package/src/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.ts +2 -2
  158. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +3 -3
  159. package/src/libs/api/metadata-converter/src/lib/iso19139/utils/status.mapper.ts +3 -0
  160. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +10 -6
  161. package/src/libs/api/repository/src/index.ts +1 -1
  162. package/src/libs/api/repository/src/lib/gn4/auth/auth.service.ts +4 -4
  163. package/src/libs/api/repository/src/lib/gn4/elasticsearch/constant.ts +3 -5
  164. package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +65 -14
  165. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +2 -2
  166. package/src/libs/api/repository/src/lib/gn4/organizations/organizations-from-groups.service.ts +2 -2
  167. package/src/libs/api/repository/src/lib/gn4/organizations/organizations-from-metadata.service.ts +2 -2
  168. package/src/libs/api/repository/src/lib/gn4/platform/gn4-platform.service.ts +60 -39
  169. package/src/libs/api/repository/src/lib/gn4/settings/gn4-settings.service.ts +8 -0
  170. package/src/libs/api/repository/src/lib/metadata-language.token.ts +8 -0
  171. package/src/libs/common/domain/src/lib/model/dataviz/dataviz-configuration.model.ts +1 -0
  172. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +21 -1
  173. package/src/libs/common/domain/src/lib/platform.service.interface.ts +3 -0
  174. package/src/libs/common/fixtures/src/lib/editor/editor.fixtures.ts +0 -3
  175. package/src/libs/feature/catalog/src/lib/sources/sources.service.ts +2 -5
  176. package/src/libs/feature/dataviz/src/lib/chart-view/chart-view.component.ts +10 -1
  177. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +3 -1
  178. package/src/libs/feature/editor/src/index.ts +1 -0
  179. package/src/libs/feature/editor/src/lib/components/metadata-quality-panel/metadata-quality-panel.component.css +0 -0
  180. package/src/libs/feature/editor/src/lib/components/metadata-quality-panel/metadata-quality-panel.component.html +37 -0
  181. package/src/libs/feature/editor/src/lib/components/metadata-quality-panel/metadata-quality-panel.component.ts +90 -0
  182. package/src/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.html +2 -1
  183. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-inspire-field/form-field-inspire-theme.component.css +0 -0
  184. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-inspire-field/form-field-inspire-theme.component.html +22 -0
  185. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-inspire-field/form-field-inspire-theme.component.ts +57 -0
  186. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +6 -0
  187. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +5 -0
  188. package/src/libs/feature/editor/src/lib/components/record-form/form-field/index.ts +1 -0
  189. package/src/libs/feature/editor/src/lib/fields.config.ts +85 -3
  190. package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +8 -8
  191. package/src/libs/feature/record/src/lib/data-view/data-view.component.html +2 -0
  192. package/src/libs/feature/record/src/lib/data-view/data-view.component.ts +34 -15
  193. package/src/libs/feature/record/src/lib/map-view/map-view.component.html +2 -0
  194. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +70 -23
  195. package/src/libs/feature/router/src/lib/default/state/query-params.utils.ts +5 -2
  196. package/src/libs/feature/router/src/lib/default/state/router.facade.ts +2 -1
  197. package/src/libs/feature/search/src/lib/state/reducer.ts +4 -1
  198. package/src/libs/ui/dataviz/src/lib/data-table/data-table.component.ts +6 -1
  199. package/src/libs/ui/elements/src/lib/api-card/api-card.component.html +4 -1
  200. package/src/libs/ui/elements/src/lib/downloads-list/downloads-list.component.html +12 -11
  201. package/src/libs/ui/elements/src/lib/downloads-list/downloads-list.component.ts +7 -1
  202. package/src/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.html +4 -1
  203. package/src/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.ts +7 -1
  204. package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.html +1 -0
  205. package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.ts +5 -1
  206. package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.html +1 -0
  207. package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.ts +21 -58
  208. package/src/libs/ui/elements/src/lib/metadata-quality-item/metadata-quality-item.component.ts +6 -6
  209. package/src/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.ts +0 -6
  210. package/src/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.html +7 -1
  211. package/src/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.ts +3 -1
  212. package/src/libs/util/app-config/src/lib/app-config.ts +4 -0
  213. package/src/libs/util/app-config/src/lib/fixtures.ts +1 -1
  214. package/src/libs/util/app-config/src/lib/model.ts +2 -0
  215. package/src/libs/util/app-config/src/lib/parse-utils.ts +4 -7
  216. package/src/libs/util/i18n/src/lib/language-codes.ts +62 -11
  217. package/src/libs/util/shared/src/index.ts +1 -1
  218. package/src/libs/util/shared/src/lib/links/link-utils.ts +11 -1
  219. package/src/libs/util/shared/src/lib/record/index.ts +2 -0
  220. package/src/libs/util/shared/src/lib/record/quality-score.util.ts +72 -0
  221. package/src/libs/util/shared/src/lib/{record.util.ts → record/record.util.ts} +1 -1
  222. package/src/libs/util/shared/src/lib/utils/geojson.ts +72 -2
  223. package/src/libs/util/shared/src/lib/utils/index.ts +1 -0
  224. package/src/libs/util/shared/src/lib/utils/mobile-screen.ts +14 -0
  225. package/translations/de.json +60 -21
  226. package/translations/en.json +61 -22
  227. package/translations/es.json +47 -8
  228. package/translations/fr.json +66 -27
  229. package/translations/it.json +60 -21
  230. package/translations/nl.json +47 -8
  231. package/translations/pt.json +47 -8
  232. package/translations/sk.json +51 -12
  233. package/esm2022/libs/api/repository/src/lib/metadata-language.mjs +0 -3
  234. package/esm2022/libs/util/app-config/src/lib/constants.mjs +0 -439
  235. package/esm2022/libs/util/shared/src/lib/record.util.mjs +0 -56
  236. package/libs/api/repository/src/lib/metadata-language.d.ts +0 -3
  237. package/libs/api/repository/src/lib/metadata-language.d.ts.map +0 -1
  238. package/libs/util/app-config/src/lib/constants.d.ts +0 -2
  239. package/libs/util/app-config/src/lib/constants.d.ts.map +0 -1
  240. package/libs/util/shared/src/lib/record.util.d.ts +0 -3
  241. package/libs/util/shared/src/lib/record.util.d.ts.map +0 -1
  242. package/src/libs/api/repository/src/lib/metadata-language.ts +0 -3
@@ -14,15 +14,16 @@ import {
14
14
  PopoverComponent,
15
15
  ProgressBarComponent,
16
16
  } from '../../../../../../libs/ui/widgets/src'
17
+ import {
18
+ getQualityValidators,
19
+ getAllKeysValidator,
20
+ type ValidatorMapperKeys,
21
+ } from '../../../../../../libs/util/shared/src'
17
22
  import { CommonModule } from '@angular/common'
18
23
  import { TranslateDirective } from '@ngx-translate/core'
19
24
  import { NgIcon, provideIcons, provideNgIconsConfig } from '@ng-icons/core'
20
25
  import { matInfoOutline } from '@ng-icons/material-icons/outline'
21
26
 
22
- type QualityChecks = {
23
- [key: string]: (metadata: Partial<CatalogRecord>) => boolean
24
- }
25
-
26
27
  @Component({
27
28
  selector: 'gn-ui-metadata-quality',
28
29
  templateUrl: './metadata-quality.component.html',
@@ -48,77 +49,39 @@ type QualityChecks = {
48
49
  ],
49
50
  })
50
51
  export class MetadataQualityComponent implements OnChanges {
51
- @Input() metadata: Partial<CatalogRecord>
52
+ @Input() metadata: CatalogRecord
52
53
  @Input() smaller = false
53
54
  @Input() metadataQualityDisplay: boolean
55
+ @Input() popoverDisplay = true
56
+ @Input() propsToValidate?: ValidatorMapperKeys[]
57
+ @Input() forceComputeScore = false // Instead of returning es' quality score
54
58
 
55
59
  items: MetadataQualityItem[] = []
56
60
 
57
61
  get qualityScore() {
58
- const qualityScore = this.metadata?.extras?.qualityScore
62
+ const qualityScore = !this.forceComputeScore
63
+ ? this.metadata?.extras?.qualityScore
64
+ : this.computedQualityScore
65
+
59
66
  return typeof qualityScore === 'number'
60
67
  ? qualityScore
61
- : this.calculatedQualityScore
68
+ : this.computedQualityScore
62
69
  }
63
70
 
64
- get calculatedQualityScore(): number {
71
+ get computedQualityScore(): number {
65
72
  return Math.round(
66
73
  (this.items.filter(({ value }) => value).length * 100) / this.items.length
67
74
  )
68
75
  }
69
76
 
70
- private add(name: string, value: boolean) {
71
- if (this.metadataQualityDisplay?.[name] !== false) {
72
- this.items.push({ name, value })
73
- }
74
- }
75
- hasGetCapabilities(url: string): boolean {
76
- return url.toLowerCase().includes('capabilities')
77
- }
78
-
79
- private readonly COMMON_CHECKS: QualityChecks = {
80
- title: (metadata) => !!metadata?.title,
81
- description: (metadata) => !!metadata?.abstract,
82
- keywords: (metadata) => (metadata?.keywords?.length ?? 0) > 0,
83
- legalConstraints: (metadata) =>
84
- (metadata?.legalConstraints?.length ?? 0) > 0,
85
- contact: (metadata) => !!metadata?.contacts?.[0]?.email,
86
- }
87
-
88
- private readonly SPECIFIC_CHECKS: Record<string, QualityChecks> = {
89
- dataset: {
90
- updateFrequency: (metadata) => !!metadata?.updateFrequency,
91
- topic: (metadata) => (metadata?.topics?.length ?? 0) > 0,
92
- organisation: (metadata) => !!metadata?.contacts?.[0]?.organization?.name,
93
- },
94
- service: {
95
- capabilities: (metadata) =>
96
- (metadata?.onlineResources ?? []).some((resource) =>
97
- this.hasGetCapabilities(resource?.url?.href ?? '')
98
- ),
99
- },
100
- reuse: {
101
- topic: (metadata) => (metadata?.topics?.length ?? 0) > 0,
102
- organisation: (metadata) => !!metadata?.contacts?.[0]?.organization?.name,
103
- source: (metadata) => !!metadata?.extras?.sourcesIdentifiers,
104
- },
105
- }
106
-
107
77
  initialize() {
108
- this.items = []
109
-
110
- Object.entries(this.COMMON_CHECKS).forEach(([name, check]) => {
111
- this.add(name, check(this.metadata))
112
- })
113
-
114
- const datasetType = this.metadata?.kind
115
- if (datasetType && this.SPECIFIC_CHECKS[datasetType]) {
116
- Object.entries(this.SPECIFIC_CHECKS[datasetType]).forEach(
117
- ([name, check]) => {
118
- this.add(name, check(this.metadata))
119
- }
120
- )
78
+ if (!this.propsToValidate) {
79
+ this.propsToValidate = getAllKeysValidator()
121
80
  }
81
+
82
+ this.items = getQualityValidators(this.metadata, this.propsToValidate).map(
83
+ ({ name, validator }) => ({ name, value: validator() })
84
+ )
122
85
  }
123
86
 
124
87
  ngOnChanges(changes: SimpleChanges): void {
@@ -6,16 +6,16 @@ import { matCheck, matWarningAmber } from '@ng-icons/material-icons/baseline'
6
6
 
7
7
  marker('record.metadata.quality.title.success')
8
8
  marker('record.metadata.quality.title.failed')
9
- marker('record.metadata.quality.description.success')
10
- marker('record.metadata.quality.description.failed')
11
- marker('record.metadata.quality.topic.success')
12
- marker('record.metadata.quality.topic.failed')
9
+ marker('record.metadata.quality.abstract.success')
10
+ marker('record.metadata.quality.abstract.failed')
11
+ marker('record.metadata.quality.topics.success')
12
+ marker('record.metadata.quality.topics.failed')
13
13
  marker('record.metadata.quality.keywords.success')
14
14
  marker('record.metadata.quality.keywords.failed')
15
15
  marker('record.metadata.quality.legalConstraints.success')
16
16
  marker('record.metadata.quality.legalConstraints.failed')
17
- marker('record.metadata.quality.contact.success')
18
- marker('record.metadata.quality.contact.failed')
17
+ marker('record.metadata.quality.contacts.success')
18
+ marker('record.metadata.quality.contacts.failed')
19
19
  marker('record.metadata.quality.updateFrequency.success')
20
20
  marker('record.metadata.quality.updateFrequency.failed')
21
21
  marker('record.metadata.quality.organisation.success')
@@ -136,12 +136,6 @@ export class ServiceCapabilitiesComponent implements OnInit {
136
136
  }
137
137
 
138
138
  selectLayer(layer: WfsFeatureTypeFull | WmsLayerFull | WmtsLayer) {
139
- if (layer === this.selectedLayer) {
140
- this.selectedLayer = null
141
- this.layerInformation = []
142
- return
143
- }
144
-
145
139
  this.selectedLayer = layer
146
140
  const filteredInfo = []
147
141
  Object.keys(layer).map((key) => {
@@ -1,5 +1,8 @@
1
1
  <div
2
2
  class="flex items-center justify-between p-3 mt-8 bg-white rounded-lg border-b solid border-gray-300"
3
+ *ngIf="
4
+ (isMobile$ | async) === false || featureCatalog?.featureTypes?.length > 1
5
+ "
3
6
  >
4
7
  <div
5
8
  class="relative shrink-0"
@@ -17,7 +20,10 @@
17
20
  name="iconoirSearch"
18
21
  ></ng-icon>
19
22
  </div>
20
- <div class="text-sm px-1 ml-auto hidden sm:inline">
23
+ <div
24
+ *ngIf="(isMobile$ | async) === false"
25
+ class="text-sm px-1 ml-auto inline"
26
+ >
21
27
  <ng-container *ngIf="featureCatalog?.featureTypes?.length > 1">
22
28
  <span
23
29
  class="text-sm font-medium text-gray-900"
@@ -6,7 +6,7 @@ import { DatasetFeatureCatalog } from '../../../../../../libs/common/domain/src/
6
6
  import { FormsModule } from '@angular/forms'
7
7
  import { of } from 'rxjs'
8
8
  import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators'
9
- import { createFuzzyFilter } from '../../../../../../libs/util/shared/src'
9
+ import { createFuzzyFilter, getIsMobile } from '../../../../../../libs/util/shared/src'
10
10
  import { iconoirSearch } from '@ng-icons/iconoir'
11
11
 
12
12
  @Component({
@@ -39,6 +39,8 @@ export class SearchFeatureCatalogComponent {
39
39
  return this._featureCatalog
40
40
  }
41
41
 
42
+ isMobile$ = getIsMobile()
43
+
42
44
  @Output() filteredFeatureCatalogChange =
43
45
  new EventEmitter<DatasetFeatureCatalog>()
44
46
  filteredFeatureCatalog: DatasetFeatureCatalog
@@ -102,6 +102,7 @@ export function loadAppConfig() {
102
102
  'web_component_embedder_url',
103
103
  'languages',
104
104
  'contact_email',
105
+ 'reuse_form_url',
105
106
  ],
106
107
  warnings,
107
108
  errors
@@ -131,6 +132,7 @@ export function loadAppConfig() {
131
132
  parsedGlobalSection.web_component_embedder_url,
132
133
  LANGUAGES: parsedGlobalSection.languages,
133
134
  CONTACT_EMAIL: parsedGlobalSection.contact_email,
135
+ REUSE_FORM_URL: parsedGlobalSection.reuse_form_url,
134
136
  } as GlobalConfig)
135
137
 
136
138
  const parsedLayersSections = parseMultiConfigSection(
@@ -229,6 +231,7 @@ export function loadAppConfig() {
229
231
  'filter_geometry_url',
230
232
  'search_preset',
231
233
  'advanced_filters',
234
+ 'limit',
232
235
  ],
233
236
  warnings,
234
237
  errors
@@ -255,6 +258,7 @@ export function loadAppConfig() {
255
258
  filters: param.filters,
256
259
  })),
257
260
  ADVANCED_FILTERS: parsedSearchSection.advanced_filters,
261
+ LIMIT: parsedSearchSection.limit,
258
262
  } as SearchConfig)
259
263
 
260
264
  const parsedMetadataQualitySection = parseConfigSection(
@@ -124,7 +124,7 @@ export const wrongLanguageCodeConfigFixture = () => `
124
124
  [global]
125
125
  geonetwork4_api_url = "/geonetwork/srv/api"
126
126
  proxy_path = "/proxy/?url="
127
- metadata_language = "fra"
127
+ metadata_language = "abc"
128
128
 
129
129
  [map]
130
130
 
@@ -11,6 +11,7 @@ export interface GlobalConfig {
11
11
  WEB_COMPONENT_EMBEDDER_URL?: string
12
12
  LANGUAGES?: string[]
13
13
  CONTACT_EMAIL?: string
14
+ REUSE_FORM_URL?: string
14
15
  }
15
16
 
16
17
  export interface LayerConfig {
@@ -59,6 +60,7 @@ export interface SearchConfig {
59
60
  FILTER_GEOMETRY_DATA?: string
60
61
  SEARCH_PRESET?: SearchPreset[]
61
62
  ADVANCED_FILTERS?: []
63
+ LIMIT?: number
62
64
  }
63
65
 
64
66
  export interface MetadataQualityConfig {
@@ -1,4 +1,4 @@
1
- import { LANGUAGE_CODES_ISO_3 } from './constants'
1
+ import { toLang2 } from '../../../../../libs/util/i18n/src'
2
2
 
3
3
  const flatten = (
4
4
  base: string,
@@ -129,13 +129,10 @@ export function checkMetadataLanguage(
129
129
  parsedConfigSection: any,
130
130
  outWarnings: string[]
131
131
  ) {
132
- if (
133
- LANGUAGE_CODES_ISO_3.indexOf(
134
- parsedConfigSection.metadata_language.toLowerCase()
135
- ) === -1
136
- ) {
132
+ const lang2 = toLang2(parsedConfigSection.metadata_language.toLowerCase())
133
+ if (lang2?.length !== 2) {
137
134
  outWarnings.push(
138
- `In the [global] section: metadata_language = "${parsedConfigSection.metadata_language}" is not in ISO 639-2/B format`
135
+ `In the [global] section: metadata_language = "${parsedConfigSection.metadata_language}" is not a recognized ISO 639 language code`
139
136
  )
140
137
  }
141
138
  return parsedConfigSection
@@ -1,20 +1,32 @@
1
1
  import { marker } from '@biesbjerg/ngx-translate-extract-marker'
2
2
 
3
+ /**
4
+ * Taken from https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes
5
+ * Note: some languages have multiple 3-char codes, like 'fre' and 'fra'; in that case, the one to be used
6
+ * in priority is the one defined last
7
+ */
3
8
  const LANG_3_TO_2_MAPPER = {
4
9
  eng: 'en',
10
+ nld: 'nl', // duplicate for "dut"
5
11
  dut: 'nl',
12
+ fra: 'fr', // duplicate for "fre"
6
13
  fre: 'fr',
14
+ deu: 'de', // duplicate for "ger"
7
15
  ger: 'de',
8
16
  kor: 'ko',
9
17
  spa: 'es',
18
+ ces: 'cs', // duplicate for "cze"
10
19
  cze: 'cs',
11
20
  cat: 'ca',
12
21
  fin: 'fi',
22
+ isl: 'is', // duplicate for "ice"
13
23
  ice: 'is',
14
24
  ita: 'it',
15
25
  por: 'pt',
16
26
  rus: 'ru',
27
+ zho: 'zh', // duplicate for "chi"
17
28
  chi: 'zh',
29
+ slk: 'sk', // duplicate for "slo"
18
30
  slo: 'sk',
19
31
  roh: 'rm',
20
32
  ara: 'ar',
@@ -25,10 +37,12 @@ const LANG_3_TO_2_MAPPER = {
25
37
  tur: 'tr',
26
38
  arm: 'hy',
27
39
  aze: 'az',
40
+ kat: 'ka', // duplicate for "geo"
28
41
  geo: 'ka',
29
42
  ukr: 'uk',
43
+ cym: 'cy', // duplicate for "wel"
30
44
  wel: 'cy',
31
- }
45
+ } as const
32
46
 
33
47
  export const LANGUAGE_NAMES = {
34
48
  en: 'English',
@@ -58,26 +72,63 @@ export const LANGUAGE_NAMES = {
58
72
  ka: 'ქართული',
59
73
  uk: 'українська',
60
74
  wel: 'Cymraeg',
61
- }
75
+ } as const
76
+
77
+ export type LanguageCode3 = keyof typeof LANG_3_TO_2_MAPPER
78
+ export type LanguageCode2 = (typeof LANG_3_TO_2_MAPPER)[LanguageCode3]
62
79
 
63
80
  export const LANG_2_TO_3_MAPPER = Object.entries(LANG_3_TO_2_MAPPER).reduce(
64
81
  (mapperObject, langEntry) => {
65
82
  return { ...mapperObject, [langEntry[1]]: langEntry[0] }
66
83
  },
67
84
  {}
68
- )
85
+ ) as Record<LanguageCode2, LanguageCode3>
69
86
 
70
- export function getLang3FromLang2(lang2: string): string {
71
- return LANG_2_TO_3_MAPPER[lang2] ?? lang2
72
- }
87
+ /**
88
+ * This can be:
89
+ * - an ISO 639-2 language code in 3 characters (e.g. 'eng', 'fre', 'ger')
90
+ * - an ISO 639-1 language code in 2 characters (e.g. 'en', 'fr', 'de')
91
+ * - a 2-character language code with locale (e.g. 'fr_FR', 'fr_CA')
92
+ */
93
+ export type LanguageCodeLike = LanguageCode2 | LanguageCode3 | string
73
94
 
74
- export function getLang2FromLang3(lang3: string): string {
75
- return LANG_3_TO_2_MAPPER[lang3] ?? lang3
95
+ /**
96
+ * Converts a language code in any format to the ISO 639-2 format (3 characters)
97
+ * Returns the given string if the corresponding language code could not be recognized
98
+ */
99
+ export function toLang3(lang: LanguageCodeLike): LanguageCode3 | string {
100
+ if (!lang) {
101
+ // also handle falsy values just in case
102
+ return lang
103
+ }
104
+ if (lang.length === 3) {
105
+ return LANG_2_TO_3_MAPPER[LANG_3_TO_2_MAPPER[lang.toLowerCase()]] ?? lang
106
+ }
107
+ const lang2 = lang.toLowerCase().substring(0, 2)
108
+ return LANG_2_TO_3_MAPPER[lang2] ?? lang
76
109
  }
77
110
 
78
- export function getLocalizedIndexKey(lang2: string): string {
79
- const lang3 = getLang3FromLang2(lang2)
80
- return lang3 ? `lang${lang3}` : null
111
+ /**
112
+ * Converts a language code in any format to the ISO 639-1 format (2 characters)
113
+ * Returns the given string if the corresponding language code could not be recognized
114
+ */
115
+ export function toLang2(lang: LanguageCodeLike): LanguageCode2 | string {
116
+ if (!lang) {
117
+ // also handle falsy values just in case
118
+ return lang
119
+ }
120
+ if (lang.length === 3) {
121
+ return LANG_3_TO_2_MAPPER[lang.toLowerCase()] ?? lang
122
+ }
123
+ const lang2 = lang.toLowerCase().substring(0, 2)
124
+ if (lang2 in LANG_2_TO_3_MAPPER) {
125
+ return lang2
126
+ }
127
+ if (lang.match(/[a-z]{2}_[A-Z]{2}/)) {
128
+ // remove locale code even if the language code is not known
129
+ return lang2
130
+ }
131
+ return lang
81
132
  }
82
133
 
83
134
  marker('language.en')
@@ -3,4 +3,4 @@ export * from './lib/utils'
3
3
  export * from './lib/links'
4
4
  export * from './lib/image-fallback.directive'
5
5
  export * from './lib/gn-ui-version'
6
- export * from './lib/record.util'
6
+ export * from './lib/record'
@@ -23,8 +23,8 @@ export const FORMATS = {
23
23
  excel: {
24
24
  extensions: [
25
25
  'excel',
26
- 'xls',
27
26
  'xlsx',
27
+ 'xls',
28
28
  'ms-excel',
29
29
  'openxmlformats-officedocument',
30
30
  ],
@@ -190,6 +190,7 @@ export function isFormatInQueryParam(
190
190
  alias: string
191
191
  ): boolean {
192
192
  const queryParams = link.url.searchParams
193
+ if (!queryParams) return false
193
194
  for (const [key, value] of queryParams.entries()) {
194
195
  if (key === 'format' || key === 'f') {
195
196
  return value === alias
@@ -230,6 +231,15 @@ export function getBadgeColor(linkFormat: FileFormat): string {
230
231
  return 'var(--color-gray-700)' // Default color ?
231
232
  }
232
233
 
234
+ export function getLinkId(link: DatasetOnlineResource): string {
235
+ const href = link.url.href ?? link.url
236
+ return `${getLinkLabel(link)
237
+ .replace(/é/g, 'e')
238
+ .replace(/è/g, 'e')
239
+ .normalize('NFD')
240
+ .replace(/[\u0300-\u036f]/g, '')}-${href}`
241
+ }
242
+
233
243
  export function getLinkLabel(
234
244
  link: DatasetOnlineResource | ServiceOnlineResource
235
245
  ): string {
@@ -0,0 +1,2 @@
1
+ export * from './quality-score.util'
2
+ export * from './record.util'
@@ -0,0 +1,72 @@
1
+ import {
2
+ CatalogRecord,
3
+ RecordKind,
4
+ } from '../../../../../../libs/common/domain/src/lib/model/record'
5
+
6
+ type TValidatorMapper = {
7
+ [key: string]: (metadata: Partial<CatalogRecord>) => boolean
8
+ }
9
+
10
+ const ValidatorMapper: TValidatorMapper = {
11
+ title: (record) => !!record?.title,
12
+ abstract: (record) => !!record?.abstract,
13
+ keywords: (record) => (record?.keywords?.length ?? 0) > 0,
14
+ legalConstraints: (record) =>
15
+ !!(
16
+ record?.legalConstraints?.length &&
17
+ record.legalConstraints.some((c) => c?.text?.trim().length > 0)
18
+ ),
19
+ contacts: (record) =>
20
+ !!record?.contacts?.[0]?.email &&
21
+ record.contacts[0].email !== 'missing@missing.com',
22
+ updateFrequency: (record) =>
23
+ !!record?.updateFrequency && record.updateFrequency !== 'unknown',
24
+ topics: (record) => (record?.topics?.length ?? 0) > 0,
25
+ organisation: (record) => !!record?.contacts?.[0]?.organization?.name,
26
+ source: (record) => !!record?.extras?.sourcesIdentifiers,
27
+ } as const
28
+
29
+ export type ValidatorMapperKeys = keyof typeof ValidatorMapper & string
30
+
31
+ export function getAllKeysValidator() {
32
+ return Object.keys(ValidatorMapper)
33
+ }
34
+
35
+ function getMappersFromKind(kind: RecordKind) {
36
+ let kindKeys = <ValidatorMapperKeys[]>[]
37
+ const commonsKeys = <ValidatorMapperKeys[]>[
38
+ 'title',
39
+ 'abstract',
40
+ 'keywords',
41
+ 'legalConstraints',
42
+ 'contacts',
43
+ ]
44
+
45
+ switch (kind) {
46
+ case 'reuse':
47
+ kindKeys = ['topics', 'organisation', 'source']
48
+ break
49
+ case 'service':
50
+ kindKeys = []
51
+ break
52
+ case 'dataset':
53
+ default:
54
+ kindKeys = ['updateFrequency', 'topics', 'organisation']
55
+ }
56
+
57
+ return [...commonsKeys, ...kindKeys]
58
+ }
59
+
60
+ export function getQualityValidators(
61
+ record: Partial<CatalogRecord>,
62
+ propsToValidate: ValidatorMapperKeys[]
63
+ ) {
64
+ const filteredProps = propsToValidate.filter((prop) =>
65
+ getMappersFromKind(record.kind).includes(prop)
66
+ )
67
+
68
+ return filteredProps.map((name) => ({
69
+ name,
70
+ validator: () => ValidatorMapper[name](record),
71
+ }))
72
+ }
@@ -10,7 +10,7 @@ import {
10
10
  OnlineLinkResource,
11
11
  Organization,
12
12
  ServiceEndpoint,
13
- } from '../../../../../libs/common/domain/src/lib/model/record'
13
+ } from '../../../../../../libs/common/domain/src/lib/model/record'
14
14
 
15
15
  type TranslatedRecordObjects =
16
16
  | BaseRecord
@@ -1,8 +1,11 @@
1
- import { Feature, FeatureCollection, Geometry } from 'geojson'
1
+ import type { Feature, FeatureCollection, Geometry, Position } from 'geojson'
2
2
 
3
+ /**
4
+ * @returns The geometry if available, otherwise null.
5
+ */
3
6
  export function getGeometryFromGeoJSON(
4
7
  data: FeatureCollection | Feature | Geometry
5
- ): Geometry {
8
+ ): Geometry | null {
6
9
  if (data.type === 'FeatureCollection') {
7
10
  return data?.features?.[0]?.geometry || null
8
11
  }
@@ -24,3 +27,70 @@ export function getGeometryFromGeoJSON(
24
27
  }
25
28
  return null
26
29
  }
30
+
31
+ // FIXME: this type should be more generic across the project
32
+ export type BoundingBox = [number, number, number, number]
33
+
34
+ export function getGeometryBoundingBox(geometry: Geometry): BoundingBox {
35
+ // use the bounding box if specified in the GeoJSON object
36
+ if (geometry.bbox) {
37
+ return geometry.bbox.length > 4
38
+ ? [geometry.bbox[0], geometry.bbox[1], geometry.bbox[3], geometry.bbox[4]]
39
+ : (geometry.bbox as BoundingBox)
40
+ }
41
+
42
+ const coordinatesReducer = (prev: BoundingBox, coords: Position) =>
43
+ [
44
+ Math.min(prev[0], coords[0]),
45
+ Math.min(prev[1], coords[1]),
46
+ Math.max(prev[2], coords[0]),
47
+ Math.max(prev[3], coords[1]),
48
+ ] as BoundingBox
49
+ const coordinatesArrayReducer = (
50
+ prev: BoundingBox,
51
+ coordsArray: Position[]
52
+ ) => {
53
+ const bbox = coordsArray.reduce(coordinatesReducer, emptyExtent)
54
+ return [
55
+ Math.min(prev[0], bbox[0]),
56
+ Math.min(prev[1], bbox[1]),
57
+ Math.max(prev[2], bbox[2]),
58
+ Math.max(prev[3], bbox[3]),
59
+ ] as BoundingBox
60
+ }
61
+ const emptyExtent = [Infinity, Infinity, -Infinity, -Infinity] as BoundingBox
62
+
63
+ switch (geometry.type) {
64
+ case 'MultiPolygon':
65
+ return geometry.coordinates.reduce((prev, polygonCoords) => {
66
+ const bbox = polygonCoords.reduce(coordinatesArrayReducer, emptyExtent)
67
+ return [
68
+ Math.min(prev[0], bbox[0]),
69
+ Math.min(prev[1], bbox[1]),
70
+ Math.max(prev[2], bbox[2]),
71
+ Math.max(prev[3], bbox[3]),
72
+ ] as BoundingBox
73
+ }, emptyExtent)
74
+ case 'GeometryCollection':
75
+ return geometry.geometries.reduce((prev, geom) => {
76
+ const bbox = getGeometryBoundingBox(geom)
77
+ return [
78
+ Math.min(prev[0], bbox[0]),
79
+ Math.min(prev[1], bbox[1]),
80
+ Math.max(prev[2], bbox[2]),
81
+ Math.max(prev[3], bbox[3]),
82
+ ] as BoundingBox
83
+ }, emptyExtent)
84
+ case 'Polygon':
85
+ case 'MultiLineString':
86
+ return geometry.coordinates.reduce(coordinatesArrayReducer, emptyExtent)
87
+ case 'LineString':
88
+ case 'MultiPoint':
89
+ return geometry.coordinates.reduce<BoundingBox>(
90
+ coordinatesReducer,
91
+ emptyExtent
92
+ )
93
+ case 'Point':
94
+ return coordinatesReducer(emptyExtent, geometry.coordinates)
95
+ }
96
+ }
@@ -4,6 +4,7 @@ export * from './format-fields'
4
4
  export * from './fuzzy-filter'
5
5
  export * from './geojson'
6
6
  export * from './image-resize'
7
+ export * from './mobile-screen'
7
8
  export * from './no-duplicate-file-name'
8
9
  export * from './parse'
9
10
  export * from './remove-whitespace'
@@ -0,0 +1,14 @@
1
+ import { fromEvent, startWith, map, shareReplay } from 'rxjs'
2
+
3
+ /**
4
+ * This returns true when the screen size is under 768px, which is the mobile threshold.
5
+ */
6
+ const MOBILE_MAX_WIDTH = 768
7
+
8
+ export function getIsMobile() {
9
+ return fromEvent(window, 'resize').pipe(
10
+ startWith(window.innerWidth),
11
+ map(() => window.innerWidth < MOBILE_MAX_WIDTH),
12
+ shareReplay({ bufferSize: 1, refCount: true })
13
+ )
14
+ }