geonetwork-ui 2.6.0-dev.a6b2f3e85 → 2.6.0-dev.a8e63e487

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 (222) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/common/distribution.mapper.mjs +3 -1
  2. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.mjs +37 -4
  3. package/esm2022/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.mjs +1 -1
  4. package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.mjs +8 -4
  5. package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.mjs +5 -2
  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/write-parts.mjs +2 -2
  8. package/esm2022/libs/api/repository/src/lib/gn4/elasticsearch/constant.mjs +2 -1
  9. package/esm2022/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.mjs +3 -3
  10. package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +41 -9
  11. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
  12. package/esm2022/libs/common/domain/src/lib/repository/records-repository.interface.mjs +1 -1
  13. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +32 -2
  14. package/esm2022/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.mjs +266 -11
  15. package/esm2022/libs/feature/record/src/index.mjs +2 -3
  16. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +31 -5
  17. package/esm2022/libs/feature/record/src/lib/state/mdview.actions.mjs +3 -1
  18. package/esm2022/libs/feature/record/src/lib/state/mdview.effects.mjs +7 -1
  19. package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +13 -13
  20. package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +7 -1
  21. package/esm2022/libs/feature/record/src/lib/state/mdview.selectors.mjs +3 -1
  22. package/esm2022/libs/feature/search/src/lib/constants.mjs +2 -1
  23. package/esm2022/libs/feature/search/src/lib/results-list/results-list.container.component.mjs +6 -2
  24. package/esm2022/libs/ui/elements/src/index.mjs +3 -1
  25. package/esm2022/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.mjs +55 -0
  26. package/esm2022/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.mjs +27 -53
  27. package/esm2022/libs/ui/elements/src/lib/kind-badge/kind-badge.component.mjs +22 -5
  28. package/esm2022/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.mjs +3 -3
  29. package/esm2022/libs/ui/elements/src/lib/metadata-info/metadata-info.component.mjs +3 -3
  30. package/esm2022/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.mjs +3 -3
  31. package/esm2022/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.mjs +51 -0
  32. package/esm2022/libs/ui/elements/src/lib/related-record-card/related-record-card.component.mjs +17 -7
  33. package/esm2022/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.mjs +12 -4
  34. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +10 -4
  35. package/esm2022/libs/ui/inputs/src/index.mjs +2 -1
  36. package/esm2022/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.mjs +3 -3
  37. package/esm2022/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.mjs +68 -0
  38. package/esm2022/libs/ui/inputs/src/lib/star-toggle/star-toggle.component.mjs +3 -3
  39. package/esm2022/libs/ui/layout/src/lib/expandable-panel/expandable-panel.component.mjs +34 -13
  40. package/esm2022/libs/ui/layout/src/lib/interactive-table/interactive-table.component.mjs +3 -3
  41. package/esm2022/libs/ui/layout/src/lib/truncated-text/truncated-text.component.mjs +65 -14
  42. package/esm2022/libs/ui/search/src/index.mjs +2 -1
  43. package/esm2022/libs/ui/search/src/lib/record-preview-row/record-preview-row.component.mjs +4 -8
  44. package/esm2022/libs/ui/search/src/lib/results-hits-search-kind/results-hits-search-kind.component.mjs +3 -3
  45. package/esm2022/libs/ui/search/src/lib/results-list/results-layout.config.mjs +2 -2
  46. package/esm2022/libs/ui/search/src/lib/results-list/results-list.component.mjs +3 -3
  47. package/esm2022/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.mjs +19 -12
  48. package/esm2022/libs/ui/search/src/lib/results-table/results-table.component.mjs +27 -14
  49. package/esm2022/libs/ui/search/src/lib/ui-search.module.mjs +10 -4
  50. package/esm2022/libs/util/i18n/src/lib/i18n.constants.mjs +42 -1
  51. package/esm2022/libs/util/i18n/src/lib/language-codes.mjs +24 -2
  52. package/esm2022/libs/util/shared/src/lib/links/link-classifier.service.mjs +4 -1
  53. package/esm2022/libs/util/shared/src/lib/links/link-utils.mjs +4 -1
  54. package/esm2022/translations/de.json +34 -5
  55. package/esm2022/translations/en.json +34 -7
  56. package/esm2022/translations/es.json +33 -4
  57. package/esm2022/translations/fr.json +34 -7
  58. package/esm2022/translations/it.json +64 -35
  59. package/esm2022/translations/nl.json +33 -4
  60. package/esm2022/translations/pt.json +33 -4
  61. package/fesm2022/geonetwork-ui.mjs +1580 -665
  62. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  63. package/libs/api/metadata-converter/src/lib/common/distribution.mapper.d.ts.map +1 -1
  64. package/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.d.ts.map +1 -1
  65. package/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.d.ts +0 -1
  66. package/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.d.ts.map +1 -1
  67. package/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.d.ts +1 -0
  68. package/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.d.ts.map +1 -1
  69. package/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.d.ts.map +1 -1
  70. package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts.map +1 -1
  71. package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
  72. package/libs/api/repository/src/lib/gn4/elasticsearch/constant.d.ts.map +1 -1
  73. package/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.d.ts +1 -1
  74. package/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.d.ts.map +1 -1
  75. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts +7 -2
  76. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
  77. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +2 -1
  78. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  79. package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts +3 -0
  80. package/libs/common/domain/src/lib/repository/records-repository.interface.d.ts.map +1 -1
  81. package/libs/feature/dataviz/src/lib/service/data.service.d.ts +1 -0
  82. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  83. package/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.d.ts +48 -3
  84. package/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.d.ts.map +1 -1
  85. package/libs/feature/record/src/index.d.ts +1 -2
  86. package/libs/feature/record/src/index.d.ts.map +1 -1
  87. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  88. package/libs/feature/record/src/lib/state/mdview.actions.d.ts +10 -0
  89. package/libs/feature/record/src/lib/state/mdview.actions.d.ts.map +1 -1
  90. package/libs/feature/record/src/lib/state/mdview.effects.d.ts +6 -0
  91. package/libs/feature/record/src/lib/state/mdview.effects.d.ts.map +1 -1
  92. package/libs/feature/record/src/lib/state/mdview.facade.d.ts +28 -21
  93. package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
  94. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts +2 -0
  95. package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
  96. package/libs/feature/record/src/lib/state/mdview.selectors.d.ts +2 -0
  97. package/libs/feature/record/src/lib/state/mdview.selectors.d.ts.map +1 -1
  98. package/libs/feature/search/src/lib/constants.d.ts.map +1 -1
  99. package/libs/feature/search/src/lib/results-list/results-list.container.component.d.ts +1 -1
  100. package/libs/feature/search/src/lib/results-list/results-list.container.component.d.ts.map +1 -1
  101. package/libs/ui/elements/src/index.d.ts +2 -0
  102. package/libs/ui/elements/src/index.d.ts.map +1 -1
  103. package/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.d.ts +15 -0
  104. package/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.d.ts.map +1 -0
  105. package/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.d.ts +3 -7
  106. package/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.d.ts.map +1 -1
  107. package/libs/ui/elements/src/lib/kind-badge/kind-badge.component.d.ts +3 -1
  108. package/libs/ui/elements/src/lib/kind-badge/kind-badge.component.d.ts.map +1 -1
  109. package/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.d.ts +16 -0
  110. package/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.d.ts.map +1 -0
  111. package/libs/ui/elements/src/lib/related-record-card/related-record-card.component.d.ts +8 -1
  112. package/libs/ui/elements/src/lib/related-record-card/related-record-card.component.d.ts.map +1 -1
  113. package/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.d.ts +1 -0
  114. package/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.d.ts.map +1 -1
  115. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +2 -1
  116. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  117. package/libs/ui/inputs/src/index.d.ts +1 -0
  118. package/libs/ui/inputs/src/index.d.ts.map +1 -1
  119. package/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.d.ts +17 -0
  120. package/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.d.ts.map +1 -0
  121. package/libs/ui/layout/src/lib/expandable-panel/expandable-panel.component.d.ts +15 -8
  122. package/libs/ui/layout/src/lib/expandable-panel/expandable-panel.component.d.ts.map +1 -1
  123. package/libs/ui/layout/src/lib/truncated-text/truncated-text.component.d.ts +15 -6
  124. package/libs/ui/layout/src/lib/truncated-text/truncated-text.component.d.ts.map +1 -1
  125. package/libs/ui/search/src/index.d.ts +1 -0
  126. package/libs/ui/search/src/index.d.ts.map +1 -1
  127. package/libs/ui/search/src/lib/results-list/results-list.component.d.ts.map +1 -1
  128. package/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.d.ts +3 -3
  129. package/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.d.ts.map +1 -1
  130. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts +5 -1
  131. package/libs/ui/search/src/lib/results-table/results-table.component.d.ts.map +1 -1
  132. package/libs/ui/search/src/lib/ui-search.module.d.ts +2 -1
  133. package/libs/ui/search/src/lib/ui-search.module.d.ts.map +1 -1
  134. package/libs/util/i18n/src/lib/i18n.constants.d.ts +1 -0
  135. package/libs/util/i18n/src/lib/i18n.constants.d.ts.map +1 -1
  136. package/libs/util/i18n/src/lib/language-codes.d.ts +23 -1
  137. package/libs/util/i18n/src/lib/language-codes.d.ts.map +1 -1
  138. package/libs/util/shared/src/lib/links/link-classifier.service.d.ts.map +1 -1
  139. package/libs/util/shared/src/lib/links/link-utils.d.ts.map +1 -1
  140. package/package.json +1 -1
  141. package/src/libs/api/metadata-converter/src/lib/common/distribution.mapper.ts +1 -0
  142. package/src/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +1 -1
  143. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +55 -4
  144. package/src/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.ts +0 -1
  145. package/src/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.ts +13 -3
  146. package/src/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.ts +5 -1
  147. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +8 -4
  148. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +4 -1
  149. package/src/libs/api/repository/src/lib/gn4/elasticsearch/constant.ts +1 -0
  150. package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +2 -2
  151. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +65 -7
  152. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +8 -1
  153. package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +3 -0
  154. package/src/libs/common/fixtures/src/lib/elasticsearch/metadata-links.fixtures.ts +10 -0
  155. package/src/libs/common/fixtures/src/lib/link.fixtures.ts +14 -0
  156. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +1 -1
  157. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +37 -0
  158. package/src/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.html +117 -11
  159. package/src/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.ts +316 -6
  160. package/src/libs/feature/record/src/index.ts +1 -2
  161. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +35 -4
  162. package/src/libs/feature/record/src/lib/state/mdview.actions.ts +10 -0
  163. package/src/libs/feature/record/src/lib/state/mdview.effects.ts +22 -0
  164. package/src/libs/feature/record/src/lib/state/mdview.facade.ts +22 -15
  165. package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +12 -0
  166. package/src/libs/feature/record/src/lib/state/mdview.selectors.ts +9 -0
  167. package/src/libs/feature/search/src/lib/constants.ts +1 -0
  168. package/src/libs/feature/search/src/lib/results-list/results-list.container.component.ts +2 -0
  169. package/src/libs/ui/elements/src/index.ts +2 -0
  170. package/src/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.css +4 -0
  171. package/src/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.html +13 -0
  172. package/src/libs/ui/elements/src/lib/geo-data-badge/geo-data-badge.component.ts +54 -0
  173. package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.html +133 -138
  174. package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.ts +19 -47
  175. package/src/libs/ui/elements/src/lib/kind-badge/kind-badge.component.html +7 -5
  176. package/src/libs/ui/elements/src/lib/kind-badge/kind-badge.component.ts +21 -2
  177. package/src/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.html +6 -3
  178. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +4 -0
  179. package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.html +1 -1
  180. package/src/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.html +48 -0
  181. package/src/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.ts +52 -0
  182. package/src/libs/ui/elements/src/lib/related-record-card/related-record-card.component.html +8 -29
  183. package/src/libs/ui/elements/src/lib/related-record-card/related-record-card.component.ts +14 -1
  184. package/src/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.html +15 -1
  185. package/src/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.ts +9 -1
  186. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +3 -1
  187. package/src/libs/ui/inputs/src/index.ts +1 -0
  188. package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.html +1 -1
  189. package/src/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.css +0 -0
  190. package/src/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.html +43 -0
  191. package/src/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.ts +77 -0
  192. package/src/libs/ui/inputs/src/lib/star-toggle/star-toggle.component.html +1 -2
  193. package/src/libs/ui/layout/src/lib/expandable-panel/expandable-panel.component.html +24 -8
  194. package/src/libs/ui/layout/src/lib/expandable-panel/expandable-panel.component.ts +36 -10
  195. package/src/libs/ui/layout/src/lib/interactive-table/interactive-table.component.html +1 -0
  196. package/src/libs/ui/layout/src/lib/truncated-text/truncated-text.component.html +8 -10
  197. package/src/libs/ui/layout/src/lib/truncated-text/truncated-text.component.ts +75 -7
  198. package/src/libs/ui/search/src/index.ts +1 -0
  199. package/src/libs/ui/search/src/lib/record-preview-row/record-preview-row.component.html +9 -81
  200. package/src/libs/ui/search/src/lib/results-hits-search-kind/results-hits-search-kind.component.html +1 -0
  201. package/src/libs/ui/search/src/lib/results-list/results-layout.config.ts +2 -2
  202. package/src/libs/ui/search/src/lib/results-list/results-list.component.html +1 -0
  203. package/src/libs/ui/search/src/lib/results-list/results-list.component.ts +0 -1
  204. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.html +11 -3
  205. package/src/libs/ui/search/src/lib/results-table/action-menu/action-menu.component.ts +14 -11
  206. package/src/libs/ui/search/src/lib/results-table/results-table.component.css +4 -0
  207. package/src/libs/ui/search/src/lib/results-table/results-table.component.html +27 -17
  208. package/src/libs/ui/search/src/lib/results-table/results-table.component.ts +20 -10
  209. package/src/libs/ui/search/src/lib/ui-search.module.ts +3 -0
  210. package/src/libs/util/i18n/src/lib/i18n.constants.ts +42 -0
  211. package/src/libs/util/i18n/src/lib/language-codes.ts +23 -1
  212. package/src/libs/util/shared/src/lib/links/link-classifier.service.ts +3 -0
  213. package/src/libs/util/shared/src/lib/links/link-utils.ts +3 -0
  214. package/tailwind.base.css +1 -1
  215. package/translations/de.json +34 -5
  216. package/translations/en.json +34 -7
  217. package/translations/es.json +33 -4
  218. package/translations/fr.json +34 -7
  219. package/translations/it.json +64 -35
  220. package/translations/nl.json +33 -4
  221. package/translations/pt.json +33 -4
  222. package/translations/sk.json +33 -4
