geonetwork-ui 2.6.0-dev.186d57931 → 2.6.0-dev.34911f182

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 (225) hide show
  1. package/esm2022/libs/api/metadata-converter/src/index.mjs +2 -1
  2. package/esm2022/libs/api/metadata-converter/src/lib/common/resource-types.mjs +17 -15
  3. package/esm2022/libs/api/repository/src/lib/gn4/gn4-repository.mjs +2 -1
  4. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
  5. package/esm2022/libs/feature/dataviz/src/lib/chart-view/chart-view.component.mjs +45 -9
  6. package/esm2022/libs/feature/dataviz/src/lib/geo-table-view/geo-table-view.component.mjs +2 -2
  7. package/esm2022/libs/feature/dataviz/src/lib/table-view/table-view.component.mjs +25 -6
  8. package/esm2022/libs/feature/editor/src/index.mjs +2 -1
  9. package/esm2022/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.mjs +18 -0
  10. package/esm2022/libs/feature/record/src/lib/data-view/data-view.component.mjs +3 -3
  11. package/esm2022/libs/feature/record/src/lib/data-view-share/data-view-share.component.mjs +3 -3
  12. package/esm2022/libs/feature/record/src/lib/external-viewer-button/external-viewer-button.component.mjs +6 -3
  13. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +3 -3
  14. package/esm2022/libs/feature/search/src/index.mjs +2 -2
  15. package/esm2022/libs/feature/search/src/lib/feature-search.module.mjs +12 -5
  16. package/esm2022/libs/feature/search/src/lib/results-hits/results-hits.container.component.mjs +41 -0
  17. package/esm2022/libs/feature/search/src/lib/utils/service/fields.mjs +70 -1
  18. package/esm2022/libs/feature/search/src/lib/utils/service/fields.service.mjs +4 -3
  19. package/esm2022/libs/ui/dataviz/src/lib/chart/chart.component.mjs +5 -3
  20. package/esm2022/libs/ui/dataviz/src/lib/data-table/data-table.component.mjs +11 -6
  21. package/esm2022/libs/ui/elements/src/index.mjs +2 -1
  22. package/esm2022/libs/ui/elements/src/lib/api-card/api-card.component.mjs +3 -3
  23. package/esm2022/libs/ui/elements/src/lib/download-item/download-item.component.mjs +3 -3
  24. package/esm2022/libs/ui/elements/src/lib/downloads-list/downloads-list.component.mjs +18 -7
  25. package/esm2022/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.mjs +3 -3
  26. package/esm2022/libs/ui/elements/src/lib/kind-badge/kind-badge.component.mjs +51 -0
  27. package/esm2022/libs/ui/elements/src/lib/link-card/link-card.component.mjs +3 -3
  28. package/esm2022/libs/ui/elements/src/lib/metadata-catalog/metadata-catalog.component.mjs +3 -3
  29. package/esm2022/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.mjs +3 -3
  30. package/esm2022/libs/ui/elements/src/lib/metadata-info/metadata-info.component.mjs +3 -3
  31. package/esm2022/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.mjs +3 -3
  32. package/esm2022/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.mjs +3 -3
  33. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +10 -4
  34. package/esm2022/libs/ui/inputs/src/index.mjs +2 -1
  35. package/esm2022/libs/ui/inputs/src/lib/button/button.component.mjs +2 -2
  36. package/esm2022/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.mjs +3 -3
  37. package/esm2022/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.mjs +3 -3
  38. package/esm2022/libs/ui/inputs/src/lib/inline-filter/inline-filter.component.mjs +42 -0
  39. package/esm2022/libs/ui/inputs/src/lib/inline-filter/inline-filter.model.mjs +2 -0
  40. package/esm2022/libs/ui/inputs/src/lib/star-toggle/star-toggle.component.mjs +3 -3
  41. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +8 -9
  42. package/esm2022/libs/ui/layout/src/index.mjs +2 -1
  43. package/esm2022/libs/ui/layout/src/lib/block-list/block-list.component.mjs +48 -11
  44. package/esm2022/libs/ui/layout/src/lib/carousel/carousel.component.mjs +3 -3
  45. package/esm2022/libs/ui/layout/src/lib/max-lines/max-lines.component.mjs +3 -3
  46. package/esm2022/libs/ui/layout/src/lib/previous-next-buttons/previous-next-buttons.component.mjs +6 -6
  47. package/esm2022/libs/ui/layout/src/lib/truncated-text/truncated-text.component.mjs +56 -0
  48. package/esm2022/libs/ui/layout/src/lib/ui-layout.module.mjs +4 -12
  49. package/esm2022/libs/ui/map/src/lib/components/feature-detail/feature-detail.component.mjs +29 -4
  50. package/esm2022/libs/ui/map/src/lib/components/spatial-extent/spatial-extent.component.mjs +2 -1
  51. package/esm2022/libs/ui/search/src/index.mjs +2 -1
  52. package/esm2022/libs/ui/search/src/lib/results-hits-number/results-hits-number.component.mjs +3 -3
  53. package/esm2022/libs/ui/search/src/lib/results-hits-search-kind/results-hits-search-kind.component.mjs +53 -0
  54. package/esm2022/libs/ui/search/src/lib/ui-search.module.mjs +11 -3
  55. package/esm2022/libs/ui/widgets/src/lib/progress-bar/progress-bar.component.mjs +3 -3
  56. package/esm2022/translations/de.json +8 -1
  57. package/esm2022/translations/en.json +10 -1
  58. package/esm2022/translations/es.json +8 -1
  59. package/esm2022/translations/fr.json +11 -2
  60. package/esm2022/translations/it.json +8 -1
  61. package/esm2022/translations/nl.json +8 -1
  62. package/esm2022/translations/pt.json +8 -1
  63. package/fesm2022/geonetwork-ui.mjs +638 -168
  64. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  65. package/libs/api/metadata-converter/src/index.d.ts +1 -0
  66. package/libs/api/metadata-converter/src/index.d.ts.map +1 -1
  67. package/libs/api/metadata-converter/src/lib/common/resource-types.d.ts +21 -0
  68. package/libs/api/metadata-converter/src/lib/common/resource-types.d.ts.map +1 -1
  69. package/libs/api/repository/src/lib/gn4/gn4-repository.d.ts.map +1 -1
  70. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +2 -0
  71. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  72. package/libs/feature/dataviz/src/lib/chart-view/chart-view.component.d.ts +12 -8
  73. package/libs/feature/dataviz/src/lib/chart-view/chart-view.component.d.ts.map +1 -1
  74. package/libs/feature/dataviz/src/lib/table-view/table-view.component.d.ts +5 -2
  75. package/libs/feature/dataviz/src/lib/table-view/table-view.component.d.ts.map +1 -1
  76. package/libs/feature/editor/src/index.d.ts +1 -0
  77. package/libs/feature/editor/src/index.d.ts.map +1 -1
  78. package/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.d.ts +7 -0
  79. package/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.d.ts.map +1 -0
  80. package/libs/feature/record/src/lib/external-viewer-button/external-viewer-button.component.d.ts +2 -1
  81. package/libs/feature/record/src/lib/external-viewer-button/external-viewer-button.component.d.ts.map +1 -1
  82. package/libs/feature/search/src/index.d.ts +1 -1
  83. package/libs/feature/search/src/index.d.ts.map +1 -1
  84. package/libs/feature/search/src/lib/feature-search.module.d.ts +4 -2
  85. package/libs/feature/search/src/lib/feature-search.module.d.ts.map +1 -1
  86. package/libs/feature/search/src/lib/results-hits/results-hits.container.component.d.ts +21 -0
  87. package/libs/feature/search/src/lib/results-hits/results-hits.container.component.d.ts.map +1 -0
  88. package/libs/feature/search/src/lib/utils/service/fields.d.ts +21 -0
  89. package/libs/feature/search/src/lib/utils/service/fields.d.ts.map +1 -1
  90. package/libs/feature/search/src/lib/utils/service/fields.service.d.ts.map +1 -1
  91. package/libs/ui/dataviz/src/lib/chart/chart.component.d.ts +2 -1
  92. package/libs/ui/dataviz/src/lib/chart/chart.component.d.ts.map +1 -1
  93. package/libs/ui/dataviz/src/lib/data-table/data-table.component.d.ts +6 -1
  94. package/libs/ui/dataviz/src/lib/data-table/data-table.component.d.ts.map +1 -1
  95. package/libs/ui/elements/src/index.d.ts +1 -0
  96. package/libs/ui/elements/src/index.d.ts.map +1 -1
  97. package/libs/ui/elements/src/lib/download-item/download-item.component.d.ts +1 -1
  98. package/libs/ui/elements/src/lib/download-item/download-item.component.d.ts.map +1 -1
  99. package/libs/ui/elements/src/lib/downloads-list/downloads-list.component.d.ts +7 -1
  100. package/libs/ui/elements/src/lib/downloads-list/downloads-list.component.d.ts.map +1 -1
  101. package/libs/ui/elements/src/lib/kind-badge/kind-badge.component.d.ts +11 -0
  102. package/libs/ui/elements/src/lib/kind-badge/kind-badge.component.d.ts.map +1 -0
  103. package/libs/ui/elements/src/lib/link-card/link-card.component.d.ts +1 -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/ui-elements.module.d.ts +2 -1
  106. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  107. package/libs/ui/inputs/src/index.d.ts +1 -0
  108. package/libs/ui/inputs/src/index.d.ts.map +1 -1
  109. package/libs/ui/inputs/src/lib/button/button.component.d.ts +1 -1
  110. package/libs/ui/inputs/src/lib/button/button.component.d.ts.map +1 -1
  111. package/libs/ui/inputs/src/lib/inline-filter/inline-filter.component.d.ts +14 -0
  112. package/libs/ui/inputs/src/lib/inline-filter/inline-filter.component.d.ts.map +1 -0
  113. package/libs/ui/inputs/src/lib/inline-filter/inline-filter.model.d.ts +6 -0
  114. package/libs/ui/inputs/src/lib/inline-filter/inline-filter.model.d.ts.map +1 -0
  115. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +25 -24
  116. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts.map +1 -1
  117. package/libs/ui/layout/src/index.d.ts +1 -0
  118. package/libs/ui/layout/src/index.d.ts.map +1 -1
  119. package/libs/ui/layout/src/lib/block-list/block-list.component.d.ts +9 -2
  120. package/libs/ui/layout/src/lib/block-list/block-list.component.d.ts.map +1 -1
  121. package/libs/ui/layout/src/lib/truncated-text/truncated-text.component.d.ts +18 -0
  122. package/libs/ui/layout/src/lib/truncated-text/truncated-text.component.d.ts.map +1 -0
  123. package/libs/ui/layout/src/lib/ui-layout.module.d.ts.map +1 -1
  124. package/libs/ui/map/src/lib/components/feature-detail/feature-detail.component.d.ts +6 -2
  125. package/libs/ui/map/src/lib/components/feature-detail/feature-detail.component.d.ts.map +1 -1
  126. package/libs/ui/map/src/lib/components/spatial-extent/spatial-extent.component.d.ts.map +1 -1
  127. package/libs/ui/search/src/index.d.ts +1 -0
  128. package/libs/ui/search/src/index.d.ts.map +1 -1
  129. package/libs/ui/search/src/lib/results-hits-search-kind/results-hits-search-kind.component.d.ts +17 -0
  130. package/libs/ui/search/src/lib/results-hits-search-kind/results-hits-search-kind.component.d.ts.map +1 -0
  131. package/libs/ui/search/src/lib/ui-search.module.d.ts +21 -19
  132. package/libs/ui/search/src/lib/ui-search.module.d.ts.map +1 -1
  133. package/package.json +1 -1
  134. package/src/libs/api/metadata-converter/src/index.ts +1 -0
  135. package/src/libs/api/metadata-converter/src/lib/common/resource-types.ts +29 -15
  136. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +1 -0
  137. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +2 -2
  138. package/src/libs/feature/dataviz/src/lib/chart-view/chart-view.component.html +12 -9
  139. package/src/libs/feature/dataviz/src/lib/chart-view/chart-view.component.ts +54 -10
  140. package/src/libs/feature/dataviz/src/lib/table-view/table-view.component.html +1 -0
  141. package/src/libs/feature/dataviz/src/lib/table-view/table-view.component.ts +27 -1
  142. package/src/libs/feature/editor/src/index.ts +1 -0
  143. package/src/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.css +0 -0
  144. package/src/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.html +14 -0
  145. package/src/libs/feature/editor/src/lib/components/multilingual-panel/multilingual-panel.component.ts +15 -0
  146. package/src/libs/feature/record/src/lib/data-view/data-view.component.html +16 -10
  147. package/src/libs/feature/record/src/lib/data-view-share/data-view-share.component.html +1 -1
  148. package/src/libs/feature/record/src/lib/external-viewer-button/external-viewer-button.component.html +2 -2
  149. package/src/libs/feature/record/src/lib/external-viewer-button/external-viewer-button.component.ts +1 -0
  150. package/src/libs/feature/record/src/lib/map-view/map-view.component.html +25 -16
  151. package/src/libs/feature/search/src/index.ts +1 -1
  152. package/src/libs/feature/search/src/lib/feature-search.module.ts +9 -2
  153. package/src/libs/feature/search/src/lib/results-hits/results-hits.container.component.css +0 -0
  154. package/src/libs/feature/search/src/lib/results-hits/results-hits.container.component.html +16 -0
  155. package/src/libs/feature/search/src/lib/results-hits/results-hits.container.component.ts +59 -0
  156. package/src/libs/feature/search/src/lib/utils/service/fields.service.ts +4 -5
  157. package/src/libs/feature/search/src/lib/utils/service/fields.ts +99 -0
  158. package/src/libs/ui/dataviz/src/lib/chart/chart.component.ts +2 -1
  159. package/src/libs/ui/dataviz/src/lib/data-table/data-table.component.html +6 -3
  160. package/src/libs/ui/dataviz/src/lib/data-table/data-table.component.ts +5 -4
  161. package/src/libs/ui/elements/src/index.ts +1 -0
  162. package/src/libs/ui/elements/src/lib/api-card/api-card.component.html +4 -4
  163. package/src/libs/ui/elements/src/lib/download-item/download-item.component.html +8 -5
  164. package/src/libs/ui/elements/src/lib/download-item/download-item.component.ts +2 -2
  165. package/src/libs/ui/elements/src/lib/downloads-list/downloads-list.component.html +38 -7
  166. package/src/libs/ui/elements/src/lib/downloads-list/downloads-list.component.ts +29 -2
  167. package/src/libs/ui/elements/src/lib/image-overlay-preview/image-overlay-preview.component.html +1 -1
  168. package/src/libs/ui/elements/src/lib/kind-badge/kind-badge.component.css +6 -0
  169. package/src/libs/ui/elements/src/lib/kind-badge/kind-badge.component.html +9 -0
  170. package/src/libs/ui/elements/src/lib/kind-badge/kind-badge.component.ts +51 -0
  171. package/src/libs/ui/elements/src/lib/link-card/link-card.component.html +5 -2
  172. package/src/libs/ui/elements/src/lib/link-card/link-card.component.ts +3 -7
  173. package/src/libs/ui/elements/src/lib/metadata-catalog/metadata-catalog.component.html +3 -5
  174. package/src/libs/ui/elements/src/lib/metadata-contact/metadata-contact.component.html +9 -9
  175. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.css +1 -1
  176. package/src/libs/ui/elements/src/lib/metadata-info/metadata-info.component.html +7 -3
  177. package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.html +2 -3
  178. package/src/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.html +1 -1
  179. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +3 -0
  180. package/src/libs/ui/inputs/src/index.ts +1 -0
  181. package/src/libs/ui/inputs/src/lib/button/button.component.ts +2 -2
  182. package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.html +1 -1
  183. package/src/libs/ui/inputs/src/lib/dropdown-selector/dropdown-selector.component.html +1 -1
  184. package/src/libs/ui/inputs/src/lib/inline-filter/inline-filter.component.html +23 -0
  185. package/src/libs/ui/inputs/src/lib/inline-filter/inline-filter.component.ts +44 -0
  186. package/src/libs/ui/inputs/src/lib/inline-filter/inline-filter.model.ts +5 -0
  187. package/src/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.ts +0 -0
  188. package/src/libs/ui/inputs/src/lib/star-toggle/star-toggle.component.html +2 -2
  189. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +3 -3
  190. package/src/libs/ui/layout/src/index.ts +1 -0
  191. package/src/libs/ui/layout/src/lib/block-list/block-list.component.css +22 -0
  192. package/src/libs/ui/layout/src/lib/block-list/block-list.component.html +2 -2
  193. package/src/libs/ui/layout/src/lib/block-list/block-list.component.ts +43 -5
  194. package/src/libs/ui/layout/src/lib/carousel/carousel.component.css +0 -1
  195. package/src/libs/ui/layout/src/lib/carousel/carousel.component.html +1 -1
  196. package/src/libs/ui/layout/src/lib/max-lines/max-lines.component.html +1 -1
  197. package/src/libs/ui/layout/src/lib/previous-next-buttons/previous-next-buttons.component.html +17 -5
  198. package/src/libs/ui/layout/src/lib/previous-next-buttons/previous-next-buttons.component.ts +3 -3
  199. package/src/libs/ui/layout/src/lib/truncated-text/truncated-text.component.html +46 -0
  200. package/src/libs/ui/layout/src/lib/truncated-text/truncated-text.component.ts +62 -0
  201. package/src/libs/ui/layout/src/lib/ui-layout.module.ts +1 -5
  202. package/src/libs/ui/map/src/lib/components/feature-detail/feature-detail.component.html +3 -3
  203. package/src/libs/ui/map/src/lib/components/feature-detail/feature-detail.component.ts +27 -3
  204. package/src/libs/ui/map/src/lib/components/spatial-extent/spatial-extent.component.ts +1 -0
  205. package/src/libs/ui/search/src/index.ts +1 -0
  206. package/src/libs/ui/search/src/lib/results-hits-number/results-hits-number.component.html +1 -1
  207. package/src/libs/ui/search/src/lib/results-hits-search-kind/results-hits-search-kind.component.html +24 -0
  208. package/src/libs/ui/search/src/lib/results-hits-search-kind/results-hits-search-kind.component.ts +53 -0
  209. package/src/libs/ui/search/src/lib/ui-search.module.ts +5 -0
  210. package/src/libs/ui/widgets/src/lib/progress-bar/progress-bar.component.html +1 -1
  211. package/tailwind.base.config.js +3 -0
  212. package/tailwind.base.css +1 -13
  213. package/translations/de.json +8 -1
  214. package/translations/en.json +10 -1
  215. package/translations/es.json +8 -1
  216. package/translations/fr.json +11 -2
  217. package/translations/it.json +8 -1
  218. package/translations/nl.json +8 -1
  219. package/translations/pt.json +8 -1
  220. package/translations/sk.json +8 -1
  221. package/esm2022/libs/feature/search/src/lib/results-hits-number/results-hits.container.component.mjs +0 -18
  222. package/libs/feature/search/src/lib/results-hits-number/results-hits.container.component.d.ts +0 -9
  223. package/libs/feature/search/src/lib/results-hits-number/results-hits.container.component.d.ts.map +0 -1
  224. package/src/libs/feature/search/src/lib/results-hits-number/results-hits.container.component.html +0 -4
  225. package/src/libs/feature/search/src/lib/results-hits-number/results-hits.container.component.ts +0 -10
@@ -4,6 +4,7 @@
4
4
  *ngIf="tableData$ | async as dataset"
5
5
  class="overflow-auto grow"
6
6
  [dataset]="dataset"
7
+ [featureAttributes]="featureAttributes"
7
8
  (selected)="onTableSelect($event)"
8
9
  ></gn-ui-data-table>
9
10
  <gn-ui-loading-mask
@@ -6,11 +6,15 @@ import {
6
6
  shareReplay,
7
7
  startWith,
8
8
  switchMap,
9
+ tap,
9
10
  } from 'rxjs/operators'
10
11
  import { BaseReader, FetchError } from '../../../../../../libs/util/data-fetcher/src'
11
12
  import { DataService } from '../service/data.service'
12
13
  import { DataTableComponent } from '../../../../../../libs/ui/dataviz/src'
13
- import { DatasetOnlineResource } from '../../../../../../libs/common/domain/src/lib/model/record'
14
+ import {
15
+ DatasetFeatureCatalog,
16
+ DatasetOnlineResource,
17
+ } from '../../../../../../libs/common/domain/src/lib/model/record'
14
18
  import { TranslateModule, TranslateService } from '@ngx-translate/core'
15
19
  import {
16
20
  LoadingMaskComponent,
@@ -33,6 +37,8 @@ import { CommonModule } from '@angular/common'
33
37
  standalone: true,
34
38
  })