@@ -1,30 +1,9 @@
1
- <a
2
- [class]="classList"
3
- [routerLink]="['/dataset', record.uniqueIdentifier]"
4
- target="_blank"
1
+ <gn-ui-internal-link-card
2
+ [linkHref]="linkHref"
3
+ [linkTarget]="'_blank'"
4
+ [record]="record"
5
+ [favoriteTemplate]="favoriteTemplate"
6
+ [metadataQualityDisplay]="metadataQualityDisplay"
7
+ [size]="size"
5
8
  >
6
- <div class="h-52 bg-gray-100">
7
- <gn-ui-thumbnail
8
- class="h-52 w-full object-cover"
9
- [thumbnailUrl]="record.overviews?.[0]?.url.toString()"
10
- ></gn-ui-thumbnail>
11
- </div>
12
- <div class="flex flex-col justify-between h-44 px-5 pt-4 pb-6">
13
- <h4
14
- class="max-h-24 font-title text-21 text-black text-ellipsis overflow-hidden"
15
- >
16
- {{ record.title }}
17
- </h4>
18
- <div>
19
- <button
20
- [matTooltip]="'tooltip.url.open' | translate"
21
- matTooltipPosition="above"
22
- >
23
- <ng-icon
24
- class="align-middle text-secondary"
25
- name="matOpenInNew"
26
- ></ng-icon>
27
- </button>
28
- </div>
29
- </div>
30
- </a>
9
+ </gn-ui-internal-link-card>
@@ -1,11 +1,19 @@
1
- import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ EventEmitter,
5
+ Input,
6
+ Output,
7
+ } from '@angular/core'
2
8
  import { CatalogRecord } from '../../../../../../libs/common/domain/src/lib/model/record'
3
9
  import { ThumbnailComponent } from '../thumbnail/thumbnail.component'
10
+ import { InternalLinkCardComponent } from '../internal-link-card/internal-link-card.component'
4
11
  import { RouterLink } from '@angular/router'
5
12
  import { MatTooltipModule } from '@angular/material/tooltip'
6
13
  import { NgIcon, provideIcons } from '@ng-icons/core'
7
14
  import { TranslateModule } from '@ngx-translate/core'
8
15
  import { matOpenInNew } from '@ng-icons/material-icons/baseline'
16
+ import { TemplateRef } from '@angular/core'
9
17
 
10
18
  @Component({
11
19
  selector: 'gn-ui-related-record-card',
@@ -13,6 +21,7 @@ import { matOpenInNew } from '@ng-icons/material-icons/baseline'
13
21
  styleUrls: ['./related-record-card.component.css'],
14
22
  changeDetection: ChangeDetectionStrategy.OnPush,
15
23
  imports: [
24
+ InternalLinkCardComponent,
16
25
  ThumbnailComponent,
17
26
  RouterLink,
18
27
  MatTooltipModule,
@@ -25,8 +34,12 @@ import { matOpenInNew } from '@ng-icons/material-icons/baseline'
25
34
  export class RelatedRecordCardComponent {
26
35
  private readonly baseClasses: string
27
36
 
37
+ @Input() linkHref: string = null
28
38
  @Input() record: CatalogRecord
29
39
  @Input() extraClass = ''
40
+ @Input() favoriteTemplate: TemplateRef<{ $implicit: CatalogRecord }>
41
+ @Input() metadataQualityDisplay: boolean
42
+ @Input() size: string
30
43
 
31
44
  constructor() {
32
45
  this.baseClasses = [
@@ -16,17 +16,31 @@
16
16
  <div class="h-14 md:w-2/5 w-full mb-4 flex flex-row relative">
17
17
  <gn-ui-text-input
18
18
  class="w-full"
19
+ [(value)]="searchQuery"
19
20
  [extraClass]="getExtraInputClass()"
20
21
  [placeholder]="'service.metadata.search' | translate"
21
22
  (input)="onSearchChange($event)"
22
23
  (keydown.enter)="onSearchEnter($event)"
23
24
  >
24
25
  </gn-ui-text-input>
26
+ <div
27
+ class="absolute right-14 h-14 w-14 flex items-center justify-center"
28
+ >
29
+ <button
30
+ #inputBtn
31
+ *ngIf="searchQuery"
32
+ [aria-label]="'service.metadata.search.clear' | translate"
33
+ (click)="clearSearch()"
34
+ class="h-12 w-12 border-0 flex items-center justify-center"
35
+ >
36
+ <ng-icon name="matClose"></ng-icon>
37
+ </button>
38
+ </div>
25
39
  <div class="border-l absolute border-gray-200 right-0 h-14 w-14">
26
40
  <gn-ui-button
27
41
  #inputBtn
28
42
  type="outline"
29
- extraClass="h-12 w-12 border-0 absolute right-1 top-1"
43
+ extraClass="h-12 w-12 border-0 absolute right-1 top-1 bg-white"
30
44
  (buttonClick)="searchLayers()"
31
45
  >
32
46
  <ng-icon name="iconoirSearch"></ng-icon>
@@ -16,6 +16,7 @@ import {
16
16
  WmsLayerFull,
17
17
  WmtsLayer,
18
18
  } from '@camptocamp/ogc-client'
19
+ import { matClose } from '@ng-icons/material-icons/baseline'
19
20
 
20
21
  marker(`service.metadata.search`)
21
22
  marker(`service.metadata.capabilities.title`)
@@ -48,6 +49,7 @@ marker(`service.metadata.capabilities.attribution`)
48
49
  provideIcons({
49
50
  iconoirSearch,
50
51
  matInfoOutline,
52
+ matClose,
51
53
  }),
52
54
  ],
53
55
  templateUrl: './service-capabilities.component.html',
@@ -104,6 +106,12 @@ export class ServiceCapabilitiesComponent implements OnInit {
104
106
  }
105
107
  }
106
108
 
109
+ clearSearch() {
110
+ this.searchActive = false
111
+ this.searchQuery = ''
112
+ this.filteredLayers = this.availableLayers
113
+ }
114
+
107
115
  async loadLayers() {
108
116
  if (
109
117
  this.apiLinks.length > 0 &&
@@ -176,7 +184,7 @@ export class ServiceCapabilitiesComponent implements OnInit {
176
184
  }
177
185
 
178
186
  getExtraClass(layerItem) {
179
- return layerItem.title === this.selectedLayer?.title
187
+ return layerItem === this.selectedLayer
180
188
  ? `h-8 rounded-lg bg-primary-darker text-white hover:text-primary-darker hover:bg-white`
181
189
  : `h-8 rounded-lg`
182
190
  }
@@ -15,6 +15,7 @@ import { provideNgIconsConfig } from '@ng-icons/core'
15
15
  import { TranslateModule } from '@ngx-translate/core'
16
16
  import { AvatarComponent } from './avatar/avatar.component'
17
17
  import { ImageInputComponent } from './image-input/image-input.component'
18
+ import { GeoDataBadgeComponent } from './geo-data-badge/geo-data-badge.component'
18
19
  import { MarkdownParserComponent } from './markdown-parser/markdown-parser.component'
19
20
  import { KindBadgeComponent } from './kind-badge/kind-badge.component'
20
21
  import { ThumbnailComponent } from './thumbnail/thumbnail.component'
@@ -23,7 +24,6 @@ import { UserPreviewComponent } from './user-preview/user-preview.component'
23
24
  import { ApplicationBannerComponent } from './application-banner/application-banner.component'
24
25
  import { InternalLinkCardComponent } from './internal-link-card/internal-link-card.component'
25
26
  import { ServiceCapabilitiesComponent } from './service-capabilities/service-capabilities.component'
26
-
27
27
  @NgModule({
28
28
  imports: [
29
29
  CommonModule,
@@ -48,6 +48,7 @@ import { ServiceCapabilitiesComponent } from './service-capabilities/service-cap
48
48
  InternalLinkCardComponent,
49
49
  ServiceCapabilitiesComponent,
50
50
  KindBadgeComponent,
51
+ GeoDataBadgeComponent,
51
52
  ],
52
53
  providers: [
53
54
  provideNgIconsConfig({
@@ -65,6 +66,7 @@ import { ServiceCapabilitiesComponent } from './service-capabilities/service-cap
65
66
  InternalLinkCardComponent,
66
67
  ServiceCapabilitiesComponent,
67
68
  KindBadgeComponent,
69
+ GeoDataBadgeComponent,
68
70
  ],
69
71
  })
70
72
  export class UiElementsModule {}
@@ -24,3 +24,4 @@ export * from './lib/text-input/text-input.component'
24
24
  export * from './lib/ui-inputs.module'
25
25
  export * from './lib/url-input/url-input.component'
26
26
  export * from './lib/viewport-intersector/viewport-intersector.component'
27
+ export * from './lib/search-feature-catalog/search-feature-catalog.component'
@@ -79,7 +79,7 @@
79
79
  <mat-option
80
80
  *ngFor="let suggestion of suggestions$ | async"
81
81
  [value]="suggestion"
82
- class="p-2 suggestion"
82
+ class="p-2 suggestion text-start"
83
83
  >
84
84
  {{ displayWithFnInternal(suggestion) }}
85
85
  </mat-option>
@@ -0,0 +1,43 @@
1
+ <div
2
+ class="flex items-center justify-between p-3 mt-8 bg-white rounded-lg border-b solid border-gray-300"
3
+ >
4
+ <div
5
+ class="relative shrink-0"
6
+ *ngIf="featureCatalog?.featureTypes?.length > 1"
7
+ >
8
+ <input
9
+ type="text"
10
+ [placeholder]="'search.filter.into.feature.catalog' | translate"
11
+ class="w-[220px] h-8 pl-3 pr-10 py-2 border rounded-md"
12
+ [(ngModel)]="searchTerm"
13
+ (ngModelChange)="filterAction(searchTerm)"
14
+ />
15
+ <ng-icon
16
+ class="absolute right-2.5 top-1 w-6 h-6 text-black"
17
+ name="iconoirSearch"
18
+ ></ng-icon>
19
+ </div>
20
+ <div class="text-sm px-1 ml-auto hidden sm:inline">
21
+ <ng-container *ngIf="featureCatalog?.featureTypes?.length > 1">
22
+ <span
23
+ class="text-sm font-medium text-gray-900"
24
+ data-cy="total-objects-label"
25
+ translate
26
+ >record.feature.catalog.number.total.object</span
27
+ ><span
28
+ class="text-sm font-bold px-1 text-gray-900"
29
+ data-cy="total-objects"
30
+ >{{ totalObjects }}</span
31
+ >
32
+ <span class="px-1.5">|</span>
33
+ </ng-container>
34
+ <span
35
+ class="text-sm font-medium px-1 text-gray-900"
36
+ data-cy="total-attributes-label"
37
+ translate
38
+ >record.feature.catalog.number.total.attribute</span
39
+ ><span class="text-sm font-bold text-gray-900" data-cy="total-attributes">{{
40
+ totalAttributes
41
+ }}</span>
42
+ </div>
43
+ </div>
@@ -0,0 +1,77 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core'
2
+ import { CommonModule } from '@angular/common'
3
+ import { TranslateModule } from '@ngx-translate/core'
4
+ import { NgIcon, provideIcons, provideNgIconsConfig } from '@ng-icons/core'
5
+ import { DatasetFeatureCatalog } from '../../../../../../libs/common/domain/src/lib/model/record'
6
+ import { FormsModule } from '@angular/forms'
7
+ import { of } from 'rxjs'
8
+ import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators'
9
+ import { createFuzzyFilter } from '../../../../../../libs/util/shared/src'
10
+ import { iconoirSearch } from '@ng-icons/iconoir'
11
+
12
+ @Component({
13
+ selector: 'gn-ui-search-feature-catalog',
14
+ templateUrl: './search-feature-catalog.component.html',
15
+ styleUrls: ['./search-feature-catalog.component.css'],
16
+ standalone: true,
17
+ imports: [CommonModule, NgIcon, TranslateModule, FormsModule],
18
+ viewProviders: [
19
+ provideIcons({ iconoirSearch }),
20
+ provideNgIconsConfig({
21
+ size: '1.5rem',
22
+ }),
23
+ ],
24
+ })
25
+ export class SearchFeatureCatalogComponent {
26
+ private _featureCatalog: DatasetFeatureCatalog
27
+ searchTerm: any
28
+ @Input() set featureCatalog(value: DatasetFeatureCatalog) {
29
+ this._featureCatalog = value
30
+ this.filteredFeatureCatalog = value
31
+ }
32
+ get featureCatalog(): DatasetFeatureCatalog {
33
+ return this._featureCatalog
34
+ }
35
+
36
+ @Output() filteredFeatureCatalogChange =
37
+ new EventEmitter<DatasetFeatureCatalog>()
38
+ filteredFeatureCatalog: DatasetFeatureCatalog
39
+
40
+ filterAction = (searchTerm: string): void => {
41
+ of(searchTerm)
42
+ .pipe(
43
+ debounceTime(300),
44
+ distinctUntilChanged(),
45
+ tap(() => {
46
+ const filtered = (this.featureCatalog?.featureTypes || []).filter(
47
+ (featureType) => {
48
+ const fuzzyFilter = createFuzzyFilter(searchTerm)
49
+ return (
50
+ fuzzyFilter(featureType.name) ||
51
+ (featureType.definition && fuzzyFilter(featureType.definition))
52
+ )
53
+ }
54
+ )
55
+ this.filteredFeatureCatalog = {
56
+ ...this.featureCatalog,
57
+ featureTypes: filtered,
58
+ }
59
+ this.filteredFeatureCatalogChange.emit(this.filteredFeatureCatalog)
60
+ })
61
+ )
62
+ .subscribe()
63
+ }
64
+
65
+ get totalObjects(): number {
66
+ return this.filteredFeatureCatalog?.featureTypes?.length || 0
67
+ }
68
+
69
+ get totalAttributes(): number {
70
+ return (
71
+ this.filteredFeatureCatalog?.featureTypes?.reduce(
72
+ (total, featureType) => total + (featureType.attributes?.length || 0),
73
+ 0
74
+ ) || 0
75
+ )
76
+ }
77
+ }
@@ -1,8 +1,7 @@
1
- <div class="inline-block relative align-middle" style="line-height: 0.7em">
1
+ <div class="inline-block relative align-middle">
2
2
  <gn-ui-button
3
3
  [type]="'outline'"
4
4
  [disabled]="disabled"
5
- class="-m-[8px] p-[8px]"
6
5
  (buttonClick)="toggle($event)"
7
6
  [ngClass]="{
8
7
  enabled: toggled,
@@ -1,22 +1,38 @@
1
1
  <div
2
- class="group flex align-middle title border-b border-gray-100 cursor-pointer pt-2.5"
2
+ class="group flex items-center justify-between title border-b border-gray-100 cursor-pointer"
3
3
  (click)="toggle()"
4
+ data-cy="expandable-panel-header"
4
5
  >
5
- <div class="grow font-medium text-black text-sm">
6
- {{ title }}
6
+ <div class="grow py-2.5">
7
+ <ng-container *ngIf="titleTemplate; else simpleTitle">
8
+ <div data-cy="expandable-panel-custom-title">
9
+ <ng-container *ngTemplateOutlet="titleTemplate"></ng-container>
10
+ </div>
11
+ </ng-container>
12
+ <ng-template #simpleTitle>
13
+ <div
14
+ class="font-medium text-black text-sm"
15
+ data-cy="expandable-panel-title"
16
+ >
17
+ {{ title }}
18
+ </div>
19
+ </ng-template>
7
20
  </div>
8
21
  <div
9
- class="w-8 opacity-25 text-primary group-hover:opacity-100 transition-opacity"
22
+ class="w-8 opacity-25 text-primary group-hover:opacity-100 transition-opacity flex items-center shrink-0"
10
23
  >
11
- <ng-icon name="matAdd" *ngIf="collapsed"></ng-icon>
12
- <ng-icon name="matRemove" *ngIf="!collapsed"></ng-icon>
24
+ <ng-icon
25
+ [name]="collapsed ? 'matAdd' : 'matRemove'"
26
+ [style.color]="iconColor"
27
+ ></ng-icon>
13
28
  </div>
14
29
  </div>
15
30
  <div
16
- class="content overflow-hidden transition-[max-height] duration-300"
31
+ class="content overflow-hidden transition-all duration-300"
17
32
  [ngClass]="collapsed ? 'ease-out' : 'ease-in'"
18
- [style.maxHeight]="maxHeight"
19
33
  #contentDiv
34
+ *ngIf="!collapsed"
35
+ data-cy="expandable-panel-content"
20
36
  >
21
37
  <ng-content></ng-content>
22
38
  </div>
@@ -1,9 +1,14 @@
1
1
  import {
2
2
  ChangeDetectionStrategy,
3
3
  Component,
4
+ ContentChild,
4
5
  ElementRef,
5
6
  Input,
7
+ TemplateRef,
6
8
  ViewChild,
9
+ OnDestroy,
10
+ ChangeDetectorRef,
11
+ AfterViewInit,
7
12
  } from '@angular/core'
8
13
  import { NgIcon, provideIcons } from '@ng-icons/core'
9
14
  import { CommonModule } from '@angular/common'
@@ -18,20 +23,41 @@ import { matAdd, matRemove } from '@ng-icons/material-icons/baseline'
18
23
  imports: [CommonModule, NgIcon],
19
24
  viewProviders: [provideIcons({ matAdd, matRemove })],
20
25
  })
21
- export class ExpandablePanelComponent {
22
- @Input() title: string
23
- @Input() collapsed = true
24
- @ViewChild('contentDiv') contentDiv: ElementRef
25
- maxHeight = this.setMaxHeight()
26
+ export class ExpandablePanelComponent implements AfterViewInit, OnDestroy {
27
+ @Input() title?: string
28
+ @Input() iconColor? = ''
29
+ @ContentChild('titleTemplate') titleTemplate?: TemplateRef<HTMLElement>
30
+ @ViewChild('contentDiv') contentDiv?: ElementRef
31
+
32
+ private _collapsed = true
33
+ private contentObserver?: ResizeObserver
34
+
35
+ constructor(private readonly changeDetector: ChangeDetectorRef) {}
36
+
37
+ ngAfterViewInit() {
38
+ if (this.contentDiv) {
39
+ this.contentObserver = new ResizeObserver(() => {
40
+ this.changeDetector.detectChanges()
41
+ })
42
+ this.contentObserver.observe(this.contentDiv.nativeElement)
43
+ }
44
+ }
45
+
46
+ @Input() set collapsed(value: boolean) {
47
+ this._collapsed = value
48
+ }
49
+
50
+ get collapsed(): boolean {
51
+ return this._collapsed
52
+ }
26
53
 
27
54
  toggle(): void {
28
55
  this.collapsed = !this.collapsed
29
- this.maxHeight = this.setMaxHeight()
30
56
  }
31
57
 
32
- setMaxHeight() {
33
- return `${
34
- this.collapsed ? '0' : this.contentDiv.nativeElement.scrollHeight
35
- }px`
58
+ ngOnDestroy() {
59
+ if (this.contentObserver) {
60
+ this.contentObserver.disconnect()
61
+ }
36
62
  }
37
63
  }
@@ -31,6 +31,7 @@
31
31
  *ngFor="let item of items"
32
32
  (click)="handleRowClick(item)"
33
33
  data-cy="table-row"
34
+ [attr.data-cy-title]="item.title"
34
35
  [title]="getItemTitle(item) | translate"
35
36
  >
36
37
  <div
@@ -1,6 +1,7 @@
1
1
  <div
2
2
  class="flex items-center justify-between w-full gap-2"
3
3
  cdkOverlayOrigin
4
+ [class]="extraClass"
4
5
  #trigger="cdkOverlayOrigin"
5
6
  >
6
7
  <span #textElement class="truncate">
@@ -19,18 +20,15 @@
19
20
  cdkConnectedOverlay
20
21
  [cdkConnectedOverlayOrigin]="trigger"
21
22
  [cdkConnectedOverlayOpen]="isOpen"
22
- [cdkConnectedOverlayPositions]="[
23
- {
24
- originX: 'end',
25
- originY: 'top',
26
- overlayX: 'end',
27
- overlayY: 'top',
28
- },
29
- ]"
30
- (detach)="isOpen = false"
23
+ [cdkConnectedOverlayPositions]="[overlayPosition]"
24
+ cdkConnectedOverlayPush
25
+ [cdkConnectedOverlayWidth]="'auto'"
26
+ [cdkConnectedOverlayFlexibleDimensions]="true"
27
+ [cdkConnectedOverlayGrowAfterOpen]="true"
28
+ (detach)="close()"
31
29
  >
32
30
  <div class="bg-white shadow-lg border border-gray-300 flex">
33
- <div class="w-64">
31
+ <div class="sm:w-64 xs:w-32">
34
32
  <p class="m-2">{{ text }}</p>
35
33
  </div>
36
34
  <gn-ui-button
@@ -4,16 +4,22 @@ import {
4
4
  Component,
5
5
  ElementRef,
6
6
  Input,
7
+ OnDestroy,
7
8
  ViewChild,
9
+ NgZone,
8
10
  } from '@angular/core'
9
11
  import { CommonModule } from '@angular/common'
10
- import { provideIcons } from '@ng-icons/core'
12
+ import { provideIcons, NgIconComponent } from '@ng-icons/core'
11
13
  import { iconoirExpand, iconoirReduce } from '@ng-icons/iconoir'
12
14
  import { TranslateModule } from '@ngx-translate/core'
13
15
  import { MatButtonModule } from '@angular/material/button'
14
- import { OverlayModule } from '@angular/cdk/overlay'
16
+ import {
17
+ OverlayModule,
18
+ ViewportRuler,
19
+ ConnectedPosition,
20
+ } from '@angular/cdk/overlay'
15
21
  import { ButtonComponent } from '../../../../../../libs/ui/inputs/src'
16
- import { NgIconComponent } from '@ng-icons/core'
22
+ import { Subscription } from 'rxjs'
17
23
 
18
24
  @Component({
19
25
  selector: 'gn-ui-truncated-text',
@@ -30,24 +36,85 @@ import { NgIconComponent } from '@ng-icons/core'
30
36
  templateUrl: './truncated-text.component.html',
31
37
  styles: [],
32
38
  })
33
- export class TruncatedTextComponent implements AfterViewInit {
39
+ export class TruncatedTextComponent implements AfterViewInit, OnDestroy {
34
40
  @Input() text = ''
41
+ @Input() extraClass = ''
42
+
35
43
  @ViewChild('textElement') textElement: ElementRef<HTMLElement>
36
44
  isTextTruncated = false
37
45
  isOpen = false
46
+ overlayPosition: ConnectedPosition = {
47
+ originX: 'end',
48
+ originY: 'top',
49
+ overlayX: 'end',
50
+ overlayY: 'top',
51
+ }
52
+ private readonly resizeObserver: ResizeObserver
53
+ private readonly mutationObserver: MutationObserver
54
+ private readonly viewportSubscription: Subscription
55
+
56
+ constructor(
57
+ private readonly cd: ChangeDetectorRef,
58
+ private readonly ngZone: NgZone,
59
+ private readonly viewportRuler: ViewportRuler
60
+ ) {
61
+ this.resizeObserver = new ResizeObserver(() => {
62
+ this.ngZone.run(() => this.checkTextTruncation())
63
+ })
38
64
 
39
- constructor(private cd: ChangeDetectorRef) {}
65
+ this.mutationObserver = new MutationObserver(() => {
66
+ this.ngZone.run(() => {
67
+ this.checkTextTruncation()
68
+ this.close()
69
+ })
70
+ })
71
+
72
+ this.viewportSubscription = this.viewportRuler.change().subscribe(() => {
73
+ if (this.isOpen) {
74
+ this.updateOverlayPosition()
75
+ }
76
+ })
77
+ }
40
78
 
41
79
  ngAfterViewInit() {
80
+ const element = this.textElement.nativeElement
81
+ this.resizeObserver?.observe(element)
82
+ this.mutationObserver?.observe(element.parentElement, {
83
+ attributes: true,
84
+ childList: true,
85
+ subtree: true,
86
+ })
42
87
  this.checkTextTruncation()
43
88
  }
44
89
 
45
- ngOnChange() {
46
- this.checkTextTruncation()
90
+ ngOnDestroy() {
91
+ this.resizeObserver?.disconnect()
92
+ this.mutationObserver?.disconnect()
93
+ this.viewportSubscription?.unsubscribe()
94
+ this.close()
47
95
  }
48
96
 
49
97
  toggleOverlay() {
50
98
  this.isOpen = !this.isOpen
99
+ if (this.isOpen) {
100
+ this.updateOverlayPosition()
101
+ }
102
+ }
103
+
104
+ private updateOverlayPosition() {
105
+ const element = this.textElement.nativeElement
106
+ const rect = element.getBoundingClientRect()
107
+ const viewportWidth = this.viewportRuler.getViewportSize().width
108
+ const isMobile = viewportWidth < 640
109
+ const overlayWidth = isMobile ? 190 : 320
110
+ const isNearLeftEdge = rect.left < overlayWidth
111
+
112
+ this.overlayPosition = {
113
+ originX: isNearLeftEdge ? 'start' : 'end',
114
+ originY: 'top',
115
+ overlayX: isNearLeftEdge ? 'start' : 'end',
116
+ overlayY: 'top',
117
+ }
51
118
  }
52
119
 
53
120
  close() {
@@ -56,6 +123,7 @@ export class TruncatedTextComponent implements AfterViewInit {
56
123
 
57
124
  private checkTextTruncation() {
58
125
  const element = this.textElement.nativeElement
126
+
59
127
  this.isTextTruncated = element.scrollWidth > element.clientWidth
60
128
  this.cd.detectChanges()
61
129
  }
@@ -19,3 +19,4 @@ export * from './lib/results-list-item/results-list-item.component'
19
19
  export * from './lib/results-hits-search-kind/results-hits-search-kind.component'
20
20
  export * from './lib/results-hits-number/results-hits-number.component'
21
21
  export * from './lib/results-table/results-table.component'
22
+ export * from './lib/results-table/action-menu/action-menu.component'