35
39
  export class TableViewComponent {
40
+ featureAttributes = []
41
+ @Input() featureCatalog: DatasetFeatureCatalog
36
42
  @Input() cacheActive = true
37
43
  @Input() set link(value: DatasetOnlineResource) {
38
44
  this.currentLink$.next(value)
@@ -52,6 +58,7 @@ export class TableViewComponent {
52
58
  }
53
59
  this.loading = true
54
60
  return this.getDatasetReader(link).pipe(
61
+ tap((dataset: BaseReader) => this.setProperties(dataset)),
55
62
  catchError((error) => {
56
63
  this.handleError(error)
57
64
  return of(undefined)
@@ -96,4 +103,23 @@ export class TableViewComponent {
96
103
  }
97
104
  this.loading = false
98
105
  }
106
+
107
+ setProperties(dataset: BaseReader) {
108
+ dataset.properties.then((properties) => {
109
+ const updatedProperties = properties.map((p) => {
110
+ let label = p.name
111
+ if (this.featureCatalog) {
112
+ const attributes = this.featureCatalog.featureTypes[0].attributes
113
+ const matchingAttribute = attributes.find(
114
+ (attr) => attr.name === p.name
115
+ )
116
+ if (matchingAttribute && matchingAttribute.code) {
117
+ label = matchingAttribute.code
118
+ }
119
+ }
120
+ return { value: p.name, label }
121
+ })
122
+ this.featureAttributes = updatedProperties
123
+ })
124
+ }
99
125
  }
@@ -11,3 +11,4 @@ export * from './lib/components/wizard/wizard.component'
11
11
  export * from './lib/components/wizard-field/wizard-field.component'
12
12
  export * from './lib/components/wizard-summarize/wizard-summarize.component'
13
13
  export * from './lib/components/record-form/form-field'
14
+ export * from './lib/components/multilingual-panel/multilingual-panel.component'
@@ -0,0 +1,14 @@
1
+ <div
2
+ class="flex flex-col h-full w-[302px] bg-neutral-100 border-l border-gray-300 py-9 px-3 gap-8"
3
+ >
4
+ <span class="text-3xl font-title text-black/80 px-2" translate
5
+ >editor.record.form.multilingual.title</span
6
+ >
7
+ <gn-ui-check-toggle
8
+ class="p-2"
9
+ [label]="'editor.record.form.multilingual.enable' | translate"
10
+ [color]="'primary'"
11
+ [value]="translationsEnabled"
12
+ (toggled)="translationsEnabled = $event"
13
+ ></gn-ui-check-toggle>
14
+ </div>
@@ -0,0 +1,15 @@
1
+ import { Component } from '@angular/core'
2
+ import { CommonModule } from '@angular/common'
3
+ import { CheckToggleComponent } from '../../../../../../../libs/ui/inputs/src'
4
+ import { TranslateModule } from '@ngx-translate/core'
5
+
6
+ @Component({
7
+ selector: 'gn-ui-multilingual-panel',
8
+ standalone: true,
9
+ imports: [CommonModule, CheckToggleComponent, TranslateModule],
10
+ templateUrl: './multilingual-panel.component.html',
11
+ styleUrl: './multilingual-panel.component.css',
12
+ })
13
+ export class MultilingualPanelComponent {
14
+ translationsEnabled = false
15
+ }
@@ -1,13 +1,17 @@
1
- <div class="w-full h-full flex flex-col p-1">
2
- <gn-ui-dropdown-selector
3
- *ngIf="dropdownChoices$ | async as choices"
4
- [ngClass]="{ hidden: !displaySource }"
5
- [title]="'table.select.data' | translate"
6
- class="truncate p-1 -mx-1 self-end mb-1"
7
- extraBtnClass="!text-primary font-sans font-medium"
8
- [choices]="choices"
9
- (selectValue)="selectLink($event)"
10
- ></gn-ui-dropdown-selector>
1
+ <div class="w-full h-full flex flex-col gap-[13px]">
2
+ <div
3
+ class="w-full py-4 px-5 bg-white border border-color-border rounded-lg mt-6"
4
+ >
5
+ <gn-ui-dropdown-selector
6
+ *ngIf="dropdownChoices$ | async as choices"
7
+ [ngClass]="{ hidden: !displaySource }"
8
+ [title]="'table.select.data' | translate"
9
+ class="h-[44px] w-full"
10
+ extraBtnClass="font-sans font-bold"
11
+ [choices]="choices"
12
+ (selectValue)="selectLink($event)"
13
+ ></gn-ui-dropdown-selector>
14
+ </div>
11
15
  <ng-container *ngIf="hidePreview; else dataView">
12
16
  <gn-ui-popup-alert
13
17
  type="warning"
@@ -23,12 +27,14 @@
23
27
  *ngIf="mode === 'table'"
24
28
  [cacheActive]="cacheActive$ | async"
25
29
  [link]="selectedLink$ | async"
30
+ [featureCatalog]="mdViewFacade.featureCatalog$ | async"
26
31
  ></gn-ui-table-view>
27
32
  <gn-ui-chart-view
28
33
  *ngIf="mode === 'chart'"
29
34
  (chartConfig$)="setChartConfig($event)"
30
35
  [cacheActive]="cacheActive$ | async"
31
36
  [link]="selectedLink$ | async"
37
+ [featureCatalog]="mdViewFacade.featureCatalog$ | async"
32
38
  ></gn-ui-chart-view>
33
39
  </div>
34
40
  </ng-template>
@@ -1,4 +1,4 @@
1
- <div class="px-5 my-1">
1
+ <div>
2
2
  <mat-tab-group
3
3
  [selectedIndex]="0"
4
4
  animationDuration="0ms"
@@ -1,9 +1,9 @@
1
1
  <gn-ui-button
2
2
  *ngIf="externalViewer"
3
3
  (buttonClick)="openInExternalViewer()"
4
- type="secondary"
4
+ type="primary"
5
5
  [title]="'record.externalViewer.open' | translate"
6
- extraClass="ms-2 !rounded-lg"
6
+ [extraClass]="extraClass + 'bg-primary ms-2 !rounded-lg'"
7
7
  >
8
8
  <ng-icon name="matOpenInNew"></ng-icon>
9
9
  </gn-ui-button>
@@ -36,6 +36,7 @@ export const EXTERNAL_VIEWER_OPEN_NEW_TAB = new InjectionToken<boolean>(
36
36
  })
37
37
  export class ExternalViewerButtonComponent {
38
38
  @Input() link: DatasetOnlineResource
39
+ @Input() extraClass = ''
39
40
 
40
41
  get externalViewer() {
41
42
  return !!this.urlTemplate && !!this.supportedLinkLayerType
@@ -1,18 +1,24 @@
1
- <div class="w-full h-full flex flex-col p-1">
2
- <div class="w-full flex justify-end">
3
- <gn-ui-dropdown-selector
4
- [ngClass]="{ hidden: !displaySource }"
5
- class="truncate p-1 -mx-1 mb-1"
6
- extraBtnClass="!text-primary font-sans font-medium"
7
- [title]="'map.select.layer' | translate"
8
- [choices]="dropdownChoices$ | async"
9
- (selectValue)="selectLinkToDisplay($event)"
10
- ></gn-ui-dropdown-selector>
11
- <gn-ui-external-viewer-button
12
- class="shrink-0 py-1 place-self-end"
13
- [link]="selectedLink$ | async"
14
- >
15
- </gn-ui-external-viewer-button>
1
+ <div class="w-full h-full flex flex-col gap-[13px]">
2
+ <div
3
+ class="flex py-4 px-5 bg-white border border-color-border rounded-lg mt-6"
4
+ >
5
+ <div class="grow min-w-0">
6
+ <gn-ui-dropdown-selector
7
+ [ngClass]="{ hidden: !displaySource }"
8
+ class="w-full"
9
+ extraBtnClass="font-sans font-bold"
10
+ [title]="'map.select.layer' | translate"
11
+ [choices]="dropdownChoices$ | async"
12
+ (selectValue)="selectLinkToDisplay($event)"
13
+ ></gn-ui-dropdown-selector>
14
+ </div>
15
+ <div class="self-end">
16
+ <gn-ui-external-viewer-button
17
+ extraClass="w-[44px] h-[44px]"
18
+ [link]="selectedLink$ | async"
19
+ >
20
+ </gn-ui-external-viewer-button>
21
+ </div>
16
22
  </div>
17
23
  <ng-container *ngIf="hidePreview; else mapView">
18
24
  <gn-ui-popup-alert
@@ -49,7 +55,10 @@
49
55
  >
50
56
  <ng-icon name="matClose" class="align-middle text-sm"></ng-icon>
51
57
  </gn-ui-button>
52
- <gn-ui-feature-detail [feature]="selection"></gn-ui-feature-detail>
58
+ <gn-ui-feature-detail
59
+ [featureCatalog]="mdViewFacade.featureCatalog$ | async"
60
+ [feature]="selection"
61
+ ></gn-ui-feature-detail>
53
62
  </div>
54
63
 
55
64
  <div
@@ -17,7 +17,7 @@ export * from './lib/facets/facets.module'
17
17
  export * from './lib/facets/facets-container/facets-container.component'
18
18
  export * from './lib/records-metrics/records-metrics.component'
19
19
  export * from './lib/favorites/favorite-star/favorite-star.component'
20
- export * from './lib/results-hits-number/results-hits.container.component'
20
+ export * from './lib/results-hits/results-hits.container.component'
21
21
  export * from './lib/results-layout/results-layout.component'
22
22
  export * from './lib/sort-by/sort-by.component'
23
23
  export * from './lib/state/container/search-state.container.directive'
@@ -4,6 +4,7 @@ import { UiSearchModule } from '../../../../../libs/ui/search/src'
4
4
  import { EffectsModule } from '@ngrx/effects'
5
5
  import { StoreModule } from '@ngrx/store'
6
6
  import { TranslateModule } from '@ngx-translate/core'
7
+ import { NgIconsModule } from '@ng-icons/core'
7
8
  import { FacetsModule } from './facets/facets.module'
8
9
  import { FuzzySearchComponent } from './fuzzy-search/fuzzy-search.component'
9
10
  import { RecordsMetricsComponent } from './records-metrics/records-metrics.component'
@@ -12,7 +13,7 @@ import { ResultsListContainerComponent } from './results-list/results-list.conta
12
13
  import { SortByComponent } from './sort-by/sort-by.component'
13
14
  import { SearchEffects } from './state/effects'
14
15
  import { initialState, reducer, SEARCH_FEATURE_KEY } from './state/reducer'
15
- import { ResultsHitsContainerComponent } from './results-hits-number/results-hits.container.component'
16
+ import { ResultsHitsContainerComponent } from './results-hits/results-hits.container.component'
16
17
  import { SearchStateContainerDirective } from './state/container/search-state.container.directive'
17
18
  import {
18
19
  AutocompleteComponent,
@@ -20,7 +21,11 @@ import {
20
21
  UiInputsModule,
21
22
  } from '../../../../../libs/ui/inputs/src'
22
23
  import { NgModule } from '@angular/core'
23
- import { ErrorComponent, UiElementsModule } from '../../../../../libs/ui/elements/src'
24
+ import {
25
+ ErrorComponent,
26
+ KindBadgeComponent,
27
+ UiElementsModule,
28
+ } from '../../../../../libs/ui/elements/src'
24
29
  import { FilterDropdownComponent } from './filter-dropdown/filter-dropdown.component'
25
30
  import {
26
31
  SpinningLoaderComponent,
@@ -58,6 +63,8 @@ import { FavoriteStarComponent } from './favorites/favorite-star/favorite-star.c
58
63
  ErrorComponent,
59
64
  FavoriteStarComponent,
60
65
  DateRangeDropdownComponent,
66
+ NgIconsModule,
67
+ KindBadgeComponent,
61
68
  ],
62
69
  exports: [
63
70
  SortByComponent,
@@ -0,0 +1,16 @@
1
+ <div
2
+ class="flex flex-col gap-3 sm:flex-row justify-between"
3
+ [ngClass]="{
4
+ 'sm:items-center': (searchFacade.resultsHits$ | async) !== 0,
5
+ }"
6
+ >
7
+ <gn-ui-results-hits-number
8
+ [loading]="searchFacade.isLoading$ | async"
9
+ [hits]="searchFacade.resultsHits$ | async"
10
+ ></gn-ui-results-hits-number>
11
+ <gn-ui-results-hits-search-kind
12
+ (selectionChanged)="onSelectionChanged($event)"
13
+ [choices]="filterChoices$ | async"
14
+ [selected]="selected$ | async"
15
+ ></gn-ui-results-hits-search-kind>
16
+ </div>
@@ -0,0 +1,59 @@
1
+ import {
2
+ catchError,
3
+ filter,
4
+ map,
5
+ Observable,
6
+ of,
7
+ startWith,
8
+ switchMap,
9
+ } from 'rxjs'
10
+ import { Component, OnInit } from '@angular/core'
11
+ import { marker } from '@biesbjerg/ngx-translate-extract-marker'
12
+ import { SearchFacade } from '../state/search.facade'
13
+ import { FieldAvailableValue, FieldValue } from '../utils/service/fields'
14
+ import { SearchService } from '../utils/service/search.service'
15
+ import { FieldsService } from '../utils/service/fields.service'
16
+
17
+ marker('search.filters.recordKind.all')
18
+ marker('search.filters.recordKind.dataset')
19
+ marker('search.filters.recordKind.service')
20
+ marker('search.filters.recordKind.reuse')
21
+
22
+ @Component({
23
+ selector: 'gn-ui-results-hits',
24
+ templateUrl: './results-hits.container.component.html',
25
+ styleUrls: ['./results-hits.container.component.css'],
26
+ })
27
+ export class ResultsHitsContainerComponent implements OnInit {
28
+ fieldName = 'recordKind'
29
+ filterChoices$: Observable<FieldAvailableValue[]>
30
+ selected$: Observable<FieldValue[]>
31
+
32
+ constructor(
33
+ protected searchFacade: SearchFacade,
34
+ private searchService: SearchService,
35
+ private fieldsService: FieldsService
36
+ ) {}
37
+
38
+ ngOnInit() {
39
+ this.selected$ = this.searchFacade.searchFilters$.pipe(
40
+ switchMap((filters) =>
41
+ this.fieldsService.readFieldValuesFromFilters(filters)
42
+ ),
43
+ map((fieldValues) => fieldValues[this.fieldName]),
44
+ filter((selected) => !!selected),
45
+ startWith([]),
46
+ catchError(() => of([]))
47
+ ) as Observable<FieldValue[]>
48
+
49
+ this.filterChoices$ = <Observable<FieldAvailableValue[]>>(
50
+ this.fieldsService.getAvailableValues(this.fieldName)
51
+ )
52
+ }
53
+
54
+ onSelectionChanged(values: string[]) {
55
+ this.fieldsService
56
+ .buildFiltersFromFieldValues({ [this.fieldName]: values })
57
+ .subscribe((filters) => this.searchService.updateFilters(filters))
58
+ }
59
+ }
@@ -10,8 +10,10 @@ import {
10
10
  MultilingualSearchField,
11
11
  OrganizationSearchField,
12
12
  OwnerSearchField,
13
+ ResourceTypeLegacyField,
13
14
  SimpleSearchField,
14
15
  TranslatedSearchField,
16
+ RecordKindField,
15
17
  UserSearchField,
16
18
  } from './fields'
17
19
  import { forkJoin, Observable, of } from 'rxjs'
@@ -47,11 +49,8 @@ export class FieldsService {
47
49
  protected fields = {
48
50
  organization: new OrganizationSearchField(this.injector),
49
51
  format: new SimpleSearchField('format', this.injector, 'asc'),
50
- resourceType: new TranslatedSearchField(
51
- 'resourceType',
52
- this.injector,
53
- 'asc'
54
- ),
52
+ resourceType: new ResourceTypeLegacyField(this.injector), // Deprecated, use `recordKind` instead
53
+ recordKind: new RecordKindField(this.injector),
55
54
  representationType: new TranslatedSearchField(
56
55
  'cl_spatialRepresentationType.key',
57
56
  this.injector,
@@ -22,6 +22,7 @@ import {
22
22
  } from '../../../../../../../libs/api/repository/src'
23
23
  import { LangService } from '../../../../../../../libs/util/i18n/src'
24
24
  import { formatUserInfo } from '../../../../../../../libs/util/shared/src'
25
+ import { PossibleResourceTypes } from '../../../../../../../libs/api/metadata-converter/src'
25
26
 
26
27
  export type FieldType = 'values' | 'dateRange'
27
28
 
@@ -29,6 +30,7 @@ export type FieldValue = string | number
29
30
  export interface FieldAvailableValue {
30
31
  value: FieldValue
31
32
  label: string
33
+ count?: number
32
34
  }
33
35
 
34
36
  export abstract class AbstractSearchField {
@@ -80,6 +82,7 @@ export class SimpleSearchField implements AbstractSearchField {
80
82
  const bucketPromises = buckets.map(async (bucket) => ({
81
83
  label: `${await this.getBucketLabel(bucket)} (${bucket.count})`,
82
84
  value: bucket.term.toString(),
85
+ count: bucket.count,
83
86
  }))
84
87
  return Promise.all(bucketPromises)
85
88
  })
@@ -480,3 +483,99 @@ export class AvailableServicesField extends SimpleSearchField {
480
483
  return of(values)
481
484
  }
482
485
  }
486
+
487
+ /**
488
+ * This class is meant to be used with the legacy filter on `resourceType` (now deprecated, the use of `recordKind` field is recommended).
489
+ * Since creating filters on the same ES field is not possible, in order to make the resource type filter still working,
490
+ * we create an ES on the fly: `resourceTypeLegacy` that references the `resourceType` under the hood.
491
+ * @deprecated Use `recordKind` field instead.
492
+ */
493
+ export class ResourceTypeLegacyField extends TranslatedSearchField {
494
+ constructor(injector: Injector) {
495
+ super('resourceTypeLegacy', injector, 'asc')
496
+
497
+ // Ask ES to create a field on the fly: 'resourceTypeLegacy' that is in fact, 'resourceType'
498
+ this.esService.registerRuntimeField(
499
+ 'resourceTypeLegacy',
500
+ `for (resourceType in doc.resourceType) { emit(resourceType) }`
501
+ )
502
+ }
503
+ }
504
+
505
+ export class RecordKindField extends SimpleSearchField {
506
+ TYPE_MAPPING = {
507
+ dataset: ['dataset', 'series', 'featureCatalog'],
508
+ service: ['service'],
509
+ reuse: Object.entries(PossibleResourceTypes)
510
+ .filter(([_, v]) => v === 'reuse')
511
+ .map(([k]) => k), // = ['application', 'map', 'staticMap', 'interactiveMap', ...]
512
+ }
513
+
514
+ constructor(injector: Injector) {
515
+ super('resourceType', injector, 'asc')
516
+ }
517
+
518
+ getAvailableValues(): Observable<FieldAvailableValue[]> {
519
+ return this.repository.aggregate(this.getAggregations()).pipe(
520
+ map(
521
+ (response) =>
522
+ (response[this.esFieldName] as AggregationBuckets).buckets || []
523
+ ),
524
+ map((buckets: TermBucket[]) => {
525
+ const counts = buckets.reduce(
526
+ (acc, { term, count }) => {
527
+ const value = term.toString()
528
+ const key = this.TYPE_MAPPING.reuse.includes(value)
529
+ ? 'reuse'
530
+ : this.TYPE_MAPPING.dataset.includes(value)
531
+ ? 'dataset'
532
+ : value
533
+
534
+ acc[key] = (acc[key] || 0) + count
535
+ return acc
536
+ },
537
+ {} as Record<string, number>
538
+ )
539
+
540
+ return Object.keys(this.TYPE_MAPPING).map((type) => ({
541
+ label: type,
542
+ value: type,
543
+ count: counts[type] ?? 0,
544
+ }))
545
+ })
546
+ )
547
+ }
548
+
549
+ getFiltersForValues(values: FieldValue[]): Observable<FieldFilters> {
550
+ const filters = {
551
+ [this.esFieldName]: values.reduce((acc, value) => {
552
+ if (value === '') return { ...acc, [value]: true }
553
+
554
+ const keysToAdd = this.TYPE_MAPPING[value] || [value]
555
+ keysToAdd.forEach((key: string) => (acc[key] = true))
556
+
557
+ return acc
558
+ }, {}),
559
+ }
560
+
561
+ return of(filters)
562
+ }
563
+
564
+ getValuesForFilter(filters: FieldFilters): Observable<FieldValue[]> {
565
+ const filter = filters[this.esFieldName]
566
+ if (!filter) return of([])
567
+
568
+ const activeValues = Object.keys(filter).filter((v) => filter[v])
569
+ const activeTypes = Object.keys(this.TYPE_MAPPING).filter((type) =>
570
+ this.TYPE_MAPPING[type].every((t: string) => activeValues.includes(t))
571
+ )
572
+
573
+ // Allow unknown values eg. 'type=somethingnotexist' (for UI to select none)
574
+ const allTypes = [].concat(...Object.values(this.TYPE_MAPPING))
575
+ const unknownValues = activeValues.filter(
576
+ (value) => !allTypes.includes(value)
577
+ )
578
+
579
+ return of([...activeTypes, ...unknownValues])
580
+ }
581
+ }
@@ -57,6 +57,7 @@ export class ChartComponent implements OnChanges, AfterViewInit {
57
57
  this.dataRaw = value
58
58
  }
59
59
  @Input() labelProperty: string
60
+ @Input() prettyLabel: string
60
61
  @Input() valueProperty: string
61
62
  @Input() secondaryValueProperty: string
62
63
  @Input() type: InputChartType = 'bar'
@@ -95,7 +96,7 @@ export class ChartComponent implements OnChanges, AfterViewInit {
95
96
  labels: this.getDataProxy(this.labelProperty) as string[],
96
97
  datasets: [
97
98
  {
98
- label: this.valueProperty,
99
+ label: this.prettyLabel,
99
100
  data,
100
101
  },
101
102
  ],
@@ -8,21 +8,24 @@
8
8
  [matSortDisableClear]="true"
9
9
  *ngrxLet="properties$ as properties"
10
10
  >
11
- <ng-container *ngFor="let prop of properties" [matColumnDef]="prop">
11
+ <ng-container
12
+ *ngFor="let attr of _featureAttributes"
13
+ [matColumnDef]="attr.value"
14
+ >
12
15
  <th
13
16
  mat-header-cell
14
17
  *matHeaderCellDef
15
18
  mat-sort-header
16
19
  class="text-sm text-black bg-white"
17
20
  >
18
- {{ prop }}
21
+ {{ attr.label }}
19
22
  </th>
20
23
  <td
21
24
  mat-cell
22
25
  *matCellDef="let element"
23
26
  class="whitespace-nowrap pr-1 truncate"
24
27
  >
25
- {{ element[prop] }}
28
+ {{ element[attr.value] }}
26
29
  </td>
27
30
  </ng-container>
28
31
 
@@ -61,13 +61,14 @@ export interface TableItemModel {
61
61
  changeDetection: ChangeDetectionStrategy.OnPush,
62
62
  })
63
63
  export class DataTableComponent implements OnInit, AfterViewInit, OnChanges {
64
+ _featureAttributes = []
65
+ @Input() set featureAttributes(value: { value: string; label: string }[]) {
66
+ this._featureAttributes = value
67
+ this.properties$.next(value.map((attr) => attr.value))
68
+ }
64
69
  @Input() set dataset(value: BaseReader) {
65
- this.properties$.next(null)
66
70
  this.dataset_ = value
67
71
  this.dataset_.load()
68
- this.dataset_.properties.then((properties) =>
69
- this.properties$.next(properties.map((p) => p.name))
70
- )
71
72
  this.dataset_.info.then((info) => (this.count = info.itemsCount))
72
73
  }
73
74
  @Input() activeId: TableItemId
@@ -7,6 +7,7 @@ export * from './lib/downloads-list/downloads-list.component'
7
7
  export * from './lib/error/error.component'
8
8
  export * from './lib/image-input/image-input.component'
9
9
  export * from './lib/image-overlay-preview/image-overlay-preview.component'
10
+ export * from './lib/kind-badge/kind-badge.component'
10
11
  export * from './lib/link-card/link-card.component'
11
12
  export * from './lib/markdown-editor/markdown-editor.component'
12
13
  export * from './lib/markdown-parser/markdown-parser.component'
@@ -1,12 +1,12 @@
1
1
  <div
2
- class="group flex justify-between rounded filter overflow-hidden"
2
+ class="group flex justify-between rounded filter overflow-hidden card-shadow"
3
3
  [ngClass]="cardClass"
4
4
  >
5
5
  <ng-container *ngIf="size !== 'S'">
6
- <div>
6
+ <div class="flex-1 min-w-0">
7
7
  <ng-container *ngTemplateOutlet="content"></ng-container>
8
8
  </div>
9
- <div class="flex items-center">
9
+ <div class="flex items-center min-w-[32px]">
10
10
  <ng-container *ngTemplateOutlet="buttons"></ng-container>
11
11
  </div>
12
12
  </ng-container>
@@ -51,7 +51,7 @@
51
51
  </ng-template>
52
52
 
53
53
  <ng-template #content>
54
- <div>
54
+ <div class="flex-1 min-w-0">
55
55
  <div class="gn-ui-card-title">
56
56
  {{ link.description || link.name }}
57
57
  </div>
@@ -1,20 +1,20 @@
1
1
  <a
2
2
  href="{{ link.url }}"
3
3
  target="_blank"
4
- class="group flex flex-row justify-between card-shadow cursor-pointer rounded overflow-hidden"
4
+ class="group flex flex-row justify-between card-shadow cursor-pointer rounded overflow-hidden w-full"
5
5
  rel="noopener"
6
6
  [ngClass]="cardClass"
7
7
  >
8
- <div class="flex flex-col justify-between">
8
+ <div class="flex flex-col flex-1 justify-between min-w-0">
9
9
  <div class="gn-ui-card-title" [title]="link.description || link.name">
10
10
  {{ link.description || link.name }}
11
11
  </div>
12
12
  <div class="gn-ui-card-detail">
13
13
  {{ link.name }}
14
14
  </div>
15
- <div class="flex flex-row gap-2 items-center pt-1">
15
+ <div class="flex flex-row gap-2 items-center pt-1 min-w-0">
16
16
  <span
17
- class="inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded transition-opacity opacity-70 group-hover:opacity-100"
17
+ class="inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded transition-opacity opacity-70 group-hover:opacity-100 whitespace-nowrap"
18
18
  [style.background-color]="color"
19
19
  data-cy="download-format"
20
20
  >{{ format || ('downloads.format.unknown' | translate) }}</span
@@ -24,7 +24,10 @@
24
24
  >
25
25
  </div>
26
26
  </div>
27
- <div class="flex" [ngClass]="size === 'S' ? 'items-end' : 'items-center'">
27
+ <div
28
+ class="flex min-w-[32px] flex-shrink-0"
29
+ [ngClass]="size === 'S' ? 'items-end' : 'items-center'"
30
+ >
28
31
  <div class="gn-ui-card-icon">
29
32
  <ng-icon
30
33
  class="inline-block card-icon align-middle"